TypeScript
Install and use @solana/keychain in TypeScript applications
Installation
Install the umbrella package or individual signers as needed:
# Umbrella package (includes all signers)
pnpm add @solana/keychain
# Or install individual packages
pnpm add @solana/keychain-core # Core interfaces (required for custom signers)
pnpm add @solana/keychain-vault # HashiCorp Vault
pnpm add @solana/keychain-aws-kms # AWS KMS
pnpm add @solana/keychain-privy # Privy
pnpm add @solana/keychain-turnkey # Turnkey
pnpm add @solana/keychain-fireblocks # FireblocksBasic Usage
All signers implement the SolanaSigner interface, which is compatible with
@solana/kit and @solana/signers:
import { SolanaSigner } from "@solana/keychain-core";
import { signTransactionMessageWithSigners } from "@solana/signers";
import {
createTransactionMessage,
setTransactionMessageFeePayerSigner,
pipe,
} from "@solana/kit";
async function signWithKeychain(signer: SolanaSigner) {
// Check availability (useful for remote signers)
if (!(await signer.isAvailable())) {
throw new Error("Signer offline");
}
// Use with @solana/kit transaction builder
const transaction = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayerSigner(signer, tx)
// ... add instructions
);
// Sign with the standard signers API
const signedTx = await signTransactionMessageWithSigners(transaction);
return signedTx;
}Backend Configuration
HashiCorp Vault
import { VaultSigner } from "@solana/keychain-vault";
const signer = new VaultSigner({
vaultAddr: "https://vault.example.com:8200",
vaultToken: "hvs.xxxxx",
keyName: "my-solana-key",
publicKey: "base58_public_key",
});AWS KMS
import { AwsKmsSigner } from "@solana/keychain-aws-kms";
const signer = new AwsKmsSigner({
keyId: "alias/my-solana-key",
publicKey: "base58_public_key",
region: "us-east-1", // optional
});Privy
import { PrivySigner } from "@solana/keychain-privy";
const signer = await PrivySigner.create({
appId: "app_id",
appSecret: "app_secret",
walletId: "wallet_id",
});Turnkey
import { TurnkeySigner } from "@solana/keychain-turnkey";
const signer = new TurnkeySigner({
apiPublicKey: "api_public_key",
apiPrivateKey: "api_private_key",
organizationId: "org_id",
privateKeyId: "private_key_id",
publicKey: "base58_public_key",
});Fireblocks
import { FireblocksSigner } from "@solana/keychain-fireblocks";
const signer = new FireblocksSigner({
apiKey: "api_key",
privateKeyPem: "-----BEGIN RSA PRIVATE KEY-----\n...",
vaultAccountId: "0",
assetId: "SOL", // or "SOL_TEST" for devnet
});
await signer.init();SolanaSigner Interface
The SolanaSigner interface extends @solana/signers types for full
compatibility:
interface SolanaSigner<TAddress extends string = string>
extends TransactionPartialSigner<TAddress>,
MessagePartialSigner<TAddress> {
// Public key address
readonly address: Address<TAddress>;
// Health check for remote signers
isAvailable(): Promise<boolean>;
// Sign messages (@solana/kit compatible)
signMessages(
messages: readonly SignableMessage[]
): Promise<readonly SignatureDictionary[]>;
// Sign transactions (@solana/kit compatible)
signTransactions(
transactions: readonly Transaction[]
): Promise<readonly SignatureDictionary[]>;
}Building Custom Signers
Implement the SolanaSigner interface to create custom signers:
import { SolanaSigner } from "@solana/keychain-core";
import type { Address } from "@solana/addresses";
class MyCustomSigner implements SolanaSigner {
readonly address: Address;
constructor(address: Address) {
this.address = address;
}
async isAvailable(): Promise<boolean> {
return await myBackend.healthCheck();
}
async signMessages(messages) {
return await myBackend.signMessages(messages);
}
async signTransactions(transactions) {
return await myBackend.signTransactions(transactions);
}
}See the Adding Signers guide to integrate additional key management services.