Skip to content

Commit 4f14a69

Browse files
author
abel
committed
(feat) Implemented all TokenFactory query module endpoints
1 parent f72b7dc commit 4f14a69

File tree

7 files changed

+313
-0
lines changed

7 files changed

+313
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import asyncio
2+
3+
from pyinjective.async_client import AsyncClient
4+
from pyinjective.core.network import Network
5+
6+
7+
async def main() -> None:
8+
network = Network.testnet()
9+
client = AsyncClient(network)
10+
metadata = await client.fetch_denom_authority_metadata(creator="inj1zvy8xrlhe7ex9scer868clfstdv7j6vz790kwa")
11+
print(metadata)
12+
13+
14+
if __name__ == "__main__":
15+
asyncio.get_event_loop().run_until_complete(main())
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import asyncio
2+
3+
from pyinjective.async_client import AsyncClient
4+
from pyinjective.core.network import Network
5+
6+
7+
async def main() -> None:
8+
network = Network.testnet()
9+
client = AsyncClient(network)
10+
denoms = await client.fetch_denoms_from_creator(creator="inj1maeyvxfamtn8lfyxpjca8kuvauuf2qeu6gtxm3")
11+
print(denoms)
12+
13+
14+
if __name__ == "__main__":
15+
asyncio.get_event_loop().run_until_complete(main())
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import asyncio
2+
3+
from pyinjective.async_client import AsyncClient
4+
from pyinjective.core.network import Network
5+
6+
7+
async def main() -> None:
8+
network = Network.testnet()
9+
client = AsyncClient(network)
10+
state = await client.fetch_tokenfactory_module_state()
11+
print(state)
12+
13+
14+
if __name__ == "__main__":
15+
asyncio.get_event_loop().run_until_complete(main())

pyinjective/async_client.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pyinjective.client.chain.grpc.chain_grpc_auth_api import ChainGrpcAuthApi
1414
from pyinjective.client.chain.grpc.chain_grpc_authz_api import ChainGrpcAuthZApi
1515
from pyinjective.client.chain.grpc.chain_grpc_bank_api import ChainGrpcBankApi
16+
from pyinjective.client.chain.grpc.chain_grpc_token_factory_api import ChainGrpcTokenFactoryApi
1617
from pyinjective.client.chain.grpc.chain_grpc_wasm_api import ChainGrpcWasmApi
1718
from pyinjective.client.chain.grpc_stream.chain_grpc_chain_stream import ChainGrpcChainStream
1819
from pyinjective.client.indexer.grpc.indexer_grpc_account_api import IndexerGrpcAccountApi
@@ -178,6 +179,12 @@ def __init__(
178179
metadata_query_provider=self._chain_cookie_metadata_requestor
179180
),
180181
)
182+
self.token_factory_api = ChainGrpcTokenFactoryApi(
183+
channel=self.chain_channel,
184+
metadata_provider=lambda: self.network.chain_metadata(
185+
metadata_query_provider=self._chain_cookie_metadata_requestor
186+
),
187+
)
181188
self.tx_api = TxGrpcApi(
182189
channel=self.chain_channel,
183190
metadata_provider=lambda: self.network.chain_metadata(
@@ -738,6 +745,24 @@ async def fetch_contracts_by_creator(
738745
pagination=pagination,
739746
)
740747

748+
# Token Factory module
749+
750+
async def fetch_denom_authority_metadata(
751+
self,
752+
creator: str,
753+
sub_denom: Optional[str] = None,
754+
) -> Dict[str, Any]:
755+
return await self.token_factory_api.fetch_denom_authority_metadata(creator=creator, sub_denom=sub_denom)
756+
757+
async def fetch_denoms_from_creator(
758+
self,
759+
creator: str,
760+
) -> Dict[str, Any]:
761+
return await self.token_factory_api.fetch_denoms_from_creator(creator=creator)
762+
763+
async def fetch_tokenfactory_module_state(self) -> Dict[str, Any]:
764+
return await self.token_factory_api.fetch_tokenfactory_module_state()
765+
741766
# Explorer RPC
742767

743768
async def get_tx_by_hash(self, tx_hash: str):
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from typing import Any, Callable, Dict, Optional
2+
3+
from grpc.aio import Channel
4+
5+
from pyinjective.proto.injective.tokenfactory.v1beta1 import (
6+
query_pb2 as token_factory_query_pb,
7+
query_pb2_grpc as token_factory_query_grpc,
8+
tx_pb2_grpc as token_factory_tx_grpc,
9+
)
10+
from pyinjective.utils.grpc_api_request_assistant import GrpcApiRequestAssistant
11+
12+
13+
class ChainGrpcTokenFactoryApi:
14+
def __init__(self, channel: Channel, metadata_provider: Callable):
15+
self._query_stub = token_factory_query_grpc.QueryStub(channel)
16+
self._tx_stub = token_factory_tx_grpc.MsgStub(channel)
17+
self._assistant = GrpcApiRequestAssistant(metadata_provider=metadata_provider)
18+
19+
async def fetch_module_params(self) -> Dict[str, Any]:
20+
request = token_factory_query_pb.QueryParamsRequest()
21+
response = await self._execute_call(call=self._query_stub.Params, request=request)
22+
23+
return response
24+
25+
async def fetch_denom_authority_metadata(
26+
self,
27+
creator: str,
28+
sub_denom: Optional[str] = None,
29+
) -> Dict[str, Any]:
30+
request = token_factory_query_pb.QueryDenomAuthorityMetadataRequest(
31+
creator=creator,
32+
sub_denom=sub_denom,
33+
)
34+
response = await self._execute_call(call=self._query_stub.DenomAuthorityMetadata, request=request)
35+
36+
return response
37+
38+
async def fetch_denoms_from_creator(self, creator: str) -> Dict[str, Any]:
39+
request = token_factory_query_pb.QueryDenomsFromCreatorRequest(creator=creator)
40+
response = await self._execute_call(call=self._query_stub.DenomsFromCreator, request=request)
41+
42+
return response
43+
44+
async def fetch_tokenfactory_module_state(self) -> Dict[str, Any]:
45+
request = token_factory_query_pb.QueryModuleStateRequest()
46+
response = await self._execute_call(call=self._query_stub.TokenfactoryModuleState, request=request)
47+
48+
return response
49+
50+
async def _execute_call(self, call: Callable, request) -> Dict[str, Any]:
51+
return await self._assistant.execute_call(call=call, request=request)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from collections import deque
2+
3+
from pyinjective.proto.injective.tokenfactory.v1beta1 import (
4+
query_pb2 as token_factory_query_pb,
5+
query_pb2_grpc as token_factory_query_grpc,
6+
)
7+
8+
9+
class ConfigurableTokenFactoryQueryServicer(token_factory_query_grpc.QueryServicer):
10+
def __init__(self):
11+
super().__init__()
12+
self.params_responses = deque()
13+
self.denom_authority_metadata_responses = deque()
14+
self.denoms_from_creator_responses = deque()
15+
self.tokenfactory_module_state_responses = deque()
16+
17+
async def Params(self, request: token_factory_query_pb.QueryParamsRequest, context=None, metadata=None):
18+
return self.params_responses.pop()
19+
20+
async def DenomAuthorityMetadata(
21+
self, request: token_factory_query_pb.QueryDenomAuthorityMetadataRequest, context=None, metadata=None
22+
):
23+
return self.denom_authority_metadata_responses.pop()
24+
25+
async def DenomsFromCreator(
26+
self, request: token_factory_query_pb.QueryDenomsFromCreatorRequest, context=None, metadata=None
27+
):
28+
return self.denoms_from_creator_responses.pop()
29+
30+
async def TokenfactoryModuleState(
31+
self, request: token_factory_query_pb.QueryModuleStateRequest, context=None, metadata=None
32+
):
33+
return self.tokenfactory_module_state_responses.pop()
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import grpc
2+
import pytest
3+
4+
from pyinjective.client.chain.grpc.chain_grpc_token_factory_api import ChainGrpcTokenFactoryApi
5+
from pyinjective.core.network import Network
6+
from pyinjective.proto.cosmos.base.v1beta1 import coin_pb2 as coin_pb
7+
from pyinjective.proto.injective.tokenfactory.v1beta1 import (
8+
authorityMetadata_pb2 as token_factory_authority_metadata_pb,
9+
genesis_pb2 as token_factory_genesis_pb,
10+
params_pb2 as token_factory_params_pb,
11+
query_pb2 as token_factory_query_pb,
12+
)
13+
from tests.client.chain.grpc.configurable_token_factory_query_servicer import ConfigurableTokenFactoryQueryServicer
14+
15+
16+
@pytest.fixture
17+
def token_factory_query_servicer():
18+
return ConfigurableTokenFactoryQueryServicer()
19+
20+
21+
class TestChainGrpcTokenFactoryApi:
22+
@pytest.mark.asyncio
23+
async def test_fetch_module_params(
24+
self,
25+
token_factory_query_servicer,
26+
):
27+
coin = coin_pb.Coin(denom="inj", amount="988987297011197594664")
28+
params = token_factory_params_pb.Params(
29+
denom_creation_fee=[coin],
30+
)
31+
token_factory_query_servicer.params_responses.append(token_factory_query_pb.QueryParamsResponse(params=params))
32+
33+
network = Network.devnet()
34+
channel = grpc.aio.insecure_channel(network.grpc_endpoint)
35+
36+
api = ChainGrpcTokenFactoryApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider())
37+
api._query_stub = token_factory_query_servicer
38+
39+
module_params = await api.fetch_module_params()
40+
expected_params = {
41+
"params": {
42+
"denomCreationFee": [
43+
{"denom": coin.denom, "amount": coin.amount},
44+
],
45+
}
46+
}
47+
48+
assert module_params == expected_params
49+
50+
@pytest.mark.asyncio
51+
async def test_fetch_denom_authority_metadata(
52+
self,
53+
token_factory_query_servicer,
54+
):
55+
authority_metadata = token_factory_authority_metadata_pb.DenomAuthorityMetadata(
56+
admin="inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
57+
)
58+
token_factory_query_servicer.denom_authority_metadata_responses.append(
59+
token_factory_query_pb.QueryDenomAuthorityMetadataResponse(
60+
authority_metadata=authority_metadata,
61+
)
62+
)
63+
64+
network = Network.devnet()
65+
channel = grpc.aio.insecure_channel(network.grpc_endpoint)
66+
67+
api = ChainGrpcTokenFactoryApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider())
68+
api._query_stub = token_factory_query_servicer
69+
70+
metadata = await api.fetch_denom_authority_metadata(
71+
creator=authority_metadata.admin,
72+
sub_denom="inj",
73+
)
74+
expected_metadata = {
75+
"authorityMetadata": {
76+
"admin": authority_metadata.admin,
77+
},
78+
}
79+
80+
assert metadata == expected_metadata
81+
82+
@pytest.mark.asyncio
83+
async def test_fetch_denoms_from_creator(
84+
self,
85+
token_factory_query_servicer,
86+
):
87+
denom = "factory/inj17vytdwqczqz72j65saukplrktd4gyfme5agf6c/weth"
88+
token_factory_query_servicer.denoms_from_creator_responses.append(
89+
token_factory_query_pb.QueryDenomsFromCreatorResponse(denoms=[denom])
90+
)
91+
92+
network = Network.devnet()
93+
channel = grpc.aio.insecure_channel(network.grpc_endpoint)
94+
95+
api = ChainGrpcTokenFactoryApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider())
96+
api._query_stub = token_factory_query_servicer
97+
98+
denoms = await api.fetch_denoms_from_creator(creator="inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7")
99+
expected_denoms = {"denoms": [denom]}
100+
101+
assert denoms == expected_denoms
102+
103+
@pytest.mark.asyncio
104+
async def test_fetch_tokenfactory_module_state(
105+
self,
106+
token_factory_query_servicer,
107+
):
108+
coin = coin_pb.Coin(denom="inj", amount="988987297011197594664")
109+
params = token_factory_params_pb.Params(
110+
denom_creation_fee=[coin],
111+
)
112+
authority_metadata = token_factory_authority_metadata_pb.DenomAuthorityMetadata(
113+
admin="inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0",
114+
)
115+
genesis_denom = token_factory_genesis_pb.GenesisDenom(
116+
denom="factory/inj1apmvarl2xyv6kecx2ukkeymddw3we4zkygjyc0/ninja",
117+
authority_metadata=authority_metadata,
118+
name="Dog Wif Nunchucks",
119+
symbol="NINJA",
120+
)
121+
state = token_factory_genesis_pb.GenesisState(
122+
params=params,
123+
factory_denoms=[genesis_denom],
124+
)
125+
token_factory_query_servicer.tokenfactory_module_state_responses.append(
126+
token_factory_query_pb.QueryModuleStateResponse(state=state)
127+
)
128+
129+
network = Network.devnet()
130+
channel = grpc.aio.insecure_channel(network.grpc_endpoint)
131+
132+
api = ChainGrpcTokenFactoryApi(channel=channel, metadata_provider=lambda: self._dummy_metadata_provider())
133+
api._query_stub = token_factory_query_servicer
134+
135+
state = await api.fetch_tokenfactory_module_state()
136+
expected_state = {
137+
"state": {
138+
"params": {
139+
"denomCreationFee": [
140+
{"denom": coin.denom, "amount": coin.amount},
141+
],
142+
},
143+
"factoryDenoms": [
144+
{
145+
"denom": genesis_denom.denom,
146+
"authorityMetadata": {
147+
"admin": authority_metadata.admin,
148+
},
149+
"name": genesis_denom.name,
150+
"symbol": genesis_denom.symbol,
151+
}
152+
],
153+
}
154+
}
155+
156+
assert state == expected_state
157+
158+
async def _dummy_metadata_provider(self):
159+
return None

0 commit comments

Comments
 (0)