Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Solana Sponsorships

Solana Sponsorships lets you sponsor the transaction fees for your users on Solana, so they can transact without holding SOL.

The paymaster speaks the Kora JSON-RPC API, so you use the @solana/kora SDK's KoraClient and build transactions with @solana/kit.

Gas Sponsorships

You pay the fee for your users. It is charged to your Pimlico balance.

Use Gas Sponsorships →

SPL Token Sponsorships

Your users pay the fee in USDC or USDT (supported tokens). The paymaster pays the SOL fee and is repaid with a token transfer in the same transaction.

Use SPL Token Sponsorships →

Quick start

npm install @solana/kora @solana/kit@6 @solana-program/token@0.12

@solana/kora 0.2 is built on @solana/kit 6, so install the matching versions of @solana/kit and @solana-program/token.

Add a helper that builds a transaction message with the paymaster as the fee payer:

sponsored-transaction.ts
import type { KoraClient } from "@solana/kora";
import {
    type Instruction,
    address,
    appendTransactionMessageInstructions,
    blockhash,
    createNoopSigner,
    createTransactionMessage,
    pipe,
    setTransactionMessageFeePayerSigner,
    setTransactionMessageLifetimeUsingBlockhash,
} from "@solana/kit";
 
export async function createSponsoredTransactionMessage(
    kora: KoraClient,
    instructions: Instruction[],
) {
    const { signer_address } = await kora.getPayerSigner();
    const { blockhash: latestBlockhash } = await kora.getBlockhash();
 
    // pipe passes the message through each step below, in order
    return pipe(
        // Start an empty version 0 transaction message
        createTransactionMessage({ version: 0 }),
        // The paymaster pays the fee. It signs later, so a noop signer leaves its signature slot empty.
        (m) => setTransactionMessageFeePayerSigner(createNoopSigner(address(signer_address)), m),
        // The blockhash keeps the transaction valid for about a minute. lastValidBlockHeight is only
        // read by @solana/kit's own send-and-confirm, and the paymaster sends the transaction for you.
        (m) =>
            setTransactionMessageLifetimeUsingBlockhash(
                { blockhash: blockhash(latestBlockhash), lastValidBlockHeight: 0n },
                m,
            ),
        // Add your app's instructions (transfers, swaps, etc.)
        (m) => appendTransactionMessageInstructions(instructions, m),
    );
}

Then build your transaction with it and send it to the paymaster:

import { KoraClient } from "@solana/kora";
import {
    getBase64EncodedWireTransaction,
    partiallySignTransactionMessageWithSigners,
} from "@solana/kit";
import { createSponsoredTransactionMessage } from "./sponsored-transaction";
 
const kora = new KoraClient({
    rpcUrl: "https://solana.pimlico.io/v1/mainnet/rpc?apikey=YOUR_API_KEY",
});
 
const message = await createSponsoredTransactionMessage(kora, instructions);
 
// Your user signs here, the paymaster signs as fee payer and broadcasts
const transaction = getBase64EncodedWireTransaction(
    await partiallySignTransactionMessageWithSigners(message),
);
 
const { signature } = await kora.signAndSendTransaction({ transaction });

How it works

  1. You build your transaction with the paymaster's address, from getPayerSigner, as the fee payer, and your user signs it.
  2. To have your user pay in a token, you append a transfer of the quoted fee to the paymaster before signing.
  3. signAndSendTransaction sends it to the paymaster. If the transaction pays the paymaster in a supported token, the fee is covered by that payment. Otherwise it is charged to your Pimlico balance.
  4. The paymaster validates and simulates the transaction, signs it as fee payer, broadcasts it, and by default responds once it is confirmed.

The signature is a normal Solana transaction signature, so you can look it up on any explorer.

Endpoints

ClusterURL
Mainnethttps://solana.pimlico.io/v1/mainnet/rpc?apikey=YOUR_API_KEY
Devnethttps://solana.pimlico.io/v1/devnet/rpc?apikey=YOUR_API_KEY

Pass your API key in the apikey query parameter, as above. KoraClient's own apiKey option sends an x-api-key header, which Pimlico does not read. Sponsorship on devnet is free.

Requirements

  • The paymaster may only be the fee payer, with one exception: it may pay the rent for an account your transaction creates, such as a token account. Any other use of it is rejected.
  • The paymaster spends at most 0.1 SOL on one transaction, including the fee, priority fee, and rent.
  • Every signer other than the paymaster must sign before you submit.
  • One transaction per request.

Next steps