Repository navigation
v0.3.0 — gas_estimated moves onto the plan
What changed
Breaking: gas_estimated has moved out of each transaction dict and onto the plan.
render_eoa used to write a gas_estimated bool into every transaction. eth_account validates
the dict it is handed and rejects any key it does not recognise, so the transactions a plan returned
could not be signed as returned:
acct.sign_transaction(plan["transactions"][0])
# TypeError: Unknown kwargs: ['gas_estimated']The README worked around it in prose, telling you to pop the key first. That put a preparation step
in front of the first thing every EOA consumer does, and pointed the traceback at eth_account
rather than at this package.
"Did this limit come from a live estimate" is not a field an Ethereum transaction has. It is
provenance about the plan, so it now travels beside the transactions:
plan["transactions"][i] # signs exactly as returned, no preparation
plan["gas_estimated"][i] # same index, same answerplan["gas_estimated"] is a list of one bool per transaction, and None in calls mode — nothing
was estimated there, so [] or [False, ...] would both assert something untrue.
Migrating
Read plan["gas_estimated"][i] instead of plan["transactions"][i]["gas_estimated"]. If you
followed the old README and pop the key, use the tolerant form — the strict tx.pop("gas_estimated")
now raises KeyError:
tx.pop("gas_estimated", None) # or just delete the lineConsumers in tx_mode="calls" are unaffected: they read plan["calls"] and never rendered
transactions.
Also in this release
- Reverts are reported as sentences. A refused plan now says
Transfer 1000000.0 USDC to 0x7a25... would revert: execution reverted: ERC20: transfer amount exceeds balance.Previously this was web3's exception repr, which for a custom error printed the
same hex string twice and named neither the call nor the error. The six OpenZeppelin v5 ERC-20
custom errors decode by name; an unregistered selector says so rather than guessing. tx_mode="calls"now simulates the first call with oneeth_call, so "a plan certain to
revert is never built" holds for smart accounts and not only for EOAs, which get it free from gas
estimation. A sender with no code deployed yet is skipped, andestimate_gas=Falseturns
simulation off in both modes. This catches what thepreflightflag's balance and allowance reads
cannot: blocklists, pauses and transfer hooks.ERC20_ERRORS_ABIis exported for consumers decoding reverts of their own.
Compatibility
The same plans.py is mirrored in langchain-erc8004 and langchain-uniswap-v2; both already
carry this change, so the plan shape is now identical across all three.