EVM Gas Sponsorship is an enterprise-only feature. Contact us to learn more about upgrading your plan.
EVM Gas Sponsorship works only with V3 MPC embedded wallets (the wallets Dynamic creates for your users). It does not work with externally imported keys that you sign for directly.
Quick start
This is everything you need to sponsor a transaction. The SDK handles the underlying setup for you automatically.Turn on gas sponsorship in the dashboard
- Go to the Dynamic Dashboard
- Navigate to Settings → Embedded Wallets
- Make sure the EVM chains you want to sponsor are enabled
- Toggle on EVM Gas Sponsorship
Send a sponsored transaction
Call The user pays no gas, and you didn’t have to think about delegation or relayers.
sendSponsoredTransaction with the wallet’s walletMetadata, the chainId, an rpcUrl, and a list of calls (what you want the transaction to do). It signs the intent, relays it, waits for the transaction to land on-chain, and returns the transaction hash.What goes in calls
Each entry in the calls array describes one action the transaction should perform. Most apps only need a single call.
| Field | Type | Description |
|---|---|---|
target | Hex | The address you’re sending to (a recipient or a contract). |
data | Hex | The action to run on the target. Use 0x for a plain native-token transfer. |
value | bigint | Amount of native token (in wei) to send with the call. Use parseEther to convert from a human-readable amount. |
Sending an ERC-20 token (USDC)
To move an ERC-20 token instead of native gas, pointtarget at the token contract, encode a transfer call as data, and leave value at 0n (no native token moves):
Batching multiple calls
A single sponsored transaction can carry severalcalls, executed in order within one on-chain transaction. This is handy for batching: for example, paying multiple recipients at once.
Relaying on behalf of an end user
By default the transaction is relayed as the authenticated service user. To relay on behalf of one of your end users (the wallet’s owner), pass theiruserId:
userId works the same way on relaySponsoredTransaction.
Advanced usage
Everything below is optional. Reach for it only when you need more control than the quick start gives you: pre-signing, custom polling, or managing the one-time delegation step yourself.How it works under the hood
When you callsendSponsoredTransaction, the SDK:
- Builds an EIP-712 intent describing the batch of calls and a deadline
- Signs the intent with the user’s embedded-wallet shares (and, if delegation is needed, an EIP-7702 authorization for the wallet’s EOA)
- Relays the signed intent to Dynamic’s sponsorship backend and gets back a
requestId - Polls the relayer until the request reaches a terminal state, then returns the on-chain transaction hash
0x0000Fb7702036ff9f76044a501ac1aA74cbab16b).
Supported chains
Dynamic operates relayers on the following EVM chains. Mainnet| Chain | Chain ID |
|---|---|
| Ethereum Mainnet | 1 |
| Base | 8453 |
| Optimism | 10 |
| Arbitrum One | 42161 |
| BNB Smart Chain | 56 |
| Chain | Chain ID |
|---|---|
| Ethereum Sepolia | 11155111 |
| Base Sepolia | 84532 |
Splitting sign and send
Reuse a pre-signed intent (for example, to sign in one process and relay from another) by callingsignSponsoredTransaction first and passing the result to sendSponsoredTransaction:
signSponsoredTransaction returns a SignedSponsoredTransaction, a JSON-serializable payload (calls, chainId, deadline, nonce, relayer, signature, walletAddress, and an optional authorization) you can hand to relaySponsoredTransaction or sendSponsoredTransaction.
By default the signed intent is valid for 10 minutes. Override with validForSeconds:
Reusing a nonce
By default each signed intent gets a fresh single-use bitmap nonce. Passnonce (a bigint, matching the nonce on the signed result) to reuse one across intents: sign several intents with the same nonce so at most one can ever land on-chain (cancel-replace):
nonce works the same way on relaySponsoredTransaction and sendSponsoredTransaction.
Inspecting the active relayer
The SDK picks an available relayer automatically when signing. To look one up yourself (for example, to display it or pre-flight a chain), callgetAvailableEvmGaslessRelayer:
Managing EIP-7702 delegation yourself
Before a wallet can submit a sponsored transaction, its EOA must be delegated to the Dynamic relayer contract via an EIP-7702 authorization. The quick start handles this automatically on the first transaction (when you provide anrpcUrl). These helpers exist for when you want explicit control over the delegation step.
Checking delegation status
Useis7702DelegationActive to check whether delegation is already active for a wallet on a given chain. It reads the wallet’s on-chain code, so it requires an rpcUrl:
Signing an authorization
sign7702Authorization signs an EIP-7702 authorization for the Dynamic delegation contract. Pass the result as authorization to signSponsoredTransaction or sendSponsoredTransaction to attach it to the next sponsored call. This is useful when you want to skip auto-delegation (e.g. you’ve turned autoDelegate off, or you’re signing without an rpcUrl):
nonce is omitted, sign7702Authorization fetches the EOA nonce from the chain via rpcUrl; pass an explicit nonce to sign without an RPC.
Polling the relay status yourself
For custom progress reporting, callrelaySponsoredTransaction (which returns a requestId immediately) and poll getEVMSponsoredTransactionStatus yourself:
status is one of:
| Status | Meaning |
|---|---|
pending | Accepted by the relayer, not yet broadcast to the chain. |
submitted | Broadcast to the chain, waiting for confirmation. |
success | Finalized successfully on-chain. |
failure | Terminal failure (errorMessage is populated). |
transactionHash is set once the relay broadcasts the transaction.
For the common “wait until done” case, use waitForSponsoredTransaction, which polls every 2 seconds and resolves on success (timeout: 60 seconds):
pollInterval (ms) and timeout (ms).
Error handling
These methods throw a standardError when sponsorship can’t go through. There is no silent fallback. Wrap the call in a try/catch so you can surface a message and decide what to do next.
- The sponsorship API rejects the request (sponsorship not enabled, chain not supported, or no relayer available)
- The relay reaches a terminal
failurestatus waitForSponsoredTransactiontimes out (default 60 seconds) before reaching a terminal statusautoDelegateis on but norpcUrl(and no pre-signedauthorization) was supplied
Limitations
| Limitation | Details |
|---|---|
| Wallet type | Embedded wallets only (V3 MPC) |
| Mechanism | EIP-7702 delegation to the Dynamic relayer contract |
| Intent validity | 10 minutes by default; configurable via validForSeconds |
| Polling timeout | waitForSponsoredTransaction resolves or throws within 60 seconds by default |
| Batching | One signed intent per sendSponsoredTransaction call; each intent can contain multiple calls |
Related
signTransaction()- Sign a regular (non-sponsored) EVM transactionWalletMetadata- The metadata object passed to every signing operationsponsorTransaction()- The Solana equivalent- Storage Best Practices - Where to cache metadata vs. vault shares