> ## 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.

# SVM Gas Sponsorship

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

<Info>
  SVM Gas Sponsorship is an enterprise-only feature. [Contact us](https://www.dynamic.xyz/talk-to-us) to learn more about upgrading your plan.
</Info>

On Solana, every transaction needs a small amount of SOL to pay the network fee. **Gas sponsorship** lets your app cover that fee instead, so users can transact without ever holding any SOL. This is one of the most common ways to remove friction for people new to crypto.

Dynamic has gas sponsorship built in. For the basic case you don't need to change any code — flip a switch in the dashboard and your existing Solana transactions get sponsored automatically.

<Note>
  SVM Gas Sponsorship works only with **V3 MPC embedded wallets** (the wallets Dynamic creates for your users). It does not work with external wallets like Phantom.
</Note>

## Quick start

<Steps>
  <Step title="Turn on gas sponsorship in the dashboard">
    1. Go to the [Dynamic Dashboard](https://app.dynamic.xyz)
    2. Navigate to **Settings** → **Embedded Wallets**
    3. Make sure Solana (SOL) is enabled in your chain configurations
    4. Toggle on **SVM Gas Sponsorship**
  </Step>

  <Step title="Send a transaction as usual">
    Once sponsorship is on, the `signAndSendTransaction` you already use sponsors embedded-wallet transactions automatically. **No code changes required.**

    ```javascript theme={"system"}
    import { signAndSendTransaction } from '@dynamic-labs-sdk/solana';

    const sendTx = async (walletAccount, transaction) => {
      // Gas is sponsored automatically when the project setting is on
      // and the wallet supports it.
      const { signature } = await signAndSendTransaction({
        transaction,
        walletAccount,
      });

      console.log('Transaction sent:', signature);
    };
    ```
  </Step>
</Steps>

<Tip>
  If you're sponsoring because your users hold **no SOL at all**, use `signAndSendSponsoredTransaction` instead. It guarantees the transaction is sponsored and throws if sponsorship isn't available — rather than silently falling back to a regular (unsponsored) transaction that a user with no SOL couldn't pay for. This is the safest choice for most "the user has an empty wallet" flows.

  ```javascript theme={"system"}
  import { signAndSendSponsoredTransaction } from '@dynamic-labs-sdk/solana';

  const { signature } = await signAndSendSponsoredTransaction({
    transaction,
    walletAccount,
  });
  ```
</Tip>

### React example

In React, use `useGetWalletAccounts` to get the user's embedded wallet, then call `signAndSendSponsoredTransaction` from a button handler. The `try/catch` shows the user a friendly message if sponsorship fails (see [Error handling](#error-handling)).

```tsx theme={"system"}
import { signAndSendSponsoredTransaction, isSolanaWalletAccount, SponsorTransactionError } from '@dynamic-labs-sdk/solana';
import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';
import { useState } from 'react';
import { Transaction, SystemProgram, PublicKey } from '@solana/web3.js';

function SponsoredSendButton({ recipientAddress }) {
  const { data: walletAccounts = [] } = useGetWalletAccounts();
  const walletAccount = walletAccounts.find(isSolanaWalletAccount);
  const [signature, setSignature] = useState('');
  const [error, setError] = useState('');

  const handleSend = async () => {
    if (!walletAccount) return;
    setError('');
    try {
      const transaction = new Transaction().add(
        SystemProgram.transfer({
          fromPubkey: new PublicKey(walletAccount.address),
          toPubkey: new PublicKey(recipientAddress),
          lamports: 1_000_000,
        }),
      );
      const { signature } = await signAndSendSponsoredTransaction({ transaction, walletAccount });
      setSignature(signature);
    } catch (err) {
      if (err instanceof SponsorTransactionError) {
        setError('Gas sponsorship failed');
      }
    }
  };

  return (
    <div>
      <button onClick={handleSend} disabled={!walletAccount}>Send (Sponsored)</button>
      {signature && <p>Signature: {signature.slice(0, 20)}...</p>}
      {error && <p style={{ color: 'red' }}>{error}</p>}
    </div>
  );
}
```

### Error handling

When you require sponsorship with `signAndSendSponsoredTransaction` and it can't go through, it throws a `SponsorTransactionError`. Wrap the call in a `try/catch` so you can show the user a message and decide what to do next.

```javascript theme={"system"}
import {
  signAndSendSponsoredTransaction,
  SponsorTransactionError,
} from '@dynamic-labs-sdk/solana';

const sendTransaction = async (walletAccount, transaction) => {
  try {
    const { signature } = await signAndSendSponsoredTransaction({
      transaction,
      walletAccount,
    });
    return { success: true, signature };
  } catch (error) {
    if (error instanceof SponsorTransactionError) {
      return { success: false, error: 'Gas sponsorship failed' };
    }
    return { success: false, error: error.message };
  }
};
```

A `SponsorTransactionError` is thrown when:

* The sponsorship API cannot sponsor the transaction (sponsorship not enabled, or a limit was hit)
* The wallet doesn't support sponsored transactions (e.g. an external wallet rather than a V3 MPC embedded wallet)

***

## Advanced usage

Everything below is optional. Reach for it only when you need more control than the quick start gives you.

### How it works under the hood

When a transaction is sponsored, the SDK:

1. Sends the transaction to Dynamic's backend for sponsorship
2. Replaces the fee payer with Dynamic's sponsored account
3. Signs the sponsored transaction with the user's wallet
4. Broadcasts to the network with `skipPreflight: true` by default

### Automatic vs. required sponsorship

There are two ways to send a sponsored transaction, and the difference matters when sponsorship might not be available:

| Function                          | `sponsorshipMode`  | Behavior                                                                                         |
| --------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------ |
| `signAndSendTransaction`          | `'auto'` (default) | Sponsors when project settings and the wallet support it; otherwise sends a regular transaction. |
| `signAndSendSponsoredTransaction` | always required    | Always requires sponsorship; throws `SponsorTransactionError` if it isn't available.             |

Use `signAndSendSponsoredTransaction` whenever a failed sponsorship should stop the transaction — for example when the user has no SOL to fall back on.

### Opting out per call

Pass `sponsorshipMode: 'off'` to skip sponsorship for a specific transaction even when the project setting is on:

```javascript theme={"system"}
const { signature } = await signAndSendTransaction({
  sponsorshipMode: 'off',
  transaction,
  walletAccount,
});
```

### Send options

You can pass `SendOptions` to override defaults. Sponsored transactions use `skipPreflight: true` by default, but you can override this:

```javascript theme={"system"}
const { signature } = await signAndSendSponsoredTransaction({
  transaction,
  walletAccount,
  options: { skipPreflight: false },
});
```

### Limitations

| Limitation       | Details                                        |
| ---------------- | ---------------------------------------------- |
| Wallet type      | Embedded wallets only (V3 MPC)                 |
| Transaction size | Maximum 2KB base64-encoded                     |
| Already-signed   | Transactions with signatures are not sponsored |
| Batching         | Each transaction sponsored individually        |

## Related Functions

* [Signing and Sending Transactions](/javascript/reference/solana/signing-sending-transactions)
* [Getting Solana Connection](/javascript/reference/solana/getting-solana-connection)
* [Adding Solana Extensions](/javascript/reference/solana/adding-solana-extensions)
