degenbot.builders.erc20_builder =============================== .. py:module:: degenbot.builders.erc20_builder .. autoapi-nested-parse:: ERC-20 token builder that fetches on-chain metadata. Module Contents --------------- .. py:class:: Erc20Builder(*, default_chain_id: degenbot.types.aliases.ChainId | None = None, tokens: degenbot.registry.TokenRegistry, py_bot: degenbot._ffi.Bot) Builds Erc20Token instances from Rust-backed metadata and RPC calls. Owns the companion I/O choreography: check the registry → ask the Rust construction core for metadata → wrap and register the token. .. py:method:: build(address: str, *, chain_id: degenbot.types.aliases.ChainId | None = None, silent: bool = False, io: degenbot._ffi.BotIo | None = None) -> degenbot.erc20.erc20.Erc20Token Construct an ERC-20 token, delegating metadata resolution to the Rust core. The DB-first + on-chain resolution, write-back and `BotState` registration are Rust-owned: `Bot.build_erc20_token` runs `build_erc20_metadata` over the attached `ConstructionIo`. This Python shell keeps only the *companion* concerns: the `TokenRegistry` idempotent short-circuit, the `EtherPlaceholder` special case, and the `Erc20Token.from_handle` display wrapper. The `io` argument is a retained compat shim (ignored — the Bot owns the `ConstructionIo`); it is stripped when `BotIo` retires. :returns: The computed value. :raises DegenbotValueError: No contract is deployed at the address, or the token metadata could not be resolved on-chain. .. py:method:: build_many(addresses: collections.abc.Sequence[str], *, chain_id: degenbot.types.aliases.ChainId | None = None, silent: bool = False, io: degenbot._ffi.BotIo | None = None) -> list[degenbot.erc20.erc20.Erc20Token] Build MANY tokens, batching metadata reads into ONE Multicall3 read. Preserves :meth:`build`'s per-token semantics — registry fast path, Ether placeholder, DB lookup, alternate-prototype fallback — but when 2+ tokens need a network metadata fetch it issues ONE ``io.fetch_erc20_metadata_batch([...])`` instead of N separate ``fetch_erc20_metadata`` round-trips. A token whose batched metadata came back ``None`` falls back to per-token :meth:`build` (so the contract-deployed check + alternate-prototype fallback still apply). :returns: One :class:`Erc20Token` per input address, in order. .. py:method:: get_token_balance(token: degenbot.erc20.erc20.Erc20Token, address: str, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None, *, io: degenbot._ffi.BotIo | None = None) -> int Retrieve the ERC-20 balance for the given address. :returns: The computed value. .. py:method:: get_token_approval(token: degenbot.erc20.erc20.Erc20Token, owner: str, spender: str, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None, *, io: degenbot._ffi.BotIo | None = None) -> int Retrieve the amount that can be spent by `spender` on behalf of `owner`. :returns: The computed value. .. py:method:: get_token_total_supply(token: degenbot.erc20.erc20.Erc20Token, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None, *, io: degenbot._ffi.BotIo | None = None) -> int Retrieve the total supply for this token. :returns: The computed value. .. py:method:: get_ether_balance(chain_id: degenbot.types.aliases.ChainId, address: str, block_identifier: degenbot.types.rpc_types.BlockIdentifier | None = None, *, io: degenbot._ffi.BotIo | None = None) -> int Retrieve the native ETH balance for the given address. :returns: The computed value.