diff --git a/examples/chain_client/0_LocalOrderHash.py b/examples/chain_client/1_LocalOrderHash.py similarity index 75% rename from examples/chain_client/0_LocalOrderHash.py rename to examples/chain_client/1_LocalOrderHash.py index 770ad5bf..fbec8988 100644 --- a/examples/chain_client/0_LocalOrderHash.py +++ b/examples/chain_client/1_LocalOrderHash.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv @@ -40,57 +41,59 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" spot_orders = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=0.524, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("0.524"), + quantity=Decimal("0.01"), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=27.92, - quantity=0.01, - is_buy=False, - is_po=False, + price=Decimal("27.92"), + quantity=Decimal("0.01"), + order_type="SELL", cid=str(uuid.uuid4()), ), ] derivative_orders = [ - composer.DerivativeOrder( + composer.derivative_order( market_id=deriv_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=10500, - quantity=0.01, - leverage=1.5, - is_buy=True, - is_po=False, + price=Decimal(10500), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(10500), leverage=Decimal(2), is_reduce_only=False + ), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.DerivativeOrder( + composer.derivative_order( market_id=deriv_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=65111, - quantity=0.01, - leverage=2, - is_buy=False, - is_reduce_only=False, + price=Decimal(65111), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(65111), leverage=Decimal(2), is_reduce_only=False + ), + order_type="SELL", cid=str(uuid.uuid4()), ), ] # prepare tx msg - spot_msg = composer.MsgBatchCreateSpotLimitOrders(sender=address.to_acc_bech32(), orders=spot_orders) + spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders) - deriv_msg = composer.MsgBatchCreateDerivativeLimitOrders(sender=address.to_acc_bech32(), orders=derivative_orders) + deriv_msg = composer.msg_batch_create_derivative_limit_orders( + sender=address.to_acc_bech32(), orders=derivative_orders + ) # compute order hashes order_hashes = order_hash_manager.compute_order_hashes( @@ -167,57 +170,59 @@ async def main() -> None: print("gas fee: {} INJ".format(gas_fee)) spot_orders = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id_2, fee_recipient=fee_recipient, - price=1.524, - quantity=0.01, - is_buy=True, - is_po=True, + price=Decimal("1.524"), + quantity=Decimal("0.01"), + order_type="BUY_PO", cid=str(uuid.uuid4()), ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id_2, fee_recipient=fee_recipient, - price=27.92, - quantity=0.01, - is_buy=False, - is_po=False, + price=Decimal("27.92"), + quantity=Decimal("0.01"), + order_type="SELL_PO", cid=str(uuid.uuid4()), ), ] derivative_orders = [ - composer.DerivativeOrder( + composer.derivative_order( market_id=deriv_market_id, subaccount_id=subaccount_id_2, fee_recipient=fee_recipient, - price=25111, - quantity=0.01, - leverage=1.5, - is_buy=True, - is_po=False, + price=Decimal(25111), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal("1.5"), is_reduce_only=False + ), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.DerivativeOrder( + composer.derivative_order( market_id=deriv_market_id, subaccount_id=subaccount_id_2, fee_recipient=fee_recipient, - price=65111, - quantity=0.01, - leverage=2, - is_buy=False, - is_reduce_only=False, + price=Decimal(65111), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(25111), leverage=Decimal(2), is_reduce_only=False + ), + order_type="SELL", cid=str(uuid.uuid4()), ), ] # prepare tx msg - spot_msg = composer.MsgBatchCreateSpotLimitOrders(sender=address.to_acc_bech32(), orders=spot_orders) + spot_msg = composer.msg_batch_create_spot_limit_orders(sender=address.to_acc_bech32(), orders=spot_orders) - deriv_msg = composer.MsgBatchCreateDerivativeLimitOrders(sender=address.to_acc_bech32(), orders=derivative_orders) + deriv_msg = composer.msg_batch_create_derivative_limit_orders( + sender=address.to_acc_bech32(), orders=derivative_orders + ) # compute order hashes order_hashes = order_hash_manager.compute_order_hashes( diff --git a/examples/chain_client/38_StreamEventOrderFail.py b/examples/chain_client/2_StreamEventOrderFail.py similarity index 100% rename from examples/chain_client/38_StreamEventOrderFail.py rename to examples/chain_client/2_StreamEventOrderFail.py diff --git a/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py b/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py deleted file mode 100644 index 7b8a6567..00000000 --- a/examples/chain_client/35_MsgInstantBinaryOptionsMarketLaunch.py +++ /dev/null @@ -1,98 +0,0 @@ -import asyncio -import os - -import dotenv -from grpc import RpcError - -from pyinjective.async_client import AsyncClient -from pyinjective.constant import GAS_FEE_BUFFER_AMOUNT, GAS_PRICE -from pyinjective.core.network import Network -from pyinjective.transaction import Transaction -from pyinjective.wallet import PrivateKey - - -async def main() -> None: - dotenv.load_dotenv() - configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY") - - # select network: local, testnet, mainnet - network = Network.testnet() - - # initialize grpc client - client = AsyncClient(network) - composer = await client.composer() - await client.sync_timeout_height() - - # load account - priv_key = PrivateKey.from_hex(configured_private_key) - pub_key = priv_key.to_public_key() - address = pub_key.to_address() - await client.fetch_account(address.to_acc_bech32()) - - # prepare tx msg - msg = composer.MsgInstantBinaryOptionsMarketLaunch( - sender=address.to_acc_bech32(), - admin=address.to_acc_bech32(), - ticker="UFC-KHABIB-TKO-05/30/2023", - oracle_symbol="UFC-KHABIB-TKO-05/30/2023", - oracle_provider="UFC", - oracle_type="Provider", - quote_denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7", - quote_decimals=6, - oracle_scale_factor=6, - maker_fee_rate=0.0005, # 0.05% - taker_fee_rate=0.0010, # 0.10% - expiration_timestamp=1680730982, - settlement_timestamp=1690730982, - min_price_tick_size=0.01, - min_quantity_tick_size=0.01, - ) - - # build sim tx - tx = ( - Transaction() - .with_messages(msg) - .with_sequence(client.get_sequence()) - .with_account_num(client.get_number()) - .with_chain_id(network.chain_id) - ) - sim_sign_doc = tx.get_sign_doc(pub_key) - sim_sig = priv_key.sign(sim_sign_doc.SerializeToString()) - sim_tx_raw_bytes = tx.get_tx_data(sim_sig, pub_key) - - # simulate tx - try: - sim_res = await client.simulate(sim_tx_raw_bytes) - except RpcError as ex: - print(ex) - return - - sim_res_msg = sim_res["result"]["msgResponses"] - print("---Simulation Response---") - print(sim_res_msg) - - # build tx - gas_price = GAS_PRICE - gas_limit = int(sim_res["gasInfo"]["gasUsed"]) + GAS_FEE_BUFFER_AMOUNT # add buffer for gas fee computation - gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0") - fee = [ - composer.coin( - amount=gas_price * gas_limit, - denom=network.fee_denom, - ) - ] - tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height) - sign_doc = tx.get_sign_doc(pub_key) - sig = priv_key.sign(sign_doc.SerializeToString()) - tx_raw_bytes = tx.get_tx_data(sig, pub_key) - - # broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode - res = await client.broadcast_tx_sync_mode(tx_raw_bytes) - print("---Transaction Response---") - print(res) - print("gas wanted: {}".format(gas_limit)) - print("gas fee: {} INJ".format(gas_fee)) - - -if __name__ == "__main__": - asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/44_MessageBroadcaster.py b/examples/chain_client/3_MessageBroadcaster.py similarity index 84% rename from examples/chain_client/44_MessageBroadcaster.py rename to examples/chain_client/3_MessageBroadcaster.py index 114a8700..6bd67033 100644 --- a/examples/chain_client/44_MessageBroadcaster.py +++ b/examples/chain_client/3_MessageBroadcaster.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv @@ -34,24 +35,22 @@ async def main() -> None: spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" spot_orders_to_create = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=3, - quantity=55, - is_buy=True, - is_po=False, - cid=str(uuid.uuid4()), + price=Decimal("3"), + quantity=Decimal("55"), + order_type="BUY", + cid=(str(uuid.uuid4())), ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=300, - quantity=55, - is_buy=False, - is_po=False, + price=Decimal("300"), + quantity=Decimal("55"), + order_type="SELL", cid=str(uuid.uuid4()), ), ] diff --git a/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py b/examples/chain_client/4_MessageBroadcasterWithGranteeAccount.py similarity index 91% rename from examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py rename to examples/chain_client/4_MessageBroadcasterWithGranteeAccount.py index 8c0166e2..4e08397b 100644 --- a/examples/chain_client/45_MessageBroadcasterWithGranteeAccount.py +++ b/examples/chain_client/4_MessageBroadcasterWithGranteeAccount.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv @@ -40,15 +41,14 @@ async def main() -> None: granter_address = Address.from_acc_bech32(granter_inj_address) granter_subaccount_id = granter_address.get_subaccount_id(index=0) - msg = composer.MsgCreateSpotLimitOrder( - sender=granter_inj_address, + msg = composer.msg_create_spot_limit_order( market_id=market_id, + sender=granter_inj_address, subaccount_id=granter_subaccount_id, fee_recipient=address.to_acc_bech32(), - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py b/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py similarity index 86% rename from examples/chain_client/46_MessageBroadcasterWithoutSimulation.py rename to examples/chain_client/5_MessageBroadcasterWithoutSimulation.py index e6e87c5a..54a79bf8 100644 --- a/examples/chain_client/46_MessageBroadcasterWithoutSimulation.py +++ b/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv @@ -34,24 +35,22 @@ async def main() -> None: spot_market_id_create = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" spot_orders_to_create = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=3, - quantity=55, - is_buy=True, - is_po=False, + price=Decimal("3"), + quantity=Decimal("55"), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=300, - quantity=55, - is_buy=False, - is_po=False, + price=Decimal("300"), + quantity=Decimal("55"), + order_type="SELL", cid=str(uuid.uuid4()), ), ] diff --git a/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py b/examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py similarity index 91% rename from examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py rename to examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py index b95114b7..4b7fbd2e 100644 --- a/examples/chain_client/47_MessageBroadcasterWithGranteeAccountWithoutSimulation.py +++ b/examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv @@ -39,15 +40,14 @@ async def main() -> None: granter_address = Address.from_acc_bech32(granter_inj_address) granter_subaccount_id = granter_address.get_subaccount_id(index=0) - msg = composer.MsgCreateSpotLimitOrder( - sender=granter_inj_address, + msg = composer.msg_create_spot_limit_order( market_id=market_id, + sender=granter_inj_address, subaccount_id=granter_subaccount_id, fee_recipient=address.to_acc_bech32(), - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/49_ChainStream.py b/examples/chain_client/7_ChainStream.py similarity index 100% rename from examples/chain_client/49_ChainStream.py rename to examples/chain_client/7_ChainStream.py diff --git a/examples/chain_client/18_MsgBid.py b/examples/chain_client/auction/1_MsgBid.py similarity index 100% rename from examples/chain_client/18_MsgBid.py rename to examples/chain_client/auction/1_MsgBid.py diff --git a/examples/chain_client/39_Account.py b/examples/chain_client/auth/query/1_Account.py similarity index 100% rename from examples/chain_client/39_Account.py rename to examples/chain_client/auth/query/1_Account.py diff --git a/examples/chain_client/19_MsgGrant.py b/examples/chain_client/authz/1_MsgGrant.py similarity index 100% rename from examples/chain_client/19_MsgGrant.py rename to examples/chain_client/authz/1_MsgGrant.py diff --git a/examples/chain_client/20_MsgExec.py b/examples/chain_client/authz/2_MsgExec.py similarity index 95% rename from examples/chain_client/20_MsgExec.py rename to examples/chain_client/authz/2_MsgExec.py index 1203ff90..8d9891a5 100644 --- a/examples/chain_client/20_MsgExec.py +++ b/examples/chain_client/authz/2_MsgExec.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -37,15 +38,14 @@ async def main() -> None: granter_address = Address.from_acc_bech32(granter_inj_address) granter_subaccount_id = granter_address.get_subaccount_id(index=0) - msg0 = composer.MsgCreateSpotLimitOrder( + msg0 = composer.msg_create_spot_limit_order( sender=granter_inj_address, market_id=market_id, subaccount_id=granter_subaccount_id, fee_recipient=grantee, - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/21_MsgRevoke.py b/examples/chain_client/authz/3_MsgRevoke.py similarity index 100% rename from examples/chain_client/21_MsgRevoke.py rename to examples/chain_client/authz/3_MsgRevoke.py diff --git a/examples/chain_client/76_MsgExecuteContractCompat.py b/examples/chain_client/authz/4_MsgExecuteContractCompat.py similarity index 100% rename from examples/chain_client/76_MsgExecuteContractCompat.py rename to examples/chain_client/authz/4_MsgExecuteContractCompat.py diff --git a/examples/chain_client/27_Grants.py b/examples/chain_client/authz/query/1_Grants.py similarity index 100% rename from examples/chain_client/27_Grants.py rename to examples/chain_client/authz/query/1_Grants.py diff --git a/examples/chain_client/1_MsgSend.py b/examples/chain_client/bank/1_MsgSend.py similarity index 100% rename from examples/chain_client/1_MsgSend.py rename to examples/chain_client/bank/1_MsgSend.py diff --git a/examples/chain_client/57_SendEnabled.py b/examples/chain_client/bank/query/10_SendEnabled.py similarity index 100% rename from examples/chain_client/57_SendEnabled.py rename to examples/chain_client/bank/query/10_SendEnabled.py diff --git a/examples/chain_client/29_BankBalance.py b/examples/chain_client/bank/query/1_BankBalance.py similarity index 100% rename from examples/chain_client/29_BankBalance.py rename to examples/chain_client/bank/query/1_BankBalance.py diff --git a/examples/chain_client/28_BankBalances.py b/examples/chain_client/bank/query/2_BankBalances.py similarity index 100% rename from examples/chain_client/28_BankBalances.py rename to examples/chain_client/bank/query/2_BankBalances.py diff --git a/examples/chain_client/50_SpendableBalances.py b/examples/chain_client/bank/query/3_SpendableBalances.py similarity index 100% rename from examples/chain_client/50_SpendableBalances.py rename to examples/chain_client/bank/query/3_SpendableBalances.py diff --git a/examples/chain_client/51_SpendableBalancesByDenom.py b/examples/chain_client/bank/query/4_SpendableBalancesByDenom.py similarity index 100% rename from examples/chain_client/51_SpendableBalancesByDenom.py rename to examples/chain_client/bank/query/4_SpendableBalancesByDenom.py diff --git a/examples/chain_client/52_TotalSupply.py b/examples/chain_client/bank/query/5_TotalSupply.py similarity index 100% rename from examples/chain_client/52_TotalSupply.py rename to examples/chain_client/bank/query/5_TotalSupply.py diff --git a/examples/chain_client/53_SupplyOf.py b/examples/chain_client/bank/query/6_SupplyOf.py similarity index 100% rename from examples/chain_client/53_SupplyOf.py rename to examples/chain_client/bank/query/6_SupplyOf.py diff --git a/examples/chain_client/54_DenomMetadata.py b/examples/chain_client/bank/query/7_DenomMetadata.py similarity index 100% rename from examples/chain_client/54_DenomMetadata.py rename to examples/chain_client/bank/query/7_DenomMetadata.py diff --git a/examples/chain_client/55_DenomsMetadata.py b/examples/chain_client/bank/query/8_DenomsMetadata.py similarity index 100% rename from examples/chain_client/55_DenomsMetadata.py rename to examples/chain_client/bank/query/8_DenomsMetadata.py diff --git a/examples/chain_client/56_DenomOwners.py b/examples/chain_client/bank/query/9_DenomOwners.py similarity index 100% rename from examples/chain_client/56_DenomOwners.py rename to examples/chain_client/bank/query/9_DenomOwners.py diff --git a/examples/chain_client/exchange/6_MsgCreateDerivativeLimitOrder.py b/examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py similarity index 90% rename from examples/chain_client/exchange/6_MsgCreateDerivativeLimitOrder.py rename to examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py index 41a19307..4e0ff327 100644 --- a/examples/chain_client/exchange/6_MsgCreateDerivativeLimitOrder.py +++ b/examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -36,16 +37,17 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" # prepare tx msg - msg = composer.MsgCreateDerivativeLimitOrder( + msg = composer.msg_create_derivative_limit_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=50000, - quantity=0.1, - leverage=1, - is_buy=False, - is_reduce_only=False, + price=Decimal(50000), + quantity=Decimal(0.1), + margin=composer.calculate_margin( + quantity=Decimal(0.1), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False + ), + order_type="SELL", cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/exchange/7_MsgCreateDerivativeMarketOrder.py b/examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py similarity index 90% rename from examples/chain_client/exchange/7_MsgCreateDerivativeMarketOrder.py rename to examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py index 37b305ed..dfedf6d6 100644 --- a/examples/chain_client/exchange/7_MsgCreateDerivativeMarketOrder.py +++ b/examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -36,15 +37,16 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" # prepare tx msg - msg = composer.MsgCreateDerivativeMarketOrder( + msg = composer.msg_create_derivative_market_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=50000, - quantity=0.01, - leverage=3, - is_buy=True, + price=Decimal(50000), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(50000), leverage=Decimal(3), is_reduce_only=False + ), cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/exchange/8_MsgCancelDerivativeOrder.py b/examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py similarity index 98% rename from examples/chain_client/exchange/8_MsgCancelDerivativeOrder.py rename to examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py index 43180b1f..20be2bd0 100644 --- a/examples/chain_client/exchange/8_MsgCancelDerivativeOrder.py +++ b/examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py @@ -35,7 +35,7 @@ async def main() -> None: order_hash = "0x667ee6f37f6d06bf473f4e1434e92ac98ff43c785405e2a511a0843daeca2de9" # prepare tx msg - msg = composer.MsgCancelDerivativeOrder( + msg = composer.msg_cancel_derivative_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, order_hash=order_hash ) diff --git a/examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py b/examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py new file mode 100644 index 00000000..a1ebde82 --- /dev/null +++ b/examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py @@ -0,0 +1,61 @@ +import asyncio +import os + +import dotenv + +from pyinjective.async_client import AsyncClient +from pyinjective.core.broadcaster import MsgBroadcasterWithPk +from pyinjective.core.network import Network +from pyinjective.wallet import PrivateKey + + +async def main() -> None: + dotenv.load_dotenv() + configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY") + + # select network: local, testnet, mainnet + network = Network.testnet() + + # initialize grpc client + client = AsyncClient(network) + composer = await client.composer() + await client.sync_timeout_height() + + message_broadcaster = MsgBroadcasterWithPk.new_using_simulation( + network=network, + private_key=configured_private_key, + ) + + # load account + priv_key = PrivateKey.from_hex(configured_private_key) + pub_key = priv_key.to_public_key() + address = pub_key.to_address() + await client.fetch_account(address.to_acc_bech32()) + + # prepare tx msg + message = composer.msg_instant_binary_options_market_launch( + sender=address.to_acc_bech32(), + ticker="UFC-KHABIB-TKO-05/30/2023", + oracle_symbol="UFC-KHABIB-TKO-05/30/2023", + oracle_provider="UFC", + oracle_type="Provider", + quote_decimals=6, + oracle_scale_factor=6, + maker_fee_rate=0.0005, # 0.05% + taker_fee_rate=0.0010, # 0.10% + expiration_timestamp=1680730982, + settlement_timestamp=1690730982, + admin=address.to_acc_bech32(), + quote_denom="peggy0xdAC17F958D2ee523a2206206994597C13D831ec7", + min_price_tick_size=0.01, + min_quantity_tick_size=0.01, + ) + + # broadcast the transaction + result = await message_broadcaster.broadcast([message]) + print("---Transaction Response---") + print(result) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/exchange/16_MsgCreateBinaryOptionsLimitOrder.py b/examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py similarity index 93% rename from examples/chain_client/exchange/16_MsgCreateBinaryOptionsLimitOrder.py rename to examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py index 2a58e173..5ad8c59e 100644 --- a/examples/chain_client/exchange/16_MsgCreateBinaryOptionsLimitOrder.py +++ b/examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -40,17 +41,17 @@ async def main() -> None: denom = Denom(description="desc", base=0, quote=6, min_price_tick_size=1000, min_quantity_tick_size=0.0001) # prepare tx msg - msg = composer.MsgCreateBinaryOptionsLimitOrder( + msg = composer.msg_create_binary_options_limit_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=0.5, - quantity=1, - is_buy=False, - is_reduce_only=False, - denom=denom, + price=Decimal("0.5"), + quantity=Decimal("1"), + margin=Decimal("0.5"), + order_type="BUY", cid=str(uuid.uuid4()), + denom=denom, ) # build sim tx diff --git a/examples/chain_client/exchange/17_MsgCreateBinaryOptionsMarketOrder.py b/examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py similarity index 90% rename from examples/chain_client/exchange/17_MsgCreateBinaryOptionsMarketOrder.py rename to examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py index 2d07658f..9b68bc85 100644 --- a/examples/chain_client/exchange/17_MsgCreateBinaryOptionsMarketOrder.py +++ b/examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -36,15 +37,16 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" # prepare tx msg - msg = composer.MsgCreateBinaryOptionsMarketOrder( + msg = composer.msg_create_binary_options_market_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=0.5, - quantity=1, - is_buy=True, - is_reduce_only=False, + price=Decimal("0.5"), + quantity=Decimal(1), + margin=composer.calculate_margin( + quantity=Decimal(1), price=Decimal("0.5"), leverage=Decimal(1), is_reduce_only=False + ), cid=str(uuid.uuid4()), ) # build sim tx diff --git a/examples/chain_client/exchange/18_MsgCancelBinaryOptionsOrder.py b/examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py similarity index 98% rename from examples/chain_client/exchange/18_MsgCancelBinaryOptionsOrder.py rename to examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py index 82107f3c..582c6dc6 100644 --- a/examples/chain_client/exchange/18_MsgCancelBinaryOptionsOrder.py +++ b/examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py @@ -35,7 +35,7 @@ async def main() -> None: order_hash = "a975fbd72b874bdbf5caf5e1e8e2653937f33ce6dd14d241c06c8b1f7b56be46" # prepare tx msg - msg = composer.MsgCancelBinaryOptionsOrder( + msg = composer.msg_cancel_binary_options_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, order_hash=order_hash ) # build sim tx diff --git a/examples/chain_client/exchange/10_MsgSubaccountTransfer.py b/examples/chain_client/exchange/17_MsgSubaccountTransfer.py similarity index 96% rename from examples/chain_client/exchange/10_MsgSubaccountTransfer.py rename to examples/chain_client/exchange/17_MsgSubaccountTransfer.py index b68717b2..a50fc0cf 100644 --- a/examples/chain_client/exchange/10_MsgSubaccountTransfer.py +++ b/examples/chain_client/exchange/17_MsgSubaccountTransfer.py @@ -1,5 +1,6 @@ import asyncio import os +from decimal import Decimal import dotenv from grpc import RpcError @@ -32,11 +33,11 @@ async def main() -> None: dest_subaccount_id = address.get_subaccount_id(index=1) # prepare tx msg - msg = composer.MsgSubaccountTransfer( + msg = composer.msg_subaccount_transfer( sender=address.to_acc_bech32(), source_subaccount_id=subaccount_id, destination_subaccount_id=dest_subaccount_id, - amount=100, + amount=Decimal(100), denom="INJ", ) diff --git a/examples/chain_client/exchange/15_ExternalTransfer.py b/examples/chain_client/exchange/18_MsgExternalTransfer.py similarity index 96% rename from examples/chain_client/exchange/15_ExternalTransfer.py rename to examples/chain_client/exchange/18_MsgExternalTransfer.py index 3200be34..2bcc86a1 100644 --- a/examples/chain_client/exchange/15_ExternalTransfer.py +++ b/examples/chain_client/exchange/18_MsgExternalTransfer.py @@ -1,5 +1,6 @@ import asyncio import os +from decimal import Decimal import dotenv from grpc import RpcError @@ -32,11 +33,11 @@ async def main() -> None: dest_subaccount_id = "0xaf79152ac5df276d9a8e1e2e22822f9713474902000000000000000000000000" # prepare tx msg - msg = composer.MsgExternalTransfer( + msg = composer.msg_external_transfer( sender=address.to_acc_bech32(), source_subaccount_id=subaccount_id, destination_subaccount_id=dest_subaccount_id, - amount=100, + amount=Decimal(100), denom="INJ", ) diff --git a/examples/chain_client/exchange/19_MsgLiquidatePosition.py b/examples/chain_client/exchange/19_MsgLiquidatePosition.py index d80ba385..9788b865 100644 --- a/examples/chain_client/exchange/19_MsgLiquidatePosition.py +++ b/examples/chain_client/exchange/19_MsgLiquidatePosition.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -36,19 +37,21 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" cid = str(uuid.uuid4()) - order = composer.DerivativeOrder( + order = composer.derivative_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=39.01, # This should be the liquidation price - quantity=0.147, - leverage=1, + price=Decimal(39.01), # This should be the liquidation price + quantity=Decimal(0.147), + margin=composer.calculate_margin( + quantity=Decimal(0.147), price=Decimal(39.01), leverage=Decimal(1), is_reduce_only=False + ), + order_type="SELL", cid=cid, - is_buy=False, ) # prepare tx msg - msg = composer.MsgLiquidatePosition( + msg = composer.msg_liquidate_position( sender=address.to_acc_bech32(), subaccount_id="0x156df4d5bc8e7dd9191433e54bd6a11eeb390921000000000000000000000000", market_id=market_id, diff --git a/examples/chain_client/exchange/1_MsgDeposit.py b/examples/chain_client/exchange/1_MsgDeposit.py index 80b9f652..bbf64710 100644 --- a/examples/chain_client/exchange/1_MsgDeposit.py +++ b/examples/chain_client/exchange/1_MsgDeposit.py @@ -31,7 +31,9 @@ async def main() -> None: subaccount_id = address.get_subaccount_id(index=0) # prepare tx msg - msg = composer.MsgDeposit(sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=0.000001, denom="INJ") + msg = composer.msg_deposit( + sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=0.000001, denom="INJ" + ) # build sim tx tx = ( diff --git a/examples/chain_client/13_MsgIncreasePositionMargin.py b/examples/chain_client/exchange/20_MsgIncreasePositionMargin.py similarity index 96% rename from examples/chain_client/13_MsgIncreasePositionMargin.py rename to examples/chain_client/exchange/20_MsgIncreasePositionMargin.py index 775a41e5..276276e7 100644 --- a/examples/chain_client/13_MsgIncreasePositionMargin.py +++ b/examples/chain_client/exchange/20_MsgIncreasePositionMargin.py @@ -1,5 +1,6 @@ import asyncio import os +from decimal import Decimal import dotenv from grpc import RpcError @@ -34,12 +35,12 @@ async def main() -> None: market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" # prepare tx msg - msg = composer.MsgIncreasePositionMargin( + msg = composer.msg_increase_position_margin( sender=address.to_acc_bech32(), market_id=market_id, source_subaccount_id=subaccount_id, destination_subaccount_id=subaccount_id, - amount=2, + amount=Decimal(2), ) # build sim tx diff --git a/examples/chain_client/exchange/12_MsgRewardsOptOut.py b/examples/chain_client/exchange/21_MsgRewardsOptOut.py similarity index 97% rename from examples/chain_client/exchange/12_MsgRewardsOptOut.py rename to examples/chain_client/exchange/21_MsgRewardsOptOut.py index 8beaa1f4..2306b541 100644 --- a/examples/chain_client/exchange/12_MsgRewardsOptOut.py +++ b/examples/chain_client/exchange/21_MsgRewardsOptOut.py @@ -30,7 +30,7 @@ async def main() -> None: await client.fetch_account(address.to_acc_bech32()) # prepare tx msg - msg = composer.MsgRewardsOptOut(sender=address.to_acc_bech32()) + msg = composer.msg_rewards_opt_out(sender=address.to_acc_bech32()) # build sim tx tx = ( diff --git a/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py b/examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py similarity index 96% rename from examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py rename to examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py index 0f39dcdb..b638b28a 100644 --- a/examples/chain_client/34_MsgAdminUpdateBinaryOptionsMarket.py +++ b/examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py @@ -1,5 +1,6 @@ import asyncio import os +from decimal import Decimal import dotenv from grpc import RpcError @@ -32,12 +33,12 @@ async def main() -> None: # prepare trade info market_id = "0xfafec40a7b93331c1fc89c23f66d11fbb48f38dfdd78f7f4fc4031fad90f6896" status = "Demolished" - settlement_price = 1 + settlement_price = Decimal(1) expiration_timestamp = 1685460582 settlement_timestamp = 1690730982 # prepare tx msg - msg = composer.MsgAdminUpdateBinaryOptionsMarket( + msg = composer.msg_admin_update_binary_options_market( sender=address.to_acc_bech32(), market_id=market_id, settlement_price=settlement_price, diff --git a/examples/chain_client/exchange/9_MsgWithdraw.py b/examples/chain_client/exchange/2_MsgWithdraw.py similarity index 95% rename from examples/chain_client/exchange/9_MsgWithdraw.py rename to examples/chain_client/exchange/2_MsgWithdraw.py index b198c0aa..1070d28c 100644 --- a/examples/chain_client/exchange/9_MsgWithdraw.py +++ b/examples/chain_client/exchange/2_MsgWithdraw.py @@ -31,7 +31,7 @@ async def main() -> None: subaccount_id = address.get_subaccount_id(index=0) # prepare tx msg - msg = composer.MsgWithdraw(sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=1, denom="USDT") + msg = composer.msg_withdraw(sender=address.to_acc_bech32(), subaccount_id=subaccount_id, amount=1, denom="USDT") # build sim tx tx = ( diff --git a/examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py b/examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py new file mode 100644 index 00000000..90a177ec --- /dev/null +++ b/examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py @@ -0,0 +1,54 @@ +import asyncio +import os +from decimal import Decimal + +import dotenv + +from pyinjective.async_client import AsyncClient +from pyinjective.core.broadcaster import MsgBroadcasterWithPk +from pyinjective.core.network import Network +from pyinjective.wallet import PrivateKey + + +async def main() -> None: + dotenv.load_dotenv() + configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY") + + # select network: local, testnet, mainnet + network = Network.testnet() + + # initialize grpc client + client = AsyncClient(network) + await client.initialize_tokens_from_chain_denoms() + composer = await client.composer() + await client.sync_timeout_height() + + message_broadcaster = MsgBroadcasterWithPk.new_using_simulation( + network=network, + private_key=configured_private_key, + ) + + # load account + priv_key = PrivateKey.from_hex(configured_private_key) + pub_key = priv_key.to_public_key() + address = pub_key.to_address() + await client.fetch_account(address.to_acc_bech32()) + + # prepare tx msg + message = composer.msg_instant_spot_market_launch( + sender=address.to_acc_bech32(), + ticker="INJ/USDC", + base_denom="INJ", + quote_denom="USDC", + min_price_tick_size=Decimal("0.001"), + min_quantity_tick_size=Decimal("0.01"), + ) + + # broadcast the transaction + result = await message_broadcaster.broadcast([message]) + print("---Transaction Response---") + print(result) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/exchange/4_MsgInstantPerpetualMarketLaunch.py b/examples/chain_client/exchange/4_MsgInstantPerpetualMarketLaunch.py new file mode 100644 index 00000000..b2b5dff4 --- /dev/null +++ b/examples/chain_client/exchange/4_MsgInstantPerpetualMarketLaunch.py @@ -0,0 +1,61 @@ +import asyncio +import os +from decimal import Decimal + +import dotenv + +from pyinjective.async_client import AsyncClient +from pyinjective.core.broadcaster import MsgBroadcasterWithPk +from pyinjective.core.network import Network +from pyinjective.wallet import PrivateKey + + +async def main() -> None: + dotenv.load_dotenv() + configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY") + + # select network: local, testnet, mainnet + network = Network.testnet() + + # initialize grpc client + client = AsyncClient(network) + await client.initialize_tokens_from_chain_denoms() + composer = await client.composer() + await client.sync_timeout_height() + + message_broadcaster = MsgBroadcasterWithPk.new_using_simulation( + network=network, + private_key=configured_private_key, + ) + + # load account + priv_key = PrivateKey.from_hex(configured_private_key) + pub_key = priv_key.to_public_key() + address = pub_key.to_address() + await client.fetch_account(address.to_acc_bech32()) + + # prepare tx msg + message = composer.msg_instant_perpetual_market_launch( + sender=address.to_acc_bech32(), + ticker="INJ/USDC PERP", + quote_denom="USDC", + oracle_base="INJ", + oracle_quote="USDC", + oracle_scale_factor=6, + oracle_type="Band", + maker_fee_rate=Decimal("-0.0001"), + taker_fee_rate=Decimal("0.001"), + initial_margin_ratio=Decimal("0.33"), + maintenance_margin_ratio=Decimal("0.095"), + min_price_tick_size=Decimal("0.001"), + min_quantity_tick_size=Decimal("0.01"), + ) + + # broadcast the transaction + result = await message_broadcaster.broadcast([message]) + print("---Transaction Response---") + print(result) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/exchange/5_MsgInstantExpiryFuturesMarketLaunch.py b/examples/chain_client/exchange/5_MsgInstantExpiryFuturesMarketLaunch.py new file mode 100644 index 00000000..d451fd15 --- /dev/null +++ b/examples/chain_client/exchange/5_MsgInstantExpiryFuturesMarketLaunch.py @@ -0,0 +1,62 @@ +import asyncio +import os +from decimal import Decimal + +import dotenv + +from pyinjective.async_client import AsyncClient +from pyinjective.core.broadcaster import MsgBroadcasterWithPk +from pyinjective.core.network import Network +from pyinjective.wallet import PrivateKey + + +async def main() -> None: + dotenv.load_dotenv() + configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY") + + # select network: local, testnet, mainnet + network = Network.testnet() + + # initialize grpc client + client = AsyncClient(network) + await client.initialize_tokens_from_chain_denoms() + composer = await client.composer() + await client.sync_timeout_height() + + message_broadcaster = MsgBroadcasterWithPk.new_using_simulation( + network=network, + private_key=configured_private_key, + ) + + # load account + priv_key = PrivateKey.from_hex(configured_private_key) + pub_key = priv_key.to_public_key() + address = pub_key.to_address() + await client.fetch_account(address.to_acc_bech32()) + + # prepare tx msg + message = composer.msg_instant_expiry_futures_market_launch( + sender=address.to_acc_bech32(), + ticker="INJ/USDC FUT", + quote_denom="USDC", + oracle_base="INJ", + oracle_quote="USDC", + oracle_scale_factor=6, + oracle_type="Band", + expiry=2000000000, + maker_fee_rate=Decimal("-0.0001"), + taker_fee_rate=Decimal("0.001"), + initial_margin_ratio=Decimal("0.33"), + maintenance_margin_ratio=Decimal("0.095"), + min_price_tick_size=Decimal("0.001"), + min_quantity_tick_size=Decimal("0.01"), + ) + + # broadcast the transaction + result = await message_broadcaster.broadcast([message]) + print("---Transaction Response---") + print(result) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/exchange/3_MsgCreateSpotLimitOrder.py b/examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py similarity index 94% rename from examples/chain_client/exchange/3_MsgCreateSpotLimitOrder.py rename to examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py index d3ca5f16..5b3b966a 100644 --- a/examples/chain_client/exchange/3_MsgCreateSpotLimitOrder.py +++ b/examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -37,15 +38,14 @@ async def main() -> None: cid = str(uuid.uuid4()) # prepare tx msg - msg = composer.MsgCreateSpotLimitOrder( + msg = composer.msg_create_spot_limit_order( sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", cid=cid, ) diff --git a/examples/chain_client/exchange/4_MsgCreateSpotMarketOrder.py b/examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py similarity index 94% rename from examples/chain_client/exchange/4_MsgCreateSpotMarketOrder.py rename to examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py index 5229632f..36ea27de 100644 --- a/examples/chain_client/exchange/4_MsgCreateSpotMarketOrder.py +++ b/examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -36,14 +37,14 @@ async def main() -> None: fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" # prepare tx msg - msg = composer.MsgCreateSpotMarketOrder( - sender=address.to_acc_bech32(), + msg = composer.msg_create_spot_market_order( market_id=market_id, + sender=address.to_acc_bech32(), subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=10.522, - quantity=0.01, - is_buy=True, + price=Decimal("10.522"), + quantity=Decimal("0.01"), + order_type="BUY", cid=str(uuid.uuid4()), ) diff --git a/examples/chain_client/exchange/5_MsgCancelSpotOrder.py b/examples/chain_client/exchange/8_MsgCancelSpotOrder.py similarity index 100% rename from examples/chain_client/exchange/5_MsgCancelSpotOrder.py rename to examples/chain_client/exchange/8_MsgCancelSpotOrder.py diff --git a/examples/chain_client/exchange/11_MsgBatchUpdateOrders.py b/examples/chain_client/exchange/9_MsgBatchUpdateOrders.py similarity index 83% rename from examples/chain_client/exchange/11_MsgBatchUpdateOrders.py rename to examples/chain_client/exchange/9_MsgBatchUpdateOrders.py index 9efdc0a0..04e41058 100644 --- a/examples/chain_client/exchange/11_MsgBatchUpdateOrders.py +++ b/examples/chain_client/exchange/9_MsgBatchUpdateOrders.py @@ -1,6 +1,7 @@ import asyncio import os import uuid +from decimal import Decimal import dotenv from grpc import RpcError @@ -43,12 +44,12 @@ async def main() -> None: spot_market_id_cancel_2 = "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0" derivative_orders_to_cancel = [ - composer.OrderData( + composer.order_data( market_id=derivative_market_id_cancel, subaccount_id=subaccount_id, order_hash="0x48690013c382d5dbaff9989db04629a16a5818d7524e027d517ccc89fd068103", ), - composer.OrderData( + composer.order_data( market_id=derivative_market_id_cancel_2, subaccount_id=subaccount_id, order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", @@ -56,12 +57,12 @@ async def main() -> None: ] spot_orders_to_cancel = [ - composer.OrderData( + composer.order_data( market_id=spot_market_id_cancel, subaccount_id=subaccount_id, cid="0e5c3ad5-2cc4-4a2a-bbe5-b12697739163", ), - composer.OrderData( + composer.order_data( market_id=spot_market_id_cancel_2, subaccount_id=subaccount_id, order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", @@ -69,49 +70,49 @@ async def main() -> None: ] derivative_orders_to_create = [ - composer.DerivativeOrder( + composer.derivative_order( market_id=derivative_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=25000, - quantity=0.1, - leverage=1, - is_buy=True, - is_po=False, + price=Decimal(25000), + quantity=Decimal(0.1), + margin=composer.calculate_margin( + quantity=Decimal(0.1), price=Decimal(25000), leverage=Decimal(1), is_reduce_only=False + ), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.DerivativeOrder( + composer.derivative_order( market_id=derivative_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=50000, - quantity=0.01, - leverage=1, - is_buy=False, - is_po=False, + price=Decimal(50000), + quantity=Decimal(0.01), + margin=composer.calculate_margin( + quantity=Decimal(0.01), price=Decimal(50000), leverage=Decimal(1), is_reduce_only=False + ), + order_type="SELL", cid=str(uuid.uuid4()), ), ] spot_orders_to_create = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=3, - quantity=55, - is_buy=True, - is_po=False, + price=Decimal("3"), + quantity=Decimal("55"), + order_type="BUY", cid=str(uuid.uuid4()), ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id_create, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=300, - quantity=55, - is_buy=False, - is_po=False, + price=Decimal("300"), + quantity=Decimal("55"), + order_type="SELL", cid=str(uuid.uuid4()), ), ] diff --git a/examples/chain_client/41_MsgCreateInsuranceFund.py b/examples/chain_client/insurance/1_MsgCreateInsuranceFund.py similarity index 100% rename from examples/chain_client/41_MsgCreateInsuranceFund.py rename to examples/chain_client/insurance/1_MsgCreateInsuranceFund.py diff --git a/examples/chain_client/42_MsgUnderwrite.py b/examples/chain_client/insurance/2_MsgUnderwrite.py similarity index 100% rename from examples/chain_client/42_MsgUnderwrite.py rename to examples/chain_client/insurance/2_MsgUnderwrite.py diff --git a/examples/chain_client/43_MsgRequestRedemption.py b/examples/chain_client/insurance/3_MsgRequestRedemption.py similarity index 100% rename from examples/chain_client/43_MsgRequestRedemption.py rename to examples/chain_client/insurance/3_MsgRequestRedemption.py diff --git a/examples/chain_client/23_MsgRelayPriceFeedPrice.py b/examples/chain_client/oracle/1_MsgRelayPriceFeedPrice.py similarity index 100% rename from examples/chain_client/23_MsgRelayPriceFeedPrice.py rename to examples/chain_client/oracle/1_MsgRelayPriceFeedPrice.py diff --git a/examples/chain_client/36_MsgRelayProviderPrices.py b/examples/chain_client/oracle/2_MsgRelayProviderPrices.py similarity index 100% rename from examples/chain_client/36_MsgRelayProviderPrices.py rename to examples/chain_client/oracle/2_MsgRelayProviderPrices.py diff --git a/examples/chain_client/22_MsgSendToEth.py b/examples/chain_client/peggy/1_MsgSendToEth.py similarity index 100% rename from examples/chain_client/22_MsgSendToEth.py rename to examples/chain_client/peggy/1_MsgSendToEth.py diff --git a/examples/chain_client/25_MsgDelegate.py b/examples/chain_client/staking/1_MsgDelegate.py similarity index 100% rename from examples/chain_client/25_MsgDelegate.py rename to examples/chain_client/staking/1_MsgDelegate.py diff --git a/examples/chain_client/71_CreateDenom.py b/examples/chain_client/tokenfactory/1_CreateDenom.py similarity index 100% rename from examples/chain_client/71_CreateDenom.py rename to examples/chain_client/tokenfactory/1_CreateDenom.py diff --git a/examples/chain_client/72_MsgMint.py b/examples/chain_client/tokenfactory/2_MsgMint.py similarity index 100% rename from examples/chain_client/72_MsgMint.py rename to examples/chain_client/tokenfactory/2_MsgMint.py diff --git a/examples/chain_client/73_MsgBurn.py b/examples/chain_client/tokenfactory/3_MsgBurn.py similarity index 100% rename from examples/chain_client/73_MsgBurn.py rename to examples/chain_client/tokenfactory/3_MsgBurn.py diff --git a/examples/chain_client/75_MsgChangeAdmin.py b/examples/chain_client/tokenfactory/4_MsgChangeAdmin.py similarity index 100% rename from examples/chain_client/75_MsgChangeAdmin.py rename to examples/chain_client/tokenfactory/4_MsgChangeAdmin.py diff --git a/examples/chain_client/74_MsgSetDenomMetadata.py b/examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py similarity index 100% rename from examples/chain_client/74_MsgSetDenomMetadata.py rename to examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py diff --git a/examples/chain_client/68_DenomAuthorityMetadata.py b/examples/chain_client/tokenfactory/query/1_DenomAuthorityMetadata.py similarity index 100% rename from examples/chain_client/68_DenomAuthorityMetadata.py rename to examples/chain_client/tokenfactory/query/1_DenomAuthorityMetadata.py diff --git a/examples/chain_client/69_DenomsFromCreator.py b/examples/chain_client/tokenfactory/query/2_DenomsFromCreator.py similarity index 100% rename from examples/chain_client/69_DenomsFromCreator.py rename to examples/chain_client/tokenfactory/query/2_DenomsFromCreator.py diff --git a/examples/chain_client/70_TokenfactoryModuleState.py b/examples/chain_client/tokenfactory/query/3_TokenfactoryModuleState.py similarity index 100% rename from examples/chain_client/70_TokenfactoryModuleState.py rename to examples/chain_client/tokenfactory/query/3_TokenfactoryModuleState.py diff --git a/examples/chain_client/37_GetTx.py b/examples/chain_client/tx/query/1_GetTx.py similarity index 100% rename from examples/chain_client/37_GetTx.py rename to examples/chain_client/tx/query/1_GetTx.py diff --git a/examples/chain_client/40_MsgExecuteContract.py b/examples/chain_client/wasm/1_MsgExecuteContract.py similarity index 100% rename from examples/chain_client/40_MsgExecuteContract.py rename to examples/chain_client/wasm/1_MsgExecuteContract.py diff --git a/examples/chain_client/67_ContractsByCreator.py b/examples/chain_client/wasm/query/10_ContractsByCreator.py similarity index 100% rename from examples/chain_client/67_ContractsByCreator.py rename to examples/chain_client/wasm/query/10_ContractsByCreator.py diff --git a/examples/chain_client/58_ContractInfo.py b/examples/chain_client/wasm/query/1_ContractInfo.py similarity index 100% rename from examples/chain_client/58_ContractInfo.py rename to examples/chain_client/wasm/query/1_ContractInfo.py diff --git a/examples/chain_client/59_ContractHistory.py b/examples/chain_client/wasm/query/2_ContractHistory.py similarity index 100% rename from examples/chain_client/59_ContractHistory.py rename to examples/chain_client/wasm/query/2_ContractHistory.py diff --git a/examples/chain_client/60_ContractsByCode.py b/examples/chain_client/wasm/query/3_ContractsByCode.py similarity index 100% rename from examples/chain_client/60_ContractsByCode.py rename to examples/chain_client/wasm/query/3_ContractsByCode.py diff --git a/examples/chain_client/61_AllContractsState.py b/examples/chain_client/wasm/query/4_AllContractsState.py similarity index 100% rename from examples/chain_client/61_AllContractsState.py rename to examples/chain_client/wasm/query/4_AllContractsState.py diff --git a/examples/chain_client/62_RawContractState.py b/examples/chain_client/wasm/query/5_RawContractState.py similarity index 100% rename from examples/chain_client/62_RawContractState.py rename to examples/chain_client/wasm/query/5_RawContractState.py diff --git a/examples/chain_client/63_SmartContractState.py b/examples/chain_client/wasm/query/6_SmartContractState.py similarity index 100% rename from examples/chain_client/63_SmartContractState.py rename to examples/chain_client/wasm/query/6_SmartContractState.py diff --git a/examples/chain_client/64_SmartContractCode.py b/examples/chain_client/wasm/query/7_SmartContractCode.py similarity index 100% rename from examples/chain_client/64_SmartContractCode.py rename to examples/chain_client/wasm/query/7_SmartContractCode.py diff --git a/examples/chain_client/65_SmartContractCodes.py b/examples/chain_client/wasm/query/8_SmartContractCodes.py similarity index 100% rename from examples/chain_client/65_SmartContractCodes.py rename to examples/chain_client/wasm/query/8_SmartContractCodes.py diff --git a/examples/chain_client/66_SmartContractPinnedCodes.py b/examples/chain_client/wasm/query/9_SmartContractPinnedCodes.py similarity index 100% rename from examples/chain_client/66_SmartContractPinnedCodes.py rename to examples/chain_client/wasm/query/9_SmartContractPinnedCodes.py diff --git a/pyinjective/composer.py b/pyinjective/composer.py index df353d6b..9a0807c9 100644 --- a/pyinjective/composer.py +++ b/pyinjective/composer.py @@ -13,7 +13,7 @@ from pyinjective.core.token import Token from pyinjective.proto.cosmos.authz.v1beta1 import authz_pb2 as cosmos_authz_pb, tx_pb2 as cosmos_authz_tx_pb from pyinjective.proto.cosmos.bank.v1beta1 import bank_pb2 as bank_pb, tx_pb2 as cosmos_bank_tx_pb -from pyinjective.proto.cosmos.base.v1beta1 import coin_pb2 as cosmos_dot_base_dot_v1beta1_dot_coin__pb2 +from pyinjective.proto.cosmos.base.v1beta1 import coin_pb2 as base_coin_pb from pyinjective.proto.cosmos.distribution.v1beta1 import ( distribution_pb2 as cosmos_distribution_pb2, tx_pb2 as cosmos_distribution_tx_pb, @@ -25,15 +25,19 @@ from pyinjective.proto.injective.auction.v1beta1 import tx_pb2 as injective_auction_tx_pb from pyinjective.proto.injective.exchange.v1beta1 import ( authz_pb2 as injective_authz_pb, - exchange_pb2 as injective_dot_exchange_dot_v1beta1_dot_exchange__pb2, + exchange_pb2 as injective_exchange_pb, tx_pb2 as injective_exchange_tx_pb, ) from pyinjective.proto.injective.insurance.v1beta1 import tx_pb2 as injective_insurance_tx_pb -from pyinjective.proto.injective.oracle.v1beta1 import tx_pb2 as injective_oracle_tx_pb +from pyinjective.proto.injective.oracle.v1beta1 import ( + oracle_pb2 as injective_oracle_pb, + tx_pb2 as injective_oracle_tx_pb, +) from pyinjective.proto.injective.peggy.v1 import msgs_pb2 as injective_peggy_tx_pb from pyinjective.proto.injective.stream.v1beta1 import query_pb2 as chain_stream_query from pyinjective.proto.injective.tokenfactory.v1beta1 import tx_pb2 as token_factory_tx_pb from pyinjective.proto.injective.wasmx.v1 import tx_pb2 as wasmx_tx_pb +from pyinjective.utils.denom import Denom REQUEST_TO_RESPONSE_TYPE_MAP = { "MsgCreateSpotLimitOrder": injective_exchange_tx_pb.MsgCreateSpotLimitOrderResponse, @@ -137,14 +141,14 @@ def Coin(self, amount: int, denom: str): This method is deprecated and will be removed soon. Please use `coin` instead """ warn("This method is deprecated. Use coin instead", DeprecationWarning, stacklevel=2) - return cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin(amount=str(amount), denom=denom) + return base_coin_pb.Coin(amount=str(amount), denom=denom) def coin(self, amount: int, denom: str): """ This method create an instance of Coin gRPC type, considering the amount is already expressed in chain format """ formatted_amount_string = str(int(amount)) - return cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin(amount=formatted_amount_string, denom=denom) + return base_coin_pb.Coin(amount=formatted_amount_string, denom=denom) def create_coin_amount(self, amount: Decimal, token_name: str): """ @@ -154,35 +158,38 @@ def create_coin_amount(self, amount: Decimal, token_name: str): chain_amount = token.chain_formatted_value(human_readable_value=amount) return self.coin(amount=int(chain_amount), denom=token.denom) - def get_order_mask(self, **kwargs): - order_mask = 0 - - if kwargs.get("is_conditional"): - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.CONDITIONAL - else: - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.REGULAR - - if kwargs.get("order_direction") == "buy": - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.DIRECTION_BUY_OR_HIGHER - - elif kwargs.get("order_direction") == "sell": - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.DIRECTION_SELL_OR_LOWER - - if kwargs.get("order_type") == "market": - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.TYPE_MARKET - - elif kwargs.get("order_type") == "limit": - order_mask += injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderMask.TYPE_LIMIT - - if order_mask == 0: - order_mask = 1 - - return order_mask - def OrderData( self, market_id: str, subaccount_id: str, order_hash: Optional[str] = None, cid: Optional[str] = None, **kwargs ): - order_mask = self.get_order_mask(**kwargs) + """ + This method is deprecated and will be removed soon. Please use `order_data` instead + """ + warn("This method is deprecated. Use order_data instead", DeprecationWarning, stacklevel=2) + + is_conditional = kwargs.get("is_conditional", False) + is_buy = kwargs.get("order_direction", "buy") == "buy" + is_market_order = kwargs.get("order_type", "limit") == "market" + order_mask = self._order_mask(is_conditional=is_conditional, is_buy=is_buy, is_market_order=is_market_order) + + return injective_exchange_tx_pb.OrderData( + market_id=market_id, + subaccount_id=subaccount_id, + order_hash=order_hash, + order_mask=order_mask, + cid=cid, + ) + + def order_data( + self, + market_id: str, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, + is_conditional: Optional[bool] = False, + is_buy: Optional[bool] = False, + is_market_order: Optional[bool] = False, + ) -> injective_exchange_tx_pb.OrderData: + order_mask = self._order_mask(is_conditional=is_conditional, is_buy=is_buy, is_market_order=is_market_order) return injective_exchange_tx_pb.OrderData( market_id=market_id, @@ -202,6 +209,11 @@ def SpotOrder( cid: Optional[str] = None, **kwargs, ): + """ + This method is deprecated and will be removed soon. Please use `spot_order` instead + """ + warn("This method is deprecated. Use spot_order instead", DeprecationWarning, stacklevel=2) + market = self.spot_markets[market_id] # prepare values @@ -210,20 +222,20 @@ def SpotOrder( trigger_price = market.price_to_chain_format(human_readable_value=Decimal(0)) if kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY + order_type = injective_exchange_pb.OrderType.BUY elif not kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL + order_type = injective_exchange_pb.OrderType.SELL elif kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY_PO + order_type = injective_exchange_pb.OrderType.BUY_PO elif not kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL_PO + order_type = injective_exchange_pb.OrderType.SELL_PO - return injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.SpotOrder( + return injective_exchange_pb.SpotOrder( market_id=market_id, - order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( + order_info=injective_exchange_pb.OrderInfo( subaccount_id=subaccount_id, fee_recipient=fee_recipient, price=str(int(price)), @@ -234,6 +246,50 @@ def SpotOrder( trigger_price=str(int(trigger_price)), ) + def spot_order( + self, + market_id: str, + subaccount_id: str, + fee_recipient: str, + price: Decimal, + quantity: Decimal, + order_type: str, + cid: Optional[str] = None, + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_pb.SpotOrder: + market = self.spot_markets[market_id] + + chain_quantity = f"{market.quantity_to_chain_format(human_readable_value=quantity).normalize():f}" + chain_price = f"{market.price_to_chain_format(human_readable_value=price).normalize():f}" + + trigger_price = trigger_price or Decimal(0) + chain_trigger_price = f"{market.price_to_chain_format(human_readable_value=trigger_price).normalize():f}" + + chain_order_type = injective_exchange_pb.OrderType.Value(order_type) + + return injective_exchange_pb.SpotOrder( + market_id=market_id, + order_info=injective_exchange_pb.OrderInfo( + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=chain_price, + quantity=chain_quantity, + cid=cid, + ), + order_type=chain_order_type, + trigger_price=chain_trigger_price, + ) + + def calculate_margin( + self, quantity: Decimal, price: Decimal, leverage: Decimal, is_reduce_only: bool = False + ) -> Decimal: + if is_reduce_only: + margin = Decimal(0) + else: + margin = quantity * price / leverage + + return margin + def DerivativeOrder( self, market_id: str, @@ -245,6 +301,10 @@ def DerivativeOrder( cid: Optional[str] = None, **kwargs, ): + """ + This method is deprecated and will be removed soon. Please use `derivative_order` instead + """ + warn("This method is deprecated. Use derivative_order instead", DeprecationWarning, stacklevel=2) market = self.derivative_markets[market_id] if kwargs.get("is_reduce_only", False): @@ -262,32 +322,32 @@ def DerivativeOrder( trigger_price = market.price_to_chain_format(human_readable_value=Decimal(str(trigger_price))) if kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY + order_type = injective_exchange_pb.OrderType.BUY elif not kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL + order_type = injective_exchange_pb.OrderType.SELL elif kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY_PO + order_type = injective_exchange_pb.OrderType.BUY_PO elif not kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL_PO + order_type = injective_exchange_pb.OrderType.SELL_PO elif kwargs.get("stop_buy"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.STOP_BUY + order_type = injective_exchange_pb.OrderType.STOP_BUY elif kwargs.get("stop_sell"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.STOP_SEll + order_type = injective_exchange_pb.OrderType.STOP_SEll elif kwargs.get("take_buy"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.TAKE_BUY + order_type = injective_exchange_pb.OrderType.TAKE_BUY elif kwargs.get("take_sell"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.TAKE_SELL + order_type = injective_exchange_pb.OrderType.TAKE_SELL - return injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.DerivativeOrder( + return injective_exchange_pb.DerivativeOrder( market_id=market_id, - order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( + order_info=injective_exchange_pb.OrderInfo( subaccount_id=subaccount_id, fee_recipient=fee_recipient, price=str(int(price)), @@ -299,60 +359,121 @@ def DerivativeOrder( trigger_price=str(int(trigger_price)), ) - def BinaryOptionsOrder( + def derivative_order( self, market_id: str, subaccount_id: str, fee_recipient: str, - price: float, - quantity: float, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, cid: Optional[str] = None, - **kwargs, - ): - market = self.binary_option_markets[market_id] - denom = kwargs.get("denom", None) + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_pb.DerivativeOrder: + market = self.derivative_markets[market_id] - if kwargs.get("is_reduce_only", False): - margin = 0 - else: - margin = market.calculate_margin_in_chain_format( - human_readable_quantity=Decimal(str(quantity)), - human_readable_price=Decimal(str(price)), - is_buy=kwargs["is_buy"], - special_denom=denom, - ) + chain_quantity = market.quantity_to_chain_format(human_readable_value=quantity) + chain_price = market.price_to_chain_format(human_readable_value=price) + chain_margin = market.margin_to_chain_format(human_readable_value=margin) - # prepare values - price = market.price_to_chain_format(human_readable_value=Decimal(str(price)), special_denom=denom) - trigger_price = market.price_to_chain_format(human_readable_value=Decimal(str(0)), special_denom=denom) - quantity = market.quantity_to_chain_format(human_readable_value=Decimal(str(quantity)), special_denom=denom) + trigger_price = trigger_price or Decimal(0) + chain_trigger_price = market.price_to_chain_format(human_readable_value=trigger_price) - if kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY + return self._basic_derivative_order( + market_id=market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + chain_price=chain_price, + chain_quantity=chain_quantity, + chain_margin=chain_margin, + order_type=order_type, + cid=cid, + chain_trigger_price=chain_trigger_price, + ) - elif not kwargs.get("is_buy") and not kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL + def binary_options_order( + self, + market_id: str, + subaccount_id: str, + fee_recipient: str, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, + cid: Optional[str] = None, + trigger_price: Optional[Decimal] = None, + denom: Optional[Denom] = None, + ) -> injective_exchange_pb.DerivativeOrder: + market = self.binary_option_markets[market_id] - elif kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.BUY_PO + chain_quantity = market.quantity_to_chain_format(human_readable_value=quantity, special_denom=denom) + chain_price = market.price_to_chain_format(human_readable_value=price, special_denom=denom) + chain_margin = market.margin_to_chain_format(human_readable_value=margin, special_denom=denom) - elif not kwargs.get("is_buy") and kwargs.get("is_po"): - order_type = injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderType.SELL_PO + trigger_price = trigger_price or Decimal(0) + chain_trigger_price = market.price_to_chain_format(human_readable_value=trigger_price, special_denom=denom) - return injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.DerivativeOrder( - market_id=market_id, - order_info=injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.OrderInfo( - subaccount_id=subaccount_id, - fee_recipient=fee_recipient, - price=str(int(price)), - quantity=str(int(quantity)), - cid=cid, - ), - margin=str(int(margin)), + return self._basic_derivative_order( + market_id=market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + chain_price=chain_price, + chain_quantity=chain_quantity, + chain_margin=chain_margin, order_type=order_type, - trigger_price=str(int(trigger_price)), + cid=cid, + chain_trigger_price=chain_trigger_price, + ) + + # region Auction module + def MsgBid(self, sender: str, bid_amount: float, round: float): + be_amount = Decimal(str(bid_amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return injective_auction_tx_pb.MsgBid( + sender=sender, + round=round, + bid_amount=self.coin(amount=int(be_amount), denom=INJ_DENOM), + ) + + # endregion + + # region Authz module + def MsgGrantGeneric(self, granter: str, grantee: str, msg_type: str, expire_in: int): + auth = cosmos_authz_pb.GenericAuthorization(msg=msg_type) + any_auth = any_pb2.Any() + any_auth.Pack(auth, type_url_prefix="") + + grant = cosmos_authz_pb.Grant( + authorization=any_auth, + expiration=timestamp_pb2.Timestamp(seconds=(int(time()) + expire_in)), + ) + + return cosmos_authz_tx_pb.MsgGrant(granter=granter, grantee=grantee, grant=grant) + + def MsgExec(self, grantee: str, msgs: List): + any_msgs: List[any_pb2.Any] = [] + for msg in msgs: + any_msg = any_pb2.Any() + any_msg.Pack(msg, type_url_prefix="") + any_msgs.append(any_msg) + + return cosmos_authz_tx_pb.MsgExec(grantee=grantee, msgs=any_msgs) + + def MsgRevoke(self, granter: str, grantee: str, msg_type: str): + return cosmos_authz_tx_pb.MsgRevoke(granter=granter, grantee=grantee, msg_type_url=msg_type) + + def msg_execute_contract_compat(self, sender: str, contract: str, msg: str, funds: str): + return wasmx_tx_pb.MsgExecuteContractCompat( + sender=sender, + contract=contract, + msg=msg, + funds=funds, ) + # endregion + + # region Bank module def MsgSend(self, from_address: str, to_address: str, amount: float, denom: str): coin = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) @@ -362,16 +483,14 @@ def MsgSend(self, from_address: str, to_address: str, amount: float, denom: str) amount=[coin], ) - def MsgExecuteContract(self, sender: str, contract: str, msg: str, **kwargs): - return wasm_tx_pb.MsgExecuteContract( - sender=sender, - contract=contract, - msg=bytes(msg, "utf-8"), - funds=kwargs.get("funds") # funds is a list of cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin. - # The coins in the list must be sorted in alphabetical order by denoms. - ) + # endregion + # region Chain Exchange module def MsgDeposit(self, sender: str, subaccount_id: str, amount: float, denom: str): + """ + This method is deprecated and will be removed soon. Please use `msg_deposit` instead + """ + warn("This method is deprecated. Use msg_deposit instead", DeprecationWarning, stacklevel=2) coin = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) return injective_exchange_tx_pb.MsgDeposit( @@ -380,6 +499,153 @@ def MsgDeposit(self, sender: str, subaccount_id: str, amount: float, denom: str) amount=coin, ) + def msg_deposit(self, sender: str, subaccount_id: str, amount: Decimal, denom: str): + coin = self.create_coin_amount(amount=amount, token_name=denom) + + return injective_exchange_tx_pb.MsgDeposit( + sender=sender, + subaccount_id=subaccount_id, + amount=coin, + ) + + def MsgWithdraw(self, sender: str, subaccount_id: str, amount: float, denom: str): + """ + This method is deprecated and will be removed soon. Please use `msg_withdraw` instead + """ + warn("This method is deprecated. Use msg_withdraw instead", DeprecationWarning, stacklevel=2) + be_amount = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) + + return injective_exchange_tx_pb.MsgWithdraw( + sender=sender, + subaccount_id=subaccount_id, + amount=be_amount, + ) + + def msg_withdraw(self, sender: str, subaccount_id: str, amount: Decimal, denom: str): + be_amount = self.create_coin_amount(amount=amount, token_name=denom) + + return injective_exchange_tx_pb.MsgWithdraw( + sender=sender, + subaccount_id=subaccount_id, + amount=be_amount, + ) + + def msg_instant_spot_market_launch( + self, + sender: str, + ticker: str, + base_denom: str, + quote_denom: str, + min_price_tick_size: Decimal, + min_quantity_tick_size: Decimal, + ) -> injective_exchange_tx_pb.MsgInstantSpotMarketLaunch: + base_token = self.tokens[base_denom] + quote_token = self.tokens[quote_denom] + + chain_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals - base_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + chain_min_quantity_tick_size = min_quantity_tick_size * Decimal( + f"1e{base_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + + return injective_exchange_tx_pb.MsgInstantSpotMarketLaunch( + sender=sender, + ticker=ticker, + base_denom=base_token.denom, + quote_denom=quote_token.denom, + min_price_tick_size=f"{chain_min_price_tick_size.normalize():f}", + min_quantity_tick_size=f"{chain_min_quantity_tick_size.normalize():f}", + ) + + def msg_instant_perpetual_market_launch( + self, + sender: str, + ticker: str, + quote_denom: str, + oracle_base: str, + oracle_quote: str, + oracle_scale_factor: int, + oracle_type: str, + maker_fee_rate: Decimal, + taker_fee_rate: Decimal, + initial_margin_ratio: Decimal, + maintenance_margin_ratio: Decimal, + min_price_tick_size: Decimal, + min_quantity_tick_size: Decimal, + ) -> injective_exchange_tx_pb.MsgInstantPerpetualMarketLaunch: + quote_token = self.tokens[quote_denom] + + chain_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + chain_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_initial_margin_ratio = initial_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_maintenance_margin_ratio = maintenance_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return injective_exchange_tx_pb.MsgInstantPerpetualMarketLaunch( + sender=sender, + ticker=ticker, + quote_denom=quote_token.denom, + oracle_base=oracle_base, + oracle_quote=oracle_quote, + oracle_scale_factor=oracle_scale_factor, + oracle_type=injective_oracle_pb.OracleType.Value(oracle_type), + maker_fee_rate=f"{chain_maker_fee_rate.normalize():f}", + taker_fee_rate=f"{chain_taker_fee_rate.normalize():f}", + initial_margin_ratio=f"{chain_initial_margin_ratio.normalize():f}", + maintenance_margin_ratio=f"{chain_maintenance_margin_ratio.normalize():f}", + min_price_tick_size=f"{chain_min_price_tick_size.normalize():f}", + min_quantity_tick_size=f"{chain_min_quantity_tick_size.normalize():f}", + ) + + def msg_instant_expiry_futures_market_launch( + self, + sender: str, + ticker: str, + quote_denom: str, + oracle_base: str, + oracle_quote: str, + oracle_scale_factor: int, + oracle_type: str, + expiry: int, + maker_fee_rate: Decimal, + taker_fee_rate: Decimal, + initial_margin_ratio: Decimal, + maintenance_margin_ratio: Decimal, + min_price_tick_size: Decimal, + min_quantity_tick_size: Decimal, + ) -> injective_exchange_tx_pb.MsgInstantPerpetualMarketLaunch: + quote_token = self.tokens[quote_denom] + + chain_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + chain_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_initial_margin_ratio = initial_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_maintenance_margin_ratio = maintenance_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return injective_exchange_tx_pb.MsgInstantExpiryFuturesMarketLaunch( + sender=sender, + ticker=ticker, + quote_denom=quote_token.denom, + oracle_base=oracle_base, + oracle_quote=oracle_quote, + oracle_scale_factor=oracle_scale_factor, + oracle_type=injective_oracle_pb.OracleType.Value(oracle_type), + expiry=expiry, + maker_fee_rate=f"{chain_maker_fee_rate.normalize():f}", + taker_fee_rate=f"{chain_taker_fee_rate.normalize():f}", + initial_margin_ratio=f"{chain_initial_margin_ratio.normalize():f}", + maintenance_margin_ratio=f"{chain_maintenance_margin_ratio.normalize():f}", + min_price_tick_size=f"{chain_min_price_tick_size.normalize():f}", + min_quantity_tick_size=f"{chain_min_quantity_tick_size.normalize():f}", + ) + def MsgCreateSpotLimitOrder( self, market_id: str, @@ -391,52 +657,151 @@ def MsgCreateSpotLimitOrder( cid: Optional[str] = None, **kwargs, ): + """ + This method is deprecated and will be removed soon. Please use `msg_create_spot_limit_order` instead + """ + warn("This method is deprecated. Use msg_create_spot_limit_order instead", DeprecationWarning, stacklevel=2) + + order_type_name = "BUY" + if kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type_name = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY) + + elif not kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type_name = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + elif kwargs.get("is_buy") and kwargs.get("is_po"): + order_type_name = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY_PO) + + elif not kwargs.get("is_buy") and kwargs.get("is_po"): + order_type_name = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL_PO) + return injective_exchange_tx_pb.MsgCreateSpotLimitOrder( sender=sender, - order=self.SpotOrder( + order=self.spot_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=price, - quantity=quantity, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + order_type=order_type_name, cid=cid, - **kwargs, ), ) - def MsgCreateSpotMarketOrder( + def msg_create_spot_limit_order( self, market_id: str, sender: str, subaccount_id: str, fee_recipient: str, - price: float, - quantity: float, - is_buy: bool, + price: Decimal, + quantity: Decimal, + order_type: str, cid: Optional[str] = None, - ): - return injective_exchange_tx_pb.MsgCreateSpotMarketOrder( + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_tx_pb.MsgCreateSpotLimitOrder: + return injective_exchange_tx_pb.MsgCreateSpotLimitOrder( sender=sender, - order=self.SpotOrder( + order=self.spot_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, price=price, quantity=quantity, - is_buy=is_buy, + order_type=order_type, cid=cid, + trigger_price=trigger_price, ), ) - def MsgCancelSpotOrder( + def MsgBatchCreateSpotLimitOrders(self, sender: str, orders: List): + """ + This method is deprecated and will be removed soon. Please use `msg_batch_create_spot_limit_orders` instead + """ + warn( + "This method is deprecated. Use msg_batch_create_spot_limit_orders instead", + DeprecationWarning, + stacklevel=2, + ) + return injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders(sender=sender, orders=orders) + + def msg_batch_create_spot_limit_orders( + self, sender: str, orders: List[injective_exchange_pb.SpotOrder] + ) -> injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders: + return injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders(sender=sender, orders=orders) + + def MsgCreateSpotMarketOrder( self, market_id: str, sender: str, subaccount_id: str, - order_hash: Optional[str] = None, + fee_recipient: str, + price: float, + quantity: float, + is_buy: bool, cid: Optional[str] = None, ): - return injective_exchange_tx_pb.MsgCancelSpotOrder( + """ + This method is deprecated and will be removed soon. Please use `msg_create_spot_market_order` instead + """ + warn("This method is deprecated. Use msg_create_spot_market_order instead", DeprecationWarning, stacklevel=2) + + order_type_name = "BUY" + if not is_buy: + order_type_name = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + return injective_exchange_tx_pb.MsgCreateSpotMarketOrder( + sender=sender, + order=self.spot_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + order_type=order_type_name, + cid=cid, + ), + ) + + def msg_create_spot_market_order( + self, + market_id: str, + sender: str, + subaccount_id: str, + fee_recipient: str, + price: Decimal, + quantity: Decimal, + order_type: str, + cid: Optional[str] = None, + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_tx_pb.MsgCreateSpotMarketOrder: + return injective_exchange_tx_pb.MsgCreateSpotMarketOrder( + sender=sender, + order=self.spot_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ), + ) + + def MsgCancelSpotOrder( + self, + market_id: str, + sender: str, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, + ): + """ + This method is deprecated and will be removed soon. Please use `msg_cancel_spot_order` instead + """ + warn("This method is deprecated. Use msg_cancel_spot_order instead", DeprecationWarning, stacklevel=2) + return injective_exchange_tx_pb.MsgCancelSpotOrder( sender=sender, market_id=market_id, subaccount_id=subaccount_id, @@ -444,14 +809,111 @@ def MsgCancelSpotOrder( cid=cid, ) - def MsgBatchCreateSpotLimitOrders(self, sender: str, orders: List): - return injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders(sender=sender, orders=orders) + def msg_cancel_spot_order( + self, + market_id: str, + sender: str, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, + ) -> injective_exchange_tx_pb.MsgCancelSpotOrder: + return injective_exchange_tx_pb.MsgCancelSpotOrder( + sender=sender, + market_id=market_id, + subaccount_id=subaccount_id, + order_hash=order_hash, + cid=cid, + ) def MsgBatchCancelSpotOrders(self, sender: str, data: List): + """ + This method is deprecated and will be removed soon. Please use `msg_batch_cancel_spot_orders` instead + """ + warn("This method is deprecated. Use msg_batch_cancel_spot_orders instead", DeprecationWarning, stacklevel=2) return injective_exchange_tx_pb.MsgBatchCancelSpotOrders(sender=sender, data=data) - def MsgRewardsOptOut(self, sender: str): - return injective_exchange_tx_pb.MsgRewardsOptOut(sender=sender) + def msg_batch_cancel_spot_orders( + self, sender: str, orders_data: List[injective_exchange_tx_pb.OrderData] + ) -> injective_exchange_tx_pb.MsgBatchCancelSpotOrders: + return injective_exchange_tx_pb.MsgBatchCancelSpotOrders(sender=sender, data=orders_data) + + def MsgBatchUpdateOrders(self, sender: str, **kwargs): + """ + This method is deprecated and will be removed soon. Please use `msg_batch_update_orders` instead + """ + warn("This method is deprecated. Use msg_batch_update_orders instead", DeprecationWarning, stacklevel=2) + return injective_exchange_tx_pb.MsgBatchUpdateOrders( + sender=sender, + subaccount_id=kwargs.get("subaccount_id"), + spot_market_ids_to_cancel_all=kwargs.get("spot_market_ids_to_cancel_all"), + derivative_market_ids_to_cancel_all=kwargs.get("derivative_market_ids_to_cancel_all"), + spot_orders_to_cancel=kwargs.get("spot_orders_to_cancel"), + derivative_orders_to_cancel=kwargs.get("derivative_orders_to_cancel"), + spot_orders_to_create=kwargs.get("spot_orders_to_create"), + derivative_orders_to_create=kwargs.get("derivative_orders_to_create"), + binary_options_orders_to_cancel=kwargs.get("binary_options_orders_to_cancel"), + binary_options_market_ids_to_cancel_all=kwargs.get("binary_options_market_ids_to_cancel_all"), + binary_options_orders_to_create=kwargs.get("binary_options_orders_to_create"), + ) + + def msg_batch_update_orders( + self, + sender: str, + subaccount_id: Optional[str] = None, + spot_market_ids_to_cancel_all: Optional[List[str]] = None, + derivative_market_ids_to_cancel_all: Optional[List[str]] = None, + spot_orders_to_cancel: Optional[List[injective_exchange_tx_pb.OrderData]] = None, + derivative_orders_to_cancel: Optional[List[injective_exchange_tx_pb.OrderData]] = None, + spot_orders_to_create: Optional[List[injective_exchange_pb.SpotOrder]] = None, + derivative_orders_to_create: Optional[List[injective_exchange_pb.DerivativeOrder]] = None, + binary_options_orders_to_cancel: Optional[List[injective_exchange_tx_pb.OrderData]] = None, + binary_options_market_ids_to_cancel_all: Optional[List[str]] = None, + binary_options_orders_to_create: Optional[List[injective_exchange_pb.DerivativeOrder]] = None, + ) -> injective_exchange_tx_pb.MsgBatchUpdateOrders: + return injective_exchange_tx_pb.MsgBatchUpdateOrders( + sender=sender, + subaccount_id=subaccount_id, + spot_market_ids_to_cancel_all=spot_market_ids_to_cancel_all, + derivative_market_ids_to_cancel_all=derivative_market_ids_to_cancel_all, + spot_orders_to_cancel=spot_orders_to_cancel, + derivative_orders_to_cancel=derivative_orders_to_cancel, + spot_orders_to_create=spot_orders_to_create, + derivative_orders_to_create=derivative_orders_to_create, + binary_options_orders_to_cancel=binary_options_orders_to_cancel, + binary_options_market_ids_to_cancel_all=binary_options_market_ids_to_cancel_all, + binary_options_orders_to_create=binary_options_orders_to_create, + ) + + def MsgPrivilegedExecuteContract( + self, sender: str, contract: str, msg: str, **kwargs + ) -> injective_exchange_tx_pb.MsgPrivilegedExecuteContract: + """ + This method is deprecated and will be removed soon. Please use `msg_privileged_execute_contract` instead + """ + warn("This method is deprecated. Use msg_privileged_execute_contract instead", DeprecationWarning, stacklevel=2) + + return injective_exchange_tx_pb.MsgPrivilegedExecuteContract( + sender=sender, + contract_address=contract, + data=msg, + funds=kwargs.get("funds") # funds is a string of Coin strings, comma separated, + # e.g. 100000inj,20000000000usdt + ) + + def msg_privileged_execute_contract( + self, + sender: str, + contract_address: str, + data: str, + funds: Optional[str] = None, + ) -> injective_exchange_tx_pb.MsgPrivilegedExecuteContract: + # funds is a string of Coin strings, comma separated, e.g. 100000inj,20000000000usdt + return injective_exchange_tx_pb.MsgPrivilegedExecuteContract( + sender=sender, + contract_address=contract_address, + data=data, + funds=funds, + ) def MsgCreateDerivativeLimitOrder( self, @@ -464,46 +926,105 @@ def MsgCreateDerivativeLimitOrder( cid: Optional[str] = None, **kwargs, ): + """ + This method is deprecated and will be removed soon. Please use `msg_create_derivative_limit_order` instead + """ + warn( + "This method is deprecated. Use msg_create_derivative_limit_order instead", DeprecationWarning, stacklevel=2 + ) + + if kwargs.get("is_reduce_only", False): + margin = Decimal(0) + else: + margin = Decimal(str(price)) * Decimal(str(quantity)) / Decimal(str(kwargs["leverage"])) + + if kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY) + + elif not kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + elif kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY_PO) + + elif not kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL_PO) + + elif kwargs.get("stop_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_BUY) + + elif kwargs.get("stop_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_SEll) + + elif kwargs.get("take_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_BUY) + + elif kwargs.get("take_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_SELL) + return injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder( sender=sender, - order=self.DerivativeOrder( + order=self.derivative_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=price, - quantity=quantity, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + margin=margin, + order_type=order_type, cid=cid, - **kwargs, + trigger_price=Decimal(str(kwargs["trigger_price"])) if "trigger_price" in kwargs else None, ), ) - def MsgCreateDerivativeMarketOrder( + def msg_create_derivative_limit_order( self, market_id: str, sender: str, subaccount_id: str, fee_recipient: str, - price: float, - quantity: float, - is_buy: bool, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, cid: Optional[str] = None, - **kwargs, - ): - return injective_exchange_tx_pb.MsgCreateDerivativeMarketOrder( + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder: + return injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder( sender=sender, - order=self.DerivativeOrder( + order=self.derivative_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, price=price, quantity=quantity, - is_buy=is_buy, + margin=margin, + order_type=order_type, cid=cid, - **kwargs, + trigger_price=trigger_price, ), ) - def MsgCreateBinaryOptionsLimitOrder( + def MsgBatchCreateDerivativeLimitOrders(self, sender: str, orders: List): + """ + This method is deprecated and will be removed soon. + Please use `msg_batch_create_derivative_limit_orders` instead + """ + warn( + "This method is deprecated. Use msg_batch_create_derivative_limit_orders instead", + DeprecationWarning, + stacklevel=2, + ) + return injective_exchange_tx_pb.MsgBatchCreateDerivativeLimitOrders(sender=sender, orders=orders) + + def msg_batch_create_derivative_limit_orders( + self, + sender: str, + orders: List[injective_exchange_pb.DerivativeOrder], + ) -> injective_exchange_tx_pb.MsgBatchCreateDerivativeLimitOrders: + return injective_exchange_tx_pb.MsgBatchCreateDerivativeLimitOrders(sender=sender, orders=orders) + + def MsgCreateDerivativeMarketOrder( self, market_id: str, sender: str, @@ -514,95 +1035,156 @@ def MsgCreateBinaryOptionsLimitOrder( cid: Optional[str] = None, **kwargs, ): - return injective_exchange_tx_pb.MsgCreateBinaryOptionsLimitOrder( + """ + This method is deprecated and will be removed soon. Please use `msg_create_derivative_market_order` instead + """ + warn( + "This method is deprecated. Use msg_create_derivative_market_order instead", + DeprecationWarning, + stacklevel=2, + ) + + if kwargs.get("is_reduce_only", False): + margin = Decimal(0) + else: + margin = Decimal(str(price)) * Decimal(str(quantity)) / Decimal(str(kwargs["leverage"])) + + if kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY) + + elif not kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + elif kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY_PO) + + elif not kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL_PO) + + elif kwargs.get("stop_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_BUY) + + elif kwargs.get("stop_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_SEll) + + elif kwargs.get("take_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_BUY) + + elif kwargs.get("take_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_SELL) + + return injective_exchange_tx_pb.MsgCreateDerivativeMarketOrder( sender=sender, - order=self.BinaryOptionsOrder( + order=self.derivative_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=price, - quantity=quantity, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + margin=margin, + order_type=order_type, cid=cid, - **kwargs, + trigger_price=Decimal(str(kwargs["trigger_price"])) if "trigger_price" in kwargs else None, ), ) - def MsgCreateBinaryOptionsMarketOrder( + def msg_create_derivative_market_order( self, market_id: str, sender: str, subaccount_id: str, fee_recipient: str, - price: float, - quantity: float, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, cid: Optional[str] = None, - **kwargs, - ): - return injective_exchange_tx_pb.MsgCreateBinaryOptionsMarketOrder( + trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_tx_pb.MsgCreateDerivativeMarketOrder: + return injective_exchange_tx_pb.MsgCreateDerivativeMarketOrder( sender=sender, - order=self.BinaryOptionsOrder( + order=self.derivative_order( market_id=market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, price=price, quantity=quantity, + margin=margin, + order_type=order_type, cid=cid, - **kwargs, + trigger_price=trigger_price, ), ) - def MsgCancelBinaryOptionsOrder( + def MsgCancelDerivativeOrder( self, - sender: str, market_id: str, + sender: str, subaccount_id: str, order_hash: Optional[str] = None, cid: Optional[str] = None, + **kwargs, ): - return injective_exchange_tx_pb.MsgCancelBinaryOptionsOrder( + """ + This method is deprecated and will be removed soon. Please use `msg_cancel_derivative_order` instead + """ + warn( + "This method is deprecated. Use msg_cancel_derivative_order instead", + DeprecationWarning, + stacklevel=2, + ) + + is_conditional = kwargs.get("is_conditional", False) + is_buy = kwargs.get("order_direction", "buy") == "buy" + is_market_order = kwargs.get("order_type", "limit") == "market" + order_mask = self._order_mask(is_conditional=is_conditional, is_buy=is_buy, is_market_order=is_market_order) + + return injective_exchange_tx_pb.MsgCancelDerivativeOrder( sender=sender, market_id=market_id, subaccount_id=subaccount_id, order_hash=order_hash, + order_mask=order_mask, cid=cid, ) - def MsgAdminUpdateBinaryOptionsMarket( + def msg_cancel_derivative_order( self, - sender: str, market_id: str, - status: str, - **kwargs, - ): - price_to_bytes = None - - if kwargs.get("settlement_price") is not None: - scale_price = Decimal((kwargs.get("settlement_price") * pow(10, 18))) - price_to_bytes = bytes(str(scale_price), "utf-8") - - else: - price_to_bytes = "" + sender: str, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, + is_conditional: Optional[bool] = False, + is_buy: Optional[bool] = False, + is_market_order: Optional[bool] = False, + ) -> injective_exchange_tx_pb.MsgCancelDerivativeOrder: + order_mask = self._order_mask(is_conditional=is_conditional, is_buy=is_buy, is_market_order=is_market_order) - return injective_exchange_tx_pb.MsgAdminUpdateBinaryOptionsMarket( + return injective_exchange_tx_pb.MsgCancelDerivativeOrder( sender=sender, market_id=market_id, - settlement_price=price_to_bytes, - expiration_timestamp=kwargs.get("expiration_timestamp"), - settlement_timestamp=kwargs.get("settlement_timestamp"), - status=status, + subaccount_id=subaccount_id, + order_hash=order_hash, + order_mask=order_mask, + cid=cid, ) - def MsgRelayProviderPrices(self, sender: str, provider: str, symbols: list, prices: list): - oracle_prices = [] - - for price in prices: - scale_price = Decimal((price) * pow(10, 18)) - price_to_bytes = bytes(str(scale_price), "utf-8") - oracle_prices.append(price_to_bytes) - - return injective_oracle_tx_pb.MsgRelayProviderPrices( - sender=sender, provider=provider, symbols=symbols, prices=oracle_prices + def MsgBatchCancelDerivativeOrders(self, sender: str, data: List): + """ + This method is deprecated and will be removed soon. Please use `msg_batch_cancel_derivative_orders` instead + """ + warn( + "This method is deprecated. Use msg_batch_cancel_derivative_orders instead", + DeprecationWarning, + stacklevel=2, ) + return injective_exchange_tx_pb.MsgBatchCancelDerivativeOrders(sender=sender, data=data) + + def msg_batch_cancel_derivative_orders( + self, sender: str, orders_data: List[injective_exchange_tx_pb.OrderData] + ) -> injective_exchange_tx_pb.MsgBatchCancelDerivativeOrders: + return injective_exchange_tx_pb.MsgBatchCancelDerivativeOrders(sender=sender, data=orders_data) def MsgInstantBinaryOptionsMarketLaunch( self, @@ -622,6 +1204,15 @@ def MsgInstantBinaryOptionsMarketLaunch( min_quantity_tick_size: float, **kwargs, ): + """ + This method is deprecated and will be removed soon. + Please use `msg_instant_binary_options_market_launch` instead + """ + warn( + "This method is deprecated. Use msg_instant_binary_options_market_launch instead", + DeprecationWarning, + stacklevel=2, + ) scaled_maker_fee_rate = Decimal((maker_fee_rate * pow(10, 18))) maker_fee_to_bytes = bytes(str(scaled_maker_fee_rate), "utf-8") @@ -651,75 +1242,281 @@ def MsgInstantBinaryOptionsMarketLaunch( admin=kwargs.get("admin"), ) - def MsgCancelDerivativeOrder( + def msg_instant_binary_options_market_launch( self, - market_id: str, sender: str, - subaccount_id: str, - order_hash: Optional[str] = None, - cid: Optional[str] = None, - **kwargs, - ): - order_mask = self.get_order_mask(**kwargs) - - return injective_exchange_tx_pb.MsgCancelDerivativeOrder( + ticker: str, + oracle_symbol: str, + oracle_provider: str, + oracle_type: str, + oracle_scale_factor: int, + maker_fee_rate: Decimal, + taker_fee_rate: Decimal, + expiration_timestamp: int, + settlement_timestamp: int, + admin: str, + quote_denom: str, + min_price_tick_size: Decimal, + min_quantity_tick_size: Decimal, + ) -> injective_exchange_tx_pb.MsgInstantPerpetualMarketLaunch: + quote_token = self.tokens[quote_denom] + + chain_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + chain_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + chain_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return injective_exchange_tx_pb.MsgInstantBinaryOptionsMarketLaunch( sender=sender, - market_id=market_id, - subaccount_id=subaccount_id, - order_hash=order_hash, - order_mask=order_mask, - cid=cid, + ticker=ticker, + oracle_symbol=oracle_symbol, + oracle_provider=oracle_provider, + oracle_type=injective_oracle_pb.OracleType.Value(oracle_type), + oracle_scale_factor=oracle_scale_factor, + maker_fee_rate=f"{chain_maker_fee_rate.normalize():f}", + taker_fee_rate=f"{chain_taker_fee_rate.normalize():f}", + expiration_timestamp=expiration_timestamp, + settlement_timestamp=settlement_timestamp, + admin=admin, + quote_denom=quote_token.denom, + min_price_tick_size=f"{chain_min_price_tick_size.normalize():f}", + min_quantity_tick_size=f"{chain_min_quantity_tick_size.normalize():f}", ) - def MsgBatchCreateDerivativeLimitOrders(self, sender: str, orders: List): - return injective_exchange_tx_pb.MsgBatchCreateDerivativeLimitOrders(sender=sender, orders=orders) + def MsgCreateBinaryOptionsLimitOrder( + self, + market_id: str, + sender: str, + subaccount_id: str, + fee_recipient: str, + price: float, + quantity: float, + cid: Optional[str] = None, + **kwargs, + ): + """ + This method is deprecated and will be removed soon. Please use `msg_create_binary_options_limit_order` instead + """ + warn( + "This method is deprecated. Use msg_create_binary_options_limit_order instead", + DeprecationWarning, + stacklevel=2, + ) + if kwargs.get("is_reduce_only", False): + margin = Decimal(0) + else: + margin = Decimal(str(price)) * Decimal(str(quantity)) - def MsgBatchCancelDerivativeOrders(self, sender: str, data: List): - return injective_exchange_tx_pb.MsgBatchCancelDerivativeOrders(sender=sender, data=data) + if kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY) - def MsgBatchUpdateOrders(self, sender: str, **kwargs): - return injective_exchange_tx_pb.MsgBatchUpdateOrders( + elif not kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + elif kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY_PO) + + elif not kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL_PO) + + elif kwargs.get("stop_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_BUY) + + elif kwargs.get("stop_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_SEll) + + elif kwargs.get("take_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_BUY) + + elif kwargs.get("take_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_SELL) + + return injective_exchange_tx_pb.MsgCreateBinaryOptionsLimitOrder( sender=sender, - subaccount_id=kwargs.get("subaccount_id"), - spot_market_ids_to_cancel_all=kwargs.get("spot_market_ids_to_cancel_all"), - derivative_market_ids_to_cancel_all=kwargs.get("derivative_market_ids_to_cancel_all"), - spot_orders_to_cancel=kwargs.get("spot_orders_to_cancel"), - derivative_orders_to_cancel=kwargs.get("derivative_orders_to_cancel"), - spot_orders_to_create=kwargs.get("spot_orders_to_create"), - derivative_orders_to_create=kwargs.get("derivative_orders_to_create"), - binary_options_orders_to_cancel=kwargs.get("binary_options_orders_to_cancel"), - binary_options_market_ids_to_cancel_all=kwargs.get("binary_options_market_ids_to_cancel_all"), - binary_options_orders_to_create=kwargs.get("binary_options_orders_to_create"), + order=self.binary_options_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=Decimal(str(kwargs["trigger_price"])) if "trigger_price" in kwargs else None, + denom=kwargs.get("denom"), + ), ) - def MsgLiquidatePosition( + def msg_create_binary_options_limit_order( self, + market_id: str, sender: str, subaccount_id: str, + fee_recipient: str, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, + cid: Optional[str] = None, + trigger_price: Optional[Decimal] = None, + denom: Optional[Denom] = None, + ) -> injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder: + return injective_exchange_tx_pb.MsgCreateDerivativeLimitOrder( + sender=sender, + order=self.binary_options_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + denom=denom, + ), + ) + + def MsgCreateBinaryOptionsMarketOrder( + self, market_id: str, - order: Optional[injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.DerivativeOrder] = None, + sender: str, + subaccount_id: str, + fee_recipient: str, + price: float, + quantity: float, + cid: Optional[str] = None, + **kwargs, ): - return injective_exchange_tx_pb.MsgLiquidatePosition( - sender=sender, subaccount_id=subaccount_id, market_id=market_id, order=order + """ + This method is deprecated and will be removed soon. Please use `msg_create_binary_options_market_order` instead + """ + warn( + "This method is deprecated. Use msg_create_binary_options_market_order instead", + DeprecationWarning, + stacklevel=2, ) + if kwargs.get("is_reduce_only", False): + margin = Decimal(0) + else: + margin = Decimal(str(price)) * Decimal(str(quantity)) - def MsgIncreasePositionMargin( + if kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY) + + elif not kwargs.get("is_buy") and not kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL) + + elif kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.BUY_PO) + + elif not kwargs.get("is_buy") and kwargs.get("is_po"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.SELL_PO) + + elif kwargs.get("stop_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_BUY) + + elif kwargs.get("stop_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.STOP_SEll) + + elif kwargs.get("take_buy"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_BUY) + + elif kwargs.get("take_sell"): + order_type = injective_exchange_pb.OrderType.Name(injective_exchange_pb.OrderType.TAKE_SELL) + + return injective_exchange_tx_pb.MsgCreateBinaryOptionsMarketOrder( + sender=sender, + order=self.binary_options_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=Decimal(str(price)), + quantity=Decimal(str(quantity)), + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=Decimal(str(kwargs["trigger_price"])) if "trigger_price" in kwargs else None, + denom=kwargs.get("denom"), + ), + ) + + def msg_create_binary_options_market_order( + self, + market_id: str, + sender: str, + subaccount_id: str, + fee_recipient: str, + price: Decimal, + quantity: Decimal, + margin: Decimal, + order_type: str, + cid: Optional[str] = None, + trigger_price: Optional[Decimal] = None, + denom: Optional[Denom] = None, + ): + return injective_exchange_tx_pb.MsgCreateBinaryOptionsMarketOrder( + sender=sender, + order=self.binary_options_order( + market_id=market_id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + denom=denom, + ), + ) + + def MsgCancelBinaryOptionsOrder( self, sender: str, - source_subaccount_id: str, - destination_subaccount_id: str, market_id: str, - amount: float, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, ): - market = self.derivative_markets[market_id] + """ + This method is deprecated and will be removed soon. Please use `msg_cancel_binary_options_order` instead + """ + warn( + "This method is deprecated. Use msg_cancel_binary_options_order instead", + DeprecationWarning, + stacklevel=2, + ) + return injective_exchange_tx_pb.MsgCancelBinaryOptionsOrder( + sender=sender, + market_id=market_id, + subaccount_id=subaccount_id, + order_hash=order_hash, + cid=cid, + ) - additional_margin = market.margin_to_chain_format(human_readable_value=Decimal(str(amount))) - return injective_exchange_tx_pb.MsgIncreasePositionMargin( + def msg_cancel_binary_options_order( + self, + market_id: str, + sender: str, + subaccount_id: str, + order_hash: Optional[str] = None, + cid: Optional[str] = None, + is_conditional: Optional[bool] = False, + is_buy: Optional[bool] = False, + is_market_order: Optional[bool] = False, + ) -> injective_exchange_tx_pb.MsgCancelBinaryOptionsOrder: + order_mask = self._order_mask(is_conditional=is_conditional, is_buy=is_buy, is_market_order=is_market_order) + + return injective_exchange_tx_pb.MsgCancelBinaryOptionsOrder( sender=sender, - source_subaccount_id=source_subaccount_id, - destination_subaccount_id=destination_subaccount_id, market_id=market_id, - amount=str(int(additional_margin)), + subaccount_id=subaccount_id, + order_hash=order_hash, + order_mask=order_mask, + cid=cid, ) def MsgSubaccountTransfer( @@ -730,6 +1527,14 @@ def MsgSubaccountTransfer( amount: int, denom: str, ): + """ + This method is deprecated and will be removed soon. Please use `msg_subaccount_transfer` instead + """ + warn( + "This method is deprecated. Use msg_subaccount_transfer instead", + DeprecationWarning, + stacklevel=2, + ) be_amount = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) return injective_exchange_tx_pb.MsgSubaccountTransfer( @@ -739,12 +1544,20 @@ def MsgSubaccountTransfer( amount=be_amount, ) - def MsgWithdraw(self, sender: str, subaccount_id: str, amount: float, denom: str): - be_amount = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) + def msg_subaccount_transfer( + self, + sender: str, + source_subaccount_id: str, + destination_subaccount_id: str, + amount: Decimal, + denom: str, + ) -> injective_exchange_tx_pb.MsgSubaccountTransfer: + be_amount = self.create_coin_amount(amount=amount, token_name=denom) - return injective_exchange_tx_pb.MsgWithdraw( + return injective_exchange_tx_pb.MsgSubaccountTransfer( sender=sender, - subaccount_id=subaccount_id, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, amount=be_amount, ) @@ -756,6 +1569,14 @@ def MsgExternalTransfer( amount: int, denom: str, ): + """ + This method is deprecated and will be removed soon. Please use `msg_external_transfer` instead + """ + warn( + "This method is deprecated. Use msg_external_transfer instead", + DeprecationWarning, + stacklevel=2, + ) coin = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) return injective_exchange_tx_pb.MsgExternalTransfer( @@ -765,129 +1586,184 @@ def MsgExternalTransfer( amount=coin, ) - def MsgBid(self, sender: str, bid_amount: float, round: float): - be_amount = Decimal(str(bid_amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + def msg_external_transfer( + self, + sender: str, + source_subaccount_id: str, + destination_subaccount_id: str, + amount: Decimal, + denom: str, + ) -> injective_exchange_tx_pb.MsgExternalTransfer: + coin = self.create_coin_amount(amount=amount, token_name=denom) - return injective_auction_tx_pb.MsgBid( + return injective_exchange_tx_pb.MsgExternalTransfer( sender=sender, - round=round, - bid_amount=self.coin(amount=int(be_amount), denom=INJ_DENOM), + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + amount=coin, ) - def MsgGrantGeneric(self, granter: str, grantee: str, msg_type: str, expire_in: int): - auth = cosmos_authz_pb.GenericAuthorization(msg=msg_type) - any_auth = any_pb2.Any() - any_auth.Pack(auth, type_url_prefix="") - - grant = cosmos_authz_pb.Grant( - authorization=any_auth, - expiration=timestamp_pb2.Timestamp(seconds=(int(time()) + expire_in)), + def MsgLiquidatePosition( + self, + sender: str, + subaccount_id: str, + market_id: str, + order: Optional[injective_exchange_pb.DerivativeOrder] = None, + ): + """ + This method is deprecated and will be removed soon. Please use `msg_liquidate_position` instead + """ + warn( + "This method is deprecated. Use msg_liquidate_position instead", + DeprecationWarning, + stacklevel=2, + ) + return injective_exchange_tx_pb.MsgLiquidatePosition( + sender=sender, subaccount_id=subaccount_id, market_id=market_id, order=order ) - return cosmos_authz_tx_pb.MsgGrant(granter=granter, grantee=grantee, grant=grant) + def msg_liquidate_position( + self, + sender: str, + subaccount_id: str, + market_id: str, + order: Optional[injective_exchange_pb.DerivativeOrder] = None, + ) -> injective_exchange_tx_pb.MsgLiquidatePosition: + return injective_exchange_tx_pb.MsgLiquidatePosition( + sender=sender, subaccount_id=subaccount_id, market_id=market_id, order=order + ) - def MsgGrantTyped( + def msg_emergency_settle_market( self, - granter: str, - grantee: str, - msg_type: str, - expire_in: int, + sender: str, subaccount_id: str, - **kwargs, + market_id: str, + ) -> injective_exchange_tx_pb.MsgEmergencySettleMarket: + return injective_exchange_tx_pb.MsgEmergencySettleMarket( + sender=sender, subaccount_id=subaccount_id, market_id=market_id + ) + + def MsgIncreasePositionMargin( + self, + sender: str, + source_subaccount_id: str, + destination_subaccount_id: str, + market_id: str, + amount: float, ): - auth = None - if msg_type == "CreateSpotLimitOrderAuthz": - auth = injective_authz_pb.CreateSpotLimitOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "CreateSpotMarketOrderAuthz": - auth = injective_authz_pb.CreateSpotMarketOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "BatchCreateSpotLimitOrdersAuthz": - auth = injective_authz_pb.BatchCreateSpotLimitOrdersAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "CancelSpotOrderAuthz": - auth = injective_authz_pb.CancelSpotOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "BatchCancelSpotOrdersAuthz": - auth = injective_authz_pb.BatchCancelSpotOrdersAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "CreateDerivativeLimitOrderAuthz": - auth = injective_authz_pb.CreateDerivativeLimitOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "CreateDerivativeMarketOrderAuthz": - auth = injective_authz_pb.CreateDerivativeMarketOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "BatchCreateDerivativeLimitOrdersAuthz": - auth = injective_authz_pb.BatchCreateDerivativeLimitOrdersAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "CancelDerivativeOrderAuthz": - auth = injective_authz_pb.CancelDerivativeOrderAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "BatchCancelDerivativeOrdersAuthz": - auth = injective_authz_pb.BatchCancelDerivativeOrdersAuthz( - subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") - ) - elif msg_type == "BatchUpdateOrdersAuthz": - auth = injective_authz_pb.BatchUpdateOrdersAuthz( - subaccount_id=subaccount_id, - spot_markets=kwargs.get("spot_markets"), - derivative_markets=kwargs.get("derivative_markets"), - ) + """ + This method is deprecated and will be removed soon. Please use `msg_increase_position_margin` instead + """ + warn( + "This method is deprecated. Use msg_increase_position_margin instead", + DeprecationWarning, + stacklevel=2, + ) + market = self.derivative_markets[market_id] - any_auth = any_pb2.Any() - any_auth.Pack(auth, type_url_prefix="") + additional_margin = market.margin_to_chain_format(human_readable_value=Decimal(str(amount))) + return injective_exchange_tx_pb.MsgIncreasePositionMargin( + sender=sender, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + market_id=market_id, + amount=str(int(additional_margin)), + ) - grant = cosmos_authz_pb.Grant( - authorization=any_auth, - expiration=timestamp_pb2.Timestamp(seconds=(int(time()) + expire_in)), + def msg_increase_position_margin( + self, + sender: str, + source_subaccount_id: str, + destination_subaccount_id: str, + market_id: str, + amount: Decimal, + ): + market = self.derivative_markets[market_id] + + additional_margin = market.margin_to_chain_format(human_readable_value=amount) + return injective_exchange_tx_pb.MsgIncreasePositionMargin( + sender=sender, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + market_id=market_id, + amount=str(int(additional_margin)), ) - return cosmos_authz_tx_pb.MsgGrant(granter=granter, grantee=grantee, grant=grant) - - def MsgExec(self, grantee: str, msgs: List): - any_msgs: List[any_pb2.Any] = [] - for msg in msgs: - any_msg = any_pb2.Any() - any_msg.Pack(msg, type_url_prefix="") - any_msgs.append(any_msg) + def MsgRewardsOptOut(self, sender: str): + """ + This method is deprecated and will be removed soon. Please use `msg_rewards_opt_out` instead + """ + warn( + "This method is deprecated. Use msg_rewards_opt_out instead", + DeprecationWarning, + stacklevel=2, + ) + return injective_exchange_tx_pb.MsgRewardsOptOut(sender=sender) - return cosmos_authz_tx_pb.MsgExec(grantee=grantee, msgs=any_msgs) + def msg_rewards_opt_out(self, sender: str) -> injective_exchange_tx_pb.MsgRewardsOptOut: + return injective_exchange_tx_pb.MsgRewardsOptOut(sender=sender) - def MsgRevoke(self, granter: str, grantee: str, msg_type: str): - return cosmos_authz_tx_pb.MsgRevoke(granter=granter, grantee=grantee, msg_type_url=msg_type) + def MsgAdminUpdateBinaryOptionsMarket( + self, + sender: str, + market_id: str, + status: str, + **kwargs, + ): + """ + This method is deprecated and will be removed soon. Please use `msg_admin_update_binary_options_market` instead + """ + warn( + "This method is deprecated. Use msg_admin_update_binary_options_market instead", + DeprecationWarning, + stacklevel=2, + ) - def MsgRelayPriceFeedPrice(self, sender: list, base: list, quote: list, price: list): - return injective_oracle_tx_pb.MsgRelayPriceFeedPrice(sender=sender, base=base, quote=quote, price=price) + if kwargs.get("settlement_price") is not None: + scale_price = Decimal((kwargs.get("settlement_price") * pow(10, 18))) + price_to_bytes = bytes(str(scale_price), "utf-8") - def MsgSendToEth(self, denom: str, sender: str, eth_dest: str, amount: float, bridge_fee: float): - be_amount = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) - be_bridge_fee = self.create_coin_amount(amount=Decimal(str(bridge_fee)), token_name=denom) + else: + price_to_bytes = "" - return injective_peggy_tx_pb.MsgSendToEth( + return injective_exchange_tx_pb.MsgAdminUpdateBinaryOptionsMarket( sender=sender, - eth_dest=eth_dest, - amount=be_amount, - bridge_fee=be_bridge_fee, + market_id=market_id, + settlement_price=price_to_bytes, + expiration_timestamp=kwargs.get("expiration_timestamp"), + settlement_timestamp=kwargs.get("settlement_timestamp"), + status=status, ) - def MsgDelegate(self, delegator_address: str, validator_address: str, amount: float): - be_amount = Decimal(str(amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + def msg_admin_update_binary_options_market( + self, + sender: str, + market_id: str, + status: str, + settlement_price: Optional[Decimal] = None, + expiration_timestamp: Optional[int] = None, + settlement_timestamp: Optional[int] = None, + ) -> injective_exchange_tx_pb.MsgAdminUpdateBinaryOptionsMarket: + market = self.binary_option_markets[market_id] - return cosmos_staking_tx_pb.MsgDelegate( - delegator_address=delegator_address, - validator_address=validator_address, - amount=self.coin(amount=int(be_amount), denom=INJ_DENOM), + if settlement_price is not None: + chain_settlement_price = market.price_to_chain_format(human_readable_value=settlement_price) + price_parameter = f"{chain_settlement_price.normalize():f}" + else: + price_parameter = None + + return injective_exchange_tx_pb.MsgAdminUpdateBinaryOptionsMarket( + sender=sender, + market_id=market_id, + settlement_price=price_parameter, + expiration_timestamp=expiration_timestamp, + settlement_timestamp=settlement_timestamp, + status=status, ) + # endregion + + # region Insurance module def MsgCreateInsuranceFund( self, sender: str, @@ -941,38 +1817,53 @@ def MsgRequestRedemption( amount=self.coin(amount=amount, denom=share_denom), ) - def MsgVote( - self, - proposal_id: str, - voter: str, - option: int, - ): - return cosmos_gov_tx_pb.MsgVote(proposal_id=proposal_id, voter=voter, option=option) + # endregion - def MsgPrivilegedExecuteContract( - self, sender: str, contract: str, msg: str, **kwargs - ) -> injective_exchange_tx_pb.MsgPrivilegedExecuteContract: - return injective_exchange_tx_pb.MsgPrivilegedExecuteContract( - sender=sender, - contract_address=contract, - data=msg, - funds=kwargs.get("funds") # funds is a string of Coin strings, comma separated, - # e.g. 100000inj,20000000000usdt + # region Oracle module + def MsgRelayProviderPrices(self, sender: str, provider: str, symbols: list, prices: list): + oracle_prices = [] + + for price in prices: + scale_price = Decimal((price) * pow(10, 18)) + price_to_bytes = bytes(str(scale_price), "utf-8") + oracle_prices.append(price_to_bytes) + + return injective_oracle_tx_pb.MsgRelayProviderPrices( + sender=sender, provider=provider, symbols=symbols, prices=oracle_prices ) - def MsgInstantiateContract( - self, sender: str, admin: str, code_id: int, label: str, message: bytes, **kwargs - ) -> wasm_tx_pb.MsgInstantiateContract: - return wasm_tx_pb.MsgInstantiateContract( + def MsgRelayPriceFeedPrice(self, sender: list, base: list, quote: list, price: list): + return injective_oracle_tx_pb.MsgRelayPriceFeedPrice(sender=sender, base=base, quote=quote, price=price) + + # endregion + + # region Peggy module + def MsgSendToEth(self, denom: str, sender: str, eth_dest: str, amount: float, bridge_fee: float): + be_amount = self.create_coin_amount(amount=Decimal(str(amount)), token_name=denom) + be_bridge_fee = self.create_coin_amount(amount=Decimal(str(bridge_fee)), token_name=denom) + + return injective_peggy_tx_pb.MsgSendToEth( sender=sender, - admin=admin, - code_id=code_id, - label=label, - msg=message, - funds=kwargs.get("funds"), # funds is a list of cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin. - # The coins in the list must be sorted in alphabetical order by denoms. + eth_dest=eth_dest, + amount=be_amount, + bridge_fee=be_bridge_fee, + ) + + # endregion + + # region Staking module + def MsgDelegate(self, delegator_address: str, validator_address: str, amount: float): + be_amount = Decimal(str(amount)) * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return cosmos_staking_tx_pb.MsgDelegate( + delegator_address=delegator_address, + validator_address=validator_address, + amount=self.coin(amount=int(be_amount), denom=INJ_DENOM), ) + # endregion + + # region Tokenfactory module def msg_create_denom( self, sender: str, @@ -990,14 +1881,14 @@ def msg_create_denom( def msg_mint( self, sender: str, - amount: cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin, + amount: base_coin_pb.Coin, ) -> token_factory_tx_pb.MsgMint: return token_factory_tx_pb.MsgMint(sender=sender, amount=amount) def msg_burn( self, sender: str, - amount: cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin, + amount: base_coin_pb.Coin, ) -> token_factory_tx_pb.MsgBurn: return token_factory_tx_pb.MsgBurn(sender=sender, amount=amount) @@ -1047,14 +1938,108 @@ def msg_change_admin( new_admin=new_admin, ) - def msg_execute_contract_compat(self, sender: str, contract: str, msg: str, funds: str): - return wasmx_tx_pb.MsgExecuteContractCompat( + # endregion + + # region Wasm module + def MsgInstantiateContract( + self, sender: str, admin: str, code_id: int, label: str, message: bytes, **kwargs + ) -> wasm_tx_pb.MsgInstantiateContract: + return wasm_tx_pb.MsgInstantiateContract( + sender=sender, + admin=admin, + code_id=code_id, + label=label, + msg=message, + funds=kwargs.get("funds"), # funds is a list of base_coin_pb.Coin. + # The coins in the list must be sorted in alphabetical order by denoms. + ) + + def MsgExecuteContract(self, sender: str, contract: str, msg: str, **kwargs): + return wasm_tx_pb.MsgExecuteContract( sender=sender, contract=contract, - msg=msg, - funds=funds, + msg=bytes(msg, "utf-8"), + funds=kwargs.get("funds") # funds is a list of base_coin_pb.Coin. + # The coins in the list must be sorted in alphabetical order by denoms. + ) + + # endregion + + def MsgGrantTyped( + self, + granter: str, + grantee: str, + msg_type: str, + expire_in: int, + subaccount_id: str, + **kwargs, + ): + auth = None + if msg_type == "CreateSpotLimitOrderAuthz": + auth = injective_authz_pb.CreateSpotLimitOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "CreateSpotMarketOrderAuthz": + auth = injective_authz_pb.CreateSpotMarketOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "BatchCreateSpotLimitOrdersAuthz": + auth = injective_authz_pb.BatchCreateSpotLimitOrdersAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "CancelSpotOrderAuthz": + auth = injective_authz_pb.CancelSpotOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "BatchCancelSpotOrdersAuthz": + auth = injective_authz_pb.BatchCancelSpotOrdersAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "CreateDerivativeLimitOrderAuthz": + auth = injective_authz_pb.CreateDerivativeLimitOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "CreateDerivativeMarketOrderAuthz": + auth = injective_authz_pb.CreateDerivativeMarketOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "BatchCreateDerivativeLimitOrdersAuthz": + auth = injective_authz_pb.BatchCreateDerivativeLimitOrdersAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "CancelDerivativeOrderAuthz": + auth = injective_authz_pb.CancelDerivativeOrderAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "BatchCancelDerivativeOrdersAuthz": + auth = injective_authz_pb.BatchCancelDerivativeOrdersAuthz( + subaccount_id=subaccount_id, market_ids=kwargs.get("market_ids") + ) + elif msg_type == "BatchUpdateOrdersAuthz": + auth = injective_authz_pb.BatchUpdateOrdersAuthz( + subaccount_id=subaccount_id, + spot_markets=kwargs.get("spot_markets"), + derivative_markets=kwargs.get("derivative_markets"), + ) + + any_auth = any_pb2.Any() + any_auth.Pack(auth, type_url_prefix="") + + grant = cosmos_authz_pb.Grant( + authorization=any_auth, + expiration=timestamp_pb2.Timestamp(seconds=(int(time()) + expire_in)), ) + return cosmos_authz_tx_pb.MsgGrant(granter=granter, grantee=grantee, grant=grant) + + def MsgVote( + self, + proposal_id: str, + voter: str, + option: int, + ): + return cosmos_gov_tx_pb.MsgVote(proposal_id=proposal_id, voter=voter, option=option) + def chain_stream_bank_balances_filter( self, accounts: Optional[List[str]] = None ) -> chain_stream_query.BankBalancesFilter: @@ -1144,7 +2129,7 @@ def MsgWithdrawValidatorCommission(self, validator_address: str): def msg_withdraw_validator_commission(self, validator_address: str): return cosmos_distribution_tx_pb.MsgWithdrawValidatorCommission(validator_address=validator_address) - def msg_fund_community_pool(self, amounts: List[cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin], depositor: str): + def msg_fund_community_pool(self, amounts: List[base_coin_pb.Coin], depositor: str): return cosmos_distribution_tx_pb.MsgFundCommunityPool(amount=amounts, depositor=depositor) def msg_update_distribution_params(self, authority: str, community_tax: str, withdraw_address_enabled: bool): @@ -1154,9 +2139,7 @@ def msg_update_distribution_params(self, authority: str, community_tax: str, wit ) return cosmos_distribution_tx_pb.MsgUpdateParams(authority=authority, params=params) - def msg_community_pool_spend( - self, authority: str, recipient: str, amount: List[cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin] - ): + def msg_community_pool_spend(self, authority: str, recipient: str, amount: List[base_coin_pb.Coin]): return cosmos_distribution_tx_pb.MsgCommunityPoolSpend(authority=authority, recipient=recipient, amount=amount) # data field format: [request-msg-header][raw-byte-msg-response] @@ -1369,3 +2352,61 @@ def _initialize_markets_and_tokens_from_files(self): self.spot_markets = spot_markets self.derivative_markets = derivative_markets self.binary_option_markets = dict() + + def _order_mask(self, is_conditional: bool, is_buy: bool, is_market_order: bool) -> int: + order_mask = 0 + + if is_conditional: + order_mask += injective_exchange_pb.OrderMask.CONDITIONAL + else: + order_mask += injective_exchange_pb.OrderMask.REGULAR + + if is_buy: + order_mask += injective_exchange_pb.OrderMask.DIRECTION_BUY_OR_HIGHER + else: + order_mask += injective_exchange_pb.OrderMask.DIRECTION_SELL_OR_LOWER + + if is_market_order: + order_mask += injective_exchange_pb.OrderMask.TYPE_MARKET + else: + order_mask += injective_exchange_pb.OrderMask.TYPE_LIMIT + + if order_mask == 0: + order_mask = 1 + + return order_mask + + def _basic_derivative_order( + self, + market_id: str, + subaccount_id: str, + fee_recipient: str, + chain_price: Decimal, + chain_quantity: Decimal, + chain_margin: Decimal, + order_type: str, + cid: Optional[str] = None, + chain_trigger_price: Optional[Decimal] = None, + ) -> injective_exchange_pb.DerivativeOrder: + formatted_quantity = f"{chain_quantity.normalize():f}" + formatted_price = f"{chain_price.normalize():f}" + formatted_margin = f"{chain_margin.normalize():f}" + + trigger_price = chain_trigger_price or Decimal(0) + formatted_trigger_price = f"{trigger_price.normalize():f}" + + chain_order_type = injective_exchange_pb.OrderType.Value(order_type) + + return injective_exchange_pb.DerivativeOrder( + market_id=market_id, + order_info=injective_exchange_pb.OrderInfo( + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=formatted_price, + quantity=formatted_quantity, + cid=cid, + ), + order_type=chain_order_type, + margin=formatted_margin, + trigger_price=formatted_trigger_price, + ) diff --git a/pyinjective/core/market.py b/pyinjective/core/market.py index 2bd4fe1b..66063130 100644 --- a/pyinjective/core/market.py +++ b/pyinjective/core/market.py @@ -169,6 +169,17 @@ def price_to_chain_format(self, human_readable_value: Decimal, special_denom: Op return extended_chain_formatted_value + def margin_to_chain_format(self, human_readable_value: Decimal, special_denom: Optional[Denom] = None) -> Decimal: + decimals = self.quote_token.decimals if special_denom is None else special_denom.quote + min_quantity_tick_size = ( + self.min_quantity_tick_size if special_denom is None else special_denom.min_quantity_tick_size + ) + chain_formatted_value = human_readable_value * Decimal(f"1e{decimals}") + quantized_value = (chain_formatted_value // min_quantity_tick_size) * min_quantity_tick_size + extended_chain_formatted_value = quantized_value * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + return extended_chain_formatted_value + def calculate_margin_in_chain_format( self, human_readable_quantity: Decimal, diff --git a/tests/core/test_gas_limit_estimator.py b/tests/core/test_gas_limit_estimator.py index 916c47a9..293f5f25 100644 --- a/tests/core/test_gas_limit_estimator.py +++ b/tests/core/test_gas_limit_estimator.py @@ -24,26 +24,24 @@ def test_estimation_for_batch_create_spot_limit_orders(self): spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=5, - quantity=1, - is_buy=True, - is_po=False, + price=Decimal("5"), + quantity=Decimal("1"), + order_type="BUY", ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=4, - quantity=1, - is_buy=True, - is_po=False, + price=Decimal("4"), + quantity=Decimal("1"), + order_type="BUY", ), ] - message = composer.MsgBatchCreateSpotLimitOrders(sender="sender", orders=orders) + message = composer.msg_batch_create_spot_limit_orders(sender="sender", orders=orders) estimator = GasLimitEstimator.for_message(message=message) expected_order_gas_limit = 50000 @@ -55,23 +53,23 @@ def test_estimation_for_batch_cancel_spot_orders(self): spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", ), - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", ), - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", ), ] - message = composer.MsgBatchCancelSpotOrders(sender="sender", data=orders) + message = composer.msg_batch_cancel_spot_orders(sender="sender", orders_data=orders) estimator = GasLimitEstimator.for_message(message=message) expected_order_gas_limit = 50000 @@ -83,28 +81,26 @@ def test_estimation_for_batch_create_derivative_limit_orders(self): market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" composer = Composer(network="testnet") orders = [ - composer.DerivativeOrder( + composer.derivative_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=3, - quantity=1, - leverage=1, - is_buy=True, - is_po=False, + price=Decimal(3), + quantity=Decimal(1), + margin=Decimal(3), + order_type="BUY", ), - composer.DerivativeOrder( + composer.derivative_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=20, - quantity=1, - leverage=1, - is_buy=False, - is_reduce_only=False, + price=Decimal(20), + quantity=Decimal(1), + margin=Decimal(20), + order_type="SELL", ), ] - message = composer.MsgBatchCreateDerivativeLimitOrders(sender="sender", orders=orders) + message = composer.msg_batch_create_derivative_limit_orders(sender="sender", orders=orders) estimator = GasLimitEstimator.for_message(message=message) expected_order_gas_limit = 70_000 @@ -116,23 +112,23 @@ def test_estimation_for_batch_cancel_derivative_orders(self): spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", ), - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", ), - composer.OrderData( + composer.order_data( market_id=spot_market_id, subaccount_id="subaccount_id", order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", ), ] - message = composer.MsgBatchCancelDerivativeOrders(sender="sender", data=orders) + message = composer.msg_batch_cancel_derivative_orders(sender="sender", orders_data=orders) estimator = GasLimitEstimator.for_message(message=message) expected_order_gas_limit = 60_000 @@ -144,23 +140,21 @@ def test_estimation_for_batch_update_orders_to_create_spot_orders(self): market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.SpotOrder( + composer.spot_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=5, - quantity=1, - is_buy=True, - is_po=False, + price=Decimal("5"), + quantity=Decimal("1"), + order_type="BUY", ), - composer.SpotOrder( + composer.spot_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=4, - quantity=1, - is_buy=True, - is_po=False, + price=Decimal("4"), + quantity=Decimal("1"), + order_type="BUY", ), ] message = composer.MsgBatchUpdateOrders( @@ -181,25 +175,23 @@ def test_estimation_for_batch_update_orders_to_create_derivative_orders(self): market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" composer = Composer(network="testnet") orders = [ - composer.DerivativeOrder( + composer.derivative_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=3, - quantity=1, - leverage=1, - is_buy=True, - is_po=False, + price=Decimal(3), + quantity=Decimal(1), + margin=Decimal(3), + order_type="BUY", ), - composer.DerivativeOrder( + composer.derivative_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=20, - quantity=1, - leverage=1, - is_buy=False, - is_reduce_only=False, + price=Decimal(20), + quantity=Decimal(1), + margin=Decimal(20), + order_type="SELL", ), ] message = composer.MsgBatchUpdateOrders( @@ -238,25 +230,23 @@ def test_estimation_for_batch_update_orders_to_create_binary_orders(self, usdt_t ) composer.binary_option_markets[market.id] = market orders = [ - composer.BinaryOptionsOrder( + composer.binary_options_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=3, - quantity=1, - leverage=1, - is_buy=True, - is_po=False, + price=Decimal(3), + quantity=Decimal(1), + margin=Decimal(3), + order_type="BUY", ), - composer.BinaryOptionsOrder( + composer.binary_options_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=20, - quantity=1, - leverage=1, - is_buy=False, - is_reduce_only=False, + price=Decimal(20), + quantity=Decimal(1), + margin=Decimal(20), + order_type="SELL", ), ] message = composer.MsgBatchUpdateOrders( @@ -278,17 +268,17 @@ def test_estimation_for_batch_update_orders_to_cancel_spot_orders(self): market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", @@ -312,17 +302,17 @@ def test_estimation_for_batch_update_orders_to_cancel_derivative_orders(self): market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" composer = Composer(network="testnet") orders = [ - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", @@ -346,17 +336,17 @@ def test_estimation_for_batch_update_orders_to_cancel_binary_orders(self): market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6" composer = Composer(network="testnet") orders = [ - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", ), - composer.OrderData( + composer.order_data( market_id=market_id, subaccount_id="subaccount_id", order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", @@ -441,14 +431,13 @@ def test_estimation_for_exec_message(self): market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") orders = [ - composer.SpotOrder( + composer.spot_order( market_id=market_id, subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=5, - quantity=1, - is_buy=True, - is_po=False, + price=Decimal("5"), + quantity=Decimal("1"), + order_type="BUY", ), ] inner_message = composer.MsgBatchUpdateOrders( @@ -510,15 +499,14 @@ def test_estimation_for_governance_message(self): def test_estimation_for_generic_exchange_message(self): composer = Composer(network="testnet") - message = composer.MsgCreateSpotLimitOrder( + message = composer.msg_create_spot_limit_order( sender="sender", market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", ) estimator = GasLimitEstimator.for_message(message=message) diff --git a/tests/core/test_market.py b/tests/core/test_market.py index ede8aea5..48c2f5e5 100644 --- a/tests/core/test_market.py +++ b/tests/core/test_market.py @@ -248,6 +248,42 @@ def test_convert_price_to_chain_format_without_fixed_denom(self, first_match_bet assert quantized_chain_format_value == chain_value + def test_convert_margin_to_chain_format_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + fixed_denom = Denom( + description="Fixed denom", + base=2, + quote=4, + min_quantity_tick_size=100, + min_price_tick_size=10000, + ) + + chain_value = first_match_bet_market.margin_to_chain_format( + human_readable_value=original_quantity, + special_denom=fixed_denom, + ) + price_decimals = fixed_denom.quote + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = (expected_value // Decimal(str(fixed_denom.min_quantity_tick_size))) * Decimal( + str(fixed_denom.min_quantity_tick_size) + ) + quantized_chain_format_value = quantized_value * Decimal("1e18") + + assert quantized_chain_format_value == chain_value + + def test_convert_margin_to_chain_format_without_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): + original_quantity = Decimal("123.456789") + + chain_value = first_match_bet_market.margin_to_chain_format(human_readable_value=original_quantity) + price_decimals = first_match_bet_market.quote_token.decimals + expected_value = original_quantity * Decimal(f"1e{price_decimals}") + quantized_value = ( + expected_value // first_match_bet_market.min_quantity_tick_size + ) * first_match_bet_market.min_quantity_tick_size + quantized_chain_format_value = quantized_value * Decimal("1e18") + + assert quantized_chain_format_value == chain_value + def test_calculate_margin_for_buy_with_fixed_denom(self, first_match_bet_market: BinaryOptionMarket): original_quantity = Decimal("123.456789") original_price = Decimal("0.6789") diff --git a/tests/core/test_message_based_transaction_fee_calculator.py b/tests/core/test_message_based_transaction_fee_calculator.py index 23e263c9..b1d774e0 100644 --- a/tests/core/test_message_based_transaction_fee_calculator.py +++ b/tests/core/test_message_based_transaction_fee_calculator.py @@ -117,15 +117,14 @@ async def test_gas_fee_for_exchange_message(self): gas_price=5_000_000, ) - message = composer.MsgCreateSpotLimitOrder( + message = composer.msg_create_spot_limit_order( sender="sender", market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", ) transaction = Transaction() transaction.with_messages(message) @@ -148,15 +147,14 @@ async def test_gas_fee_for_msg_exec_message(self): gas_price=5_000_000, ) - inner_message = composer.MsgCreateSpotLimitOrder( + inner_message = composer.msg_create_spot_limit_order( sender="sender", market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", ) message = composer.MsgExec(grantee="grantee", msgs=[inner_message]) transaction = Transaction() @@ -184,15 +182,14 @@ async def test_gas_fee_for_two_messages_in_one_transaction(self): gas_price=5_000_000, ) - inner_message = composer.MsgCreateSpotLimitOrder( + inner_message = composer.msg_create_spot_limit_order( sender="sender", market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe", subaccount_id="subaccount_id", fee_recipient="fee_recipient", - price=7.523, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("7.523"), + quantity=Decimal("0.01"), + order_type="BUY", ) message = composer.MsgExec(grantee="grantee", msgs=[inner_message]) diff --git a/tests/test_composer.py b/tests/test_composer.py index a0cca2ab..2dcbd056 100644 --- a/tests/test_composer.py +++ b/tests/test_composer.py @@ -2,12 +2,11 @@ from decimal import Decimal import pytest +from google.protobuf import json_format from pyinjective.composer import Composer -from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket +from pyinjective.constant import ADDITIONAL_CHAIN_FORMAT_DECIMALS from pyinjective.core.network import Network -from pyinjective.proto.injective.exchange.v1beta1 import exchange_pb2 -from pyinjective.utils.denom import Denom from tests.model_fixtures.markets_fixtures import btc_usdt_perp_market # noqa: F401 from tests.model_fixtures.markets_fixtures import first_match_bet_market # noqa: F401 from tests.model_fixtures.markets_fixtures import inj_token # noqa: F401 @@ -57,211 +56,6 @@ def test_composer_initialization_from_ini_files(self): assert 6 == inj_usdt_spot_market.quote_token.decimals assert 6 == inj_usdt_perp_market.quote_token.decimals - def test_buy_spot_order_creation(self, basic_composer: Composer, inj_usdt_spot_market: SpotMarket): - fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" - price = 6.869 - quantity = 1587 - order = basic_composer.SpotOrder( - market_id=inj_usdt_spot_market.id, - subaccount_id="1", - fee_recipient=fee_recipient, - price=price, - quantity=quantity, - is_buy=True, - ) - - price_decimals = inj_usdt_spot_market.quote_token.decimals - inj_usdt_spot_market.base_token.decimals - chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") - expected_price = ( - (chain_format_price // inj_usdt_spot_market.min_price_tick_size) - * inj_usdt_spot_market.min_price_tick_size - * Decimal("1e18") - ) - chain_format_quantity = Decimal(str(quantity)) * Decimal(f"1e{inj_usdt_spot_market.base_token.decimals}") - expected_quantity = ( - (chain_format_quantity // inj_usdt_spot_market.min_quantity_tick_size) - * inj_usdt_spot_market.min_quantity_tick_size - * Decimal("1e18") - ) - - assert order.market_id == inj_usdt_spot_market.id - assert order.order_info.subaccount_id == "1" - assert order.order_info.fee_recipient == fee_recipient - assert order.order_info.price == str(int(expected_price)) - assert order.order_info.quantity == str(int(expected_quantity)) - assert order.order_type == exchange_pb2.OrderType.BUY - assert order.trigger_price == "0" - - def test_buy_derivative_order_creation(self, basic_composer: Composer, btc_usdt_perp_market: DerivativeMarket): - fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" - price = 6.869 - quantity = 1587 - leverage = 2 - order = basic_composer.DerivativeOrder( - market_id=btc_usdt_perp_market.id, - subaccount_id="1", - fee_recipient=fee_recipient, - price=price, - quantity=quantity, - is_buy=True, - leverage=leverage, - ) - - price_decimals = btc_usdt_perp_market.quote_token.decimals - chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") - expected_price = ( - (chain_format_price // btc_usdt_perp_market.min_price_tick_size) - * btc_usdt_perp_market.min_price_tick_size - * Decimal("1e18") - ) - chain_format_quantity = Decimal(str(quantity)) - expected_quantity = ( - (chain_format_quantity // btc_usdt_perp_market.min_quantity_tick_size) - * btc_usdt_perp_market.min_quantity_tick_size - * Decimal("1e18") - ) - chain_format_margin = (chain_format_quantity * chain_format_price) / Decimal(leverage) - expected_margin = ( - (chain_format_margin // btc_usdt_perp_market.min_quantity_tick_size) - * btc_usdt_perp_market.min_quantity_tick_size - * Decimal("1e18") - ) - - assert order.market_id == btc_usdt_perp_market.id - assert order.order_info.subaccount_id == "1" - assert order.order_info.fee_recipient == fee_recipient - assert order.order_info.price == str(int(expected_price)) - assert order.order_info.quantity == str(int(expected_quantity)) - assert order.order_type == exchange_pb2.OrderType.BUY - assert order.margin == str(int(expected_margin)) - assert order.trigger_price == "0" - - def test_increase_position_margin(self, basic_composer: Composer, btc_usdt_perp_market: DerivativeMarket): - sender = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" - amount = 1587.789 - message = basic_composer.MsgIncreasePositionMargin( - sender=sender, - source_subaccount_id="1", - destination_subaccount_id="2", - market_id=btc_usdt_perp_market.id, - amount=amount, - ) - - price_decimals = btc_usdt_perp_market.quote_token.decimals - chain_format_margin = Decimal(str(amount)) * Decimal(f"1e{price_decimals}") - expected_margin = ( - (chain_format_margin // btc_usdt_perp_market.min_quantity_tick_size) - * btc_usdt_perp_market.min_quantity_tick_size - * Decimal("1e18") - ) - - assert message.market_id == btc_usdt_perp_market.id - assert message.sender == sender - assert message.source_subaccount_id == "1" - assert message.destination_subaccount_id == "2" - assert message.amount == str(int(expected_margin)) - - def test_buy_binary_option_order_creation_with_fixed_denom( - self, basic_composer: Composer, first_match_bet_market: BinaryOptionMarket - ): - fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" - price = 6.869 - quantity = 1587 - fixed_denom = Denom( - description="Fixed denom", - base=2, - quote=6, - min_price_tick_size=1000, - min_quantity_tick_size=10000, - ) - - order = basic_composer.BinaryOptionsOrder( - market_id=first_match_bet_market.id, - subaccount_id="1", - fee_recipient=fee_recipient, - price=price, - quantity=quantity, - is_buy=True, - denom=fixed_denom, - ) - - price_decimals = fixed_denom.quote - chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") - expected_price = ( - (chain_format_price // Decimal(str(fixed_denom.min_price_tick_size))) - * Decimal(str(fixed_denom.min_price_tick_size)) - * Decimal("1e18") - ) - quantity_decimals = fixed_denom.base - chain_format_quantity = Decimal(str(quantity)) * Decimal(f"1e{quantity_decimals}") - expected_quantity = ( - (chain_format_quantity // Decimal(str(fixed_denom.min_quantity_tick_size))) - * Decimal(str(fixed_denom.min_quantity_tick_size)) - * Decimal("1e18") - ) - chain_format_margin = chain_format_quantity * chain_format_price - expected_margin = ( - (chain_format_margin // Decimal(str(fixed_denom.min_quantity_tick_size))) - * Decimal(str(fixed_denom.min_quantity_tick_size)) - * Decimal("1e18") - ) - - assert order.market_id == first_match_bet_market.id - assert order.order_info.subaccount_id == "1" - assert order.order_info.fee_recipient == fee_recipient - assert order.order_info.price == str(int(expected_price)) - assert order.order_info.quantity == str(int(expected_quantity)) - assert order.order_type == exchange_pb2.OrderType.BUY - assert order.margin == str(int(expected_margin)) - assert order.trigger_price == "0" - - def test_buy_binary_option_order_creation_without_fixed_denom( - self, - basic_composer: Composer, - first_match_bet_market: BinaryOptionMarket, - ): - fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" - price = 6.869 - quantity = 1587 - - order = basic_composer.BinaryOptionsOrder( - market_id=first_match_bet_market.id, - subaccount_id="1", - fee_recipient=fee_recipient, - price=price, - quantity=quantity, - is_buy=True, - ) - - price_decimals = first_match_bet_market.quote_token.decimals - chain_format_price = Decimal(str(price)) * Decimal(f"1e{price_decimals}") - expected_price = ( - (chain_format_price // first_match_bet_market.min_price_tick_size) - * first_match_bet_market.min_price_tick_size - * Decimal("1e18") - ) - chain_format_quantity = Decimal(str(quantity)) - expected_quantity = ( - (chain_format_quantity // first_match_bet_market.min_quantity_tick_size) - * first_match_bet_market.min_quantity_tick_size - * Decimal("1e18") - ) - chain_format_margin = chain_format_quantity * chain_format_price - expected_margin = ( - (chain_format_margin // first_match_bet_market.min_quantity_tick_size) - * first_match_bet_market.min_quantity_tick_size - * Decimal("1e18") - ) - - assert order.market_id == first_match_bet_market.id - assert order.order_info.subaccount_id == "1" - assert order.order_info.fee_recipient == fee_recipient - assert order.order_info.price == str(int(expected_price)) - assert order.order_info.quantity == str(int(expected_quantity)) - assert order.order_type == exchange_pb2.OrderType.BUY - assert order.margin == str(int(expected_margin)) - assert order.trigger_price == "0" - def test_msg_create_denom(self, basic_composer: Composer): sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" subdenom = "inj-test" @@ -380,3 +174,1259 @@ def test_msg_execute_contract_compat(self, basic_composer): assert message.contract == contract assert message.msg == msg assert message.funds == funds + + def test_msg_deposit(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + amount = Decimal(100) + denom = "INJ" + + token = basic_composer.tokens[denom] + + expected_amount = token.chain_formatted_value(human_readable_value=Decimal(amount)) + + message = basic_composer.msg_deposit( + sender=sender, + subaccount_id=subaccount_id, + amount=amount, + denom=denom, + ) + + expected_message = { + "sender": sender, + "subaccountId": subaccount_id, + "amount": { + "amount": f"{expected_amount.normalize():f}", + "denom": token.denom, + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_withdraw(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + amount = Decimal(100) + denom = "INJ" + + token = basic_composer.tokens[denom] + + expected_amount = token.chain_formatted_value(human_readable_value=Decimal(amount)) + + message = basic_composer.msg_withdraw( + sender=sender, + subaccount_id=subaccount_id, + amount=amount, + denom=denom, + ) + + expected_message = { + "sender": sender, + "subaccountId": subaccount_id, + "amount": { + "amount": f"{expected_amount.normalize():f}", + "denom": token.denom, + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_instant_spot_market_launch(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + ticker = "INJ/USDT" + base_denom = "INJ" + quote_denom = "USDT" + min_price_tick_size = Decimal("0.01") + min_quantity_tick_size = Decimal("1") + + base_token = basic_composer.tokens[base_denom] + quote_token = basic_composer.tokens[quote_denom] + + expected_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals - base_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + expected_min_quantity_tick_size = min_quantity_tick_size * Decimal( + f"1e{base_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + + message = basic_composer.msg_instant_spot_market_launch( + sender=sender, + ticker=ticker, + base_denom=base_denom, + quote_denom=quote_denom, + min_price_tick_size=min_price_tick_size, + min_quantity_tick_size=min_quantity_tick_size, + ) + + expected_message = { + "sender": sender, + "ticker": ticker, + "baseDenom": base_token.denom, + "quoteDenom": quote_token.denom, + "minPriceTickSize": f"{expected_min_price_tick_size.normalize():f}", + "minQuantityTickSize": f"{expected_min_quantity_tick_size.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_instant_perpetual_market_launch(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + ticker = "BTC/INJ PERP" + quote_denom = "INJ" + oracle_base = "BTC" + oracle_quote = "INJ" + oracle_scale_factor = 6 + oracle_type = "Band" + min_price_tick_size = Decimal("0.01") + min_quantity_tick_size = Decimal("1") + maker_fee_rate = Decimal("0.001") + taker_fee_rate = Decimal("-0.002") + initial_margin_ratio = Decimal("0.05") + maintenance_margin_ratio = Decimal("0.03") + + quote_token = basic_composer.tokens[quote_denom] + + expected_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + expected_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_initial_margin_ratio = initial_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_maintenance_margin_ratio = maintenance_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + message = basic_composer.msg_instant_perpetual_market_launch( + sender=sender, + ticker=ticker, + quote_denom=quote_denom, + oracle_base=oracle_base, + oracle_quote=oracle_quote, + oracle_scale_factor=oracle_scale_factor, + oracle_type=oracle_type, + maker_fee_rate=maker_fee_rate, + taker_fee_rate=taker_fee_rate, + initial_margin_ratio=initial_margin_ratio, + maintenance_margin_ratio=maintenance_margin_ratio, + min_price_tick_size=min_price_tick_size, + min_quantity_tick_size=min_quantity_tick_size, + ) + + expected_message = { + "sender": sender, + "ticker": ticker, + "quoteDenom": quote_token.denom, + "oracleBase": oracle_base, + "oracleQuote": oracle_quote, + "oracleScaleFactor": oracle_scale_factor, + "oracleType": oracle_type, + "makerFeeRate": f"{expected_maker_fee_rate.normalize():f}", + "takerFeeRate": f"{expected_taker_fee_rate.normalize():f}", + "initialMarginRatio": f"{expected_initial_margin_ratio.normalize():f}", + "maintenanceMarginRatio": f"{expected_maintenance_margin_ratio.normalize():f}", + "minPriceTickSize": f"{expected_min_price_tick_size.normalize():f}", + "minQuantityTickSize": f"{expected_min_quantity_tick_size.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_instant_expiry_futures_market_launch(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + ticker = "BTC/INJ PERP" + quote_denom = "INJ" + oracle_base = "BTC" + oracle_quote = "INJ" + oracle_scale_factor = 6 + oracle_type = "Band" + expiry = 1630000000 + min_price_tick_size = Decimal("0.01") + min_quantity_tick_size = Decimal("1") + maker_fee_rate = Decimal("0.001") + taker_fee_rate = Decimal("-0.002") + initial_margin_ratio = Decimal("0.05") + maintenance_margin_ratio = Decimal("0.03") + + quote_token = basic_composer.tokens[quote_denom] + + expected_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + expected_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_initial_margin_ratio = initial_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_maintenance_margin_ratio = maintenance_margin_ratio * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + message = basic_composer.msg_instant_expiry_futures_market_launch( + sender=sender, + ticker=ticker, + quote_denom=quote_denom, + oracle_base=oracle_base, + oracle_quote=oracle_quote, + oracle_scale_factor=oracle_scale_factor, + oracle_type=oracle_type, + expiry=expiry, + maker_fee_rate=maker_fee_rate, + taker_fee_rate=taker_fee_rate, + initial_margin_ratio=initial_margin_ratio, + maintenance_margin_ratio=maintenance_margin_ratio, + min_price_tick_size=min_price_tick_size, + min_quantity_tick_size=min_quantity_tick_size, + ) + + expected_message = { + "sender": sender, + "ticker": ticker, + "quoteDenom": quote_token.denom, + "oracleBase": oracle_base, + "oracleQuote": oracle_quote, + "oracleType": oracle_type, + "oracleScaleFactor": oracle_scale_factor, + "expiry": str(expiry), + "makerFeeRate": f"{expected_maker_fee_rate.normalize():f}", + "takerFeeRate": f"{expected_taker_fee_rate.normalize():f}", + "initialMarginRatio": f"{expected_initial_margin_ratio.normalize():f}", + "maintenanceMarginRatio": f"{expected_maintenance_margin_ratio.normalize():f}", + "minPriceTickSize": f"{expected_min_price_tick_size.normalize():f}", + "minQuantityTickSize": f"{expected_min_quantity_tick_size.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_spot_order(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = Decimal("36.1") + quantity = Decimal("100") + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + order = basic_composer.spot_order( + market_id=spot_market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = spot_market.price_to_chain_format(human_readable_value=price) + expected_quantity = spot_market.quantity_to_chain_format(human_readable_value=quantity) + expected_trigger_price = spot_market.price_to_chain_format(human_readable_value=trigger_price) + + expected_order = { + "marketId": spot_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=order, + including_default_value_fields=True, + ) + assert dict_message == expected_order + + def test_derivative_order(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + price = Decimal("36.1") + quantity = Decimal("100") + margin = price * quantity + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + order = basic_composer.derivative_order( + market_id=derivative_market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = derivative_market.price_to_chain_format(human_readable_value=price) + expected_quantity = derivative_market.quantity_to_chain_format(human_readable_value=quantity) + expected_margin = derivative_market.margin_to_chain_format(human_readable_value=margin) + expected_trigger_price = derivative_market.price_to_chain_format(human_readable_value=trigger_price) + + expected_order = { + "marketId": derivative_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "orderType": order_type, + "margin": f"{expected_margin.normalize():f}", + "triggerPrice": f"{expected_trigger_price.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=order, + including_default_value_fields=True, + ) + assert dict_message == expected_order + + def test_msg_create_spot_limit_order(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_spot_limit_order( + market_id=spot_market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = spot_market.price_to_chain_format(human_readable_value=price) + expected_quantity = spot_market.quantity_to_chain_format(human_readable_value=quantity) + expected_trigger_price = spot_market.price_to_chain_format(human_readable_value=trigger_price) + + assert "injective.exchange.v1beta1.MsgCreateSpotLimitOrder" == message.DESCRIPTOR.full_name + expected_message = { + "sender": sender, + "order": { + "marketId": spot_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_batch_create_spot_limit_orders(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + order = basic_composer.spot_order( + market_id=spot_market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + message = basic_composer.msg_batch_create_spot_limit_orders( + sender=sender, + orders=[order], + ) + + expected_message = { + "sender": sender, + "orders": [json_format.MessageToDict(message=order, including_default_value_fields=True)], + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_create_spot_market_order(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_spot_market_order( + market_id=spot_market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = spot_market.price_to_chain_format(human_readable_value=price) + expected_quantity = spot_market.quantity_to_chain_format(human_readable_value=quantity) + expected_trigger_price = spot_market.price_to_chain_format(human_readable_value=trigger_price) + + assert "injective.exchange.v1beta1.MsgCreateSpotMarketOrder" == message.DESCRIPTOR.full_name + expected_message = { + "sender": sender, + "order": { + "marketId": spot_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_cancel_spot_order(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + order_hash = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + cid = "test_cid" + + message = basic_composer.msg_cancel_spot_order( + market_id=spot_market.id, + sender=sender, + subaccount_id=subaccount_id, + order_hash=order_hash, + cid=cid, + ) + + expected_message = { + "sender": sender, + "marketId": spot_market.id, + "subaccountId": subaccount_id, + "orderHash": order_hash, + "cid": cid, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_batch_cancel_spot_orders(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + + order_data = basic_composer.order_data( + market_id=spot_market.id, + subaccount_id=subaccount_id, + order_hash="0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000", + ) + + message = basic_composer.msg_batch_cancel_spot_orders( + sender=sender, + orders_data=[order_data], + ) + + assert "injective.exchange.v1beta1.MsgBatchCancelSpotOrders" == message.DESCRIPTOR.full_name + expected_message = { + "sender": sender, + "data": [json_format.MessageToDict(message=order_data, including_default_value_fields=True)], + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_batch_update_orders(self, basic_composer): + spot_market = list(basic_composer.spot_markets.values())[0] + derivative_market = list(basic_composer.derivative_markets.values())[0] + binary_options_market = list(basic_composer.binary_option_markets.values())[0] + + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + spot_market_id = spot_market.id + derivative_market_id = derivative_market.id + binary_options_market_id = binary_options_market.id + spot_order_to_cancel = basic_composer.order_data( + market_id=spot_market_id, + subaccount_id=subaccount_id, + order_hash="0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000", + ) + derivative_order_to_cancel = basic_composer.order_data( + market_id=derivative_market_id, + subaccount_id=subaccount_id, + order_hash="0x222daa22f60fe9f075ed0ca583459e121c23e64431c3fbffdedda04598ede0d2", + ) + binary_options_order_to_cancel = basic_composer.order_data( + market_id=binary_options_market_id, + subaccount_id=subaccount_id, + order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", + ) + spot_order_to_create = basic_composer.spot_order( + market_id=spot_market_id, + subaccount_id=subaccount_id, + fee_recipient="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", + price=Decimal("36.1"), + quantity=Decimal("100"), + order_type="BUY", + cid="test_cid", + trigger_price=Decimal("43.5"), + ) + derivative_order_to_create = basic_composer.derivative_order( + market_id=derivative_market_id, + subaccount_id=subaccount_id, + fee_recipient="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", + price=Decimal("36.1"), + quantity=Decimal("100"), + margin=Decimal("36.1") * Decimal("100"), + order_type="BUY", + ) + binary_options_order_to_create = basic_composer.binary_options_order( + market_id=binary_options_market_id, + subaccount_id=subaccount_id, + fee_recipient="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", + price=Decimal("36.1"), + quantity=Decimal("100"), + margin=Decimal("36.1") * Decimal("100"), + order_type="BUY", + ) + + message = basic_composer.msg_batch_update_orders( + sender=sender, + subaccount_id=subaccount_id, + spot_market_ids_to_cancel_all=[spot_market_id], + derivative_market_ids_to_cancel_all=[derivative_market_id], + spot_orders_to_cancel=[spot_order_to_cancel], + derivative_orders_to_cancel=[derivative_order_to_cancel], + spot_orders_to_create=[spot_order_to_create], + derivative_orders_to_create=[derivative_order_to_create], + binary_options_orders_to_cancel=[binary_options_order_to_cancel], + binary_options_market_ids_to_cancel_all=[binary_options_market_id], + binary_options_orders_to_create=[binary_options_order_to_create], + ) + + expected_message = { + "sender": sender, + "subaccountId": subaccount_id, + "spotMarketIdsToCancelAll": [spot_market_id], + "derivativeMarketIdsToCancelAll": [derivative_market_id], + "spotOrdersToCancel": [ + json_format.MessageToDict(message=spot_order_to_cancel, including_default_value_fields=True) + ], + "derivativeOrdersToCancel": [ + json_format.MessageToDict(message=derivative_order_to_cancel, including_default_value_fields=True) + ], + "spotOrdersToCreate": [ + json_format.MessageToDict(message=spot_order_to_create, including_default_value_fields=True) + ], + "derivativeOrdersToCreate": [ + json_format.MessageToDict(message=derivative_order_to_create, including_default_value_fields=True) + ], + "binaryOptionsOrdersToCancel": [ + json_format.MessageToDict(message=binary_options_order_to_cancel, including_default_value_fields=True) + ], + "binaryOptionsMarketIdsToCancelAll": [binary_options_market_id], + "binaryOptionsOrdersToCreate": [ + json_format.MessageToDict(message=binary_options_order_to_create, including_default_value_fields=True) + ], + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_privileged_execute_contract(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + contract_address = "inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7" + data = "test_data" + funds = "100inj,420peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7" + + message = basic_composer.msg_privileged_execute_contract( + sender=sender, + contract_address=contract_address, + data=data, + funds=funds, + ) + + expected_message = { + "sender": sender, + "funds": funds, + "contractAddress": contract_address, + "data": data, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_create_derivative_limit_order(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + margin = price * quantity + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_derivative_limit_order( + market_id=derivative_market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = derivative_market.price_to_chain_format(human_readable_value=price) + expected_quantity = derivative_market.quantity_to_chain_format(human_readable_value=quantity) + expected_margin = derivative_market.margin_to_chain_format(human_readable_value=margin) + expected_trigger_price = derivative_market.price_to_chain_format(human_readable_value=trigger_price) + + expected_message = { + "sender": sender, + "order": { + "marketId": derivative_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "margin": f"{expected_margin.normalize():f}", + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_batch_create_derivative_limit_orders(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + order = basic_composer.derivative_order( + market_id=derivative_market.id, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=price * quantity, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + message = basic_composer.msg_batch_create_derivative_limit_orders( + sender=sender, + orders=[order], + ) + + expected_message = { + "sender": sender, + "orders": [json_format.MessageToDict(message=order, including_default_value_fields=True)], + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_create_derivative_market_order(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + margin = price * quantity + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_derivative_market_order( + market_id=derivative_market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = derivative_market.price_to_chain_format(human_readable_value=price) + expected_quantity = derivative_market.quantity_to_chain_format(human_readable_value=quantity) + expected_margin = derivative_market.margin_to_chain_format(human_readable_value=margin) + expected_trigger_price = derivative_market.price_to_chain_format(human_readable_value=trigger_price) + + expected_message = { + "sender": sender, + "order": { + "marketId": derivative_market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "margin": f"{expected_margin.normalize():f}", + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_cancel_derivative_order(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + order_hash = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + cid = "test_cid" + is_conditional = False + is_buy = True + is_market_order = False + + expected_order_mask = basic_composer._order_mask( + is_conditional=is_conditional, + is_buy=is_buy, + is_market_order=is_market_order, + ) + + message = basic_composer.msg_cancel_derivative_order( + market_id=derivative_market.id, + sender=sender, + subaccount_id=subaccount_id, + order_hash=order_hash, + cid=cid, + is_conditional=is_conditional, + is_buy=is_buy, + is_market_order=is_market_order, + ) + + expected_message = { + "sender": sender, + "marketId": derivative_market.id, + "subaccountId": subaccount_id, + "orderHash": order_hash, + "orderMask": expected_order_mask, + "cid": cid, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_batch_cancel_derivative_orders(self, basic_composer): + derivative_market = list(basic_composer.derivative_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + + order_data = basic_composer.order_data( + market_id=derivative_market.id, + subaccount_id=subaccount_id, + order_hash="0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000", + ) + + message = basic_composer.msg_batch_cancel_derivative_orders( + sender=sender, + orders_data=[order_data], + ) + + expected_message = { + "sender": sender, + "data": [json_format.MessageToDict(message=order_data, including_default_value_fields=True)], + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_instant_binary_options_market_launch(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + ticker = "B2500/INJ" + oracle_symbol = "B2500_1/INJ" + oracle_provider = "Injective" + oracle_scale_factor = 6 + oracle_type = "Band" + quote_denom = "INJ" + min_price_tick_size = Decimal("0.01") + min_quantity_tick_size = Decimal("1") + maker_fee_rate = Decimal("0.001") + taker_fee_rate = Decimal("-0.002") + expiration_timestamp = 1630000000 + settlement_timestamp = 1660000000 + admin = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + + quote_token = basic_composer.tokens[quote_denom] + + expected_min_price_tick_size = min_price_tick_size * Decimal( + f"1e{quote_token.decimals + ADDITIONAL_CHAIN_FORMAT_DECIMALS}" + ) + expected_min_quantity_tick_size = min_quantity_tick_size * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_maker_fee_rate = maker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + expected_taker_fee_rate = taker_fee_rate * Decimal(f"1e{ADDITIONAL_CHAIN_FORMAT_DECIMALS}") + + message = basic_composer.msg_instant_binary_options_market_launch( + sender=sender, + ticker=ticker, + oracle_symbol=oracle_symbol, + oracle_provider=oracle_provider, + oracle_type=oracle_type, + oracle_scale_factor=oracle_scale_factor, + maker_fee_rate=maker_fee_rate, + taker_fee_rate=taker_fee_rate, + expiration_timestamp=expiration_timestamp, + settlement_timestamp=settlement_timestamp, + admin=admin, + quote_denom=quote_denom, + min_price_tick_size=min_price_tick_size, + min_quantity_tick_size=min_quantity_tick_size, + ) + + expected_message = { + "sender": sender, + "ticker": ticker, + "oracleSymbol": oracle_symbol, + "oracleProvider": oracle_provider, + "oracleType": oracle_type, + "oracleScaleFactor": oracle_scale_factor, + "makerFeeRate": f"{expected_maker_fee_rate.normalize():f}", + "takerFeeRate": f"{expected_taker_fee_rate.normalize():f}", + "expirationTimestamp": str(expiration_timestamp), + "settlementTimestamp": str(settlement_timestamp), + "admin": admin, + "quoteDenom": quote_token.denom, + "minPriceTickSize": f"{expected_min_price_tick_size.normalize():f}", + "minQuantityTickSize": f"{expected_min_quantity_tick_size.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_create_binary_options_limit_order(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + margin = price * quantity + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_binary_options_limit_order( + market_id=market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = market.price_to_chain_format(human_readable_value=price) + expected_quantity = market.quantity_to_chain_format(human_readable_value=quantity) + expected_margin = market.margin_to_chain_format(human_readable_value=margin) + expected_trigger_price = market.price_to_chain_format(human_readable_value=trigger_price) + + expected_message = { + "sender": sender, + "order": { + "marketId": market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "margin": f"{expected_margin.normalize():f}", + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_create_binary_options_market_order(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + price = Decimal("36.1") + quantity = Decimal("100") + margin = price * quantity + order_type = "BUY" + cid = "test_cid" + trigger_price = Decimal("43.5") + + message = basic_composer.msg_create_binary_options_market_order( + market_id=market.id, + sender=sender, + subaccount_id=subaccount_id, + fee_recipient=fee_recipient, + price=price, + quantity=quantity, + margin=margin, + order_type=order_type, + cid=cid, + trigger_price=trigger_price, + ) + + expected_price = market.price_to_chain_format(human_readable_value=price) + expected_quantity = market.quantity_to_chain_format(human_readable_value=quantity) + expected_margin = market.margin_to_chain_format(human_readable_value=margin) + expected_trigger_price = market.price_to_chain_format(human_readable_value=trigger_price) + + expected_message = { + "sender": sender, + "order": { + "marketId": market.id, + "orderInfo": { + "subaccountId": subaccount_id, + "feeRecipient": fee_recipient, + "price": f"{expected_price.normalize():f}", + "quantity": f"{expected_quantity.normalize():f}", + "cid": cid, + }, + "margin": f"{expected_margin.normalize():f}", + "orderType": order_type, + "triggerPrice": f"{expected_trigger_price.normalize():f}", + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_cancel_derivative_order(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + order_hash = "0x5e249f0e8cb406f41de16e1bd6f6b55e7bc75add000000000000000000000000" + cid = "test_cid" + is_conditional = False + is_buy = True + is_market_order = False + + expected_order_mask = basic_composer._order_mask( + is_conditional=is_conditional, + is_buy=is_buy, + is_market_order=is_market_order, + ) + + message = basic_composer.msg_cancel_derivative_order( + market_id=market.id, + sender=sender, + subaccount_id=subaccount_id, + order_hash=order_hash, + cid=cid, + is_conditional=is_conditional, + is_buy=is_buy, + is_market_order=is_market_order, + ) + + expected_message = { + "sender": sender, + "marketId": market.id, + "subaccountId": subaccount_id, + "orderHash": order_hash, + "orderMask": expected_order_mask, + "cid": cid, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_subaccount_transfer(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + source_subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + destination_subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000002" + amount = Decimal(100) + denom = "INJ" + + token = basic_composer.tokens[denom] + + expected_amount = token.chain_formatted_value(human_readable_value=amount) + + message = basic_composer.msg_subaccount_transfer( + sender=sender, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + amount=amount, + denom=denom, + ) + + expected_message = { + "sender": sender, + "sourceSubaccountId": source_subaccount_id, + "destinationSubaccountId": destination_subaccount_id, + "amount": { + "amount": f"{expected_amount.normalize():f}", + "denom": token.denom, + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_external_transfer(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + source_subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + destination_subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" + amount = Decimal(100) + denom = "INJ" + + token = basic_composer.tokens[denom] + + expected_amount = token.chain_formatted_value(human_readable_value=amount) + + message = basic_composer.msg_subaccount_transfer( + sender=sender, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + amount=amount, + denom=denom, + ) + + expected_message = { + "sender": sender, + "sourceSubaccountId": source_subaccount_id, + "destinationSubaccountId": destination_subaccount_id, + "amount": { + "amount": f"{expected_amount.normalize():f}", + "denom": token.denom, + }, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_liquidate_position(self, basic_composer): + market = list(basic_composer.derivative_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + order = basic_composer.derivative_order( + market_id=market.id, + subaccount_id=subaccount_id, + fee_recipient="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", + price=Decimal("36.1"), + quantity=Decimal("100"), + margin=Decimal("36.1") * Decimal("100"), + order_type="BUY", + ) + + message = basic_composer.msg_liquidate_position( + sender=sender, + subaccount_id=subaccount_id, + market_id=market.id, + order=order, + ) + + expected_message = { + "sender": sender, + "subaccountId": subaccount_id, + "marketId": market.id, + "order": json_format.MessageToDict(message=order, including_default_value_fields=True), + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_emergency_settle_market(self, basic_composer): + market = list(basic_composer.derivative_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + + message = basic_composer.msg_emergency_settle_market( + sender=sender, + subaccount_id=subaccount_id, + market_id=market.id, + ) + + expected_message = { + "sender": sender, + "subaccountId": subaccount_id, + "marketId": market.id, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_external_transfer(self, basic_composer): + market = list(basic_composer.derivative_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + source_subaccount_id = "0x893f2abf8034627e50cbc63923120b1122503ce0000000000000000000000001" + destination_subaccount_id = "0xc6fe5d33615a1c52c08018c47e8bc53646a0e101000000000000000000000000" + amount = Decimal(100) + + expected_amount = market.margin_to_chain_format(human_readable_value=amount) + + message = basic_composer.msg_increase_position_margin( + sender=sender, + source_subaccount_id=source_subaccount_id, + destination_subaccount_id=destination_subaccount_id, + market_id=market.id, + amount=amount, + ) + + expected_message = { + "sender": sender, + "sourceSubaccountId": source_subaccount_id, + "destinationSubaccountId": destination_subaccount_id, + "marketId": market.id, + "amount": f"{expected_amount.normalize():f}", + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_rewards_opt_out(self, basic_composer): + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + + message = basic_composer.msg_rewards_opt_out( + sender=sender, + ) + + expected_message = { + "sender": sender, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message + + def test_msg_admin_update_binary_options_market(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + sender = "inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0" + status = "Paused" + settlement_price = Decimal("100.5") + expiration_timestamp = 1630000000 + settlement_timestamp = 1660000000 + + expected_settlement_price = market.price_to_chain_format(human_readable_value=settlement_price) + + message = basic_composer.msg_admin_update_binary_options_market( + sender=sender, + market_id=market.id, + status=status, + settlement_price=settlement_price, + expiration_timestamp=expiration_timestamp, + settlement_timestamp=settlement_timestamp, + ) + + expected_message = { + "sender": sender, + "marketId": market.id, + "settlementPrice": f"{expected_settlement_price.normalize():f}", + "expirationTimestamp": str(expiration_timestamp), + "settlementTimestamp": str(settlement_timestamp), + "status": status, + } + dict_message = json_format.MessageToDict( + message=message, + including_default_value_fields=True, + ) + assert dict_message == expected_message diff --git a/tests/test_composer_deprecation_warnings.py b/tests/test_composer_deprecation_warnings.py new file mode 100644 index 00000000..20a86779 --- /dev/null +++ b/tests/test_composer_deprecation_warnings.py @@ -0,0 +1,522 @@ +import warnings +from decimal import Decimal + +import pytest + +from pyinjective.composer import Composer +from pyinjective.core.network import Network +from tests.model_fixtures.markets_fixtures import btc_usdt_perp_market # noqa: F401 +from tests.model_fixtures.markets_fixtures import first_match_bet_market # noqa: F401 +from tests.model_fixtures.markets_fixtures import inj_token # noqa: F401 +from tests.model_fixtures.markets_fixtures import inj_usdt_spot_market # noqa: F401 +from tests.model_fixtures.markets_fixtures import usdt_perp_token # noqa: F401 +from tests.model_fixtures.markets_fixtures import usdt_token # noqa: F401 + + +class TestComposerDeprecationWarnings: + @pytest.fixture + def basic_composer(self, inj_usdt_spot_market, btc_usdt_perp_market, first_match_bet_market): + composer = Composer( + network=Network.devnet().string(), + spot_markets={inj_usdt_spot_market.id: inj_usdt_spot_market}, + derivative_markets={btc_usdt_perp_market.id: btc_usdt_perp_market}, + binary_option_markets={first_match_bet_market.id: first_match_bet_market}, + tokens={ + inj_usdt_spot_market.base_token.symbol: inj_usdt_spot_market.base_token, + inj_usdt_spot_market.quote_token.symbol: inj_usdt_spot_market.quote_token, + btc_usdt_perp_market.quote_token.symbol: btc_usdt_perp_market.quote_token, + }, + ) + + return composer + + def test_msg_deposit_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgDeposit(sender="sender", subaccount_id="subaccount id", amount=1, denom="INJ") + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_deposit instead" + + def test_msg_withdraw_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgWithdraw(sender="sender", subaccount_id="subaccount id", amount=1, denom="USDT") + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_withdraw instead" + + def teste_order_data_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.OrderData( + market_id="market id", + subaccount_id="subaccount id", + order_hash="order hash", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use order_data instead" + + def test_spot_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.SpotOrder( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + is_buy=True, + cid="cid", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use spot_order instead" + + def test_derivative_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.DerivativeOrder( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + is_buy=True, + cid="cid", + leverage=1, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use derivative_order instead" + + def test_msg_create_spot_limit_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCreateSpotLimitOrder( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + cid="cid", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_create_spot_limit_order instead" + ) + + def test_msg_batch_create_spot_limit_orders_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + order = composer.spot_order( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=Decimal(1), + quantity=Decimal(1), + order_type="BUY", + ) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgBatchCreateSpotLimitOrders( + sender="sender", + orders=[order], + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_batch_create_spot_limit_orders instead" + ) + + def test_msg_create_spot_market_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCreateSpotMarketOrder( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + is_buy=True, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_create_spot_market_order instead" + ) + + def test_msg_cancel_spot_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCancelSpotOrder( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + sender="sender", + subaccount_id="subaccount id", + order_hash="order hash", + cid="cid", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_cancel_spot_order instead" + + def test_msg_batch_cancel_spot_orders_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + orders = [ + composer.order_data( + market_id="0xa508cb32923323679f29a032c70342c147c17d0145625922b0ef22e955c844c0", + subaccount_id="subaccount_id", + order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", + ), + ] + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgBatchCancelSpotOrders(sender="sender", data=orders) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_batch_cancel_spot_orders instead" + ) + + def test_msg_batch_update_orders_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgBatchUpdateOrders(sender="sender") + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_batch_update_orders instead" + + def test_msg_privileged_execute_contract_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgPrivilegedExecuteContract( + sender="sender", + contract="contract", + msg="msg", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_privileged_execute_contract instead" + ) + + def test_msg_create_derivative_limit_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCreateDerivativeLimitOrder( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + cid="cid", + leverage=1, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_create_derivative_limit_order instead" + ) + + def test_msg_batch_create_derivative_limit_orders_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + order = composer.derivative_order( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=Decimal(1), + quantity=Decimal(1), + margin=Decimal(1), + order_type="BUY", + ) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgBatchCreateDerivativeLimitOrders( + sender="sender", + orders=[order], + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_batch_create_derivative_limit_orders instead" + ) + + def test_msg_create_derivative_market_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCreateDerivativeMarketOrder( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + cid="cid", + leverage=1, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_create_derivative_market_order instead" + ) + + def test_msg_cancel_derivative_order_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgCancelDerivativeOrder( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + sender="sender", + subaccount_id="subaccount id", + order_hash="order hash", + cid="cid", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_cancel_derivative_order instead" + ) + + def test_msg_batch_cancel_derivative_orders_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + orders = [ + composer.order_data( + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + subaccount_id="subaccount_id", + order_hash="0x3870fbdd91f07d54425147b1bb96404f4f043ba6335b422a6d494d285b387f2d", + ), + ] + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgBatchCancelDerivativeOrders(sender="sender", data=orders) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_batch_cancel_derivative_orders instead" + ) + + def test_msg_instant_binary_options_market_launch_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgInstantBinaryOptionsMarketLaunch( + sender="sender", + ticker="B2400/INJ", + oracle_symbol="B2400/INJ", + oracle_provider="injective", + oracle_type="Band", + oracle_scale_factor=6, + maker_fee_rate=0.001, + taker_fee_rate=0.001, + expiration_timestamp=1630000000, + settlement_timestamp=1630000000, + quote_denom="inj", + quote_decimals=18, + min_price_tick_size=0.01, + min_quantity_tick_size=0.01, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_instant_binary_options_market_launch instead" + ) + + def test_msg_create_binary_options_limit_order_deprecation_warning(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + + with warnings.catch_warnings(record=True) as all_warnings: + basic_composer.MsgCreateBinaryOptionsLimitOrder( + market_id=market.id, + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + cid="cid", + is_buy=True, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_create_binary_options_limit_order instead" + ) + + def test_msg_create_binary_options_market_order_deprecation_warning(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + + with warnings.catch_warnings(record=True) as all_warnings: + basic_composer.MsgCreateBinaryOptionsMarketOrder( + market_id=market.id, + sender="sender", + subaccount_id="subaccount id", + fee_recipient="fee recipient", + price=1, + quantity=1, + cid="cid", + is_buy=True, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_create_binary_options_market_order instead" + ) + + def test_msg_cancel_binary_options_order_deprecation_warning(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + + with warnings.catch_warnings(record=True) as all_warnings: + basic_composer.MsgCancelBinaryOptionsOrder( + market_id=market.id, + sender="sender", + subaccount_id="subaccount id", + order_hash="order hash", + cid="cid", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_cancel_binary_options_order instead" + ) + + def test_msg_subaccount_transfer_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgSubaccountTransfer( + sender="sender", + source_subaccount_id="source subaccount id", + destination_subaccount_id="destination subaccount id", + amount=1, + denom="INJ", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_subaccount_transfer instead" + + def test_msg_external_transfer_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgExternalTransfer( + sender="sender", + source_subaccount_id="source subaccount id", + destination_subaccount_id="destination subaccount id", + amount=1, + denom="INJ", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_external_transfer instead" + + def test_msg_liquidate_position_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgLiquidatePosition( + sender="sender", + subaccount_id="subaccount id", + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_liquidate_position instead" + + def test_msg_increase_position_margin_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgIncreasePositionMargin( + sender="sender", + source_subaccount_id="source_subaccount id", + destination_subaccount_id="destination_subaccount id", + market_id="0x7cc8b10d7deb61e744ef83bdec2bbcf4a056867e89b062c6a453020ca82bd4e4", + amount=1, + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_increase_position_margin instead" + ) + + def test_msg_rewards_opt_out_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgRewardsOptOut( + sender="sender", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_rewards_opt_out instead" + + def test_msg_admin_update_binary_options_market_deprecation_warning(self, basic_composer): + market = list(basic_composer.binary_option_markets.values())[0] + + with warnings.catch_warnings(record=True) as all_warnings: + basic_composer.MsgAdminUpdateBinaryOptionsMarket( + sender="sender", + market_id=market.id, + status="Paused", + ) + + deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)] + assert len(deprecation_warnings) == 1 + assert ( + str(deprecation_warnings[0].message) + == "This method is deprecated. Use msg_admin_update_binary_options_market instead" + ) diff --git a/tests/test_orderhash.py b/tests/test_orderhash.py index c57b6305..c2940d8d 100644 --- a/tests/test_orderhash.py +++ b/tests/test_orderhash.py @@ -1,3 +1,5 @@ +from decimal import Decimal + from pyinjective import PrivateKey from pyinjective.composer import Composer from pyinjective.core.network import Network @@ -22,23 +24,21 @@ def test_spot_order_hash(self, requests_mock): fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r" spot_orders = [ - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=0.524, - quantity=0.01, - is_buy=True, - is_po=False, + price=Decimal("0.524"), + quantity=Decimal("0.01"), + order_type="BUY", ), - composer.SpotOrder( + composer.spot_order( market_id=spot_market_id, subaccount_id=subaccount_id, fee_recipient=fee_recipient, - price=27.92, - quantity=0.01, - is_buy=False, - is_po=False, + price=Decimal("27.92"), + quantity=Decimal("0.01"), + order_type="SELL", ), ]