metadata.json generator
This commit is contained in:
@@ -77,6 +77,7 @@ def upgrade() -> None:
|
||||
op.create_table('token',
|
||||
sa.Column('chain', dexorder.database.column_types.Blockchain(), nullable=False),
|
||||
sa.Column('address', dexorder.database.column_types.Address(), nullable=False),
|
||||
sa.Column('name', sa.String(), nullable=False),
|
||||
sa.Column('symbol', sa.String(), nullable=False),
|
||||
sa.Column('decimals', sa.SMALLINT(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('chain', 'address')
|
||||
|
||||
75
src/dexorder/bin/metadata.py
Normal file
75
src/dexorder/bin/metadata.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
from dexorder import db
|
||||
from dexorder.configuration import parse_args
|
||||
from dexorder.database.model import Pool, Token
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
token_map: dict[str,Token] = {}
|
||||
|
||||
|
||||
def dump(*args):
|
||||
print(*args, end='')
|
||||
|
||||
|
||||
def json_dump(**kwargs):
|
||||
dump(json.dumps(dict(**kwargs),separators=(',', ':')))
|
||||
|
||||
def dump_tokens():
|
||||
first = True
|
||||
for token in db.session.scalars(select(Token)):
|
||||
token: Token
|
||||
token_map[token.address] = token
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
dump(',')
|
||||
json_dump(
|
||||
a=token.address,
|
||||
n=token.name,
|
||||
s=token.symbol,
|
||||
d=token.decimals,
|
||||
)
|
||||
|
||||
|
||||
def dump_pools():
|
||||
first = True
|
||||
for pool in db.session.scalars(select(Pool)):
|
||||
pool: Pool
|
||||
if first:
|
||||
first = False
|
||||
else:
|
||||
dump(',')
|
||||
json_dump(
|
||||
a=pool.address,
|
||||
b=pool.base,
|
||||
q=pool.quote,
|
||||
f=pool.fee,
|
||||
e=pool.exchange.value,
|
||||
d=pool.decimals,
|
||||
)
|
||||
|
||||
def generate_metadata():
|
||||
dump('{"t":[')
|
||||
dump_tokens()
|
||||
dump('],"p":[')
|
||||
dump_pools()
|
||||
dump(']}')
|
||||
|
||||
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO, stream=sys.stderr)
|
||||
log.setLevel(logging.DEBUG)
|
||||
parse_args()
|
||||
db.connect(migrate=False)
|
||||
generate_metadata()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -26,3 +26,4 @@ class Config:
|
||||
deployments: Optional[dict[str,str]] = field(default_factory=dict)
|
||||
min_gas: str = '0'
|
||||
|
||||
tokens_dir: str = '.'
|
||||
|
||||
@@ -14,6 +14,7 @@ class TokenDict (TypedDict):
|
||||
type: str
|
||||
chain: int
|
||||
address: str
|
||||
name: str
|
||||
symbol: str
|
||||
decimals: int
|
||||
|
||||
@@ -25,6 +26,7 @@ class Token (Base):
|
||||
|
||||
chain: Mapped[Blockchain] = mapped_column(primary_key=True)
|
||||
address: Mapped[Address] = mapped_column(primary_key=True)
|
||||
name: Mapped[str]
|
||||
symbol: Mapped[str]
|
||||
decimals: Mapped[Uint8]
|
||||
|
||||
@@ -32,10 +34,10 @@ class Token (Base):
|
||||
@staticmethod
|
||||
def load(token_dict: TokenDict) -> 'Token':
|
||||
return Token(chain=Blockchain.get(token_dict['chain']), address=token_dict['address'],
|
||||
symbol=token_dict['symbol'], decimals=token_dict['decimals'])
|
||||
name=token_dict['name'], symbol=token_dict['symbol'], decimals=token_dict['decimals'])
|
||||
|
||||
|
||||
def dump(self):
|
||||
return TokenDict(type='Token', chain=self.chain.chain_id, address=self.address,
|
||||
symbol=self.symbol, decimals=self.decimals)
|
||||
name=self.name, symbol=self.symbol, decimals=self.decimals)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from eth_abi.exceptions import InsufficientDataBytes
|
||||
@@ -11,7 +12,7 @@ from dexorder.database.model.token import TokenDict
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def get_token(address):
|
||||
async def get_token(address) -> TokenDict:
|
||||
try:
|
||||
return address_metadata[address]
|
||||
except KeyError:
|
||||
@@ -21,13 +22,13 @@ async def get_token(address):
|
||||
|
||||
async def load_token(address: str) -> TokenDict:
|
||||
contract = ERC20(address)
|
||||
symbolProm = contract.symbol()
|
||||
prom = asyncio.gather(contract.name(), contract.symbol())
|
||||
try:
|
||||
decimals = await contract.decimals()
|
||||
except (InsufficientDataBytes, ContractLogicError, BadFunctionCallOutput):
|
||||
log.warning(f'token {address} has no decimals()')
|
||||
decimals = 0
|
||||
symbol = await symbolProm
|
||||
log.debug(f'new token {symbol} {address}')
|
||||
name, symbol = await prom
|
||||
log.debug(f'new token {name} {symbol} {address}')
|
||||
return TokenDict(type='Token', chain=current_chain.get().chain_id, address=address,
|
||||
symbol=symbol, decimals=decimals)
|
||||
name=name, symbol=symbol, decimals=decimals)
|
||||
|
||||
Reference in New Issue
Block a user