/
main.go
177 lines (160 loc) · 7.24 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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package scraper
import (
"context"
"time"
orbitrclient "github.com/lantah/go/clients/orbitrclient"
hProtocol "github.com/lantah/go/protocols/orbitr"
"github.com/lantah/go/services/ticker/internal/utils"
hlog "github.com/lantah/go/support/log"
)
type ScraperConfig struct {
Client orbitrclient.ClientInterface
Logger *hlog.Entry
Ctx *context.Context
}
// TOMLDoc is the interface for storing TOML Issuer Documentation.
// See: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md#currency-documentation
type TOMLDoc struct {
OrgName string `toml:"ORG_NAME"`
OrgURL string `toml:"ORG_URL"`
OrgTwitter string `toml:"ORG_TWITTER"`
}
// TOMLCurrency is the interface for storing TOML Currency Information.
// See: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md#currency-documentation
type TOMLCurrency struct {
Code string `toml:"code"`
Issuer string `toml:"issuer"`
IsAssetAnchored bool `toml:"is_asset_anchored"`
AnchorAsset string `toml:"anchor_asset"`
AnchorAssetType string `toml:"anchor_asset_type"`
DisplayDecimals int `toml:"display_decimals"`
Name string `toml:"name"`
Desc string `toml:"desc"`
Conditions string `toml:"conditions"`
FixedNumber int `toml:"fixed_number"`
MaxNumber int `toml:"max_number"`
IsUnlimited bool `toml:"is_unlimited"`
RedemptionInstructions string `toml:"redemption_instructions"`
CollateralAddresses []string `toml:"collateral_addresses"`
CollateralAddressSignatures []string `toml:"collateral_address_signatures"`
Status string `toml:"status"`
}
// TOMLIssuer is the interface for storing TOML Issuer Information.
// See: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md#currency-documentation
type TOMLIssuer struct {
FederationServer string `toml:"FEDERATION_SERVER"`
AuthServer string `toml:"AUTH_SERVER"`
TransferServer string `toml:"TRANSFER_SERVER"`
WebAuthEndpoint string `toml:"WEB_AUTH_ENDPOINT"`
SigningKey string `toml:"SIGNING_KEY"`
DepositServer string `toml:"DEPOSIT_SERVER"` // for legacy purposes
Documentation TOMLDoc `toml:"DOCUMENTATION"`
Currencies []TOMLCurrency `toml:"CURRENCIES"`
TOMLURL string `toml:"-"`
}
// FinalAsset is the interface to represent the aggregated Asset data.
type FinalAsset struct {
Code string `json:"code"`
Issuer string `json:"issuer"`
Type string `json:"type"`
NumAccounts int32 `json:"num_accounts"`
AuthRequired bool `json:"auth_required"`
AuthRevocable bool `json:"auth_revocable"`
Amount float64 `json:"amount"`
IssuerDetails TOMLIssuer `json:"-"`
AssetControlledByDomain bool `json:"asset_controlled_by_domain"`
Error string `json:"-"`
AnchorAsset string `json:"anchor_asset"`
AnchorAssetType string `json:"anchor_asset_type"`
IsValid bool `json:"-"`
LastValid time.Time `json:"-"`
LastChecked time.Time `json:"-"`
IsTrash bool `json:"-"`
DisplayDecimals int `json:"display_decimals"`
Name string `json:"name"`
Desc string `json:"desc"`
Conditions string `json:"conditions"`
IsAssetAnchored bool `json:"is_asset_anchored"`
FixedNumber int `json:"fixed_number"`
MaxNumber int `json:"max_number"`
IsUnlimited bool `json:"is_unlimited"`
RedemptionInstructions string `json:"redemption_instructions"`
CollateralAddresses []string `json:"collateral_addresses"`
CollateralAddressSignatures []string `json:"collateral_address_signatures"`
Countries string `json:"countries"`
Status string `json:"status"`
}
// OrderbookStats represents the Orderbook stats for a given asset
type OrderbookStats struct {
BaseAssetCode string
BaseAssetType string
BaseAssetIssuer string
CounterAssetCode string
CounterAssetType string
CounterAssetIssuer string
NumBids int
BidVolume float64
HighestBid float64
NumAsks int
AskVolume float64
LowestAsk float64
Spread float64
SpreadMidPoint float64
}
// ProcessAllAssets fetches assets from the OrbitR public net. If limit = 0, will fetch all assets.
func (c *ScraperConfig) ProcessAllAssets(limit int, parallelism int, assetQueue chan<- FinalAsset) (numNonTrash int, numTrash int) {
dirtyAssets, err := c.retrieveAssets(limit)
if err != nil {
return
}
numNonTrash, numTrash = c.parallelProcessAssets(dirtyAssets, parallelism, assetQueue)
c.Logger.Infof(
"Scanned %d entries. Trash: %d. Non-trash: %d\n",
len(dirtyAssets),
numTrash,
numNonTrash,
)
return
}
// FetchAllTrades fetches all trades for a given period, respecting the limit. If limit = 0,
// will fetch all trades for that given period.
func (c *ScraperConfig) FetchAllTrades(since time.Time, limit int) (trades []hProtocol.Trade, err error) {
c.Logger.Info("Fetching trades from OrbitR")
trades, err = c.retrieveTrades(since, limit)
if len(trades) > 0 {
c.Logger.Info("Last close time ingested:", trades[len(trades)-1].LedgerCloseTime)
}
c.Logger.Infof("Fetched: %d trades\n", len(trades))
return
}
// StreamNewTrades streams trades directly from orbitr and calls the handler function
// whenever a new trade appears.
func (c *ScraperConfig) StreamNewTrades(cursor string, h orbitrclient.TradeHandler) error {
c.Logger.Info("Starting to stream trades with cursor at:", cursor)
return c.streamTrades(h, cursor)
}
// FetchOrderbookForAssets fetches the orderbook stats for the base and counter assets provided in the parameters
func (c *ScraperConfig) FetchOrderbookForAssets(bType, bCode, bIssuer, cType, cCode, cIssuer string) (OrderbookStats, error) {
c.Logger.Infof("Fetching orderbook info for %s:%s / %s:%s\n", bCode, bIssuer, cCode, cIssuer)
return c.fetchOrderbook(bType, bCode, bIssuer, cType, cCode, cIssuer)
}
// NormalizeTradeAssets enforces the following rules:
// 1. native asset type refers to a "GRAM" code and a "native" issuer
// 2. native is always the base asset (and if not, base and counter are swapped)
// 3. when trades are between two non-native, the base is the asset whose string
// comes first alphabetically.
func NormalizeTradeAssets(t *hProtocol.Trade) {
addNativeData(t)
if t.BaseAssetType == "native" {
return
}
if t.CounterAssetType == "native" {
reverseAssets(t)
return
}
bAssetString := utils.GetAssetString(t.BaseAssetType, t.BaseAssetCode, t.BaseAssetIssuer)
cAssetString := utils.GetAssetString(t.CounterAssetType, t.CounterAssetCode, t.CounterAssetIssuer)
if bAssetString > cAssetString {
reverseAssets(t)
}
}