diff --git a/v2/client.go b/v2/client.go index eee433e15..3eac28897 100644 --- a/v2/client.go +++ b/v2/client.go @@ -1456,6 +1456,12 @@ func (c *Client) NewSimpleEarnService() *SimpleEarnService { // ----- end simple earn service ----- +// ----- vip loan service ----- +func (c *Client) NewVipLoanService() *VipLoanService { + return &VipLoanService{c: c} +} + +// ----- end vip loan service ----- func (c *Client) NewDualInvestmentService() *DualInvestmentService { return &DualInvestmentService{c: c} } diff --git a/v2/vip_loan_service.go b/v2/vip_loan_service.go new file mode 100644 index 000000000..bc39c5356 --- /dev/null +++ b/v2/vip_loan_service.go @@ -0,0 +1,861 @@ +package binance + +import ( + "context" + "encoding/json" + "net/http" +) + +type VipLoanService struct { + c *Client +} + +func (s *VipLoanService) InterestRate() *VipLoanInterestRateService { + return &VipLoanInterestRateService{c: s.c} +} + +func (s *VipLoanService) InterestRateHistory() *VipLoanInterestRateHistoryService { + return &VipLoanInterestRateHistoryService{c: s.c} +} + +func (s *VipLoanService) LoanableAssetData() *VipLoanLoanableAssetDataService { + return &VipLoanLoanableAssetDataService{c: s.c} +} + +func (s *VipLoanService) CollateralAssetData() *VipLoanCollateralAssetDataService { + return &VipLoanCollateralAssetDataService{c: s.c} +} + +func (s *VipLoanService) OngoingOrders() *VipLoanOngoingOrdersService { + return &VipLoanOngoingOrdersService{c: s.c} +} + +func (s *VipLoanService) RepaymentHistory() *VipLoanRepaymentHistoryService { + return &VipLoanRepaymentHistoryService{c: s.c} +} + +func (s *VipLoanService) AccruedInterest() *VipLoanAccruedInterestService { + return &VipLoanAccruedInterestService{c: s.c} +} + +func (s *VipLoanService) CollateralAccount() *VipLoanCollateralAccountService { + return &VipLoanCollateralAccountService{c: s.c} +} + +func (s *VipLoanService) ApplicationStatus() *VipLoanApplicationStatusService { + return &VipLoanApplicationStatusService{c: s.c} +} + +func (s *VipLoanService) Renew() *VipLoanRenewService { + return &VipLoanRenewService{c: s.c} +} + +func (s *VipLoanService) Repay() *VipLoanRepayService { + return &VipLoanRepayService{c: s.c} +} + +func (s *VipLoanService) Borrow() *VipLoanBorrowService { + return &VipLoanBorrowService{c: s.c} +} + +type VipLoanInterestRateService struct { + c *Client + loanCoin string // Mandatory: YES, max 10 assets split by comma +} + +func (s *VipLoanInterestRateService) LoanCoin(loanCoin string) *VipLoanInterestRateService { + s.loanCoin = loanCoin + return s +} + +func (s *VipLoanInterestRateService) Do(ctx context.Context) (*VipLoanInterestRate, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/request/interestRate", + secType: secTypeSigned, + } + + r.setParam("loanCoin", s.loanCoin) + + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanInterestRate) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanInterestRate []*VipLoanInterestRateElement + +type VipLoanInterestRateElement struct { + Asset string `json:"asset"` + FlexibleDailyInterestRate string `json:"flexibleDailyInterestRate"` + FlexibleYearlyInterestRate string `json:"flexibleYearlyInterestRate"` + Time string `json:"time"` +} + +type VipLoanInterestRateHistoryService struct { + c *Client + coin string + startTime *int64 + endTime *int64 + current *int64 // Mandatory: NO, default 1 + limit *int64 // Mandatory: NO, default 10, max 100 +} + +func (s *VipLoanInterestRateHistoryService) Coin(coin string) *VipLoanInterestRateHistoryService { + s.coin = coin + return s +} + +func (s *VipLoanInterestRateHistoryService) StartTime(startTime int64) *VipLoanInterestRateHistoryService { + s.startTime = &startTime + return s +} + +func (s *VipLoanInterestRateHistoryService) EndTime(endTime int64) *VipLoanInterestRateHistoryService { + s.endTime = &endTime + return s +} + +func (s *VipLoanInterestRateHistoryService) Current(current int64) *VipLoanInterestRateHistoryService { + s.current = ¤t + return s +} + +func (s *VipLoanInterestRateHistoryService) Limit(limit int64) *VipLoanInterestRateHistoryService { + s.limit = &limit + return s +} + +func (s *VipLoanInterestRateHistoryService) Do(ctx context.Context) (*VipLoanInterestRateHistoryResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/interestRateHistory", + secType: secTypeSigned, + } + + r.setParam("coin", s.coin) + + if s.startTime != nil { + r.setParam("startTime", *s.startTime) + } + if s.endTime != nil { + r.setParam("endTime", *s.endTime) + } + if s.current != nil { + r.setParam("current", *s.current) + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanInterestRateHistoryResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanInterestRateHistoryResponse struct { + Rows []VipLoanInterestRateHistory `json:"rows"` + Total int64 `json:"total"` +} + +type VipLoanInterestRateHistory struct { + Coin string `json:"coin"` + AnnualizedInterestRate string `json:"annualizedInterestRate"` + Time string `json:"time"` +} + +type VipLoanLoanableAssetDataService struct { + c *Client + loanCoin *string + vipLevel *int64 // Mandatory: NO, default to user vip level +} + +func (s *VipLoanLoanableAssetDataService) LoanCoin(loanCoin string) *VipLoanLoanableAssetDataService { + s.loanCoin = &loanCoin + return s +} + +func (s *VipLoanLoanableAssetDataService) VipLevel(vipLevel int64) *VipLoanLoanableAssetDataService { + s.vipLevel = &vipLevel + return s +} + +func (s *VipLoanLoanableAssetDataService) Do(ctx context.Context) (*VipLoanLoanableAssetDataResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/loanable/data", + secType: secTypeSigned, + } + if s.loanCoin != nil { + r.setParam("loanCoin", *s.loanCoin) + } + if s.vipLevel != nil { + r.setParam("vipLevel", *s.vipLevel) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanLoanableAssetDataResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanLoanableAssetDataResponse struct { + Rows []VipLoanLoanableAssetData `json:"rows"` + Total int `json:"total"` +} + +type VipLoanLoanableAssetData struct { + LoanCoin string `json:"loanCoin"` + FlexibleDailyInterestRate string `json:"_flexibleDailyInterestRate"` + FlexibleYearlyInterestRate string `json:"_flexibleYearlyInterestRate"` + ThirtyDayDailyInterestRate string `json:"_30dDailyInterestRate"` + ThirtyDayYearlyInterestRate string `json:"_30dYearlyInterestRate"` + SixtyDayDailyInterestRate string `json:"_60dDailyInterestRate"` + SixtyDayYearlyInterestRate string `json:"_60dYearlyInterestRate"` + MinLimit string `json:"minLimit"` + MaxLimit string `json:"maxLimit"` + VipLevel int `json:"vipLevel"` +} + +type VipLoanCollateralAssetDataService struct { + c *Client + collateralCoin *string // Mandatory: NO +} + +func (s *VipLoanCollateralAssetDataService) CollateralCoin(collateralCoin string) *VipLoanCollateralAssetDataService { + s.collateralCoin = &collateralCoin + return s +} + +func (s *VipLoanCollateralAssetDataService) Do(ctx context.Context) (*VipLoanCollateralAssetDataResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/collateral/data", + secType: secTypeSigned, + } + if s.collateralCoin != nil { + r.setParam("collateralCoin", *s.collateralCoin) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanCollateralAssetDataResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanCollateralAssetDataResponse struct { + Rows []VipLoanCollateralAssetData `json:"rows"` + Total int `json:"total"` +} + +type VipLoanCollateralAssetData struct { + CollateralCoin string `json:"collateralCoin"` + FirstCollateralRatio string `json:"_1stCollateralRatio"` + FirstCollateralRange string `json:"_1stCollateralRange"` + SecondCollateralRatio string `json:"_2ndCollateralRatio"` + SecondCollateralRange string `json:"_2ndCollateralRange"` + ThirdCollateralRatio string `json:"_3rdCollateralRatio"` + ThirdCollateralRange string `json:"_3rdCollateralRange"` + FourthCollateralRatio string `json:"_4thCollateralRatio"` + FourthCollateralRange string `json:"_4thCollateralRange"` + FifthCollateralRatio string `json:"_5thCollateralRatio"` + FifthCollateralRange string `json:"_5thCollateralRange"` + SixthCollateralRatio string `json:"_6thCollateralRatio"` + SixthCollateralRange string `json:"_6thCollateralRange"` + SeventhCollateralRatio string `json:"_7thCollateralRatio"` + SeventhCollateralRange string `json:"_7thCollateralRange"` + EighthCollateralRatio string `json:"_8thCollateralRatio"` + EighthCollateralRange string `json:"_8thCollateralRange"` + NinthCollateralRatio string `json:"_9thCollateralRatio"` + NinthCollateralRange string `json:"_9thCollateralRange"` +} + +type VipLoanOngoingOrdersService struct { + c *Client + orderId *int64 // Mandatory: NO + collateralAccountId *int64 // Mandatory: NO + loanCoin *string // Mandatory: NO + collateralCoin *string // Mandatory: NO + current *int64 // Mandatory: NO, default 1, max 100 + limit *int64 // Mandatory: NO, default 10, max 100 +} + +func (s *VipLoanOngoingOrdersService) OrderId(orderId int64) *VipLoanOngoingOrdersService { + s.orderId = &orderId + return s +} + +func (s *VipLoanOngoingOrdersService) CollateralAccountId(collateralAccountId int64) *VipLoanOngoingOrdersService { + s.collateralAccountId = &collateralAccountId + return s +} + +func (s *VipLoanOngoingOrdersService) LoanCoin(loanCoin string) *VipLoanOngoingOrdersService { + s.loanCoin = &loanCoin + return s +} + +func (s *VipLoanOngoingOrdersService) CollateralCoin(collateralCoin string) *VipLoanOngoingOrdersService { + s.collateralCoin = &collateralCoin + return s +} + +func (s *VipLoanOngoingOrdersService) Current(current int64) *VipLoanOngoingOrdersService { + s.current = ¤t + return s +} + +func (s *VipLoanOngoingOrdersService) Limit(limit int64) *VipLoanOngoingOrdersService { + s.limit = &limit + return s +} + +func (s *VipLoanOngoingOrdersService) Do(ctx context.Context) (*VipLoanOngoingOrderResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/ongoing/orders", + secType: secTypeSigned, + } + if s.orderId != nil { + r.setParam("orderId", *s.orderId) + } + if s.collateralAccountId != nil { + r.setParam("collateralAccountId", *s.collateralAccountId) + } + if s.loanCoin != nil { + r.setParam("loanCoin", *s.loanCoin) + } + if s.collateralCoin != nil { + r.setParam("collateralCoin", *s.collateralCoin) + } + if s.current != nil { + r.setParam("current", *s.current) + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanOngoingOrderResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanOngoingOrderResponse struct { + Rows []VipLoanOngoingOrder `json:"rows"` + Total int `json:"total"` +} + +type VipLoanOngoingOrder struct { + OrderId int `json:"orderId"` + LoanCoin string `json:"loanCoin"` + TotalDebt string `json:"totalDebt"` + LoanRate string `json:"loanRate"` + ResidualInterest string `json:"residualInterest"` + CollateralAccountId string `json:"collateralAccountId"` + CollateralCoin string `json:"collateralCoin"` + TotalCollateralValueAfterHaircut string `json:"totalCollateralValueAfterHaircut"` + LockedCollateralValue string `json:"lockedCollateralValue"` + CurrentLTV string `json:"currentLTV"` + ExpirationTime int64 `json:"expirationTime"` + LoanDate string `json:"loanDate"` + LoanTerm string `json:"loanTerm"` +} + +type VipLoanRepaymentHistoryService struct { + c *Client + orderId *int64 + loanCoin *string + startTime *int64 + endTime *int64 + current *int64 + limit *int64 +} + +func (s *VipLoanRepaymentHistoryService) OrderId(orderId int64) *VipLoanRepaymentHistoryService { + s.orderId = &orderId + return s +} + +func (s *VipLoanRepaymentHistoryService) LoanCoin(loanCoin string) *VipLoanRepaymentHistoryService { + s.loanCoin = &loanCoin + return s +} + +func (s *VipLoanRepaymentHistoryService) StartTime(startTime int64) *VipLoanRepaymentHistoryService { + s.startTime = &startTime + return s +} + +func (s *VipLoanRepaymentHistoryService) EndTime(endTime int64) *VipLoanRepaymentHistoryService { + s.endTime = &endTime + return s +} + +func (s *VipLoanRepaymentHistoryService) Current(current int64) *VipLoanRepaymentHistoryService { + s.current = ¤t + return s +} + +func (s *VipLoanRepaymentHistoryService) Limit(limit int64) *VipLoanRepaymentHistoryService { + s.limit = &limit + return s +} + +func (s *VipLoanRepaymentHistoryService) Do(ctx context.Context) (*VipLoanRepaymentHistoryResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/repayment/history", + secType: secTypeSigned, + } + if s.orderId != nil { + r.setParam("orderId", *s.orderId) + } + if s.loanCoin != nil { + r.setParam("loanCoin", *s.loanCoin) + } + if s.startTime != nil { + r.setParam("startTime", *s.startTime) + } + if s.endTime != nil { + r.setParam("endTime", *s.endTime) + } + if s.current != nil { + r.setParam("current", *s.current) + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanRepaymentHistoryResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanRepaymentHistoryResponse struct { + Rows []VipLoanRepaymentHistory `json:"rows"` + Total int `json:"total"` +} + +type VipLoanRepaymentHistory struct { + LoanCoin string `json:"loanCoin"` + RepayAmount string `json:"repayAmount"` + CollateralCoin string `json:"collateralCoin"` + RepayStatus string `json:"repayStatus"` + LoanDate string `json:"loanDate"` + RepayTime string `json:"repayTime"` + OrderId string `json:"orderId"` +} + +type VipLoanAccruedInterestService struct { + c *Client + orderId *int64 + loanCoin *string + startTime *int64 + endTime *int64 + current *int64 + limit *int64 +} + +func (s *VipLoanAccruedInterestService) OrderId(orderId int64) *VipLoanAccruedInterestService { + s.orderId = &orderId + return s +} + +func (s *VipLoanAccruedInterestService) LoanCoin(loanCoin string) *VipLoanAccruedInterestService { + s.loanCoin = &loanCoin + return s +} + +func (s *VipLoanAccruedInterestService) StartTime(startTime int64) *VipLoanAccruedInterestService { + s.startTime = &startTime + return s +} + +func (s *VipLoanAccruedInterestService) EndTime(endTime int64) *VipLoanAccruedInterestService { + s.endTime = &endTime + return s +} + +func (s *VipLoanAccruedInterestService) Current(current int64) *VipLoanAccruedInterestService { + s.current = ¤t + return s +} + +func (s *VipLoanAccruedInterestService) Limit(limit int64) *VipLoanAccruedInterestService { + s.limit = &limit + return s +} + +func (s *VipLoanAccruedInterestService) Do(ctx context.Context) (*VipLoanAccruedInterestResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/accruedInterest", + secType: secTypeSigned, + } + if s.loanCoin != nil { + r.setParam("loanCoin", *s.loanCoin) + } + if s.startTime != nil { + r.setParam("startTime", *s.startTime) + } + if s.endTime != nil { + r.setParam("endTime", *s.endTime) + } + if s.current != nil { + r.setParam("current", *s.current) + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanAccruedInterestResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanAccruedInterestResponse struct { + Rows []VipLoanAccruedInterest `json:"rows"` + Total int `json:"total"` +} + +type VipLoanAccruedInterest struct { + LoanCoin string `json:"loanCoin"` + PrincipalAmount string `json:"principalAmount"` + InterestAmount string `json:"interestAmount"` + AnnualInterestRate string `json:"annualInterestRate"` + AccrualTime int64 `json:"accrualTime"` + OrderId int64 `json:"orderId"` +} + +type VipLoanCollateralAccountService struct { + c *Client + orderId *int64 + collateralAccountId *int64 +} + +func (s *VipLoanCollateralAccountService) OrderId(orderId int64) *VipLoanCollateralAccountService { + s.orderId = &orderId + return s +} + +func (s *VipLoanCollateralAccountService) CollateralAccountId(collateralAccountId int64) *VipLoanCollateralAccountService { + s.collateralAccountId = &collateralAccountId + return s +} + +func (s *VipLoanCollateralAccountService) Do(ctx context.Context) (*VipLoanCollateralAccountResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/collateral/account", + secType: secTypeSigned, + } + if s.orderId != nil { + r.setParam("orderId", *s.orderId) + } + if s.collateralAccountId != nil { + r.setParam("collateralAccountId", *s.collateralAccountId) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanCollateralAccountResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanCollateralAccountResponse struct { + Rows []VipLoanCollateralAccount `json:"rows"` + Total int `json:"total"` +} + +type VipLoanCollateralAccount struct { + CollateralAccountId string `json:"collateralAccountId"` + CollateralCoin string `json:"collateralCoin"` +} + +type VipLoanApplicationStatusService struct { + c *Client + current *int64 // Mandatory: NO, default 1 + limit *int64 // Mandatory: NO, default 10, Max 100 +} + +func (s *VipLoanApplicationStatusService) Current(current int64) *VipLoanApplicationStatusService { + s.current = ¤t + return s +} + +func (s *VipLoanApplicationStatusService) Limit(limit int64) *VipLoanApplicationStatusService { + s.limit = &limit + return s +} + +func (s *VipLoanApplicationStatusService) Do(ctx context.Context) (*VipLoanApplicationStatusResponse, error) { + r := &request{ + method: http.MethodGet, + endpoint: "/sapi/v1/loan/vip/request/data", + secType: secTypeSigned, + } + if s.limit != nil { + r.setParam("limit", *s.limit) + } + data, err := s.c.callAPI(ctx, r) + if err != nil { + return nil, err + } + res := new(VipLoanApplicationStatusResponse) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanApplicationStatusResponse struct { + Rows []VipLoanApplicationStatus `json:"rows"` + Total int `json:"total"` +} + +type VipLoanApplicationStatus struct { + LoanAccountId string `json:"loanAccountId"` + OrderId string `json:"orderId"` + RequestId string `json:"requestId"` + LoanCoin string `json:"loanCoin"` + LoanAmount string `json:"loanAmount"` + CollateralAccountId string `json:"collateralAccountId"` + CollateralCoin string `json:"collateralCoin"` + LoanTerm string `json:"loanTerm"` + Status string `json:"status"` + LoanDate string `json:"loanDate"` +} + +type VipLoanRenewService struct { + c *Client + orderId int64 // Mandatory: YES + loanTerm int64 // Mandatory: YES, 30 or 60 days +} + +func (s *VipLoanRenewService) OrderId(orderId int64) *VipLoanRenewService { + s.orderId = orderId + return s +} + +func (s *VipLoanRenewService) LoanTerm(loanTerm int64) *VipLoanRenewService { + s.loanTerm = loanTerm + return s +} + +func (s *VipLoanRenewService) Do(ctx context.Context, opts ...RequestOption) (*VipLoanRenew, error) { + r := &request{ + method: http.MethodPost, + endpoint: "/sapi/v1/loan/vip/renew", + secType: secTypeSigned, + } + m := params{ + "orderId": s.orderId, + "loanTerm": s.loanTerm, + } + r.setParams(m) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res := new(VipLoanRenew) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanRenew struct { + LoanAccountId string `json:"loanAccountId"` + LoanCoin string `json:"loanCoin"` + LoanAmount string `json:"loanAmount"` + CollateralAccountId string `json:"collateralAccountId"` + CollateralCoin string `json:"collateralCoin"` + LoanTerm string `json:"loanTerm"` +} + +type VipLoanRepayService struct { + c *Client + orderId int64 + amount float64 +} + +func (s *VipLoanRepayService) OrderId(orderId int64) *VipLoanRepayService { + s.orderId = orderId + return s +} + +func (s *VipLoanRepayService) Amount(amount float64) *VipLoanRepayService { + s.amount = amount + return s +} + +func (s *VipLoanRepayService) Do(ctx context.Context, opts ...RequestOption) (*VipLoanRepay, error) { + r := &request{ + method: http.MethodPost, + endpoint: "/sapi/v1/loan/vip/repay", + secType: secTypeSigned, + } + m := params{ + "orderId": s.orderId, + "amount": s.amount, + } + r.setParams(m) + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res := new(VipLoanRepay) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanRepay struct { + LoanCoin string `json:"loanCoin"` + RepayAmount string `json:"repayAmount"` + RemainingPrincipal string `json:"remainingPrincipal"` + RemainingInterest string `json:"remainingInterest"` + CollateralCoin string `json:"collateralCoin"` + CurrentLTV string `json:"currentLTV"` + RepayStatus string `json:"repayStatus"` +} + +type VipLoanBorrowService struct { + c *Client + loanAccountId int64 + loanCoin string // Mandatory: YES + loanAmount float64 + collateralAccountId string // Mandatory: YES, accounts split by comma + collateralCoin string // Mandatory: YES, coins split by comma + isFlexibleRate bool // Mandatory: YES, TRUE: flexible rate; FALSE: fixed rate + loanTerm *int64 // Mandatory: YES for fixed interest, No for floating interest, 30 or 60 +} + +func (s *VipLoanBorrowService) LoanAccountId(loanAccountId int64) *VipLoanBorrowService { + s.loanAccountId = loanAccountId + return s +} + +func (s *VipLoanBorrowService) LoanCoin(loanCoin string) *VipLoanBorrowService { + s.loanCoin = loanCoin + return s +} + +func (s *VipLoanBorrowService) LoanAmount(loanAmount float64) *VipLoanBorrowService { + s.loanAmount = loanAmount + return s +} + +func (s *VipLoanBorrowService) CollateralAccountId(collateralAccountId string) *VipLoanBorrowService { + s.collateralAccountId = collateralAccountId + return s +} + +func (s *VipLoanBorrowService) CollateralCoin(collateralCoin string) *VipLoanBorrowService { + s.collateralCoin = collateralCoin + return s +} + +func (s *VipLoanBorrowService) IsFlexibleRate(isFlexibleRate bool) *VipLoanBorrowService { + s.isFlexibleRate = isFlexibleRate + return s +} + +func (s *VipLoanBorrowService) LoanTerm(loanTerm int64) *VipLoanBorrowService { + s.loanTerm = &loanTerm + return s +} + +func (s *VipLoanBorrowService) Do(ctx context.Context, opts ...RequestOption) (*VipLoanBorrow, error) { + r := &request{ + method: http.MethodPost, + endpoint: "/sapi/v1/loan/vip/borrow", + secType: secTypeSigned, + } + + r.setParam("loanAccountId", s.loanAccountId) + + r.setParam("loanCoin", s.loanCoin) + + r.setParam("loanAmount", s.loanAmount) + + r.setParam("collateralAccountId", s.collateralAccountId) + + r.setParam("collateralCoin", s.collateralCoin) + + r.setParam("isFlexibleRate", s.isFlexibleRate) + + if s.loanTerm != nil { + r.setParam("loanTerm", *s.loanTerm) + } + data, err := s.c.callAPI(ctx, r, opts...) + if err != nil { + return nil, err + } + res := new(VipLoanBorrow) + err = json.Unmarshal(data, res) + if err != nil { + return nil, err + } + return res, nil +} + +type VipLoanBorrow struct { + LoanAccountId string `json:"loanAccountId"` + RequestId string `json:"requestId"` + LoanCoin string `json:"loanCoin"` + IsFlexibleRate string `json:"isFlexibleRate"` + LoanAmount string `json:"loanAmount"` + CollateralAccountId string `json:"collateralAccountId"` + CollateralCoin string `json:"collateralCoin"` + LoanTerm string `json:"loanTerm"` +} diff --git a/v2/vip_loan_service_test.go b/v2/vip_loan_service_test.go new file mode 100644 index 000000000..594fb0c2f --- /dev/null +++ b/v2/vip_loan_service_test.go @@ -0,0 +1,590 @@ +package binance + +import ( + "github.com/stretchr/testify/suite" + "testing" +) + +type vipLoanServiceTestSuite struct { + baseTestSuite +} + +func TestVipLoanService(t *testing.T) { + suite.Run(t, new(vipLoanServiceTestSuite)) +} + +func (s *vipLoanServiceTestSuite) TestVipLoanInterestRateService() { + data := []byte(`[ + { + "asset": "BUSD", + "flexibleDailyInterestRate": "0.001503", + "flexibleYearlyInterestRate": "0.548595", + "time": "1577233578000" + }, + { + "asset": "BTC", + "flexibleDailyInterestRate": "0.001503", + "flexibleYearlyInterestRate": "0.548595", + "time": "1577233562000" + } +]`) + s.mockDo(data, nil) + defer s.assertDo() + + s.assertReq(func(r *request) { + e := newSignedRequest().setParam("loanCoin", "BTC,BUSD") + s.assertRequestEqual(e, r) + }) + res, err := s.client.NewVipLoanService().InterestRate().LoanCoin("BTC,BUSD").Do(newContext()) + s.r().NoError(err) + e := &VipLoanInterestRate{ + { + Asset: "BUSD", + FlexibleDailyInterestRate: "0.001503", + FlexibleYearlyInterestRate: "0.548595", + Time: "1577233578000", + }, + { + Asset: "BTC", + FlexibleDailyInterestRate: "0.001503", + FlexibleYearlyInterestRate: "0.548595", + Time: "1577233562000", + }, + } + s.assertVipLoanInterestRateEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanInterestRateEqual(e, a VipLoanInterestRate) { + r := s.r() + for i := 0; i < len(e); i++ { + r.Equal(e[i].Asset, a[i].Asset, "Asset") + r.Equal(e[i].FlexibleDailyInterestRate, a[i].FlexibleDailyInterestRate, "FlexibleDailyInterestRate") + r.Equal(e[i].FlexibleYearlyInterestRate, a[i].FlexibleYearlyInterestRate, "FlexibleYearlyInterestRate") + r.Equal(e[i].Time, a[i].Time, "Time") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanInterestRateHistory() { + data := []byte(`{ + "rows": [ + { + "coin": "USDT", + "annualizedInterestRate": "0.0647", + "time": "1575018510000" + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().InterestRateHistory().Coin("USDT").Do(newContext()) + s.r().NoError(err) + e := &VipLoanInterestRateHistoryResponse{ + Rows: []VipLoanInterestRateHistory{ + { + Coin: "USDT", + AnnualizedInterestRate: "0.0647", + Time: "1575018510000", + }, + }, + Total: 1, + } + s.assertVipLoanInterestRateHistoryResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanInterestRateHistoryResponseEqual(e, a VipLoanInterestRateHistoryResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].Coin, a.Rows[i].Coin, "Coin") + r.Equal(e.Rows[i].AnnualizedInterestRate, a.Rows[i].AnnualizedInterestRate, "AnnualizedInterestRate") + r.Equal(e.Rows[i].Time, a.Rows[i].Time, "Time") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanLoanableAssetData() { + data := []byte(`{ + "rows": [ + { + "loanCoin": "BUSD", + "_flexibleDailyInterestRate": "0.001503", + "_flexibleYearlyInterestRate": "0.548595", + "_30dDailyInterestRate": "0.000136", + "_30dYearlyInterestRate": "0.03450", + "_60dDailyInterestRate": "0.000145", + "_60dYearlyInterestRate": "0.04103", + "minLimit": "100", + "maxLimit": "1000000", + "vipLevel": 1 + } + ], + "total": 1 +} +`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().LoanableAssetData().LoanCoin("BUSD").VipLevel(1).Do(newContext()) + s.r().NoError(err) + e := &VipLoanLoanableAssetDataResponse{ + Rows: []VipLoanLoanableAssetData{ + { + LoanCoin: "BUSD", + FlexibleDailyInterestRate: "0.001503", + FlexibleYearlyInterestRate: "0.548595", + ThirtyDayDailyInterestRate: "0.000136", + ThirtyDayYearlyInterestRate: "0.03450", + SixtyDayDailyInterestRate: "0.000145", + SixtyDayYearlyInterestRate: "0.04103", + }, + }, + Total: 1, + } + s.assertVipLoanLoanableAssetDataResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanLoanableAssetDataResponseEqual(e, a VipLoanLoanableAssetDataResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].LoanCoin, a.Rows[i].LoanCoin, "LoanCoin") + r.Equal(e.Rows[i].FlexibleYearlyInterestRate, a.Rows[i].FlexibleYearlyInterestRate, "FlexibleYearlyInterestRate") + r.Equal(e.Rows[i].FlexibleDailyInterestRate, a.Rows[i].FlexibleDailyInterestRate, "FlexibleDailyInterestRate") + r.Equal(e.Rows[i].ThirtyDayYearlyInterestRate, a.Rows[i].ThirtyDayYearlyInterestRate, "ThirtyDayYearlyInterestRate") + r.Equal(e.Rows[i].ThirtyDayDailyInterestRate, a.Rows[i].ThirtyDayDailyInterestRate, "ThirtyDayDailyInterestRate") + r.Equal(e.Rows[i].SixtyDayYearlyInterestRate, a.Rows[i].SixtyDayYearlyInterestRate, "SixtyDayYearlyInterestRate") + r.Equal(e.Rows[i].SixtyDayDailyInterestRate, a.Rows[i].SixtyDayDailyInterestRate, "SixtyDayDailyInterestRate") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanLoanCollateralData() { + data := []byte(`{ + "rows": [ + { + "collateralCoin": "BUSD", + "_1stCollateralRatio": "100%", + "_1stCollateralRange": "1-10000000", + "_2ndCollateralRatio": "80%", + "_2ndCollateralRange": "10000000-100000000", + "_3rdCollateralRatio": "60%", + "_3rdCollateralRange": "100000000-1000000000", + "_4thCollateralRatio": "0%", + "_4thCollateralRange": ">10000000000" + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().CollateralAssetData().CollateralCoin("BUSD").Do(newContext()) + s.r().NoError(err) + e := &VipLoanCollateralAssetDataResponse{ + Rows: []VipLoanCollateralAssetData{ + { + CollateralCoin: "BUSD", + FirstCollateralRatio: "100%", + FirstCollateralRange: "1-10000000", + SecondCollateralRatio: "80%", + SecondCollateralRange: "10000000-100000000", + ThirdCollateralRatio: "60%", + ThirdCollateralRange: "100000000-1000000000", + FourthCollateralRatio: "0%", + FourthCollateralRange: ">10000000000", + }, + }, + Total: 1, + } + + s.assertVipLoanCollateralAssetDataResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanCollateralAssetDataResponseEqual(e, a VipLoanCollateralAssetDataResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].CollateralCoin, a.Rows[i].CollateralCoin, "CollateralCoin") + r.Equal(e.Rows[i].FirstCollateralRatio, a.Rows[i].FirstCollateralRatio, "FirstCollateralRatio") + r.Equal(e.Rows[i].FirstCollateralRange, a.Rows[i].FirstCollateralRange, "FirstCollateralRange") + r.Equal(e.Rows[i].SecondCollateralRatio, a.Rows[i].SecondCollateralRatio, "SecondCollateralRatio") + r.Equal(e.Rows[i].SecondCollateralRange, a.Rows[i].SecondCollateralRange, "SecondCollateralRange") + r.Equal(e.Rows[i].ThirdCollateralRatio, a.Rows[i].ThirdCollateralRatio, "ThirdCollateralRatio") + r.Equal(e.Rows[i].ThirdCollateralRange, a.Rows[i].ThirdCollateralRange, "ThirdCollateralRange") + r.Equal(e.Rows[i].FourthCollateralRatio, a.Rows[i].FourthCollateralRatio, "FourthCollateralRatio") + r.Equal(e.Rows[i].FourthCollateralRange, a.Rows[i].FourthCollateralRange, "FourthCollateralRange") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanOngoingOrders() { + data := []byte(`{ + "rows": [ + { + "orderId": 100000001, + "loanCoin": "BUSD", + "totalDebt": "10000", + "loanRate": "0.0123", + "residualInterest": "10.27687923", + "collateralAccountId": "12345678,23456789", + "collateralCoin": "BNB,BTC,ETH", + "totalCollateralValueAfterHaircut": "25000.27565492", + "lockedCollateralValue": "25000.27565492", + "currentLTV": "0.57", + "expirationTime": 1575018510000, + "loanDate": "1676851200000", + "loanTerm": "30days" + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().OngoingOrders().LoanCoin("BUSD").OrderId(100000001).Do(newContext()) + s.r().NoError(err) + e := &VipLoanOngoingOrderResponse{ + Rows: []VipLoanOngoingOrder{ + { + OrderId: 100000001, + LoanCoin: "BUSD", + TotalDebt: "10000", + LoanRate: "0.0123", + ResidualInterest: "10.27687923", + CollateralAccountId: "12345678,23456789", + CollateralCoin: "BNB,BTC,ETH", + TotalCollateralValueAfterHaircut: "25000.27565492", + LockedCollateralValue: "25000.27565492", + CurrentLTV: "0.57", + ExpirationTime: 1575018510000, + LoanDate: "1676851200000", + LoanTerm: "30days", + }, + }, + Total: 1, + } + s.assertVipLoanOngoingOrderResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanOngoingOrderResponseEqual(e, a VipLoanOngoingOrderResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].OrderId, a.Rows[i].OrderId, "OrderId") + r.Equal(e.Rows[i].LoanCoin, a.Rows[i].LoanCoin, "LoanCoin") + r.Equal(e.Rows[i].TotalDebt, a.Rows[i].TotalDebt, "TotalDebt") + r.Equal(e.Rows[i].LoanRate, a.Rows[i].LoanRate, "LoanRate") + r.Equal(e.Rows[i].ResidualInterest, a.Rows[i].ResidualInterest, "ResidualInterest") + r.Equal(e.Rows[i].CollateralAccountId, a.Rows[i].CollateralAccountId, "CollateralAccountId") + r.Equal(e.Rows[i].CollateralCoin, a.Rows[i].CollateralCoin, "CollateralCoin") + r.Equal(e.Rows[i].TotalCollateralValueAfterHaircut, a.Rows[i].TotalCollateralValueAfterHaircut, "TotalCollateralValueAfterHaircut") + r.Equal(e.Rows[i].LockedCollateralValue, a.Rows[i].LockedCollateralValue, "LockedCollateralValue") + r.Equal(e.Rows[i].CurrentLTV, a.Rows[i].CurrentLTV, "CurrentLTV") + r.Equal(e.Rows[i].ExpirationTime, a.Rows[i].ExpirationTime, "ExpirationTime") + r.Equal(e.Rows[i].LoanDate, a.Rows[i].LoanDate, "LoanDate") + r.Equal(e.Rows[i].LoanTerm, a.Rows[i].LoanTerm, "LoanTerm") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanRepaymentHistory() { + data := []byte(`{ + "rows": [ + { + "loanCoin": "BUSD", + "repayAmount": "10000", + "collateralCoin": "BNB,BTC,ETH", + "repayStatus": "Repaid", + "loanDate": "1676851200000", + "repayTime": "1575018510000", + "orderId": "756783308056935434" + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().RepaymentHistory().LoanCoin("BUSD").OrderId(756783308056935434).Do(newContext()) + s.r().NoError(err) + e := &VipLoanRepaymentHistoryResponse{ + Rows: []VipLoanRepaymentHistory{ + { + LoanCoin: "BUSD", + RepayAmount: "10000", + CollateralCoin: "BNB,BTC,ETH", + RepayStatus: "Repaid", + LoanDate: "1676851200000", + RepayTime: "1575018510000", + OrderId: "756783308056935434", + }, + }, + Total: 1, + } + s.assertVipLoanRepaymentRecordResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanRepaymentRecordResponseEqual(e, a VipLoanRepaymentHistoryResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].LoanCoin, a.Rows[i].LoanCoin, "LoanCoin") + r.Equal(e.Rows[i].RepayAmount, a.Rows[i].RepayAmount, "RepayAmount") + r.Equal(e.Rows[i].CollateralCoin, a.Rows[i].CollateralCoin, "CollateralCoin") + r.Equal(e.Rows[i].RepayStatus, a.Rows[i].RepayStatus, "RepayStatus") + r.Equal(e.Rows[i].LoanDate, a.Rows[i].LoanDate, "LoanDate") + r.Equal(e.Rows[i].RepayTime, a.Rows[i].RepayTime, "RepayTime") + r.Equal(e.Rows[i].OrderId, a.Rows[i].OrderId, "OrderId") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanAccruedInterest() { + data := []byte(`{ + "rows": [ + { + "loanCoin": "USDT", + "principalAmount": "10000", + "interestAmount": "1.2", + "annualInterestRate": "0.001273", + "accrualTime": 1575018510000, + "orderId": 756783308056935434 + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().AccruedInterest().LoanCoin("USDT").OrderId(756783308056935434).Do(newContext()) + s.r().NoError(err) + e := &VipLoanAccruedInterestResponse{ + Rows: []VipLoanAccruedInterest{ + { + LoanCoin: "USDT", + PrincipalAmount: "10000", + InterestAmount: "1.2", + AnnualInterestRate: "0.001273", + AccrualTime: 1575018510000, + OrderId: 756783308056935434, + }, + }, + Total: 1, + } + s.assertVipLoanAccruedInterestResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanAccruedInterestResponseEqual(e, a VipLoanAccruedInterestResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].LoanCoin, a.Rows[i].LoanCoin, "LoanCoin") + r.Equal(e.Rows[i].PrincipalAmount, a.Rows[i].PrincipalAmount, "PrincipalAmount") + r.Equal(e.Rows[i].InterestAmount, a.Rows[i].InterestAmount, "InterestAmount") + r.Equal(e.Rows[i].AnnualInterestRate, a.Rows[i].AnnualInterestRate, "AnnualInterestRate") + r.Equal(e.Rows[i].AccrualTime, a.Rows[i].AccrualTime, "AccrualTime") + r.Equal(e.Rows[i].OrderId, a.Rows[i].OrderId, "OrderId") + } +} + +func (s *vipLoanServiceTestSuite) TestVipCollateralAccount() { + data := []byte(`{ + "rows": [ + { + "collateralAccountId": "12345678", + "collateralCoin": "BNB,BTC,ETH" + }, + { + "collateralAccountId": "23456789", + "collateralCoin": "BNB,BTC,ETH" + } + ], + "total": 2 +}`) + s.mockDo(data, nil) + defer s.assertDo() + res, err := s.client.NewVipLoanService().CollateralAccount().Do(newContext()) + s.r().NoError(err) + e := &VipLoanCollateralAccountResponse{ + Rows: []VipLoanCollateralAccount{ + { + CollateralAccountId: "12345678", + CollateralCoin: "BNB,BTC,ETH", + }, + { + CollateralAccountId: "23456789", + CollateralCoin: "BNB,BTC,ETH", + }, + }, + Total: 2, + } + s.assertVipLoanCollateralAccountResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanCollateralAccountResponseEqual(e, a VipLoanCollateralAccountResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].CollateralAccountId, a.Rows[i].CollateralAccountId, "CollateralAccountId") + r.Equal(e.Rows[i].CollateralCoin, a.Rows[i].CollateralCoin, "CollateralCoin") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanApplicationStatus() { + data := []byte(`{ + "rows": [ + { + "loanAccountId": "12345678", + "orderId": "12345678", + "requestId": "12345678", + "loanCoin": "BTC", + "loanAmount": "100.55", + "collateralAccountId": "12345678,12345678,12345678", + "collateralCoin": "BUSD,USDT,ETH", + "loanTerm": "30", + "status": "Repaid", + "loanDate": "1676851200000" + } + ], + "total": 1 +}`) + s.mockDo(data, nil) + defer s.assertDo() + + res, err := s.client.NewVipLoanService().ApplicationStatus().Do(newContext()) + s.r().NoError(err) + e := &VipLoanApplicationStatusResponse{ + Rows: []VipLoanApplicationStatus{ + { + LoanAccountId: "12345678", + OrderId: "12345678", + RequestId: "12345678", + LoanCoin: "BTC", + LoanAmount: "100.55", + LoanTerm: "30", + Status: "Repaid", + LoanDate: "1676851200000", + }, + }, + Total: 1, + } + s.assertVipLoanApplicationStatusResponseEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanApplicationStatusResponseEqual(e, a VipLoanApplicationStatusResponse) { + r := s.r() + r.Equal(e.Total, a.Total) + for i := 0; i < len(e.Rows); i++ { + r.Equal(e.Rows[i].LoanAccountId, a.Rows[i].LoanAccountId, "LoanAccountId") + r.Equal(e.Rows[i].OrderId, a.Rows[i].OrderId, "OrderId") + r.Equal(e.Rows[i].RequestId, a.Rows[i].RequestId, "RequestId") + r.Equal(e.Rows[i].LoanCoin, a.Rows[i].LoanCoin, "LoanCoin") + r.Equal(e.Rows[i].LoanAmount, a.Rows[i].LoanAmount, "LoanAmount") + r.Equal(e.Rows[i].LoanTerm, a.Rows[i].LoanTerm, "LoanTerm") + r.Equal(e.Rows[i].Status, a.Rows[i].Status, "Status") + r.Equal(e.Rows[i].LoanDate, a.Rows[i].LoanDate, "LoanDate") + } +} + +func (s *vipLoanServiceTestSuite) TestVipLoanRenew() { + data := []byte(`{ + "loanAccountId": "12345678", + "loanCoin": "BTC", + "loanAmount": "100.55", + "collateralAccountId": "12345677,12345678,12345679", + "collateralCoin": "BUSD,USDT,ETH", + "loanTerm": "30" +}`) + s.mockDo(data, nil) + defer s.assertDo() + + res, err := s.client.NewVipLoanService().Renew().OrderId(12345678).LoanTerm(30).Do(newContext()) + s.r().NoError(err) + e := &VipLoanRenew{LoanCoin: "BTC", LoanAmount: "100.55", LoanTerm: "30", CollateralAccountId: "12345677,12345678,12345679", CollateralCoin: "BUSD,USDT,ETH"} + s.assertVipLoanRenewEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertVipLoanRenewEqual(e, a VipLoanRenew) { + r := s.r() + r.Equal(e.LoanCoin, a.LoanCoin, "LoanCoin") + r.Equal(e.LoanAmount, a.LoanAmount, "LoanAmount") + r.Equal(e.LoanTerm, a.LoanTerm, "LoanTerm") + r.Equal(e.CollateralAccountId, a.CollateralAccountId, "CollateralAccountId") + r.Equal(e.CollateralCoin, a.CollateralCoin, "CollateralCoin") +} + +func (s *vipLoanServiceTestSuite) TestVipLoanRepay() { + data := []byte(`{ + "loanCoin": "BUSD", + "repayAmount": "200.5", + "remainingPrincipal": "100.5", + "remainingInterest": "0", + "collateralCoin": "BNB,BTC,ETH", + "currentLTV": "0.25", + "repayStatus": "Repaid" +}`) + s.mockDo(data, nil) + defer s.assertDo() + + res, err := s.client.NewVipLoanService().Repay().OrderId(12345678).Amount(200.5).Do(newContext()) + s.r().NoError(err) + + e := &VipLoanRepay{ + LoanCoin: "BUSD", + RepayAmount: "200.5", + RemainingPrincipal: "100.5", + RemainingInterest: "0", + CollateralCoin: "BNB,BTC,ETH", + CurrentLTV: "0.25", + RepayStatus: "Repaid", + } + + s.assertRepayEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertRepayEqual(e, a VipLoanRepay) { + r := s.r() + r.Equal(e.LoanCoin, a.LoanCoin, "LoanCoin") + r.Equal(e.RepayAmount, a.RepayAmount, "RepayAmount") + r.Equal(e.RemainingPrincipal, a.RemainingPrincipal, "RemainingPrincipal") + r.Equal(e.RemainingInterest, a.RemainingInterest, "RemainingInterest") + r.Equal(e.CollateralCoin, a.CollateralCoin, "CollateralCoin") + r.Equal(e.CurrentLTV, a.CurrentLTV, "CurrentLTV") + r.Equal(e.RepayStatus, a.RepayStatus, "RepayStatus") +} + +func (s *vipLoanServiceTestSuite) TestVipLoanBorrow() { + data := []byte(`{ + "loanAccountId": "12345678", + "requestId": "12345678", + "loanCoin": "BTC", + "isFlexibleRate": "No", + "loanAmount": "100.55", + "collateralAccountId": "12345678,12345678,12345678", + "collateralCoin": "BUSD,USDT,ETH", + "loanTerm": "30" +}`) + s.mockDo(data, nil) + defer s.assertDo() + + res, err := s.client.NewVipLoanService().Borrow().LoanAccountId(12345678).LoanCoin("BTC"). + CollateralAccountId("12345678,12345678,12345678").CollateralCoin("BUSD,USDT,ETH"). + IsFlexibleRate(false).LoanTerm(30).Do(newContext()) + s.r().NoError(err) + + e := &VipLoanBorrow{ + LoanAccountId: "12345678", + RequestId: "12345678", + LoanCoin: "BTC", + IsFlexibleRate: "No", + LoanAmount: "100.55", + CollateralAccountId: "12345678,12345678,12345678", + CollateralCoin: "BUSD,USDT,ETH", + LoanTerm: "30", + } + + s.assertBorrowEqual(*e, *res) +} + +func (s *vipLoanServiceTestSuite) assertBorrowEqual(e, a VipLoanBorrow) { + r := s.r() + r.Equal(e.LoanAccountId, a.LoanAccountId, "LoanAccountId") + r.Equal(e.RequestId, a.RequestId, "RequestId") + r.Equal(e.LoanCoin, a.LoanCoin, "LoanCoin") + r.Equal(e.IsFlexibleRate, a.IsFlexibleRate, "IsFlexibleRate") + r.Equal(e.LoanAmount, a.LoanAmount, "LoanAmount") + r.Equal(e.CollateralAccountId, a.CollateralAccountId, "CollateralAccountId") + r.Equal(e.CollateralCoin, a.CollateralCoin, "CollateralCoin") + r.Equal(e.LoanTerm, a.LoanTerm, "LoanTerm") +}