EIP-7702
Ink’s public EIP-7702 paymaster is live on EntryPoint v0.8. Use the SDK’s
INK_PUBLIC_PAYMASTER_V08 deployment metadata; the default
INK_PUBLIC_PAYMASTER constant remains pinned to EntryPoint v0.7.
EIP-7702 lets an EOA behave like a smart account by authorizing a delegate implementation. The paymaster supplies native ETH from its EntryPoint deposit and separately charges the EOA in USDC. USDC does not become Ink’s protocol gas token.
Live deployment
| Field | Value |
|---|---|
| Network | Ink Mainnet (57073) |
| SDK | @hellomoon/ink-paymaster v0.2.3 or later |
| SDK deployment | INK_PUBLIC_PAYMASTER_V08 |
| EntryPoint v0.8 | 0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108 |
| Paymaster | 0xE361E63515109BFDC4c32EfC4d2e0ede4d4744D8 |
| Simple7702 delegate | 0xe6Cae83BdE06E4c305530e199D7217f42808555B |
| Reimbursement token | USDC |
| Quote version | 3 |
Use the exported constants instead of copying these addresses into application code.
Before the first operation
The EOA must:
- hold enough native ETH to establish its USDC approval;
- hold enough USDC for the application call and gas reimbursement; and
- approve
INK_PUBLIC_PAYMASTER_V08.paymasterto spend a finite USDC amount.
The public paymaster cannot pay for its own approval. Send that approval with ordinary gas before requesting a prepaid operation.
Create the EIP-7702 account
import { createPublicClient, defineChain, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import {
createBundlerClient,
toSimple7702SmartAccount,
} from "viem/account-abstraction";
import {
createInkPublicPaymasterClient,
createInkViemPaymaster,
INK_PUBLIC_PAYMASTER_V08,
INK_SIMPLE_7702_DELEGATE,
} from "@hellomoon/ink-paymaster";
const inkRpcUrl = process.env.INK_RPC_URL!;
const owner = privateKeyToAccount(process.env.OWNER_PRIVATE_KEY! as `0x${string}`);
const ink = defineChain({
id: INK_PUBLIC_PAYMASTER_V08.chainId,
name: INK_PUBLIC_PAYMASTER_V08.chainName,
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: { default: { http: [inkRpcUrl] } },
});
const publicClient = createPublicClient({
chain: ink,
transport: http(inkRpcUrl),
});
const account = await toSimple7702SmartAccount({
client: publicClient,
entryPoint: "0.8",
implementation: INK_SIMPLE_7702_DELEGATE,
owner,
});
const service = createInkPublicPaymasterClient({
deployment: INK_PUBLIC_PAYMASTER_V08,
});service.bundlerUrl points to the versioned EntryPoint v0.8 Alto endpoint.
Alto is the ERC-4337 bundler; the separate paymaster contract supplies native
gas through EntryPoint.
Send the first prepaid operation
Viem does not pass its EIP-7702 authorization into the paymaster hook. Supply
the delegate in paymasterContext, then sign and pass the authorization to
sendUserOperation explicitly.
const maxTokenCost = 100_000n;
const bundler = createBundlerClient({
account,
chain: ink,
client: publicClient,
transport: http(service.bundlerUrl),
paymaster: createInkViemPaymaster(service),
paymasterContext: {
token: "USDC",
maxTokenCost,
idempotencyKey: "checkout-order-123",
eip7702Delegate: INK_SIMPLE_7702_DELEGATE,
},
});
const authorization = await owner.signAuthorization({
address: INK_SIMPLE_7702_DELEGATE,
chainId: ink.id,
nonce: await publicClient.getTransactionCount({
address: owner.address,
blockTag: "pending",
}),
});
const userOperationHash = await bundler.sendUserOperation({
authorization,
calls: [{ to: destination, value: 0n, data: calldata }],
});
const receipt = await bundler.waitForUserOperationReceipt({
hash: userOperationHash,
});
if (!receipt.success) throw new Error("EIP-7702 operation reverted");For an already delegated EOA, keep supplying eip7702Delegate in
paymasterContext. The quote remains bound to the delegate installed on the
sender even when a new authorization is unnecessary.
Safety checks
Quote version 3 signs the expected delegate address. The paymaster verifies the sender’s EIP-7702 code designator onchain. The SDK also rejects:
- an EIP-7702 marker without
paymasterContext.eip7702Delegate; - an EIP-7702 operation configured against EntryPoint v0.7;
- a v0.8 deployment that reports quote version 2; and
- a quote whose delegate differs from the requested or installed delegate.
Keep the account, UserOperation encoding, SDK deployment, paymaster, Alto, and EntryPoint on the same version.