Sponsor fees & rent on Solana

Fees and rent are a significant barrier to entry for new users of your app. Sponsor fees and rent to enable users to transact without holding SOL.

How it works

When you request gas sponsorship for a transaction using a configured policy, the policy engine will determine if that transaction is eligible for sponsorship. If eligible, Gas Manager will pay for the fees and rent upfront when the user sends the transaction. Gas Manager will make a note of the sponsored cost and add it to your monthly bill.

  • Fees: the cost of executing transactions
  • Rent: the minimum payment to store data onchain
    • Rent sponsorship is supported for createAccount and createAssociatedTokenAccount. If you need support for custom programs, contact [email protected].

Prerequisites

  • API key from your dashboard
  • Smart Wallets for Solana set up in your project if you want to enable sign up/login for creation of wallets
  • A sponsorship policy to cover fees and/or rent: create a policy

Implementation

Required SDK version: ^v4.59.1

Global sponsorship

To apply a sponsorship policy to all transactions sent by the Solana wallet provider, you can configure fee and rent sponsorship by passing a policyId into your Solana config. Replace the API key and Policy Id with your keys from the dashboard. This setup applies sponsorship to all Solana transactions sent from wallets created with this configuration (e.g. this will be applied to usage of the useSolana… hooks).

import { 
const cookieStorage: (config?: { sessionLength?: number; domain?: string; }) => Storage

Function to create cookie based Storage

cookieStorage
,
const createConfig: (props: CreateConfigProps, ui?: AlchemyAccountsUIConfig) => AlchemyAccountsConfigWithUI

Wraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).

createConfig
} from "@account-kit/react";
import {
class Connection

A connection to a fullnode JSON RPC endpoint

Connection
} from "@solana/web3.js";
function createConfig(props: CreateConfigProps, ui?: AlchemyAccountsUIConfig): AlchemyAccountsConfigWithUI

Wraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).

createConfig
({
...
any
otherConfig
,
solana: { connection: Connection; policyId: string; }
solana
: {
connection: Connection
connection
: new
new Connection(endpoint: string, commitmentOrConfig?: Commitment | ConnectionConfig): Connection

Establish a JSON RPC connection

Connection
(
"https://solana-devnet.g.alchemy.com/v2/<API_KEY>", {
wsEndpoint?: string | undefined

Optional endpoint URL to the fullnode JSON RPC PubSub WebSocket Endpoint

wsEndpoint
: "wss://api.devnet.solana.com",
commitment?: Commitment | undefined

Optional commitment level

commitment
: "confirmed",
} ),
policyId?: string | undefined
policyId
: "<PolicyId>"
} }

Per transaction sponsorship

Alternatively, to apply sponsorship conditionally for each transaction, you can pass a policyId to the useSolanaTransaction hook.

import { 
function useSolanaTransaction(opts?: SolanaTransactionHookParams): SolanaTransaction

This is the hook that will be used to send a transaction. It will prioritize external connected Solana wallets, falling back to the internal signer when not connected. Supports sponsorship for both external wallets and internal signers.

useSolanaTransaction
} from "@account-kit/react";
import {
class Connection

A connection to a fullnode JSON RPC endpoint

Connection
,
class PublicKey

A public key

PublicKey
,
class SystemProgram

Factory class for transactions to interact with the System program

SystemProgram
} from "@solana/web3.js";
function
function MyComponent(): JSX.Element
MyComponent
() {
const
const policyId: "<YourPolicyId>"
policyId
= "<YourPolicyId>";
const {
const sendTransaction: (params: SolanaTransactionParams) => void

Send the transaction

sendTransaction
,
const signer: SolanaSigner | null

The solana signer used to send the transaction

signer
} =
function useSolanaTransaction(opts?: SolanaTransactionHookParams): SolanaTransaction

This is the hook that will be used to send a transaction. It will prioritize external connected Solana wallets, falling back to the internal signer when not connected. Supports sponsorship for both external wallets and internal signers.

useSolanaTransaction
({
policyId?: string | void | undefined
policyId
,
}); if (!
const signer: SolanaSigner | null

The solana signer used to send the transaction

signer
) {
return <
React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>Loading signer...</
React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>;
} return ( <
React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
onClick
={() =>
const sendTransaction: (params: SolanaTransactionParams) => void

Send the transaction

sendTransaction
({
transfer: { amount: number; toAddress: string; }
transfer
: {
toAddress: string
toAddress
: "<ToAddress>",
amount: number
amount
: 1000000,
}, }) } > Send Sponsored Transaction </
React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
>
); }

Congrats! You’re now creating smart wallets on Solana with social login and sending sponsored transactions to create a zero-friction experience from sign-up to transaction.