mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-04 07:26:47 +00:00
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:
@@ -17,6 +17,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"
|
||||
@@ -89,29 +90,32 @@ func (b *Bitfinex) SetDefaults() {
|
||||
REST: true,
|
||||
Websocket: true,
|
||||
RESTCapabilities: protocol.Features{
|
||||
TickerBatching: true,
|
||||
TickerFetching: true,
|
||||
OrderbookFetching: true,
|
||||
AutoPairUpdates: true,
|
||||
AccountInfo: true,
|
||||
CryptoDeposit: true,
|
||||
CryptoWithdrawal: true,
|
||||
FiatWithdraw: true,
|
||||
GetOrder: true,
|
||||
GetOrders: true,
|
||||
CancelOrders: true,
|
||||
CancelOrder: true,
|
||||
SubmitOrder: true,
|
||||
SubmitOrders: true,
|
||||
DepositHistory: true,
|
||||
WithdrawalHistory: true,
|
||||
TradeFetching: true,
|
||||
UserTradeHistory: true,
|
||||
TradeFee: true,
|
||||
FiatDepositFee: true,
|
||||
FiatWithdrawalFee: true,
|
||||
CryptoDepositFee: true,
|
||||
CryptoWithdrawalFee: true,
|
||||
TickerBatching: true,
|
||||
TickerFetching: true,
|
||||
OrderbookFetching: true,
|
||||
AutoPairUpdates: true,
|
||||
AccountInfo: true,
|
||||
CryptoDeposit: true,
|
||||
CryptoWithdrawal: true,
|
||||
FiatWithdraw: true,
|
||||
GetOrder: true,
|
||||
GetOrders: true,
|
||||
CancelOrders: true,
|
||||
CancelOrder: true,
|
||||
SubmitOrder: true,
|
||||
SubmitOrders: true,
|
||||
DepositHistory: true,
|
||||
WithdrawalHistory: true,
|
||||
TradeFetching: true,
|
||||
UserTradeHistory: true,
|
||||
TradeFee: true,
|
||||
FiatDepositFee: true,
|
||||
FiatWithdrawalFee: true,
|
||||
CryptoDepositFee: true,
|
||||
CryptoWithdrawalFee: true,
|
||||
MultiChainDeposits: true,
|
||||
MultiChainWithdrawals: true,
|
||||
MultiChainDepositRequiresChainSet: true,
|
||||
},
|
||||
WebsocketCapabilities: protocol.Features{
|
||||
AccountBalance: true,
|
||||
@@ -731,18 +735,39 @@ func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair curren
|
||||
}
|
||||
|
||||
// GetDepositAddress returns a deposit address for a specified currency
|
||||
func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) {
|
||||
func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accountID, chain string) (*deposit.Address, error) {
|
||||
if accountID == "" {
|
||||
accountID = "deposit"
|
||||
accountID = "funding"
|
||||
}
|
||||
|
||||
method, err := b.ConvertSymbolToDepositMethod(ctx, c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
if c == currency.USDT {
|
||||
// USDT is UST on Bitfinex
|
||||
c = currency.NewCode("UST")
|
||||
}
|
||||
|
||||
if err := b.PopulateAcceptableMethods(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
methods := acceptableMethods.lookup(c)
|
||||
if len(methods) == 0 {
|
||||
return nil, errors.New("unsupported currency")
|
||||
}
|
||||
method := methods[0]
|
||||
if len(methods) > 1 && chain != "" {
|
||||
method = chain
|
||||
} else if len(methods) > 1 && chain == "" {
|
||||
return nil, fmt.Errorf("a chain must be specified, %s available", methods)
|
||||
}
|
||||
|
||||
resp, err := b.NewDeposit(ctx, method, accountID, 0)
|
||||
return resp.Address, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &deposit.Address{
|
||||
Address: resp.Address,
|
||||
Tag: resp.PoolAddress,
|
||||
}, err
|
||||
}
|
||||
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted
|
||||
@@ -750,6 +775,31 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ
|
||||
if err := withdrawRequest.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := b.PopulateAcceptableMethods(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tmpCurr := withdrawRequest.Currency
|
||||
if tmpCurr == currency.USDT {
|
||||
// USDT is UST on Bitfinex
|
||||
tmpCurr = currency.NewCode("UST")
|
||||
}
|
||||
|
||||
methods := acceptableMethods.lookup(tmpCurr)
|
||||
if len(methods) == 0 {
|
||||
return nil, errors.New("no transfer methods returned for currency")
|
||||
}
|
||||
method := methods[0]
|
||||
if len(methods) > 1 && withdrawRequest.Crypto.Chain != "" {
|
||||
if !common.StringDataCompareInsensitive(methods, withdrawRequest.Crypto.Chain) {
|
||||
return nil, fmt.Errorf("invalid chain %s supplied, %v available", withdrawRequest.Crypto.Chain, methods)
|
||||
}
|
||||
method = withdrawRequest.Crypto.Chain
|
||||
} else if len(methods) > 1 && withdrawRequest.Crypto.Chain == "" {
|
||||
return nil, fmt.Errorf("a chain must be specified, %s available", methods)
|
||||
}
|
||||
|
||||
// Bitfinex has support for three types, exchange, margin and deposit
|
||||
// As this is for trading, I've made the wrapper default 'exchange'
|
||||
// TODO: Discover an automated way to make the decision for wallet type to withdraw from
|
||||
@@ -757,9 +807,9 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequ
|
||||
resp, err := b.WithdrawCryptocurrency(ctx,
|
||||
walletType,
|
||||
withdrawRequest.Crypto.Address,
|
||||
withdrawRequest.Description,
|
||||
withdrawRequest.Amount,
|
||||
withdrawRequest.Currency)
|
||||
withdrawRequest.Crypto.AddressTag,
|
||||
method,
|
||||
withdrawRequest.Amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1119,3 +1169,22 @@ func (b *Bitfinex) fixCasing(in currency.Pair, a asset.Item) (string, error) {
|
||||
runes[0] = unicode.ToLower(runes[0])
|
||||
return string(runes), nil
|
||||
}
|
||||
|
||||
// GetAvailableTransferChains returns the available transfer blockchains for the specific
|
||||
// cryptocurrency
|
||||
func (b *Bitfinex) GetAvailableTransferChains(ctx context.Context, cryptocurrency currency.Code) ([]string, error) {
|
||||
if err := b.PopulateAcceptableMethods(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cryptocurrency == currency.USDT {
|
||||
// USDT is UST on Bitfinex
|
||||
cryptocurrency = currency.NewCode("UST")
|
||||
}
|
||||
|
||||
availChains := acceptableMethods.lookup(cryptocurrency)
|
||||
if len(availChains) == 0 {
|
||||
return nil, fmt.Errorf("unable to find any available chains")
|
||||
}
|
||||
return availChains, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user