ClientPlugin

type ClientPlugin<TInput, TOutput> = (input) => TOutput;

Defines a plugin that transforms or extends a client with additional functionality.

For instance, plugins may add RPC capabilities, wallet integration, transaction building, or other features necessary for interacting with the Solana blockchain.

Plugins are functions that take a client object as input and return a new client object or a promise that resolves to a new client object. This allows for both synchronous and asynchronous transformations and extensions of the client.

Plugins are usually applied using the use method on a Client or AsyncClient instance, which createEmptyClient provides as a starting point.

Type Parameters

Type ParameterDescription
TInput extends objectThe input client object type that this plugin accepts.
TOutput extends | Promise<object> | objectThe output type. Either a new client object or a promise resolving to one.

Parameters

ParameterType
inputTInput

Returns

TOutput

Examples

Given an RPC endpoint, this plugin adds an rpc property to the client.

import { createEmptyClient, createSolanaRpc } from '@solana/kit';
 
// Define a simple RPC plugin.
function rpcPlugin(endpoint: string) {
    return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });
}
 
// Use the plugin.
const client = createEmptyClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));
await client.rpc.getLatestBlockhash().send();

The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.

import { createEmptyClient, generateKeypairSigner } from '@solana/kit';
 
// Define a plugin that generates a new keypair signer.
function generatedPayerPlugin() {
    return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });
}
 
// Use the plugin.
const client = await createEmptyClient().use(generatedPayerPlugin());
console.log(client.payer.address);

A plugin can specify required properties on the input client. The example below requires the client to already have a payer signer attached to the client in order to perform an airdrop.

import { createEmptyClient, TransactionSigner, Lamports, lamports } from '@solana/kit';
 
// Define a plugin that airdrops lamports to the payer set on the client.
function airdropPayerPlugin(lamports: Lamports) {
    return async <T extends { payer: TransactionSigner }>(client: T) => {
        await myAirdropFunction(client.payer, lamports);
        return client;
    };
}
 
// Use the plugins.
const client = await createEmptyClient()
    .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.
    .use(airdropPayerPlugin(lamports(1_000_000_000n)));

Multiple plugins — asynchronous or not — can be chained together to build up complex clients. The example below demonstrates how to gradually build a client with multiple plugins. Notice how, despite having multiple asynchronous plugins, we only need to await the final result. This is because the use method on AsyncClient returns another AsyncClient, allowing for seamless chaining.

import { createEmptyClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';
 
// Define multiple plugins.
function rpcPlugin(endpoint: string) {
    return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });
}
function rpcSubscriptionsPlugin(endpoint: string) {
    return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });
}
function generatedPayerPlugin() {
    return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });
}
function generatedAuthorityPlugin() {
    return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });
}
 
// Chain plugins together.
const client = await createEmptyClient()
    .use(rpcPlugin('https://api.mainnet-beta.solana.com'))
    .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))
    .use(generatedPayerPlugin())
    .use(generatedAuthorityPlugin());

On this page