Rust

安装

将 solana-keychain 添加到您的 Cargo.toml 中,仅启用所需的后端:

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"] }

从 1.x 升级?请参阅 迁移到 2.0 指南。

功能标志

功能描述
memory本地 keypair 签名(默认)
vaultHashiCorp Vault Transit 引擎
aws_kmsAWS KMS(Ed25519)
gcp_kmsGCP Cloud KMS(Ed25519)
privyPrivy 嵌入式钱包
turnkeyTurnkey API
fireblocksFireblocks MPC
cdpCoinbase 开发者平台
crossmintCrossmint 托管钱包
dfnsDfns 钱包基础设施
openfortOpenfort 嵌入式钱包
paraPara MPC 钱包
utilaUtila MPC 托管
fordefiFordefi MPC 托管
ledger通过 USB-HID 连接的 Ledger 硬件钱包(仅限 Rust,需手动启用,不包含在 all 中)
all启用除 ledger 之外的所有后端
sdk-v2Solana SDK 2.x(默认)
sdk-v3Solana SDK 3.x
sdk-v4Solana SDK 4.x(v1 交易必需)
unsafe-debug记录完整的提供商错误响应;切勿在生产环境中启用

sdk-v2、sdk-v3 和 sdk-v4 中必须且只能启用一个。

基本用法

所有签名器都实现了基础的 SolanaSigner trait (pubkey、sign_message、is_available)。每个后端还会恰好实现一个能力 trait:

  • TransactionSigner:按原样签署您的交易。
  • ModifyingSigner:提供商先重写交易,再进行签名。
  • SendingSigner:提供商完成签名并广播交易。
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(())
}

使用 .into() 转换旧版 Transaction。旧版交易和 v0 交易适用于所有 SDK 功能;v1 交易需要 sdk-v4。

签名器能力

后端能力 traitsign_message
CrossmintSendingSigner不支持
Fordefi 原生自动模式SendingSigner是
Fordefi 原生手动模式ModifyingSigner是
UtilaTransactionSigner不支持
CDPTransactionSigner仅支持 UTF-8 载荷
LedgerTransactionSigner是,通过链下信封实现
所有其他后端(包括 Fordefi 黑盒模式)TransactionSigner是

Signer::from_* 构造函数会自动为您运行 init()。如果您直接构造 Privy、Fireblocks、Dfns、Crossmint、Para、Openfort 或 Utila 签名器类型,请在使用前调用 init().await。

后端配置

内存签名器

用于本地密钥对的开发和测试:

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

用于自托管 HSM 与 Transit 引擎:

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

用于使用 AWS KMS Ed25519 密钥的云原生签名:

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

用于嵌入式钱包签名:

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

用于非托管签名:

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

用于机构级 MPC 签名:

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

用于使用 GCP Cloud KMS Ed25519 密钥进行云原生签名:

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 开发者平台)

用于 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 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
})?;

CDP 的 sign_message 仅接受 UTF-8 载荷。

Crossmint

Crossmint 仅支持发送:其 API 会在服务端执行每一笔已批准的交易,因此不存在仅签名的路径,sign_message 会失败。请调用 sign_and_send_transaction,它不会改动您的交易,并返回最终上链交易的签名。如果 Crossmint 代付 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

用于 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

用于 Para MPC 钱包签名:

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

用于 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

用于 Utila MPC 托管签名。不支持 sign_message,且需要您自行广播已签名的交易。

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 托管签名。API 请求通过 ECDSA P-256 请求签名进行身份验证。请在 private_key_pem 或 request_signer(一个 Arc<dyn FordefiRequestSigner>,用于将该密钥保存在 KMS/HSM 中)中恰好提供一个。

Fordefi 提供三种签名器类型,由 chain 和 push_mode 在构造时确定:

chainpush_mode类型能力行为
None任意FordefiBlackBoxSignerTransactionSigner对原始字节签名;由您自行广播
Some(..)None 或 AutoFordefiNativeAutoSignerSendingSignerFordefi 可能会重写区块哈希和费用,然后签名并广播
Some(..)ManualFordefiNativeManualSignerModifyingSignerFordefi 重写并签名;由您广播返回的交易

原生手动模式会用 Fordefi 签名后的交易替换您的交易。后续操作请基于该交易继续,切勿使用您自己构建的交易。它必须先于任何其他必需的签名器运行。

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

用于通过 USB-HID 进行硬件钱包签名(仅限 Rust)。需要启用 ledger 功能,设备需已解锁并运行 Solana 应用;在 Linux 上,还需要 Ledger 的 udev 规则。Ledger 不在当前审计范围内;请参阅 审计状态。

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

sign_message 签署的是包裹您载荷的链下信封,而不是原始字节;如需验证,请使用 solana_keychain::ledger::ledger_offchain_envelope 重新构建。无人值守使用时,请设置 auto_open_app: false。若在设备上拒绝提示,将返回 SignerError::UserRejected。

统一签名器枚举

使用 Signer 枚举在运行时选择后端:

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 仅实现 SolanaSigner。请通过 as_transaction_signer()、as_modifying_signer() 或 as_sending_signer() 获取相应能力,当后端不具备该形态时,这些方法会返回 None:

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

或者让 sign_and_send 根据后端自动路由。该 crate 不含 RPC 客户端,因此广播需由您提供;对于发送型后端,该闭包永远不会被调用:

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

错误处理

SignerError::BroadcastUnconfirmed { provider_tx_id, idempotency_key, transaction_signature, .. } (来自 Crossmint、Fordefi 原生自动模式,或失败的 sign_and_send 闭包) 表示交易可能已经上链。请勿盲目重试:应先核对 provider_tx_id 或 transaction_signature,或者仅重新发送字节完全相同的交易。对 SignerError 进行穷尽式 match 时需要包含此分支。有关每种签名形态的保证,请参阅 安全模型。

添加自定义签名器

请参阅添加签名器指南以集成其他密钥管理服务。

Is this page helpful?

Table of Contents

Edit Page
©️ 2026 Solana 基金会版权所有