Skip to content

Commit dafbd4f

Browse files
authored
Merge pull request #29 from cryptomkt/feat/update-january-2025
Feat/update january 2025
2 parents eb9ea52 + 4756576 commit dafbd4f

File tree

9 files changed

+127
-12
lines changed

9 files changed

+127
-12
lines changed

cryptomarket/client.py

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Commission, Currency, Fee, Order,
1111
OrderBook, Price, PriceHistory,
1212
SubAccount, Symbol, Ticker, Trade,
13-
Transaction)
13+
Transaction, WhitelistedAddress)
1414
from cryptomarket.dataclasses.aclSettings import ACLSettings
1515
from cryptomarket.dataclasses.convertedCandles import ConvertedCandles
1616
from cryptomarket.dataclasses.convertedCandlesOfSymbol import \
@@ -748,6 +748,7 @@ def replace_spot_order(
748748
new_client_order_id: str,
749749
quantity: str,
750750
price: Optional[str] = None,
751+
stop_price: Optional[str] = None,
751752
strict_validate: Optional[bool] = None
752753
) -> Order:
753754
"""Replaces a spot order
@@ -761,13 +762,14 @@ def replace_spot_order(
761762
:param client order id: client order id of the old order
762763
:param new client order id: client order id for the new order
763764
:param quantity: Order quantity
764-
:param strict validate: Price and quantity will be checked for incrementation within the symbol’s tick size and quantity step. See the symbol's tick_size and quantity_increment
765765
:param price: Required if order type is 'limit', 'stopLimit', or 'takeProfitLimit'. Order price
766+
:param stop price: Required if order type is 'stopLimit', 'stopMarket', 'takeProfitLimit', or 'takeProfitMarket'. Order stop price
767+
:param strict validate: Price and quantity will be checked for incrementation within the symbol’s tick size and quantity step. See the symbol's tick_size and quantity_increment
766768
767769
:return: The new spot order
768770
"""
769771
params = args.DictBuilder().new_client_order_id(new_client_order_id).quantity(
770-
quantity).price(price).strict_validate(strict_validate).build()
772+
quantity).price(price).stop_price(stop_price).strict_validate(strict_validate).build()
771773
response = self._patch(
772774
endpoint=f'spot/order/{client_order_id}', params=params)
773775
return from_dict(data_class=Order, data=response, config=Config(cast=[Enum]))
@@ -934,6 +936,18 @@ def get_wallet_balance_of_currency(self, currency: Optional[str] = None) -> Bala
934936
response = self._get(endpoint=f'wallet/balance/{currency}')
935937
return from_dict(data_class=Balance, data=response)
936938

939+
def get_whitelisted_addresses(self) -> List[WhitelistedAddress]:
940+
"""Gets the list of whitelisted addresses
941+
942+
Requires the "Payment information" API key Access Right
943+
944+
https://api.exchange.cryptomkt.com/#get-whitelisted-addresses
945+
946+
:return: A list of addresses
947+
"""
948+
response = self._get(endpoint=f'wallet/crypto/address/white-list')
949+
return [from_dict(data_class=WhitelistedAddress, data=data) for data in response]
950+
937951
def get_deposit_crypto_addresses(self) -> List[Address]:
938952
"""Get the current addresses of the user
939953
@@ -1109,7 +1123,9 @@ def get_estimate_withdrawal_fees(self, fee_requests: List[args.FeeRequest]) -> L
11091123
11101124
:return: A list of expected withdrawal fees
11111125
"""
1112-
params = [asdict(fee_request) for fee_request in fee_requests]
1126+
params = [args.clean_nones(asdict(fee_request))
1127+
for fee_request
1128+
in fee_requests]
11131129
result = self._post(
11141130
endpoint='wallet/crypto/fees/estimate', params=params)
11151131
return [Fee.from_dict(fee_data) for fee_data in result]
@@ -1123,11 +1139,24 @@ def get_bulk_estimate_withdrawal_fees(self, fee_requests: List[args.FeeRequest])
11231139
11241140
:return: A list of expected withdrawal fees
11251141
"""
1126-
params = [asdict(fee_request) for fee_request in fee_requests]
1142+
params = [args.clean_nones(asdict(fee_request))
1143+
for fee_request
1144+
in fee_requests]
11271145
result = self._post(
11281146
endpoint='wallet/crypto/fee/estimate/bulk', params=params)
11291147
return [Fee.from_dict(fee_data) for fee_data in result]
11301148

1149+
def get_withdrawal_fees_hash(self) -> str:
1150+
"""Gets the hash of withdrawal fees
1151+
1152+
Requires the "Payment information" API key Access Right
1153+
1154+
https://api.exchange.cryptomkt.com/#get-withdrawal-fees-hash
1155+
1156+
:return: the fees hash
1157+
"""
1158+
return self._get(endpoint='wallet/crypto/fee/withdraw/hash')['hash']
1159+
11311160
# def get_estimate_deposit_fee(self, currency: str, amount: str, network_code: Optional[str] = None) -> str:
11321161
# """Get an estimate of the Deposit fee
11331162

@@ -1443,6 +1472,49 @@ def transfer_funds(
14431472
amount).currency(currency).type(type).build()
14441473
return self._post(endpoint='sub-account/transfer', params=params)['result']
14451474

1475+
def transfer_to_super_account(self, amount: str, currency: str) -> str:
1476+
"""Creates and commits a transfer from a subaccount to its super account
1477+
1478+
Call is being sent by a subaccount
1479+
1480+
Created but not committed transfer will reserve pending amount on the sender
1481+
wallet affecting their ability to withdraw or transfer crypto to another
1482+
account. Incomplete withdrawals affect subaccount transfers the same way
1483+
1484+
Requires the "Withdraw cryptocurrencies" API key Access Right
1485+
1486+
https://api.exchange.cryptomkt.com/#transfer-to-super-account
1487+
1488+
:param amount: the amount of currency to transfer
1489+
:param currency: the currency to transfer
1490+
:return: The transaction id of the tranfer
1491+
"""
1492+
params = args.DictBuilder().amount(amount).currency(currency).build()
1493+
return self._post(endpoint='sub-account/transfer/sub-to-super', params=params)['result']
1494+
1495+
def transfer_to_another_subaccount(self, sub_account_id: str, amount: str, currency: str) -> str:
1496+
"""Creates and commits a transfer between the user (subaccount) and another
1497+
subaccount.
1498+
1499+
Call is being sent by a subaccount
1500+
1501+
Created but not committed transfer will reserve pending amount on the sender
1502+
wallet affecting their ability to withdraw or transfer crypto to another
1503+
account. Incomplete withdrawals affect subaccount transfers the same way
1504+
1505+
Requires the "Withdraw cryptocurrencies" API key Access Right
1506+
1507+
https://api.exchange.cryptomkt.com/#transfer-across-subaccounts
1508+
1509+
:param sub_account_id: Identifier of a subaccount
1510+
:param amount: the amount of currency to transfer
1511+
:param currency: the currency to transfer
1512+
:return: The transaction id of the tranfer
1513+
"""
1514+
params = args.DictBuilder().sub_account_id(sub_account_id).amount(
1515+
amount).currency(currency).build()
1516+
return self._post(endpoint='sub-account/transfer/sub-to-sub', params=params)['result']
1517+
14461518
def get_ACL_settings(self, sub_account_ids: List[str]) -> List[ACLSettings]:
14471519
"""Get a list of withdrawal settings for all sub-accounts or for the specified sub-accounts
14481520

cryptomarket/dataclasses/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from .wsTrade import WSTrade
3232
from .wsPriceRate import WSPriceRate
3333
from .fee import Fee
34+
from .whitelistedAddress import WhitelistedAddress
3435
__all__ = [
3536
ACLSettings,
3637
Address,
@@ -66,4 +67,5 @@
6667
WSPriceRate,
6768
SubAccount,
6869
Fee,
70+
WhitelistedAddress
6971
]

cryptomarket/dataclasses/order.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Order:
1919
quantity_cumulative: str
2020
created_at: str
2121
updated_at: str
22+
price_average: str
2223
price: Optional[str] = None
2324
expire_time: Optional[str] = None
2425
stop_price: Optional[str] = None

cryptomarket/dataclasses/price.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
@dataclass
66
class Price:
7-
price: str
87
timestamp: str
8+
price: Optional[str] = None
99
currency: Optional[str] = None
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from dataclasses import dataclass
2+
from typing import Optional
3+
4+
5+
@dataclass
6+
class WhitelistedAddress:
7+
address: str
8+
currency: str
9+
name: str
10+
network: str

cryptomarket/websockets/trading_client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ def replace_spot_order(
335335
new_client_order_id: str,
336336
quantiy: str,
337337
price: str,
338+
stop_price: Optional[str] = None,
338339
strict_validate: Optional[bool] = None,
339340
callback: Optional[Callback[Report]] = None
340341
):
@@ -346,11 +347,12 @@ def replace_spot_order(
346347
:param new_client_order_id: the new client order id for the modified order. must be unique within the trading day
347348
:param quantity: new order quantity
348349
:param price: new order price
350+
:param stop price: Required if order type is 'stopLimit', 'stopMarket', 'takeProfitLimit', or 'takeProfitMarket'. Order stop price
349351
:param strict_validate: price and quantity will be checked for the incrementation with tick size and quantity step. See symbol's tick_size and quantity_increment
350352
:param callback: A callable of two arguments, takes either a CryptomarketAPIException, or a report of the new version of the order
351353
"""
352354
params = args.DictBuilder().client_order_id(client_order_id).new_client_order_id(
353-
new_client_order_id).quantity(quantiy).price(price).strict_validate(strict_validate).build()
355+
new_client_order_id).quantity(quantiy).price(price).stop_price(stop_price).strict_validate(strict_validate).build()
354356
intercept_response_callback: InterceptResponseCallback = None
355357
if callback:
356358
def intercept_result(err, response):

tests/websockets/test_helpers.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import time
22
from dataclasses import asdict
3-
from typing import Any, Dict, List
3+
from typing import Any, Callable, Dict, List
44

55
from cryptomarket.dataclasses import (Balance, OrderBookLevel, Report,
66
WSCandle, WSMiniTicker, WSOrderBook,
77
WSOrderBookTop, WSPublicTrade, WSTicker,
88
WSTrade)
9+
from cryptomarket.dataclasses.commission import Commission
910
from cryptomarket.dataclasses.wsPriceRate import WSPriceRate
10-
from tests.rest.test_helpers import good_list
11+
12+
13+
def good_list(check_fn: Callable[[Any], bool], list: List[Any]) -> bool:
14+
for elem in list:
15+
if not check_fn(elem):
16+
print(elem)
17+
return False
18+
return True
1119

1220

1321
def defined(a_dict, key):
@@ -19,6 +27,28 @@ def defined(a_dict, key):
1927
return True
2028

2129

30+
def good_balance(balance: Balance) -> bool:
31+
return good_dict(
32+
asdict(balance),
33+
[
34+
"currency",
35+
"available",
36+
"reserved",
37+
]
38+
)
39+
40+
41+
def good_trading_commission(commission: Commission) -> bool:
42+
return good_dict(
43+
asdict(commission),
44+
[
45+
"symbol",
46+
"take_rate",
47+
"make_rate",
48+
]
49+
)
50+
51+
2252
def good_dict(a_dict: Dict[str, Any], fields: List[str]) -> bool:
2353
if not isinstance(a_dict, dict):
2454
return False

tests/websockets/test_market_data_subs.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
WSOrderBookTop, WSTicker, WSTrade)
88
from cryptomarket.dataclasses.wsPriceRate import WSPriceRate
99
from cryptomarket.websockets import MarketDataClient
10-
from tests.rest.test_helpers import good_list
11-
from tests.websockets.test_helpers import Veredict, good_candle_list, good_mini_ticker, good_orderbook_top, good_price_rate, good_wsorder_book, good_wsticker, good_wstrade
10+
from test_helpers import *
1211

1312
SECOND = 1
1413
MINUTE = 60

tests/websockets/test_trading_client.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from test_helpers import *
88

99
from cryptomarket.websockets import TradingClient
10-
from tests.rest.test_helpers import good_balance, good_trading_commission
1110

1211
with open('/home/ismael/cryptomarket/keys.json') as fd:
1312
keys = json.load(fd)

0 commit comments

Comments
 (0)