Guide
Recipes
Short, end-to-end checklists that combine the earlier chapters. Each links back to the chapter with the full detail.
Passkey wallet from zero
- Create a WebAuthn credential and wrap it as a signer.
- Build the account with
newSmartAccount8130(the address is deterministic; no pre-deploy needed). - Send the first transaction: the account deploys on first use.
Passkey onboardingts
import { createWebAuthnCredential, toWebAuthnAccount,} from 'viem/account-abstraction'import { newSmartAccount8130, sendCalls8130, toWebAuthnSigner,} from 'viem/experimental/eip8130'
const credential = await createWebAuthnCredential({ name: 'vibes' })const account = newSmartAccount8130({ signer: toWebAuthnSigner(toWebAuthnAccount({ credential })),})
// Deploys on first use; the passkey signs sender_auth.const hash = await sendCalls8130(client, { account, calls: [{ to: recipient, value: 1n }], gas: 300_000n,})Detail: Creating accounts and Signing.
Gasless first transaction
- Point a payer client at an ERC-8168 endpoint.
- Call
sendSponsoredCalls: it fetches terms, selects a sponsored offer, signs, and hands off. - Confirm any token charge before re-signing.
Sponsored sendts
import { createPayerClient, sendSponsoredCalls } from 'viem/experimental/eip8168'
const payerClient = createPayerClient({ url: 'https://payer.example.com/v1' })
const { transactionHash } = await sendSponsoredCalls(client, { account, // signs sender_auth payerClient, // co-signs payer_auth and submits calls: [{ to: recipient, data }],})Detail: Gas & payers.
Issue a spend-limited session key
- Author a policy config (token limits + allowlists) and bind it with
defineSessionPolicy. - Authorize the key with a restricted scope + policy and ride the install call in the same transaction.
- Hand the key to the app; it spends via
executeCallwithin its committed policy.
Detail: Session keys.
Rotate a compromised key
- Read the next config sequence with
getConfigSequence8130. - Authorize the replacement and revoke the old key in one change.
- Land it as a config-only transaction.
Atomic rotationts
import { actorScope, authorizeActor, key, revokeActor, sendCalls8130,} from 'viem/experimental/eip8130'
const rotate = await account.change( [ authorizeActor(key.k1('0xnewOwner…'), { scope: actorScope.sender }), revokeActor(key.k1('0xoldOwner…')), ], { chainId: client.chain.id, sequence: Number(sequence) },)
await sendCalls8130(client, { account, accountChanges: [rotate], calls: [], gas: 200_000n })Detail: Keys & scopes.
High-throughput sends
- Use
nonce.randomChannel()for independent, out-of-order lanes. - Or use
nonce.nonceless(...)for fully parallel, retry-safe sends bounded by expiry.
Detail: Nonces & throughput.
Take an account multichain
- Register native chains with
register8130Chains; the same address works everywhere. - On non-8130 chains, drive it through ERC-4337 with
toSmartAccount8130. - Rotate keys once with a
chainId 0change and apply it everywhere.
Detail: Multichain.