degenbot.erc20 ============== .. py:module:: degenbot.erc20 .. autoapi-nested-parse:: ERC-20 token with on-chain metadata and balance tracking. Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/degenbot/erc20/erc20/index /autoapi/degenbot/erc20/ether_placeholder/index Package Contents ---------------- .. py:data:: UNKNOWN_DECIMALS :value: 18 .. py:data:: UNKNOWN_NAME :value: 'Unknown Token' .. py:data:: UNKNOWN_SYMBOL :value: 'UNKNOWN' .. py:class:: Erc20Token(*args: Any, **kwargs: Any) Bases: :py:obj:`degenbot.types.abstract.AbstractErc20Token` An ERC-20 token contract. Constructed from pre-fetched data only. Use ``Bot.build_erc20token()`` to fetch from chain. Balance, approval, and total supply queries go through ``Bot.get_token_balance()`` etc. .. py:method:: from_handle(py_token: degenbot._ffi.Erc20Token, *, oracle_address: str | None = None, state_cache_depth: int = 8) -> Self :classmethod: Wrap a Rust-owned ``_TokenHandle`` handle as a Python companion. Internal seam (ADR-005, Polars-style ``_from_pydf`` pattern). Rust owns the token metadata (address, name, symbol, decimals, chain_id) as a ``TokenEntry``; this companion reads it through ``self._py_token`` on every access and holds no metadata copy. Price oracle + balance/approval/total-supply caches stay Python (I/O constructs that cannot move to Rust). Only ``Bot.get_token()`` / ``Bot.build_erc20token()`` (production) and ``make_erc20`` (tests) should call this — they have already registered the token metadata in a ``Bot`` and obtained the handle. ``cls`` is used so subclasses that only set ClassVars inherit this seam and produce instances of the subclass. :returns: A ``cls`` instance wrapping ``py_token``. .. py:property:: address :type: degenbot.types.chain.ChecksummedAddress Token contract address (EIP-55 checksum). Rust holds the address bytes; ``get_checksum_address`` applies the codebase-wide EIP-55 display convention. .. py:property:: name :type: str Token name (read from Rust-owned ``TokenEntry``). .. py:property:: symbol :type: str Token symbol (read from Rust-owned ``TokenEntry``). .. py:property:: decimals :type: int Token decimals (read from Rust-owned ``TokenEntry``). .. py:method:: get_cached_balance(address: degenbot.types.chain.ChecksummedAddress, block_number: int) -> int | None Return cached balance. :returns: The computed value. .. py:method:: set_cached_balance(address: degenbot.types.chain.ChecksummedAddress, block_number: int, balance: int) -> None Set cached balance. .. py:method:: get_cached_approval(block_number: int, owner: degenbot.types.chain.ChecksummedAddress, spender: degenbot.types.chain.ChecksummedAddress) -> int | None Return cached approval. :returns: The computed value. .. py:method:: set_cached_approval(block_number: int, owner: degenbot.types.chain.ChecksummedAddress, spender: degenbot.types.chain.ChecksummedAddress, amount: int) -> None Set cached approval. .. py:method:: get_cached_total_supply(block_number: int) -> int | None Return cached total supply. :returns: The computed value. .. py:method:: set_cached_total_supply(block_number: int, total_supply: int) -> None Set cached total supply. .. py:property:: price :type: float Price. :raises NoPriceOracle: See function documentation. .. py:property:: chain_id :type: int Chain ID (read from Rust-owned ``TokenEntry``). .. py:class:: EtherPlaceholder Bases: :py:obj:`degenbot.erc20.Erc20Token` An Erc20Token-like adapter for the 'all Es' or zero address placeholder. Used by pools to represent native Ether. Under ADR-005, metadata (name="Ether Placeholder", symbol="ETH", decimals=18) is registered in the Rust ``Bot`` when an ``EtherPlaceholder`` is built; the inherited delegating properties read it back through the Rust ``Erc20Token`` handle. Direct construction is forbidden (inherited from :class:`Erc20Token`). Use :meth:`Erc20Token.from_handle` — which produces an ``EtherPlaceholder`` instance when called on the subclass — after registering the metadata in a ``Bot``. .. py:attribute:: addresses