> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# EVM Gas Sponsorship

> Sponsor EVM transaction fees for your users with Dynamic's built-in gas sponsorship feature.

> [!NOTE]
>
> EVM Gas Sponsorship on testnets is available on every plan. Sponsoring mainnet transactions requires an Enterprise plan. [Contact us](https://www.dynamic.xyz/talk-to-us) to learn more about upgrading your plan.

Normally, a user needs to hold some of a network's native token (like ETH) to pay the "gas" fee on every transaction. **Gas sponsorship** lets your app pay those fees instead, so users can transact without ever topping up a wallet.

> [!NOTE]
>
> EVM Gas Sponsorship works only with **V3 MPC embedded wallets** (the wallets Dynamic creates for your users). It does not work with external wallets like MetaMask.

## Quick start

**1. Turn on gas sponsorship in the developer console**

1. Go to the [Dynamic Developer Console](https://console.dynamic.xyz)
2. Navigate to **Settings** > **Embedded Wallets**
3. Make sure the EVM chains you want to sponsor are enabled
4. Toggle on **EVM Gas Sponsorship**, then choose which of the [supported networks](https://www.dynamic.xyz/docs/embedded-wallets/gas-sponsorship.md#supported-chains) to sponsor

**2. Send a sponsored transaction**

Call `sendSponsoredTransaction` on `DynamicSDK.instance.web3dart` with a list of `EvmSponsoredCall` entries and the user's wallet. It returns the relayed transaction hash.

```dart theme={"system"}
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:dynamic_sdk_web3dart/dynamic_sdk_web3dart.dart';

Future<String> sendSponsoredTx(
  BaseWallet wallet,
  String recipientAddress,
) {
  return DynamicSDK.instance.web3dart.sendSponsoredTransaction(
    calls: [
      EvmSponsoredCall(
        target: recipientAddress,
        data: '0x',                  // '0x' = a plain native-token transfer
        value: '10000000000000000',  // 0.01 ETH in wei
      ),
    ],
    wallet: wallet,
  );
}
```

The user pays no gas, and the first sponsored transaction handles the one-time EIP-7702 delegation setup automatically.

## What goes in `calls`

Each `EvmSponsoredCall` describes one action the transaction performs:

| Field | Type | Description |
| - | - | - |
| `target` | `String` | The address you are sending to (a recipient or a contract). |
| `data` | `String` | The ABI-encoded action to run on the target. Use `'0x'` for a plain native-token transfer. |
| `value` | `String` | Amount of native token to send with the call, in wei as a decimal string. Use `'0'` when the call moves no native token. |

## Batch calls

A single sponsored transaction can carry more than one call: they are executed together, atomically (all succeed or all revert). The example below approves an ERC-20 spend and deposits into a contract in one sponsored transaction:

```dart theme={"system"}
import 'package:web3dart/web3dart.dart';

Future<String> approveAndDeposit(
  BaseWallet wallet,
  String tokenAddress,
  String spenderAddress,
  BigInt amount,
) {
  final erc20 = DeployedContract(
    ContractAbi.fromJson('[{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]}]', 'ERC20'),
    EthereumAddress.fromHex(tokenAddress),
  );

  final approveData = bytesToHex(
    erc20.function('approve').encodeCall([
      EthereumAddress.fromHex(spenderAddress),
      amount,
    ]),
    include0x: true,
  );

  return DynamicSDK.instance.web3dart.sendSponsoredTransaction(
    calls: [
      EvmSponsoredCall(target: tokenAddress, data: approveData, value: '0'),
      EvmSponsoredCall(target: spenderAddress, data: '0x...', value: '0'),
    ],
    wallet: wallet,
  );
}
```

Use `erc20Allowance` to read the allowance a spender already holds, so you can skip an approval the wallet already granted:

```dart theme={"system"}
final allowance = await DynamicSDK.instance.web3dart.erc20Allowance(
  token: tokenAddress,
  owner: wallet.address,
  spender: spenderAddress,
  chainId: 8453, // Base mainnet
);
```

## Check sponsorship availability

`isGasSponsorshipEnabled` reports whether the environment can sponsor for the current wallet. Use it before building a sponsored flow, and keep a wallet-paid path for when it returns `false`:

```dart theme={"system"}
if (await DynamicSDK.instance.web3dart.isGasSponsorshipEnabled()) {
  await DynamicSDK.instance.web3dart.sendSponsoredTransaction(
    calls: calls,
    wallet: wallet,
  );
} else {
  // Fall back to a regular sendTransaction
}
```

## Earn integration

When [Earn](https://www.dynamic.xyz/docs/flutter/earn.md) executes an EVM vault action, its `sponsored` parameter routes the approval and the vault call through gas sponsorship automatically. See [Gas sponsorship](https://www.dynamic.xyz/docs/flutter/earn.md#gas-sponsorship) in the Earn guide.

## What's Next

* [SVM Gas Sponsorship](https://www.dynamic.xyz/docs/flutter/wallets/solana/svm-gas-sponsorship.md) - Sponsor Solana transaction fees
* [Earn](https://www.dynamic.xyz/docs/flutter/earn.md) - Deposit into yield vaults with sponsored execution
* [Send ETH](https://www.dynamic.xyz/docs/flutter/wallets/evm/send-eth.md) - Wallet-paid EVM transactions


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.