Skip to content

Commit

Permalink
(feat) Added logic to initialize tokens in AsyncClient using the deno…
Browse files Browse the repository at this point in the history
…ms metadata from chain bank module
  • Loading branch information
abel committed Dec 26, 2023
1 parent 8da302a commit 50d93a4
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 9 deletions.
46 changes: 46 additions & 0 deletions pyinjective/async_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import base64
import time
from copy import deepcopy
from decimal import Decimal
Expand Down Expand Up @@ -2495,6 +2496,51 @@ async def composer(self):
tokens=await self.all_tokens(),
)

async def initialize_tokens_from_chain_denoms(self):
# force initialization of markets and tokens
await self.all_tokens()

all_denoms_metadata = []

query_result = await self.fetch_denoms_metadata()

all_denoms_metadata.extend(query_result.get("metadatas", []))
next_key = query_result.get("pagination", {}).get("nextKey", "")

while next_key != "":
query_result = await self.fetch_denoms_metadata(pagination=PaginationOption(key=next_key))

all_denoms_metadata.extend(query_result.get("metadatas", []))

Check warning on line 2513 in pyinjective/async_client.py

View check run for this annotation

Codecov / codecov/patch

pyinjective/async_client.py#L2513

Added line #L2513 was not covered by tests
result_next_key = query_result.get("pagination", {}).get("nextKey", "")
next_key = base64.b64decode(result_next_key).decode()

for token_metadata in all_denoms_metadata:

Check warning on line 2517 in pyinjective/async_client.py

View check run for this annotation

Codecov / codecov/patch

pyinjective/async_client.py#L2515-L2517

Added lines #L2515 - L2517 were not covered by tests
symbol = token_metadata["symbol"]
denom = token_metadata["base"]

if denom != "" and symbol != "" and denom not in self._tokens_by_denom:
name = token_metadata["name"] or symbol
decimals = max({denom_unit["exponent"] for denom_unit in token_metadata["denomUnits"]})

unique_symbol = denom
for symbol_candidate in [symbol, name]:
if symbol_candidate not in self._tokens_by_symbol:
unique_symbol = symbol_candidate
break

token = Token(
name=name,
symbol=symbol,
denom=denom,
address="",
decimals=decimals,
logo=token_metadata["uri"],
updated=-1,
)

self._tokens_by_denom[denom] = token
self._tokens_by_symbol[unique_symbol] = token

async def _initialize_tokens_and_markets(self):
spot_markets = dict()
derivative_markets = dict()
Expand Down
2 changes: 1 addition & 1 deletion pyinjective/client/model/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def create_pagination_request(self) -> pagination_pb.PageRequest:
page_request = pagination_pb.PageRequest()

if self.key is not None:
page_request.key = bytes.fromhex(self.key)
page_request.key = self.key.encode()
if self.skip is not None:
page_request.offset = self.skip
if self.limit is not None:
Expand Down
26 changes: 26 additions & 0 deletions tests/rpc_fixtures/markets_fixtures.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
import pytest


@pytest.fixture
def smart_denom_metadata():
from pyinjective.proto.cosmos.bank.v1beta1 import bank_pb2 as bank_pb

first_denom_unit = bank_pb.DenomUnit(
denom="factory/inj105ujajd95znwjvcy3hwcz80pgy8tc6v77spur0/SMART", exponent=0, aliases=["microSMART"]
)
second_denom_unit = bank_pb.DenomUnit(denom="SMART", exponent=6, aliases=["SMART"])
metadata = bank_pb.Metadata(
description="SMART",
denom_units=[first_denom_unit, second_denom_unit],
base="factory/inj105ujajd95znwjvcy3hwcz80pgy8tc6v77spur0/SMART",
display="SMART",
name="SMART",
symbol="SMART",
uri=(
"https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/"
"Flag_of_the_People%27s_Republic_of_China.svg/"
"2560px-Flag_of_the_People%27s_Republic_of_China.svg.png"
),
uri_hash="",
)

return metadata


@pytest.fixture
def inj_token_meta():
from pyinjective.proto.exchange.injective_spot_exchange_rpc_pb2 import TokenMeta
Expand Down
66 changes: 58 additions & 8 deletions tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,31 @@

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network
from pyinjective.proto.cosmos.bank.v1beta1 import query_pb2 as bank_query_pb
from pyinjective.proto.cosmos.base.query.v1beta1 import pagination_pb2 as pagination_pb
from pyinjective.proto.exchange import injective_derivative_exchange_rpc_pb2, injective_spot_exchange_rpc_pb2
from tests.client.chain.grpc.configurable_bank_query_servicer import ConfigurableBankQueryServicer
from tests.client.indexer.configurable_derivative_query_servicer import ConfigurableDerivativeQueryServicer
from tests.client.indexer.configurable_spot_query_servicer import ConfigurableSpotQueryServicer
from tests.rpc_fixtures.markets_fixtures import ape_token_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import ape_usdt_spot_market_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import btc_usdt_perp_market_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import inj_token_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import inj_usdt_spot_market_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import usdt_perp_token_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import usdt_token_meta # noqa: F401
from tests.rpc_fixtures.markets_fixtures import ( # noqa: F401; noqa: F401; noqa: F401
from tests.rpc_fixtures.markets_fixtures import ( # noqa: F401
ape_token_meta,
ape_usdt_spot_market_meta,
btc_usdt_perp_market_meta,
first_match_bet_market_meta,
inj_token_meta,
inj_usdt_spot_market_meta,
smart_denom_metadata,
usdt_perp_token_meta,
usdt_token_meta,
usdt_token_meta_second_denom,
)


@pytest.fixture
def bank_servicer():
return ConfigurableBankQueryServicer()


@pytest.fixture
def spot_servicer():
return ConfigurableSpotQueryServicer()
Expand Down Expand Up @@ -127,3 +136,44 @@ async def test_initialize_tokens_and_markets(
assert any(
(first_match_bet_market_meta.market_id == market.id for market in all_binary_option_markets.values())
)

@pytest.mark.asyncio
async def test_initialize_tokens_from_chain_denoms(
self,
bank_servicer,
spot_servicer,
derivative_servicer,
smart_denom_metadata,
):
pagination = pagination_pb.PageResponse(
total=1,
)

bank_servicer.denoms_metadata_responses.append(
bank_query_pb.QueryDenomsMetadataResponse(
metadatas=[smart_denom_metadata],
pagination=pagination,
)
)

spot_servicer.markets_responses.append(injective_spot_exchange_rpc_pb2.MarketsResponse(markets=[]))
derivative_servicer.markets_responses.append(injective_derivative_exchange_rpc_pb2.MarketsResponse(markets=[]))
derivative_servicer.binary_options_markets_responses.append(
injective_derivative_exchange_rpc_pb2.BinaryOptionsMarketsResponse(markets=[])
)

client = AsyncClient(
network=Network.local(),
insecure=False,
)

client.bank_api._stub = bank_servicer
client.exchange_spot_api._stub = spot_servicer
client.exchange_derivative_api._stub = derivative_servicer

await client._initialize_tokens_and_markets()
await client.initialize_tokens_from_chain_denoms()

all_tokens = await client.all_tokens()
assert 1 == len(all_tokens)
assert smart_denom_metadata.symbol in all_tokens

0 comments on commit 50d93a4

Please sign in to comment.