Skip to content

Commit

Permalink
Merge pull request #286 from InjectiveLabs/feat/initialize_tokens_fro…
Browse files Browse the repository at this point in the history
…m_chain_denoms

Feat/initialize tokens from chain denoms
  • Loading branch information
aarmoa authored Jan 2, 2024
2 parents 3261b40 + 7143944 commit ffd1928
Show file tree
Hide file tree
Showing 15 changed files with 743 additions and 12 deletions.
16 changes: 16 additions & 0 deletions examples/chain_client/50_SpendableBalances.py
Original file line number Diff line number Diff line change
@@ -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)
address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
spendable_balances = await client.fetch_spendable_balances(address=address)
print(spendable_balances)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
17 changes: 17 additions & 0 deletions examples/chain_client/51_SpendableBalancesByDenom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)
address = "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"
denom = "inj"
spendable_balances = await client.fetch_spendable_balances_by_denom(address=address, denom=denom)
print(spendable_balances)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
18 changes: 18 additions & 0 deletions examples/chain_client/52_TotalSupply.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import asyncio

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)
total_supply = await client.fetch_total_supply(
pagination=PaginationOption(limit=10),
)
print(total_supply)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
15 changes: 15 additions & 0 deletions examples/chain_client/53_SupplyOf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)
supply_of = await client.fetch_supply_of(denom="inj")
print(supply_of)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
16 changes: 16 additions & 0 deletions examples/chain_client/54_DenomMetadata.py
Original file line number Diff line number Diff line change
@@ -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)
denom = "factory/inj107aqkjc3t5r3l9j4n9lgrma5tm3jav8qgppz6m/position"
metadata = await client.fetch_denom_metadata(denom=denom)
print(metadata)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
18 changes: 18 additions & 0 deletions examples/chain_client/55_DenomsMetadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import asyncio

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)
denoms = await client.fetch_denoms_metadata(
pagination=PaginationOption(limit=10),
)
print(denoms)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
20 changes: 20 additions & 0 deletions examples/chain_client/56_DenomOwners.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import asyncio

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)
denom = "inj"
owners = await client.fetch_denom_owners(
denom=denom,
pagination=PaginationOption(limit=10),
)
print(owners)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
20 changes: 20 additions & 0 deletions examples/chain_client/57_SendEnabled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import asyncio

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)
denom = "inj"
enabled = await client.fetch_send_enabled(
denoms=[denom],
pagination=PaginationOption(limit=10),
)
print(enabled)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
82 changes: 82 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 @@ -522,6 +523,42 @@ async def get_bank_balance(self, address: str, denom: str):
async def fetch_bank_balance(self, address: str, denom: str) -> Dict[str, Any]:
return await self.bank_api.fetch_balance(account_address=address, denom=denom)

async def fetch_spendable_balances(
self,
address: str,
pagination: Optional[PaginationOption] = None,
) -> Dict[str, Any]:
return await self.bank_api.fetch_spendable_balances(account_address=address, pagination=pagination)

async def fetch_spendable_balances_by_denom(
self,
address: str,
denom: str,
) -> Dict[str, Any]:
return await self.bank_api.fetch_spendable_balances_by_denom(account_address=address, denom=denom)

async def fetch_total_supply(self, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
return await self.bank_api.fetch_total_supply(pagination=pagination)

async def fetch_supply_of(self, denom: str) -> Dict[str, Any]:
return await self.bank_api.fetch_supply_of(denom=denom)

async def fetch_denom_metadata(self, denom: str) -> Dict[str, Any]:
return await self.bank_api.fetch_denom_metadata(denom=denom)

async def fetch_denoms_metadata(self, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
return await self.bank_api.fetch_denoms_metadata(pagination=pagination)

async def fetch_denom_owners(self, denom: str, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
return await self.bank_api.fetch_denom_owners(denom=denom, pagination=pagination)

async def fetch_send_enabled(
self,
denoms: Optional[List[str]] = None,
pagination: Optional[PaginationOption] = None,
) -> Dict[str, Any]:
return await self.bank_api.fetch_send_enabled(denoms=denoms, pagination=pagination)

# Injective Exchange client methods

# Auction RPC
Expand Down Expand Up @@ -2461,6 +2498,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", []))
result_next_key = query_result.get("pagination", {}).get("nextKey", "")
next_key = base64.b64decode(result_next_key).decode()

for token_metadata in all_denoms_metadata:
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
82 changes: 79 additions & 3 deletions pyinjective/client/chain/grpc/chain_grpc_bank_api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Any, Callable, Dict
from typing import Any, Callable, Dict, List, Optional

from grpc.aio import Channel

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.proto.cosmos.bank.v1beta1 import query_pb2 as bank_query_pb, query_pb2_grpc as bank_query_grpc
from pyinjective.utils.grpc_api_request_assistant import GrpcApiRequestAssistant

Expand Down Expand Up @@ -29,11 +30,86 @@ async def fetch_balances(self, account_address: str) -> Dict[str, Any]:

return response

async def fetch_total_supply(self) -> Dict[str, Any]:
request = bank_query_pb.QueryTotalSupplyRequest()
async def fetch_spendable_balances(
self,
account_address: str,
pagination: Optional[PaginationOption] = None,
) -> Dict[str, Any]:
pagination_request = None
if pagination is not None:
pagination_request = pagination.create_pagination_request()
request = bank_query_pb.QuerySpendableBalancesRequest(
address=account_address,
pagination=pagination_request,
)
response = await self._execute_call(call=self._stub.SpendableBalances, request=request)

return response

async def fetch_spendable_balances_by_denom(
self,
account_address: str,
denom: str,
) -> Dict[str, Any]:
request = bank_query_pb.QuerySpendableBalanceByDenomRequest(
address=account_address,
denom=denom,
)
response = await self._execute_call(call=self._stub.SpendableBalanceByDenom, request=request)

return response

async def fetch_total_supply(self, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
pagination_request = None
if pagination is not None:
pagination_request = pagination.create_pagination_request()
request = bank_query_pb.QueryTotalSupplyRequest(pagination=pagination_request)
response = await self._execute_call(call=self._stub.TotalSupply, request=request)

return response

async def fetch_supply_of(self, denom: str) -> Dict[str, Any]:
request = bank_query_pb.QuerySupplyOfRequest(denom=denom)
response = await self._execute_call(call=self._stub.SupplyOf, request=request)

return response

async def fetch_denom_metadata(self, denom: str) -> Dict[str, Any]:
request = bank_query_pb.QueryDenomMetadataRequest(denom=denom)
response = await self._execute_call(call=self._stub.DenomMetadata, request=request)

return response

async def fetch_denoms_metadata(self, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
pagination_request = None
if pagination is not None:
pagination_request = pagination.create_pagination_request()
request = bank_query_pb.QueryDenomsMetadataRequest(pagination=pagination_request)
response = await self._execute_call(call=self._stub.DenomsMetadata, request=request)

return response

async def fetch_denom_owners(self, denom: str, pagination: Optional[PaginationOption] = None) -> Dict[str, Any]:
pagination_request = None
if pagination is not None:
pagination_request = pagination.create_pagination_request()
request = bank_query_pb.QueryDenomOwnersRequest(denom=denom, pagination=pagination_request)
response = await self._execute_call(call=self._stub.DenomOwners, request=request)

return response

async def fetch_send_enabled(
self,
denoms: Optional[List[str]] = None,
pagination: Optional[PaginationOption] = None,
) -> Dict[str, Any]:
pagination_request = None
if pagination is not None:
pagination_request = pagination.create_pagination_request()
request = bank_query_pb.QuerySendEnabledRequest(denoms=denoms, pagination=pagination_request)
response = await self._execute_call(call=self._stub.SendEnabled, 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)
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
Loading

0 comments on commit ffd1928

Please sign in to comment.