mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-01 15:10:44 +00:00
accounts: Move to instance methods, fix races and isolate tests (#1923)
* Bybit: Fix race in TestUpdateAccountInfo and TestWSHandleData * DriveBy rename TestWSHandleData * This doesn't address running with -race=2+ due to the singleton * Accounts: Add account.GetService() * exchange: Assertify TestSetupDefaults * Exchanges: Add account.Service override for testing * Exchanges: Remove duplicate IsWebsocketEnabled test from TestSetupDefaults * Dispatch: Replace nil checks with NilGuard * Engine: Remove deprecated printAccountHoldingsChangeSummary * Dispatcher: Add EnsureRunning method * Accounts: Move singleton accounts service to exchange Accounts * Move singleton accounts service to exchange Accounts This maintains the concept of a global store, whilst allowing exchanges to override it when needed, particularly for testing. APIServer: * Remove getAllActiveAccounts from apiserver Deprecated apiserver only thing using this, so remove it instead of updating it * Update comment for UpdateAccountBalances everywhere * Docs: Add punctuation to function comments * Bybit: Coverage for wsProcessWalletPushData Save
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package huobi
|
||||
|
||||
import "github.com/thrasher-corp/gocryptotrader/types"
|
||||
import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// WsSwapReqKline stores req kline data for swap websocket
|
||||
type WsSwapReqKline struct {
|
||||
@@ -631,20 +634,20 @@ type BasisData struct {
|
||||
// SwapAccountInformation stores swap account information
|
||||
type SwapAccountInformation struct {
|
||||
Data []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
ContractCode string `json:"contract_code"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
Symbol currency.Code `json:"symbol"`
|
||||
ContractCode string `json:"contract_code"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
@@ -724,20 +727,20 @@ type SubAccountsAssetData struct {
|
||||
type SingleSubAccountAssetsInfo struct {
|
||||
Timestamp types.Time `json:"ts"`
|
||||
Data []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
ContractCode string `json:"contract_code"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
Symbol currency.Code `json:"symbol"`
|
||||
ContractCode string `json:"contract_code"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package huobi
|
||||
|
||||
import "github.com/thrasher-corp/gocryptotrader/types"
|
||||
import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/types"
|
||||
)
|
||||
|
||||
// FContractInfoData gets contract info data for futures
|
||||
type FContractInfoData struct {
|
||||
@@ -311,19 +314,19 @@ type FBasisData struct {
|
||||
// FUserAccountData stores user account data info for futures
|
||||
type FUserAccountData struct {
|
||||
AccData []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
Symbol currency.Code `json:"symbol"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
} `json:"data"`
|
||||
Timestamp types.Time `json:"ts"`
|
||||
}
|
||||
@@ -367,19 +370,19 @@ type FSubAccountAssetsInfo struct {
|
||||
// FSingleSubAccountAssetsInfo stores futures assets info for a single subaccount
|
||||
type FSingleSubAccountAssetsInfo struct {
|
||||
AssetsData []struct {
|
||||
Symbol string `json:"symbol"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
Symbol currency.Code `json:"symbol"`
|
||||
MarginBalance float64 `json:"margin_balance"`
|
||||
MarginPosition float64 `json:"margin_position"`
|
||||
MarginFrozen float64 `json:"margin_frozen"`
|
||||
MarginAvailable float64 `json:"margin_available"`
|
||||
ProfitReal float64 `json:"profit_real"`
|
||||
ProfitUnreal float64 `json:"profit_unreal"`
|
||||
WithdrawAvailable float64 `json:"withdraw_available"`
|
||||
RiskRate float64 `json:"risk_rate"`
|
||||
LiquidationPrice float64 `json:"liquidation_price"`
|
||||
AdjustFactor float64 `json:"adjust_factor"`
|
||||
LeverageRate float64 `json:"lever_rate"`
|
||||
MarginStatic float64 `json:"margin_static"`
|
||||
} `json:"data"`
|
||||
Timestamp types.Time `json:"ts"`
|
||||
}
|
||||
|
||||
@@ -1211,12 +1211,12 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestUpdateAccountInfo(t *testing.T) {
|
||||
func TestUpdateAccountBalances(t *testing.T) {
|
||||
t.Parallel()
|
||||
sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders)
|
||||
for _, a := range []asset.Item{asset.Spot, asset.CoinMarginedFutures, asset.Futures} {
|
||||
_, err := e.UpdateAccountInfo(t.Context(), a)
|
||||
assert.NoErrorf(t, err, "UpdateAccountInfo should not error for asset %s", a)
|
||||
_, err := e.UpdateAccountBalances(t.Context(), a)
|
||||
assert.NoErrorf(t, err, "UpdateAccountBalances should not error for asset %s", a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -655,9 +655,9 @@ type AccountBalance struct {
|
||||
|
||||
// AccountBalanceDetail stores the user account balance
|
||||
type AccountBalanceDetail struct {
|
||||
Currency string `json:"currency"`
|
||||
Type string `json:"type"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
Currency currency.Code `json:"currency"`
|
||||
Type string `json:"type"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
}
|
||||
|
||||
// AggregatedBalance stores balances of all the sub-account
|
||||
@@ -743,8 +743,7 @@ type MarginAccountBalance struct {
|
||||
List []AccountBalance `json:"list"`
|
||||
}
|
||||
|
||||
// SpotNewOrderRequestParams holds the params required to place
|
||||
// an order
|
||||
// SpotNewOrderRequestParams holds the params required to place an order
|
||||
type SpotNewOrderRequestParams struct {
|
||||
AccountID int `json:"account-id,string"` // Account ID, obtained using the accounts method. Currency trades use the accountid of the ‘spot’ account; for loan asset transactions, please use the accountid of the ‘margin’ account.
|
||||
Amount float64 `json:"amount"` // The limit price indicates the quantity of the order, the market price indicates how much to buy when the order is paid, and the market price indicates how much the coin is sold when the order is sold.
|
||||
|
||||
@@ -18,8 +18,8 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/encoding/json"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchange/accounts"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchange/websocket"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
@@ -555,7 +555,7 @@ func (e *Exchange) manageSubs(ctx context.Context, op string, subs subscription.
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *Exchange) wsGenerateSignature(creds *account.Credentials, timestamp string) ([]byte, error) {
|
||||
func (e *Exchange) wsGenerateSignature(creds *accounts.Credentials, timestamp string) ([]byte, error) {
|
||||
values := url.Values{}
|
||||
values.Set("accessKey", creds.Key)
|
||||
values.Set("signatureMethod", signatureMethod)
|
||||
|
||||
@@ -15,9 +15,9 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/common/key"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchange/accounts"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchange/websocket"
|
||||
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/fundingrate"
|
||||
@@ -653,161 +653,102 @@ func (e *Exchange) GetAccountID(ctx context.Context) ([]Account, error) {
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
// UpdateAccountInfo retrieves balances for all enabled currencies for the
|
||||
// HUOBI exchange - to-do
|
||||
func (e *Exchange) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) {
|
||||
var info account.Holdings
|
||||
var acc account.SubAccount
|
||||
info.Exchange = e.Name
|
||||
// UpdateAccountBalances retrieves currency balances
|
||||
func (e *Exchange) UpdateAccountBalances(ctx context.Context, assetType asset.Item) (subAccts accounts.SubAccounts, err error) {
|
||||
switch assetType {
|
||||
case asset.Spot:
|
||||
accounts, err := e.GetAccountID(ctx)
|
||||
resp, err := e.GetAccountID(ctx)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
for i := range accounts {
|
||||
if accounts[i].Type != "spot" {
|
||||
subAccts = make(accounts.SubAccounts, 0, len(resp))
|
||||
for i := range resp {
|
||||
if resp[i].Type != "spot" {
|
||||
continue
|
||||
}
|
||||
acc.ID = strconv.FormatInt(accounts[i].ID, 10)
|
||||
balances, err := e.GetAccountBalance(ctx, acc.ID)
|
||||
a := accounts.NewSubAccount(assetType, strconv.FormatInt(resp[i].ID, 10))
|
||||
balances, err := e.GetAccountBalance(ctx, a.ID)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var currencyDetails []account.Balance
|
||||
balance:
|
||||
for j := range balances {
|
||||
frozen := balances[j].Type == "frozen"
|
||||
for i := range currencyDetails {
|
||||
if currencyDetails[i].Currency.String() == balances[j].Currency {
|
||||
if frozen {
|
||||
currencyDetails[i].Hold = balances[j].Balance
|
||||
} else {
|
||||
currencyDetails[i].Total = balances[j].Balance
|
||||
}
|
||||
continue balance
|
||||
}
|
||||
}
|
||||
|
||||
if frozen {
|
||||
currencyDetails = append(currencyDetails,
|
||||
account.Balance{
|
||||
Currency: currency.NewCode(balances[j].Currency),
|
||||
Hold: balances[j].Balance,
|
||||
})
|
||||
if balances[j].Type == "frozen" {
|
||||
err = a.Balances.Add(balances[j].Currency, accounts.Balance{Hold: balances[j].Balance})
|
||||
} else {
|
||||
currencyDetails = append(currencyDetails,
|
||||
account.Balance{
|
||||
Currency: currency.NewCode(balances[j].Currency),
|
||||
Total: balances[j].Balance,
|
||||
})
|
||||
err = a.Balances.Add(balances[j].Currency, accounts.Balance{Total: balances[j].Balance})
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
acc.Currencies = currencyDetails
|
||||
subAccts = subAccts.Merge(a)
|
||||
}
|
||||
|
||||
case asset.CoinMarginedFutures:
|
||||
// fetch swap account info
|
||||
acctInfo, err := e.GetSwapAccountInfo(ctx, currency.EMPTYPAIR)
|
||||
mainResp, err := e.GetSwapAccountInfo(ctx, currency.EMPTYPAIR)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mainAcctBalances []account.Balance
|
||||
for x := range acctInfo.Data {
|
||||
mainAcctBalances = append(mainAcctBalances, account.Balance{
|
||||
Currency: currency.NewCode(acctInfo.Data[x].Symbol),
|
||||
Total: acctInfo.Data[x].MarginBalance,
|
||||
Hold: acctInfo.Data[x].MarginFrozen,
|
||||
Free: acctInfo.Data[x].MarginAvailable,
|
||||
subAccts = accounts.SubAccounts{accounts.NewSubAccount(assetType, "")}
|
||||
for i := range mainResp.Data {
|
||||
subAccts[0].Balances.Set(mainResp.Data[i].Symbol, accounts.Balance{
|
||||
Total: mainResp.Data[i].MarginBalance,
|
||||
Hold: mainResp.Data[i].MarginFrozen,
|
||||
Free: mainResp.Data[i].MarginAvailable,
|
||||
})
|
||||
}
|
||||
|
||||
info.Accounts = append(info.Accounts, account.SubAccount{
|
||||
Currencies: mainAcctBalances,
|
||||
AssetType: assetType,
|
||||
})
|
||||
|
||||
// fetch subaccounts data
|
||||
subAccsData, err := e.GetSwapAllSubAccAssets(ctx, currency.EMPTYPAIR)
|
||||
subResp, err := e.GetSwapAllSubAccAssets(ctx, currency.EMPTYPAIR)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
var currencyDetails []account.Balance
|
||||
for x := range subAccsData.Data {
|
||||
a, err := e.SwapSingleSubAccAssets(ctx,
|
||||
currency.EMPTYPAIR,
|
||||
subAccsData.Data[x].SubUID)
|
||||
for i := range subResp.Data {
|
||||
resp, err := e.SwapSingleSubAccAssets(ctx, currency.EMPTYPAIR, subResp.Data[i].SubUID)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
for y := range a.Data {
|
||||
currencyDetails = append(currencyDetails, account.Balance{
|
||||
Currency: currency.NewCode(a.Data[y].Symbol),
|
||||
Total: a.Data[y].MarginBalance,
|
||||
Hold: a.Data[y].MarginFrozen,
|
||||
Free: a.Data[y].MarginAvailable,
|
||||
a := accounts.NewSubAccount(assetType, strconv.FormatInt(subResp.Data[i].SubUID, 10))
|
||||
for j := range resp.Data {
|
||||
a.Balances.Set(resp.Data[j].Symbol, accounts.Balance{
|
||||
Total: resp.Data[j].MarginBalance,
|
||||
Hold: resp.Data[j].MarginFrozen,
|
||||
Free: resp.Data[j].MarginAvailable,
|
||||
})
|
||||
}
|
||||
subAccts = subAccts.Merge(a)
|
||||
}
|
||||
acc.Currencies = currencyDetails
|
||||
case asset.Futures:
|
||||
// fetch main account data
|
||||
mainAcctData, err := e.FGetAccountInfo(ctx, currency.EMPTYCODE)
|
||||
mainResp, err := e.FGetAccountInfo(ctx, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mainAcctBalances []account.Balance
|
||||
for x := range mainAcctData.AccData {
|
||||
mainAcctBalances = append(mainAcctBalances, account.Balance{
|
||||
Currency: currency.NewCode(mainAcctData.AccData[x].Symbol),
|
||||
Total: mainAcctData.AccData[x].MarginBalance,
|
||||
Hold: mainAcctData.AccData[x].MarginFrozen,
|
||||
Free: mainAcctData.AccData[x].MarginAvailable,
|
||||
subAccts = accounts.SubAccounts{accounts.NewSubAccount(assetType, "")}
|
||||
for i := range mainResp.AccData {
|
||||
subAccts[0].Balances.Set(mainResp.AccData[i].Symbol, accounts.Balance{
|
||||
Total: mainResp.AccData[i].MarginBalance,
|
||||
Hold: mainResp.AccData[i].MarginFrozen,
|
||||
Free: mainResp.AccData[i].MarginAvailable,
|
||||
})
|
||||
}
|
||||
|
||||
info.Accounts = append(info.Accounts, account.SubAccount{
|
||||
Currencies: mainAcctBalances,
|
||||
AssetType: assetType,
|
||||
})
|
||||
|
||||
// fetch subaccounts data
|
||||
subAccsData, err := e.FGetAllSubAccountAssets(ctx, currency.EMPTYCODE)
|
||||
subResp, err := e.FGetAllSubAccountAssets(ctx, currency.EMPTYCODE)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
var currencyDetails []account.Balance
|
||||
for x := range subAccsData.Data {
|
||||
a, err := e.FGetSingleSubAccountInfo(ctx,
|
||||
"",
|
||||
strconv.FormatInt(subAccsData.Data[x].SubUID, 10))
|
||||
for i := range subResp.Data {
|
||||
a := accounts.NewSubAccount(assetType, strconv.FormatInt(subResp.Data[i].SubUID, 10))
|
||||
resp, err := e.FGetSingleSubAccountInfo(ctx, "", a.ID)
|
||||
if err != nil {
|
||||
return info, err
|
||||
return nil, err
|
||||
}
|
||||
for y := range a.AssetsData {
|
||||
currencyDetails = append(currencyDetails, account.Balance{
|
||||
Currency: currency.NewCode(a.AssetsData[y].Symbol),
|
||||
Total: a.AssetsData[y].MarginBalance,
|
||||
Hold: a.AssetsData[y].MarginFrozen,
|
||||
Free: a.AssetsData[y].MarginAvailable,
|
||||
for j := range resp.AssetsData {
|
||||
a.Balances.Set(resp.AssetsData[j].Symbol, accounts.Balance{
|
||||
Total: resp.AssetsData[j].MarginBalance,
|
||||
Hold: resp.AssetsData[j].MarginFrozen,
|
||||
Free: resp.AssetsData[j].MarginAvailable,
|
||||
})
|
||||
}
|
||||
subAccts = subAccts.Merge(a)
|
||||
}
|
||||
acc.Currencies = currencyDetails
|
||||
}
|
||||
acc.AssetType = assetType
|
||||
info.Accounts = append(info.Accounts, acc)
|
||||
creds, err := e.GetCredentials(ctx)
|
||||
if err != nil {
|
||||
return account.Holdings{}, err
|
||||
}
|
||||
if err := account.Process(&info, creds); err != nil {
|
||||
return info, err
|
||||
}
|
||||
return info, nil
|
||||
return subAccts, e.Accounts.Save(ctx, subAccts, true)
|
||||
}
|
||||
|
||||
// GetAccountFundingHistory returns funding history, deposits and
|
||||
@@ -1793,10 +1734,9 @@ func (e *Exchange) AuthenticateWebsocket(ctx context.Context) error {
|
||||
return e.wsLogin(ctx)
|
||||
}
|
||||
|
||||
// ValidateAPICredentials validates current credentials used for wrapper
|
||||
// functionality
|
||||
// ValidateAPICredentials validates current credentials used for wrapper functionality
|
||||
func (e *Exchange) ValidateAPICredentials(ctx context.Context, assetType asset.Item) error {
|
||||
_, err := e.UpdateAccountInfo(ctx, assetType)
|
||||
_, err := e.UpdateAccountBalances(ctx, assetType)
|
||||
return e.CheckTransientError(err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user