Kurulum
solana-keychain dosyasını Cargo.toml dosyanıza yalnızca ihtiyacınız olan
backend'lerle ekleyin:
[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"] }
1.x sürümünden mi yükseltiyorsunuz? 2.0'a Geçiş kılavuzuna göz atın.
Özellik Bayrakları
| Özellik | Açıklama |
|---|---|
memory | Yerel keypair imzalama (varsayılan) |
vault | HashiCorp Vault Transit motoru |
aws_kms | Ed25519 ile AWS KMS |
gcp_kms | Ed25519 ile GCP Cloud KMS |
privy | Privy gömülü cüzdanlar |
turnkey | Turnkey API |
fireblocks | Fireblocks MPC |
cdp | Coinbase Geliştirici Platformu |
crossmint | Crossmint yönetilen cüzdanlar |
dfns | Dfns cüzdan altyapısı |
openfort | Openfort gömülü cüzdanlar |
para | Para MPC cüzdanları |
utila | Utila MPC saklama |
fordefi | Fordefi MPC saklama |
ledger | USB-HID üzerinden Ledger donanım cüzdanı (yalnızca Rust, isteğe bağlı, all içinde yer almaz) |
all | ledger hariç tüm backend'leri etkinleştirir |
sdk-v2 | Solana SDK 2.x (varsayılan) |
sdk-v3 | Solana SDK 3.x |
sdk-v4 | Solana SDK 4.x (v1 işlemleri için gerekli) |
unsafe-debug | Sağlayıcının tüm hata yanıtlarını günlüğe kaydeder; üretim ortamında asla etkinleştirmeyin |
sdk-v2, sdk-v3 ve sdk-v4 özelliklerinden tam olarak biri etkinleştirilmelidir.
Temel Kullanım
Tüm imzalayıcılar temel SolanaSigner trait'ini (pubkey, sign_message, is_available) uygular. Her backend ayrıca yalnızca bir yetenek trait'ini uygular:
TransactionSigner: işleminizi olduğu gibi imzalar.ModifyingSigner: sağlayıcı işlemi yeniden yazar, ardından imzalar.SendingSigner: sağlayıcı işlemi imzalar ve ağa yayınlar.
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(())}
Eski (legacy) bir Transaction nesnesini .into() ile dönüştürün. Legacy ve v0 işlemleri tüm SDK özelliklerinde çalışır; v1 işlemleri sdk-v4 gerektirir.
İmzalayıcı Yetenekleri
| Backend | Yetenek trait'i | sign_message |
|---|---|---|
| Crossmint | SendingSigner | Desteklenmiyor |
| Fordefi native auto | SendingSigner | Evet |
| Fordefi native manual | ModifyingSigner | Evet |
| Utila | TransactionSigner | Desteklenmiyor |
| CDP | TransactionSigner | Yalnızca UTF-8 yükleri |
| Ledger | TransactionSigner | Evet, zincir dışı (off-chain) bir zarf üzerinden |
| Diğer tümü (Fordefi black box dahil) | TransactionSigner | Evet |
Signer::from_* yapıcıları (constructor) init() işlevini sizin yerinize çalıştırır. Privy, Fireblocks, Dfns, Crossmint, Para, Openfort veya Utila imzalayıcı türlerini doğrudan oluşturuyorsanız, kullanmadan önce init().await çağrısını yapın.
Backend Yapılandırması
Bellek İmzalayıcı
Yerel keypair'lerle geliştirme ve test için:
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
Transit motoru ile kendi barındırılan HSM için:
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
AWS KMS Ed25519 anahtarlarıyla bulut tabanlı imzalama için:
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
Gömülü cüzdan imzalama için:
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
Saklama dışı imzalama için:
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
Kurumsal MPC imzalama için:
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
GCP Cloud KMS Ed25519 anahtarları ile bulut tabanlı imzalama için:
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)
Coinbase yönetilen cüzdan imzalama için:
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})?;
CDP'nin sign_message işlevi yalnızca UTF-8 yüklerini kabul eder.
Crossmint
Crossmint yalnızca gönderim yapar: API'si onaylanan her işlemi sunucu tarafında yürüttüğü için yalnızca imzalama yolu yoktur ve sign_message başarısız olur. İşleminize dokunmadan bırakan ve ağa ulaşan işlemin imzasını döndüren sign_and_send_transaction işlevini çağırın. Crossmint gas ücretini sponsor ederse bu işlem sizin işleminizden farklı olabilir.
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
Dfns cüzdan altyapısı imzalama için:
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
Para MPC cüzdan imzalama için:
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
Openfort backend cüzdanı ile imzalama için:
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
Utila MPC saklama ile imzalama için. sign_message desteklenmez ve imzalanan işlemi ağa kendiniz yayınlarsınız.
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
Fordefi MPC saklama ile imzalama için. API istekleri ECDSA P-256 istek imzasıyla doğrulanır. private_key_pem veya request_signer (bir Arc<dyn FordefiRequestSigner>; bu anahtarı bir KMS/HSM içinde tutmak için kullanılır) seçeneklerinden tam olarak birini sağlayın.
Fordefi, oluşturma sırasında chain ve push_mode değerleriyle belirlenen üç imzalayıcı türüyle gelir:
chain | push_mode | Tür | Yetenek | Davranış |
|---|---|---|---|---|
None | herhangi biri | FordefiBlackBoxSigner | TransactionSigner | Ham baytları imzalar; ağa yayını siz yaparsınız |
Some(..) | None veya Auto | FordefiNativeAutoSigner | SendingSigner | Fordefi blockhash ve ücretleri yeniden yazabilir, işlemi imzalar ve ağa yayınlar |
Some(..) | Manual | FordefiNativeManualSigner | ModifyingSigner | Fordefi işlemi yeniden yazar ve imzalar; döndürülen işlemi ağa siz yayınlarsınız |
Native manual modu, işleminizi Fordefi'nin imzaladığı işlemle değiştirir. Devam ederken her zaman bu işlemi kullanın, kendi oluşturduğunuz işlemi asla kullanmayın. Bu mod, gerekli diğer tüm imzalayıcılardan önce çalışmalıdır.
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
USB-HID üzerinden donanım cüzdanı ile imzalama için (yalnızca Rust). ledger özelliğini, Solana uygulamasını çalıştıran kilidi açık bir cihazı ve Linux'ta Ledger'ın udev kurallarını gerektirir. Ledger mevcut denetim kapsamında değildir; bkz. denetim durumu.
use solana_keychain::{LedgerConfig, Signer};let signer = Signer::from_ledger(LedgerConfig {confirm_pubkey_on_device: true,..LedgerConfig::default()}).await?;
sign_message, ham baytları değil, yükünüzü saran zincir dışı (off-chain) bir zarfı imzalar; doğrulamak için bu zarfı solana_keychain::ledger::ledger_offchain_envelope ile yeniden oluşturun. Gözetimsiz kullanım için auto_open_app: false ayarlayın. Cihazda reddedilen bir istem SignerError::UserRejected döndürür.
Birleşik İmzalayıcı Enum
Çalışma zamanında arka uçları seçmek için Signer enum'unu kullanın:
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 yalnızca SolanaSigner uygular. Bir yeteneğe as_transaction_signer(), as_modifying_signer() veya as_sending_signer() ile ulaşın; backend'de bu yapı yoksa bu işlevler None döndürür:
if let Some(transaction_signer) = signer.as_transaction_signer() {let result = transaction_signer.sign_transaction(&mut tx).await?;}
Ya da sign_and_send işlevinin backend'e göre yönlendirme yapmasına izin verin. Crate'te RPC istemcisi yoktur, bu nedenle ağa yayını siz sağlarsınız; gönderim yapan bir backend için closure hiçbir zaman çağrılmaz:
let signature = signer.sign_and_send(&mut tx, |encoded| async move { broadcast(encoded).await }).await?;
Hata Yönetimi
SignerError::BroadcastUnconfirmed { provider_tx_id, idempotency_key, transaction_signature, .. } (Crossmint'ten, Fordefi native auto'dan veya başarısız olan bir sign_and_send closure'ından gelir) işlemin ağa ulaşmış olabileceği anlamına gelir. Körü körüne yeniden denemeyin: önce provider_tx_id veya transaction_signature değerini mutabakata tabi tutun ya da yalnızca bayt bayt aynı işlemi yeniden gönderin. SignerError üzerindeki kapsamlı match ifadelerinin bu kolu içermesi gerekir. Her imzalama yapısının neyi garanti ettiği için güvenlik modeline bakın.
Özel İmzalayıcılar Ekleme
Ek anahtar yönetim hizmetlerini entegre etmek için İmzalayıcılar Ekleme kılavuzuna bakın.
Is this page helpful?