Skip to content

Commit

Permalink
Release v1.0.0 (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
urischwartz-cb authored Jan 3, 2024
1 parent c5f110b commit 8748f26
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 1 deletion.
3 changes: 2 additions & 1 deletion coinbase/jwt_generator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import secrets
import time

import jwt
Expand Down Expand Up @@ -25,7 +26,7 @@ def build_jwt(key_var, secret_var, service, uri=None):
jwt_data,
private_key,
algorithm="ES256",
headers={"kid": key_var, "nonce": str(int(time.time()))},
headers={"kid": key_var, "nonce": secrets.token_hex()},
)

return jwt_token
Expand Down
8 changes: 8 additions & 0 deletions coinbase/rest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ class RESTClient(RESTBase):
from .common import get_unix_time
from .convert import commit_convert_trade, create_convert_quote, get_convert_trade
from .fees import get_transaction_summary
from .futures import (
cancel_pending_futures_sweep,
get_futures_balance_summary,
get_futures_position,
list_futures_positions,
list_futures_sweeps,
schedule_futures_sweep,
)
from .market_data import get_candles, get_market_trades
from .orders import (
cancel_orders,
Expand Down
69 changes: 69 additions & 0 deletions coinbase/rest/futures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from coinbase.constants import API_PREFIX


def get_futures_balance_summary(self, **kwargs):
"""
Get information on your balances related to Coinbase Financial Markets (CFM) futures trading.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmbalancesummary
"""
endpoint = f"{API_PREFIX}/cfm/balance_summary"

return self.get(endpoint, **kwargs)


def list_futures_positions(self, **kwargs):
"""
Get a list of all open positions in CFM futures products.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmpositions
"""
endpoint = f"{API_PREFIX}/cfm/positions"

return self.get(endpoint, **kwargs)


def get_futures_position(self, product_id: str, **kwargs):
"""
Get the position of a specific CFM futures product.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmposition
"""
endpoint = f"{API_PREFIX}/cfm/positions/{product_id}"

return self.get(endpoint, **kwargs)


def schedule_futures_sweep(self, usd_amount: str, **kwargs):
"""
Schedule a sweep of funds from your CFTC-regulated futures account to your Coinbase Inc. USD Spot wallet.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_schedulefcmsweep
"""
endpoint = f"{API_PREFIX}/cfm/sweeps/schedule"

data = {"usd_amount": usd_amount}

return self.post(endpoint, data=data, **kwargs)


def list_futures_sweeps(self, **kwargs):
"""
Get information on your pending and/or processing requests to sweep funds from your CFTC-regulated futures account to your Coinbase Inc. USD Spot wallet.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfcmsweeps
"""
endpoint = f"{API_PREFIX}/cfm/sweeps"

return self.get(endpoint, **kwargs)


def cancel_pending_futures_sweep(self, **kwargs):
"""
Cancel your pending sweep of funds from your CFTC-regulated futures account to your Coinbase Inc. USD Spot wallet.
https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_cancelfcmsweep
"""
endpoint = f"{API_PREFIX}/cfm/sweeps"

return self.delete(endpoint, **kwargs)
118 changes: 118 additions & 0 deletions tests/rest/test_futures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import unittest

from requests_mock import Mocker

from coinbase.rest import RESTClient
from tests.constants import TEST_API_KEY, TEST_API_SECRET


class FuturesTest(unittest.TestCase):
def test_get_futures_balance_summary(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"GET",
"https://api.coinbase.com/api/v3/brokerage/cfm/balance_summary",
json=expected_response,
)
balance_summary = client.get_futures_balance_summary()

captured_request = m.request_history[0]

self.assertEqual(captured_request.query, "")
self.assertEqual(balance_summary, expected_response)

def test_list_futures_positions(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"GET",
"https://api.coinbase.com/api/v3/brokerage/cfm/positions",
json=expected_response,
)
positions = client.list_futures_positions()

captured_request = m.request_history[0]

self.assertEqual(captured_request.query, "")
self.assertEqual(positions, expected_response)

def test_get_futures_position(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"GET",
"https://api.coinbase.com/api/v3/brokerage/cfm/positions/PRODUCT_ID_1",
json=expected_response,
)
position = client.get_futures_position("PRODUCT_ID_1")

captured_request = m.request_history[0]

self.assertEqual(captured_request.query, "")
self.assertEqual(position, expected_response)

def test_schedule_futures_sweep(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"POST",
"https://api.coinbase.com/api/v3/brokerage/cfm/sweeps/schedule",
json=expected_response,
)
response = client.schedule_futures_sweep("5")

captured_request = m.request_history[0]
captured_json = captured_request.json()

self.assertEqual(captured_request.query, "")
self.assertEqual(captured_json, {"usd_amount": "5"})
self.assertEqual(response, expected_response)

def test_list_futures_sweeps(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"GET",
"https://api.coinbase.com/api/v3/brokerage/cfm/sweeps",
json=expected_response,
)
sweeps = client.list_futures_sweeps()

captured_request = m.request_history[0]

self.assertEqual(captured_request.query, "")
self.assertEqual(sweeps, expected_response)

def test_cancel_pending_futures_sweep(self):
client = RESTClient(TEST_API_KEY, TEST_API_SECRET)

expected_response = {"key_1": "value_1", "key_2": "value_2"}

with Mocker() as m:
m.request(
"DELETE",
"https://api.coinbase.com/api/v3/brokerage/cfm/sweeps",
json=expected_response,
)
delete = client.cancel_pending_futures_sweep()

captured_request = m.request_history[0]

self.assertEqual(captured_request.query, "")
self.assertEqual(delete, expected_response)

0 comments on commit 8748f26

Please sign in to comment.