Keychain

Solana Keychain provides a unified interface for signing Solana transactions across multiple key management backends. Develop locally with an in-memory key, then switch to enterprise key management, cloud HSMs, or managed wallet services in production, without rewriting your signing code.

Why Keychain?

  • Single Interface: One SolanaSigner base interface across all backends, plus one capability per backend: sign, rewrite-and-sign, or sign-and-broadcast
  • Swap Backends: Change key management providers through configuration; call sites only change when the new backend has a different capability (Crossmint and Fordefi native modes)
  • Pay for what you use: Rust feature flags, per-backend npm packages, Python extras and per-backend Go modules include only the backends you need
  • Audited: Rust, TypeScript, Python and Go audited by OtterSec (the opt-in Ledger backend was out of scope); an earlier Accretion audit covered Rust and TypeScript. See audit status.

Architecture

  • Languages: Rust, TypeScript, Python and Go, at parity (the Ledger backend is Rust-only)
  • Interface: SolanaSigner base (pubkey, sign_message, is_available) plus exactly one capability per backend: TransactionSigner, ModifyingSigner or SendingSigner
  • Backends: Memory, Vault, AWS KMS, GCP KMS, Privy, Turnkey, Fireblocks, CDP, Crossmint, Dfns, Openfort, Para, Utila, Fordefi, Ledger (Rust only, opt-in, unaudited)
  • Compatibility: @solana/kit and @solana/signers 8.1+ (TypeScript) | solana-sdk 2.x, 3.x or 4.x via the sdk-v2 / sdk-v3 / sdk-v4 features (Rust; v1 transactions need sdk-v4) | solders (Python) | solana-go v2 (Go)

Supported Backends

Backends span local development, self-hosted and cloud key management, and managed or MPC wallet services. See Choosing a backend to compare custody models and pick the right one.

BackendUse CaseRustTypeScriptPythonGo
MemoryDevelopment, testing✓✓✓✓
HashiCorp VaultSelf-hosted key management✓✓✓✓
AWS KMSCloud-native (AWS)✓✓✓✓
GCP KMSCloud-native (GCP)✓✓✓✓
PrivyEmbedded wallets✓✓✓✓
TurnkeyNon-custodial key management✓✓✓✓
FireblocksInstitutional custody✓✓✓✓
CDPCoinbase Developer Platform✓✓✓✓
CrossmintCrossmint managed wallets✓✓✓✓
DfnsDfns wallet infrastructure✓✓✓✓
OpenfortOpenfort backend wallets✓✓✓✓
ParaPara MPC wallets✓✓✓✓
UtilaUtila MPC custody✓✓✓✓
FordefiFordefi MPC custody✓✓✓✓
LedgerHardware wallet (opt-in, unaudited)✓

Quick Start

Rust

Install the Rust crate:

cargo add solana-keychain

Basic usage:

use solana_keychain::{Signer, SolanaSigner};
// Create a signer from any backend
let signer = Signer::from_memory("base58_private_key")?;
let pubkey = signer.pubkey();
// Transaction signing is a capability; `tx` is a VersionedTransaction
if let Some(tx_signer) = signer.as_transaction_signer() {
let result = tx_signer.sign_transaction(&mut tx).await?;
}
// Or let the umbrella route any backend shape and supply the RPC hop yourself
let signature = signer
.sign_and_send(&mut tx, |encoded| async move { broadcast(encoded).await })
.await?;

TypeScript

Install the TypeScript package:

pnpm add @solana/keychain

Basic usage:

import { createKeychainSigner } from "@solana/keychain";
import { signTransactionWithSigners } from "@solana/signers";
// Create any signer via the unified factory
const signer = await createKeychainSigner({
backend: "vault",
vaultAddr: "https://vault.example.com:8200",
vaultToken: "hvs.xxxxx",
keyName: "my-solana-key",
publicKey: "base58_public_key"
});
// Sign an already-compiled transaction
const signedTx = await signTransactionWithSigners(
[signer],
compiledTransaction
);

To install a Keychain signer on a Kit client as its payer or identity, use @solana/keychain-kit-plugin (Crossmint and Fordefi native modes are excluded, since they rewrite transactions).

Python

Install the package (heavier backends ship as extras, for example solana-keychain[aws-kms]):

pip install solana-keychain

Basic usage:

import os
from solana_keychain import VaultSignerConfig, create_vault_signer
signer = await create_vault_signer(
VaultSignerConfig(
api_base_url="https://vault.example.com:8200",
token=os.environ["VAULT_TOKEN"],
key_name="my-solana-key",
public_key="base58_public_key",
)
)
# tx is a solders VersionedTransaction
result = await signer.sign_transaction(tx)
  • Python Guide - Full installation, extras and backend configuration
  • PyPI - Python package

Go

Each backend is its own Go module, so you only pull the backends you import:

go get github.com/solana-foundation/solana-keychain/go/signers/vault/v2@latest

Basic usage:

import "github.com/solana-foundation/solana-keychain/go/signers/vault/v2"
signer, err := vault.New(vault.Config{
VaultAddr: "https://vault.example.com:8200",
Token: os.Getenv("VAULT_TOKEN"),
KeyName: "my-solana-key",
Pubkey: "base58_public_key",
})
if err != nil {
return err
}
// tx is a *solana.Transaction from solana-go v2
res, err := signer.SignTransaction(ctx, tx)

Next steps

Source

Built and maintained by the Solana Foundation. Licensed under MIT.

Is this page helpful?

Table of Contents

Edit Page
© 2026 Solana Foundation. All rights reserved.
Keychain | Solana