Rust

Installatie

Voeg solana-keychain toe aan je Cargo.toml met alleen de backends die je nodig hebt:

Cargo.toml
[dependencies]
# Memory signer only (default, Solana SDK 2.x)
solana-keychain = "2.0"
# Or specify backends explicitly (pick exactly one SDK feature)
solana-keychain = { version = "2.0", default-features = false, features = ["vault", "aws_kms", "sdk-v2"] }
# All remote backends on the Solana 4.x SDK line
solana-keychain = { version = "2.0", default-features = false, features = ["all", "sdk-v4"] }

Upgraden vanaf 1.x? Zie de gids voor migreren naar 2.0.

Feature Flags

FunctieBeschrijving
memoryLokale keypair ondertekening (standaard)
vaultHashiCorp Vault Transit engine
aws_kmsAWS KMS met Ed25519
gcp_kmsGCP Cloud KMS met Ed25519
privyPrivy embedded wallets
turnkeyTurnkey API
fireblocksFireblocks MPC
cdpCoinbase Developer Platform
crossmintCrossmint beheerde wallets
dfnsDfns wallet-infrastructuur
openfortOpenfort embedded wallets
paraPara MPC-wallets
utilaUtila MPC-bewaring
fordefiFordefi MPC-bewaring
ledgerLedger hardware wallet via USB-HID (alleen Rust, opt-in, niet in all)
allSchakel elke backend in behalve ledger
sdk-v2Solana SDK 2.x (standaard)
sdk-v3Solana SDK 3.x
sdk-v4Solana SDK 4.x (vereist voor v1-transacties)
unsafe-debugLogt volledige foutresponses van providers; schakel dit nooit in op productie

Precies één van sdk-v2, sdk-v3 en sdk-v4 moet zijn ingeschakeld.

Basisgebruik

Alle signers implementeren de basis- SolanaSigner-trait (pubkey, sign_message, is_available). Elke backend implementeert bovendien precies één capability-trait:

  • TransactionSigner: ondertekent je transactie zoals die is aangeleverd.
  • ModifyingSigner: de provider herschrijft de transactie en ondertekent deze vervolgens.
  • SendingSigner: de provider ondertekent en verzendt de transactie.
use solana_keychain::{SignerError, SolanaSigner, TransactionSigner};
use solana_sdk::transaction::VersionedTransaction;
async fn sign_transaction(
signer: &impl TransactionSigner,
tx: &mut VersionedTransaction,
) -> 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: returns Complete or Partial
let result = signer.sign_transaction(tx).await?;
let (base64_tx, signature) = result.into_signed_transaction();
println!("Signature: {}", signature);
Ok(())
}

Converteer een legacy Transaction met .into(). Legacy- en v0-transacties werken met elke SDK-feature; v1-transacties vereisen sdk-v4.

Signer-capabilities

BackendCapability-traitsign_message
CrossmintSendingSignerNiet ondersteund
Fordefi native autoSendingSignerJa
Fordefi native manualModifyingSignerJa
UtilaTransactionSignerNiet ondersteund
CDPTransactionSignerAlleen UTF-8-payloads
LedgerTransactionSignerJa, via een off-chain envelope
Alle overige (incl. Fordefi black box)TransactionSignerJa

De Signer::from_*-constructors voeren init() voor je uit. Als je de signertypes van Privy, Fireblocks, Dfns, Crossmint, Para, Openfort of Utila rechtstreeks aanmaakt, roep dan init().await aan vóór gebruik.

Backend-configuratie

Memory Signer

Voor ontwikkeling en testen met lokale keypairs:

use solana_keychain::Signer;
// From base58 private key
let signer = Signer::from_memory("base58_private_key")?;
// From JSON keypair file path
let signer = Signer::from_memory_file("/path/to/keypair.json")?;
// From byte array string
let signer = Signer::from_memory("[1,2,3,...]")?;

HashiCorp Vault

Voor zelf-gehoste HSM met 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
None, // Default HTTP timeouts
)?;

AWS KMS

Voor cloud-native ondertekening met AWS KMS Ed25519-sleutels:

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

Voor embedded wallet ondertekening:

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
None, // Default HTTP timeouts
).await?;

Turnkey

Voor non-custodial ondertekening:

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
None, // Default HTTP timeouts
)?;

Fireblocks

Voor institutionele MPC-ondertekening:

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: Some("SOL".to_string()), // None defaults to "SOL"; "SOL_TEST" for devnet
api_base_url: None,
poll_interval_ms: None,
max_poll_attempts: None,
use_program_call: None, // Some(true) signs via PROGRAM_CALL (sign-only, legacy/v0, hot wallet)
http_client_config: None,
};
let signer = Signer::from_fireblocks(config).await?;

GCP KMS

Voor cloud-native ondertekening met GCP Cloud KMS Ed25519-sleutels:

use solana_keychain::Signer;
let signer = Signer::from_gcp_kms(
"projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key/cryptoKeyVersions/1".to_string(),
"base58_public_key".to_string(),
).await?;

CDP (Coinbase Developer Platform)

Voor ondertekening met door Coinbase beheerde wallets:

use solana_keychain::{Signer, CdpSignerConfig, CDP_NETWORK_MAINNET};
let signer = Signer::from_cdp(CdpSignerConfig {
api_key_id: "api_key_id".to_string(), // CDP API key ID
api_key_secret: "api_key_secret".to_string(), // CDP API private key (base64 Ed25519)
wallet_secret: "wallet_secret".to_string(), // CDP wallet secret (base64 PKCS#8 DER)
address: "base58_address".to_string(), // Solana account address
network: Some(CDP_NETWORK_MAINNET.to_string()), // Required to sign transactions with address lookup tables
api_base_url: None,
http_client_config: None, // Default HTTP timeouts
})?;

sign_message van CDP accepteert alleen UTF-8-payloads.

Crossmint

Crossmint is alleen-verzenden: de API voert elke goedgekeurde transactie aan de serverzijde uit, dus er is geen sign-only-pad en sign_message mislukt. Roep sign_and_send_transaction aan; die laat je transactie ongemoeid en retourneert de handtekening van de transactie die is verwerkt. Die transactie kan afwijken van de jouwe als Crossmint de gas sponsort.

use solana_keychain::{Signer, CrossmintSignerConfig};
let config = CrossmintSignerConfig {
api_key: "api_key".to_string(),
wallet_locator: "wallet_locator".to_string(),
signer_secret: None,
signer: None,
api_base_url: None,
poll_interval_ms: None,
max_poll_attempts: None,
};
let signer = Signer::from_crossmint(config).await?;
let signature = signer
.as_sending_signer()
.expect("Crossmint is a sending signer")
.sign_and_send_transaction(&tx)
.await?;

Dfns

Voor ondertekening met Dfns wallet-infrastructuur:

use solana_keychain::{Signer, DfnsSignerConfig};
let config = DfnsSignerConfig {
auth_token: "auth_token".to_string(),
cred_id: "cred_id".to_string(),
private_key_pem: "-----BEGIN EC PRIVATE KEY-----\n...".to_string(),
wallet_id: "wallet_id".to_string(),
api_base_url: None,
http_client_config: None,
};
let signer = Signer::from_dfns(config).await?;

Para

Voor ondertekening met Para MPC-wallets:

use solana_keychain::Signer;
let signer = Signer::from_para(
"api_key".to_string(), // Para API key
"wallet_id".to_string(), // Para wallet ID
None, // Default API base URL
).await?;

Openfort

Voor het ondertekenen met een Openfort-backendwallet:

use solana_keychain::Signer;
let signer = Signer::from_openfort(
"sk_live_...".to_string(), // Openfort secret key
"acc_...".to_string(), // Account ID
"wallet_secret".to_string(), // Wallet secret (base64 PKCS#8 DER or PEM)
None, // Default HTTP timeouts
).await?;

Utila

Voor ondertekening met Utila MPC-bewaring. sign_message wordt niet ondersteund en je verzendt de ondertekende transactie zelf.

use solana_keychain::{Signer, UtilaSignerConfig};
let signer = Signer::from_utila(UtilaSignerConfig {
service_account_email: "sa@example.com".to_string(),
service_account_private_key_pem: "-----BEGIN PRIVATE KEY-----\n...".to_string(),
vault_id: "vault_id".to_string(),
wallet_id: "wallet_id".to_string(),
network: "networks/solana-devnet".to_string(),
api_base_url: None,
poll_interval_ms: None,
max_poll_attempts: None,
designated_signers: None,
http_client_config: None,
}).await?;

Fordefi

Voor ondertekening met Fordefi MPC-bewaring. API-verzoeken worden geauthenticeerd met een ECDSA P-256-verzoekhandtekening. Geef precies één van private_key_pem of request_signer op (een Arc<dyn FordefiRequestSigner>, waarmee die sleutel in een KMS/HSM blijft).

Fordefi is er in drie signertypes, vastgelegd bij het aanmaken via chain en push_mode:

chainpush_modeTypeCapabilityGedrag
NoneelkeFordefiBlackBoxSignerTransactionSignerOndertekent ruwe bytes; jij verzendt
Some(..)None of AutoFordefiNativeAutoSignerSendingSignerFordefi kan de blockhash en fees herschrijven, ondertekent en verzendt
Some(..)ManualFordefiNativeManualSignerModifyingSignerFordefi herschrijft en ondertekent; jij verzendt de geretourneerde transactie

De native manual-modus vervangt je transactie door de transactie die Fordefi heeft ondertekend. Ga daarmee verder, nooit met de transactie die je zelf hebt gebouwd. Deze moet vóór elke andere vereiste signer worden uitgevoerd.

use solana_keychain::{
Signer, FordefiSignerConfig, FordefiPushMode, SolanaChainUniqueId, FordefiSolanaFee,
FordefiPriorityLevel,
};
let config = FordefiSignerConfig {
access_token: "api_token".to_string(),
vault_id: "vault_uuid".to_string(),
private_key_pem: Some(std::fs::read_to_string("./secret/private.pem")?),
request_signer: None, // Or Some(Arc::new(your_kms_signer))
public_key: "base58_public_key".to_string(), // Solana vault address
chain: Some(SolanaChainUniqueId::SolanaDevnet), // None for black box mode
fee: Some(FordefiSolanaFee::Priority {
priority_level: FordefiPriorityLevel::Medium,
}),
push_mode: Some(FordefiPushMode::Auto), // Manual: sign without broadcasting
api_base_url: None, // Default: https://api.fordefi.com
poll_interval_ms: None, // Default: 2000
max_poll_attempts: None, // Default: 50
http_client_config: None, // Default HTTP timeouts
};
let signer = Signer::from_fordefi(config).await?;

Ledger

Voor ondertekening met een hardware wallet via USB-HID (alleen Rust). Vereist de ledger- feature, een ontgrendeld apparaat met de Solana-app en, op Linux, de udev-regels van Ledger. Ledger valt niet onder de huidige audit; zie auditstatus.

use solana_keychain::{LedgerConfig, Signer};
let signer = Signer::from_ledger(LedgerConfig {
confirm_pubkey_on_device: true,
..LedgerConfig::default()
})
.await?;

sign_message ondertekent een off-chain envelope die je payload omhult, niet de ruwe bytes; bouw die opnieuw op met solana_keychain::ledger::ledger_offchain_envelope om te verifiëren. Stel auto_open_app: false in voor onbeheerd gebruik. Een op het apparaat geweigerde prompt retourneert SignerError::UserRejected.

Uniform Signer Enum

Gebruik de Signer enum om backends tijdens runtime te selecteren:

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();

Signer implementeert alleen SolanaSigner. Je krijgt toegang tot een capability via as_transaction_signer(), as_modifying_signer() of as_sending_signer(), die None retourneren wanneer de backend die vorm niet heeft:

if let Some(transaction_signer) = signer.as_transaction_signer() {
let result = transaction_signer.sign_transaction(&mut tx).await?;
}

Of laat sign_and_send routeren op basis van de backend. De crate heeft geen RPC-client, dus jij levert de verzending aan; bij een sending-backend wordt de closure nooit aangeroepen:

let signature = signer
.sign_and_send(&mut tx, |encoded| async move { broadcast(encoded).await })
.await?;

Foutafhandeling

SignerError::BroadcastUnconfirmed { provider_tx_id, idempotency_key, transaction_signature, .. } (van Crossmint, Fordefi native auto of een falende sign_and_send-closure) betekent dat de transactie mogelijk is verwerkt. Probeer niet blindelings opnieuw: reconcilieer eerst provider_tx_id of transaction_signature, of verzend alleen de byte-identieke transactie opnieuw. Exhaustive match-expressies op SignerError hebben deze arm nodig. Zie het beveiligingsmodel voor wat elke ondertekenvorm garandeert.

Aangepaste Signers Toevoegen

Zie de handleiding voor het toevoegen van Signers om additionale key management services te integreren.

Is this page helpful?

© 2026 Solana Foundation. Alle rechten voorbehouden.