Skip to content

feat: add evm-wallet-experiment package#877

Merged
sirtimid merged 185 commits intomainfrom
sirtimid/eth-wallet
Mar 17, 2026
Merged

feat: add evm-wallet-experiment package#877
sirtimid merged 185 commits intomainfrom
sirtimid/eth-wallet

Conversation

@sirtimid
Copy link
Copy Markdown
Contributor

@sirtimid sirtimid commented Mar 16, 2026

Summary

Adds @ocap/evm-wallet-experiment — a capability-driven EVM wallet implemented as an OCAP kernel subcluster. Uses the MetaMask Delegation Framework for delegated transaction authority via ERC-4337 UserOperations.

⚠️ Experimental: This package was developed with AI code generation assistance. It includes extensive test coverage but has not been formally audited. See the Disclaimer in the README.

Features

Core wallet

  • Key management in an isolated keyring vat (SRP/mnemonic or throwaway keys)
  • Optional AES-256-GCM mnemonic encryption at rest (password + PBKDF2)
  • Transaction signing, message signing, EIP-712 typed data signing
  • Ethereum JSON-RPC provider in a separate vat with fetch allowlisting

Delegation framework

  • Create, sign, and redeem delegations via the MetaMask Delegation Framework (Gator)
  • ERC-4337 UserOp pipeline: gas estimation, bundler submission, paymaster sponsorship
  • On-chain spending limits: per-transaction (ValueLteEnforcer) and cumulative (NativeTokenTransferAmountEnforcer)
  • On-chain delegation revocation via DelegationManager.disableDelegation
  • Batch execution: multiple transactions in a single UserOp for smart accounts

Smart accounts

  • EIP-7702 stateless smart accounts (home device — EOA becomes the smart account)
  • Hybrid DeleGator smart accounts (away device — counterfactual, deploys on first UserOp)

Multi-chain support

  • All 8 chains where the Delegation Framework is deployed: Ethereum, Optimism, BNB Smart Chain, Polygon, Base, Arbitrum One, Linea, Sepolia
  • Chain-aware setup scripts with --chain <name> (e.g. --chain base) and --rpc-url for custom providers
  • Same deterministic CREATE2 contract addresses on all chains

Token swaps

  • Swap quotes and execution via MetaMask Swaps aggregator API
  • Automatic ERC-20 approval handling (batched into a single UserOp when using a bundler)
  • Best-quote selection across multiple DEX aggregators

ERC-20 tokens

  • Balance queries, transfers, and allowance management
  • Token symbol/address resolution via on-chain registry and curated token lists

Peer wallet (home ↔ away)

  • Two-device architecture: home (keys) + away (VPS agent) connected over QUIC/CapTP
  • Automatic delegate address and delegation exchange over the peer connection
  • Offline autonomy: away device caches accounts and operates without the home device
  • Peer account caching with automatic refresh

OpenClaw agent plugin

  • 11 wallet tools: wallet_balance, wallet_send, wallet_token_balance, wallet_token_send, wallet_token_info, wallet_token_resolve, wallet_swap, wallet_swap_quote, wallet_sign, wallet_accounts, wallet_capabilities
  • Natural language interaction via OpenClaw AI agents

Setup & operations

  • Automated setup scripts for home (mnemonic + interactive/MetaMask modes) and away devices
  • Interactive MetaMask Mobile signing via MetaMask SDK (QR code connection)
  • update-limits.sh for changing delegation spending limits (revoke + re-create)
  • Relay support for NAT traversal (libp2p circuit relay)

Testing

  • 490+ unit tests (vitest, mocked vats)
  • 34 single-kernel integration assertions (real SES + kernel)
  • 27 peer wallet assertions (two kernels over QUIC)
  • 23 daemon integration assertions (JSON-RPC socket)
  • 13 Sepolia E2E assertions (on-chain UserOp submission)
  • 41 peer wallet Sepolia E2E assertions (full two-kernel flow)

Documentation

  • README — API reference, architecture, SES compatibility
  • How It Works — component diagram, data flow, supported chains
  • Setup Guide — step-by-step deployment for home + VPS

Test plan

  • 490+ unit tests pass (yarn workspace @ocap/evm-wallet-experiment test:dev:quiet)
  • Lint passes (yarn workspace @ocap/evm-wallet-experiment lint:fix)
  • Build succeeds (yarn workspace @ocap/evm-wallet-experiment build)
  • Swap tested end-to-end on Base mainnet (ETH → USDC)
  • Two-device setup tested (home laptop + VPS) with delegation exchange

🤖 Generated with Claude Code


Note

High Risk
Large new package introduces key management, signing, delegated transaction execution, and network/bundler interactions; these security- and funds-adjacent paths increase the risk of subtle authorization or RPC misuse bugs. CI is updated to run the new package’s E2E suite, but the surface area added is still substantial.

Overview
Adds a new @ocap/evm-wallet-experiment workspace package implementing an experimental capability-based EVM wallet subcluster, plus extensive docs and setup scripts (including an interactive MetaMask-driven home flow).

Introduces an OpenClaw plugin (openclaw-plugin/) that exposes wallet tools by shelling out to ocap daemon exec and decoding CapData, including token symbol resolution via MetaMask’s Token API and helper logic for formatting/awaiting transaction and UserOp results.

Updates CI to include the new workspace in the E2E matrix and adjusts root lavamoat.allowScripts to suppress native ws optional deps (bufferutil, utf-8-validate) used via vitest/jsdom.

Written by Cursor Bugbot for commit 28230aa. This will update automatically on new commits. Configure here.

@sirtimid sirtimid requested a review from a team as a code owner March 16, 2026 16:35
sirtimid and others added 29 commits March 16, 2026 17:37
…hereum wallet subcluster

Implements Phase 1 of the eth-wallet subcluster with:

- Keyring management (SRP mnemonic + throwaway keys, HD derivation, signing)
- EIP-7710 delegation framework (create, sign, receive, revoke, match)
- Coordinator vat orchestrating signing strategy resolution (delegation → local → peer)
- Provider vat wrapping JSON-RPC communication
- Cluster config using bundleSpec with `ocap bundle` build step
- 109 unit tests, all lint-clean

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add end-to-end integration tests validating two wallet subclusters
communicating via QUIC direct transport: peer connection via OCAP URL,
remote message/transaction signing, no-authority rejection, and
capabilities reporting.

Key fixes discovered during integration testing:
- Fix exo self-reference: use stored variable instead of `this`
- Fix delegation-vat parameters when undefined (no parameters configured)
- Fix signMessage peer forwarding with optional account field
- Add TextEncoder/TextDecoder to VatSupervisor allowed globals
- Add globals config to wallet vat cluster config
- Specify individual vat files in build script to exclude test files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…and MetaMask SDK signer

- Fix delegation matching to use proper ABI decoding instead of substring matching
- Add valueLte and timestamp caveat checks to delegationMatchesAction
- Make contract addresses configurable via ChainContracts registry
- Add UserOperation type (ERC-4337 v0.7) and Execution type
- Add userop.ts: delegation chain encoding, UserOp building, hash computation
- Add bundler.ts: submitUserOp, estimateGas, waitForUserOp polling
- Add metamask-signer.ts: MetaMask SDK signing adapter with provider abstraction
- Add @metamask/sdk dependency
- Add chainId option to WalletClusterConfigOptions and caveat helpers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…igner support

Connect the coordinator vat to the ERC-4337 UserOp pipeline for
delegation redemption, add external signer (MetaMask) integration,
and extend the provider vat with bundler RPC methods.

- Add submitUserOp/estimateUserOpGas to provider vat via viem http transport
- Add ExternalSignerFacet type and connectExternalSigner method
- Add configureBundler method with ENTRY_POINT_V07 default
- Add redeemDelegation method (full UserOp build → sign → submit flow)
- Extract resolveTypedDataSigning/resolveMessageSigning helpers
- Update all signing paths with keyring → external → peer priority
- Update createDelegation to work with external signer when no keyring
- Merge and deduplicate accounts from local + external signers
- Add hasExternalSigner/hasBundlerConfig to WalletCapabilities

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lidation, harden, and README

Wire the full ERC-4337 UserOp pipeline: EntryPoint nonce lookup, bundler
gas estimation, delegation status validation, explicit delegation chains,
and sendTransaction delegation path. Add harden() to all lib modules and
constants for SES compatibility, fix Date.now() in delegation matching,
add HTTP status check in bundler, restore derived accounts on keyring
resuscitation, add connectMetaMaskSigner test, and validate external
signer interface. Comprehensive README documenting architecture, home/away
kernel setup, signing strategy resolution, and delegation flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… estimation, and caveat handling

- Fix EIP-191 bug: add signHash for raw ECDSA UserOp hash signing
- Add delegation signature verification in receiveDelegation (EIP-712)
- Add erc20TransferAmount and limitedCalls caveat matching
- Add chain ID filtering in findDelegationForAction
- Add getGasFees provider method with EIP-1559 heuristic
- Make gas params optional in redeemDelegation/sendTransaction
- Add waitForUserOpReceipt polling on coordinator
- Make forceReset configurable in cluster config
- Export generateMnemonicPhrase from package index

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and makeChainConfig factory

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace manual UserOp/bundler/encoding pipeline with the SDK as the
single source of truth for contract addresses, delegation encoding,
and smart account management.

- Add `lib/sdk.ts` adapter wrapping all SDK imports (type mapping,
  environment resolution, delegation encoding, execution, smart account)
- Wire `constants.ts` to resolve addresses from SDK environment first,
  falling back to manual registry then placeholders
- Delegate `userop.ts` encoding to SDK (`encodeSdkDelegations`,
  `buildSdkRedeemCallData`)
- Add `lib/bundler-client.ts` using viem `createClient + bundlerActions`;
  wire `provider-vat.ts` to use it instead of raw `http()` transports
- Add `SmartAccountConfig` type with counterfactual address derivation
  via SDK's `getCounterfactualAccountData`
- Coordinator uses smart account address as sender/delegator when
  configured; signing still done by underlying EOA key
- Deprecate `lib/bundler.ts` (retained for backward compat)
- Add Sepolia (`SEPOLIA_CHAIN_ID`) and Pimlico constants

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t, remove dead code

- Add Pimlico paymaster sponsorship via `pm_sponsorUserOperation` RPC:
  `bundler-client.ts` gets `sponsorUserOperation()`, `provider-vat.ts`
  gets `sponsorUserOp()`, coordinator uses it when `usePaymaster` is set
- Add factory/factoryData fields to SmartAccountConfig and
  buildDelegationUserOp for first-time smart account deployment;
  coordinator marks account as deployed after first successful UserOp
- Fix critical signing bug: submitDelegationUserOp now resolves the
  EOA owner address for signing when a smart account is configured,
  instead of passing the smart account address to the keyring
- Wire coordinator.configureBundler() to call
  E(providerVat).configureBundler() for bundler client reuse
- Decouple constants.ts from sdk.ts to prevent SDK from being bundled
  into non-coordinator vats (SES lockdown compatibility)
- Revert userop.ts to manual ABI encoding (no SDK import) for same
  reason — SDK only enters coordinator-vat bundle now
- Remove dead code: fromSdkDelegation, resolveCaveatType,
  createHybridSmartAccount and their unused imports
- Add Sepolia E2E integration test (skips without env vars)
- Update README for SDK, Sepolia, Pimlico, smart accounts, paymaster

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix vat code to run under real SES lockdown and add plain Node.js
integration tests that bypass vitest SES issues.

SES fixes:
- Add TextEncoder/TextDecoder globals to coordinator vat config
- Add keccak256-counter fallback for generateSalt() (crypto unavailable)
- Add keccak256-counter fallback for throwaway key generation
- Add harden() to all delegation-vat return values and baggage persists

Tests:
- run-wallet.mjs: single-kernel test (34 assertions) — keyring init,
  signing, delegation lifecycle, throwaway keys, capabilities
- run-peer-wallet.mjs: two-kernel QUIC test (29 assertions) — peer
  connection via OCAP URL, remote signing forwarded over CapTP,
  delegation transfer, signature parity verification

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test the wallet subcluster through the daemon JSON-RPC socket, verifying
the full agent-to-wallet communication path: daemon → kernel → vats.

Covers: daemon getStatus, launchSubcluster via RPC, keyring init via
queueMessage, signing (message/tx/delegation), capabilities, error
propagation, and subcluster termination — 23 assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a Testing section describing all four test tiers: unit tests (275),
single-kernel integration (34), peer wallet over QUIC (29), and daemon
integration (23) — with commands and what each tier verifies.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add run-sepolia-e2e.mjs — a plain Node.js test that exercises the full
on-chain flow on Sepolia: smart account creation, delegation, UserOp
submission via Pimlico paymaster, and on-chain receipt verification.
Skips automatically when PIMLICO_API_KEY / SEPOLIA_RPC_URL are not set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…add Sepolia E2E

viem's createClient/createPublicClient uses Math.random() which is
blocked by SES lockdown. Replace with raw fetch-based JSON-RPC in both
provider.ts and bundler-client.ts. This also halves the provider bundle
size (800KB → 287KB).

Additional SES fixes:
- Add harden() to coordinator-vat for bundlerConfig, smartAccountConfig,
  and getCapabilities return values
- Add harden() to provider-vat for baggage persists
- Replace URL constructor validation with regex (URL unavailable in SES)
- Add platformConfig.fetch with allowedHosts to provider vat config

Sepolia E2E:
- Add run-sepolia-e2e.mjs (skips if PIMLICO_API_KEY/SEPOLIA_RPC_URL unset)
- Remove old vitest-based sepolia-e2e.test.ts (blocked by SES/vitest)
- Test passes through smart account creation + delegation signing
- UserOp on-chain submission requires further async pipeline work

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… a crank

When a vat's async operation (e.g. fetch) completes between cranks, the
resulting syscall.resolve was buffered with immediate=false. Since no
crank was active to flush the buffer, notifications were never delivered
and the crank loop never restarted — causing the kernel to hang.

Fix: check kernelStore.isInCrank() in VatSyscall handlers. During a
crank, continue buffering (immediate=false). Outside a crank, enqueue
immediately (immediate=true) so the run queue wakes up.

This unblocks any vat method that chains multiple E() calls with real
async I/O (e.g. eth-wallet's redeemDelegation pipeline which chains
getGasFees → getEntryPointNonce → sponsorUserOp → signHash → submitUserOp).

Also update eth-wallet README to reflect vitest integration tests now
passing, and fix Sepolia E2E delegation to use EOA as delegate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…UserOps

The UserOp callData must call the smart account's execute() function,
which routes to the DelegationManager, not call redeemDelegations
directly. Use DeleGatorCore.encode.execute() from the SDK to wrap the
redeemDelegations callData properly.

Also:
- Add Date to coordinator globals (SDK code uses Date.now at import)
- Add dummy 65-byte signature for paymaster sponsorship simulation
- Fix delegation delegate to match smart account (msg.sender)
- Add sponsorshipPolicyId to Sepolia test bundler config
- buildSdkRedeemCallData now requires chainId parameter

Sepolia E2E progress: 11/13 pass. Remaining issue is a Gator
contract-level error (0x155ff427) during delegation signature
verification in the redemption flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ationManager address

HybridDeleGator validates UserOp signatures as EIP-712 typed data over
PackedUserOperation (not raw ECDSA over the standard UserOp hash). Add
prepareUserOpTypedData() to sdk.ts and use signTypedData instead of
signHash in the coordinator's submitDelegationUserOp pipeline.

Also pass the real DelegationManager address (from SDK environment
resolution) to the delegation vat so EIP-712 verifyingContract matches
the on-chain contract. Previously used a zero-address placeholder,
causing InvalidERC1271Signature errors.

Sepolia E2E: 11/13 pass. Remaining AA24 signature error likely due to
packed UserOp format mismatch — needs further debugging of the EIP-712
domain/message encoding against HybridDeleGator's on-chain validation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix the remaining issues blocking on-chain delegation redemption:
- Use 'HybridDeleGator' as EIP-712 domain name (not 'DelegationManager')
- Add 10% gas fee buffer to meet Pimlico's bundler minimums
- Use unique deploy salt per test run to avoid AA10 (sender already
  constructed) errors
- Poll for UserOp receipt from test script (setTimeout unavailable
  under SES in vats)

Full on-chain flow verified on Sepolia:
  1. Smart account deployed via CREATE2
  2. Delegation created and EIP-712 signed
  3. UserOp submitted to Pimlico bundler with paymaster sponsorship
  4. UserOp included on-chain
  Tx: 0xe56bf8d5dfcc2377edd69f8f4a4ce3bfdcfd9279f165091c3afdb06acc6d6768

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix the OpenClaw plugin to use the actual OCAP daemon interface:
- Call `ocap daemon exec queueMessage` instead of a non-existent
  `wallet` binary
- Route all tools through the wallet coordinator via its kref
- Add wallet_capabilities and wallet_accounts tools
- Update plugin manifest with correct configSchema and uiHints
- Convert to plain JS (.mjs) for standalone deployment

Add docs/setup-guide.md with step-by-step instructions for:
- Building and starting the home daemon with wallet subcluster
- Setting up the away VPS with throwaway key + peer connection
- Delegating authority from home to away
- Installing and configuring the OpenClaw wallet plugin

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
OpenClaw expects TypeScript plugins. Add a local tsconfig.json for
the plugin directory and restore proper TypeScript types. Add plugin
loading instructions to the setup guide.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… and CLI examples

Co-authored-by: Cursor <cursoragent@cursor.com>
…coverage

Co-authored-by: Cursor <cursoragent@cursor.com>
…send

Decode daemon CapData for OpenClaw wallet tool outputs and infer a default sender before sendTransaction. Add unit and real daemon-backed integration tests for plugin behavior, plus a dedicated test:integration:plugin script.

Co-authored-by: Cursor <cursoragent@cursor.com>
Clarify that setup-away.sh does not install or configure the OpenClaw wallet plugin, and add a dedicated step-by-step section for plugin install, config, and tool allowlist.

Co-authored-by: Cursor <cursoragent@cursor.com>
Define the mock child process kill method before applying vi.spyOn so wallet plugin unit tests no longer throw on missing properties.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ationHints as RPC methods

Add kernel-control RPC handlers so the daemon CLI can initialize the
libp2p networking stack and register peer location hints. Update the
eth-wallet setup scripts to call these new methods (QUIC transport)
and pass listen addresses between home and away devices. Update the
setup guide docs to reflect the complete connection flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sirtimid
Copy link
Copy Markdown
Contributor Author

@SocketSecurity ignore-all

… vat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/evm-wallet-experiment/src/vats/coordinator-vat.ts
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tsconfig.json Outdated
Comment thread packages/evm-wallet-experiment/src/cluster-config.ts Outdated
sirtimid and others added 3 commits March 16, 2026 18:32
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Validate all batch actions against delegation, not just the first
- Fix tsconfig include to cover tools/ subdirectory
- Default forceReset to false to preserve wallet state across runs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…y missing

The ocap CLI binary may not be available in all CI environments.
Use describe.skipIf to gracefully skip instead of failing the suite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/evm-wallet-experiment/scripts/home-interactive.mjs
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/swap.ts
sirtimid and others added 2 commits March 16, 2026 18:49
The mock RPC server needs to handle eth_getBlockByNumber,
eth_estimateGas, eth_getTransactionCount, eth_chainId, and
eth_maxPriorityFeePerGas for viem to build transactions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The wallet_send tool now returns formatted output (UserOp hash, explorer
link) instead of a raw hex hash. Update assertion accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 16, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 77.26%
⬆️ +1.16%
7800 / 10095
🔵 Statements 77.07%
⬆️ +1.08%
7925 / 10282
🔵 Functions 75.27%
⬆️ +1.32%
1885 / 2504
🔵 Branches 74.65%
⬇️ -0.70%
3181 / 4261
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/evm-wallet-experiment/src/cluster-config.ts 100% 85.71% 100% 100%
packages/evm-wallet-experiment/src/constants.ts 96.55% 90% 75% 100% 3
packages/evm-wallet-experiment/src/index.ts 100% 100% 100% 100%
packages/evm-wallet-experiment/src/types.ts 91.3% 0% 33.33% 91.3% 28, 37
packages/evm-wallet-experiment/src/lib/bundler-client.ts 66.03% 50% 66.66% 66.66% 12, 118, 124-125, 131-139, 164-168, 177-182, 250-268, 293-296
packages/evm-wallet-experiment/src/lib/bundler.ts 88.88% 82.35% 85.71% 92% 9, 66-68, 157-159
packages/evm-wallet-experiment/src/lib/caveats.ts 100% 100% 100% 100%
packages/evm-wallet-experiment/src/lib/delegation.ts 92.06% 92% 90.9% 93.44% 20, 78-79, 251-256, 296-300
packages/evm-wallet-experiment/src/lib/erc20.ts 98.11% 91.66% 94.44% 100% 9
packages/evm-wallet-experiment/src/lib/keyring.ts 96.42% 91.66% 88.88% 100% 13
packages/evm-wallet-experiment/src/lib/metamask-signer.ts 88.09% 73.07% 83.33% 92.3% 29, 101, 107, 110, 180
packages/evm-wallet-experiment/src/lib/mnemonic-crypto.ts 97.43% 75% 85.71% 100% 6
packages/evm-wallet-experiment/src/lib/provider.ts 41.09% 16.66% 61.53% 41.42% 5, 45, 51-52, 58-76, 104-108, 117, 190-242
packages/evm-wallet-experiment/src/lib/sdk.ts 88.46% 85.71% 88.88% 89.79% 54, 352-371, 402
packages/evm-wallet-experiment/src/lib/signing.ts 100% 69.56% 100% 100%
packages/evm-wallet-experiment/src/lib/userop.ts 94.73% 50% 87.5% 94.44% 258
packages/evm-wallet-experiment/src/vats/coordinator-vat.ts 83.35% 74.15% 85.54% 83.41% 49, 73-75, 113-158, 440-443, 462-464, 484, 488, 681, 684, 720-722, 730, 745-749, 907-923, 952-955, 987, 1011-1014, 1023-1025, 1058-1061, 1080-1082, 1110-1113, 1125-1127, 1186, 1199, 1206, 1213, 1274-1276, 1405, 1424-1427, 1448-1456, 1500, 1534-1538, 1542-1545, 1553, 1649, 1719, 1755-1757, 1771-1773, 1797, 1815, 1919-1925, 2014, 2089, 2107, 2192, 2209-2212, 2239-2242, 2247, 2261, 2306-2307, 2349, 2357, 2360-2362, 2378, 2398, 2420, 2429-2439, 2449-2456, 2464-2473, 2475
packages/evm-wallet-experiment/src/vats/delegation-vat.ts 92.59% 79.41% 92.3% 94.33% 24, 112, 170, 195
packages/evm-wallet-experiment/src/vats/keyring-vat.ts 88% 82.85% 100% 87.87% 135, 146, 190, 205, 210, 227, 231, 239, 244, 248, 266, 270
packages/evm-wallet-experiment/src/vats/provider-vat.ts 78.57% 67.56% 90% 79.71% 12, 47-48, 53-60, 72-74, 87, 104, 119, 126, 133, 140, 203-204, 257
Generated in workflow #3938 for commit 28230aa by the Vitest Coverage Report Action

Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/swap.ts Outdated
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/eth.ts
- Validate decimal places in encodeEthToTerms instead of silent truncation
- Add try-catch for getTokenMetadata in swap token resolution
- Recognize native tokens (BNB, MATIC/POL) across supported chains
- Reject zero-value hex amounts in wallet_send

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/swap.ts
NATIVE_TOKEN_SYMBOLS replaced with NATIVE_TOKEN_BY_CHAIN map so that
BNB/MATIC/POL only resolve to the zero address on their home chains,
preventing incorrect native token resolution on other networks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/evm-wallet-experiment/scripts/home-interactive.mjs Outdated
Comment thread packages/evm-wallet-experiment/openclaw-plugin/utils.ts
…ygon

- Use BigInt constants for smart account funding thresholds to avoid
  floating-point precision issues that could produce negative fund amounts
- Accept both "MATIC" and "POL" as native token on Polygon (chain 137)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/eth.ts
Comment thread packages/evm-wallet-experiment/openclaw-plugin/tools/swap.ts Outdated
…ting to mainnet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Comment thread packages/evm-wallet-experiment/scripts/home-interactive.mjs
Comment thread packages/evm-wallet-experiment/openclaw-plugin/utils.ts
@grypez
Copy link
Copy Markdown
Contributor

grypez commented Mar 16, 2026

I would call it packages/evm-wallet-experimental, not packages/evm-wallet-experiment.

Otherwise, what kind of review do you want?

I have made a couple branches off of various stages of this work so having a trackable target sounds nice.

@sirtimid
Copy link
Copy Markdown
Contributor Author

I would call it packages/evm-wallet-experimental, not packages/evm-wallet-experiment.

Otherwise, what kind of review do you want?

I have made a couple branches off of various stages of this work so having a trackable target sounds nice.

Why use an adjective instead of a noun here though? Sounds a bit odd as a package suffix to me.

I ask just an approval to merge since this is a self-contained experimental package and it doesn't touch anything else. It's been manually tested end-to-end and has 500+ unit/integration tests. As we discussed, just getting it into main so we can iterate from there.

@sirtimid sirtimid enabled auto-merge March 16, 2026 21:57
@grypez
Copy link
Copy Markdown
Contributor

grypez commented Mar 17, 2026

For reasons I know not, -experimental is the standard suffix for a package that's a little more fast and loose than usual.

@sirtimid sirtimid added this pull request to the merge queue Mar 17, 2026
Merged via the queue into main with commit a2a205d Mar 17, 2026
33 checks passed
@sirtimid sirtimid deleted the sirtimid/eth-wallet branch March 17, 2026 13:00
sirtimid added a commit that referenced this pull request Apr 24, 2026
…n setup scripts

Both setup scripts configured the provider vat with `platformConfig: { fetch:
{ allowedHosts } }` and no fetch-family globals. The kernel's
`platformConfigStruct` (`kernel-platforms/src/capabilities/index.ts`) only
accepts `fs?: FsConfig`, so the `fetch` field was either rejected by
`isVatConfig` or silently dropped — leaving the provider vat unable to reach
any RPC. The correct form (already used in `cluster-config.ts`, the Docker e2e
helper, and the setup-guide config blocks) is:

    globals: [..., 'fetch', 'Request', 'Headers', 'Response'],
    network: { allowedHosts: hosts },

Pre-existing since the package's original introduction in PR #877. Also
extends `test/setup-scripts.test.ts` with per-role provider-vat assertions so
this exact class of drift (missing fetch globals, invalid `platformConfig`)
cannot silently regress.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants