diff --git a/CHANGELOG.md b/CHANGELOG.md index 876c5845..34ec054b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project will be documented in this file. +## [1.5.0] - 9999-99-99 +### Added +- Added support for all queries in the chain 'tendermint' module + +## [1.4.1] - 2024-03-12 +### Changed +- Updates example scripts that were still using deprecated methods + ## [1.4.0] - 2024-03-11 ### Added - Added support for all queries and messages in the chain 'distribution' module diff --git a/examples/chain_client/3_MessageBroadcaster.py b/examples/chain_client/3_MessageBroadcaster.py index 6bd67033..735b92e3 100644 --- a/examples/chain_client/3_MessageBroadcaster.py +++ b/examples/chain_client/3_MessageBroadcaster.py @@ -56,7 +56,7 @@ async def main() -> None: ] # prepare tx msg - msg = composer.MsgBatchUpdateOrders( + msg = composer.msg_batch_update_orders( sender=address.to_acc_bech32(), spot_orders_to_create=spot_orders_to_create, ) diff --git a/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py b/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py index 54a79bf8..8c4f685f 100644 --- a/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py +++ b/examples/chain_client/5_MessageBroadcasterWithoutSimulation.py @@ -56,7 +56,7 @@ async def main() -> None: ] # prepare tx msg - msg = composer.MsgBatchUpdateOrders( + msg = composer.msg_batch_update_orders( sender=address.to_acc_bech32(), spot_orders_to_create=spot_orders_to_create, ) diff --git a/examples/chain_client/exchange/8_MsgCancelSpotOrder.py b/examples/chain_client/exchange/8_MsgCancelSpotOrder.py index 970b2190..4bcedda8 100644 --- a/examples/chain_client/exchange/8_MsgCancelSpotOrder.py +++ b/examples/chain_client/exchange/8_MsgCancelSpotOrder.py @@ -35,7 +35,7 @@ async def main() -> None: order_hash = "0x52888d397d5ae821869c8acde5823dfd8018802d2ef642d3aa639e5308173fcf" # prepare tx msg - msg = composer.MsgCancelSpotOrder( + msg = composer.msg_cancel_spot_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/9_MsgBatchUpdateOrders.py b/examples/chain_client/exchange/9_MsgBatchUpdateOrders.py index 04e41058..ac490216 100644 --- a/examples/chain_client/exchange/9_MsgBatchUpdateOrders.py +++ b/examples/chain_client/exchange/9_MsgBatchUpdateOrders.py @@ -118,7 +118,7 @@ async def main() -> None: ] # prepare tx msg - msg = composer.MsgBatchUpdateOrders( + msg = composer.msg_batch_update_orders( sender=address.to_acc_bech32(), derivative_orders_to_create=derivative_orders_to_create, spot_orders_to_create=spot_orders_to_create, diff --git a/examples/chain_client/tendermint/query/1_GetNodeInfo.py b/examples/chain_client/tendermint/query/1_GetNodeInfo.py new file mode 100644 index 00000000..9e116e80 --- /dev/null +++ b/examples/chain_client/tendermint/query/1_GetNodeInfo.py @@ -0,0 +1,16 @@ +import asyncio + +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + node_info = await client.fetch_node_info() + print(node_info) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/tendermint/query/2_GetSyncing.py b/examples/chain_client/tendermint/query/2_GetSyncing.py new file mode 100644 index 00000000..29a8b5b7 --- /dev/null +++ b/examples/chain_client/tendermint/query/2_GetSyncing.py @@ -0,0 +1,16 @@ +import asyncio + +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + syncing = await client.fetch_syncing() + print(syncing) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/tendermint/query/3_GetLatestBlock.py b/examples/chain_client/tendermint/query/3_GetLatestBlock.py new file mode 100644 index 00000000..a30748e5 --- /dev/null +++ b/examples/chain_client/tendermint/query/3_GetLatestBlock.py @@ -0,0 +1,16 @@ +import asyncio + +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + latest_block = await client.fetch_latest_block() + print(latest_block) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/tendermint/query/4_GetBlockByHeight.py b/examples/chain_client/tendermint/query/4_GetBlockByHeight.py new file mode 100644 index 00000000..fdab714b --- /dev/null +++ b/examples/chain_client/tendermint/query/4_GetBlockByHeight.py @@ -0,0 +1,16 @@ +import asyncio + +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + block = await client.fetch_block_by_height(height=15793860) + print(block) + + +if __name__ == "__main__": + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/tendermint/query/5_GetLatestValidatorSet.py b/examples/chain_client/tendermint/query/5_GetLatestValidatorSet.py new file mode 100644 index 00000000..204cd06f --- /dev/null +++ b/examples/chain_client/tendermint/query/5_GetLatestValidatorSet.py @@ -0,0 +1,19 @@ +import asyncio + +from google.protobuf import symbol_database + +from pyinjective.async_client import AsyncClient +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + validator_set = await client.fetch_latest_validator_set() + print(validator_set) + + +if __name__ == "__main__": + symbol_db = symbol_database.Default() + asyncio.get_event_loop().run_until_complete(main()) diff --git a/examples/chain_client/tendermint/query/6_GetValidatorSetByHeight.py b/examples/chain_client/tendermint/query/6_GetValidatorSetByHeight.py new file mode 100644 index 00000000..118ec2b3 --- /dev/null +++ b/examples/chain_client/tendermint/query/6_GetValidatorSetByHeight.py @@ -0,0 +1,22 @@ +import asyncio + +from google.protobuf import symbol_database + +from pyinjective.async_client import AsyncClient +from pyinjective.client.model.pagination import PaginationOption +from pyinjective.core.network import Network + + +async def main() -> None: + network = Network.testnet() + client = AsyncClient(network) + + pagination = PaginationOption(skip=2, limit=4) + + validator_set = await client.fetch_validator_set_by_height(height=23040174, pagination=pagination) + print(validator_set) + + +if __name__ == "__main__": + symbol_db = symbol_database.Default() + asyncio.get_event_loop().run_until_complete(main()) diff --git a/pyinjective/async_client.py b/pyinjective/async_client.py index d684a234..86c74833 100644 --- a/pyinjective/async_client.py +++ b/pyinjective/async_client.py @@ -39,6 +39,7 @@ from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket from pyinjective.core.network import Network from pyinjective.core.token import Token +from pyinjective.core.tx.grpc.tendermint_grpc_api import TendermintGrpcApi from pyinjective.core.tx.grpc.tx_grpc_api import TxGrpcApi from pyinjective.exceptions import NotFoundError from pyinjective.proto.cosmos.auth.v1beta1 import query_pb2 as auth_query, query_pb2_grpc as auth_query_grpc @@ -49,6 +50,7 @@ query_pb2 as tendermint_query, query_pb2_grpc as tendermint_query_grpc, ) +from pyinjective.proto.cosmos.crypto.ed25519 import keys_pb2 as ed25519_keys # noqa: F401 for validator set responses from pyinjective.proto.cosmos.tx.v1beta1 import service_pb2 as tx_service, service_pb2_grpc as tx_service_grpc from pyinjective.proto.exchange import ( injective_accounts_rpc_pb2 as exchange_accounts_rpc_pb, @@ -192,6 +194,12 @@ def __init__( metadata_query_provider=self._chain_cookie_metadata_requestor ), ) + self.tendermint_api = TendermintGrpcApi( + channel=self.chain_channel, + metadata_provider=lambda: self.network.chain_metadata( + metadata_query_provider=self._chain_cookie_metadata_requestor + ), + ) self.token_factory_api = ChainGrpcTokenFactoryApi( channel=self.chain_channel, metadata_provider=lambda: self.network.chain_metadata( @@ -379,8 +387,8 @@ async def close_chain_channel(self): async def sync_timeout_height(self): try: - block = await self.get_latest_block() - self.timeout_height = block.block.header.height + DEFAULT_TIMEOUTHEIGHT + block = await self.fetch_latest_block() + self.timeout_height = int(block["block"]["header"]["height"]) + DEFAULT_TIMEOUTHEIGHT except Exception as e: LoggerProvider().logger_for_class(logging_class=self.__class__).debug( f"error while fetching latest block, setting timeout height to 0: {e}" @@ -388,9 +396,6 @@ async def sync_timeout_height(self): self.timeout_height = 0 # default client methods - async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse: - req = tendermint_query.GetLatestBlockRequest() - return await self.stubCosmosTendermint.GetLatestBlock(req) async def get_account(self, address: str) -> Optional[account_pb2.EthAccount]: """ @@ -500,8 +505,8 @@ async def send_tx_block_mode(self, tx_byte: bytes) -> abci_type.TxResponse: return result.tx_response async def get_chain_id(self) -> str: - latest_block = await self.get_latest_block() - return latest_block.block.header.chain_id + latest_block = await self.fetch_latest_block() + return latest_block["block"]["header"]["chainId"] async def get_grants(self, granter: str, grantee: str, **kwargs): """ @@ -1225,6 +1230,44 @@ async def fetch_denoms_from_creator( async def fetch_tokenfactory_module_state(self) -> Dict[str, Any]: return await self.token_factory_api.fetch_tokenfactory_module_state() + # ------------------------------ + # region Tendermint module + async def fetch_node_info(self) -> Dict[str, Any]: + return await self.tendermint_api.fetch_node_info() + + async def fetch_syncing(self) -> Dict[str, Any]: + return await self.tendermint_api.fetch_syncing() + + async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse: + """ + This method is deprecated and will be removed soon. Please use `fetch_latest_block` instead + """ + warn("This method is deprecated. Use fetch_latest_block instead", DeprecationWarning, stacklevel=2) + req = tendermint_query.GetLatestBlockRequest() + return await self.stubCosmosTendermint.GetLatestBlock(req) + + async def fetch_latest_block(self) -> Dict[str, Any]: + return await self.tendermint_api.fetch_latest_block() + + async def fetch_block_by_height(self, height: int) -> Dict[str, Any]: + return await self.tendermint_api.fetch_block_by_height(height=height) + + async def fetch_latest_validator_set(self) -> Dict[str, Any]: + return await self.tendermint_api.fetch_latest_validator_set() + + async def fetch_validator_set_by_height( + self, height: int, pagination: Optional[PaginationOption] = None + ) -> Dict[str, Any]: + return await self.tendermint_api.fetch_validator_set_by_height(height=height, pagination=pagination) + + async def abci_query( + self, path: str, data: Optional[bytes] = None, height: Optional[int] = None, prove: bool = False + ) -> Dict[str, Any]: + return await self.tendermint_api.abci_query(path=path, data=data, height=height, prove=prove) + + # endregion + + # ------------------------------ # Explorer RPC async def get_tx_by_hash(self, tx_hash: str): diff --git a/pyinjective/core/tx/grpc/tendermint_grpc_api.py b/pyinjective/core/tx/grpc/tendermint_grpc_api.py new file mode 100644 index 00000000..c6e091c6 --- /dev/null +++ b/pyinjective/core/tx/grpc/tendermint_grpc_api.py @@ -0,0 +1,69 @@ +from typing import Any, Callable, Dict, Optional + +from grpc.aio import Channel + +from pyinjective.client.model.pagination import PaginationOption +from pyinjective.proto.cosmos.base.tendermint.v1beta1 import ( + query_pb2 as tendermint_query, + query_pb2_grpc as tendermint_query_grpc, +) +from pyinjective.utils.grpc_api_request_assistant import GrpcApiRequestAssistant + + +class TendermintGrpcApi: + def __init__(self, channel: Channel, metadata_provider: Callable): + self._stub = tendermint_query_grpc.ServiceStub(channel) + self._assistant = GrpcApiRequestAssistant(metadata_provider=metadata_provider) + + async def fetch_node_info(self) -> Dict[str, Any]: + request = tendermint_query.GetNodeInfoRequest() + response = await self._execute_call(call=self._stub.GetNodeInfo, request=request) + + return response + + async def fetch_syncing(self) -> Dict[str, Any]: + request = tendermint_query.GetSyncingRequest() + response = await self._execute_call(call=self._stub.GetSyncing, request=request) + + return response + + async def fetch_latest_block(self) -> Dict[str, Any]: + request = tendermint_query.GetLatestBlockRequest() + response = await self._execute_call(call=self._stub.GetLatestBlock, request=request) + + return response + + async def fetch_block_by_height(self, height: int) -> Dict[str, Any]: + request = tendermint_query.GetBlockByHeightRequest(height=height) + response = await self._execute_call(call=self._stub.GetBlockByHeight, request=request) + + return response + + async def fetch_latest_validator_set(self) -> Dict[str, Any]: + request = tendermint_query.GetLatestValidatorSetRequest() + response = await self._execute_call(call=self._stub.GetLatestValidatorSet, request=request) + + return response + + async def fetch_validator_set_by_height( + self, height: int, pagination: Optional[PaginationOption] = None + ) -> Dict[str, Any]: + if pagination is None: + pagination = PaginationOption() + request = tendermint_query.GetValidatorSetByHeightRequest( + height=height, pagination=pagination.create_pagination_request() + ) + response = await self._execute_call(call=self._stub.GetValidatorSetByHeight, request=request) + + return response + + async def abci_query( + self, path: str, data: Optional[bytes] = None, height: Optional[int] = None, prove: bool = False + ) -> Dict[str, Any]: + request = tendermint_query.ABCIQueryRequest(path=path, data=data, height=height, prove=prove) + response = await self._execute_call(call=self._stub.ABCIQuery, request=request) + + return response + + async def _execute_call(self, call: Callable, request) -> Dict[str, Any]: + return await self._assistant.execute_call(call=call, request=request) diff --git a/pyinjective/denoms_devnet.ini b/pyinjective/denoms_devnet.ini index 3c422179..2b6020db 100644 --- a/pyinjective/denoms_devnet.ini +++ b/pyinjective/denoms_devnet.ini @@ -164,10 +164,10 @@ min_display_quantity_tick_size = 0.00001 description = 'Devnet Spot PROJ/INJ' base = 18 quote = 18 -min_price_tick_size = 0.001 -min_display_price_tick_size = 0.001 -min_quantity_tick_size = 10000000000000 -min_display_quantity_tick_size = 0.00001 +min_price_tick_size = 0.00000001 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 1000000000000000000000 +min_display_quantity_tick_size = 1000 [0x2d3b8d8833dda54a717adea9119134556848105fd6028e9a4a526e4e5a122a57] description = 'Devnet Spot KIRA/INJ' @@ -178,6 +178,24 @@ min_display_price_tick_size = 0.00000001 min_quantity_tick_size = 1000000000 min_display_quantity_tick_size = 1000 +[0x42edf70cc37e155e9b9f178e04e18999bc8c404bd7b638cc4cbf41da8ef45a21] +description = 'Devnet Spot QUNT/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 1000000000 +min_display_quantity_tick_size = 1000 + +[0xc8fafa1fcab27e16da20e98b4dc9dda45320418c27db80663b21edac72f3b597] +description = 'Devnet Spot HDRO/INJ' +base = 6 +quote = 18 +min_price_tick_size = 1000000 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + [0x1422a13427d5eabd4d8de7907c8340f7e58cb15553a9fd4ad5c90406561886f9] description = 'Devnet Derivative COMP/USDT PERP' base = 0 @@ -296,6 +314,10 @@ decimals = 18 peggy_denom = peggy0xAaEf88cEa01475125522e117BFe45cF32044E238 decimals = 18 +[HDRO] +peggy_denom = factory/inj1etz0laas6h7vemg3qtd67jpr6lh8v7xz7gfzqw/hdro +decimals = 6 + [INJ] peggy_denom = inj decimals = 18 @@ -316,6 +338,10 @@ decimals = 18 peggy_denom = proj decimals = 18 +[QUNT] +peggy_denom = factory/inj127l5a2wmkyvucxdlupqyac3y0v6wqfhq03ka64/qunt +decimals = 6 + [SOMM] peggy_denom = ibc/34346A60A95EB030D62D6F5BDD4B745BE18E8A693372A8A347D5D53DBBB1328B decimals = 6 diff --git a/pyinjective/denoms_mainnet.ini b/pyinjective/denoms_mainnet.ini index 9d88ca6d..5f6611ef 100644 --- a/pyinjective/denoms_mainnet.ini +++ b/pyinjective/denoms_mainnet.ini @@ -682,6 +682,15 @@ min_display_price_tick_size = 0.000001 min_quantity_tick_size = 10000000000000000000 min_display_quantity_tick_size = 10 +[0xe6dd9895b169e2ca0087fcb8e8013805d06c3ed8ffc01ccaa31c710eef14a984] +description = 'Mainnet Spot DOJO/INJ' +base = 18 +quote = 18 +min_price_tick_size = 0.000001 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 10000000000000000000 +min_display_quantity_tick_size = 10 + [0x0a1366c8b05658c0ccca6064e4b20aacd5ad350c02debd6ec0f4dc9178145d14] description = 'Mainnet Spot GYEN/USDT' base = 6 @@ -700,6 +709,78 @@ min_display_price_tick_size = 0.0001 min_quantity_tick_size = 100000 min_display_quantity_tick_size = 0.1 +[0x9c42d763ba5135809ac4684b02082e9c880d69f6b96d258fe4c172396e9af7be] +description = 'Mainnet Spot ANDR/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000000 +min_display_price_tick_size = 0.00001 +min_quantity_tick_size = 100000 +min_display_quantity_tick_size = 0.1 + +[0x1b1e062b3306f26ae3af3c354a10c1cf38b00dcb42917f038ba3fc14978b1dd8] +description = 'Mainnet Spot hINJ/INJ' +base = 18 +quote = 18 +min_price_tick_size = 0.0001 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1000000000000000 +min_display_quantity_tick_size = 0.001 + +[0x959c9401a557ac090fff3ec11db5a1a9832e51a97a41b722d2496bb3cb0b2f72] +description = 'Mainnet Spot ANDR/INJ' +base = 6 +quote = 6 +min_price_tick_size = 0.0001 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + +[0x697457537bc2af5ff652bc0616fe23537437a570d0e4d91566f03af279e095d5] +description = 'Mainnet Spot PHUC/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 1000000000 +min_display_quantity_tick_size = 1000 + +[0x42edf70cc37e155e9b9f178e04e18999bc8c404bd7b638cc4cbf41da8ef45a21] +description = 'Mainnet Spot QUNT/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 1000000000 +min_display_quantity_tick_size = 1000 + +[0x586409ac5f6d6e90a81d2585b9a8e76de0b4898d5f2c047d0bc025a036489ba1] +description = 'Mainnet Spot WHALE/INJ' +base = 6 +quote = 18 +min_price_tick_size = 1000000 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + +[0xc8fafa1fcab27e16da20e98b4dc9dda45320418c27db80663b21edac72f3b597] +description = 'Mainnet Spot HDRO/INJ' +base = 6 +quote = 18 +min_price_tick_size = 1000000 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + +[0xb965ebede42e67af153929339040e650d5c2af26d6aa43382c110d943c627b0a] +description = 'Mainnet Spot PYTH/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000000 +min_display_price_tick_size = 0.00001 +min_quantity_tick_size = 100000 +min_display_quantity_tick_size = 0.1 + [0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce] description = 'Mainnet Derivative BTC/USDT PERP' base = 0 @@ -772,6 +853,15 @@ min_display_price_tick_size = 0.01 min_quantity_tick_size = 0.001 min_display_quantity_tick_size = 0.001 +[0x3b7fb1d9351f7fa2e6e0e5a11b3639ee5e0486c33a6a74f629c3fc3c3043efd5] +description = 'Mainnet Derivative BONK/USDT PERP' +base = 0 +quote = 6 +min_price_tick_size = 0.01 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 10000 +min_display_quantity_tick_size = 10000 + [0xcd0c859a99f26bb3530e21890937ed77d20754aa7825a599c71710514fc125ef] description = 'Mainnet Derivative 1MPEPE/USDT PERP' base = 0 @@ -889,10 +979,41 @@ min_display_price_tick_size = 0.001 min_quantity_tick_size = 0.1 min_display_quantity_tick_size = 0.1 +[0xf1bc70398e9b469db459f3153433c6bd1253bd02377248ee29bd346a218e6243] +description = 'Mainnet Derivative W/USDT PERP' +base = 0 +quote = 6 +min_price_tick_size = 100 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1 +min_display_quantity_tick_size = 1 + +[0x03c8da1f6aaf8aca2be26b0f4d6b89d475835c7812a1dcdb19af7dec1c6b7f60] +description = 'Mainnet Derivative LINK/USDT PERP' +base = 0 +quote = 6 +min_price_tick_size = 10000 +min_display_price_tick_size = 0.01 +min_quantity_tick_size = 0.01 +min_display_quantity_tick_size = 0.01 + +[0x7980993e508e0efc1c2634c153a1ef90f517b74351d6406221c77c04ec4799fe] +description = 'Mainnet Derivative DOGE/USDT PERP' +base = 0 +quote = 6 +min_price_tick_size = 10 +min_display_price_tick_size = 0.00001 +min_quantity_tick_size = 10 +min_display_quantity_tick_size = 10 + [AAVE] peggy_denom = peggy0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9 decimals = 18 +[ANDR] +peggy_denom = ibc/61FA42C3F0B0F8768ED2CE380EDD3BE0E4CB7E67688F81F70DE9ECF5F8684E1E +decimals = 6 + [APE] peggy_denom = peggy0x4d224452801ACEd8B2F0aebE155379bb5D594381 decimals = 18 @@ -937,6 +1058,10 @@ decimals = 8 peggy_denom = ibc/3A6DD3358D9F7ADD18CDE79BA10B400511A5DE4AE2C037D7C9639B52ADAF35C6 decimals = 6 +[DOJO] +peggy_denom = factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj1zdj9kqnknztl2xclm5ssv25yre09f8908d4923 +decimals = 18 + [DOT] peggy_denom = ibc/624BA9DD171915A2B9EA70F69638B2CEA179959850C1A586F6C485498F29EDD4 decimals = 10 @@ -965,6 +1090,10 @@ decimals = 18 peggy_denom = peggy0xC08512927D12348F6620a698105e1BAac6EcD911 decimals = 6 +[HDRO] +peggy_denom = factory/inj1etz0laas6h7vemg3qtd67jpr6lh8v7xz7gfzqw/hdro +decimals = 6 + [HUAHUA] peggy_denom = ibc/E7807A46C0B7B44B350DA58F51F278881B863EC4DCA94635DAB39E52C30766CB decimals = 6 @@ -1021,6 +1150,10 @@ decimals = 6 peggy_denom = ibc/C20C0A822BD22B2CEF0D067400FCCFB6FAEEE9E91D360B4E0725BD522302D565 decimals = 6 +[PHUC] +peggy_denom = factory/inj1995xnrrtnmtdgjmx0g937vf28dwefhkhy6gy5e/phuc +decimals = 6 + [PUG] peggy_denom = peggy0xf9a06dE3F6639E6ee4F079095D5093644Ad85E8b decimals = 18 @@ -1033,6 +1166,10 @@ decimals = 6 peggy_denom = peggy0x4a220E6096B25EADb88358cb44068A3248254675 decimals = 18 +[QUNT] +peggy_denom = factory/inj127l5a2wmkyvucxdlupqyac3y0v6wqfhq03ka64/qunt +decimals = 6 + [SNOWY] peggy_denom = factory/inj1ml33x7lkxk6x2x95d3alw4h84evlcdz2gnehmk/SNOWY decimals = 6 @@ -1125,6 +1262,10 @@ decimals = 6 peggy_denom = peggy0xb2617246d0c6c0087f18703d576831899ca94f01 decimals = 18 +[hINJ] +peggy_denom = factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj18luqttqyckgpddndh8hvaq25d5nfwjc78m56lc +decimals = 18 + [nINJ] peggy_denom = factory/inj14ejqjyq8um4p3xfqj74yld5waqljf88f9eneuk/inj13xlpypcwl5fuc84uhqzzqumnrcfpptyl6w3vrf decimals = 18 diff --git a/pyinjective/denoms_testnet.ini b/pyinjective/denoms_testnet.ini index fd823592..e8b5aa61 100644 --- a/pyinjective/denoms_testnet.ini +++ b/pyinjective/denoms_testnet.ini @@ -142,6 +142,24 @@ min_display_price_tick_size = 0.001 min_quantity_tick_size = 10000000000000 min_display_quantity_tick_size = 0.00001 +[0x21d4ee074f37f2a310929425e58f69850fca9f734d292bfc5ee48d3c28ea1c09] +description = 'Testnet Spot TEST2/INJ' +base = 6 +quote = 18 +min_price_tick_size = 100000000 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1000 +min_display_quantity_tick_size = 0.001 + +[0xf2ced33ef12a73962be92686503450cc4966feeb9cf6c809f4dc43acad5d7efb] +description = 'Testnet Spot TEST2/USDT' +base = 6 +quote = 6 +min_price_tick_size = 0.0001 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1000 +min_display_quantity_tick_size = 0.001 + [0xf02752c2c87728af7fd10a298a8a645261859eafd0295dcda7e2c5b45c8412cf] description = 'Testnet Spot stINJ/INJ' base = 18 @@ -205,6 +223,60 @@ min_display_price_tick_size = 0.001 min_quantity_tick_size = 100000 min_display_quantity_tick_size = 0.001 +[0xe93f09f7a06d507ff8b66f2969e1af931c9eb9ec3f640a6f87dbcd3456258466] +description = 'Testnet Spot Inj' +base = 18 +quote = 8 +min_price_tick_size = 0.0000000000001 +min_display_price_tick_size = 0.001 +min_quantity_tick_size = 1000000000000000 +min_display_quantity_tick_size = 0.001 + +[0xed865fd44f1bc9d46d978db415ed00444fac4f6aef7e09e2d0235f8d140b219f] +description = 'Testnet Spot MT/INJ' +base = 6 +quote = 18 +min_price_tick_size = 10000 +min_display_price_tick_size = 0.00000001 +min_quantity_tick_size = 1000000000 +min_display_quantity_tick_size = 1000 + +[0x215970bfdea5c94d8e964a759d3ce6eae1d113900129cc8428267db5ccdb3d1a] +description = 'Testnet Spot INJ/USDC' +base = 18 +quote = 6 +min_price_tick_size = 0.000000000000001 +min_display_price_tick_size = 0.001 +min_quantity_tick_size = 10000000000000000 +min_display_quantity_tick_size = 0.01 + +[0xd8e9ea042ac67990134d8e024a251809b1b76c5f7df49f511858e040a285efca] +description = 'Testnet Spot HDRO/INJ' +base = 6 +quote = 18 +min_price_tick_size = 1000000 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + +[0x2d7f47811527bd721ce2e4e0ff27b0f3a281f65abcd41758baf157c8ddfcd910] +description = 'Testnet Spot hINJ/INJ' +base = 18 +quote = 18 +min_price_tick_size = 0.0001 +min_display_price_tick_size = 0.0001 +min_quantity_tick_size = 1000000000000000 +min_display_quantity_tick_size = 0.001 + +[0xe4b31c0112c89e0963b2db6884b416c17101a899e0ce6dc9f5dde79e6a01b52b] +description = 'Testnet Spot TEST1/INJ' +base = 6 +quote = 18 +min_price_tick_size = 1000000 +min_display_price_tick_size = 0.000001 +min_quantity_tick_size = 1000000 +min_display_quantity_tick_size = 1 + [0x2e94326a421c3f66c15a3b663c7b1ab7fb6a5298b3a57759ecf07f0036793fc9] description = 'Testnet Derivative BTC/USDT PERP Pyth' base = 0 @@ -393,10 +465,18 @@ decimals = 18 peggy_denom = factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/atom decimals = 8 +[HDRO] +peggy_denom = factory/inj1pk7jhvjj2lufcghmvr7gl49dzwkk3xj0uqkwfk/hdro +decimals = 6 + [INJ] peggy_denom = inj decimals = 18 +[MT] +peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/mitotest2 +decimals = 6 + [MitoTest1] peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/mitotest1 decimals = 18 @@ -409,6 +489,14 @@ decimals = 18 peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/projx decimals = 18 +[TEST1] +peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/test1 +decimals = 6 + +[TEST2] +peggy_denom = factory/inj1gvhyp8un5l9jpxpd90rdtj3ejd6qser2s2jxtz/test2 +decimals = 6 + [USD Coin] peggy_denom = factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/usdc decimals = 6 @@ -437,6 +525,10 @@ decimals = 18 peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/uzen decimals = 18 +[hINJ] +peggy_denom = factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj1mz7mfhgx8tuvjqut03qdujrkzwlx9xhcj6yldc +decimals = 18 + [stINJ] peggy_denom = factory/inj17gkuet8f6pssxd8nycm3qr9d9y699rupv6397z/stinj decimals = 18 diff --git a/pyproject.toml b/pyproject.toml index c983dd07..281d7c59 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "injective-py" -version = "1.4.0-pre" +version = "1.5.0-pre" description = "Injective Python SDK, with Exchange API Client" authors = ["Injective Labs "] license = "Apache-2.0" diff --git a/tests/core/test_gas_limit_estimator.py b/tests/core/test_gas_limit_estimator.py index 293f5f25..b4a5657c 100644 --- a/tests/core/test_gas_limit_estimator.py +++ b/tests/core/test_gas_limit_estimator.py @@ -157,7 +157,7 @@ def test_estimation_for_batch_update_orders_to_create_spot_orders(self): order_type="BUY", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=orders, @@ -194,7 +194,7 @@ def test_estimation_for_batch_update_orders_to_create_derivative_orders(self): order_type="SELL", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=orders, spot_orders_to_create=[], @@ -249,7 +249,7 @@ def test_estimation_for_batch_update_orders_to_create_binary_orders(self, usdt_t order_type="SELL", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=[], @@ -284,7 +284,7 @@ def test_estimation_for_batch_update_orders_to_cancel_spot_orders(self): order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=[], @@ -318,7 +318,7 @@ def test_estimation_for_batch_update_orders_to_cancel_derivative_orders(self): order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=[], @@ -352,7 +352,7 @@ def test_estimation_for_batch_update_orders_to_cancel_binary_orders(self): order_hash="0x7ee76255d7ca763c56b0eab9828fca89fdd3739645501c8a80f58b62b4f76da5", ), ] - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=[], @@ -371,7 +371,7 @@ def test_estimation_for_batch_update_orders_to_cancel_all_for_spot_market(self): market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", subaccount_id="subaccount_id", spot_market_ids_to_cancel_all=[market_id], @@ -391,7 +391,7 @@ def test_estimation_for_batch_update_orders_to_cancel_all_for_derivative_market( market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", subaccount_id="subaccount_id", derivative_market_ids_to_cancel_all=[market_id], @@ -411,7 +411,7 @@ def test_estimation_for_batch_update_orders_to_cancel_all_for_binary_options_mar market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe" composer = Composer(network="testnet") - message = composer.MsgBatchUpdateOrders( + message = composer.msg_batch_update_orders( sender="senders", subaccount_id="subaccount_id", binary_options_market_ids_to_cancel_all=[market_id], @@ -440,7 +440,7 @@ def test_estimation_for_exec_message(self): order_type="BUY", ), ] - inner_message = composer.MsgBatchUpdateOrders( + inner_message = composer.msg_batch_update_orders( sender="senders", derivative_orders_to_create=[], spot_orders_to_create=orders, diff --git a/tests/core/tx/grpc/configurable_tendermint_query_servicer.py b/tests/core/tx/grpc/configurable_tendermint_query_servicer.py new file mode 100644 index 00000000..004e3e47 --- /dev/null +++ b/tests/core/tx/grpc/configurable_tendermint_query_servicer.py @@ -0,0 +1,43 @@ +from collections import deque + +from pyinjective.proto.cosmos.base.tendermint.v1beta1 import ( + query_pb2 as tendermint_query, + query_pb2_grpc as tendermint_query_grpc, +) + + +class ConfigurableTendermintQueryServicer(tendermint_query_grpc.ServiceServicer): + def __init__(self): + super().__init__() + self.get_node_info_responses = deque() + self.get_syncing_responses = deque() + self.get_latest_block_responses = deque() + self.get_block_by_height_responses = deque() + self.get_latest_validator_set_responses = deque() + self.get_validator_set_by_height_responses = deque() + self.abci_query_responses = deque() + + async def GetNodeInfo(self, request: tendermint_query.GetNodeInfoRequest, context=None, metadata=None): + return self.get_node_info_responses.pop() + + async def GetSyncing(self, request: tendermint_query.GetSyncingRequest, context=None, metadata=None): + return self.get_syncing_responses.pop() + + async def GetLatestBlock(self, request: tendermint_query.GetLatestBlockRequest, context=None, metadata=None): + return self.get_latest_block_responses.pop() + + async def GetBlockByHeight(self, request: tendermint_query.GetBlockByHeightRequest, context=None, metadata=None): + return self.get_block_by_height_responses.pop() + + async def GetLatestValidatorSet( + self, request: tendermint_query.GetLatestValidatorSetRequest, context=None, metadata=None + ): + return self.get_latest_validator_set_responses.pop() + + async def GetValidatorSetByHeight( + self, request: tendermint_query.GetValidatorSetByHeightRequest, context=None, metadata=None + ): + return self.get_validator_set_by_height_responses.pop() + + async def ABCIQuery(self, request: tendermint_query.ABCIQueryRequest, context=None, metadata=None): + return self.abci_query_responses.pop() diff --git a/tests/core/tx/grpc/test_tendermint_grpc_api.py b/tests/core/tx/grpc/test_tendermint_grpc_api.py new file mode 100644 index 00000000..ed9333f6 --- /dev/null +++ b/tests/core/tx/grpc/test_tendermint_grpc_api.py @@ -0,0 +1,387 @@ +import base64 + +import grpc +import pytest + +from pyinjective.client.model.pagination import PaginationOption +from pyinjective.core.network import Network +from pyinjective.core.tx.grpc.tendermint_grpc_api import TendermintGrpcApi +from pyinjective.proto.cosmos.base.query.v1beta1 import pagination_pb2 as pagination_pb +from pyinjective.proto.cosmos.base.tendermint.v1beta1 import query_pb2 as tendermint_query +from pyinjective.proto.tendermint.p2p import types_pb2 as tendermint_p2p_types +from pyinjective.proto.tendermint.types import types_pb2 as tendermint_types +from tests.core.tx.grpc.configurable_tendermint_query_servicer import ConfigurableTendermintQueryServicer + + +@pytest.fixture +def tendermint_servicer(): + return ConfigurableTendermintQueryServicer() + + +class TestTxGrpcApi: + @pytest.mark.asyncio + async def test_fetch_node_info( + self, + tendermint_servicer, + ): + protocol_version = tendermint_p2p_types.ProtocolVersion( + p2p=7, + block=10, + app=0, + ) + other = tendermint_p2p_types.DefaultNodeInfoOther( + tx_index="on", + rpc_address="tcp://0.0.0.0:26657", + ) + node_info = tendermint_p2p_types.DefaultNodeInfo( + protocol_version=protocol_version, + default_node_id="dda2a9ee6dc43955d0942be709a16a301f7ba318", + listen_addr="tcp://0.0.0.0:26656", + network="injective-1", + version="0.34.13", + channels="channels".encode(), + moniker="injective", + other=other, + ) + module = tendermint_query.Module( + path="cloud.google.com/go", + version="v0.110.4", + sum="h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=", + ) + application_version = tendermint_query.VersionInfo( + name="injective", + app_name="injectived", + version="0.0.1", + git_commit="1f0a39381", + build_tags="netgo,ledger", + go_version="go version go1.19.13 linux/amd64", + build_deps=[module], + cosmos_sdk_version="v0.47.5", + ) + + tendermint_servicer.get_node_info_responses.append( + tendermint_query.GetNodeInfoResponse( + default_node_info=node_info, + application_version=application_version, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_info = await api.fetch_node_info() + expected_info = { + "defaultNodeInfo": { + "protocolVersion": { + "p2p": str(protocol_version.p2p), + "block": str(protocol_version.block), + "app": str(protocol_version.app), + }, + "defaultNodeId": node_info.default_node_id, + "listenAddr": node_info.listen_addr, + "network": node_info.network, + "version": node_info.version, + "channels": base64.b64encode(node_info.channels).decode(), + "moniker": node_info.moniker, + "other": { + "txIndex": other.tx_index, + "rpcAddress": other.rpc_address, + }, + }, + "applicationVersion": { + "name": application_version.name, + "appName": application_version.app_name, + "version": application_version.version, + "gitCommit": application_version.git_commit, + "buildTags": application_version.build_tags, + "goVersion": application_version.go_version, + "buildDeps": [ + { + "path": module.path, + "version": module.version, + "sum": module.sum, + } + ], + "cosmosSdkVersion": application_version.cosmos_sdk_version, + }, + } + + assert result_info == expected_info + + @pytest.mark.asyncio + async def test_fetch_syncing( + self, + tendermint_servicer, + ): + response = tendermint_query.GetSyncingResponse( + syncing=True, + ) + + tendermint_servicer.get_syncing_responses.append(response) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_syncing = await api.fetch_syncing() + expected_syncing = { + "syncing": response.syncing, + } + + assert result_syncing == expected_syncing + + @pytest.mark.asyncio + async def test_fetch_latest_block( + self, + tendermint_servicer, + ): + block_id = tendermint_types.BlockID( + hash="bdc7f6e819864a8fd050dd4494dd560c1a1519fba3383dfabbec0ea271a34979".encode(), + part_set_header=tendermint_types.PartSetHeader( + total=1, + hash="859e00bfb56409cc182a308bd72d0816e24d57f18fe5f2c5748111daaeb19fbd".encode(), + ), + ) + + tendermint_servicer.get_latest_block_responses.append( + tendermint_query.GetLatestBlockResponse( + block_id=block_id, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_block = await api.fetch_latest_block() + expected_block = { + "blockId": { + "hash": base64.b64encode(block_id.hash).decode(), + "partSetHeader": { + "total": block_id.part_set_header.total, + "hash": base64.b64encode(block_id.part_set_header.hash).decode(), + }, + }, + } + + assert result_block == expected_block + + @pytest.mark.asyncio + async def test_fetch_block_by_height( + self, + tendermint_servicer, + ): + block_id = tendermint_types.BlockID( + hash="bdc7f6e819864a8fd050dd4494dd560c1a1519fba3383dfabbec0ea271a34979".encode(), + part_set_header=tendermint_types.PartSetHeader( + total=1, + hash="859e00bfb56409cc182a308bd72d0816e24d57f18fe5f2c5748111daaeb19fbd".encode(), + ), + ) + + tendermint_servicer.get_block_by_height_responses.append( + tendermint_query.GetBlockByHeightResponse( + block_id=block_id, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_block = await api.fetch_block_by_height(height=1) + expected_block = { + "blockId": { + "hash": base64.b64encode(block_id.hash).decode(), + "partSetHeader": { + "total": block_id.part_set_header.total, + "hash": base64.b64encode(block_id.part_set_header.hash).decode(), + }, + }, + } + + assert result_block == expected_block + + @pytest.mark.asyncio + async def test_fetch_latest_validator_set( + self, + tendermint_servicer, + ): + block_height = 1 + validator = tendermint_query.Validator( + address="inj1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a", + voting_power=10, + proposer_priority=1, + ) + result_pagination = pagination_pb.PageResponse( + next_key=b"\001\032\264\007Z\224$]\377s8\343\004-\265\267\314?B\341", + total=16036, + ) + tendermint_servicer.get_latest_validator_set_responses.append( + tendermint_query.GetLatestValidatorSetResponse( + block_height=block_height, + validators=[validator], + pagination=result_pagination, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_validator_set = await api.fetch_latest_validator_set() + expected_validator_set = { + "blockHeight": str(block_height), + "validators": [ + { + "address": validator.address, + "votingPower": str(validator.voting_power), + "proposerPriority": str(validator.proposer_priority), + } + ], + "pagination": { + "nextKey": base64.b64encode(result_pagination.next_key).decode(), + "total": str(result_pagination.total), + }, + } + + assert result_validator_set == expected_validator_set + + @pytest.mark.asyncio + async def test_fetch_validator_set_by_height( + self, + tendermint_servicer, + ): + block_height = 1 + validator = tendermint_query.Validator( + address="inj1xml3ew93xmjtuf5zwpcl9jzznphte30hvdre9a", + voting_power=10, + proposer_priority=1, + ) + result_pagination = pagination_pb.PageResponse( + next_key=b"\001\032\264\007Z\224$]\377s8\343\004-\265\267\314?B\341", + total=16036, + ) + tendermint_servicer.get_validator_set_by_height_responses.append( + tendermint_query.GetValidatorSetByHeightResponse( + block_height=block_height, + validators=[validator], + pagination=result_pagination, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + pagination_option = PaginationOption( + skip=10, + limit=30, + reverse=False, + count_total=True, + ) + + result_validator_set = await api.fetch_validator_set_by_height( + height=block_height, pagination=pagination_option + ) + expected_validator_set = { + "blockHeight": str(block_height), + "validators": [ + { + "address": validator.address, + "votingPower": str(validator.voting_power), + "proposerPriority": str(validator.proposer_priority), + } + ], + "pagination": { + "nextKey": base64.b64encode(result_pagination.next_key).decode(), + "total": str(result_pagination.total), + }, + } + + assert result_validator_set == expected_validator_set + + @pytest.mark.asyncio + async def test_abci_query( + self, + tendermint_servicer, + ): + proof_op = tendermint_query.ProofOp( + type="test type", + key="proof key".encode(), + data="proof data".encode(), + ) + + code = 0 + log = "test log" + info = "test info" + index = 1 + key = "test key".encode() + value = "test value".encode() + proof_ops = tendermint_query.ProofOps(ops=[proof_op]) + height = 4567 + codespace = "test codespace" + + tendermint_servicer.abci_query_responses.append( + tendermint_query.ABCIQueryResponse( + code=code, + log=log, + info=info, + index=index, + key=key, + value=value, + proof_ops=proof_ops, + height=height, + codespace=codespace, + ) + ) + + network = Network.devnet() + channel = grpc.aio.insecure_channel(network.grpc_endpoint) + + api = TendermintGrpcApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider()) + api._stub = tendermint_servicer + + result_validator_set = await api.abci_query( + data="query data".encode(), + path="/custom/test", + height=height, + prove=True, + ) + expected_validator_set = { + "code": code, + "log": log, + "info": info, + "index": str(index), + "key": base64.b64encode(key).decode(), + "value": base64.b64encode(value).decode(), + "proofOps": { + "ops": [ + { + "type": proof_op.type, + "key": base64.b64encode(proof_op.key).decode(), + "data": base64.b64encode(proof_op.data).decode(), + } + ] + }, + "height": str(height), + "codespace": codespace, + } + + assert result_validator_set == expected_validator_set + + async def _dummy_metadata_provider(self): + return None diff --git a/tests/test_async_client_deprecation_warnings.py b/tests/test_async_client_deprecation_warnings.py index 1df77fe8..90375112 100644 --- a/tests/test_async_client_deprecation_warnings.py +++ b/tests/test_async_client_deprecation_warnings.py @@ -6,6 +6,7 @@ from pyinjective.core.network import Network from pyinjective.proto.cosmos.authz.v1beta1 import query_pb2 as authz_query from pyinjective.proto.cosmos.bank.v1beta1 import query_pb2 as bank_query_pb +from pyinjective.proto.cosmos.base.tendermint.v1beta1 import query_pb2 as tendermint_query from pyinjective.proto.cosmos.tx.v1beta1 import service_pb2 as tx_service from pyinjective.proto.exchange import ( injective_accounts_rpc_pb2 as exchange_accounts_pb, @@ -33,6 +34,7 @@ from tests.client.indexer.configurable_oracle_query_servicer import ConfigurableOracleQueryServicer from tests.client.indexer.configurable_portfolio_query_servicer import ConfigurablePortfolioQueryServicer from tests.client.indexer.configurable_spot_query_servicer import ConfigurableSpotQueryServicer +from tests.core.tx.grpc.configurable_tendermint_query_servicer import ConfigurableTendermintQueryServicer from tests.core.tx.grpc.configurable_tx_query_servicer import ConfigurableTxQueryServicer @@ -106,6 +108,11 @@ def tx_servicer(): return ConfigurableTxQueryServicer() +@pytest.fixture +def tendermint_servicer(): + return ConfigurableTendermintQueryServicer() + + class TestAsyncClientDeprecationWarnings: def test_insecure_parameter_deprecation_warning( self, @@ -537,24 +544,6 @@ async def test_stream_keepalive_deprecation_warning( assert len(deprecation_warnings) == 1 assert str(deprecation_warnings[0].message) == "This method is deprecated. Use listen_keepalive instead" - @pytest.mark.asyncio - async def test_oracle_list_deprecation_warning( - self, - oracle_servicer, - ): - client = AsyncClient( - network=Network.local(), - ) - client.stubOracle = oracle_servicer - oracle_servicer.oracle_list_responses.append(exchange_oracle_pb.OracleListResponse()) - - with catch_warnings(record=True) as all_warnings: - await client.get_oracle_list() - - 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 fetch_oracle_list instead" - @pytest.mark.asyncio async def test_get_oracle_list_deprecation_warning( self, @@ -1700,3 +1689,21 @@ async def test_chain_stream_deprecation_warning( assert ( str(deprecation_warnings[0].message) == "This method is deprecated. Use listen_chain_stream_updates instead" ) + + @pytest.mark.asyncio + async def test_get_latest_block_deprecation_warning( + self, + tendermint_servicer, + ): + client = AsyncClient( + network=Network.local(), + ) + client.stubCosmosTendermint = tendermint_servicer + tendermint_servicer.get_latest_block_responses.append(tendermint_query.GetLatestBlockResponse()) + + with catch_warnings(record=True) as all_warnings: + await client.get_latest_block() + + 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 fetch_latest_block instead" diff --git a/tests/test_composer_deprecation_warnings.py b/tests/test_composer_deprecation_warnings.py index 20a86779..a2891299 100644 --- a/tests/test_composer_deprecation_warnings.py +++ b/tests/test_composer_deprecation_warnings.py @@ -50,7 +50,20 @@ def test_msg_withdraw_deprecation_warning(self): 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): + def test_coin_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.Coin( + 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 coin instead" + + def test_order_data_deprecation_warning(self): composer = Composer(network=Network.devnet().string()) with warnings.catch_warnings(record=True) as all_warnings: @@ -520,3 +533,19 @@ def test_msg_admin_update_binary_options_market_deprecation_warning(self, basic_ str(deprecation_warnings[0].message) == "This method is deprecated. Use msg_admin_update_binary_options_market instead" ) + + def test_msg_withdraw_delegator_reward_deprecation_warning(self): + composer = Composer(network=Network.devnet().string()) + + with warnings.catch_warnings(record=True) as all_warnings: + composer.MsgWithdrawDelegatorReward( + delegator_address="delegator address", + validator_address="validator address", + ) + + 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_delegator_reward instead" + )