For the complete documentation index, see llms.txt. This page is also available as Markdown.

Gasless Deposits

Architecture & batching: For EIP-5792 transaction batching, SIO relay flow diagrams, batch strategy tables, and operator setup, see Transaction Batching & EIP-7702.

On testnet, gasless mode lets users sign intent data without paying on-chain gas for the Compact deposit step. The Epoch allocator relays those transactions when gasless is enabled for your environment.

User-facing rule: when gasless is enabled, treat the entire flow as gasless. Do not tell end users that only part of the intent is sponsored.

Gasless is testnet-only today. Mainnet support is not documented here until explicitly announced.


Who can use gasless relay

Gasless relay (allocator-sponsored gas via epoch-sio) is local private-key wallets only. Injected browser wallets do not use the relay — they may still batch approve + deposit in one prompt when the wallet is already a smart account, but the user pays gas.

Integration

Gasless relay (SIO)

Batching (wallet_sendCalls)

Setup

Local private-key wallet (scripts, agents, CI)

Yes — convertToSmartAccount + allowGaslessSmartAccount: true

Sequential txs, or relayed atomic batch on-chain

convertToSmartAccount({ chainId }) once per EOA + chain

Browser wallet (MetaMask, Rainbow, …)

No — user pays gas

Yes — when wallet is already a smart account (7702 or atomic)

SDK does not prompt upgrade

Widget

Not supported

Not supported

Use shouldUseGaslessRelay(walletClient) — returns true only when walletClient.account.type === "local".


Injected wallets: batching (not gasless)

Browser wallets use EIP-5792 batching inside depositToCompact and solveIntent when the wallet strategy is atomic. This is not gasless relay — the user pays on-chain gas.

Probe before showing UI

Submit with batching (user-paid gas)

Passing gasless: true without allowGaslessSmartAccount on a browser wallet still executes wallet-paid transactions; batching applies when the wallet supports it. Do not label this path "gasless" in your UI.

Batching edge cases (injected wallets)

Scenario
What happens

Plain EOA, no atomic capability

sequential-tx — approve and deposit are two separate prompts; user pays gas twice

Smart wallet active (7702 delegated or atomic enabled)

atomicone wallet_sendCalls prompt; user still pays gas

User rejects atomic batch

SDK throws TransactionError; no gasless relay fallback

Batch RPC error (not user reject)

SDK may fall back to sequential eth_sendTransaction per call

USDT-style token (allowance reset required)

SDK may build [approve(0), approve(N), deposit] — batching depends on wallet limits

gasless: true + allowGaslessSmartAccount: true on injected wallet

Relay ignored (shouldUseGaslessRelay is false); user pays gas — misconfiguration if UI says "gasless"

Multi-leg intent (resourceLockRequired: false)

Contiguous same-chain txs batched via executeWalletBatch when atomic; onExecutionStatus reports phase: "batching"

delegation === "other"

Unsupported delegate bytecode — use a fresh EOA or revoke before local gasless relay

The SDK never calls convertToSmartAccount for injected wallets. Smart-account upgrade must come from the wallet vendor, not your app.

Reference script: scripts/injected-wallet-batch-probe.ts


Supported chains

Verify live support before showing gasless UI:

Example response fields: enabled, supportedChainIds.

Network
Chain ID

Base Sepolia

84532

Ethereum Sepolia

11155111

Optimism Sepolia

11155420

Polygon Amoy

80002


SDK integration (local private-key wallets)

Package: @epoch-protocol/epoch-intents-sdk

Gasless relay steps below apply only to local signers (account.type === "local"). Skip this section for MetaMask / Rainbow / wagmi injected clients — use Injected wallets: batching instead.

1. Check wallet and chain support

Useful fields: delegation, needsSetup, canRelayDeposit, accountType ("local" | "json-rpc").

2. Enable smart account (local wallets only)

Call once per EOA and chain before the first gasless solve. The user signs an authorization; the allocator broadcasts setup via epoch-sio.

solveIntent does not auto-convert EOAs. If you pass allowGaslessSmartAccount: true without prior setup, the SDK throws GaslessUnavailableError.

Do not call convertToSmartAccount for injected wallets — it is designed for local private-key signers in scripts and backend flows.

3. Submit a gasless intent (local wallets only)

Optional config default:

Parameter reference

Param
Local private-key
Injected browser wallet

gasless: true + allowGaslessSmartAccount: true

SIO gasless relay; throws on failure (no wallet-paid fallback)

Relay not used; wallet-paid execution

gasless: true (no allowGaslessSmartAccount)

Wallet-paid sequential txs

Wallet-paid; batch when smart wallet active

gasless: false

Standard wallet-paid deposit

Standard wallet-paid deposit

omitted

Uses gaslessDefault from SDK config

Uses gaslessDefault from SDK config

Errors

Error
What to do

GaslessUnavailableError

Chain not enabled, smart account not set up, or relay unavailable — call convertToSmartAccount (local only) or fall back to gasless: false

INTENT_TASK_INVALID

Swap intents need different tokenIn and tokenOut (e.g. USDC → DAI, not USDC → USDC)

NO_QUOTE_AVAILABLE

Retry quote; confirm tokens are supported on the testnet graph

See Error Handling.


End-to-end test scripts

Local wallet — gasless relay

Use the SDK example to validate your integration against a gasless-enabled allocator:

Script: smallocator/sdk/test/local-wallet-gasless.ts

Setup

Create smallocator/sdk/.env.local (do not commit private keys):

Fund the test wallet with testnet ETH. Point GASLESS_API_BASE_URL at an allocator with gasless enabled.

Run

On success:

Optional env flags:

Env
Effect

SKIP_SETUP=1

Skip smart-account setup; probe + intent only

SKIP_INTENT=1

Setup + verify only

What the script demonstrates

Other example: pnpm example:gasless (test/integration-gasless-example.ts).

Injected wallet — batch probe

Script: scripts/injected-wallet-batch-probe.ts

Copy into a wagmi React app (see compact-demo-epoch). Probes resolveWalletBatchStrategy, canBatchCalls, and getWalletGaslessStatus, then runs solveIntent without allowGaslessSmartAccount.

Compare outcomes:

Wallet state

Expected strategy.mode

Prompts

Gas payer

Plain EOA

sequential-tx

2+ (approve, deposit)

User

Smart wallet active

atomic

1 (wallet_sendCalls)

User

Local private key + gasless

N/A (use local script)

Sign only (relay)

Relayer


Reference UI

compact-demo-epoch demonstrates gasless in a React app with a local-signer tab for relay testing. The browser wallet tab uses batching when available — not gasless relay. The widget package does not expose gasless mode.


Next steps

Last updated