Skip to content

feat: multichain EVM (Base + Ethereum + Polygon) in one wallet#16

Merged
TeoSlayer merged 1 commit into
mainfrom
multichain-evm
Jun 8, 2026
Merged

feat: multichain EVM (Base + Ethereum + Polygon) in one wallet#16
TeoSlayer merged 1 commit into
mainfrom
multichain-evm

Conversation

@TeoSlayer

Copy link
Copy Markdown
Contributor

A single secp256k1 key derives the same `0x…` address on every EVM chain, so the canonical pattern is "one signer, multiple bindings." v0.3.1 hardcoded a single chain; this lifts that:

```
--evm-chains 8453,1,137
```

The first id is the primary (used when `wallet.evm.*` requests omit `chain_id`). Per-chain RPC endpoints come from `PILOT_EVM_RPC_` env vars.

Adds Polygon native USDC

`0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` — NOT the bridged USDC.e. Only the native Circle-issued USDC contract exposes EIP-3009 `transferWithAuthorization`.

API

  • `wallet.evm.{address,balance,satisfy,verify}` accept optional `chain_id`. Omitted → primary.
  • New `wallet.evm.chains` returns the full configured set + primary marker.

Caps

`SatisfyEVMOn` still checks against the wallet-wide spendLog. A multichain wallet can't dodge a cap by switching chains.

Live-verified

```
methods=15
addr=0xfedc…21ad chain=1 token=0xa0b8…eb48 rpc=false
addr=0xfedc…21ad chain=137 token=0x3c49…3359 rpc=false
addr=0xfedc…21ad chain=8453 token=0x8335…2913 rpc=false
```

Same address on every chain (secp256k1 derivation is chain-agnostic), correct USDC contract per chain, `wallet.evm.chains` lists all three, unknown chain errors cleanly.

Test plan

  • go test ./... green
  • Post-merge: tag wallet-v0.3.2, upload bundle, bump catalogue.json

A single secp256k1 key derives the same 0x… address on every EVM
chain, so the canonical pattern is "one signer, multiple bindings."
v0.3.1 hard-coded a single chain at startup; this lifts that:

  --evm-chains 8453,1,137

The first id is the primary (used when wallet.evm.* requests omit
chain_id). Per-chain RPC endpoints come from PILOT_EVM_RPC_<chainID>
env vars; the primary chain also accepts --evm-rpc / $PILOT_EVM_RPC
for compatibility with v0.3.1.

## pkg/evm
- Adds ChainPolygonMainnet (137) + native Circle-issued USDC at
  0x3c499c… (NOT the bridged USDC.e — only the native contract
  exposes EIP-3009 transferWithAuthorization).
- KnownChainIDs helper for callers iterating supported chains.

## pkg/wallet
- New evmByChain map[chainID]*evmBinding alongside the existing
  primary `evm *evmBinding`. NewWithEVM stays as a thin wrapper over
  the new NewWithEVMs([]EVMConfig).
- Per-chain accessors: EVMChainIDs, HasEVMChain, HasEVMRPCFor,
  EVMTokenFor, EVMBalanceFor, EVMMethodFor.
- SatisfyEVMOn(ctx, chainID, contract) is the multichain entry; old
  SatisfyEVM delegates to it with the primary chain. Caps still
  apply against the wallet-wide spendLog regardless of chain, so a
  multichain wallet can't dodge a cap by switching chains.

## pkg/walletipc
- wallet.evm.{address,balance,satisfy,verify} all accept optional
  `chain_id`. Omitted/0 means primary.
- New wallet.evm.chains returns the full configured set.

## cmd/wallet
- --evm-chains comma-separated list; preserves the old single-chain
  shape (--evm-chain → --evm-chains) under the new flag name.
- Logs one line per chain at startup so an operator can confirm
  exactly what landed.

## Version
0.3.1 → 0.3.2. Manifest exposes list adds wallet.evm.chains;
manifest_test confirms the binary's --version constant matches.

## Live-verified
methods=15, same address on every chain, wallet.evm.chains lists
{8453, 1, 137}, address+balance routes by chain_id, unknown chain
errors cleanly.
@TeoSlayer TeoSlayer merged commit 1d9a95e into main Jun 8, 2026
2 checks passed
@TeoSlayer TeoSlayer deleted the multichain-evm branch June 8, 2026 09:12
@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.04046% with 102 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/wallet/hooks_evm.go 25.00% 44 Missing and 7 partials ⚠️
pkg/walletipc/dispatcher_evm.go 47.16% 22 Missing and 6 partials ⚠️
cmd/wallet/main.go 65.11% 8 Missing and 7 partials ⚠️
pkg/evm/chains.go 11.11% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

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