Skip to content

v0.1.0 — LangChain tools for ERC-20 primitives as execution

Choose a tag to compare

@Conrad-sudo Conrad-sudo released this 07 Aug 08:00
· 5 commits to main since this release

LangChain tools for ERC-20 primitives, usable by an EOA or by any smart-contract wallet.

Every write tool returns an ordered execution plan rather than a bare transaction, because (to, value, data) is the last point at which every account type still agrees — an EOA transaction is that plus nonce/gas/fees, an ERC-7579 Execution is exactly that, and an ERC-4337 UserOp wraps a batch of them.

Install

pip install langchain-erc20

Added

15 tools. Reads: get_token_metadata, get_balance, get_native_balance, get_allowance, is_balance_sufficient, is_allowance_sufficient, supports_permit. Writes: transfer, transfer_all, transfer_from, batch_transfer, approve, revoke_approval, wrap_native, unwrap_native.

Two execution modes. tx_mode="eoa" (default) also renders signable transactions with sequential nonces. tx_mode="calls" returns account-agnostic calls only and makes zero nonce/gas/fee RPC calls — a 4337 nonce is EntryPoint.getNonce(sender, key), not an EOA transaction count, and eth_estimateGas with from set to a smart account simulates the account calling itself as an EOA, so the number is wrong even when it succeeds.

Token references. Every token argument accepts an address or a symbol from a registry you supply. No token addresses are bundled: a wrong address in one is a silent, unrecoverable loss of funds.

Amounts. Accepted as float or str and converted through Decimal. Strings are preferred and documented as such, because a float cannot hold 18 decimal places. Conversion truncates toward zero and never rounds up, and reports amount_truncated when precision was actually lost. Every write tool also accepts amount_base for exact base units.

Token compatibility

The standard is a suggestion in practice. Each of these is a real token that breaks a naive implementation, and each is handled and tested:

  • USDT, BNB, OMG — transfer/approve return nothing. Write functions are only ever encoded, never called, so empty returndata is never decoded. ERC20_NO_RETURN_ABI is exported for consumers who dry-run writes themselves.
  • USDT — approve reverts while a non-zero allowance stands. zero_first_approvals="auto" reads the allowance and emits [approve_reset, approve] when needed, which also closes the generic front-running window.
  • MKR and most pre-2018 tokens — name/symbol return bytes32. Retried against a bytes32 ABI; unreadable metadata becomes null rather than failing the call.
  • Tokens without decimals() — never assumed to be 18. Raises and points at decimals_overrides, because guessing 18 on a 6-decimal token sends 10¹² times the intended amount.
  • UNI — stores allowances in 96 bits. unlimited=True encodes exactly 2**256 - 1; anything above the uint256 ceiling raises before encoding rather than surfacing web3's MismatchedABI.
  • Fee-on-transfer and rebasing tokens — summaries say amount_sent, never amount_received. transfer_all records balance_read_at_block and warns its fixed amount can go stale.

Supported chains for wrapped-native

Ethereum, Sepolia, Optimism, BSC, Polygon, Base, Arbitrum, Avalanche.

Every address is verified against the live chain by scripts/verify_networks.py, which checks bytecode, symbol(), decimals() and the presence of deposit()/withdraw(uint256), following EIP-1967 proxies where needed. Everything except wrap_native/unwrap_native works on any EVM chain.

Celo is deliberately absent: CELO is natively an ERC-20 with no wrapping step, so for_chain(42220) fails loudly rather than guessing.

Known limitations

  • Preflight is not a guarantee. It checks balances and allowances only. Blocklists, pauses, transfer hooks and reentrancy are not detectable in advance.
  • EIP-2612 permit is detected but not yet implemented. supports_permit reports eip2612, dai, unknown or null so a DAI-style token fails loudly instead of being silently encoded against the wrong signature. The signing flow lands in a later release. Permit is also effectively EOA-only, since ecrecover cannot validate a smart-contract signature.
  • No live-network test suite yet. All 337 tests run against mocks configured to behave like the real tokens named above.

Verification

337 tests on Python 3.10–3.13, with ruff and pyright clean in CI.