# Solana Paymaster — Fee Sponsorship

The Openfort Solana Paymaster provides fee sponsorship for your users' transactions on Solana. With Openfort's transaction fee sponsorship, you can deliver sponsored transactions where users don't need to hold SOL to interact with your application.

## Overview

Solana has native support for fee sponsorship through *fee payers*. A fee payer is an account that covers transaction fees on behalf of the user, enabling gasless, sponsored transactions.

Fee sponsorship on Solana works as follows:

1. Openfort receives a transaction from your application.
2. Openfort validates the transaction against your fee sponsorship policies and signs it as the fee payer.
3. Openfort returns the signed sponsored transaction for execution.

### Fee sponsorship policies

To use the Solana Paymaster, you must define a **fee sponsorship policy** with the `sponsorSolTransaction` operation. Create policies in the [Openfort Dashboard](https://dashboard.openfort.io) or via the [Policy Engine](/docs/configuration/policies).

:::info
Solana fee sponsorship only supports **project** scope — policies are evaluated automatically for all transactions. Unlike Ethereum, there is no `policyId` parameter to pass per-request. All Solana sponsorship policies use project-scoped auto-discovery.
:::

When the sponsored transaction is executed on Solana, the fee payer account covers the transaction fees instead of the user.

## Getting started

To use Solana fee sponsorship for sponsored transactions, make JSON-RPC requests to:

```text
https://api.openfort.io/rpc/solana/{cluster}
```

Replace `{cluster}` with `devnet` or `mainnet-beta`. Include your Openfort publishable key in the `Authorization` header:

```http
Authorization: Bearer {{YOUR_OPENFORT_PUBLISHABLE_KEY}}
```

Get your public key from the [Openfort Dashboard](https://dashboard.openfort.io).

## Available endpoints

### Transaction signing

| Method | Description |
|--------|-------------|
| [`signAndSendTransaction`](/docs/products/infrastructure/paymaster/solana/endpoints#signandsendtransaction) | Sign and broadcast a transaction to the network, waiting for confirmation |
| [`signAndSendTransactionWithoutConfirmation`](/docs/products/infrastructure/paymaster/solana/endpoints#signandsendtransactionwithoutconfirmation) | Sign and broadcast a transaction without waiting for confirmation |
| [`signTransaction`](/docs/products/infrastructure/paymaster/solana/endpoints#signtransaction) | Sign a transaction without broadcasting |

### Fee estimation

| Method | Description |
|--------|-------------|
| [`estimateTransactionFee`](/docs/products/infrastructure/paymaster/solana/endpoints#estimatetransactionfee) | Estimate transaction fee in lamports and tokens |
| [`getSupportedTokens`](/docs/products/infrastructure/paymaster/solana/endpoints#getsupportedtokens) | List tokens accepted for fee payment |

### Configuration

| Method | Description |
|--------|-------------|
| [`getConfig`](/docs/products/infrastructure/paymaster/solana/endpoints#getconfig) | Get server configuration and enabled methods |
| [`getPayerSigner`](/docs/products/infrastructure/paymaster/solana/endpoints#getpayersigner) | Get payer and signer addresses |
| [`getBlockhash`](/docs/products/infrastructure/paymaster/solana/endpoints#getblockhash) | Get latest blockhash from the network |

## Full SDK example

This example demonstrates a complete gasless, sponsored SPL token transfer. You build the transfer with the standard `@solana-program/token` library, set Kora as the fee payer, and hand the user-signed transaction to Kora's [`signAndSendTransaction`](/docs/products/infrastructure/paymaster/solana/endpoints#signandsendtransaction) to co-sign and broadcast:

```typescript
import { KoraClient } from "@solana/kora";
import {
  address,
  createNoopSigner,
  getBase64EncodedWireTransaction,
  partiallySignTransactionMessageWithSigners,
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstructions,
  type Blockhash,
  type TransactionVersion,
  type KeyPairSigner,
  type MicroLamports,
} from "@solana/kit";
import {
  findAssociatedTokenPda,
  getTransferInstruction,
  TOKEN_PROGRAM_ADDRESS,
} from "@solana-program/token";
import {
  updateOrAppendSetComputeUnitLimitInstruction,
  updateOrAppendSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";

// Configuration
const CONFIG = {
  computeUnitLimit: 200_000,
  computeUnitPrice: 1_000_000n as MicroLamports,
  transactionVersion: 0,
  koraRpcUrl: "https://api.openfort.io/rpc/solana/devnet",
};

// Initialize the Kora client with API key authentication
const client = new KoraClient({
  rpcUrl: CONFIG.koraRpcUrl,
  apiKey: "Bearer {{PUBLISHABLE_KEY}}",
});

async function executeGaslessTransfer(
  senderKeypair: KeyPairSigner,
  destinationAddress: string
) {
  // Step 1: Get the fee payer signer address from Kora
  const { signer_address } = await client.getPayerSigner();
  const feePayer = createNoopSigner(address(signer_address));

  // Step 2: Pick the SPL token to transfer
  const config = await client.getConfig();
  const mint = address(config.validation_config.allowed_spl_paid_tokens[0]);

  // Step 3: Build the transfer instruction with the standard SPL Token program
  const [source] = await findAssociatedTokenPda({
    owner: senderKeypair.address,
    tokenProgram: TOKEN_PROGRAM_ADDRESS,
    mint,
  });
  const [destination] = await findAssociatedTokenPda({
    owner: address(destinationAddress),
    tokenProgram: TOKEN_PROGRAM_ADDRESS,
    mint,
  });

  const transferInstruction = getTransferInstruction({
    source,
    destination,
    authority: senderKeypair,
    amount: 100_000n, // 0.10 USDC (6 decimals)
  });

  // Step 4: Assemble the transaction with Kora as the fee payer
  const { blockhash } = await client.getBlockhash();

  const transactionMessage = pipe(
    createTransactionMessage({ version: CONFIG.transactionVersion as TransactionVersion }),
    (tx) => setTransactionMessageFeePayerSigner(feePayer, tx),
    (tx) => setTransactionMessageLifetimeUsingBlockhash({
      blockhash: blockhash as Blockhash,
      lastValidBlockHeight: 0n,
    }, tx),
    (tx) => updateOrAppendSetComputeUnitPriceInstruction(CONFIG.computeUnitPrice, tx),
    (tx) => updateOrAppendSetComputeUnitLimitInstruction(CONFIG.computeUnitLimit, tx),
    (tx) => appendTransactionMessageInstructions([transferInstruction], tx),
  );

  // Step 5: Sign the user's part of the transaction
  const userSigned = await partiallySignTransactionMessageWithSigners(transactionMessage);
  const base64Transaction = getBase64EncodedWireTransaction(userSigned);

  // Step 6: Hand the transaction to Kora to co-sign as fee payer and broadcast
  const { signature } = await client.signAndSendTransaction({
    transaction: base64Transaction,
    signer_key: signer_address,
  });

  return signature;
}
```

### Key concepts

1. **KoraClient initialization**. Use `apiKey` with your Openfort publishable key prefixed with `Bearer` to enable fee sponsorship.
2. **Fee payer signer**. Retrieve the signer address that covers transaction fees, and set it as the transaction fee payer.
3. **Standard instructions**. Build the transfer with the standard Solana libraries (`@solana-program/token` here, or `@solana-program/system` for native SOL) — Openfort sponsors any valid transaction.
4. **Transaction signing**. The user signs first, then Kora co-signs as the fee payer and broadcasts in a single `signAndSendTransaction` call.

## Fee payer mechanics

On Solana, fee sponsorship is determined by the first signer of the transaction. When Openfort sponsors a transaction:

1. Openfort's fee payer account becomes the first signer for the sponsored transaction.
2. The user signs the transaction for authorization.
3. Openfort adds the fee payer signature to complete the fee sponsorship.
4. The sponsored transaction is submitted with Openfort's account covering the fees.

Solana's native fee sponsorship is handled at the transaction level using multi-signature capabilities, making sponsored transactions straightforward to implement.

## Supported clusters

Openfort supports the following Solana clusters:

| Cluster | Endpoint | Description |
|---------|----------|-------------|
| `devnet` | `https://api.openfort.io/rpc/solana/devnet` | Development and testing |
| `mainnet-beta` | `https://api.openfort.io/rpc/solana/mainnet-beta` | Production network |

## Next steps

* [Endpoint Reference](/docs/products/infrastructure/paymaster/solana/endpoints) - Detailed documentation for all Solana fee sponsorship methods
* [Error Reference](/docs/products/infrastructure/paymaster/solana/errors) - Common errors and how to resolve them
* [Gasless Solana transactions](/docs/products/embedded-wallet/react/wallet/actions/send-transaction/solana#gasless-solana-transactions) - Send fee-sponsored transfers with an embedded wallet
