Skip to content

Commit 6528188

Browse files
author
abel
committed
(feat) Added logic to initialize tokens in AsyncClient using the denoms metadata from chain bank module
1 parent ff3aa9d commit 6528188

File tree

4 files changed

+131
-9
lines changed

4 files changed

+131
-9
lines changed

pyinjective/async_client.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import base64
23
import time
34
from copy import deepcopy
45
from decimal import Decimal
@@ -2497,6 +2498,51 @@ async def composer(self):
24972498
tokens=await self.all_tokens(),
24982499
)
24992500

2501+
async def initialize_tokens_from_chain_denoms(self):
2502+
# force initialization of markets and tokens
2503+
await self.all_tokens()
2504+
2505+
all_denoms_metadata = []
2506+
2507+
query_result = await self.fetch_denoms_metadata()
2508+
2509+
all_denoms_metadata.extend(query_result.get("metadatas", []))
2510+
next_key = query_result.get("pagination", {}).get("nextKey", "")
2511+
2512+
while next_key != "":
2513+
query_result = await self.fetch_denoms_metadata(pagination=PaginationOption(key=next_key))
2514+
2515+
all_denoms_metadata.extend(query_result.get("metadatas", []))
2516+
result_next_key = query_result.get("pagination", {}).get("nextKey", "")
2517+
next_key = base64.b64decode(result_next_key).decode()
2518+
2519+
for token_metadata in all_denoms_metadata:
2520+
symbol = token_metadata["symbol"]
2521+
denom = token_metadata["base"]
2522+
2523+
if denom != "" and symbol != "" and denom not in self._tokens_by_denom:
2524+
name = token_metadata["name"] or symbol
2525+
decimals = max({denom_unit["exponent"] for denom_unit in token_metadata["denomUnits"]})
2526+
2527+
unique_symbol = denom
2528+
for symbol_candidate in [symbol, name]:
2529+
if symbol_candidate not in self._tokens_by_symbol:
2530+
unique_symbol = symbol_candidate
2531+
break
2532+
2533+
token = Token(
2534+
name=name,
2535+
symbol=symbol,
2536+
denom=denom,
2537+
address="",
2538+
decimals=decimals,
2539+
logo=token_metadata["uri"],
2540+
updated=-1,
2541+
)
2542+
2543+
self._tokens_by_denom[denom] = token
2544+
self._tokens_by_symbol[unique_symbol] = token
2545+
25002546
async def _initialize_tokens_and_markets(self):
25012547
spot_markets = dict()
25022548
derivative_markets = dict()

pyinjective/client/model/pagination.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def create_pagination_request(self) -> pagination_pb.PageRequest:
3131
page_request = pagination_pb.PageRequest()
3232

3333
if self.key is not None:
34-
page_request.key = bytes.fromhex(self.key)
34+
page_request.key = self.key.encode()
3535
if self.skip is not None:
3636
page_request.offset = self.skip
3737
if self.limit is not None:

tests/rpc_fixtures/markets_fixtures.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
import pytest
22

33

4+
@pytest.fixture
5+
def smart_denom_metadata():
6+
from pyinjective.proto.cosmos.bank.v1beta1 import bank_pb2 as bank_pb
7+
8+
first_denom_unit = bank_pb.DenomUnit(
9+
denom="factory/inj105ujajd95znwjvcy3hwcz80pgy8tc6v77spur0/SMART", exponent=0, aliases=["microSMART"]
10+
)
11+
second_denom_unit = bank_pb.DenomUnit(denom="SMART", exponent=6, aliases=["SMART"])
12+
metadata = bank_pb.Metadata(
13+
description="SMART",
14+
denom_units=[first_denom_unit, second_denom_unit],
15+
base="factory/inj105ujajd95znwjvcy3hwcz80pgy8tc6v77spur0/SMART",
16+
display="SMART",
17+
name="SMART",
18+
symbol="SMART",
19+
uri=(
20+
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/"
21+
"Flag_of_the_People%27s_Republic_of_China.svg/"
22+
"2560px-Flag_of_the_People%27s_Republic_of_China.svg.png"
23+
),
24+
uri_hash="",
25+
)
26+
27+
return metadata
28+
29+
430
@pytest.fixture
531
def inj_token_meta():
632
from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta

tests/test_async_client.py

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,31 @@
44

55
from pyinjective.async_client import AsyncClient
66
from pyinjective.core.network import Network
7+
from pyinjective.proto.cosmos.bank.v1beta1 import query_pb2 as bank_query_pb
8+
from pyinjective.proto.cosmos.base.query.v1beta1 import pagination_pb2 as pagination_pb
79
from pyinjective.proto.exchange import injective_derivative_exchange_rpc_pb2, injective_spot_exchange_rpc_pb2
10+
from tests.client.chain.grpc.configurable_bank_query_servicer import ConfigurableBankQueryServicer
811
from tests.client.indexer.configurable_derivative_query_servicer import ConfigurableDerivativeQueryServicer
912
from tests.client.indexer.configurable_spot_query_servicer import ConfigurableSpotQueryServicer
10-
from tests.rpc_fixtures.markets_fixtures import ape_token_meta # noqa: F401
11-
from tests.rpc_fixtures.markets_fixtures import ape_usdt_spot_market_meta # noqa: F401
12-
from tests.rpc_fixtures.markets_fixtures import btc_usdt_perp_market_meta # noqa: F401
13-
from tests.rpc_fixtures.markets_fixtures import inj_token_meta # noqa: F401
14-
from tests.rpc_fixtures.markets_fixtures import inj_usdt_spot_market_meta # noqa: F401
15-
from tests.rpc_fixtures.markets_fixtures import usdt_perp_token_meta # noqa: F401
16-
from tests.rpc_fixtures.markets_fixtures import usdt_token_meta # noqa: F401
17-
from tests.rpc_fixtures.markets_fixtures import ( # noqa: F401; noqa: F401; noqa: F401
13+
from tests.rpc_fixtures.markets_fixtures import ( # noqa: F401
14+
ape_token_meta,
15+
ape_usdt_spot_market_meta,
16+
btc_usdt_perp_market_meta,
1817
first_match_bet_market_meta,
18+
inj_token_meta,
19+
inj_usdt_spot_market_meta,
20+
smart_denom_metadata,
21+
usdt_perp_token_meta,
22+
usdt_token_meta,
1923
usdt_token_meta_second_denom,
2024
)
2125

2226

27+
@pytest.fixture
28+
def bank_servicer():
29+
return ConfigurableBankQueryServicer()
30+
31+
2332
@pytest.fixture
2433
def spot_servicer():
2534
return ConfigurableSpotQueryServicer()
@@ -127,3 +136,44 @@ async def test_initialize_tokens_and_markets(
127136
assert any(
128137
(first_match_bet_market_meta.market_id == market.id for market in all_binary_option_markets.values())
129138
)
139+
140+
@pytest.mark.asyncio
141+
async def test_initialize_tokens_from_chain_denoms(
142+
self,
143+
bank_servicer,
144+
spot_servicer,
145+
derivative_servicer,
146+
smart_denom_metadata,
147+
):
148+
pagination = pagination_pb.PageResponse(
149+
total=1,
150+
)
151+
152+
bank_servicer.denoms_metadata_responses.append(
153+
bank_query_pb.QueryDenomsMetadataResponse(
154+
metadatas=[smart_denom_metadata],
155+
pagination=pagination,
156+
)
157+
)
158+
159+
spot_servicer.markets_responses.append(injective_spot_exchange_rpc_pb2.MarketsResponse(markets=[]))
160+
derivative_servicer.markets_responses.append(injective_derivative_exchange_rpc_pb2.MarketsResponse(markets=[]))
161+
derivative_servicer.binary_options_markets_responses.append(
162+
injective_derivative_exchange_rpc_pb2.BinaryOptionsMarketsResponse(markets=[])
163+
)
164+
165+
client = AsyncClient(
166+
network=Network.local(),
167+
insecure=False,
168+
)
169+
170+
client.bank_api._stub = bank_servicer
171+
client.exchange_spot_api._stub = spot_servicer
172+
client.exchange_derivative_api._stub = derivative_servicer
173+
174+
await client._initialize_tokens_and_markets()
175+
await client.initialize_tokens_from_chain_denoms()
176+
177+
all_tokens = await client.all_tokens()
178+
assert 1 == len(all_tokens)
179+
assert smart_denom_metadata.symbol in all_tokens

0 commit comments

Comments
 (0)