Skip to content

Commit 5c4ac82

Browse files
authored
Implement subaccount transfer history and refactor user universal transfer (#567)
* feat: add sub-account transfer history api * refactor: update sub-account-transfer-history time argument as int64 instead of time * feat: add list user universal transfer service and update user universal transfer
1 parent 6d8559f commit 5c4ac82

5 files changed

+403
-104
lines changed

v2/client.go

+60
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ type RateLimitInterval string
102102
// AccountType define the account types
103103
type AccountType string
104104

105+
// SubAccountTransferType define the sub account transfer types
106+
type SubAccountTransferType int
107+
108+
// UserUniversalTransferType define the user universal transfer types
109+
type UserUniversalTransferType string
110+
111+
// UserUniversalTransferStatus define the user universal transfer status
112+
type UserUniversalTransferStatusType string
113+
105114
// Endpoints
106115
var (
107116
BaseAPIMainURL = "https://api.binance.com"
@@ -239,6 +248,47 @@ const (
239248
AccountTypeIsolatedMargin AccountType = "ISOLATED_MARGIN"
240249
AccountTypeUSDTFuture AccountType = "USDT_FUTURE"
241250
AccountTypeCoinFuture AccountType = "COIN_FUTURE"
251+
252+
SubAccountTransferTypeTransferIn SubAccountTransferType = 1
253+
SubAccountTransferTypeTransferOut SubAccountTransferType = 2
254+
255+
UserUniversalTransferTypeMainToUmFutures UserUniversalTransferType = "MAIN_UMFUTURE"
256+
UserUniversalTransferTypeMainToCmFutures UserUniversalTransferType = "MAIN_CMFUTURE"
257+
UserUniversalTransferTypeMainToMargin UserUniversalTransferType = "MAIN_MARGIN"
258+
UserUniversalTransferTypeUmFuturesToMain UserUniversalTransferType = "UMFUTURE_MAIN"
259+
UserUniversalTransferTypeUmFuturesToMargin UserUniversalTransferType = "UMFUTURE_MARGIN"
260+
UserUniversalTransferTypeCmFuturesToMain UserUniversalTransferType = "CMFUTURE_MAIN"
261+
UserUniversalTransferTypeMarginToMain UserUniversalTransferType = "MARGIN_MAIN"
262+
UserUniversalTransferTypeMarginToUmFutures UserUniversalTransferType = "MARGIN_UMFUTURE"
263+
UserUniversalTransferTypeMarginToCmFutures UserUniversalTransferType = "MARGIN_CMFUTURE"
264+
UserUniversalTransferTypeCmFuturesToMargin UserUniversalTransferType = "CMFUTURE_MARGIN"
265+
UserUniversalTransferTypeIsolatedMarginToMargin UserUniversalTransferType = "ISOLATEDMARGIN_MARGIN"
266+
UserUniversalTransferTypeMarginToIsolatedMargin UserUniversalTransferType = "MARGIN_ISOLATEDMARGIN"
267+
UserUniversalTransferTypeIsolatedMarginToIsolatedMargin UserUniversalTransferType = "ISOLATEDMARGIN_ISOLATEDMARGIN"
268+
UserUniversalTransferTypeMainToFunding UserUniversalTransferType = "MAIN_FUNDING"
269+
UserUniversalTransferTypeFundingToMain UserUniversalTransferType = "FUNDING_MAIN"
270+
UserUniversalTransferTypeFundingToUmFutures UserUniversalTransferType = "FUNDING_UMFUTURE"
271+
UserUniversalTransferTypeUmFuturesToFunding UserUniversalTransferType = "UMFUTURE_FUNDING"
272+
UserUniversalTransferTypeMarginToFunding UserUniversalTransferType = "MARGIN_FUNDING"
273+
UserUniversalTransferTypeFundingToMargin UserUniversalTransferType = "FUNDING_MARGIN"
274+
UserUniversalTransferTypeFundingToCmFutures UserUniversalTransferType = "FUNDING_CMFUTURE"
275+
UserUniversalTransferTypeCmFuturesToFunding UserUniversalTransferType = "CMFUTURE_FUNDING"
276+
UserUniversalTransferTypeMainToOption UserUniversalTransferType = "MAIN_OPTION"
277+
UserUniversalTransferTypeOptionToMain UserUniversalTransferType = "OPTION_MAIN"
278+
UserUniversalTransferTypeUmFuturesToOption UserUniversalTransferType = "UMFUTURE_OPTION"
279+
UserUniversalTransferTypeOptionToUmFutures UserUniversalTransferType = "OPTION_UMFUTURE"
280+
UserUniversalTransferTypeMarginToOption UserUniversalTransferType = "MARGIN_OPTION"
281+
UserUniversalTransferTypeOptionToMargin UserUniversalTransferType = "OPTION_MARGIN"
282+
UserUniversalTransferTypeFundingToOption UserUniversalTransferType = "FUNDING_OPTION"
283+
UserUniversalTransferTypeOptionToFunding UserUniversalTransferType = "OPTION_FUNDING"
284+
UserUniversalTransferTypeMainToPortfolioMargin UserUniversalTransferType = "MAIN_PORTFOLIO_MARGIN"
285+
UserUniversalTransferTypePortfolioMarginToMain UserUniversalTransferType = "PORTFOLIO_MARGIN_MAIN"
286+
UserUniversalTransferTypeMainToIsolatedMargin UserUniversalTransferType = "MAIN_ISOLATED_MARGIN"
287+
UserUniversalTransferTypeIsolatedMarginToMain UserUniversalTransferType = "ISOLATED_MARGIN_MAIN"
288+
289+
UserUniversalTransferStatusTypePending UserUniversalTransferStatusType = "PENDING"
290+
UserUniversalTransferStatusTypeConfirmed UserUniversalTransferStatusType = "CONFIRMED"
291+
UserUniversalTransferStatusTypeFailed UserUniversalTransferStatusType = "FAILED"
242292
)
243293

244294
func currentTimestamp() int64 {
@@ -1027,3 +1077,13 @@ func (c *Client) NewSubAccountFuturesSummaryV1Service() *SubAccountFuturesSummar
10271077
func (c *Client) NewSubAccountFuturesTransferV1Service() *SubAccountFuturesTransferV1Service {
10281078
return &SubAccountFuturesTransferV1Service{c: c}
10291079
}
1080+
1081+
// NewSubAccountTransferHistoryService Transfer History for Sub-account (For Sub-account)
1082+
func (c *Client) NewSubAccountTransferHistoryService() *SubAccountTransferHistoryService {
1083+
return &SubAccountTransferHistoryService{c: c}
1084+
}
1085+
1086+
// NewListUserUniversalTransferService Query User Universal Transfer History
1087+
func (c *Client) NewListUserUniversalTransferService() *ListUserUniversalTransferService {
1088+
return &ListUserUniversalTransferService{c: c}
1089+
}

v2/subaccount_service.go

+91
Original file line numberDiff line numberDiff line change
@@ -674,3 +674,94 @@ type SubAccountFuturesTransferResponse struct {
674674
// seems api doc bug, return `tranId` as int64 actually in production environment
675675
TranID int64 `json:"tranId"`
676676
}
677+
678+
// Sub-account Transfer History (For Sub-account)
679+
// https://binance-docs.github.io/apidocs/spot/en/#sub-account-transfer-history-for-sub-account
680+
type SubAccountTransferHistoryService struct {
681+
c *Client
682+
asset *string
683+
transferType *SubAccountTransferType
684+
startTime *int64
685+
endTime *int64
686+
limit *int
687+
returnFailHistory *bool
688+
}
689+
690+
func (s *SubAccountTransferHistoryService) Asset(v string) *SubAccountTransferHistoryService {
691+
s.asset = &v
692+
return s
693+
}
694+
695+
func (s *SubAccountTransferHistoryService) TransferType(v SubAccountTransferType) *SubAccountTransferHistoryService {
696+
s.transferType = &v
697+
return s
698+
}
699+
700+
func (s *SubAccountTransferHistoryService) StartTime(v int64) *SubAccountTransferHistoryService {
701+
s.startTime = &v
702+
return s
703+
}
704+
705+
func (s *SubAccountTransferHistoryService) EndTime(v int64) *SubAccountTransferHistoryService {
706+
s.endTime = &v
707+
return s
708+
}
709+
710+
func (s *SubAccountTransferHistoryService) Limit(v int) *SubAccountTransferHistoryService {
711+
s.limit = &v
712+
return s
713+
}
714+
715+
func (s *SubAccountTransferHistoryService) ReturnFailHistory(v bool) *SubAccountTransferHistoryService {
716+
s.returnFailHistory = &v
717+
return s
718+
}
719+
720+
func (s *SubAccountTransferHistoryService) Do(ctx context.Context, opts ...RequestOption) (res []*SubAccountTransferHistory, err error) {
721+
r := &request{
722+
method: http.MethodGet,
723+
endpoint: "/sapi/v1/sub-account/transfer/subUserHistory",
724+
secType: secTypeSigned,
725+
}
726+
if s.asset != nil {
727+
r.setParam("asset", *s.asset)
728+
}
729+
if s.transferType != nil {
730+
r.setParam("type", *s.transferType)
731+
}
732+
if s.startTime != nil {
733+
r.setParam("startTime", *s.startTime)
734+
}
735+
if s.endTime != nil {
736+
r.setParam("endTime", *s.endTime)
737+
}
738+
if s.limit != nil {
739+
r.setParam("limit", *s.limit)
740+
}
741+
if s.returnFailHistory != nil {
742+
r.setParam("returnFailHistory", *s.returnFailHistory)
743+
}
744+
data, err := s.c.callAPI(ctx, r, opts...)
745+
if err != nil {
746+
return nil, err
747+
}
748+
res = make([]*SubAccountTransferHistory, 0)
749+
err = json.Unmarshal(data, &res)
750+
if err != nil {
751+
return nil, err
752+
}
753+
return res, nil
754+
}
755+
756+
type SubAccountTransferHistory struct {
757+
CounterParty string `json:"counterParty"`
758+
Email string `json:"email"`
759+
Type SubAccountTransferType `json:"type"`
760+
Asset string `json:"asset"`
761+
Qty string `json:"qty"`
762+
FromAccountType AccountType `json:"fromAccountType"`
763+
ToAccountType AccountType `json:"toAccountType"`
764+
Status string `json:"status"`
765+
TranID int64 `json:"tranId"`
766+
Time int64 `json:"time"`
767+
}

v2/subaccount_service_test.go

+82
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package binance
22

33
import (
44
"testing"
5+
"time"
56

67
"github.com/stretchr/testify/suite"
78
)
@@ -333,3 +334,84 @@ func (s *subAccountServiceTestSuite) TestSubAccountFuturesTransferService() {
333334
r.Equal(int64(123456789), response.TranID, "TranID")
334335

335336
}
337+
338+
func (s *subAccountServiceTestSuite) TestSubAccountTransferHistoryService() {
339+
data := []byte(`
340+
[
341+
{
342+
"counterParty":"master",
343+
"email":"[email protected]",
344+
"type":1,
345+
"asset":"BTC",
346+
"qty":"1",
347+
"fromAccountType":"SPOT",
348+
"toAccountType":"SPOT",
349+
"status":"SUCCESS",
350+
"tranId":11798835829,
351+
"time":1544433325000
352+
},
353+
{
354+
"counterParty": "subAccount",
355+
"email": "[email protected]",
356+
"type": 2,
357+
"asset":"ETH",
358+
"qty":"2",
359+
"fromAccountType":"SPOT",
360+
"toAccountType":"COIN_FUTURE",
361+
"status":"SUCCESS",
362+
"tranId":11798829519,
363+
"time":1544433326000
364+
}
365+
]
366+
`)
367+
s.mockDo(data, nil)
368+
defer s.assertDo()
369+
370+
transferType := SubAccountTransferTypeTransferIn
371+
startTime := time.Date(2018, 9, 15, 0, 0, 0, 0, time.UTC).UnixMilli()
372+
endTime := time.Date(2018, 9, 16, 0, 0, 0, 0, time.UTC).UnixMilli()
373+
374+
s.assertReq(func(r *request) {
375+
e := newSignedRequest().setParams(params{
376+
"type": int(transferType),
377+
"startTime": startTime,
378+
"endTime": endTime,
379+
})
380+
s.assertRequestEqual(e, r)
381+
})
382+
383+
response, err := s.client.NewSubAccountTransferHistoryService().
384+
TransferType(transferType).
385+
StartTime(startTime).
386+
EndTime(endTime).
387+
Do(newContext())
388+
389+
r := s.r()
390+
r.NoError(err)
391+
s.assertSubAccountTransferHistoryEqual(&SubAccountTransferHistory{
392+
CounterParty: "master",
393+
394+
Type: 1,
395+
Asset: "BTC",
396+
Qty: "1",
397+
FromAccountType: "SPOT",
398+
ToAccountType: "SPOT",
399+
Status: "SUCCESS",
400+
TranID: 11798835829,
401+
Time: 1544433325000,
402+
}, response[0])
403+
}
404+
405+
func (s *subAccountServiceTestSuite) assertSubAccountTransferHistoryEqual(e, a *SubAccountTransferHistory) {
406+
r := s.r()
407+
r.Equal(e.CounterParty, a.CounterParty, "CounterParty")
408+
r.Equal(e.Email, a.Email, "Email")
409+
r.Equal(e.Type, a.Type, "Type")
410+
r.Equal(e.Asset, a.Asset, "Asset")
411+
r.Equal(e.Qty, a.Qty, "Qty")
412+
r.Equal(e.FromAccountType, a.FromAccountType, "FromAccountType")
413+
r.Equal(e.ToAccountType, a.ToAccountType, "ToAccountType")
414+
r.Equal(e.Status, a.Status, "Status")
415+
r.Equal(e.TranID, a.TranID, "TranId")
416+
r.Equal(e.Time, a.Time, "Time")
417+
}

0 commit comments

Comments
 (0)