-
Notifications
You must be signed in to change notification settings - Fork 126
/
anyswap.go
137 lines (108 loc) · 3.18 KB
/
anyswap.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
package source
import (
"encoding/json"
"github.com/diadata-org/diadata/pkg/dia"
"github.com/diadata-org/diadata/pkg/dia/helpers/ethhelper"
models "github.com/diadata-org/diadata/pkg/model"
"github.com/diadata-org/diadata/pkg/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
const (
anyswapAPIUrl = "https://bridgeapi.anyswap.exchange/v3/serverinfoV3?chainId=all&version=STABLEV3"
)
var (
chainMap map[string]string
)
func init() {
chainMap = make(map[string]string)
chainMap["1"] = dia.ETHEREUM
chainMap["56"] = dia.BINANCESMARTCHAIN
chainMap["137"] = dia.POLYGON
chainMap["250"] = dia.FANTOM
chainMap["1284"] = dia.MOONBEAM
chainMap["1285"] = dia.MOONRIVER
chainMap["42161"] = dia.ARBITRUM
chainMap["43114"] = dia.AVALANCHE
// chainMap["66"] = chainInfo{Name: "OKExChain", Client: ""}
// chainMap["128"] = chainInfo{Name: "HuobiECOChain", Client: ""}
// chainMap["288"] = chainInfo{Name: "Boba", Client: ""}
}
type AnyswapAssetSource struct {
assetChannel chan dia.Asset
doneChannel chan bool
URL string
relDB *models.RelDB
}
func NewAnyswapAssetSource(exchange dia.Exchange) *AnyswapAssetSource {
var assetChannel = make(chan dia.Asset)
var doneChannel = make(chan bool)
relDB, err := models.NewRelDataStore()
if err != nil {
log.Fatal("make new relational datastore: ", err)
}
sas := &AnyswapAssetSource{
assetChannel: assetChannel,
doneChannel: doneChannel,
URL: anyswapAPIUrl,
relDB: relDB,
}
go func() {
sas.fetchAssets()
}()
return sas
}
func (sas *AnyswapAssetSource) Asset() chan dia.Asset {
return sas.assetChannel
}
func (sas *AnyswapAssetSource) Done() chan bool {
return sas.doneChannel
}
func (sas *AnyswapAssetSource) fetchAssets() {
allAssetsAllChains, err := sas.fetchEndpoint()
if err != nil {
log.Error("fetch endpoint: ", err)
return
}
clientMap, err := getClientMap()
if err != nil {
log.Error("get client map: ", err)
}
// @chainMap can be substituted with allAssetsAllChains as soon as we have clients for all chains.
for chainID := range clientMap {
allAssets := allAssetsAllChains[chainID]
for address := range allAssets {
asset, err := ethhelper.ETHAddressToAsset(common.HexToAddress(address), clientMap[chainID], chainMap[chainID])
if err != nil {
log.Error("fetch asset from on-chain: ", err)
}
sas.assetChannel <- asset
}
}
sas.doneChannel <- true
}
func getClientMap() (map[string]*ethclient.Client, error) {
clientMap := make(map[string]*ethclient.Client)
for key := range chainMap {
restClient, err := ethclient.Dial(utils.Getenv("ETH_URI_"+key, ""))
if err != nil {
log.Error("connecting to chainID: ", key)
return clientMap, err
}
clientMap[key] = restClient
}
return clientMap, nil
}
// fetchEndpoint returns all assets available in the Anyswap bridge obtained through an API endpoint.
func (sas *AnyswapAssetSource) fetchEndpoint() (response map[string]map[string]interface{}, err error) {
// @response is of type map[chainID]map[assetAddress]interface{}
data, _, err := utils.GetRequest(sas.URL)
if err != nil {
return
}
err = json.Unmarshal(data, &response)
if err != nil {
return
}
return
}