exchanges/engine: Add multichain deposit/withdrawal support (#794)

* Add exchange multichain support

* Start tidying up

* Add multichain transfer support for Bitfinex and fix poloniex bug

* Add Coinbene multichain support

* Start adjusting the deposit address manager

* Fix deposit tests and further enhancements

* Cleanup

* Add bypass flag, expand tests plus error coverage for Huobi

Adjust helpers

* Address nitterinos

* BFX wd changes

* Address nitterinos

* Minor fixes rebasing on master

* Fix BFX acceptableMethods test

* Add some TO-DOs for 2 tests WRT races

* Fix acceptableMethods test round 2

* Address nitterinos
This commit is contained in:
Adrian Gallagher
2021-10-15 15:55:38 +11:00
committed by GitHub
parent b093a7df19
commit 0c00b7e1df
145 changed files with 46329 additions and 5507 deletions

View File

@@ -16,6 +16,7 @@ import (
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/deposit"
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
@@ -118,25 +119,27 @@ func (b *Binance) SetDefaults() {
REST: true,
Websocket: true,
RESTCapabilities: protocol.Features{
TickerBatching: true,
TickerFetching: true,
KlineFetching: true,
OrderbookFetching: true,
AutoPairUpdates: true,
AccountInfo: true,
CryptoDeposit: true,
CryptoWithdrawal: true,
GetOrder: true,
GetOrders: true,
CancelOrders: true,
CancelOrder: true,
SubmitOrder: true,
DepositHistory: true,
WithdrawalHistory: true,
TradeFetching: true,
UserTradeHistory: true,
TradeFee: true,
CryptoWithdrawalFee: true,
TickerBatching: true,
TickerFetching: true,
KlineFetching: true,
OrderbookFetching: true,
AutoPairUpdates: true,
AccountInfo: true,
CryptoDeposit: true,
CryptoWithdrawal: true,
GetOrder: true,
GetOrders: true,
CancelOrders: true,
CancelOrder: true,
SubmitOrder: true,
DepositHistory: true,
WithdrawalHistory: true,
TradeFetching: true,
UserTradeHistory: true,
TradeFee: true,
CryptoWithdrawalFee: true,
MultiChainDeposits: true,
MultiChainWithdrawals: true,
},
WebsocketCapabilities: protocol.Features{
TradeFetching: true,
@@ -431,27 +434,40 @@ func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error {
if err != nil {
return err
}
for y := range tick {
cp, err := currency.NewPairFromString(tick[y].Symbol)
if err != nil {
return err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
High: tick[y].HighPrice,
Low: tick[y].LowPrice,
Bid: tick[y].BidPrice,
Ask: tick[y].AskPrice,
Volume: tick[y].Volume,
QuoteVolume: tick[y].QuoteVolume,
Open: tick[y].OpenPrice,
Close: tick[y].PrevClosePrice,
Pair: cp,
ExchangeName: b.Name,
AssetType: a,
})
if err != nil {
return err
pairs, err := b.GetEnabledPairs(a)
if err != nil {
return err
}
for i := range pairs {
for y := range tick {
pairFmt, err := b.FormatExchangeCurrency(pairs[i], a)
if err != nil {
return err
}
if tick[y].Symbol != pairFmt.String() {
continue
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[y].LastPrice,
High: tick[y].HighPrice,
Low: tick[y].LowPrice,
Bid: tick[y].BidPrice,
Ask: tick[y].AskPrice,
Volume: tick[y].Volume,
QuoteVolume: tick[y].QuoteVolume,
Open: tick[y].OpenPrice,
Close: tick[y].PrevClosePrice,
Pair: pairFmt,
ExchangeName: b.Name,
AssetType: a,
})
if err != nil {
return err
}
}
}
case asset.USDTMarginedFutures:
@@ -522,10 +538,6 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick.Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick.LastPrice,
High: tick.HighPrice,
@@ -536,7 +548,7 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
QuoteVolume: tick.QuoteVolume,
Open: tick.OpenPrice,
Close: tick.PrevClosePrice,
Pair: cp,
Pair: p,
ExchangeName: b.Name,
AssetType: a,
})
@@ -548,10 +560,6 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick[0].Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[0].LastPrice,
High: tick[0].HighPrice,
@@ -560,7 +568,7 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
QuoteVolume: tick[0].QuoteVolume,
Open: tick[0].OpenPrice,
Close: tick[0].PrevClosePrice,
Pair: cp,
Pair: p,
ExchangeName: b.Name,
AssetType: a,
})
@@ -572,10 +580,6 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
if err != nil {
return nil, err
}
cp, err := currency.NewPairFromString(tick[0].Symbol)
if err != nil {
return nil, err
}
err = ticker.ProcessTicker(&ticker.Price{
Last: tick[0].LastPrice,
High: tick[0].HighPrice,
@@ -584,7 +588,7 @@ func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Ite
QuoteVolume: tick[0].QuoteVolume,
Open: tick[0].OpenPrice,
Close: tick[0].PrevClosePrice,
Pair: cp,
Pair: p,
ExchangeName: b.Name,
AssetType: a,
})
@@ -763,7 +767,6 @@ func (b *Binance) FetchAccountInfo(ctx context.Context, assetType asset.Item) (a
if err != nil {
return b.UpdateAccountInfo(ctx, assetType)
}
return acc, nil
}
@@ -775,21 +778,26 @@ func (b *Binance) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory
// GetWithdrawalsHistory returns previous withdrawals data
func (b *Binance) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) {
w, err := b.WithdrawStatus(ctx, c, "", 0, 0)
w, err := b.WithdrawHistory(ctx, c, "", time.Time{}, time.Time{}, 0, 10000)
if err != nil {
return nil, err
}
for i := range w {
tm, err := time.Parse(binanceSAPITimeLayout, w[i].ApplyTime)
if err != nil {
return nil, err
}
resp = append(resp, exchange.WithdrawalHistory{
Status: strconv.FormatInt(w[i].Status, 10),
TransferID: w[i].ID,
Currency: w[i].Asset,
Currency: w[i].Coin,
Amount: w[i].Amount,
Fee: w[i].TransactionFee,
CryptoToAddress: w[i].Address,
CryptoTxID: w[i].TxID,
Timestamp: time.Unix(w[i].ApplyTime/1000, 0),
CryptoTxID: w[i].TransactionID,
CryptoChain: w[i].Network,
Timestamp: tm,
})
}
@@ -1216,8 +1224,16 @@ func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currenc
}
// GetDepositAddress returns a deposit address for a specified currency
func (b *Binance) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) {
return b.GetDepositAddressForCurrency(ctx, cryptocurrency.String())
func (b *Binance) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _, chain string) (*deposit.Address, error) {
addr, err := b.GetDepositAddressForCurrency(ctx, cryptocurrency.String(), chain)
if err != nil {
return nil, err
}
return &deposit.Address{
Address: addr.Address,
Tag: addr.Tag,
}, nil
}
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is
@@ -1229,9 +1245,13 @@ func (b *Binance) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawReque
amountStr := strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64)
v, err := b.WithdrawCrypto(ctx,
withdrawRequest.Currency.String(),
"", // withdrawal order ID
withdrawRequest.Crypto.Chain,
withdrawRequest.Crypto.Address,
withdrawRequest.Crypto.AddressTag,
withdrawRequest.Description, amountStr)
withdrawRequest.Description,
amountStr,
false)
if err != nil {
return nil, err
}
@@ -1730,3 +1750,22 @@ func (b *Binance) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item)
}
return b.LoadLimits(limits)
}
// GetAvailableTransferChains returns the available transfer blockchains for the specific
// cryptocurrency
func (b *Binance) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) {
coinInfo, err := b.GetAllCoinsInfo(ctx)
if err != nil {
return nil, err
}
var availableChains []string
for x := range coinInfo {
if strings.EqualFold(coinInfo[x].Coin, cryptocurrency.String()) {
for y := range coinInfo[x].NetworkList {
availableChains = append(availableChains, coinInfo[x].NetworkList[y].Network)
}
}
}
return availableChains, nil
}