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

# Sending sponsored Solana transactions

> Send custodial Solana transactions with fee sponsorship using solSendTransaction (sponsor: true).

The SDK primarily abstracts three endpoints: `prepare_sol_transaction`, `sol_send_transaction`, and `get_send_transaction_status` (plus Gas Station usage / limits for sponsorship budgets).

You can sign and broadcast Solana transactions in two primary ways:

* **Using the React handler (`handleSendTransaction`) from `@0xkey-io/react-wallet-kit`**

  This gives you:

  * modals
  * spinner + chain logo
  * success screen
  * explorer link
  * built-in polling

* **Using low-level functions in `@0xkey-io/core` / `@0xkey-io/sdk-server`**

  You manually call:

  * `prepareSolTransaction` → build unsigned message (set `sponsor: true` for fee sponsorship)
  * `solSendTransaction` → submit
  * `pollTransactionStatus` / `getSendTransactionStatus` → wait for confirmation

This page walks you through sponsored custodial sends. For EVM Gas Station (EIP-7702), see [Sending sponsored EVM transactions](/embedded-wallets/code-examples/sending-sponsored-transactions).

<Note>
  Fee sponsorship (`sponsor: true`) uses a platform Solana fee-payer as
  `account_keys[0]`. Review
  [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction)
  before submitting third-party or router-built payloads.
</Note>

## How Solana fee sponsorship works

Solana sponsorship is **not** EIP-7702. 0xkey inserts a platform fee-payer as `account_keys[0]` and requires the user wallet as the second required signer on the **same** transaction (custodial dual-sign). Your users do not need SOL for fees; 0xkey pays them and records usage against your Gas Station limits (lamports).

| Mode             | Who pays fees                          | Who signs                                     |
| :--------------- | :------------------------------------- | :-------------------------------------------- |
| `sponsor: false` | User wallet (`account_keys[0]`)        | User only                                     |
| `sponsor: true`  | Platform fee-payer (`account_keys[0]`) | User (`account_keys[1]`) + platform fee-payer |

<Note>
  Enable Gas Station in the 0xkey dashboard and configure Solana spend limits before using `sponsor: true`. Self-paid sends (`sponsor: false`) do not require Gas Station.
</Note>

For payload constraints (program whitelist, account-creation rules, ALT), see [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction).

## Prepare then send (recommended)

1. Call `prepareSolTransaction` with `sponsor: true` so the unsigned message places the platform fee-payer at index `0` and the user at index `1`.
2. Submit `solSendTransaction` with the same `sponsor: true`, `signWith` set to the **user** address, and the unsigned transaction hex from prepare (or an equivalent message you built with the same account ordering).

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { ZeroXKeyClient } from "@0xkey-io/sdk-server"; // or @0xkey-io/core

const client = new ZeroXKeyClient({ /* apiBaseUrl, organizationId, stamper */ });

const prepared = await client.prepareSolTransaction({
  organizationId,
  from: userSolanaAddress,
  to: recipientAddress,
  amount: "1000000", // lamports
  caip2: "solana:devnet",
  sponsor: true,
});

const { activity } = await client.solSendTransaction({
  type: "ACTIVITY_TYPE_SOL_SEND_TRANSACTION",
  timestampMs: String(Date.now()),
  organizationId,
  parameters: {
    signWith: userSolanaAddress,
    unsignedTransaction: prepared.unsignedTransaction,
    caip2: "solana:devnet",
    sponsor: true,
  },
});

const statusId = activity.result?.solSendTransactionResult?.sendTransactionStatusId;
```

Dashboard Send uses the same flow via the dashboard gateway (`POST /api/v1/sol_send_transaction`) with WebAuthn / stamp auth.

## Using `handleSendTransaction` (React)

When your React kit build exposes Solana send with sponsorship:

```tsx theme={"theme":{"light":"github-light","dark":"github-dark"}}
const { handleSendTransaction, wallets } = useZeroXKey();

const walletAccount = wallets
  .flatMap((w) => w.accounts)
  .find((a) => a.addressFormat === "ADDRESS_FORMAT_SOLANA");

if (!walletAccount) {
  throw new Error("No Solana wallet account found");
}

await handleSendTransaction({
  transaction: {
    signWith: walletAccount.address,
    unsignedTransaction: "<hex-serialized-unsigned-solana-tx>",
    caip2: "solana:devnet",
    sponsor: true,
  },
});
```

Prefer building `unsignedTransaction` with `prepareSolTransaction({ sponsor: true })` so fee-payer ordering matches what the coordinator validates.

## Checking usage and limits

Gas Station tracks Solana sponsorship in **lamports** (separate from EVM wei limits). Query usage via Gas Station / gas-usage APIs and configure window limits in the dashboard.

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const usage = await client.getGasUsage({ organizationId });
// Enforce client-side UX when approaching windowLimit* fields for Solana
```

## Policy notes

Sponsored and self-paid Solana sends both flow through the enclave parser and policy engine (`solana.tx.*`). With `sponsor: true`, policy binding allows `signWith` to be a non-fee-payer required signer (`account_keys[1..)`), and may require `feePayer` to match `account_keys[0]`.

See [Solana policy examples](/concepts/policies/examples/solana) and [Solana overview](/networks/solana).

## Next steps

* [Solana (SVM) support](/networks/solana)
* [Solana transaction construction for sponsored flows](/networks/solana-transaction-construction)
* [Sending sponsored EVM transactions](/embedded-wallets/code-examples/sending-sponsored-transactions) (EIP-7702 Gas Station — different mechanism)
