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 gereklidir) |
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 tam olarak
bir yetenek trait'i 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 | Desteklenmez |
| Fordefi native auto | SendingSigner | Evet |
| Fordefi native manual | ModifyingSigner | Evet |
| Utila | TransactionSigner | Desteklenmez |
| CDP | TransactionSigner | Yalnızca UTF-8 yükleri |
| Ledger | TransactionSigner | Evet, zincir dışı bir zarf (envelope) üzerinden |
| Diğerlerinin 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ı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ütür, dolayısıyla yalnızca imzalama yolu yoktur ve sign_message başarısız olur.
sign_and_send_transaction işlevini çağırın; bu işlev işleminize dokunmaz ve zincire işlenen
işlemin imzasını döndürür. Crossmint gas ücretini sponsorluk yoluyla karşılıyorsa bu işlem
sizinkinden 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 imzalaması 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 imzalaması için. API istekleri bir 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 ile 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'i ve ücretleri yeniden yazabilir, imzalar ve ağa yayınlar |
Some(..) | Manual | FordefiNativeManualSigner | ModifyingSigner | Fordefi 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. İşlemlere bundan devam edin, oluşturduğunuz işlemden asla devam etmeyin. Bu mod, diğer tüm gerekli 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ın çalıştığı kilidi açılmış 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ışı bir zarfı (envelope) imzalar;
doğrulamak için 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 söz konusu yapıya sahip değilse bunlar 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'in bir RPC istemcisi yoktur, bu yüzden
ağa yayını siz sağlarsınız; gönderim yapan bir backend için closure hiç ç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)
işlemin zincire işlenmiş olabileceği anlamına gelir. Körü körüne yeniden denemeyin: önce
provider_tx_id veya transaction_signature değerini mutabakata bağlayın ya da yalnızca
bayt düzeyinde aynı işlemi yeniden gönderin. SignerError üzerindeki kapsamlı (exhaustive) match ifadelerinin bu kolu içermesi gerekir.
Her imzalama biçiminin neleri garanti ettiği için bkz.
güvenlik modeli.
Ö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?