mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 16:55:15 +00:00
ftx:support deposit histories
This commit is contained in:
parent
f84b3a5177
commit
ab743f85c2
97
pkg/cmd/deposit.go
Normal file
97
pkg/cmd/deposit.go
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/bbgo"
|
||||||
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
depositsCmd.Flags().String("session", "", "the exchange session name for querying balances")
|
||||||
|
depositsCmd.Flags().String("asset", "", "the trading pair, like btcusdt")
|
||||||
|
RootCmd.AddCommand(depositsCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// go run ./cmd/bbgo deposits --session=ftx --asset="BTC"
|
||||||
|
// This is a testing util and will query deposits in last 7 days.
|
||||||
|
var depositsCmd = &cobra.Command{
|
||||||
|
Use: "deposits",
|
||||||
|
SilenceUsage: true,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
configFile, err := cmd.Flags().GetString("config")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(configFile) == 0 {
|
||||||
|
return errors.New("--config option is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
// if config file exists, use the config loaded from the config file.
|
||||||
|
// otherwise, use a empty config object
|
||||||
|
var userConfig *bbgo.Config
|
||||||
|
if _, err := os.Stat(configFile); err == nil {
|
||||||
|
// load successfully
|
||||||
|
userConfig, err = bbgo.Load(configFile, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
// config file doesn't exist
|
||||||
|
userConfig = &bbgo.Config{}
|
||||||
|
} else {
|
||||||
|
// other error
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
environ := bbgo.NewEnvironment()
|
||||||
|
|
||||||
|
if err := environ.ConfigureExchangeSessions(userConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionName, err := cmd.Flags().GetString("session")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
session, ok := environ.Session(sessionName)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("session %s not found", sessionName)
|
||||||
|
}
|
||||||
|
|
||||||
|
asset, err := cmd.Flags().GetString("asset")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't get the asset from flags: %w", err)
|
||||||
|
}
|
||||||
|
if asset == "" {
|
||||||
|
return fmt.Errorf("asset is not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
until := time.Now()
|
||||||
|
since := until.Add(-7 * 24 * time.Hour)
|
||||||
|
exchange, ok := session.Exchange.(types.ExchangeTransferService)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("exchange session %s does not implement transfer service", sessionName)
|
||||||
|
}
|
||||||
|
histories, err := exchange.QueryDepositHistory(ctx, asset, since, until)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, h := range histories {
|
||||||
|
log.Infof("deposit history: %+v", h)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
|
@ -3,6 +3,9 @@ package ftx
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/c9s/bbgo/pkg/datatype"
|
"github.com/c9s/bbgo/pkg/datatype"
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
|
@ -73,3 +76,35 @@ func toGlobalOrder(r order) (types.Order, error) {
|
||||||
|
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toGlobalDeposit(input depositHistory) (types.Deposit, error) {
|
||||||
|
s, err := toGlobalDepositStatus(input.Status)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Warnf("assign empty string to the deposit status")
|
||||||
|
}
|
||||||
|
t := input.Time
|
||||||
|
if input.ConfirmedTime != (time.Time{}) {
|
||||||
|
t = input.ConfirmedTime
|
||||||
|
}
|
||||||
|
d := types.Deposit{
|
||||||
|
GID: 0,
|
||||||
|
Exchange: types.ExchangeFTX,
|
||||||
|
Time: datatype.Time(t),
|
||||||
|
Amount: input.Size,
|
||||||
|
Asset: toGlobalCurrency(input.Coin),
|
||||||
|
TransactionID: input.TxID,
|
||||||
|
Status: s,
|
||||||
|
Address: input.Address.Address,
|
||||||
|
AddressTag: input.Address.Tag,
|
||||||
|
}
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toGlobalDepositStatus(input string) (types.DepositStatus, error) {
|
||||||
|
// The document only list `confirmed` status
|
||||||
|
switch input {
|
||||||
|
case "confirmed", "complete":
|
||||||
|
return types.DepositSuccess, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("unsupported status %s", input)
|
||||||
|
}
|
||||||
|
|
|
@ -149,7 +149,27 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []types.Deposit, err error) {
|
func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since, until time.Time) (allDeposits []types.Deposit, err error) {
|
||||||
panic("implement me")
|
if err = verifySinceUntil(since, until); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := e.newRest().DepositHistory(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sort.Slice(resp.Result, func(i, j int) bool {
|
||||||
|
return resp.Result[i].Time.Before(resp.Result[j].Time)
|
||||||
|
})
|
||||||
|
for _, r := range resp.Result {
|
||||||
|
d, err := toGlobalDeposit(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if d.Asset == asset && !since.After(d.Time.Time()) && !until.Before(d.Time.Time()) {
|
||||||
|
allDeposits = append(allDeposits, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error) {
|
func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since, until time.Time) (allWithdraws []types.Withdraw, err error) {
|
||||||
|
@ -212,8 +232,8 @@ func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders [
|
||||||
// symbol, since and until are all optional. FTX can only query by order created time, not updated time.
|
// symbol, since and until are all optional. FTX can only query by order created time, not updated time.
|
||||||
// FTX doesn't support lastOrderID, so we will query by the time range first, and filter by the lastOrderID.
|
// FTX doesn't support lastOrderID, so we will query by the time range first, and filter by the lastOrderID.
|
||||||
func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) (orders []types.Order, err error) {
|
func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since, until time.Time, lastOrderID uint64) (orders []types.Order, err error) {
|
||||||
if since.After(until) {
|
if err := verifySinceUntil(since, until); err != nil {
|
||||||
return nil, fmt.Errorf("since can't be after until")
|
return nil, err
|
||||||
}
|
}
|
||||||
if lastOrderID > 0 {
|
if lastOrderID > 0 {
|
||||||
logger.Warn("FTX doesn't support lastOrderID")
|
logger.Warn("FTX doesn't support lastOrderID")
|
||||||
|
@ -281,3 +301,16 @@ func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticke
|
||||||
func (e *Exchange) QueryTickers(ctx context.Context, symbol ...string) (map[string]types.Ticker, error) {
|
func (e *Exchange) QueryTickers(ctx context.Context, symbol ...string) (map[string]types.Ticker, error) {
|
||||||
panic("implement me")
|
panic("implement me")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func verifySinceUntil(since, until time.Time) error {
|
||||||
|
if since.After(until) {
|
||||||
|
return fmt.Errorf("since can't be greater than until")
|
||||||
|
}
|
||||||
|
if since == (time.Time{}) {
|
||||||
|
return fmt.Errorf("since not found")
|
||||||
|
}
|
||||||
|
if until == (time.Time{}) {
|
||||||
|
return fmt.Errorf("until not found")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/c9s/bbgo/pkg/datatype"
|
||||||
"github.com/c9s/bbgo/pkg/fixedpoint"
|
"github.com/c9s/bbgo/pkg/fixedpoint"
|
||||||
"github.com/c9s/bbgo/pkg/types"
|
"github.com/c9s/bbgo/pkg/types"
|
||||||
)
|
)
|
||||||
|
@ -116,7 +117,7 @@ func TestExchange_QueryClosedOrders(t *testing.T) {
|
||||||
serverURL, err := url.Parse(ts.URL)
|
serverURL, err := url.Parse(ts.URL)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
ex.restEndpoint = serverURL
|
ex.restEndpoint = serverURL
|
||||||
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Time{}, time.Time{}, 100)
|
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Now(), time.Now(), 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
assert.Len(t, resp, 0)
|
assert.Len(t, resp, 0)
|
||||||
|
@ -157,7 +158,7 @@ func TestExchange_QueryClosedOrders(t *testing.T) {
|
||||||
serverURL, err := url.Parse(ts.URL)
|
serverURL, err := url.Parse(ts.URL)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
ex.restEndpoint = serverURL
|
ex.restEndpoint = serverURL
|
||||||
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Time{}, time.Time{}, 100)
|
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Now(), time.Now(), 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resp, 1)
|
assert.Len(t, resp, 1)
|
||||||
assert.Equal(t, "BTC-PERP", resp[0].Symbol)
|
assert.Equal(t, "BTC-PERP", resp[0].Symbol)
|
||||||
|
@ -201,7 +202,7 @@ func TestExchange_QueryClosedOrders(t *testing.T) {
|
||||||
serverURL, err := url.Parse(ts.URL)
|
serverURL, err := url.Parse(ts.URL)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
ex.restEndpoint = serverURL
|
ex.restEndpoint = serverURL
|
||||||
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Time{}, time.Time{}, 100)
|
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Now(), time.Now(), 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resp, 3)
|
assert.Len(t, resp, 3)
|
||||||
|
|
||||||
|
@ -272,7 +273,7 @@ func TestExchange_QueryClosedOrders(t *testing.T) {
|
||||||
serverURL, err := url.Parse(ts.URL)
|
serverURL, err := url.Parse(ts.URL)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
ex.restEndpoint = serverURL
|
ex.restEndpoint = serverURL
|
||||||
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Time{}, time.Time{}, 100)
|
resp, err := ex.QueryClosedOrders(context.Background(), "BTC-PERP", time.Now(), time.Now(), 100)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Len(t, resp, 2)
|
assert.Len(t, resp, 2)
|
||||||
expectedOrderID := []uint64{123, 456}
|
expectedOrderID := []uint64{123, 456}
|
||||||
|
@ -423,3 +424,63 @@ func TestExchange_QueryMarkets(t *testing.T) {
|
||||||
TickSize: 1,
|
TickSize: 1,
|
||||||
}, resp["BTC/USD"])
|
}, resp["BTC/USD"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExchange_QueryDepositHistory(t *testing.T) {
|
||||||
|
respJSON := `
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"coin": "TUSD",
|
||||||
|
"confirmations": 64,
|
||||||
|
"confirmedTime": "2019-03-05T09:56:55.728933+00:00",
|
||||||
|
"fee": 0,
|
||||||
|
"id": 1,
|
||||||
|
"sentTime": "2019-03-05T09:56:55.735929+00:00",
|
||||||
|
"size": 99.0,
|
||||||
|
"status": "confirmed",
|
||||||
|
"time": "2019-03-05T09:56:55.728933+00:00",
|
||||||
|
"txid": "0x8078356ae4b06a036d64747546c274af19581f1c78c510b60505798a7ffcaf1",
|
||||||
|
"address": {"address": "test-addr", "tag": "test-tag"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Fprintln(w, respJSON)
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
ex := NewExchange("", "", "")
|
||||||
|
serverURL, err := url.Parse(ts.URL)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
ex.restEndpoint = serverURL
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
layout := "2006-01-02T15:04:05.999999Z07:00"
|
||||||
|
actualConfirmedTime, err := time.Parse(layout, "2019-03-05T09:56:55.728933+00:00")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
dh, err := ex.QueryDepositHistory(ctx, "TUSD", actualConfirmedTime.Add(-1*time.Hour), actualConfirmedTime.Add(1*time.Hour))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, dh, 1)
|
||||||
|
assert.Equal(t, types.Deposit{
|
||||||
|
Exchange: types.ExchangeFTX,
|
||||||
|
Time: datatype.Time(actualConfirmedTime),
|
||||||
|
Amount: 99.0,
|
||||||
|
Asset: "TUSD",
|
||||||
|
TransactionID: "0x8078356ae4b06a036d64747546c274af19581f1c78c510b60505798a7ffcaf1",
|
||||||
|
Status: types.DepositSuccess,
|
||||||
|
Address: "test-addr",
|
||||||
|
AddressTag: "test-tag",
|
||||||
|
}, dh[0])
|
||||||
|
|
||||||
|
// not in the time range
|
||||||
|
dh, err = ex.QueryDepositHistory(ctx, "TUSD", actualConfirmedTime.Add(1*time.Hour), actualConfirmedTime.Add(2*time.Hour))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, dh, 0)
|
||||||
|
|
||||||
|
// exclude by asset
|
||||||
|
dh, err = ex.QueryDepositHistory(ctx, "BTC", actualConfirmedTime.Add(-1*time.Hour), actualConfirmedTime.Add(1*time.Hour))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Len(t, dh, 0)
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type restRequest struct {
|
type restRequest struct {
|
||||||
*balanceRequest
|
*walletRequest
|
||||||
*orderRequest
|
*orderRequest
|
||||||
*accountRequest
|
*accountRequest
|
||||||
*marketRequest
|
*marketRequest
|
||||||
|
@ -46,7 +46,7 @@ func newRestRequest(c *http.Client, baseURL *url.URL) *restRequest {
|
||||||
|
|
||||||
r.marketRequest = &marketRequest{restRequest: r}
|
r.marketRequest = &marketRequest{restRequest: r}
|
||||||
r.accountRequest = &accountRequest{restRequest: r}
|
r.accountRequest = &accountRequest{restRequest: r}
|
||||||
r.balanceRequest = &balanceRequest{restRequest: r}
|
r.walletRequest = &walletRequest{restRequest: r}
|
||||||
r.orderRequest = &orderRequest{restRequest: r}
|
r.orderRequest = &orderRequest{restRequest: r}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package ftx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type balanceRequest struct {
|
|
||||||
*restRequest
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *balanceRequest) Balances(ctx context.Context) (balances, error) {
|
|
||||||
resp, err := r.
|
|
||||||
Method("GET").
|
|
||||||
ReferenceURL("api/wallet/balances").
|
|
||||||
DoAuthenticatedRequest(ctx)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return balances{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var b balances
|
|
||||||
if err := json.Unmarshal(resp.Body, &b); err != nil {
|
|
||||||
return balances{}, fmt.Errorf("failed to unmarshal balance response body to json: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b, nil
|
|
||||||
}
|
|
|
@ -200,3 +200,57 @@ type orderResponse struct {
|
||||||
|
|
||||||
Result order `json:"result"`
|
Result order `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"result": [
|
||||||
|
{
|
||||||
|
"coin": "TUSD",
|
||||||
|
"confirmations": 64,
|
||||||
|
"confirmedTime": "2019-03-05T09:56:55.728933+00:00",
|
||||||
|
"fee": 0,
|
||||||
|
"id": 1,
|
||||||
|
"sentTime": "2019-03-05T09:56:55.735929+00:00",
|
||||||
|
"size": 99.0,
|
||||||
|
"status": "confirmed",
|
||||||
|
"time": "2019-03-05T09:56:55.728933+00:00",
|
||||||
|
"txid": "0x8078356ae4b06a036d64747546c274af19581f1c78c510b60505798a7ffcaf1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
type depositHistoryResponse struct {
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Result []depositHistory `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type depositHistory struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Coin string `json:"coin"`
|
||||||
|
TxID string `json:"txid"`
|
||||||
|
Address address `json:"address"`
|
||||||
|
Confirmations int64 `json:"confirmations"`
|
||||||
|
ConfirmedTime time.Time `json:"confirmedTime"`
|
||||||
|
Fee float64 `json:"fee"`
|
||||||
|
SentTime time.Time `json:"sentTime"`
|
||||||
|
Size float64 `json:"size"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Time time.Time `json:"time"`
|
||||||
|
Notes string `json:"notes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
{
|
||||||
|
"address": "test123",
|
||||||
|
"tag": null,
|
||||||
|
"method": "ltc",
|
||||||
|
"coin": null
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
type address struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
Tag string `json:"tag"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Coin string `json:"coin"`
|
||||||
|
}
|
||||||
|
|
47
pkg/exchange/ftx/rest_wallet_request.go
Normal file
47
pkg/exchange/ftx/rest_wallet_request.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package ftx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type walletRequest struct {
|
||||||
|
*restRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *walletRequest) DepositHistory(ctx context.Context) (depositHistoryResponse, error) {
|
||||||
|
resp, err := r.
|
||||||
|
Method("GET").
|
||||||
|
ReferenceURL("api/wallet/deposits").
|
||||||
|
DoAuthenticatedRequest(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return depositHistoryResponse{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var d depositHistoryResponse
|
||||||
|
if err := json.Unmarshal(resp.Body, &d); err != nil {
|
||||||
|
return depositHistoryResponse{}, fmt.Errorf("failed to unmarshal deposit history response body to json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *walletRequest) Balances(ctx context.Context) (balances, error) {
|
||||||
|
resp, err := r.
|
||||||
|
Method("GET").
|
||||||
|
ReferenceURL("api/wallet/balances").
|
||||||
|
DoAuthenticatedRequest(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return balances{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var b balances
|
||||||
|
if err := json.Unmarshal(resp.Body, &b); err != nil {
|
||||||
|
return balances{}, fmt.Errorf("failed to unmarshal balance response body to json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import (
|
||||||
type DepositStatus string
|
type DepositStatus string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DepositOther = DepositStatus("")
|
// EMPTY string means not supported
|
||||||
|
|
||||||
DepositPending = DepositStatus("pending")
|
DepositPending = DepositStatus("pending")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user