Claude Skill

cli-cast

Imported from paulrberg/agent-skills/skills/cli-cast.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download paulrberg-agent-skills-skills_cli-cast-913232a.zip · 20 KB
Part of paulrberg/agent-skills — 42 skills

Install

skills CLI npx skills add https://github.com/PaulRBerg/agent-skills/tree/main/skills/cli-cast
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install paulrberg-agent-skills@llmmart
Git git clone https://github.com/PaulRBerg/agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole paulrberg/agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Foundry Cast CLI

This skill is coordination-exempt: skip the ai-coord gate for its declared work.

Separate read, preparation, simulation, signing, and broadcast so no state-changing action is hidden inside command construction.

For EIP-7702 authorization or delegation revocation, read references/eip7702.md before preparation. It defines signer selection, authority versus transaction sender, conditional staged approval, and authorization verification in addition to the transaction receipt.

Resolve Chain and Provider

Invoke $evm-atlas before every network operation. It owns chain resolution, discrete reads, and bounded live subscriptions. Pass the explicit chain name or ID, JSON-RPC method and exact parameters or call object, block selector or checkpoint requirement, and why the result is needed. Require its read packet containing the resolved chain name and ID, provider route, result, observed block or checkpoint, and coverage gaps.

If the chain is absent from evm-atlas, stop RPC-dependent work. Do not accept an arbitrary RPC URL as an escape hatch and never infer Ethereum when the chain is ambiguous.

Use an RPC URL in this skill only for a trace, fork, or send flow that cannot be expressed as bounded discrete reads. For RouteMesh-backed continuous transport, first require evm-atlas to confirm current RouteMesh coverage, then use the explicit Foundry alias when it is configured:

ROUTEMESH_CHAIN_ID="$CHAIN_ID" cast COMMAND --rpc-url routemesh

Otherwise use the nonsecret public RPC verified by evm-atlas. Never construct, inspect, or print a RouteMesh URL. Treat Cast stderr as secret-bearing because Foundry may reveal a resolved alias URL on transport failure; never repeat that output in chat, logs, or external reports.

Resolve every RPC value from evm-atlas's current read packet or the RouteMesh alias above; hard-coding a public RPC URL, such as a literal https:// endpoint typed from memory or a prior response, in a prepare, simulate, or verify command violates this delegation even when the chain matches. When a local cast command against that provider returns a --json hex quantity, decode it with cast to-dec <hex> or a field-select form such as cast receipt <hash> <field> or cast tx <hash> <field>; do not pipe --json output through jq tonumber, which fails on hex strings and on null.

Authority Phases

Read

Local ABI encoding/decoding and selector derivation may run without transaction approval. Delegate chain, block, fee, nonce, eth_call, eth_estimateGas, transaction, receipt, log, balance, code, storage, proof, and ENS reads to $evm-atlas, including reads needed to prepare or verify a transaction. Do not ask evm-atlas to hand a read back to this skill merely because later work may change state.

Use env -i PATH="$PATH" cast <command> --help for exact local syntax. Cast help can print inherited environment values, including API keys; do not load credentials or decrypted dotenv for capability checks. Typical local operations:

cast calldata 'transfer(address,uint256)' "$TO" "$AMOUNT"
cast decode-calldata 'transfer(address,uint256)' "$CALLDATA"

Prepare

Resolve and validate chain ID, sender, target, function signature, arguments, calldata, native value, nonce, and fee assumptions without signing. Obtain every on-chain fact through evm-atlas; do not request or load key material during preparation. Select a supported signer under Sign and Broadcast and check its command capabilities before simulation or helper construction.

Request both the confirmed nonce at the numeric checkpoint block and the pending nonce. When they differ, or a wallet reports replacement transaction underpriced, a queued transaction occupies the lowest unconfirmed nonce, and later nonces stay stuck behind it. Target that nonce with fees that clear the node's replacement bump, usually 10-20% on both the fee cap and the tip, instead of queueing another transaction behind it.

For Ethereum mainnet, the default gas policy is references/ethereum-gas.md: fetch a fresh Rabby slow quote and bind its EIP-1559 fee pair before simulation. The user or a consuming skill may explicitly choose a different gas policy, including a fixed legacy gas price for an exact-zero sweep. Honor that choice; it does not require a separate policy-exception approval. Record its source, transaction type, fee values, and any constraints in the transaction review. Apply the selected policy to every signer and do not silently substitute a different tier or transaction type. Do not reuse Ethereum fee values on another chain.

Elsewhere, absent a selected policy, set an EIP-1559 max fee with headroom over the latest base fee, such as 2 * baseFee + priorityFee, instead of passing eth_gasPrice as the cap. The charge stays base fee plus tip, while an exact cap can fall below the base fee before signing and force a revised review.

Chain-specific gas accounting

Resolve the chain's active fee model before choosing a transaction type or subtracting fees from a balance. Use current official protocol documentation for semantics and $evm-atlas for the target chain's parameters, fee-oracle calls, estimates, and receipts. EVM compatibility, a native symbol of ETH, and support for legacy transactions do not establish Ethereum fee semantics. A chain absent from atlas remains unsupported.

For the exact transaction, retain a public fee record containing the chain/checkpoint, active fork and sources, transaction type, gas estimate and limit, price/caps, expected total fee, upfront fee reserve with each component and margin, and refund behavior. Identify which charges are included in estimated gas and which are additional native debits. Use arbitrary-precision integer arithmetic and round reserves up. Never count a component twice or subtract an anticipated refund from the upfront funding requirement. Re-estimate when value, calldata, nonce, type, gas, or fees change; serialization can change the L1 charge even for an empty-calldata transfer.

  • Ethereum-style accounting: establish that all fees for this transaction are covered by gas. Reserve gasLimit * gasPrice for legacy, or gasLimit * maxFeePerGas for EIP-1559. Actual cost uses receipt gasUsed and effectiveGasPrice. Exact-zero native sweeps require evidence of a fixed charged price, fixed gas used, and no additional charges or credits; a plain undelegated EOA transfer on Ethereum with empty calldata and legacy pricing can use exactly 21000 gas. Do not apply that constant to other fee models.
  • Arbitrum Nitro: use the complete eth_estimateGas result, or NodeInterface.gasEstimateComponents() through atlas. It includes the parent-chain posting charge converted into child-chain gas. Budget the full gas limit at the reviewed price cap; do not add a second L1 fee. Legacy transactions are supported, but their charged price depends on the active ArbOS version and tip-collection setting. Verify that behavior through atlas and the current fee processor: newer versions make tip collection configurable. When tips are disabled, prefer EIP-1559 with zero priority fee; legacy bids and equal caps still charge the inclusion base fee. When tips are collected, apply the active effective-price rules. A fixed charged price alone does not fix the variable posting-gas component or prove an exact-zero sweep. Reconcile unused gas/price headroom against the reviewed residual policy. Use receipt gasUsed * effectiveGasPrice for total cost; gasUsedForL1 is an included gas component, not an extra wei charge. See gas and fees and estimation.
  • OP Stack: reserve execution gas plus the L1 data fee and any enabled operator fee. Through atlas, query the verified GasPriceOracle for getL1Fee(bytes) using the serialized unsigned transaction, and, where supported, getL1FeeUpperBound(uint256) using its unsigned byte length. These interfaces account for signature overhead; do not add it twice. The latter is a practical size bound at the current oracle prices, not a cap on fees at inclusion. Query getOperatorFee(gasLimit) for upfront budgeting and reconstruct the included operator charge using the inclusion fork's parameters, gas use, and exact client rounding/refund semantics. Before Isthmus it is absent; Isthmus and Jovian use different scalar formulas. Establish absence from fork/configuration evidence, not a failed call or a missing provider field. Receipt total is execution cost plus l1Fee plus operator cost, each once. See transaction fees, Fjord oracle, Isthmus operator accounting, and Jovian changes.
  • Other models, including ZKsync: obtain the current chain-native estimator and receipt semantics through atlas and official docs. Establish coverage of pubdata, resource overhead, custom debits, and refunds for the actual transaction type. Use an ordinary type 0/2 transfer only if the chain and browser transport support it with complete fee coverage. Do not substitute a deprecated estimator or add custom transaction fields without a supported signing path. ZKsync's fee structure includes pubdata/overhead and refunds; neither 21000 gas nor exact-zero accounting follows from EVM compatibility. Stop with the missing component when complete accounting cannot be established.

On chains with fees outside transaction caps, label the total as an estimated reserve, disclose the uncovered price movement, and recheck affordability immediately before signing. A margin is not a protocol-enforced maximum. Require value + upfront fee reserve <= balance; ordinary gas estimation or a successful eth_call alone does not prove this. If final wallet fee edits are allowed, recompute dependent additional fees and affordability from those values. Sweeps whose value depends on the reserve must preserve all reviewed fields under the fixed-fee exception below.

Refunded or unspent gas is normally already reflected in the final charged fee and sender balance; do not subtract it again. Treat asynchronous refunds, such as Arbitrum retryable tickets, separately: never spend an expected credit before it arrives or claim a snapshot balance is permanent. Discovery of unrelated pending refunds is not implicit in a plain transfer. A consuming sweep must state its residual-balance policy and any known pending credits before approval.

Simulate

Simulate the exact prepared call, preserving sender, target, value, calldata, nonce, transaction type, gas limit, and fee fields, then estimate gas. Delegate bounded eth_call and eth_estimateGas evidence to evm-atlas. When an RPC error contradicts the supplied gas or checkpointed balance, have atlas diagnose the exact simulation path before attributing it to transaction invalidity or chain-wide type support. Changing fields to make a diagnostic call pass does not validate the prepared transaction. Preserve the consuming workflow's simulation and approval requirements. Use a local fork, project simulation, or Cast trace only when the simulation requires a continuous provider, following Resolve Chain and Provider. A successful simulation is evidence, not authorization to sign.

When exact EIP-7702 simulation needs a signed authorization, use the reference's approved authorization-signing stage first; transaction signing and broadcast still follow simulation and transaction approval.

Review

Before a transaction signature or broadcast, present one concrete review containing:

  • chain name and ID, RPC source, and latest block used;
  • sender, target, function, decoded arguments, calldata, and native value;
  • nonce, gas estimate/limit, fee assumptions, expected total cost, upfront reserve, and any protocol-enforced fee caps;
  • chain-specific fee components, inclusion-price uncertainty outside those caps, and expected refunds or residuals;
  • the selected gas policy and source; for Rabby Slow, the oracle URL, tier, quote time, estimated inclusion time, max fee per gas, and max priority fee per gas; for a legacy policy, the fixed gas price and transaction type;
  • expected approvals, transfers, or other state changes;
  • simulation command and outcome;
  • selected signer and the exact signing/broadcast command with secrets redacted.

Lead the review with ### ⚠️ Transaction approval required. Put repeated fields in a compact table, keep the exact command in a fenced block, and state precisely what confirmation authorizes. Stop and require explicit user confirmation of this review in a subsequent message. If any reviewed field changes outside the browser-wallet exception below, simulate again and present a revised review. Existing explicit approval of the concrete payload and its stated use remains valid; EIP-7702 authorization signatures follow the reference's conditional staged review.

For browser signing only, the reviewed gas limit and fees are starting values unless the consuming workflow requires them to remain fixed. The user may deliberately change the gas limit, gas price, max fee per gas, or max priority fee per gas in the wallet confirmation UI. Their approval of that final wallet screen authorizes those edited gas settings; apply chain-specific accounting to the additional fees and resulting affordability. Do not stop, require a second approval, or resimulate solely because they differ from the prepared values. Continue only when the chain, sender, target, calldata, native value, nonce, authorization list (if present), and decoded intent still match the approved review. Wallet changes to any of those fields require rejection and a revised review.

When fees determine the transfer value or another reviewed invariant, such as leaving exactly zero native balance, the browser exception does not apply. Preserve the reviewed transaction type, gas limit, and fee values. If the wallet changes them, reject before signing, recompute the dependent values, simulate, and obtain approval of the revised review.

Sign and Broadcast

Read references/browser-signing.md for browser capability checks and sender handling; open a signing request only after approval. Prefer browser, encrypted keystore, or hardware wallet in that order unless the user or consuming skill restricts the signer. A browser-only workflow must stop if browser signing is unavailable; never substitute another signer. Use an environment-backed private key only when the user explicitly opts in or no safer method is available; never ask for a key in chat or print it.

cast send signs and broadcasts in one command. Run it only after the review approval. So do the Cast 1.8.3+ helpers cast erc20-token transfer|approve|mint|burn, cast erc20-token permit --broadcast, cast erc4626 deposit|mint|withdraw|redeem, and cast safe propose|sign|execute: apply the same Prepare, Simulate, and Review phases to them; a Safe proposal or confirmation is a signature artifact that needs its own payload review. Treat any other subcommand whose installed help shows it signs or submits, such as cast safe create, add-delegate, or remove-delegate, the same way. Signing a message or typed data, including cast erc20-token permit without --broadcast, also requires a review of the exact payload, domain, chain binding, and intended use before approval.

Pass the selected fees explicitly: EIP-1559 uses --gas-price and --priority-gas-price; a fixed legacy policy uses --legacy --gas-price without --priority-gas-price. Under the default Ethereum policy, use the approved Rabby Slow pair. Before opening the signer, recheck the active chain's gas and additional-fee requirements and that the approved cap or legacy gas price covers its current base fee where applicable. If fees must change before signing, simulate again and present a revised review; never silently change the selected policy. Wallet fee edits follow Review, including its fixed-fee exception. Message and typed-data signatures consume no gas.

After broadcast, capture the transaction hash and have evm-atlas verify the receipt on the reviewed chain. When a receipt is still pending, it may use one bounded RouteMesh newHeads subscription to wait for the next block before checking again. Receipt verification remains required; a pending-transaction or log notification alone cannot confirm the transaction. Reconcile actual fees under the active chain's model, including additional receipt components and refunds without double counting. Missing fee evidence is incomplete accounting, not zero fees. Report status, block, gas used, actual total fee or its exact evidence gap, and the explorer link under ### ✅ Transaction confirmed for a successful receipt or ### ↩ Transaction reverted for a mined failure. For an ambiguous outcome, lead with ### ⛔ Broadcast unresolved — do not retry and state the evidence still needed. Do not retry a failed or uncertain broadcast without first checking whether the transaction exists — for browser-wallet signing specifically, read references/browser-signing.md's Timing and Recovering sections before concluding nothing was sent: a killed or timed-out process does not prove non-broadcast, since wallet approval is an unbounded human wait and the wallet may broadcast via its own RPC provider.

Stop Conditions

Stop before signing when the signer, sender, chain, target, or decoded intent is unresolved. Transaction signing also requires resolved fee accounting, affordability, and simulation. Only the explicitly approved EIP-7702 authorization stage may precede those transaction checks; its authorization payload, signer, and intended use must already be resolved. Review must distinguish enforced caps from an estimated reserve; browser approval of edited gas settings authorizes those settings but does not establish coverage of omitted chain-specific charges. Stop before retrying when broadcast outcome is ambiguous. Completion requires either a verified read result, a local encoding result, an approved signature artifact, or a mined receipt verified by evm-atlas that matches the reviewed transaction apart from user-approved browser-wallet gas settings. Never decorate or truncate addresses, calldata, signatures, hashes, RPC URLs, fee values, commands, or safety wording. Revocation completion additionally requires the authorization and cleared-code checks in references/eip7702.md.

Files (agent-skills)
  • agents
    • openai.yaml 42 B
      policy:
        allow_implicit_invocation: true
      
  • references
    • browser-signing.md 10.9 KB
      # Browser Wallet Signing
      
      Check capabilities and establish the public sender during preparation. Open a signing request only after the transaction
      or message review in `SKILL.md` has been explicitly approved.
      
      ## Availability
      
      Confirm the installed Cast supports browser signing:
      
      ```sh
      CAST_SEND_HELP=$(env -i PATH="$PATH" cast send --help) || exit 1
      printf '%s\n' "$CAST_SEND_HELP" | rg --no-config -- '--browser'
      ```
      
      Check the help command's exit status as well as the match. Use a clean environment for help output because Cast may
      print environment-backed credential defaults. Browser support is specific to each subcommand; `send --browser` does not
      imply `wallet address --browser` or `wallet sign --browser` exists.
      
      If unavailable in a browser-only workflow, stop without a signer fallback. Otherwise the signer preferences in
      `SKILL.md` apply. Browser signing requires an interactive browser and local port `9545`; it does not work in ordinary
      headless CI or SSH sessions.
      
      ### EIP-7702 Authorization Boundary
      
      Read [eip7702.md](eip7702.md) before preparing delegation or revocation. Check `cast wallet sign-auth --help` in a clean
      environment separately: `send --browser` does not establish authorization-signing support. When `sign-auth` lacks
      browser support, a browser-only request needing a new authorization is blocked before opening a signer. Report the
      missing capability and supported next step; never substitute message/typed-data signing or introduce secret-entry
      automation. A different signer requires authorization under the user's signer constraints.
      
      An already approved, verified authorization can accompany `cast send --auth "$SIGNED_AUTH" --browser` when the installed
      Cast and connected wallet support that type-4 transaction. The browser signs the outer transaction as its sender/fee
      payer; the authorization's recovered authority may differ. An address-valued `--auth` needs a local signer and cannot
      obtain a new authorization through the browser sender. Preserve the full reviewed authorization list and transaction
      type in the wallet; reject unsupported transport, dropped tuples, or substituted authorizations. Apply the existing
      fee-edit exception only to gas settings. Verify authorization application and account code after inclusion as well as
      the receipt.
      
      ## Resolve the Sender
      
      Use the public address supplied by the user or already known from the connected wallet as `OWNER` for preparation.
      Resolve ENS through `$evm-atlas`. Do not load key material to discover an address. Use `cast wallet address --browser`
      only if that exact subcommand's current help exposes `--browser`; otherwise ask for the public address.
      
      `cast send --browser` does not enforce `--from` or `--nonce`: the wallet signs with its active account and may
      substitute that account's nonce, so a mismatch broadcasts from the wrong sender. Immediately before each approved
      broadcast, run `cast wallet address --browser` (when its help exposes `--browser`) and require the result to equal the
      reviewed `OWNER`; otherwise have the user confirm the active wallet account first. On a mismatch, stop and ask the user
      to switch accounts; an account change requires a revised review. After broadcast, verify the transaction's `from` and
      nonce against the review as part of receipt verification.
      
      ## Approved Broadcast
      
      Run the exact reviewed command, for example:
      
      ```sh
      cast send "$CONTRACT" 'transfer(address,uint256)' "$TO" "$AMOUNT" \
        --rpc-url "$RPC_URL" \
        --from "$OWNER" \
        --gas-price "$RABBY_SLOW_MAX_FEE_WEI" \
        --priority-gas-price "$RABBY_SLOW_PRIORITY_FEE_WEI" \
        --async \
        --browser
      ```
      
      `$RPC_URL` is the reviewed continuous-provider transport selected under `SKILL.md`; never use it for a standalone read.
      
      The example uses the default Ethereum fee policy. Use the user- or consumer-selected policy from `SKILL.md` when one is
      specified. For a fixed legacy policy, replace the fee pair with `--legacy --gas-price "$GAS_PRICE"` and preserve the
      reviewed gas limit. Do not pass EIP-1559 priority-fee flags with a legacy transaction.
      
      Unless the reviewed workflow fixes its fees, the user may deliberately edit the gas limit, gas price, max fee per gas,
      or max priority fee per gas in Rabby's confirmation UI, including by selecting a different tier. Treat their approval of
      the final wallet screen as authorization for those gas settings. Apply `SKILL.md`'s chain-specific accounting to the
      resulting reserve, additional fees, and affordability; an execution fee cap may not cap the total cost. Do not reject,
      stop, request another approval, or resimulate solely because those values differ from the reviewed command.
      
      This exception applies only to gas settings changed and approved in the wallet UI. Confirm the chain, account, target,
      calldata, native value, nonce, and authorization list (if present) still match the reviewed transaction; reject the
      request if any of those fields change.
      
      For a workflow whose transfer value depends on its fee reserve, including exact-zero and best-effort sweeps, preserve
      the reviewed transaction type, gas limit, and gas price or both EIP-1559 fee caps. Reject wallet changes before signing
      and rebuild, simulate, and review the dependent transfer value. Cast 1.8.3+ forwards an explicit `--legacy` type to the
      browser wallet; earlier versions could drop it at the provider boundary, so confirm the wallet screen shows the reviewed
      type. If the wallet cannot preserve a legacy request, stop without submitting an EIP-1559 substitute.
      
      Do not combine `--browser` with another signer flag. Capture the transaction hash, then have `$evm-atlas` verify the
      receipt before reporting success.
      
      ## Timing
      
      Wallet approval is an unbounded human-interaction step, not network latency: the wait is for a person to notice and
      click a prompt, which can exceed a typical command timeout. Run the broadcast command with a generous timeout, or in the
      background, so the process outlives the approval wait. A short synchronous timeout risks killing the process after the
      wallet has already broadcast but before `cast` prints the hash back — the transaction still lands on-chain, but the
      operator loses the hash and cannot immediately confirm it.
      
      Add `--async` to every browser-signed broadcast, not only as a fallback: it prints the transaction hash as soon as
      signing and broadcast succeed and exits without also waiting for a receipt, shrinking the window in which a timeout can
      outrace the printed output. Poll for the receipt separately afterward.
      
      ## Recovering From a Killed or Timed-Out Process
      
      If the process is killed or times out before printing a hash, its exit status alone does not prove nothing was broadcast
      — the wallet may have submitted the transaction via its own configured RPC provider, independent of the `--rpc-url`
      passed to `cast`, and mempool visibility lags and varies across providers (especially behind a load-balanced RPC
      aggregator). Do not treat a single provider's pending-transaction count or a single provider lookup miss as proof of
      non-broadcast. Before concluding nothing was sent:
      
      - Ask `$evm-atlas` to repeat the raw `eth_getTransactionByHash` lookup over 30-60 seconds to allow mempool propagation,
        rather than accepting one immediate miss as final.
      - Ask the user to check their wallet's own pending-activity view — the wallet knows definitively whether it submitted
        the transaction, independent of any RPC endpoint the agent queries.
      
      Only report the outcome as resolved (confirmed or genuinely never sent) once one of these gives a positive or a stable,
      repeated negative result.
      
      ## Message Signing
      
      Cast supports browser signing of plain messages and EIP-712 typed data. Confirm the installed version's capabilities
      before preparation, using clean-environment help:
      
      ```sh
      env -i PATH="$PATH" cast wallet sign --help
      env -i PATH="$PATH" cast wallet verify --help
      ```
      
      Require `sign` to expose `--browser` and `--from`; for typed data, also require `--data` and `--from-file` on both
      subcommands. If unavailable, stop a browser-only flow without loading a key or substituting a transaction signature.
      
      Use an EIP-712 JSON file containing `domain`, `types`, `primaryType`, and `message`. An API's `values` object is not a
      Cast `message`: use the consuming workflow's validated adapter and preserve the domain, type definitions, and all signed
      values exactly. Keep large integers as exact decimal strings or losslessly parsed integers. Do not infer a primary type
      from JSON key order or sign the raw API response.
      
      Present the exact plain-message bytes or full decoded EIP-712 domain, primary type, and payload. Review the owner,
      chain, verifying contract, authorizations, amounts, nonces, deadlines, and intended recipient of the signature where
      applicable. Bind the browser account to `OWNER`. Only after approval, sign and verify the same payload:
      
      ```sh
      SIGNATURE="$(cast wallet sign --data --from-file "$TYPED_DATA_JSON" --from "$OWNER" --browser)" || exit 1
      cast wallet verify --address "$OWNER" --data --from-file "$TYPED_DATA_JSON" "$SIGNATURE" || exit 1
      ```
      
      For plain messages, use `cast wallet sign "$MESSAGE" --from "$OWNER" --browser`, then
      `cast wallet verify --address "$OWNER" "$MESSAGE" "$SIGNATURE"`. Do not use `--no-hash` for EIP-712 documents or
      ordinary prefixed messages.
      
      Message signing is a human-interaction wait: preserve the process until the wallet responds. `--async` applies to
      broadcasts, not `wallet sign`. Treat sign or verify failure as blocking; never return or submit an unverified signature.
      This local recovery check requires a signature recoverable to `OWNER`; it does not verify EIP-1271 contract-wallet
      signatures. If that check cannot establish the reviewed signer, stop this flow.
      
      Return the verified signature and signer address. Submit it elsewhere only when approval explicitly covers that
      submission. For Permit2, the consuming workflow must bind the permit to its reviewed quote and state; a refreshed quote
      or changed payload requires a new review and signature. Never silently reuse or modify a signed payload.
      
      ## Failure Handling
      
      On a port conflict, missing browser, rejected wallet request, timeout, chain mismatch, or account mismatch, stop and
      report the failure. Do not silently fall back to a private key or retry a broadcast. If the user selects another signer,
      update the transaction review when the sender or command changes.
      
      Classify each failure before retrying:
      
      - `Wallet connection timeout` before `Wallet connected`, or `ChainSwitch rejected`: nothing was signed. Confirm the
        sender nonce is unchanged, then retry the same reviewed command.
      - A signed request rejected by an RPC for another chain, such as `nonce too low` with a different chain ID or `minNonce`
        in the error: the wallet's network state is inconsistent. The printed hash was signed; look it up on the reviewed
        chain and confirm the nonce is unchanged. Ask the user to reset the `localhost:9545` site network in the wallet before
        retrying.
      - Each command switches the wallet to its chain. Sending first on the already connected chain avoids a switch prompt.
      
    • eip7702.md 14.3 KB
      # EIP-7702 Delegation Revocation
      
      Use Cast's native authorization commands to clear delegation. Follow
      [the EIP-7702 specification](https://eips.ethereum.org/EIPS/eip-7702) and verify that each selected chain's active fork
      supports type-4 transactions through `$evm-atlas` and current official chain documentation. All state, simulation,
      estimation, and verification reads belong to atlas under `SKILL.md`.
      
      ## Select the Signer and Native Route First
      
      Before transaction preparation or secret access, check the installed capabilities in a clean environment:
      
      ```sh
      env -i PATH="$PATH" cast wallet sign-auth --help
      env -i PATH="$PATH" cast send --help
      env -i PATH="$PATH" cast recover-authority --help
      env -i PATH="$PATH" cast from-rlp --help
      ```
      
      Check each producer's exit status; when filtering, capture successful help first as in
      [browser-signing.md](browser-signing.md). Do not infer authorization signing from `send --browser` or ordinary message
      signing. Check hardware support for this operation as well as the CLI flag; a listed device is not proof its firmware
      can sign the authorization digest.
      
      | Route                                                             | When to use it                                                                                             | Signing boundary                                                                                                                                                      |
      | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
      | `cast send --auth "$ZERO_DELEGATE"` with a supported local signer | Authority is also the transaction sender and no separately signed artifact is needed before final approval | Cast constructs the authorization with the selected chain and transaction nonce plus one, then signs and broadcasts the outer transaction. This is never preparation. |
      | `cast wallet sign-auth`, then `cast send --auth "$SIGNED_AUTH"`   | Exact simulation needs a signature, the fee payer differs, or the outer transaction uses a browser         | Approve the authorization before creating it; submit the unchanged verified artifact only within its approved use and the transaction approval.                       |
      
      Resolve the public authority, public sender, and supported signer for each before investing in simulation. Reuse an
      existing encrypted keystore, supported hardware signer, or an explicitly supported target-project secret consumer,
      subject to `SKILL.md`'s signer preferences and the user's restrictions. Discover a project's secret-manager adapter and
      its owning instructions at runtime; do not assume a particular repository or secret-manager setup. Preparation does not
      load credentials. Never ask for secrets in chat, print them, or expose them through command logs.
      
      If the necessary integration is absent, report the precise missing prerequisite and supported next step: an existing
      supported signer, an authorization produced through an approved supported route, or separately authorized adapter work
      in its owning project. Do not invent keystore cryptography, automate secret-entry terminals, or build a signing/approval
      framework incidentally. In a browser-only flow without authorization-signing support, stop before a signing request;
      never fall back silently. See [browser-signing.md](browser-signing.md) for using an existing authorization with a
      browser outer transaction.
      
      ## Bind the Authorization and Nonces
      
      The **authority** signs permission to change its own code. The **sender** signs, funds, and submits the containing
      transaction; it may be the authority or a separate fee payer. Revocation sets the authorization's delegate to
      `0x0000000000000000000000000000000000000000`. This delegate is distinct from the outer transaction's `to` address. An
      ordinary transfer to zero does not revoke delegation. Review the outer destination, value, and calldata independently;
      type 4 requires a destination and cannot create a contract.
      
      Prepare one clearing authorization per selected chain. Review authority, chain ID, zero delegate, authorization nonce,
      signer, and intended transaction sender. Use the selected chain's nonzero ID explicitly; wildcard chain ID `0` requires
      explicit cross-chain scope authorization. Never infer it from a multi-chain request or bypass its warning with
      `--force`. Repeat state checks, fee accounting, approvals within their stated scope, and outcome verification for every
      chain.
      
      Ask atlas for a canonical checkpoint (block number/hash), authority code and nonce, sender nonce and balance, and
      pending nonce evidence for both accounts. Code `0x` already satisfies clearing at that checkpoint; report the observed
      state without manufacturing a revocation transaction. A delegation indicator is `0xef0100` followed by a 20-byte
      delegate; other code requires investigation. Resolve pending activity and nonce changes before signing, then refresh
      again before submission. A single provider's pending count does not exclude every outstanding authorization.
      
      For one tuple and no intervening nonce changes:
      
      | Sender relationship | Outer transaction nonce          | Authorization nonce                                                   |
      | ------------------- | -------------------------------- | --------------------------------------------------------------------- |
      | Self-broadcast      | Authority's applicable nonce `N` | `N + 1`: the sender increment happens before authorization processing |
      | Separate fee payer  | Payer's applicable nonce `P`     | Authority's applicable nonce `A`, without a self-broadcast increment  |
      
      A successfully applied authorization increments the authority nonce once more. Do not reuse the table blindly for
      multiple tuples or pending sequences; reconcile their processing order. If state changes invalidate the reviewed nonce,
      stop and rebuild/review the changed payload instead of retrying the old signature.
      
      Check installed behavior against the matching
      [wallet source](https://github.com/foundry-rs/foundry/blob/master/crates/cast/src/cmd/wallet/mod.rs) and
      [transaction builder's `resolve_auth`](https://github.com/foundry-rs/foundry/blob/master/crates/cast/src/tx.rs).
      `sign-auth --nonce` supplies the authorization nonce directly; `--self-broadcast` derives a nonce by RPC and adds one,
      and currently conflicts with `--nonce`. Use atlas's explicit `--chain` and computed `--nonce`, omitting
      `--self-broadcast`, so `sign-auth` performs no implicit standalone chain/nonce lookup. For address-valued `send --auth`,
      pass the outer nonce `N`; Cast adds one internally. Never add that increment twice.
      
      ## Approval and Simulation
      
      Use staged approval when exact simulation needs a real signature or a separately approved authorization artifact is
      required. This conditional route does not add stages to ordinary transactions. Existing explicit approval covering a
      concrete payload and its subsequent use remains valid; do not request it again merely because work enters a new phase.
      
      1. **Review authorization intent without signing.** Present all authorization fields, signer, intended sender, exact
         signing command, and intended use. Name the later simulation/provider disclosure the approval covers. The signature
         authorizes code clearing and is independently submit-able by anyone while its chain/nonce conditions hold; it is not
         bound to the outer transaction's sender, fees, destination, calldata, or value. Require explicit approval of this
         payload and scope before accessing secrets or creating the signature. This approval does not itself authorize an
         outer transaction signature or broadcast.
      2. **Sign and recover locally.** Refresh nonces through atlas, create the approved authorization using the selected
         supported signer, decode it, and recover its authority as below. Do not broadcast. Handle the signature as an
         authorization capability: keep it out of ordinary logs and transmit it to a simulation provider only when the
         approval covers that disclosure. A failed simulation does not cancel an already issued authorization.
      3. **Simulate, estimate, and review the outer transaction.** Through atlas, use the actual authorization in the exact
         type-4 call object/`authorizationList`, with reviewed sender, nonce, destination, value, calldata, and fees. Require
         evidence that the provider applies the tuple and models its nonce transition and gas effects. An accepted RPC field,
         dummy signature, skipped tuple, or code-only state override does not prove the complete signed transaction. If the
         provider lacks support, resolve a supported simulation route under `SKILL.md` or report the exact gap. Complete
         chain-specific fee accounting and present the concrete transaction under `SKILL.md`'s Review before its
         signature/send.
      4. **Refresh and submit within approval.** Recheck authority code/nonces, sender nonce/balance, pending activity, fee
         validity, and affordability through atlas. Preserve the approved authorization and outer fields. Changed payloads
         require a revised review and simulation; wallet gas edits retain only the existing browser exception. Submit with the
         exact approved signer and command, then verify both outcomes below.
      
      The one-command local route is available only when simulation can establish the complete reviewed authorization's
      effects without first creating its signature, or equivalent exact evidence is already available. State the simulation
      method and its limits. Its transaction review must include the authorization intent and explicitly approve both
      signatures and broadcast. If simulation instead requires an actual signature, select the staged route; never invoke
      `cast send` to obtain a preparation artifact.
      
      ## Native Commands
      
      These are signing/broadcast templates, executable only at their approved phase. Populate public variables from the
      review and atlas; use the selected fee policy. `KEYSTORE_FILE` denotes an existing approved keystore, not a request to
      create one. Replace its signer option only with the reviewed supported signer. `RPC_URL` means the continuous transport
      selected under `SKILL.md`, including its alias and stderr rules.
      
      For an approved local self-broadcast, `AUTHORITY` equals the sender and `TX_NONCE` is `N`:
      
      ```sh
      ZERO_DELEGATE='0x0000000000000000000000000000000000000000'
      cast send "$TX_TO" --data "$CALLDATA" --value "$VALUE_WEI" \
        --auth "$ZERO_DELEGATE" --chain "$CHAIN_ID" --nonce "$TX_NONCE" \
        --from "$AUTHORITY" --keystore "$KEYSTORE_FILE" --rpc-url "$RPC_URL" \
        --gas-limit "$GAS_LIMIT" --gas-price "$MAX_FEE_WEI" \
        --priority-gas-price "$PRIORITY_FEE_WEI" --async
      ```
      
      For a separately approved authorization, `AUTH_NONCE` is `N + 1` for self-broadcast or `A` for a different payer:
      
      ```sh
      ZERO_DELEGATE='0x0000000000000000000000000000000000000000'
      SIGNED_AUTH=$(cast wallet sign-auth "$ZERO_DELEGATE" \
        --chain "$CHAIN_ID" --nonce "$AUTH_NONCE" --keystore "$KEYSTORE_FILE") || exit 1
      ```
      
      Decode locally with `cast from-rlp "$SIGNED_AUTH"`. Its six fields are `[chain_id, address, nonce, y_parity, r, s]`;
      verify chain, zero delegate, and nonce against the approved intent. Losslessly map those fields to the authorization
      JSON keys `chainId`, `address`, `nonce`, `yParity`, `r`, and `s`, preserving integer precision and using RPC hex
      quantities (`0x0` for integer zero, not RLP's empty `0x`). Recover with `cast recover-authority "$AUTH_JSON"` and
      require an exact address match with the reviewed authority. The RLP artifact is not a plain message signature; do not
      pass it to `wallet verify` as one. Keep the decoded tuple and signed RLP bound together through simulation and
      submission; recovery alone does not prove on-chain nonce validity.
      
      After simulation and transaction approval, submit the same signed authorization. The sender's signer can differ:
      
      ```sh
      cast send "$TX_TO" --data "$CALLDATA" --value "$VALUE_WEI" \
        --auth "$SIGNED_AUTH" --chain "$CHAIN_ID" --nonce "$TX_NONCE" \
        --from "$SENDER" --keystore "$SENDER_KEYSTORE_FILE" --rpc-url "$RPC_URL" \
        --gas-limit "$GAS_LIMIT" --gas-price "$MAX_FEE_WEI" \
        --priority-gas-price "$PRIORITY_FEE_WEI" --async
      ```
      
      For a supported browser outer transaction, replace the keystore option with `--browser`, following
      [browser-signing.md](browser-signing.md); do not combine signer options. Always preserve the authorization list and
      type.
      
      Type-4 revocations use EIP-1559 fee caps, not `--legacy`. Retain the default Ethereum
      [Rabby Slow policy](ethereum-gas.md) unless another compatible policy is selected. Include authorization intrinsic
      costs, applicable refunds, and chain-specific additional fees in the full estimate/reserve under `SKILL.md` and current
      official sources. Do not subtract expected refunds from upfront funding or reuse a 21000-gas exact-zero transfer
      assumption. A legacy sweep, if separately requested, is a separate reviewed transaction after clearing is verified.
      
      ## Verify and Recover
      
      Have atlas obtain the outer transaction and canonical receipt, reconcile the selected tuple's chain, recovered
      authority, delegate, and nonce against transaction evidence, and query `eth_getCode` for the authority at a canonical
      checkpoint at or after inclusion. Require code `0x` for successful clearing. Reconcile nonce transitions and tuple
      ordering as needed to establish application; investigate later transactions or reorgs when evidence conflicts. Code
      already empty before inclusion does not by itself prove this tuple applied.
      
      Report the transaction outcome and authorization outcome separately, with the code checkpoint and ordinary receipt, fee,
      nonce, and explorer evidence:
      
      - A successful outer receipt can contain a skipped authorization. Unchanged delegation means clearing was not achieved;
        missing application evidence is unresolved, not success.
      - An applied authorization survives a reverted transaction body. Recognize cleared code even when receipt status is
        failure; do not blindly submit another revocation.
      - For an uncertain broadcast, preserve `SKILL.md`'s no-retry handling and the browser recovery rules. Check transaction
        existence and actual authority state before any retry, replacement, or new authorization.
      
      Clearing delegation removes code; it does not erase account storage or revoke unrelated token approvals. Keep those
      effects and any separately requested cleanup distinct.
      
    • ethereum-gas.md 3.8 KB
      # Ethereum Slow Gas
      
      This is the default policy for Ethereum mainnet transactions. The user or consuming skill may explicitly select another
      policy under `SKILL.md`, including fixed legacy pricing for an exact-zero sweep. In that case, use and review the
      selected policy instead of fetching or enforcing this fee pair. Do not treat an API failure as an implicit override.
      
      Rabby's keyless gas-market endpoint supplies the same `slow`, `normal`, and `fast` tiers used by the wallet, including
      separate EIP-1559 max-fee and priority-fee values. It is a public runtime API, not a documented third-party SLA; stop on
      an outage or schema change instead of substituting another source.
      
      ## Fetch the Quote
      
      Resolve `scripts/rabby-slow-gas.sh` relative to this skill and run it immediately before simulation and review:
      
      ```sh
      RABBY_SLOW_QUOTE=$("$CLI_CAST_SKILL_DIR/scripts/rabby-slow-gas.sh")
      RABBY_SLOW_MAX_FEE_WEI=$(printf '%s\n' "$RABBY_SLOW_QUOTE" | jq -er '.max_fee_per_gas_wei')
      RABBY_SLOW_PRIORITY_FEE_WEI=$(printf '%s\n' "$RABBY_SLOW_QUOTE" | jq -er '.max_priority_fee_per_gas_wei')
      RABBY_SLOW_ESTIMATED_SECONDS=$(printf '%s\n' "$RABBY_SLOW_QUOTE" | jq -er '.estimated_seconds')
      RABBY_SLOW_QUOTED_AT=$(printf '%s\n' "$RABBY_SLOW_QUOTE" | jq -er '.quoted_at')
      ```
      
      Set `CLI_CAST_SKILL_DIR` to the absolute directory containing this `SKILL.md`. The helper calls
      `https://api.rabby.io/v2/wallet/gas_market`, selects exactly one `slow` entry, and rejects malformed, non-integer,
      incoherent, or incorrectly ordered tiers. Do not reuse a quote for another transaction or a restarted review.
      
      Ask `$evm-atlas` for one read packet containing the resolved Ethereum chain ID, latest block number and hash, and that
      block's base fee. Require chain ID `1`, then bind the returned values locally:
      
      ```sh
      test "$EVM_ATLAS_CHAIN_ID" = '1'
      RABBY_SLOW_BLOCK="$EVM_ATLAS_BLOCK_NUMBER"
      RABBY_SLOW_BASE_FEE_WEI="$EVM_ATLAS_BASE_FEE_WEI"
      test "$RABBY_SLOW_MAX_FEE_WEI" -ge "$RABBY_SLOW_BASE_FEE_WEI"
      ```
      
      If validation fails, fetch once more. Stop if the second result fails; do not fall back to `cast gas-price`,
      `eth_gasPrice`, Normal, or Fast.
      
      ## Bind the Fees
      
      When this policy is selected, pass both values to simulation where supported and to every transaction-building or
      `cast send` command:
      
      ```sh
      cast send "$CONTRACT" 'transfer(address,uint256)' "$TO" "$AMOUNT" \
        --rpc-url "$RPC_URL" \
        --gas-price "$RABBY_SLOW_MAX_FEE_WEI" \
        --priority-gas-price "$RABBY_SLOW_PRIORITY_FEE_WEI" \
        SIGNER_FLAGS
      ```
      
      For EIP-1559 transactions, Cast interprets `--gas-price` as the max fee per gas and `--priority-gas-price` as the max
      priority fee per gas. Start browser (`--browser`), encrypted-keystore, hardware-wallet, and environment-backed
      private-key commands with the same fee pair. Use one reviewed signer suffix such as `--browser`,
      `--keystore "$KEYSTORE_FILE"`, `--ledger`, or `--private-key "$ETH_PRIVATE_KEY"`; the signer preference and approval
      rules in `SKILL.md` still apply. For browser signing, these flags are starting values: the user may deliberately edit
      the gas limit or fee caps in the wallet confirmation UI, and the approved final wallet values govern the transaction. Do
      not use `--legacy` for this policy.
      
      For `cast publish`, inspect the signed transaction first and verify it already contains the approved fee pair; fees
      cannot be changed after signing. The Rabby quote covers execution gas only, so a blob transaction still needs an
      independently reviewed blob-gas price.
      
      Immediately before broadcast, have `$evm-atlas` fetch the latest block and base fee again. If it exceeds the reviewed
      max fee, the transaction is not currently includable: obtain a new Slow quote, simulate again, and present a revised
      review. For replacements or cancellations, stop when Slow does not satisfy the required fee bump rather than silently
      increasing the tier.
      
    • version.txt 6 B
      1.8.3
      
  • scripts
    • rabby-slow-gas.sh 2.2 KB
      #!/bin/bash
      set -euo pipefail
      
      command -v curl >/dev/null 2>&1 || {
        echo 'rabby-slow-gas: curl is required' >&2
        exit 1
      }
      command -v jq >/dev/null 2>&1 || {
        echo 'rabby-slow-gas: jq is required' >&2
        exit 1
      }
      
      endpoint='https://api.rabby.io/v2/wallet/gas_market'
      response=$(
        curl --fail --silent --show-error \
          --connect-timeout 5 \
          --max-time 10 \
          --retry 2 \
          --retry-delay 1 \
          --request POST \
          --header 'content-type: application/json' \
          --data '{"chain_id":"eth"}' \
          "$endpoint"
      )
      quoted_at_unix=$(date +%s)
      quoted_at=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
      
      printf '%s\n' "$response" | jq -ce \
        --arg endpoint "$endpoint" \
        --arg quoted_at "$quoted_at" \
        --argjson quoted_at_unix "$quoted_at_unix" '
        def one_tier($name):
          [.[] | select(.level == $name)] as $matches
          | if ($matches | length) == 1 then $matches[0]
            else error("expected exactly one \($name) tier")
            end;
        def valid_tier:
          (.price | type) == "number"
          and (.price | floor) == .price
          and .price > 0
          and (.priority_price | type) == "number"
          and (.priority_price | floor) == .priority_price
          and .priority_price >= 0
          and .priority_price <= .price
          and (.estimated_seconds | type) == "number"
          and (.estimated_seconds | floor) == .estimated_seconds
          and .estimated_seconds >= 0;
      
        if type != "array" then error("expected a tier array") else . end
        | . as $tiers
        | ($tiers | one_tier("slow")) as $slow
        | ($tiers | one_tier("normal")) as $normal
        | ($tiers | one_tier("fast")) as $fast
        | if (($slow | valid_tier) and ($normal | valid_tier) and ($fast | valid_tier))
            and $slow.price <= $normal.price
            and $normal.price <= $fast.price
            and $slow.priority_price <= $normal.priority_price
            and $normal.priority_price <= $fast.priority_price
          then {
            endpoint: $endpoint,
            chain_id: 1,
            chain_server_id: "eth",
            tier: "slow",
            max_fee_per_gas_wei: ($slow.price | tostring),
            max_priority_fee_per_gas_wei: ($slow.priority_price | tostring),
            estimated_seconds: $slow.estimated_seconds,
            quoted_at_unix: $quoted_at_unix,
            quoted_at: $quoted_at
          }
          else error("invalid or incorrectly ordered gas tiers")
          end
        '
      
  • SKILL.md 19 KB
    ---
    coordination: exempt
    name: cli-cast
    skill-dependencies:
      - evm-atlas
    user-invocable: false
    description:
      "Use for Foundry cast transaction actions: prepare, trace, simulate, sign, or broadcast; sign messages; or
      encode/decode ABI/calldata. Delegate every standalone RPC read to evm-atlas."
    ---
    
    # Foundry Cast CLI
    
    This skill is coordination-exempt: skip the ai-coord gate for its declared work.
    
    Separate read, preparation, simulation, signing, and broadcast so no state-changing action is hidden inside command
    construction.
    
    For EIP-7702 authorization or delegation revocation, read [references/eip7702.md](references/eip7702.md) before
    preparation. It defines signer selection, authority versus transaction sender, conditional staged approval, and
    authorization verification in addition to the transaction receipt.
    
    ## Resolve Chain and Provider
    
    Invoke `$evm-atlas` before every network operation. It owns chain resolution, discrete reads, and bounded live
    subscriptions. Pass the explicit chain name or ID, JSON-RPC method and exact parameters or call object, block selector
    or checkpoint requirement, and why the result is needed. Require its read packet containing the resolved chain name and
    ID, provider route, result, observed block or checkpoint, and coverage gaps.
    
    If the chain is absent from `evm-atlas`, stop RPC-dependent work. Do not accept an arbitrary RPC URL as an escape hatch
    and never infer Ethereum when the chain is ambiguous.
    
    Use an RPC URL in this skill only for a trace, fork, or send flow that cannot be expressed as bounded discrete reads.
    For RouteMesh-backed continuous transport, first require `evm-atlas` to confirm current RouteMesh coverage, then use the
    explicit Foundry alias when it is configured:
    
    ```sh
    ROUTEMESH_CHAIN_ID="$CHAIN_ID" cast COMMAND --rpc-url routemesh
    ```
    
    Otherwise use the nonsecret public RPC verified by `evm-atlas`. Never construct, inspect, or print a RouteMesh URL.
    Treat Cast stderr as secret-bearing because Foundry may reveal a resolved alias URL on transport failure; never repeat
    that output in chat, logs, or external reports.
    
    Resolve every RPC value from `evm-atlas`'s current read packet or the RouteMesh alias above; hard-coding a public RPC
    URL, such as a literal `https://` endpoint typed from memory or a prior response, in a prepare, simulate, or verify
    command violates this delegation even when the chain matches. When a local `cast` command against that provider returns
    a `--json` hex quantity, decode it with `cast to-dec <hex>` or a field-select form such as `cast receipt <hash> <field>`
    or `cast tx <hash> <field>`; do not pipe `--json` output through `jq tonumber`, which fails on hex strings and on
    `null`.
    
    ## Authority Phases
    
    ### Read
    
    Local ABI encoding/decoding and selector derivation may run without transaction approval. Delegate chain, block, fee,
    nonce, `eth_call`, `eth_estimateGas`, transaction, receipt, log, balance, code, storage, proof, and ENS reads to
    `$evm-atlas`, including reads needed to prepare or verify a transaction. Do not ask `evm-atlas` to hand a read back to
    this skill merely because later work may change state.
    
    Use `env -i PATH="$PATH" cast <command> --help` for exact local syntax. Cast help can print inherited environment
    values, including API keys; do not load credentials or decrypted dotenv for capability checks. Typical local operations:
    
    ```sh
    cast calldata 'transfer(address,uint256)' "$TO" "$AMOUNT"
    cast decode-calldata 'transfer(address,uint256)' "$CALLDATA"
    ```
    
    ### Prepare
    
    Resolve and validate chain ID, sender, target, function signature, arguments, calldata, native value, nonce, and fee
    assumptions without signing. Obtain every on-chain fact through `evm-atlas`; do not request or load key material during
    preparation. Select a supported signer under Sign and Broadcast and check its command capabilities before simulation or
    helper construction.
    
    Request both the confirmed nonce at the numeric checkpoint block and the pending nonce. When they differ, or a wallet
    reports `replacement transaction underpriced`, a queued transaction occupies the lowest unconfirmed nonce, and later
    nonces stay stuck behind it. Target that nonce with fees that clear the node's replacement bump, usually 10-20% on both
    the fee cap and the tip, instead of queueing another transaction behind it.
    
    For Ethereum mainnet, the default gas policy is [references/ethereum-gas.md](references/ethereum-gas.md): fetch a fresh
    Rabby `slow` quote and bind its EIP-1559 fee pair before simulation. The user or a consuming skill may explicitly choose
    a different gas policy, including a fixed legacy gas price for an exact-zero sweep. Honor that choice; it does not
    require a separate policy-exception approval. Record its source, transaction type, fee values, and any constraints in
    the transaction review. Apply the selected policy to every signer and do not silently substitute a different tier or
    transaction type. Do not reuse Ethereum fee values on another chain.
    
    Elsewhere, absent a selected policy, set an EIP-1559 max fee with headroom over the latest base fee, such as
    `2 * baseFee + priorityFee`, instead of passing `eth_gasPrice` as the cap. The charge stays base fee plus tip, while an
    exact cap can fall below the base fee before signing and force a revised review.
    
    #### Chain-specific gas accounting
    
    Resolve the chain's active fee model before choosing a transaction type or subtracting fees from a balance. Use current
    official protocol documentation for semantics and `$evm-atlas` for the target chain's parameters, fee-oracle calls,
    estimates, and receipts. EVM compatibility, a native symbol of ETH, and support for legacy transactions do not establish
    Ethereum fee semantics. A chain absent from atlas remains unsupported.
    
    For the exact transaction, retain a public fee record containing the chain/checkpoint, active fork and sources,
    transaction type, gas estimate and limit, price/caps, expected total fee, upfront fee reserve with each component and
    margin, and refund behavior. Identify which charges are included in estimated gas and which are additional native
    debits. Use arbitrary-precision integer arithmetic and round reserves up. Never count a component twice or subtract an
    anticipated refund from the upfront funding requirement. Re-estimate when value, calldata, nonce, type, gas, or fees
    change; serialization can change the L1 charge even for an empty-calldata transfer.
    
    - **Ethereum-style accounting:** establish that all fees for this transaction are covered by gas. Reserve
      `gasLimit * gasPrice` for legacy, or `gasLimit * maxFeePerGas` for EIP-1559. Actual cost uses receipt `gasUsed` and
      `effectiveGasPrice`. Exact-zero native sweeps require evidence of a fixed charged price, fixed gas used, and no
      additional charges or credits; a plain undelegated EOA transfer on Ethereum with empty calldata and legacy pricing can
      use exactly 21000 gas. Do not apply that constant to other fee models.
    - **Arbitrum Nitro:** use the complete `eth_estimateGas` result, or `NodeInterface.gasEstimateComponents()` through
      atlas. It includes the parent-chain posting charge converted into child-chain gas. Budget the full gas limit at the
      reviewed price cap; do not add a second L1 fee. Legacy transactions are supported, but their charged price depends on
      the active ArbOS version and tip-collection setting. Verify that behavior through atlas and the current
      [fee processor](https://github.com/OffchainLabs/nitro/blob/master/arbos/tx_processor.go): newer versions make tip
      collection configurable. When tips are disabled, prefer EIP-1559 with zero priority fee; legacy bids and equal caps
      still charge the inclusion base fee. When tips are collected, apply the active effective-price rules. A fixed charged
      price alone does not fix the variable posting-gas component or prove an exact-zero sweep. Reconcile unused gas/price
      headroom against the reviewed residual policy. Use receipt `gasUsed * effectiveGasPrice` for total cost;
      `gasUsedForL1` is an included gas component, not an extra wei charge. See
      [gas and fees](https://docs.arbitrum.io/how-arbitrum-works/deep-dives/gas-and-fees) and
      [estimation](https://docs.arbitrum.io/arbitrum-essentials/how-to-estimate-gas).
    - **OP Stack:** reserve execution gas plus the L1 data fee and any enabled operator fee. Through atlas, query the
      verified `GasPriceOracle` for `getL1Fee(bytes)` using the serialized unsigned transaction, and, where supported,
      `getL1FeeUpperBound(uint256)` using its unsigned byte length. These interfaces account for signature overhead; do not
      add it twice. The latter is a practical size bound at the current oracle prices, not a cap on fees at inclusion. Query
      `getOperatorFee(gasLimit)` for upfront budgeting and reconstruct the included operator charge using the inclusion
      fork's parameters, gas use, and exact client rounding/refund semantics. Before Isthmus it is absent; Isthmus and
      Jovian use different scalar formulas. Establish absence from fork/configuration evidence, not a failed call or a
      missing provider field. Receipt total is execution cost plus `l1Fee` plus operator cost, each once. See
      [transaction fees](https://docs.optimism.io/op-stack/transactions/fees),
      [Fjord oracle](https://specs.optimism.io/protocol/fjord/predeploys.html),
      [Isthmus operator accounting](https://specs.optimism.io/protocol/isthmus/exec-engine.html), and
      [Jovian changes](https://specs.optimism.io/protocol/jovian/exec-engine.html).
    - **Other models, including ZKsync:** obtain the current chain-native estimator and receipt semantics through atlas and
      official docs. Establish coverage of pubdata, resource overhead, custom debits, and refunds for the actual transaction
      type. Use an ordinary type `0`/`2` transfer only if the chain and browser transport support it with complete fee
      coverage. Do not substitute a deprecated estimator or add custom transaction fields without a supported signing path.
      ZKsync's [fee structure](https://docs.zksync.io/zksync-protocol/era-vm/transactions/fee-model/fee-structure) includes
      pubdata/overhead and refunds; neither 21000 gas nor exact-zero accounting follows from EVM compatibility. Stop with
      the missing component when complete accounting cannot be established.
    
    On chains with fees outside transaction caps, label the total as an **estimated reserve**, disclose the uncovered price
    movement, and recheck affordability immediately before signing. A margin is not a protocol-enforced maximum. Require
    `value + upfront fee reserve <= balance`; ordinary gas estimation or a successful `eth_call` alone does not prove this.
    If final wallet fee edits are allowed, recompute dependent additional fees and affordability from those values. Sweeps
    whose value depends on the reserve must preserve all reviewed fields under the fixed-fee exception below.
    
    Refunded or unspent gas is normally already reflected in the final charged fee and sender balance; do not subtract it
    again. Treat asynchronous refunds, such as Arbitrum retryable tickets, separately: never spend an expected credit before
    it arrives or claim a snapshot balance is permanent. Discovery of unrelated pending refunds is not implicit in a plain
    transfer. A consuming sweep must state its residual-balance policy and any known pending credits before approval.
    
    ### Simulate
    
    Simulate the exact prepared call, preserving sender, target, value, calldata, nonce, transaction type, gas limit, and
    fee fields, then estimate gas. Delegate bounded `eth_call` and `eth_estimateGas` evidence to `evm-atlas`. When an RPC
    error contradicts the supplied gas or checkpointed balance, have atlas diagnose the exact simulation path before
    attributing it to transaction invalidity or chain-wide type support. Changing fields to make a diagnostic call pass does
    not validate the prepared transaction. Preserve the consuming workflow's simulation and approval requirements. Use a
    local fork, project simulation, or Cast trace only when the simulation requires a continuous provider, following Resolve
    Chain and Provider. A successful simulation is evidence, not authorization to sign.
    
    When exact EIP-7702 simulation needs a signed authorization, use the reference's approved authorization-signing stage
    first; transaction signing and broadcast still follow simulation and transaction approval.
    
    ### Review
    
    Before a transaction signature or broadcast, present one concrete review containing:
    
    - chain name and ID, RPC source, and latest block used;
    - sender, target, function, decoded arguments, calldata, and native value;
    - nonce, gas estimate/limit, fee assumptions, expected total cost, upfront reserve, and any protocol-enforced fee caps;
    - chain-specific fee components, inclusion-price uncertainty outside those caps, and expected refunds or residuals;
    - the selected gas policy and source; for Rabby Slow, the oracle URL, tier, quote time, estimated inclusion time, max
      fee per gas, and max priority fee per gas; for a legacy policy, the fixed gas price and transaction type;
    - expected approvals, transfers, or other state changes;
    - simulation command and outcome;
    - selected signer and the exact signing/broadcast command with secrets redacted.
    
    Lead the review with `### ⚠️ Transaction approval required`. Put repeated fields in a compact table, keep the exact
    command in a fenced block, and state precisely what confirmation authorizes. Stop and require explicit user confirmation
    of this review in a subsequent message. If any reviewed field changes outside the browser-wallet exception below,
    simulate again and present a revised review. Existing explicit approval of the concrete payload and its stated use
    remains valid; EIP-7702 authorization signatures follow the reference's conditional staged review.
    
    For browser signing only, the reviewed gas limit and fees are starting values unless the consuming workflow requires
    them to remain fixed. The user may deliberately change the gas limit, gas price, max fee per gas, or max priority fee
    per gas in the wallet confirmation UI. Their approval of that final wallet screen authorizes those edited gas settings;
    apply chain-specific accounting to the additional fees and resulting affordability. Do not stop, require a second
    approval, or resimulate solely because they differ from the prepared values. Continue only when the chain, sender,
    target, calldata, native value, nonce, authorization list (if present), and decoded intent still match the approved
    review. Wallet changes to any of those fields require rejection and a revised review.
    
    When fees determine the transfer value or another reviewed invariant, such as leaving exactly zero native balance, the
    browser exception does not apply. Preserve the reviewed transaction type, gas limit, and fee values. If the wallet
    changes them, reject before signing, recompute the dependent values, simulate, and obtain approval of the revised
    review.
    
    ### Sign and Broadcast
    
    Read [references/browser-signing.md](references/browser-signing.md) for browser capability checks and sender handling;
    open a signing request only after approval. Prefer browser, encrypted keystore, or hardware wallet in that order unless
    the user or consuming skill restricts the signer. A browser-only workflow must stop if browser signing is unavailable;
    never substitute another signer. Use an environment-backed private key only when the user explicitly opts in or no safer
    method is available; never ask for a key in chat or print it.
    
    `cast send` signs and broadcasts in one command. Run it only after the review approval. So do the Cast 1.8.3+ helpers
    `cast erc20-token transfer|approve|mint|burn`, `cast erc20-token permit --broadcast`,
    `cast erc4626 deposit|mint|withdraw|redeem`, and `cast safe propose|sign|execute`: apply the same Prepare, Simulate, and
    Review phases to them; a Safe proposal or confirmation is a signature artifact that needs its own payload review. Treat
    any other subcommand whose installed help shows it signs or submits, such as `cast safe create`, `add-delegate`, or
    `remove-delegate`, the same way. Signing a message or typed data, including `cast erc20-token permit` without
    `--broadcast`, also requires a review of the exact payload, domain, chain binding, and intended use before approval.
    
    Pass the selected fees explicitly: EIP-1559 uses `--gas-price` and `--priority-gas-price`; a fixed legacy policy uses
    `--legacy --gas-price` without `--priority-gas-price`. Under the default Ethereum policy, use the approved Rabby Slow
    pair. Before opening the signer, recheck the active chain's gas and additional-fee requirements and that the approved
    cap or legacy gas price covers its current base fee where applicable. If fees must change before signing, simulate again
    and present a revised review; never silently change the selected policy. Wallet fee edits follow Review, including its
    fixed-fee exception. Message and typed-data signatures consume no gas.
    
    After broadcast, capture the transaction hash and have `evm-atlas` verify the receipt on the reviewed chain. When a
    receipt is still pending, it may use one bounded RouteMesh `newHeads` subscription to wait for the next block before
    checking again. Receipt verification remains required; a pending-transaction or log notification alone cannot confirm
    the transaction. Reconcile actual fees under the active chain's model, including additional receipt components and
    refunds without double counting. Missing fee evidence is incomplete accounting, not zero fees. Report status, block, gas
    used, actual total fee or its exact evidence gap, and the explorer link under `### ✅ Transaction confirmed` for a
    successful receipt or `### ↩ Transaction reverted` for a mined failure. For an ambiguous outcome, lead with
    `### ⛔ Broadcast unresolved — do not retry` and state the evidence still needed. Do not retry a failed or uncertain
    broadcast without first checking whether the transaction exists — for browser-wallet signing specifically, read
    [references/browser-signing.md](references/browser-signing.md)'s Timing and Recovering sections before concluding
    nothing was sent: a killed or timed-out process does not prove non-broadcast, since wallet approval is an unbounded
    human wait and the wallet may broadcast via its own RPC provider.
    
    ## Stop Conditions
    
    Stop before signing when the signer, sender, chain, target, or decoded intent is unresolved. Transaction signing also
    requires resolved fee accounting, affordability, and simulation. Only the explicitly approved EIP-7702 authorization
    stage may precede those transaction checks; its authorization payload, signer, and intended use must already be
    resolved. Review must distinguish enforced caps from an estimated reserve; browser approval of edited gas settings
    authorizes those settings but does not establish coverage of omitted chain-specific charges. Stop before retrying when
    broadcast outcome is ambiguous. Completion requires either a verified read result, a local encoding result, an approved
    signature artifact, or a mined receipt verified by `evm-atlas` that matches the reviewed transaction apart from
    user-approved browser-wallet gas settings. Never decorate or truncate addresses, calldata, signatures, hashes, RPC URLs,
    fee values, commands, or safety wording. Revocation completion additionally requires the authorization and cleared-code
    checks in [references/eip7702.md](references/eip7702.md).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related