Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GetAccountsBalance() #7

Merged
merged 1 commit into from
Aug 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ If you want to execute the Private API, you need to create a client with the API
| API | Method Name |Description |
| :--- | :--- | :--- |
| GET /api/bank_accounts | [GetBankAccounts()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetBankAccounts) | Display list of bank account you registered (withdrawal).|
| GET /api/accounts/balance | [GetAccountsBalance()](https://pkg.go.dev/github.com/nao1215/coincheck#Client.GetAccountsBalance) | Get the balance of your account. |

## License

Expand Down
57 changes: 57 additions & 0 deletions balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package coincheck

import (
"context"
"net/http"
)

// GetAccountsBalanceResponse represents the response from the GetAccountsBalance method.
type GetAccountsBalanceResponse struct {
// Success is true if the request was successful.
Success bool `json:"success"`
// JPY is the balance of JPY.
JPY string `json:"jpy"`
// BTC is the balance of BTC.
BTC string `json:"btc"`
// JPYReserved is amount of JPY for unsettled buying order
JPYReserved string `json:"jpy_reserved"`
// BTCReserved is amount of BTC for unsettled selling order
BTCReserved string `json:"btc_reserved"`
// JPYLendInUse is JPY amount you are applying for lending (We don't allow you to loan JPY.)
JPYLendInUse string `json:"jpy_lend_in_use"`
// BTCLendInUse is BTC Amount you are applying for lending (We don't allow you to loan BTC.)
BTCLendInUse string `json:"btc_lend_in_use"`
// JPYLent is JPY lending amount (Currently, we don't allow you to loan JPY.)
JPYLent string `json:"jpy_lent"`
// BTCLent is BTC lending amount (Currently, we don't allow you to loan BTC.)
BTCLent string `json:"btc_lent"`
// JPYDebt is JPY borrowing amount
JPYDebt string `json:"jpy_debt"`
// BTCDebt is BTC borrowing amount
BTCDebt string `json:"btc_debt"`
// JPYTsumitate is JPY reserving amount
JPYTsumitate string `json:"jpy_tsumitate"`
// BTCTsumitate is BTC reserving amount
BTCTsumitate string `json:"btc_tsumitate"`
}

// GetAccountsBalance returns the balance of the account.
// API: GET /api/accounts/balance
// Visibility: Private
// It doesn't include jpy_reserved use unsettled orders (it's GET /api/exchange/orders/opens) in jpy btc.
func (c *Client) GetAccountsBalance(ctx context.Context) (*GetAccountsBalanceResponse, error) {
req, err := c.createRequest(ctx, createRequestInput{
method: http.MethodGet,
path: "/api/accounts/balance",
private: true,
})
if err != nil {
return nil, err
}

var output GetAccountsBalanceResponse
if err := c.do(req, &output); err != nil {
return nil, err
}
return &output, nil
}
111 changes: 111 additions & 0 deletions balance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package coincheck

import (
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/google/go-cmp/cmp"
)

func TestClient_GetBalance(t *testing.T) {
t.Run("GetBalance returns the balance", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
wantMethod := http.MethodGet
if diff := cmp.Diff(wantMethod, r.Method); diff != "" {
printDiff(t, diff)
}

wantEndpoint := "/api/accounts/balance"
if diff := cmp.Diff(wantEndpoint, r.URL.Path); diff != "" {
printDiff(t, diff)
}

result := GetAccountsBalanceResponse{
Success: true,
JPY: "0.8401",
BTC: "7.75052654",
JPYReserved: "3000.0",
BTCReserved: "3.5002",
JPYLendInUse: "1.1",
BTCLendInUse: "0.3",
JPYLent: "0",
BTCLent: "1.2",
JPYDebt: "0",
BTCDebt: "0",
JPYTsumitate: "10000.0",
BTCTsumitate: "0.43034",
}
if err := json.NewEncoder(w).Encode(result); err != nil {
t.Fatal(err)
}
}))

client, err := NewClient(
WithBaseURL(testServer.URL),
WithCredentials("api_key", "api_secret"),
)
if err != nil {
t.Fatal(err)
}

got, err := client.GetAccountsBalance(context.Background())
if err != nil {
t.Fatal(err)
}

want := &GetAccountsBalanceResponse{
Success: true,
JPY: "0.8401",
BTC: "7.75052654",
JPYReserved: "3000.0",
BTCReserved: "3.5002",
JPYLendInUse: "1.1",
BTCLendInUse: "0.3",
JPYLent: "0",
BTCLent: "1.2",
JPYDebt: "0",
BTCDebt: "0",
JPYTsumitate: "10000.0",
BTCTsumitate: "0.43034",
}
if diff := cmp.Diff(want, got); diff != "" {
printDiff(t, diff)
}
})

t.Run("GetBalance returns an error if the server returns an error", func(t *testing.T) {
testServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))

client, err := NewClient(
WithBaseURL(testServer.URL),
WithCredentials("api_key", "api_secret"),
)
if err != nil {
t.Fatal(err)
}

_, err = client.GetAccountsBalance(context.Background())
if err == nil {
t.Fatal("GetBalance did not return an error")
}
})
t.Run("GetBankAccounts returns an error if client does not set credentials", func(t *testing.T) {
// Create a new client
client, err := NewClient(WithBaseURL("https://example.com"))
if err != nil {
t.Fatal(err)
}

// Start testing
_, err = client.GetAccountsBalance(context.Background())
if !errors.Is(err, ErrNoCredentials) {
t.Errorf("error is not ErrNoCredentials: %v", err)
}
})
}
7 changes: 7 additions & 0 deletions coincheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type createRequestInput struct {
path string // API path (e.g. /api/orders)
body io.Reader // Request body. If you don't need it, set nil.
queryParam map[string]string // Query parameters (e.g. {"pair": "btc_jpy"}) If you don't need it, set nil.
private bool // If true, it's a private API.
}

// createRequest creates a new HTTP request.
Expand Down Expand Up @@ -108,6 +109,12 @@ func (c *Client) createRequest(ctx context.Context, input createRequestInput) (*

req.Header.Add("content-type", "application/json")
req.Header.Add("cache-control", "no-cache")
if input.private {
if err := c.setAuthHeaders(req, ""); err != nil {
return nil, err
}
}

return req, nil
}

Expand Down
8 changes: 3 additions & 5 deletions withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,13 @@ type BankAccount struct {
// Visibility: Private
func (c *Client) GetBankAccounts(ctx context.Context) (*GetBankAccountsResponse, error) {
req, err := c.createRequest(ctx, createRequestInput{
method: http.MethodGet,
path: "/api/bank_accounts",
method: http.MethodGet,
path: "/api/bank_accounts",
private: true,
})
if err != nil {
return nil, err
}
if err := c.setAuthHeaders(req, ""); err != nil {
return nil, err
}

var output GetBankAccountsResponse
if err := c.do(req, &output); err != nil {
Expand Down