Skip to content

chore(evm-wallet-experiment): Reduce e2e testing friction#940

Draft
grypez wants to merge 16 commits intogrypez/evm-wallet-home-awayfrom
grypez/evm-wallet-command-revamp
Draft

chore(evm-wallet-experiment): Reduce e2e testing friction#940
grypez wants to merge 16 commits intogrypez/evm-wallet-home-awayfrom
grypez/evm-wallet-command-revamp

Conversation

@grypez
Copy link
Copy Markdown
Contributor

@grypez grypez commented Apr 21, 2026

Changes

  • Adds some convenience scripts for running the evm-wallet e2e tests.
  • Adds an agent skill for running the evm-wallet docker e2e tests.
  • Replaces the word 'interactive' in the yarn scripts to the shorter 'demo'.

grypez and others added 16 commits April 20, 2026 16:32
…n and slim method-catalog

Remove CaveatSpec, CaveatSpecStruct, BigIntStruct, and the old
DelegationGrant type (which carried raw caveat bytes on the away side).

Replace with TransferNativeGrant | TransferFungibleGrant — a discriminated
union where each variant carries pre-decoded semantic fields (to, maxAmount,
token) alongside the signed Delegation. This means the away side never
needs to decode caveat bytes; the home encodes once when building the grant.

Slim method-catalog to only the two methods this refactor introduces:
transferNative and transferFungible.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Vat that builds and stores delegation grants on the home side. Exposes:
- buildTransferNativeGrant: valueLte + allowedTargets caveats (conditional)
- buildTransferFungibleGrant: allowedTargets(token) + allowedMethods(ERC20
  transfer selector) always; erc20TransferAmount + allowedCalldata(to)
  conditionally
- storeGrant / removeGrant / listGrants: persisted in baggage

Grants are returned unsigned (status: 'unsigned'); signing is done by
the home coordinator before storeGrant is called.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Simple away-side store for DelegationGrant values received from the home
coordinator. Grants are keyed by delegation.id and persisted in baggage.
Exposes receiveGrant / removeGrant / listGrants; used by away-coordinator
when rebuilding the away sheaf.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tor-vat

Home coordinator keeps all shared infrastructure (signing, tx submission,
ERC-20, swap, smart account, OcapURL) and adds delegation management via
the new delegator-vat plus a homeSection exo.

New additions:
- buildTransferNativeGrant / buildTransferFungibleGrant: sign + store
  via delegator-vat
- signDelegationInGrant: resolves DelegationManager from chain contracts,
  signs via keyring or external signer, finalizes delegation
- listGrants / revokeGrant: list and on-chain disable grants
- getHomeSection(): returns the pre-built homeSection exo
- homeSection: local exo with transferNative/transferFungible that submit
  direct transactions; throws after 2 uses per method (demo limit)

Removes: all away-side peer protocol (connectToPeer, registerAwayWallet,
handleSigningRequest, handleRedemptionRequest) and the old delegation
routing in sendTransaction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
makeDelegationTwin({ grant, redeemFn }) builds a discoverable exo that
enforces the grant's constraints locally before submitting an Execution:

- transferNative: validates recipient (eq constraint or any) and amount
  (lte constraint or any), using M.interface guards
- transferFungible: validates token (must match), recipient (optional eq),
  and tracks cumulative spend with reserve-before-await rollback on error;
  concurrent calls cannot together exceed the budget

DelegationSection is a discriminated union carrying method and (for
transferFungible) token — used by away-coordinator routing to filter
matching sections and propagate constraint errors correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…er-relay support

Away coordinator manages the wallet API on the agent (away) side.
Shares infrastructure with home (provider, smart account, tx submission)
and routes semantic calls through delegation twins before falling back to
the home section.

Key design:
- receiveDelegation(grant): stores in redeemer-vat, rebuilds delegation
  sections from all stored grants via makeDelegationTwin
- transferNative / transferFungible: filter delegation sections by method
  and token; if any matched sections exist, try them and propagate errors
  (constraint violations are not swallowed); fall back to homeSection only
  if no sections match
- makeRedeemFn: submits delegation UserOp locally when bundler/smart
  account is available; relays to homeCoordRef.redeemDelegation() in
  peer-relay mode (away has no bundler; home's smart account is delegate)
- connectToPeer(ocapUrl): redeems URL, fetches homeSection, rebuilds routing
- initializeKeyring / unlockKeyring / isKeyringLocked, signMessage,
  signTypedData, listGrants, refreshPeerAccounts,
  sendDelegateAddressToPeer: peer setup and key management

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion-grant

Delete the monolithic coordinator-vat (3275 lines mixing home and away
concerns) and the old delegation-vat, now superseded by the home/away
split and the new delegator-vat/redeemer-vat pair.

Remove delegation-grant.ts, which built grants from raw CaveatSpec lists;
that role now belongs to delegator-vat, which encodes caveats and returns
pre-decoded TransferNativeGrant / TransferFungibleGrant values.

Update package.json build script: coordinator-vat → home-coordinator +
away-coordinator. Remove delegation-grant exports from index.ts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tor API

Replace old coordinator API references (createDelegation, provisionTwin,
listDelegations, pushDelegationToAway) with the new semantic grant methods
(buildTransferNativeGrant, receiveDelegation, listGrants, transferNative).

- wallet-setup.ts: launchWalletSubcluster now accepts role:'home'|'away'
  and points to home-coordinator.bundle/away-coordinator.bundle with the
  appropriate delegator/redeemer auxiliary vat
- setup-wallets.ts: replace createDelegation+provisionTwin with
  buildTransferNativeGrant+receiveDelegation
- docker-e2e.test.ts: delegation redemption suite uses new grant API;
  DelegationGrant type replaces old Delegation type; transferNative
  replaces sendTransaction for delegated ETH sends
- run-delegation-twin-e2e.mjs: rewrites twin test using
  buildTransferFungibleGrant+receiveDelegation+transferFungible
- docker-exec.ts: callVat now passes --raw to the CLI and decodes
  smallcaps CapData inline, fixing BigInt values arriving as
  '1000000000000000000n' strings from prettifySmallcaps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…unters

Normalize token to lowercase in makeDelegationTwin and the
transferFungible routing filter so checksummed vs. lowercase addresses
always match.

Introduce delegationTwinMap in rebuildRouting so existing twins are
reused instead of recreated, preserving in-memory spent counters across
receiveDelegation calls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cker-exec

Replace the manual typeof/in/Array.isArray guard with an is() check
against a CapDataStruct, per review feedback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… integration test

Same pattern as the docker-exec fix: replace manual typeof/Array.isArray
guard with assert() against CapDataStruct.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move applyGasBuffer, validateGasEstimate, and validateTokenCallResult
out of both coordinator vats into src/lib/tx-utils.ts. Both vats now
import from the shared module.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ation twin

The twin's M.eq guard is built with a lowercased token. Passing a
checksummed address from the outer transferFungible call caused the
guard to reject it. Compute tokenLower once and use it for both the
section filter and the exo call.

Adds a regression test that constructs a twin with a checksummed token
and asserts section.token is normalized.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…demo, add docker:ps/down:volumes, make docker:delegate pair-aware
@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 70.56%
⬇️ -7.92%
8033 / 11384
🔵 Statements 70.4%
⬇️ -7.90%
8166 / 11599
🔵 Functions 71.6%
⬇️ -4.32%
1954 / 2729
🔵 Branches 64.03%
⬇️ -12.24%
3242 / 5063
File CoverageNo changed files found.
Generated in workflow #4326 for commit 41a4dee by the Vitest Coverage Report Action

@grypez grypez force-pushed the grypez/evm-wallet-home-away branch from 62111cc to 9c824f4 Compare April 21, 2026 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant