feat: EIP-8130 (native account abstraction) + ERC-8168 payer services - #5004
Draft
chunter-cb wants to merge 79 commits into
Draft
feat: EIP-8130 (native account abstraction) + ERC-8168 payer services#5004chunter-cb wants to merge 79 commits into
chunter-cb wants to merge 79 commits into
Conversation
Adds a ground-up `viem/experimental/eip8130` module implementing the EIP-8130 (`AA_TX_TYPE` = 0x7b) wire format: - serializeTransaction8130 / parseTransaction8130 (round-trip) - sender (AA_TX_TYPE) and payer (AA_PAYER_TYPE) signature hashes - account_changes encoders/decoders: create, config (actor changes with scope/expiry/policy), and delegation entries - 2D nonce, nonce-free mode, and self-pay/sponsored payer modes - constants, actor/authenticator types, and structural assertions
Adds signTransaction8130 producing sender_auth (EOA raw signature or ECRECOVER_AUTHENTICATOR || signature for configured actors) and, for sponsored transactions, payer_auth bound to the resolved sender.
Adds computeAddress8130 (and the DEPLOYMENT_HEADER builder) for create entries: actors_commitment over sorted [actorId || authenticator], an effective salt over user_salt, and CREATE2 derivation against ACCOUNT_CONFIG_ADDRESS. Address constants are placeholders pending the canonical base/eip-8130 deployment and are overridable per call.
Adds account-configuration support: - canonical authenticator set constants (k1 native sentinel; p256, passkey, delegate placeholders) and actorIdFromAddress - hashActorChanges8130 (SignedActorChanges ABI digest) and signActorChanges8130, returning a ready config account-change entry - IAccountConfiguration / IAuthenticator / precompile ABIs Shares the actor-change `data` encoder with the transaction serializer.
Enables routing the same account between 8130 and non-8130 chains: - is8130Enabled chain registry + predicate (AA_TX_TYPE vs ERC-4337) - toFactoryArgs8130 / encodeCreateAccountData: ERC-4337 factory args via the AccountConfiguration contract (address matches computeAddress8130) - encodeApplySignedActorChangesData: portable any-chain config-change path
Lets the same EIP-8130 account run on non-8130 chains via a bundlerClient, backed by the canonical BackwardCompatibleERC4337Account wallet: - toSmartAccount8130: encodeCalls via executeBatch(Call[]), getFactoryArgs via AccountConfiguration.createAccount, getAddress via computeAddress8130, and signatures in authenticator||data form for authenticateActor validation - erc4337AccountAbi for the wallet (executeBatch/validateUserOp/isValidSignature) - erc1167Bytecode helper for the minimal-proxy deployment code
…alls) High-level surface over the 8130 primitives: - to8130Account: create()/change()/delegate()/signTransaction() lifecycle - key builders (k1/p256/passkey/delegate) + actorIdFromPublicKey (keccak256(x||y)) and scope/policy helpers (toScope, authorizeActor, revokeActor, encodePolicyData) - sendCalls8130 / prepareTransaction8130: prepare (fees + nonce), sign, serialize and submit an AA_TX_TYPE transaction
Ties payer sponsorship into the 8130 transaction flow: - createPayerClient: payer_* JSON-RPC (getTerms/sendTransaction/ signTransaction/getBalance/getSponsorshipOptions/getCapabilities) - buildSponsoredCalls: phase construction from terms (full sponsorship, token payment, required calls) + ERC-20 transfer encoding - sendSponsoredCalls: getTerms -> build -> prepare -> sender co-sign (payer_auth empty) -> payer_sendTransaction / payer_signTransaction - full ERC-8168 types + error codes; viem/experimental/eip8168 subpath
- add eip8130Deployments registry (AccountConfiguration, account impls, authenticator contracts) with getEip8130Deployment(chainId) - replace placeholder accountConfigAddress / defaultAccountAddress and canonical p256/passkey/delegate authenticators with the deployed values
…tion The deployed AccountConfiguration contract decodes an authorizeActor change's `data` via abi.decode(data, (ActorConfig, bytes)), but our codec used RLP per the EIP-8130 text. RLP data reverts at abi.decode, so applySignedActorChanges could not land on-chain. Consolidate on a single ABI encoder/decoder (actorChangeData.ts) used by the config-change digest, the applySignedActorChanges calldata, and the native-wire serialize/parse paths. Validated end-to-end on Base Sepolia: account creation and a P-256 session-key authorization both land and read back as expected. Adds gated (PRIVATE_KEY) integration scripts for the two on-chain flows.
toSmartAccount8130 now signs the raw userOpHash (no EIP-191 prefix) to match on-chain validateUserOp, with a pluggable `sign` and configurable `stubData` for non-k1 authenticators. Adds Base Sepolia scripts that drive ERC-4337 flows, including self-bundled create+execute via EntryPoint.handleOps (AccountConfiguration as the factory, no staking).
Add encodeSignedActorChangesSignature (+ signedActorChangesMagic): builds a
BackwardCompatibleERC4337Account userOp signature carrying SignedActorChanges[]
(abi.encode(magic, [{ changes, auth }, ...])). Applying the signed change chain
during validateUserOp authorizes the op — no separate op signature. Sets apply
in order, enabling chained rotations. Adds a Base Sepolia script that creates an
account and authorizes a P-256 actor in the validation phase in one self-bundled
userOp.
New Deploy.s.sol + CreateAccounts.s.sol run: AccountConfiguration: 0xb0198a714872EE5bfDF829e7986DB5C5899a6b50 DefaultAccount: 0x124b52d5D57a76ed064c414975beA11Beffe0251 DefaultHighRateAccount:0x13dD0F222cCF60B7C08a95C2d1FcC85A38DD675D ERC4337Account: 0x9748aeA1e1762E50a4d8927777FeDB63A2Ef06C0 DelegateAuthenticator: 0xE67D299Ff3F0a185398B6C5a28998696969265d7
…ployment The deployed BackwardCompatibleERC4337Account decodes the signed-actor-changes signature as (bytes32 magic, SignedActorChanges[] changeSets, bytes opAuth) and authenticates the op via the trailing opAuth blob over userOpHash. Re-add the opAuth parameter to encodeSignedActorChangesSignature to match, and pass the correct AccountConfiguration address through the self-bundle scripts. - constants: point accountConfigAddress / defaultAccountAddress at the latest Base Sepolia deployment - signedActorChangesSignature: add required opAuth arg + update tests - scripts: pass accountConfigAddress explicitly; selfBundleRotateP256 signs userOpHash as opAuth and uses sequence 1 (createAccount seeds localSequence=1)
…d tx demo
Move the EIP-8130 dev/integration scripts into a dedicated scripts/eip8130/
folder and collapse the vitest include to a single glob so new scripts are
picked up automatically. Add build8130Transaction: an offline demo that builds,
signs, serializes, and parses an EIP-8130 transaction, printing the JSON object,
the RLP envelope, and the decoded 13-field wire layout. The demo highlights that
a call is only { to, data } (no per-call value).
Add optional `value` to `AaCall` and `encodeWalletCalls`, which routes value-bearing phases through the account's `executeBatch` (pluggable via `encodeExecute`) while passing value-less calls through as `[to, data]`. Wire into `sendCalls8130` and reject non-zero `value` at serialization.
- Rename payer_getSponsorshipOptions → payer_getOptions (method + types) - Rename maxCost → paymentAmount in PayerTokenOption and buildSponsoredCalls - Fix SponsorshipOption: type 'full_sponsorship' → 'sponsored', tokenSymbol → symbol, estimatedCost → estimatedAmount; rename to PayerOption - Fix error codes: -32600–32608 range → -32001–32009 (JSON-RPC impl-defined range; the old codes conflicted with JSON-RPC 2.0 protocol errors) - Add overhead to PayerGasEstimate; add usdRate + refund to PayerTokenOption - Add RefundPolicy type; add feeRecipient, callPolicy, refund to PayerChainCapabilities; remove non-spec requiredChainId from PayerConditions - Add payer_fillTransaction method to PayerClient - Fix expiry semantics: terms.expiry is relative (seconds from now); convert to absolute on-chain timestamp in sendSponsoredCalls, clamped to conditions.maxExpiry / minExpiry - Update tests: use relative durations, freeze time for deterministic expiry assertions, add payer_getOptions mapping test
Add EIP-8130-aware JSON-RPC actions matching the base node RPC surface: - getTransactionCount8130: read the 2D channel nonce via the eth_getTransactionCount nonce_key extension. The NonceManager precompile is not callable via eth_call, so this replaces the reverting readContract path in prepareTransaction8130. - estimateGas8130: eth_estimateGas for AA_TX_TYPE with declared sender/payer auth scheme + size and an optional sponsoring payer (MAX_AUTH_SIZE guarded). - getTransactionReceipt8130 + parseEip8130ReceiptFields/allPhasesSucceeded: surface payer, phaseStatuses, and metadata off the receipt (graceful when absent on older nodes). Also brings in the session-policy helpers (policies.ts), signer adapters (signers.ts), serialization/parse alignment, and the vibenet devnet deployment with their tests.
Update the ERC-8168 module to the revised spec: offer-based terms with a top-level gasEstimate, the sponsored/sponsored_declined/token discriminants, the single -32000 payerRejected error envelope with a string data.code, and count/asset balance limits. Adds parsePayerError and refreshes the tests.
Reads the local and multichain config-change sequences from the AccountConfiguration system contract. Always supply the active chain's deployment address so vibenet and Base Sepolia use the correct contract rather than a hardcoded constant.
…esses - getPayerSignatureHash8130: include `payer` field in the RLP body to match the Rust node's payer_signature_hash (which encodes all fields including the payer slot). Previously the payer field was excluded, producing a hash mismatch that caused "actor is not bound" errors. - deployments: replace stale per-chain address objects with a single canonicalEip8130Deployment derived from solc 0.8.33 via Deploy.s.sol. Both baseSepoliaDeployment and vibenetDevnetDeployment now reference the same canonical set (accountConfiguration 0xC659…, P256 0x3AE1…, etc.). The execution client enshrines these addresses; using any other accountConfiguration causes "create address mismatch" on account creation.
…e 0x7b formatting - Add getTransaction8130 action: fetches an EIP-8130 tx by hash, flattens the nested `tx` body returned by the node, injects the request hash (absent from the RPC response), and returns a fully-typed Transaction8130 object with all EIP-8130 fields. - Add waitForTransactionReceipt8130 action: polls until an EIP-8130 tx is mined using getTransactionReceipt8130 (which surfaces the EIP-8130-specific receipt fields). Skips the replacement-detection path since EIP-8130 uses 2D nonces. - getTransaction: flatten type 0x7b responses inline so the standard path also works for EIP-8130 txs (injects hash, maps nested body fields to the expected flat shape). - waitForTransactionReceipt: skip candidates with no hash — can occur when a block contains a type 0x7b tx that the generic parser can't fully deserialize. - formatters/transaction: register '0x7b' -> 'eip8130' in transactionType. - Add vibenet 6-part integration test covering: EOA plain tx, EOA owner change, EOA with new key, smart account create, smart account tx, and smart account key rotation.
…& 8) Tests 7 and 8 cover the full P256 lifecycle on vibenet: 7. P256 smart account — createAccount + ETH send (P-256 signer) 8. P256 smart account — follow-up send with same P-256 key (no redeploy) Uses toP256Signer + ox/P256.randomPrivateKey to generate a fresh key each run and verifies end-to-end: fund → create → send → balance check.
Add accountChanges + calls parameters to EstimateGas8130Parameters. When present, the request is sent as a complete EIP-8130 tx body so the node routes through the real executor simulation (required for create account-change pricing and accurate per-phase call cost). When omitted, the existing simplified mode is used unchanged (backward compatible). The serialize helper converts typed AaAccountChange objects to the plain JSON the node's eth_estimateGas deserialiser expects.
Forward senderAuthScheme/senderAuthSize to the node even when accountChanges/calls are present, so the node can price intrinsic auth gas correctly for accounts not yet deployed on-chain (where it can't infer the scheme from account state).
…t, key.webAuthn - key.webAuthn: alias for key.passkey to match deployment naming convention - newSmartAccount8130(params): factory that auto-derives actor from signer type (K1/P256/WebAuthn detected from publicKey + authenticator), generates a random salt, defaults code to canonical DefaultAccount, and exposes createChange as a property for convenient first-tx usage - toEoa8130Account(signer): wraps a K1 EOA for EIP-8130 txs using the implicit self-actor path (raw 65-byte sig, no authenticator prefix, no smart contract) - Export canonicalEip8130Deployment for downstream consumers
…EOAs
Split To8130AccountParameters into two shapes:
- Smart account (userSalt + code + initialActors): derives CREATE2 address,
exposes create()
- Delegated EOA (address only): binds to a known address, no salt/code/actors
needed, create() throws with a clear message directing to delegate(impl)
This fixes the DX smell where EOA delegation required dummy userSalt/code/
initialActors. Now: to8130Account({ signer, address: eoaAddress }) is all
that's needed for the delegated-EOA path; the first tx uses delegate(impl)
in accountChanges and change([...]) to add actors.
…change + sign Adds `delegate(target)` and `change(actorChanges, opts)` to `toEoa8130Account` so a bare EOA can build its first-tx delegation and actor-config changes without needing a second account handle. `signTransaction` still uses the implicit self-actor path: no `from` field, raw 65-byte K1 signature, sender recovered via ecrecover.
Resolves the sender (`from`) of an EIP-8130 transaction: returns `transaction.from` when present, otherwise (EOA path, where the wire omits `from`) recovers it via ecrecover over the sender signature hash computed with `from` empty — matching the node. Lets relayers / payers bind to the resolved sender for EOA-path txs.
Track the new AccountConfiguration deployment and default canonical accounts to ERC-1167 proxies over DefaultAccount, avoiding stale unaudited example implementations.
# Conflicts: # src/experimental/eip8130/accounts/to8130Account.ts # src/experimental/eip8130/actions/sendCalls.ts # src/experimental/eip8130/errors.ts
Detect when a signed expiry has passed while waiting for inclusion and throw TransactionExpiredError. Thread the resolved expiry via onTransaction on sendCalls8130 and sendSponsoredCalls so callers do not rely on pending eth_getTransactionByHash.
The node rule is: an actor must use nonce-free (expiring) mode only if it is non-admin AND lacks SCOPE_NONCE. Admin actors (scope 0x00) and SCOPE_NONCE actors may use ordered (sequenced) OR nonce-free nonces. canUseSequencedNonce / isNoncelessOnly wrongly treated admin (scope 0) as nonceless-only because bit 0x04 was unset, forcing admin owners into nonce-free/expiring mode (and throwing NonceScopeError on a sequenced nonceKey). Fix the predicate so admin is allowed ordered nonces; sends now default to ordered (expiry-free) for admin owners. Also auto-default the expiry for any nonce-free send (including admin/SCOPE_NONCE actors opting in) rather than throwing. Update NonceScopeError text and doc comments, and fix the nonce integration test mock to answer eth_call (actor-not-bound → declared scope fallback).
Bring the experimental EIP-8130 module to parity with the finalized Keystore.sol contracts: - Update canonical CREATE2 addresses to the per-contract vanity-mined 0x8130… deployments (Keystore, account impls, authenticators, policies). - Switch counterfactual address derivation to the leaves-then-list `_computeActorsCommitment` scheme with `scope` widened to uint16. - Replace the transaction `expiry` field with `validAfter`/`validBefore` (unix milliseconds) across serialize/parse/hash/assert and consumers. - Adopt the SignedAccountChanges / AccountChange(changeType, payload) model with the full ChangeType enum (authorize/revoke/incrementLocalEpoch /lock/unlock), ABI-encoded payloads, channel+sequence, and the reworked digest and applySignedAccountChanges calldata. - Rebuild lock.ts as lockChange()/unlockChange() batch ops. - Drop redundant `8130` suffixes from module filenames. - Refresh colocated unit tests, golden vectors, docs, and scripts.
- actorId: right-align address-derived IDs to bytes32(uint256(uint160)) to match the finalized Keystore (was left-aligned bytes32(bytes20)), which unblocks the EVM applySignedAccountChanges path. - isActor: derive from getActorConfig (authenticator != zero) since the contract no longer exposes isActor. - getPolicy: read via the combined getActor accessor. - abis: drop removed isActor/getPolicy, add getActor. - sendCalls: thread validAfter through prepareTransaction.
Promote EIP-8130 (native account abstraction) and ERC-8168 (payer
sponsorship) from `viem/experimental/*` to top-level `viem/eip8130` /
`viem/eip8168` for a production-ready, upstream-submittable surface.
- move src/experimental/eip813{0,8}* -> src/{eip8130,eip8168} and rewrite
every internal import specifier
- add ./eip8130 + ./eip8168 export and typesVersions maps (drop the
experimental entries); update knip entry globs
- repoint scripts, the eip8130 vitest config, and site docs/sidebar to the
new paths
- refresh unit tests for the finalized Keystore reads (getActorConfig /
getActor), right-aligned actorId, and validBefore (unix ms)
- biome format + organize-imports across both modules; drop dead
noExplicitAny suppressions
Validation: full build, publint --strict + attw (viem/eip8130, viem/eip8168
all green), and the eip8130/eip8168 unit suite (123 tests) all pass.
- scripts README: drop "experimental/temporary" framing; point at the docs - buildTransaction demo: print the real 15-field wire layout (valid_after/valid_before/metadata) instead of the stale 13-field/expiry list - receipts guide: use `validBefore` (unix ms), matching waitForTransactionReceipt (the tx has no `expiry` field) - fix stale `viem/experimental` doc-imports -> `viem/eip8130`
A wallet may reach a payer several ways at once — the chain's node RPC, a
block builder integrated with the sequencer (e.g. flashblocks), an app
endpoint, or a wallet-injected payer. Add a discovery surface that queries
them all in parallel and presents one PayerClient.
- createAggregatePayerClient({ payers }): fans `getTerms` out with
Promise.allSettled (a slow/failing source never blocks the rest), merges
offers best-first in source order, and routes `payer_sendTransaction` /
`payer_signTransaction` back to the source that offered the tx's `payer`.
It is itself a PayerClient, so it drops into sendSponsoredCalls unchanged.
- toChainPayerClient(client): adapt the wallet's execution client into a
PayerClient when the chain/builder serves `payer_*` natively.
- hasChainPayerService + payerServiceChainIds registry (mirrors is8130Enabled),
no core Chain type change.
- unit tests (parallel merge, source-order, failure skip, tx.payer routing,
balance concat) + a "Discovering payers" docs section.
… production typecheck
- newSmartAccount: `proxy: 'erc1167' | 'upgradeable'` (default `upgradeable`,
which requires an explicit UUPS implementation until one is enshrined) plus
`admins`/`extraActors` for the initial actor set. Widen the `signer` type so a
standard K1 `privateKeyToAccount` (SEC1 hex `publicKey`) typechecks — the
primary documented usage previously did not compile.
- Update canonical EIP-8130 addresses to the regenerated vanity set (Keystore,
DefaultAccount, high-rate account, authenticators, policy manager + session).
- Docs: document the proxy/admins API and correct the ERC-4337 portable-path
section (`accounts.erc4337` is intentionally out of scope / not enshrined;
supply your own deployed implementation).
- Typecheck: exclude the manual, network-gated `scripts/eip8130` demos from
`check:types` (they run via their own vitest config); fix test type looseness
(call `to` literals typed as `0x${string}`, PaymentOption token-variant cast).
eip8130 + eip8168 sources and unit tests (137) are type-clean; publint reports
no problems and attw is green for `viem/eip8130` and `viem/eip8168`.
base/eip-8130 wevm#79 skips expired unsequenced (JIT) `AuthorizeActor` grants instead of reverting and removes the `ExpiredChange` error. That is a contract-side behavior change with no viem surface — viem never documented the revert path — so no client logic changes. The bytecode change regenerated the `0x8130` vanity CREATE2 addresses (verified via `forge script Deploy.s.sol --sig addresses()`): - Keystore, DefaultAccount, CanonicalHighRatePayerAccount - DelegateAuthenticator, PolicyManager, SessionPolicy - P256 / WebAuthn authenticators unchanged Updates `deployments.ts` + `constants.ts` to the new set (all valid EIP-55) and refreshes the `commitmentOf` reference vector (depends on the SessionPolicy address). eip8130 + eip8168 unit tests (137) pass.
`incrementLocalEpoch` (ChangeType 0x02) was fully plumbed (type, wire byte,
encode/parse/gas) and already accepted by `account.change`, but had no
ergonomic builder like `authorizeActor` / `revokeActor` — callers had to
hand-write `{ changeType: 0x02 }`. Add a named, discoverable, typed builder
plus a serialize<->parse round-trip test, and document it in the owner-rotation
guide as a "revoke all pending" epoch kill-switch.
Reads already expose the epoch via `getConfigSequence` (`localEpoch`); lock /
unlock already ship `lockChange` / `unlockChange` builders in `lock.ts`.
The local config sequence is a packed `localEpoch << 32 | localSequence` word that can exceed Number.MAX_SAFE_INTEGER, and `account.change` takes a `bigint`. Drop the lossy `Number(sequence)` in the rotate-owners examples.
Lowers a `wallet_grantPermissions` request (7715 permissions + expiry) onto EIP-8130 session-key primitives: - `toSessionPolicyConfig(permissions)`: pure mapping of native/erc20 transfer and contract-call permissions (+ token-allowance / rate-limit policies) to a `SessionPolicyConfig`. rate-limit `interval` becomes the cap's reset `period` (recurring allowance); gas-limit is left to the payer/8168 layer; unbounded transfers and custom permissions/policies throw. - `toSessionPolicy(params)`: binds the lowered config to an account via `defineSessionPolicy`, mapping the 7715 `expiry` to `validUntil`. Exported from viem/eip8130, unit-tested, and documented in session-keys.
Extends the ERC-7715 adapter into a full wallet-side fulfillment that returns
the ready-to-sign authorizeActor change, always POLICY-gated:
- `role: 'session'` (default) → k1 actor, acts via PolicyManager.execute.
- `role: 'pull'` → external-pull sentinel actor (EXTERNAL_POLICY_AUTHENTICATOR),
draws via PolicyManager.executeFor from its own address.
A single ERC-7715 `expiry` drives both the actor authorization and the policy
binding's validUntil so they can't drift.
Supporting additions:
- `externalPolicyAuthenticator` constant (keccak256("externalPolicyCaller")).
- `key.externalPull(address)` actor builder.
- `SessionPolicy.executeForCall` (PolicyManager.executeFor encoder).
Exported from viem/eip8130, unit-tested (session + pull), and documented.
fulfillGrantPermissions is now an action (client, parameters): it reads the account and, if the policy manager isn't yet a trusted-executor actor, folds that one-time registration into the returned `changes` batch (managerChange first, then the grantee change). One `account.change(changes)` now both provisions the manager and authorizes the grantee. - adds `managerChange` + `changes` to the return; `assumeManagerRegistered` option skips the on-chain read. - tests cover registered / unregistered / skip paths for session + pull.
…account Fulfills a wallet_addSubAccount (type: 'create') request as a distinct 8130 smart account (own address, asset isolation) whose initial owner set is the requested keys plus key.delegate(parent). The parent-control link is installed at creation (in createChange) — no separate change tx — and the returned handle signs for the sub-account with the parent's signer via the delegate authenticator. - maps ERC-7895 key types → owner actors (address→k1, p256/webcrypto→p256, webauthn→webAuthn); rejects duplicate/colliding actor ids. - returns the account handle + createChange + parentActor + ERC-7895 response. - unit-tested and documented in sub-accounts.
…nt keys - eip8130Capabilities / eip8130CapabilitiesByChain: wallet-side descriptor for wallet_getCapabilities advertising exactly what the adapters support — atomic batches, ERC-7715 grants (permissions/policy/signer types), and ERC-7895 sub-accounts (key types); optional paymasterService (ERC-8168). custom and gas-limit are deliberately not advertised (can't be lowered to a SessionPolicy). - fulfillAddSubAccount: add keyScope / keyPolicy so requested keys can be registered as scoped (optionally policy-gated) session-key actors instead of full co-owners, keeping the parent the sole unrestricted owner. Both exported from viem/eip8130, unit-tested, and documented.
…mption)
Adds the ERC-7715 redemption path so a granted key's calls can be routed
through the policy manager with no wallet-side storage:
- toPermissionsContext / parsePermissionsContext: encode a grant into an opaque,
self-describing context (account, role, actor, full policy binding) and decode
it back into a rebound SessionPolicy (recomputes the same commitment).
- routePermissionedCalls({ context, calls }): wraps each action as
session.executeCall (session key, dispatched as the account) or
executeForCall (external pull actor).
- fulfillGrantPermissions now also returns `permissionsContext`.
Exported from viem/eip8130, round-trip + routing tests, and documented.
…-closed Update canonical SessionPolicy to 0x813070914C530d030f4Efd8Fa99C18e836435e55 (re-mined after base/eip-8130#80; PolicyManager unchanged). Document that native ETH is fail-closed: a session key can only move value with a zero-address tokenLimit; absent means no ETH, not unlimited.
…ction # Conflicts: # package.json # scripts/tsconfig.json
|
@chunter-cb is attempting to deploy a commit to the Wevm Team on Vercel. A member of the Team first needs to authorize it. |
|
soheimam
added a commit
to base/skills
that referenced
this pull request
Aug 13, 2026
The 8130 modules aren't on npm yet (upstream PR wevm/viem#5004 is still a draft), so they must be built from the chunter-cb/viem feat/eip-8130-production fork. Doing the clone→pnpm build→npm --install-links dance by hand is error-prone, so bundle it as scripts/setup-viem-8130.sh (idempotent, branch overridable via env). Rewire SKILL.md to lead with the script and keep the manual steps in a collapsible "what it does and why" section. Script header notes the whole thing collapses to `npm install viem@latest` once the PR ships. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
Revert incidental `on-chain` -> `onchain` wording changes in tempo and circle-usdc pages/tests that were unrelated to the EIP-8130 work, so the upstream PR stays scoped to the new eip8130/eip8168 modules.
Remove `scripts/eip8130/**`, `scripts/smoke-estimate-sender-actor.mjs`, and the dedicated `test/vitest.eip8130.config.ts`, and revert `scripts/tsconfig.json` to upstream. These were deep-relative-import, credential/testnet-gated dev harnesses excluded from CI and `check:types`, with no upstream precedent under `scripts/`. CI-covered behavior remains fully tested by the colocated `src/eip8130/**/*.test.ts` suites. Harnesses remain recoverable in git history.
soheimam
added a commit
to base/skills
that referenced
this pull request
Aug 14, 2026
…haviour (#149) * updated vibenet skill * vibenet: correct endpoints, add account lifecycle, fix verified-wrong guidance Verified live against the devnet by building a Next.js app end to end. Endpoints: API host moved vibes.base.org -> api.vibes.base.org (the bare host 302s to an HTML page, which viem reports as "Unrecognized token '<'"). Add faucet/status, chain-health and explorer. rpc.vibes.base.org is CORS-enabled, so the browser proxy is optional rather than required. Lifecycle: new section covering counterfactual -> deployed. There is no deploy step; the first transaction creates the account. Sponsored is the shortest path (no faucet). Read deployment from eth_getCode, never optimistic local state. Corrections, all reproduced live: - sendSponsoredCalls resolves with { transactionHash }; the previous text said the opposite and the declared return type is wrong. - A bad config sequence is rejected at broadcast, not silently applied. The real trap is the inverse: a change can apply on a tx reporting status 0x0. - The end-to-end example imported core viem helpers from the 8130 module, which does not export them, so it could not compile. - npm file: installs need --install-links or Turbopack cannot resolve viem. New gotchas: payer validation lags ~1 block after deploy ("actor is not bound"); "no backend is currently healthy" means the devnet is halted; a value-bearing call to a never-funded address reverts. * docs: frame vibenet as Base Vibes in README, add example usage Adds vibenet prompt examples alongside the existing ones, plus a worked gasless-onboarding snippet showing the counterfactual-to-deployed flow with an ERC-8168 payer. The snippet was compiled and run live against the devnet (deployed at a zero balance, status 0x1). * updated viem package * vibenet: add setup-viem-8130.sh installer, lead install with it The 8130 modules aren't on npm yet (upstream PR wevm/viem#5004 is still a draft), so they must be built from the chunter-cb/viem feat/eip-8130-production fork. Doing the clone→pnpm build→npm --install-links dance by hand is error-prone, so bundle it as scripts/setup-viem-8130.sh (idempotent, branch overridable via env). Rewire SKILL.md to lead with the script and keep the manual steps in a collapsible "what it does and why" section. Script header notes the whole thing collapses to `npm install viem@latest` once the PR ships. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * updated readme removed examples --------- Co-authored-by: Claude <noreply@anthropic.com>
…cal changes - getConfigSequence now defaults `accountConfiguration` to the canonical (enshrined) keystore, matching every sibling read (getLockStatus, isLocked, getActorConfig, getPolicy, isActor). There is a single keystore, so callers no longer pass it. - Add first-class support for unsequenced (JIT) local changes: the `unsequencedLocalHalf` sentinel (type(uint32).max, mirrors Keystore.UNSEQUENCED) and `unsequencedLocalSequence(localEpoch)` helper that packs `localEpoch << 32 | UNSEQUENCED` for signing epoch-bound, sequence-less local changes. Exported from viem/eip8130 with a unit test. - Docs: drop the now-redundant keystore address from getConfigSequence examples.
… overrides) The keystore (AccountConfiguration) is enshrined in the execution client and identical on every chain — using any other address derives a different account address and fails the create tx. So it is not configurable. - Rename the `accountConfigAddress` constant to `keystoreAddress` and document it as the fixed, enshrined keystore. - Drop the `accountConfiguration` / `accountConfigAddress` override params from every read (getLockStatus, isLocked, getActorConfig, getPolicy, isActor, getConfigSequence), the permissions helper, the account builders (toAccount/newSmartAccount/toSmartAccount/subAccounts), and the encoders (computeAddress, toFactoryArgs). All now reference `keystoreAddress` directly. - Remove the `accountConfigAddress` property from the account object; sendCalls reads the keystore constant instead. - Remove `accountConfiguration` from the `Eip8130Deployment` record (it is the fixed `keystoreAddress`, not a per-chain address). - Update tests + docs; drop the now-impossible override cases.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds two new (additive) modules to viem for EIP-8130 native account abstraction and its ERC-8168 payer-service companion. The change is almost entirely additive (
+16.6k / -8across ~112 files); no existing public APIs are modified.viem/eip8130— accounts, actions, and utilities for the EIP-8130AA_TX_TYPE(0x79) native-AA transaction: smart-account creation, actor management (authorize/revoke, scopes, expiry), session keys, sub-accounts, receipts/metadata, and a portable ERC-4337 path (via bundler + EntryPoint) for chains without native 8130 support.viem/eip8168— payer-service client for sponsoring EIP-8130 transactions (discover/aggregate payer sources, carry account changes through sponsored calls).Both modules are documented under
site/pages/eip8130/**and are wired into the docs sidebar.What's included
newSmartAccount,toSmartAccount,toAccount(address-only / delegated EOA modes), key builders (key.k1,key.p256,key.webAuthn,key.trustedExecutor, ...).estimateGas,getActorConfig,getConfigSequence,getTransaction,getTransactionReceipt,waitForTransactionReceipt,isActor, lock/policy/session reads, etc.0x79, actor-change hashing/signing, address computation (CREATE2), signed-actor-changes signature envelope.getTransaction/waitForTransactionReceiptlearn to flatten the nested0x79response body.Testing
src/eip8130/**(encoding, factory args, signing, nonce/scope logic).scripts/eip8130, run viatest/vitest.eip8130.config.ts) exercises create-on-first-use, a follow-up userOp, and authorize/revoke actor changes end-to-end against a bundler.Status / notes
viem/eip8130for iteration. The intent is a clean path to promote once the spec + canonical contracts stabilize.main(merge, not rebase) to preserve history; only trivial config conflicts (package.jsonknip list,scripts/tsconfig.jsonexcludes) were resolved.