diff --git a/docs/ADD_NEW_EXCHANGE.md b/docs/ADD_NEW_EXCHANGE.md index cac51361..5e79ced2 100644 --- a/docs/ADD_NEW_EXCHANGE.md +++ b/docs/ADD_NEW_EXCHANGE.md @@ -716,7 +716,7 @@ func (f *FTX) WsConnect() error { // This reader routine is called prior to initiating a subscription for // efficient processing. go f.wsReadData() - if f.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if f.IsWebsocketAuthenticationSupported() { err = f.WsAuth(context.TODO()) if err != nil { f.Websocket.DataHandler <- err @@ -766,7 +766,7 @@ func (f *FTX) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, erro } } // Appends authenticated channels to the subscription list - if f.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if f.IsWebsocketAuthenticationSupported() { var authchan = []string{wsOrders, wsFills} for x := range authchan { subscriptions = append(subscriptions, stream.ChannelSubscription{ diff --git a/engine/helpers.go b/engine/helpers.go index ddc2ab12..7c6ed68d 100644 --- a/engine/helpers.go +++ b/engine/helpers.go @@ -328,8 +328,8 @@ func (bot *Engine) GetAuthAPISupportedExchanges() []string { exchanges := bot.GetExchanges() exchangeNames := make([]string, 0, len(exchanges)) for x := range exchanges { - if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) && - !exchanges[x].GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !exchanges[x].IsRESTAuthenticationSupported() && + !exchanges[x].IsWebsocketAuthenticationSupported() { continue } exchangeNames = append(exchangeNames, exchanges[x].GetName()) @@ -696,10 +696,10 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map depositSyncer.Add(len(exchanges)) var m sync.Mutex for x := range exchanges { - go func(x int) { + go func(exch exchange.IBotExchange) { defer depositSyncer.Done() - exchName := exchanges[x].GetName() - if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) { + exchName := exch.GetName() + if !exch.IsRESTAuthenticationSupported() { if bot.Settings.Verbose { log.Debugf(log.ExchangeSys, "GetAllExchangeCryptocurrencyDepositAddresses: Skippping %s due to disabled authenticated API support.\n", exchName) } @@ -711,15 +711,15 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map log.Errorf(log.ExchangeSys, "%s failed to get cryptocurrency deposit addresses. Err: %s\n", exchName, err) return } - supportsMultiChain := exchanges[x].GetBase().Features.Supports.RESTCapabilities.MultiChainDeposits - requiresChainSet := exchanges[x].GetBase().Features.Supports.RESTCapabilities.MultiChainDepositRequiresChainSet + supportsMultiChain := exch.GetBase().Features.Supports.RESTCapabilities.MultiChainDeposits + requiresChainSet := exch.GetBase().Features.Supports.RESTCapabilities.MultiChainDepositRequiresChainSet cryptoAddr := make(map[string][]deposit.Address) for y := range cryptoCurrencies { cryptocurrency := cryptoCurrencies[y] isSingular := false var depositAddrs []deposit.Address if supportsMultiChain { - availChains, err := exchanges[x].GetAvailableTransferChains(context.TODO(), currency.NewCode(cryptocurrency)) + availChains, err := exch.GetAvailableTransferChains(context.TODO(), currency.NewCode(cryptocurrency)) if err != nil { log.Errorf(log.Global, "%s failed to get cryptocurrency available transfer chains. Err: %s\n", exchName, err) continue @@ -728,7 +728,7 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map // store the default non-chain specified address for a specified crypto chainContainsItself := common.StringDataCompareInsensitive(availChains, cryptocurrency) if !chainContainsItself && !requiresChainSet { - depositAddr, err := exchanges[x].GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", "") + depositAddr, err := exch.GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", "") if err != nil { log.Errorf(log.Global, "%s failed to get cryptocurrency deposit address for %s. Err: %s\n", exchName, @@ -740,7 +740,7 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map depositAddrs = append(depositAddrs, *depositAddr) } for z := range availChains { - depositAddr, err := exchanges[x].GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", availChains[z]) + depositAddr, err := exch.GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", availChains[z]) if err != nil { log.Errorf(log.Global, "%s failed to get cryptocurrency deposit address for %s [chain %s]. Err: %s\n", exchName, @@ -759,7 +759,7 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map } if !supportsMultiChain || isSingular { - depositAddr, err := exchanges[x].GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", "") + depositAddr, err := exch.GetDepositAddress(context.TODO(), currency.NewCode(cryptocurrency), "", "") if err != nil { log.Errorf(log.Global, "%s failed to get cryptocurrency deposit address for %s. Err: %s\n", exchName, @@ -774,7 +774,7 @@ func (bot *Engine) GetAllExchangeCryptocurrencyDepositAddresses() map[string]map m.Lock() result[exchName] = cryptoAddr m.Unlock() - }(x) + }(exchanges[x]) } depositSyncer.Wait() if len(result) > 0 { diff --git a/engine/helpers_test.go b/engine/helpers_test.go index 4babb96b..11565032 100644 --- a/engine/helpers_test.go +++ b/engine/helpers_test.go @@ -1006,10 +1006,6 @@ func (f fakeDepositExchange) GetName() string { return "fake" } -func (f fakeDepositExchange) GetAuthenticatedAPISupport(endpoint uint8) bool { - return f.SupportsAuth -} - func (f fakeDepositExchange) GetBase() *exchange.Base { return &exchange.Base{ Features: exchange.Features{Supports: exchange.FeaturesSupported{ @@ -1021,6 +1017,10 @@ func (f fakeDepositExchange) GetBase() *exchange.Base { } } +func (f fakeDepositExchange) IsRESTAuthenticationSupported() bool { + return f.SupportsAuth +} + func (f fakeDepositExchange) GetAvailableTransferChains(_ context.Context, c currency.Code) ([]string, error) { if f.ThrowTransferChainError { return nil, errors.New("unable to get available transfer chains") diff --git a/engine/order_manager.go b/engine/order_manager.go index f2cc024f..54da6296 100644 --- a/engine/order_manager.go +++ b/engine/order_manager.go @@ -642,7 +642,7 @@ func (m *OrderManager) processOrders() { } var wg sync.WaitGroup for i := range exchanges { - if !exchanges[i].GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !exchanges[i].IsRESTAuthenticationSupported() { continue } log.Debugf(log.OrderMgr, diff --git a/engine/portfolio_manager.go b/engine/portfolio_manager.go index 0ce4d27b..7bda1633 100644 --- a/engine/portfolio_manager.go +++ b/engine/portfolio_manager.go @@ -247,7 +247,7 @@ func (m *portfolioManager) getExchangeAccountInfo(exchanges []exchange.IBotExcha if !exchanges[x].IsEnabled() { continue } - if !exchanges[x].GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !exchanges[x].IsRESTAuthenticationSupported() { if m.base.Verbose { log.Debugf(log.PortfolioMgr, "skipping %s due to disabled authenticated API support.\n", diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 465b7481..29a9b7e2 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -1570,7 +1570,7 @@ func (s *RPCServer) GetCryptocurrencyDepositAddresses(ctx context.Context, r *gc return nil, err } - if !exch.GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !exch.IsRESTAuthenticationSupported() { return nil, fmt.Errorf("%s, %w", r.Exchange, exchange.ErrAuthenticationSupportNotEnabled) } @@ -1603,7 +1603,7 @@ func (s *RPCServer) GetCryptocurrencyDepositAddress(ctx context.Context, r *gctr return nil, err } - if !exch.GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !exch.IsRESTAuthenticationSupported() { return nil, fmt.Errorf("%s, %w", r.Exchange, exchange.ErrAuthenticationSupportNotEnabled) } @@ -4362,7 +4362,7 @@ func (s *RPCServer) GetCollateral(ctx context.Context, r *gctrpc.GetCollateralRe if err != nil { return nil, err } - creds, err := exch.GetBase().GetCredentials(ctx) + creds, err := exch.GetCredentials(ctx) if err != nil { return nil, err } diff --git a/exchanges/bittrex/bittrex_websocket.go b/exchanges/bittrex/bittrex_websocket.go index 17f368f2..b9fceaf6 100644 --- a/exchanges/bittrex/bittrex_websocket.go +++ b/exchanges/bittrex/bittrex_websocket.go @@ -117,7 +117,7 @@ func (b *Bittrex) WsConnect() error { Tickers: make(map[string]*TickerData), } - if b.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if b.IsWebsocketAuthenticationSupported() { err = b.WsAuth(context.TODO()) if err != nil { b.Websocket.DataHandler <- err @@ -217,7 +217,7 @@ func (b *Bittrex) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, } channels := defaultSpotSubscribedChannels - if b.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if b.IsWebsocketAuthenticationSupported() { channels = append(channels, defaultSpotSubscribedChannelsAuth...) } diff --git a/exchanges/btse/btse_websocket.go b/exchanges/btse/btse_websocket.go index aec8f318..d6c6a787 100644 --- a/exchanges/btse/btse_websocket.go +++ b/exchanges/btse/btse_websocket.go @@ -13,7 +13,6 @@ import ( "github.com/gorilla/websocket" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -45,7 +44,7 @@ func (b *BTSE) WsConnect() error { b.Websocket.Wg.Add(1) go b.wsReadData() - if b.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if b.IsWebsocketAuthenticationSupported() { err = b.WsAuthenticate(context.TODO()) if err != nil { b.Websocket.DataHandler <- err diff --git a/exchanges/coinbasepro/coinbasepro_websocket.go b/exchanges/coinbasepro/coinbasepro_websocket.go index bf5fcef8..6626b5b4 100644 --- a/exchanges/coinbasepro/coinbasepro_websocket.go +++ b/exchanges/coinbasepro/coinbasepro_websocket.go @@ -380,7 +380,7 @@ func (c *CoinbasePro) GenerateDefaultSubscriptions() ([]stream.ChannelSubscripti var subscriptions []stream.ChannelSubscription for i := range channels { if (channels[i] == "user" || channels[i] == "full") && - !c.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + !c.IsWebsocketAuthenticationSupported() { continue } for j := range enabledCurrencies { @@ -403,7 +403,7 @@ func (c *CoinbasePro) GenerateDefaultSubscriptions() ([]stream.ChannelSubscripti func (c *CoinbasePro) Subscribe(channelsToSubscribe []stream.ChannelSubscription) error { var creds *exchange.Credentials var err error - if c.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if c.IsWebsocketAuthenticationSupported() { creds, err = c.GetCredentials(context.TODO()) if err != nil { return err diff --git a/exchanges/credentials.go b/exchanges/credentials.go index ed90921c..4806962a 100644 --- a/exchanges/credentials.go +++ b/exchanges/credentials.go @@ -412,14 +412,14 @@ func (b *Base) SetAPICredentialDefaults() { } } -// GetAuthenticatedAPISupport returns whether the exchange supports -// authenticated API requests -func (b *Base) GetAuthenticatedAPISupport(endpoint uint8) bool { - switch endpoint { - case RestAuthentication: - return b.API.AuthenticatedSupport - case WebsocketAuthentication: - return b.API.AuthenticatedWebsocketSupport - } - return false +// IsWebsocketAuthenticationSupported returns whether the exchange supports +// websocket authenticated API requests +func (b *Base) IsWebsocketAuthenticationSupported() bool { + return b.API.AuthenticatedWebsocketSupport +} + +// IsRESTAuthenticationSupported returns whether the exchange supports REST authenticated +// API requests +func (b *Base) IsRESTAuthenticationSupported() bool { + return b.API.AuthenticatedSupport } diff --git a/exchanges/credentials_test.go b/exchanges/credentials_test.go index d8d704b5..6538504d 100644 --- a/exchanges/credentials_test.go +++ b/exchanges/credentials_test.go @@ -456,19 +456,20 @@ func TestGetAuthenticatedAPISupport(t *testing.T) { }, } - if !base.GetAuthenticatedAPISupport(RestAuthentication) { + if !base.IsRESTAuthenticationSupported() { t.Fatal("Expected RestAuthentication to return true") } - if base.GetAuthenticatedAPISupport(WebsocketAuthentication) { + base.API.AuthenticatedSupport = false + if base.IsRESTAuthenticationSupported() { + t.Fatal("Expected RestAuthentication to return false") + } + if base.IsWebsocketAuthenticationSupported() { t.Fatal("Expected WebsocketAuthentication to return false") } base.API.AuthenticatedWebsocketSupport = true - if !base.GetAuthenticatedAPISupport(WebsocketAuthentication) { + if !base.IsWebsocketAuthenticationSupported() { t.Fatal("Expected WebsocketAuthentication to return true") } - if base.GetAuthenticatedAPISupport(2) { - t.Fatal("Expected default case of 'false' to be returned") - } } func TestIsEmpty(t *testing.T) { diff --git a/exchanges/exchange_types.go b/exchanges/exchange_types.go index 7e514dfa..0e914607 100644 --- a/exchanges/exchange_types.go +++ b/exchanges/exchange_types.go @@ -17,8 +17,6 @@ import ( // Endpoint authentication types const ( - RestAuthentication uint8 = 0 - WebsocketAuthentication uint8 = 1 // Repeated exchange strings // FeeType custom type for calculating fees based on method WireTransfer InternationalBankTransactionType = iota diff --git a/exchanges/ftx/ftx.go b/exchanges/ftx/ftx.go index 1f1f3a14..552b997b 100644 --- a/exchanges/ftx/ftx.go +++ b/exchanges/ftx/ftx.go @@ -1290,7 +1290,7 @@ func (f *FTX) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, method, // GetFee returns an estimate of fee based on type of transaction func (f *FTX) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 - if !f.GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !f.IsRESTAuthenticationSupported() { feeBuilder.FeeType = exchange.OfflineTradeFee } switch feeBuilder.FeeType { @@ -1697,7 +1697,7 @@ func (f *FTX) LoadCollateralWeightings(ctx context.Context) error { f.collateralWeight.load("ZM", 0.9, 0.85, 0.01) f.collateralWeight.load("ZRX", 0.85, 0.8, 0.001) - if !f.GetAuthenticatedAPISupport(exchange.RestAuthentication) { + if !f.IsRESTAuthenticationSupported() { return nil } coins, err := f.GetCoins(ctx) diff --git a/exchanges/ftx/ftx_websocket.go b/exchanges/ftx/ftx_websocket.go index a400be63..10ca2439 100644 --- a/exchanges/ftx/ftx_websocket.go +++ b/exchanges/ftx/ftx_websocket.go @@ -15,7 +15,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/fill" "github.com/thrasher-corp/gocryptotrader/exchanges/order" @@ -64,7 +63,7 @@ func (f *FTX) WsConnect() error { f.Websocket.Wg.Add(1) go f.wsReadData() - if f.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if f.IsWebsocketAuthenticationSupported() { err = f.WsAuth(context.TODO()) if err != nil { f.Websocket.DataHandler <- err @@ -206,7 +205,7 @@ func (f *FTX) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, erro } } } - if f.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if f.IsWebsocketAuthenticationSupported() { var authchan = []string{wsOrders, wsFills} for x := range authchan { subscriptions = append(subscriptions, stream.ChannelSubscription{ diff --git a/exchanges/gateio/gateio_websocket.go b/exchanges/gateio/gateio_websocket.go index 7a0afcbf..2e4b4c4d 100644 --- a/exchanges/gateio/gateio_websocket.go +++ b/exchanges/gateio/gateio_websocket.go @@ -15,7 +15,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common/convert" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -43,7 +42,7 @@ func (g *Gateio) WsConnect() error { g.Websocket.Wg.Add(1) go g.wsReadData() - if g.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if g.IsWebsocketAuthenticationSupported() { err = g.wsServerSignIn(context.TODO()) if err != nil { g.Websocket.DataHandler <- err diff --git a/exchanges/gemini/gemini_websocket.go b/exchanges/gemini/gemini_websocket.go index ce2791cb..48f9d0ef 100644 --- a/exchanges/gemini/gemini_websocket.go +++ b/exchanges/gemini/gemini_websocket.go @@ -177,7 +177,7 @@ func (g *Gemini) Unsubscribe(channelsToUnsubscribe []stream.ChannelSubscription) // WsAuth will connect to Gemini's secure endpoint func (g *Gemini) WsAuth(ctx context.Context, dialer *websocket.Dialer) error { - if !g.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !g.IsWebsocketAuthenticationSupported() { return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", g.Name) } creds, err := g.GetCredentials(ctx) diff --git a/exchanges/hitbtc/hitbtc_websocket.go b/exchanges/hitbtc/hitbtc_websocket.go index 61863763..de56ebb2 100644 --- a/exchanges/hitbtc/hitbtc_websocket.go +++ b/exchanges/hitbtc/hitbtc_websocket.go @@ -14,7 +14,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -566,7 +565,7 @@ func (h *HitBTC) Unsubscribe(channelsToUnsubscribe []stream.ChannelSubscription) // Unsubscribe sends a websocket message to stop receiving data from the channel func (h *HitBTC) wsLogin(ctx context.Context) error { - if !h.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !h.IsWebsocketAuthenticationSupported() { return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) } creds, err := h.GetCredentials(ctx) diff --git a/exchanges/huobi/huobi_websocket.go b/exchanges/huobi/huobi_websocket.go index 12d3000f..230c3835 100644 --- a/exchanges/huobi/huobi_websocket.go +++ b/exchanges/huobi/huobi_websocket.go @@ -103,7 +103,7 @@ func (h *HUOBI) wsDial(dialer *websocket.Dialer) error { } func (h *HUOBI) wsAuthenticatedDial(dialer *websocket.Dialer) error { - if !h.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !h.IsWebsocketAuthenticationSupported() { return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) } @@ -636,7 +636,7 @@ func (h *HUOBI) wsGenerateSignature(creds *exchange.Credentials, timestamp, endp } func (h *HUOBI) wsLogin(ctx context.Context) error { - if !h.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !h.IsWebsocketAuthenticationSupported() { return fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", h.Name) } creds, err := h.GetCredentials(ctx) diff --git a/exchanges/interfaces.go b/exchanges/interfaces.go index 1c060ac7..a4847954 100644 --- a/exchanges/interfaces.go +++ b/exchanges/interfaces.go @@ -27,9 +27,7 @@ type IBotExchange interface { Start(wg *sync.WaitGroup) error SetDefaults() GetName() string - IsEnabled() bool SetEnabled(bool) - ValidateCredentials(ctx context.Context, a asset.Item) error FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) UpdateTickers(ctx context.Context, a asset.Item) error @@ -39,18 +37,14 @@ type IBotExchange interface { UpdateTradablePairs(ctx context.Context, forceUpdate bool) error GetEnabledPairs(a asset.Item) (currency.Pairs, error) GetAvailablePairs(a asset.Item) (currency.Pairs, error) - GetAuthenticatedAPISupport(endpoint uint8) bool SetPairs(pairs currency.Pairs, a asset.Item, enabled bool) error GetAssetTypes(enabled bool) asset.Items GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) - SupportsAutoPairUpdates() bool - SupportsRESTTickerBatchUpdates() bool GetFeeByType(ctx context.Context, f *FeeBuilder) (float64, error) GetLastPairsUpdateTime() int64 GetWithdrawPermissions() uint32 FormatWithdrawPermissions() string - SupportsWithdrawPermissions(permissions uint32) bool GetFundingHistory(ctx context.Context) ([]FundHistory, error) OrderManagement @@ -65,11 +59,8 @@ type IBotExchange interface { SetHTTPClientUserAgent(ua string) error GetHTTPClientUserAgent() (string, error) SetClientProxyAddress(addr string) error - SupportsREST() bool - GetSubscriptions() ([]stream.ChannelSubscription, error) GetDefaultConfig() (*config.Exchange, error) GetBase() *Base - SupportsAsset(assetType asset.Item) bool GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) DisableRateLimiter() error @@ -82,11 +73,9 @@ type IBotExchange interface { GetFuturesPositions(context.Context, asset.Item, currency.Pair, time.Time, time.Time) ([]order.Detail, error) GetWebsocket() (*stream.Websocket, error) - IsWebsocketEnabled() bool - SupportsWebsocket() bool SubscribeToWebsocketChannels(channels []stream.ChannelSubscription) error UnsubscribeToWebsocketChannels(channels []stream.ChannelSubscription) error - IsAssetWebsocketSupported(aType asset.Item) bool + GetSubscriptions() ([]stream.ChannelSubscription, error) FlushWebsocketChannels() error AuthenticateWebsocket(ctx context.Context) error @@ -95,6 +84,10 @@ type IBotExchange interface { UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error AccountManagement + GetCredentials(ctx context.Context) (*Credentials, error) + ValidateCredentials(ctx context.Context, a asset.Item) error + + FunctionalityChecker } // OrderManagement defines functionality for order management @@ -125,3 +118,19 @@ type AccountManagement interface { FetchAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) HasAssetTypeAccountSegregation() bool } + +// FunctionalityChecker defines functionality for retrieving exchange +// support/enabled features +type FunctionalityChecker interface { + IsEnabled() bool + IsAssetWebsocketSupported(a asset.Item) bool + SupportsAsset(assetType asset.Item) bool + SupportsREST() bool + SupportsWithdrawPermissions(permissions uint32) bool + SupportsRESTTickerBatchUpdates() bool + IsWebsocketEnabled() bool + SupportsWebsocket() bool + SupportsAutoPairUpdates() bool + IsWebsocketAuthenticationSupported() bool + IsRESTAuthenticationSupported() bool +} diff --git a/exchanges/kraken/kraken_websocket.go b/exchanges/kraken/kraken_websocket.go index 4dfce328..6db06aed 100644 --- a/exchanges/kraken/kraken_websocket.go +++ b/exchanges/kraken/kraken_websocket.go @@ -16,7 +16,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/convert" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -100,7 +99,7 @@ func (k *Kraken) WsConnect() error { go k.wsReadData(comms) go k.wsFunnelConnectionData(k.Websocket.Conn, comms) - if k.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if k.IsWebsocketAuthenticationSupported() { authToken, err = k.GetWebsocketToken(context.TODO()) if err != nil { k.Websocket.SetCanUseAuthenticatedEndpoints(false) diff --git a/exchanges/okgroup/okgroup_websocket.go b/exchanges/okgroup/okgroup_websocket.go index 008af79b..f5c1a725 100644 --- a/exchanges/okgroup/okgroup_websocket.go +++ b/exchanges/okgroup/okgroup_websocket.go @@ -15,7 +15,6 @@ import ( "github.com/gorilla/websocket" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -195,7 +194,7 @@ func (o *OKGroup) WsConnect() error { o.Websocket.Wg.Add(1) go o.WsReadData() - if o.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if o.IsWebsocketAuthenticationSupported() { err = o.WsLogin(context.TODO()) if err != nil { log.Errorf(log.ExchangeSys, @@ -822,7 +821,7 @@ func (o *OKGroup) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, switch assets[x] { case asset.Spot: channels := defaultSpotSubscribedChannels - if o.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if o.IsWebsocketAuthenticationSupported() { channels = append(channels, okGroupWsSpotMarginAccount, okGroupWsSpotAccount, @@ -845,7 +844,7 @@ func (o *OKGroup) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, } case asset.Futures: channels := defaultFuturesSubscribedChannels - if o.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if o.IsWebsocketAuthenticationSupported() { channels = append(channels, okGroupWsFuturesAccount, okGroupWsFuturesPosition, @@ -906,7 +905,7 @@ func (o *OKGroup) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, } case asset.PerpetualSwap: channels := defaultSwapSubscribedChannels - if o.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if o.IsWebsocketAuthenticationSupported() { channels = append(channels, okGroupWsSwapAccount, okGroupWsSwapPosition, diff --git a/exchanges/poloniex/poloniex_websocket.go b/exchanges/poloniex/poloniex_websocket.go index f3fe220c..1de2061b 100644 --- a/exchanges/poloniex/poloniex_websocket.go +++ b/exchanges/poloniex/poloniex_websocket.go @@ -523,7 +523,7 @@ func (p *Poloniex) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, Channel: strconv.FormatInt(wsTickerDataID, 10), }) - if p.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if p.IsWebsocketAuthenticationSupported() { subscriptions = append(subscriptions, stream.ChannelSubscription{ Channel: strconv.FormatInt(wsAccountNotificationID, 10), }) @@ -543,7 +543,7 @@ func (p *Poloniex) GenerateDefaultSubscriptions() ([]stream.ChannelSubscription, // Subscribe sends a websocket message to receive data from the channel func (p *Poloniex) Subscribe(sub []stream.ChannelSubscription) error { var creds *exchange.Credentials - if p.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if p.IsWebsocketAuthenticationSupported() { var err error creds, err = p.GetCredentials(context.TODO()) if err != nil { @@ -590,7 +590,7 @@ channels: // Unsubscribe sends a websocket message to stop receiving data from the channel func (p *Poloniex) Unsubscribe(unsub []stream.ChannelSubscription) error { var creds *exchange.Credentials - if p.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if p.IsWebsocketAuthenticationSupported() { var err error creds, err = p.GetCredentials(context.TODO()) if err != nil { diff --git a/exchanges/sharedtestvalues/customex.go b/exchanges/sharedtestvalues/customex.go index 25286add..1e6b6bb1 100644 --- a/exchanges/sharedtestvalues/customex.go +++ b/exchanges/sharedtestvalues/customex.go @@ -94,10 +94,6 @@ func (c *CustomEx) UpdateAccountInfo(ctx context.Context, a asset.Item) (account return account.Holdings{}, nil } -func (c *CustomEx) GetAuthenticatedAPISupport(endpoint uint8) bool { - return false -} - func (c *CustomEx) SetPairs(pairs currency.Pairs, a asset.Item, enabled bool) error { return nil } diff --git a/exchanges/zb/zb_websocket.go b/exchanges/zb/zb_websocket.go index 98320638..5c257894 100644 --- a/exchanges/zb/zb_websocket.go +++ b/exchanges/zb/zb_websocket.go @@ -15,7 +15,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" @@ -352,7 +351,7 @@ func (z *ZB) wsFixInvalidJSON(json []byte) []byte { } func (z *ZB) wsAddSubUser(ctx context.Context, username, password string) (*WsGetSubUserListResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } creds, err := z.GetCredentials(ctx) @@ -398,7 +397,7 @@ func (z *ZB) wsAddSubUser(ctx context.Context, username, password string) (*WsGe } func (z *ZB) wsGetSubUserList(ctx context.Context) (*WsGetSubUserListResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -437,7 +436,7 @@ func (z *ZB) wsGetSubUserList(ctx context.Context) (*WsGetSubUserListResponse, e } func (z *ZB) wsDoTransferFunds(ctx context.Context, pair currency.Code, amount float64, fromUserName, toUserName string) (*WsRequestResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -481,7 +480,7 @@ func (z *ZB) wsDoTransferFunds(ctx context.Context, pair currency.Code, amount f } func (z *ZB) wsCreateSubUserKey(ctx context.Context, assetPerm, entrustPerm, leverPerm, moneyPerm bool, keyName, toUserID string) (*WsRequestResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -527,7 +526,7 @@ func (z *ZB) wsCreateSubUserKey(ctx context.Context, assetPerm, entrustPerm, lev } func (z *ZB) wsSubmitOrder(ctx context.Context, pair currency.Pair, amount, price float64, tradeType int64) (*WsSubmitOrderResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -569,7 +568,7 @@ func (z *ZB) wsSubmitOrder(ctx context.Context, pair currency.Pair, amount, pric } func (z *ZB) wsCancelOrder(ctx context.Context, pair currency.Pair, orderID int64) (*WsCancelOrderResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -611,7 +610,7 @@ func (z *ZB) wsCancelOrder(ctx context.Context, pair currency.Pair, orderID int6 } func (z *ZB) wsGetOrder(ctx context.Context, pair currency.Pair, orderID int64) (*WsGetOrderResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -651,7 +650,7 @@ func (z *ZB) wsGetOrder(ctx context.Context, pair currency.Pair, orderID int64) } func (z *ZB) wsGetOrders(ctx context.Context, pair currency.Pair, pageIndex, tradeType int64) (*WsGetOrdersResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -694,7 +693,7 @@ func (z *ZB) wsGetOrders(ctx context.Context, pair currency.Pair, pageIndex, tra } func (z *ZB) wsGetOrdersIgnoreTradeType(ctx context.Context, pair currency.Pair, pageIndex, pageSize int64) (*WsGetOrdersIgnoreTradeTypeResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) } @@ -736,7 +735,7 @@ func (z *ZB) wsGetOrdersIgnoreTradeType(ctx context.Context, pair currency.Pair, } func (z *ZB) wsGetAccountInfoRequest(ctx context.Context) (*WsGetAccountInfoResponse, error) { - if !z.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { + if !z.IsWebsocketAuthenticationSupported() { return nil, fmt.Errorf("%v AuthenticatedWebsocketAPISupport not enabled", z.Name) }