Keychain provides one SolanaSigner interface across
many key-management backends — in-memory keys, cloud KMS/HSM, and managed wallet
services. Write your signing code once, then switch backends through
configuration.
The example below signs and sends a transfer with an in-memory signer. The same code works with any backend; only the signer's construction changes.
import { createClient, generateKeyPairSigner, lamports } from "@solana/kit";import { createMemorySigner } from "@solana/keychain-memory";import { rpcAirdrop, solanaRpc } from "@solana/kit-plugin-rpc";import { airdropSigner, signer } from "@solana/kit-plugin-signer";import { getTransferSolInstruction } from "@solana-program/system";// Every Keychain backend returns the same `SolanaSigner`. Swap this in-memory// signer for `createAwsKmsSigner`, `createVaultSigner`, ... and the rest of// this file is identical.const keychainSigner = await createMemorySigner({privateKey: crypto.getRandomValues(new Uint8Array(32)),});const recipient = await generateKeyPairSigner();const client = await createClient().use(signer(keychainSigner)).use(solanaRpc({rpcUrl: "http://localhost:8899",rpcSubscriptionsUrl: "ws://localhost:8900",}),).use(rpcAirdrop()).use(airdropSigner(lamports(1_000_000_000n)));const { context } = await client.sendTransaction([getTransferSolInstruction({source: keychainSigner,destination: recipient.address,amount: lamports(10_000_000n),}),]);console.log("Signature:", context.signature);
The in-memory signer holds a raw private key — use it for development and tests. In production, use a managed backend so keys stay in dedicated infrastructure. See Choosing a backend.
Use a production backend
To sign with a production backend, install its package (or the umbrella
@solana/keychain) and construct the signer through the unified factory. The
signing code stays the same.
import { createKeychainSigner } from "@solana/keychain";const signer = await createKeychainSigner({backend: "aws-kms",keyId: "alias/my-solana-key",publicKey: "base58_public_key"});
import { createKeychainSigner } from "@solana/keychain";const signer = await createKeychainSigner({backend: "vault",vaultAddr: "https://vault.example.com:8200",vaultToken: "hvs.xxxxx",keyName: "my-solana-key",publicKey: "base58_public_key"});
See the TypeScript guide for every backend's configuration, or Choosing a backend to compare custody models.
Is this page helpful?