Rust
Install and use solana-keychain in Rust applications
Installation
Add solana-keychain to your Cargo.toml with only the backends you need:
[dependencies]
# Memory signer only (default)
solana-keychain = "0.2.1"
# Or specify backends explicitly
solana-keychain = { version = "0.2.1", default-features = false, features = ["vault", "aws_kms"] }
# All backends
solana-keychain = { version = "0.2.1", features = ["all"] }Feature Flags
| Feature | Description |
|---|---|
memory | Local keypair signing (default) |
vault | HashiCorp Vault Transit engine |
aws_kms | AWS KMS with Ed25519 |
privy | Privy embedded wallets |
turnkey | Turnkey API |
fireblocks | Fireblocks MPC |
all | Enable all backends |
Basic Usage
All signers implement the SolanaSigner trait:
use solana_keychain::{SolanaSigner, Signer, SignerError};
use solana_sdk::transaction::Transaction;
async fn sign_transaction(
signer: &impl SolanaSigner,
tx: &mut Transaction,
) -> Result<(), SignerError> {
// Get the signer's public key
let pubkey = signer.pubkey();
println!("Signing with: {}", pubkey);
// Check availability (useful for remote signers)
if !signer.is_available().await {
return Err(SignerError::NotAvailable("Signer offline".into()));
}
// Sign the transaction
let signature = signer.sign_transaction(&mut tx).await?;
println!("Signature: {}", signature);
Ok(())
}Backend Configuration
Memory Signer
For development and testing with local keypairs:
use solana_keychain::Signer;
// From base58 private key
let signer = Signer::from_memory("base58_private_key")?;
// From JSON file path
let signer = Signer::from_memory("/path/to/keypair.json")?;
// From byte array string
let signer = Signer::from_memory("[1,2,3,...]")?;HashiCorp Vault
For self-hosted HSM with Transit engine:
use solana_keychain::Signer;
let signer = Signer::from_vault(
"https://vault.example.com:8200".to_string(), // Vault address
"hvs.xxxxx".to_string(), // Vault token
"my-solana-key".to_string(), // Key name in Transit
"base58_public_key".to_string(), // Expected public key
)?;AWS KMS
For cloud-native signing with AWS KMS Ed25519 keys:
use solana_keychain::Signer;
let signer = Signer::from_aws_kms(
"alias/my-solana-key".to_string(), // KMS key ID or alias
"base58_public_key".to_string(), // Expected public key
Some("us-east-1".to_string()), // Region (optional)
).await?;Privy
For embedded wallet signing:
use solana_keychain::Signer;
let signer = Signer::from_privy(
"app_id".to_string(), // Privy app ID
"app_secret".to_string(), // Privy app secret
"wallet_id".to_string(), // Wallet ID
).await?;Turnkey
For non-custodial signing:
use solana_keychain::Signer;
let signer = Signer::from_turnkey(
"api_public_key".to_string(), // Turnkey API public key
"api_private_key".to_string(), // Turnkey API private key
"org_id".to_string(), // Organization ID
"private_key_id".to_string(), // Private key ID in Turnkey
"base58_public_key".to_string(),// Expected public key
)?;Fireblocks
For institutional MPC signing:
use solana_keychain::{Signer, FireblocksSignerConfig};
let config = FireblocksSignerConfig {
api_key: "api_key".to_string(),
private_key_pem: "-----BEGIN RSA PRIVATE KEY-----\n...".to_string(),
vault_account_id: "0".to_string(),
asset_id: "SOL".to_string(), // or "SOL_TEST" for devnet
};
let signer = Signer::from_fireblocks(config).await?;Unified Signer Enum
Use the Signer enum to select backends at runtime:
use solana_keychain::{Signer, SolanaSigner, SignerError};
async fn get_signer(backend: &str) -> Result<Signer, SignerError> {
match backend {
"memory" => Signer::from_memory("base58_key"),
"vault" => Signer::from_vault(/* ... */),
"kms" => Signer::from_aws_kms(/* ... */).await,
_ => Err(SignerError::ConfigError("Unknown backend".into())),
}
}
// Use it generically
let signer = get_signer("kms").await?;
let pubkey = signer.pubkey();Adding Custom Signers
See the Adding Signers guide to integrate additional key management services.