Cài đặt
Thêm solana-keychain vào Cargo.toml của bạn với chỉ những backend bạn cần:
[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"] }
Nâng cấp từ 1.x? Xem hướng dẫn Chuyển sang 2.0.
Cờ Tính năng
| Tính năng | Mô tả |
|---|---|
memory | Ký keypair cục bộ (mặc định) |
vault | HashiCorp Vault Transit engine |
aws_kms | AWS KMS với Ed25519 |
gcp_kms | GCP Cloud KMS với Ed25519 |
privy | Ví nhúng Privy |
turnkey | Turnkey API |
fireblocks | Fireblocks MPC |
cdp | Coinbase Developer Platform |
crossmint | Ví được quản lý bởi Crossmint |
dfns | Cơ sở hạ tầng ví Dfns |
openfort | Ví nhúng Openfort |
para | Ví MPC Para |
utila | Lưu ký MPC Utila |
fordefi | Lưu ký MPC Fordefi |
ledger | Ví cứng Ledger qua USB-HID (chỉ Rust, tùy chọn bật, không nằm trong all) |
all | Bật mọi backend ngoại trừ ledger |
sdk-v2 | Solana SDK 2.x (mặc định) |
sdk-v3 | Solana SDK 3.x |
sdk-v4 | Solana SDK 4.x (bắt buộc đối với giao dịch v1) |
unsafe-debug | Ghi log toàn bộ phản hồi lỗi từ nhà cung cấp; không bao giờ bật trong môi trường production |
Phải bật đúng một trong các tính năng sdk-v2, sdk-v3 và sdk-v4.
Cách sử dụng Cơ bản
Tất cả signer đều triển khai
trait SolanaSigner
cơ sở (pubkey, sign_message, is_available). Mỗi backend cũng triển khai đúng
một trait khả năng:
TransactionSigner: ký giao dịch của bạn đúng như được cung cấp.ModifyingSigner: nhà cung cấp viết lại giao dịch, sau đó ký.SendingSigner: nhà cung cấp ký và phát sóng giao dịch.
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(())}
Chuyển đổi Transaction legacy bằng .into(). Giao dịch legacy và v0 hoạt động
trên mọi tính năng SDK; giao dịch v1 yêu cầu sdk-v4.
Khả năng của Signer
| Backend | Trait khả năng | sign_message |
|---|---|---|
| Crossmint | SendingSigner | Không được hỗ trợ |
| Fordefi native auto | SendingSigner | Có |
| Fordefi native manual | ModifyingSigner | Có |
| Utila | TransactionSigner | Không được hỗ trợ |
| CDP | TransactionSigner | Chỉ payload UTF-8 |
| Ledger | TransactionSigner | Có, thông qua một envelope off-chain |
| Tất cả các backend còn lại (bao gồm Fordefi black box) | TransactionSigner | Có |
Các hàm khởi tạo Signer::from_* sẽ tự chạy init() cho bạn. Nếu bạn tạo trực tiếp
các kiểu signer Privy, Fireblocks, Dfns, Crossmint, Para, Openfort hoặc Utila,
hãy gọi init().await trước khi sử dụng.
Cấu hình Backend
Memory Signer
Dành cho phát triển và thử nghiệm với keypair cục bộ:
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
Dành cho HSM tự lưu trữ với 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
Dành cho ký cloud-native với khóa Ed25519 AWS KMS:
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
Dành cho ký ví nhúng:
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
Dành cho ký phi tập trung:
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
Để ký MPC cấp tổ chức:
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
Để ký native trên đám mây với khóa Ed25519 của GCP Cloud KMS:
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)
Để ký ví được quản lý bởi Coinbase:
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 của CDP chỉ chấp nhận payload UTF-8.
Crossmint
Crossmint chỉ hỗ trợ gửi: API của Crossmint thực thi mọi giao dịch đã được phê duyệt
trên phía máy chủ, vì vậy không có luồng chỉ ký, và sign_message sẽ thất bại. Hãy gọi
sign_and_send_transaction; hàm này giữ nguyên giao dịch của bạn và trả về
chữ ký của giao dịch đã được ghi nhận. Giao dịch đó có thể khác với giao dịch
của bạn nếu Crossmint tài trợ phí gas.
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
Để ký cơ sở hạ tầng ví Dfns:
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
Để ký ví MPC của Para:
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
Dành cho việc ký bằng ví backend của Openfort:
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
Dành cho việc ký với lưu ký MPC Utila. sign_message không được hỗ trợ, và bạn
tự phát sóng giao dịch đã ký.
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
Dành cho việc ký với lưu ký MPC Fordefi. Các yêu cầu API được xác thực bằng chữ ký yêu cầu
ECDSA P-256. Hãy cung cấp đúng một trong hai: private_key_pem, hoặc
request_signer (một Arc<dyn FordefiRequestSigner>, dùng để giữ khóa đó trong
KMS/HSM).
Fordefi có ba kiểu signer, được cố định khi khởi tạo bởi chain và
push_mode:
chain | push_mode | Kiểu | Khả năng | Hành vi |
|---|---|---|---|---|
None | bất kỳ | FordefiBlackBoxSigner | TransactionSigner | Ký trên byte thô; bạn tự phát sóng |
Some(..) | None hoặc Auto | FordefiNativeAutoSigner | SendingSigner | Fordefi có thể viết lại blockhash và phí, rồi ký và phát sóng |
Some(..) | Manual | FordefiNativeManualSigner | ModifyingSigner | Fordefi viết lại và ký; bạn tự phát sóng giao dịch được trả về |
Chế độ native manual thay thế giao dịch của bạn bằng giao dịch mà Fordefi đã ký. Hãy tiếp tục từ giao dịch đó, không bao giờ từ giao dịch bạn đã dựng. Chế độ này phải chạy trước mọi signer bắt buộc khác.
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
Dành cho việc ký bằng ví cứng qua USB-HID (chỉ Rust). Yêu cầu tính năng ledger,
một thiết bị đã mở khóa đang chạy ứng dụng Solana và, trên Linux, các quy tắc udev của Ledger.
Ledger không nằm trong phạm vi cuộc kiểm toán hiện tại; xem
trạng thái kiểm toán.
use solana_keychain::{LedgerConfig, Signer};let signer = Signer::from_ledger(LedgerConfig {confirm_pubkey_on_device: true,..LedgerConfig::default()}).await?;
sign_message ký một envelope off-chain bao quanh payload của bạn, chứ không phải
byte thô; hãy dựng lại bằng solana_keychain::ledger::ledger_offchain_envelope để
xác minh. Đặt auto_open_app: false khi dùng không cần giám sát. Nếu từ chối lời nhắc trên
thiết bị, hàm sẽ trả về SignerError::UserRejected.
Enum Signer Thống Nhất
Sử dụng enum Signer để chọn backend tại 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 genericallylet signer = get_signer("kms").await?;let pubkey = signer.pubkey();
Signer chỉ triển khai SolanaSigner. Hãy truy cập một khả năng thông qua
as_transaction_signer(), as_modifying_signer() hoặc as_sending_signer(),
các hàm này trả về None khi backend không có dạng đó:
if let Some(transaction_signer) = signer.as_transaction_signer() {let result = transaction_signer.sign_transaction(&mut tx).await?;}
Hoặc để sign_and_send tự định tuyến theo backend. Crate này không có RPC client, vì vậy bạn
tự cung cấp phần phát sóng; với backend dạng sending, closure sẽ không bao giờ được gọi:
let signature = signer.sign_and_send(&mut tx, |encoded| async move { broadcast(encoded).await }).await?;
Xử lý lỗi
SignerError::BroadcastUnconfirmed { provider_tx_id, idempotency_key, transaction_signature, .. }
(từ Crossmint, Fordefi native auto, hoặc một closure sign_and_send bị lỗi)
nghĩa là giao dịch có thể đã được ghi nhận. Đừng thử lại một cách mù quáng: hãy đối soát
provider_tx_id hoặc transaction_signature trước, hoặc chỉ gửi lại giao dịch
giống hệt từng byte. Các match đầy đủ trên SignerError cần có nhánh này.
Xem
mô hình bảo mật
để biết mỗi dạng ký đảm bảo những gì.
Thêm Signer Tùy Chỉnh
Xem hướng dẫn Thêm Signer để tích hợp các dịch vụ quản lý khóa bổ sung.
Is this page helpful?