From 7e43dd276751c25a8890b81237670561a1ddf611 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 11:17:45 +0400 Subject: [PATCH 1/7] Use base 1e18 for all onchain and offchain interactions --- src/bluefin_v2_client/client.py | 40 +++++++++++++----------------- src/bluefin_v2_client/constants.py | 4 +-- src/bluefin_v2_client/utilities.py | 24 ++++++------------ 3 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/bluefin_v2_client/client.py b/src/bluefin_v2_client/client.py index c0f872b..7a27456 100644 --- a/src/bluefin_v2_client/client.py +++ b/src/bluefin_v2_client/client.py @@ -15,10 +15,12 @@ from .interfaces import * from .enumerations import * -_SUI_BASE_NUM = 1000000000 - class BluefinClient: + """ + A class to represent a client for interacting with bluefin offchain and onchain APIs. + """ + def __init__(self, are_terms_accepted, network, private_key=""): self.are_terms_accepted = are_terms_accepted self.network = network @@ -153,9 +155,9 @@ def create_signed_order(self, req: OrderSignatureRequest) -> OrderSignatureRespo OrderSignatureResponse: order raw info and generated signature """ sui_params = deepcopy(req) - sui_params["price"] = toDapiBase(req["price"]) - sui_params["quantity"] = toDapiBase(req["quantity"]) - sui_params["leverage"] = toDapiBase(req["leverage"]) + sui_params["price"] = to1e18(req["price"]) + sui_params["quantity"] = to1e18(req["quantity"]) + sui_params["leverage"] = to1e18(req["leverage"]) order = self.create_order_to_sign(sui_params) symbol = sui_params["symbol"].value @@ -193,9 +195,9 @@ def create_signed_cancel_order( OrderSignatureResponse: generated cancel signature """ sui_params = deepcopy(params) - sui_params["price"] = toDapiBase(params["price"]) - sui_params["quantity"] = toDapiBase(params["quantity"]) - sui_params["leverage"] = toDapiBase(params["leverage"]) + sui_params["price"] = to1e18(params["price"]) + sui_params["quantity"] = to1e18(params["quantity"]) + sui_params["leverage"] = to1e18(params["leverage"]) order_to_sign = self.create_order_to_sign(sui_params) hash_val = self.order_signer.get_order_hash(order_to_sign, withBufferHex=False) @@ -313,7 +315,7 @@ async def post_signed_order(self, params: PlaceOrderRequest): ), "postOnly": default_value(params, "postOnly", False), "cancelOnRevert": default_value(params, "cancelOnRevert", False), - "clientId": "bluefin-python-client: {}".format( + "clientId": "bluefin-v2-client-python: {}".format( default_value(params, "clientId", "bluefin-python-client") ), }, @@ -336,7 +338,7 @@ async def deposit_margin_to_bank(self, amount: int, coin_id: str) -> bool: callArgs = [] callArgs.append(self.contracts.get_bank_id()) callArgs.append(self.account.getUserAddress()) - callArgs.append(str(toSuiBase(amount, base=CONTRACTS_BASE_NUM))) + callArgs.append(str(to1e18(amount))) callArgs.append(coin_id) txBytes = rpc_unsafe_moveCall( self.url, @@ -371,7 +373,7 @@ async def withdraw_margin_from_bank(self, amount: Union[float, int]) -> bool: callArgs = [ bank_id, account_address, - str(toSuiBase(amount, base=CONTRACTS_BASE_NUM)), + str(to1e18(amount)), ] txBytes = rpc_unsafe_moveCall( self.url, @@ -438,14 +440,13 @@ async def adjust_leverage(self, symbol, leverage, parentAddress: str = ""): account_address = self.account.address if parentAddress == "" else parentAddress # implies user has an open position on-chain, perform on-chain leverage update - open_position = True if user_position != {}: callArgs = [] callArgs.append(self.contracts.get_perpetual_id(symbol)) callArgs.append(self.contracts.get_bank_id()) callArgs.append(self.contracts.get_sub_account_id()) callArgs.append(account_address) - callArgs.append(str(toDapiBase(leverage))) + callArgs.append(str(to1e18(leverage))) callArgs.append(self.contracts.get_price_oracle_object_id(symbol)) txBytes = rpc_unsafe_moveCall( self.url, @@ -467,7 +468,7 @@ async def adjust_leverage(self, symbol, leverage, parentAddress: str = ""): { "symbol": symbol.value, "address": account_address, - "leverage": toDapiBase(leverage), + "leverage": to1e18(leverage), "marginType": MARGIN_TYPE.ISOLATED.value, }, auth_required=True, @@ -507,7 +508,7 @@ async def adjust_margin( callArgs.append(self.contracts.get_sub_account_id()) callArgs.append(self.account.getUserAddress()) - callArgs.append(str(toDapiBase(amount))) + callArgs.append(str(to1e18(amount))) callArgs.append(self.contracts.get_price_oracle_object_id(symbol)) if operation == ADJUST_MARGIN.ADD: txBytes = rpc_unsafe_moveCall( @@ -894,7 +895,7 @@ async def get_user_leverage(self, symbol: MARKET_SYMBOLS, parentAddress: str = " for i in account_data_by_market: if symbol.value == i["symbol"]: - return fromDapiBase(int(i["selectedLeverage"])) + return from1e18(int(i["selectedLeverage"])) # default leverage on system is 3 # todo fetch from exchange info route return 3 @@ -952,10 +953,3 @@ async def close_connections(self): # close aio http connection await self.apis.close_session() await self.dms_api.close_session() - - def _from_sui_base(self, number: Union[str, int]) -> float: - number = float(number) - return number / float(_SUI_BASE_NUM) - - def _to_sui_base(self, number: Union[int, float]) -> int: - return int(number * _SUI_BASE_NUM) diff --git a/src/bluefin_v2_client/constants.py b/src/bluefin_v2_client/constants.py index 1f95172..89ef94c 100644 --- a/src/bluefin_v2_client/constants.py +++ b/src/bluefin_v2_client/constants.py @@ -64,6 +64,4 @@ }, } -SUI_BASE_NUM = 1000000000 -DAPI_BASE_NUM = 1000000000000000000 -CONTRACTS_BASE_NUM = 1000000 +BASE_1E18 = 1000000000000000000 diff --git a/src/bluefin_v2_client/utilities.py b/src/bluefin_v2_client/utilities.py index 5f3a3d5..72dbd3b 100644 --- a/src/bluefin_v2_client/utilities.py +++ b/src/bluefin_v2_client/utilities.py @@ -3,33 +3,25 @@ # from web3 import Web3 import time +from typing import Union import bip_utils import hashlib -from typing import Union -from .constants import SUI_BASE_NUM, DAPI_BASE_NUM, CONTRACTS_BASE_NUM - - -def toDapiBase(number: Union[int, float]) -> int: - return int(number * DAPI_BASE_NUM) +from .constants import BASE_1E18 -def fromDapiBase(number: Union[int, float], dtype=int) -> int: - return dtype(number / DAPI_BASE_NUM) +def to1e18(number: Union[int, float]) -> int: + """Takes in a number and multiples it by 1e18""" + return int(number * BASE_1E18) -def toSuiBase(number: Union[int, float], base=SUI_BASE_NUM) -> int: - return int(number * base) - - -def fromSuiBase(number: Union[str, int], base=SUI_BASE_NUM) -> float: +def from1e18(number: Union[str, int]) -> float: + """Takes in a number and divides it by 1e18""" number = float(number) - return number / float(base) + return number / float(BASE_1E18) def numberToHex(num, pad=32): - # converting number to Hexadecimal format hexNum = hex(num) - # padding it with zero to make the size 32 bytes padHex = hexNum[2:].zfill(pad) return padHex From 1037c94e3b033e98f03c254ea6d486f8b9370428 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 11:19:44 +0400 Subject: [PATCH 2/7] Bump up client version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b830e93..42ce72e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "bluefin_v2_client" -version = "2.1.0" +version = "3.0.0" description = "Library to interact with Bluefin exchange protocol including its off-chain api-gateway and on-chain contracts" readme = "README.md" requires-python = ">=3.8" From 7330a6d9a6a60e69c27b0f4b8d5c6ca9767a064c Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 11:20:04 +0400 Subject: [PATCH 3/7] Fix version number --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 42ce72e..482148b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "bluefin_v2_client" -version = "3.0.0" +version = "2.1.1" description = "Library to interact with Bluefin exchange protocol including its off-chain api-gateway and on-chain contracts" readme = "README.md" requires-python = ">=3.8" From 4ed6c52489cbc7dd2ca9f814d73ffec8223673d7 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 13:58:42 +0400 Subject: [PATCH 4/7] use 1e6 for deposit withdraw since usdc quantities are in 1e6 --- src/bluefin_v2_client/client.py | 10 +++++----- src/bluefin_v2_client/constants.py | 2 ++ src/bluefin_v2_client/utilities.py | 13 ++++++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/bluefin_v2_client/client.py b/src/bluefin_v2_client/client.py index 7a27456..f1615fa 100644 --- a/src/bluefin_v2_client/client.py +++ b/src/bluefin_v2_client/client.py @@ -338,7 +338,7 @@ async def deposit_margin_to_bank(self, amount: int, coin_id: str) -> bool: callArgs = [] callArgs.append(self.contracts.get_bank_id()) callArgs.append(self.account.getUserAddress()) - callArgs.append(str(to1e18(amount))) + callArgs.append(str(toUsdcBase(amount))) callArgs.append(coin_id) txBytes = rpc_unsafe_moveCall( self.url, @@ -373,7 +373,7 @@ async def withdraw_margin_from_bank(self, amount: Union[float, int]) -> bool: callArgs = [ bank_id, account_address, - str(to1e18(amount)), + str(toUsdcBase(amount)), ] txBytes = rpc_unsafe_moveCall( self.url, @@ -579,7 +579,7 @@ async def get_native_chain_token_balance(self) -> float: result = rpc_call_sui_function( self.url, callArgs, method="suix_getBalance" )["totalBalance"] - return self._from_sui_base(result) + return from1e18(result) except Exception as e: raise (Exception(f"Failed to get balance, error: {e}")) @@ -607,7 +607,7 @@ async def get_usdc_balance(self) -> float: result = rpc_call_sui_function( self.url, callArgs, method="suix_getBalance" )["totalBalance"] - return self._from_sui_base(result) + return from1e18(result) except Exception as e: raise (Exception("Failed to get balance, Exception: {}".format(e))) @@ -626,7 +626,7 @@ async def get_margin_bank_balance(self) -> float: self.url, call_args, method="suix_getDynamicFieldObject" ) - balance = fromDapiBase( + balance = from1e18( result["data"]["content"]["fields"]["value"]["fields"]["balance"] ) return balance diff --git a/src/bluefin_v2_client/constants.py b/src/bluefin_v2_client/constants.py index 89ef94c..fb69548 100644 --- a/src/bluefin_v2_client/constants.py +++ b/src/bluefin_v2_client/constants.py @@ -65,3 +65,5 @@ } BASE_1E18 = 1000000000000000000 +# 1e6 for USDC token +BASE_1E6 = 1000000 diff --git a/src/bluefin_v2_client/utilities.py b/src/bluefin_v2_client/utilities.py index 72dbd3b..c79965b 100644 --- a/src/bluefin_v2_client/utilities.py +++ b/src/bluefin_v2_client/utilities.py @@ -6,7 +6,7 @@ from typing import Union import bip_utils import hashlib -from .constants import BASE_1E18 +from .constants import BASE_1E18, BASE_1E6 def to1e18(number: Union[int, float]) -> int: @@ -20,6 +20,17 @@ def from1e18(number: Union[str, int]) -> float: return number / float(BASE_1E18) +def toUsdcBase(number: Union[int, float]) -> int: + """Converts a number to usdc contract onchain representation i.e. multiply it by 1e6""" + return int(number * BASE_1E6) + + +def fromUsdcBase(number: Union[str, int]) -> float: + """Converts a usdc quantity to number i.e. divide it by 1e6""" + number = float(number) + return number / float(BASE_1E6) + + def numberToHex(num, pad=32): hexNum = hex(num) # padding it with zero to make the size 32 bytes From a2a3b45e75b9737175b188c05b5cb60702177d47 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 14:02:16 +0400 Subject: [PATCH 5/7] Define default leverage as constant --- src/bluefin_v2_client/client.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bluefin_v2_client/client.py b/src/bluefin_v2_client/client.py index f1615fa..35403bb 100644 --- a/src/bluefin_v2_client/client.py +++ b/src/bluefin_v2_client/client.py @@ -15,6 +15,8 @@ from .interfaces import * from .enumerations import * +DEAULT_EXCHANGE_LEVERAGE = 3 + class BluefinClient: """ @@ -896,9 +898,8 @@ async def get_user_leverage(self, symbol: MARKET_SYMBOLS, parentAddress: str = " for i in account_data_by_market: if symbol.value == i["symbol"]: return from1e18(int(i["selectedLeverage"])) - # default leverage on system is 3 # todo fetch from exchange info route - return 3 + return DEAULT_EXCHANGE_LEVERAGE async def get_cancel_on_disconnect_timer( self, params: GetCancelOnDisconnectTimerRequest = None From fc299b1558337a9ce2cc47845bbdafc721b3ddb8 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 14:02:32 +0400 Subject: [PATCH 6/7] Remove unused imports --- src/bluefin_v2_client/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bluefin_v2_client/client.py b/src/bluefin_v2_client/client.py index 35403bb..01531fa 100644 --- a/src/bluefin_v2_client/client.py +++ b/src/bluefin_v2_client/client.py @@ -5,7 +5,7 @@ from .contracts import Contracts from .order_signer import OrderSigner from .onboarding_signer import OnboardingSigner -from .constants import TIME, SERVICE_URLS, CONTRACTS_BASE_NUM +from .constants import TIME, SERVICE_URLS from .sockets_lib import Sockets from .websocket_client import WebsocketClient from .signer import Signer From c3412017b2f2d8f2a50b4977e3d3e64eaca70187 Mon Sep 17 00:00:00 2001 From: yasir_ejaz Date: Mon, 11 Sep 2023 15:37:22 +0400 Subject: [PATCH 7/7] Use suiBase for direct sui chain calls --- src/bluefin_v2_client/client.py | 4 ++-- src/bluefin_v2_client/constants.py | 4 ---- src/bluefin_v2_client/utilities.py | 12 +++++++++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/bluefin_v2_client/client.py b/src/bluefin_v2_client/client.py index 01531fa..f37de47 100644 --- a/src/bluefin_v2_client/client.py +++ b/src/bluefin_v2_client/client.py @@ -581,7 +581,7 @@ async def get_native_chain_token_balance(self) -> float: result = rpc_call_sui_function( self.url, callArgs, method="suix_getBalance" )["totalBalance"] - return from1e18(result) + return fromSuiBase(result) except Exception as e: raise (Exception(f"Failed to get balance, error: {e}")) @@ -609,7 +609,7 @@ async def get_usdc_balance(self) -> float: result = rpc_call_sui_function( self.url, callArgs, method="suix_getBalance" )["totalBalance"] - return from1e18(result) + return fromSuiBase(result) except Exception as e: raise (Exception("Failed to get balance, Exception: {}".format(e))) diff --git a/src/bluefin_v2_client/constants.py b/src/bluefin_v2_client/constants.py index fb69548..83346c0 100644 --- a/src/bluefin_v2_client/constants.py +++ b/src/bluefin_v2_client/constants.py @@ -63,7 +63,3 @@ "ORDERS_HASH": "/orders/hash", }, } - -BASE_1E18 = 1000000000000000000 -# 1e6 for USDC token -BASE_1E6 = 1000000 diff --git a/src/bluefin_v2_client/utilities.py b/src/bluefin_v2_client/utilities.py index c79965b..fcb59bd 100644 --- a/src/bluefin_v2_client/utilities.py +++ b/src/bluefin_v2_client/utilities.py @@ -6,7 +6,11 @@ from typing import Union import bip_utils import hashlib -from .constants import BASE_1E18, BASE_1E6 + + +BASE_1E18 = 1000000000000000000 +BASE_1E6 = 1000000 # 1e6 for USDC token +BASE_1E9 = 1000000000 def to1e18(number: Union[int, float]) -> int: @@ -20,6 +24,12 @@ def from1e18(number: Union[str, int]) -> float: return number / float(BASE_1E18) +def fromSuiBase(number: Union[str, int]) -> float: + """Takes in a number and divides it by 1e9""" + number = float(number) + return number / float(BASE_1E9) + + def toUsdcBase(number: Union[int, float]) -> int: """Converts a number to usdc contract onchain representation i.e. multiply it by 1e6""" return int(number * BASE_1E6)