/
main.go
123 lines (112 loc) · 3.65 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package gql
import (
"net/http"
"time"
"github.com/graph-gophers/graphql-go"
"github.com/graph-gophers/graphql-go/relay"
"github.com/shantanu-hashcash/go/services/ticker/internal/gql/static"
"github.com/shantanu-hashcash/go/services/ticker/internal/tickerdb"
hlog "github.com/shantanu-hashcash/go/support/log"
)
// asset represents a Hcnet asset, with some type
// adaptations to match the GraphQL type system
type asset struct {
Code string
IssuerAccount string
Type string
NumAccounts int32
AuthRequired bool
AuthRevocable bool
Amount float64
AssetControlledByDomain bool
AnchorAssetCode string
AnchorAssetType string
IsValid bool
DisplayDecimals BigInt
Name string
Desc string
Conditions string
IsAssetAnchored bool
FixedNumber BigInt
MaxNumber BigInt
IsUnlimited bool
RedemptionInstructions string
CollateralAddresses string
CollateralAddressSignatures string
Countries string
Status string
IssuerID int32
OrderbookStats orderbookStats
}
// partialMarket represents the aggregated market data for a
// specific pair of assets since <Since>
type partialMarket struct {
TradePair string
BaseAssetCode string
BaseAssetIssuer string
CounterAssetCode string
CounterAssetIssuer string
BaseVolume float64
CounterVolume float64
TradeCount int32
Open float64
Low float64
High float64
Change float64
Close float64
IntervalStart graphql.Time
FirstLedgerCloseTime graphql.Time
LastLedgerCloseTime graphql.Time
OrderbookStats orderbookStats
}
// orderbookStats represents the orderbook stats for a
// specific pair of assets (aggregated or not)
type orderbookStats struct {
BidCount BigInt
BidVolume float64
BidMax float64
AskCount BigInt
AskVolume float64
AskMin float64
Spread float64
SpreadMidPoint float64
}
type resolver struct {
db *tickerdb.TickerSession
logger *hlog.Entry
}
// New creates a new GraphQL resolver
func New(s *tickerdb.TickerSession, l *hlog.Entry) *resolver {
if s == nil {
panic("A valid database session must be provided for the GraphQL server")
}
return &resolver{db: s, logger: l}
}
// Serve creates a GraphQL interface on <address>/graphql and a GraphiQL explorer on /graphiql
func (r *resolver) Serve(address string) {
relayHandler := r.NewRelayHandler()
mux := http.NewServeMux()
mux.Handle("/graphql", http.HandlerFunc(func(wr http.ResponseWriter, re *http.Request) {
r.logger.Infof("%s %s %s\n", re.RemoteAddr, re.Method, re.URL)
relayHandler.ServeHTTP(wr, re)
}))
mux.Handle("/graphiql", GraphiQL{})
server := &http.Server{
Addr: address,
Handler: mux,
ReadTimeout: 5 * time.Second,
}
r.logger.Infof("Starting to serve on address %s\n", address)
if err := server.ListenAndServe(); err != nil {
r.logger.Error("server.ListenAndServe:", err)
}
}
// NewRelayHandler sets up the response handler.
func (r *resolver) NewRelayHandler() relay.Handler {
opts := []graphql.SchemaOpt{graphql.UseFieldResolvers()}
r.logger.Info("Validating GraphQL schema")
s := graphql.MustParseSchema(static.Schema(), r, opts...)
r.logger.Infof("Schema Validated!")
relayHandler := relay.Handler{Schema: s}
return relayHandler
}