Installatie
Voeg solana-keychain toe aan je Cargo.toml met alleen de backends die je
nodig hebt:
[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 linesolana-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
| Functie | Beschrijving |
|---|---|
memory | Lokale keypair ondertekening (standaard) |
vault | HashiCorp Vault Transit engine |
aws_kms | AWS KMS met Ed25519 |
gcp_kms | GCP Cloud KMS met Ed25519 |
privy | Privy embedded wallets |
turnkey | Turnkey API |
fireblocks | Fireblocks MPC |
cdp | Coinbase Developer Platform |
crossmint | Crossmint beheerde wallets |
dfns | Dfns wallet-infrastructuur |
openfort | Openfort embedded wallets |
para | Para MPC-wallets |
utila | Utila MPC-bewaring |
fordefi | Fordefi MPC-bewaring |
ledger | Ledger hardware wallet via USB-HID (alleen Rust, opt-in, niet in all) |
all | Schakel elke backend in behalve ledger |
sdk-v2 | Solana SDK 2.x (standaard) |
sdk-v3 | Solana SDK 3.x |
sdk-v4 | Solana SDK 4.x (vereist voor v1-transacties) |
unsafe-debug | Logt 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 keylet 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 Partiallet 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
| Backend | Capability-trait | sign_message |
|---|---|---|
| Crossmint | SendingSigner | Niet ondersteund |
| Fordefi native auto | SendingSigner | Ja |
| Fordefi native manual | ModifyingSigner | Ja |
| Utila | TransactionSigner | Niet ondersteund |
| CDP | TransactionSigner | Alleen UTF-8-payloads |
| Ledger | TransactionSigner | Ja, via een off-chain envelope |
| Alle overige (incl. Fordefi black box) | TransactionSigner | Ja |
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 keylet signer = Signer::from_memory("base58_private_key")?;// From JSON keypair file pathlet signer = Signer::from_memory_file("/path/to/keypair.json")?;// From byte array stringlet 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 keyNone, // 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 keySome("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 IDNone, // 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 keyNone, // 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 devnetapi_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 IDapi_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 addressnetwork: Some(CDP_NETWORK_MAINNET.to_string()), // Required to sign transactions with address lookup tablesapi_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 IDNone, // 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:
chain | push_mode | Type | Capability | Gedrag |
|---|---|---|---|---|
None | elke | FordefiBlackBoxSigner | TransactionSigner | Ondertekent ruwe bytes; jij verzendt |
Some(..) | None of Auto | FordefiNativeAutoSigner | SendingSigner | Fordefi kan de blockhash en fees herschrijven, ondertekent en verzendt |
Some(..) | Manual | FordefiNativeManualSigner | ModifyingSigner | Fordefi 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 addresschain: Some(SolanaChainUniqueId::SolanaDevnet), // None for black box modefee: Some(FordefiSolanaFee::Priority {priority_level: FordefiPriorityLevel::Medium,}),push_mode: Some(FordefiPushMode::Auto), // Manual: sign without broadcastingapi_base_url: None, // Default: https://api.fordefi.compoll_interval_ms: None, // Default: 2000max_poll_attempts: None, // Default: 50http_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 genericallylet 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?