Kit Plugins ➤ RPC
This package provides plugins that add RPC functionality to your Kit clients.
Installation
pnpm install @solana/kit-plugin-rpc
solanaRpc plugin
The solanaRpc plugin sets up a full Solana RPC client in a single call. It installs an RPC connection, RPC Subscriptions, minimum balance computation, transaction planning, and transaction execution on the client.
The client must have a payer set before applying this plugin.
Installation
import { createClient } from '@solana/kit';
import { solanaRpc } from '@solana/kit-plugin-rpc';
import { payer } from '@solana/kit-plugin-signer';
const client = createClient()
.use(payer(myPayer))
.use(solanaRpc({ rpcUrl: 'https://api.mainnet-beta.solana.com' }));
Options
All options are provided via a SolanaRpcConfig object:
rpcUrl(required): URL of the Solana RPC endpoint.rpcSubscriptionsUrl: URL of the RPC Subscriptions endpoint. Defaults to therpcUrlwith the protocol changed fromhttptows. As a convenience, the exact stringshttp://127.0.0.1:8899andhttp://localhost:8899(the canonical local validator RPC endpoints) are rewritten to port8900. The match is exact-string only — any other host, scheme, or port (includinghttps://localhost:8899orhttp://0.0.0.0:8899) is left untouched. PassrpcSubscriptionsUrlexplicitly when your RPC and WebSocket endpoints use different ports.rpcConfig: Optional configuration forwarded tocreateSolanaRpc.rpcSubscriptionsConfig: Optional configuration forwarded tocreateSolanaRpcSubscriptions.transactionConfig: Options to configure how transaction messages are created. See therpcTransactionPlanneroptions below.maxConcurrency: Maximum number of concurrent transaction executions. Defaults to 10.skipPreflight: Whether to always skip preflight simulation. Defaults tofalse.
Features
rpc: Call any Solana RPC method.rpcSubscriptions: Subscribe to Solana RPC notifications.getMinimumBalance: Compute minimum lamports for rent exemption.planTransaction(s): Plan instructions into transaction messages without executing them.sendTransaction(s): Plan and execute instructions, instruction plans, or transaction messages in one call.transactionPlanner/transactionPlanExecutor(deprecated): Fields kept for backward compatibility. UseplanTransaction(s)/sendTransaction(s)instead.
solanaMainnetRpc plugin
A convenience wrapper around solanaRpc that types the connection as a mainnet URL, preventing accidental use of devnet-only features such as airdrops.
Installation
import { createClient } from '@solana/kit';
import { solanaMainnetRpc } from '@solana/kit-plugin-rpc';
import { payer } from '@solana/kit-plugin-signer';
const client = createClient()
.use(payer(myPayer))
.use(solanaMainnetRpc({ rpcUrl: 'https://api.mainnet-beta.solana.com' }));
Features
See solanaRpc for available features.
solanaDevnetRpc plugin
A convenience wrapper around solanaRpc that defaults to the public devnet endpoint (https://api.devnet.solana.com) and includes airdrop support for requesting SOL from the faucet.
Installation
import { createClient } from '@solana/kit';
import { solanaDevnetRpc } from '@solana/kit-plugin-rpc';
import { payerFromFile } from '@solana/kit-plugin-signer';
const client = createClient().use(payerFromFile('~/.config/solana/id.json')).use(solanaDevnetRpc());
Features
See solanaRpc for available features, plus:
airdrop: Request SOL from the devnet faucet.await client.airdrop(address('HQVxiMVDoV9jzG4tpoxmDZsNfWvaHXm8DGGv93Gka75v'), lamports(1_000_000_000n));
solanaTestnetRpc plugin
A convenience wrapper around solanaRpc that defaults to the public testnet endpoint (https://api.testnet.solana.com) and includes airdrop support for requesting SOL from the faucet.
Installation
import { createClient } from '@solana/kit';
import { solanaTestnetRpc } from '@solana/kit-plugin-rpc';
import { payerFromFile } from '@solana/kit-plugin-signer';
const client = createClient().use(payerFromFile('~/.config/solana/id.json')).use(solanaTestnetRpc());
Features
See solanaRpc for available features, plus:
airdrop: Request SOL from the testnet faucet.await client.airdrop(address('HQVxiMVDoV9jzG4tpoxmDZsNfWvaHXm8DGGv93Gka75v'), lamports(1_000_000_000n));
solanaLocalRpc plugin
A convenience wrapper around solanaRpc that defaults to http://127.0.0.1:8899 for the RPC and ws://127.0.0.1:8900 for subscriptions, and includes airdrop support.
Installation
import { createClient } from '@solana/kit';
import { solanaLocalRpc } from '@solana/kit-plugin-rpc';
import { payerFromFile } from '@solana/kit-plugin-signer';
const client = createClient().use(payerFromFile('~/.config/solana/id.json')).use(solanaLocalRpc());
Features
See solanaRpc for available features, plus:
airdrop: Request SOL from the local validator faucet.await client.airdrop(address('HQVxiMVDoV9jzG4tpoxmDZsNfWvaHXm8DGGv93Gka75v'), lamports(1_000_000_000n));
solanaRpcConnection plugin
The solanaRpcConnection plugin creates a Solana RPC and Solana RPC Subscriptions from a cluster URL and installs both on the client.
Installation
import { createClient } from '@solana/kit';
import { solanaRpcConnection } from '@solana/kit-plugin-rpc';
const client = createClient().use(solanaRpcConnection({ rpcUrl: 'https://api.mainnet-beta.solana.com' }));
You may wrap your RPC URL using the mainnet, devnet, or testnet helpers from @solana/kit. When you do, the returned RPC API will be adjusted to match the selected cluster since some RPC features are not available on all clusters.
import { mainnet } from '@solana/kit';
const client = createClient().use(solanaRpcConnection({ rpcUrl: mainnet('https://api.mainnet-beta.solana.com') }));
Options
All options are provided via a SolanaRpcConnectionConfig object:
rpcUrl(required): URL of the Solana RPC endpoint.rpcSubscriptionsUrl: URL of the RPC Subscriptions endpoint. Defaults to therpcUrlwith the protocol changed fromhttptows. As a convenience, the exact stringshttp://127.0.0.1:8899andhttp://localhost:8899(the canonical local validator RPC endpoints) are rewritten to port8900. The match is exact-string only — any other host, scheme, or port (includinghttps://localhost:8899orhttp://0.0.0.0:8899) is left untouched. PassrpcSubscriptionsUrlexplicitly when your RPC and WebSocket endpoints use different ports.rpcConfig: Optional configuration forwarded tocreateSolanaRpc.rpcSubscriptionsConfig: Optional configuration forwarded tocreateSolanaRpcSubscriptions.
Features
rpc: Call any Solana RPC method using type-safe methods.const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();rpcSubscriptions: Subscribe to Solana RPC notifications using async iterators.const slotNotifications = await client.rpcSubscriptions.slotNotifications({ commitment: 'confirmed' }).subscribe(); for await (const slotNotification of slotNotifications) { console.log('Got a slot notification', slotNotification); }
rpcAirdrop plugin
This plugin adds an airdrop method to your Kit client that requests SOL airdrops via the RPC and RPC Subscriptions transports.
Airdrop is only available on test clusters (devnet, testnet) and local validators. Using this plugin with a mainnet RPC will produce a TypeScript error.
Installation
The client must have rpc and rpcSubscriptions installed before applying this plugin.
import { createClient } from '@solana/kit';
import { solanaRpcConnection, rpcAirdrop } from '@solana/kit-plugin-rpc';
const client = createClient()
.use(solanaRpcConnection({ rpcUrl: 'http://127.0.0.1:8899' }))
.use(rpcAirdrop());
Features
airdrop: An asynchronous helper function that airdrops a specified amount of lamports to a given address.await client.airdrop(address('HQVxiMVDoV9jzG4tpoxmDZsNfWvaHXm8DGGv93Gka75v'), lamports(1_000_000_000n));
rpcGetMinimumBalance plugin
This plugin adds a getMinimumBalance method to your Kit client that computes the minimum lamports required for an account with a given data size, using the getMinimumBalanceForRentExemption RPC method.
Installation
The client must have rpc installed before applying this plugin.
import { createClient } from '@solana/kit';
import { solanaRpcConnection, rpcGetMinimumBalance } from '@solana/kit-plugin-rpc';
const client = createClient()
.use(solanaRpcConnection({ rpcUrl: 'https://api.mainnet-beta.solana.com' }))
.use(rpcGetMinimumBalance());
Features
getMinimumBalance: An asynchronous helper that returns the minimum lamports required for an account with the given data size. By default, the 128-byte account header is included on top of the provided space.// Minimum balance for an account with 100 bytes of data (plus header). const balance = await client.getMinimumBalance(100); // Minimum balance for exactly 100 bytes (without adding the header). const rawBalance = await client.getMinimumBalance(100, { withoutHeader: true });
rpcTransactionPlanner plugin
Adds planTransaction and planTransactions to the client, using a planner that plans instructions into transaction messages with a fee payer, provisory resource limits (a compute unit limit, plus a loaded accounts data size limit for version 1 transactions), and optional priority fees. The fee payer is read from client.payer lazily, at plan time, so a dynamic payer (such as a connected wallet) is always respected.
Usage
The client must have a payer set before installing the plugin.
import { createClient } from '@solana/kit';
import { rpcTransactionPlanSendingExecutor, rpcTransactionPlanner, solanaRpcConnection } from '@solana/kit-plugin-rpc';
import { generatedPayer } from '@solana/kit-plugin-signer';
const client = await createClient()
.use(solanaRpcConnection({ rpcUrl: 'https://api.mainnet-beta.solana.com' }))
.use(generatedPayer())
.use(rpcTransactionPlanner())
.use(rpcTransactionPlanSendingExecutor());
const transactionPlan = await client.planTransactions(myInstructionPlan);
Options
All options are provided via a TransactionPlannerConfig object. Its shape is discriminated by the transaction version.
For legacy and version 0 transactions:
version: The transaction message version to use. Accepts0or'legacy'. Defaults to0.microLamportsPerComputeUnit: The priority fee in micro-lamports per compute unit, added as asetComputeUnitPriceinstruction. Defaults to no priority fees.estimateResourceLimits: Whether to estimate and set resource limits by simulating before sending. Set tofalseto skip estimation and reserve no provisory limits, which is useful for transactions close to the message size limit. Defaults totrue.
Version 1 transactions are defined for forward compatibility but are not yet buildable by @solana/kit; passing version: 1 currently throws. When available, version 1 will accept priorityFeeLamports (a flat total in lamports) instead of microLamportsPerComputeUnit, alongside the shared estimateResourceLimits option.
rpcTransactionPlanSendingExecutor plugin
Adds sendTransaction and sendTransactions to the client, using an executor that estimates resource limits, signs, and sends transactions via RPC. Resource limit estimation covers the compute unit limit and, for version 1 transactions, the loaded accounts data size limit.
Usage
The client must have rpc and rpcSubscriptions configured, and a transaction planner installed, before installing this plugin — sending plans through the client's planning functions.
import { createClient } from '@solana/kit';
import { rpcTransactionPlanSendingExecutor, rpcTransactionPlanner, solanaRpcConnection } from '@solana/kit-plugin-rpc';
import { generatedPayer } from '@solana/kit-plugin-signer';
const client = await createClient()
.use(solanaRpcConnection({ rpcUrl: 'https://api.mainnet-beta.solana.com' }))
.use(generatedPayer())
.use(rpcTransactionPlanner())
.use(rpcTransactionPlanSendingExecutor());
const transactionPlanResult = await client.sendTransactions(myInstructionPlan);
Options
All options are provided via a RpcTransactionPlanExecutorConfig object:
estimateResourceLimits: Whether to estimate and set resource limits by simulating before sending (default:true). This should match theestimateResourceLimitsoption on the planner;solanaRpckeeps them in sync automatically.getComputeUnitLimitFromEstimate: A(estimatedComputeUnits: number) => numberfunction that maps the estimated compute unit consumption to the compute unit limit to set, adding headroom for variation between simulation and execution. Defaults to a function that adds a buffer on top of the estimate of at least 300 compute units, or a margin that decays linearly from 10% at low estimates to 2% at 500,000 compute units and above, whichever is greater. The result is always capped at 1,400,000 (the per-transaction maximum).maxConcurrency: Maximum number of concurrent executions (default: 10).skipPreflight: Whether to skip the preflight simulation when sending transactions (default:false).
Result context
As it works through a transaction, the executor records the planned message (once its blockhash lifetime and resource limits are set), the fully signed transaction, and the signature it was sent under. A successful plan result carries all three on its context, and the exported RpcSendContext type names that shape so you can annotate results yourself.
import { SuccessfulSingleTransactionPlanResult } from '@solana/kit';
import { RpcSendContext } from '@solana/kit-plugin-rpc';
function logSentTransaction(result: SuccessfulSingleTransactionPlanResult<RpcSendContext>) {
console.log(
`Sent ${result.context.signature} using blockhash ${result.context.message.lifetimeConstraint.blockhash}`,
);
}
Because the context is filled in as execution progresses, a transaction that fails or is canceled part way through carries only what was recorded before it stopped. Failed and canceled results therefore type the context as partial — only successful results guarantee every field.
The sendTransaction and sendTransactions functions installed by this plugin propagate this context type, so their results carry a typed RpcSendContext without any annotation needed.
Preflight and Resource Limit Estimation
By default, the executor estimates resource limits by simulating the transaction before sending it. This covers the compute unit limit and, for version 1 transactions, the loaded accounts data size limit. When estimation is performed, preflight is skipped to avoid a redundant second simulation. When every applicable resource limit is already explicitly set (no estimation needed), preflight runs as the only simulation.
Setting skipPreflight: true changes the behavior:
- Preflight is always skipped regardless of whether estimation was performed.
- If the resource limit estimation simulation fails, the consumed resources from the failed simulation are used to set the limits (with the compute unit buffer from
getComputeUnitLimitFromEstimateapplied) so the transaction still reaches the validator. This is useful for debugging failed transactions in an explorer.
| Scenario | skipPreflight: false (default) |
skipPreflight: true |
|---|---|---|
| Estimation succeeds | Set limits, skip preflight | Set limits, skip preflight |
| Estimation fails | Throw | Use consumed resources, skip preflight |
| Explicit limits set | Run preflight | Skip preflight |
Set estimateResourceLimits: false to opt out of resource limit estimation entirely. The planner then reserves no provisory resource limits and the executor does not simulate to estimate or inject any; any explicit resource limits already present on the message are preserved. This is useful for transactions close to the message size limit, where adding a compute budget instruction would make an otherwise valid transaction too large.
Note that disabling estimation does not disable preflight. When estimateResourceLimits: false and skipPreflight is left at its default false, the executor still runs a preflight simulation when sending — this becomes the only simulation. To avoid all simulation overhead, set skipPreflight: true as well.
When using solanaRpc, both the planner and executor read estimateResourceLimits from a single place: transactionConfig.
const client = createClient()
.use(payer(myPayer))
.use(
solanaRpc({
rpcUrl: 'https://api.mainnet-beta.solana.com',
skipPreflight: true,
transactionConfig: { estimateResourceLimits: false },
}),
);
Compute unit buffer
Because a transaction can consume slightly more compute units at execution time than during simulation, the executor adds a buffer to the estimated compute unit limit. By default this buffer is the greater of a fixed minimum of 300 compute units and a margin that decays linearly from 10% at low estimates to 2% at 500,000 compute units and above, added on top of the estimate.
Override this by passing a getComputeUnitLimitFromEstimate function that maps the raw estimate to the limit to set. It is applied on both successful estimation and the skipPreflight recovery path. The resulting limit is always capped at 1,400,000, the maximum number of compute units allowed per transaction, including for custom functions.
const client = createClient()
.use(payer(myPayer))
.use(
solanaRpc({
rpcUrl: 'https://api.mainnet-beta.solana.com',
// Add a flat 20% buffer instead of the default curve.
getComputeUnitLimitFromEstimate: estimatedComputeUnits => Math.ceil(estimatedComputeUnits * 1.2),
}),
);
Deprecated plugins
The following plugins are still exported for backward compatibility but are deprecated. Prefer solanaRpcConnection for new code.
rpcConnection(rpc)/rpcSubscriptionsConnection(rpcSubscriptions): Trivial wrappers aroundextendClient. InlineextendClient({ rpc })orextendClient({ rpcSubscriptions })instead, or usesolanaRpcConnectionwhen starting from a cluster URL.solanaRpcSubscriptionsConnection(url, config?): No longer needed becausesolanaRpcConnectioninstalls bothrpcandrpcSubscriptions.rpcTransactionPlanExecutor(config?): Only sets the deprecatedclient.transactionPlanExecutorfield. UserpcTransactionPlanSendingExecutorinstead, which installssendTransactionandsendTransactionsalongside the executor.// Before const client = await createClient() .use(rpcTransactionPlanner()) .use(rpcTransactionPlanExecutor()) .use(planAndSendTransactions()); // After const client = await createClient().use(rpcTransactionPlanner()).use(rpcTransactionPlanSendingExecutor());