架构概述
Kora 使用外部
solana-keychain
crate 来执行所有签名操作。此架构为签署 Solana 交易提供了统一的签名接口。要向 Kora 添加新的签名器,您需要:
- 首先:将您的签名器实现添加到
solana-keychaincrate - 其次:在 Kora 中添加对您的签名器的配置支持
分步集成指南
快速集成检查清单
第一部分:将签名器添加到 solana-keychain Crate
- 按照 solana-keychain 集成指南 实现您的签名器
- 等待 PR 审批和 crate 发布
第二部分:添加 Kora 配置支持
- 更新 Cargo.toml 的依赖项,使
solana-keychaincrate 使用最新版本(包含您的签名器) - 为您的签名器的环境变量添加配置结构体
- 更新
crates/lib/src/signer/config.rs中的SignerTypeConfig枚举 - 为您的签名器配置添加验证逻辑
- 添加构建逻辑以从配置构造您的签名器
- 在
crates/lib/src/signer/mod.rs中导出配置结构体 - (可选)在
crates/lib/src/tests/config_mock.rs中添加测试模拟构建器 - 更新示例配置文件
- 更新测试脚本以包含您的签名器(见下文)
- 更新文档以包含您的签名器(见下文)
- 向 Kora 仓库提交 PR
在 Kora 中添加签名器支持
首先,确保您的签名器在 solana-keychain
crate 中得到支持。如果不支持,请按照以下指南操作:
https://github.com/solana-foundation/solana-keychain/blob/main/docs/ADDING_SIGNERS.md
步骤 1:更新 Cargo.toml
更新 Cargo.toml 的依赖项,使 solana-keychain
crate 使用最新版本(包含您的签名器):
[dependencies]solana-keychain = { version = "X.Y.Z", default-features = false, features = ["all","sdk-v3",] }
步骤 2:定义您的配置结构体
在 crates/lib/src/signer/config.rs
中,为您的签名器添加一个新的配置结构体,定义需要哪些环境变量。例如:
/// YourService signer configuration#[derive(Clone, Serialize, Deserialize)]pub struct YourServiceSignerConfig {pub api_key_env: String,pub api_secret_env: String,pub wallet_id_env: String,}
步骤 2:将您的签名器添加到 SignerTypeConfig 枚举
在 crates/lib/src/signer/config.rs 中将您的签名器变体添加到 SignerTypeConfig
枚举:
/// Signer type-specific configuration#[derive(Clone, Serialize, Deserialize)]#[serde(tag = "type", rename_all = "snake_case")]pub enum SignerTypeConfig {// Existing signer variantsMemory { #[serde(flatten)] config: MemorySignerConfig },// ... existing variants ...// Add your signer hereYourService {#[serde(flatten)]config: YourServiceSignerConfig,},}
步骤 3:添加构建逻辑
在同一文件(config.rs)中,在 SignerConfig
实现中添加一个方法,从配置构建您的签名器:
impl SignerConfig {pub async fn build_signer_from_config(config: &SignerConfig) -> Result<Signer, KoraError> {match &config.config {// ... existing casesSignerTypeConfig::YourService { config: your_service_config } => {Self::build_your_service_signer(your_service_config, &config.name).await}}}// Add this new methodasync fn build_your_service_signer(config: &YourServiceSignerConfig,signer_name: &str,) -> Result<Signer, KoraError> {// Update the environment variable names to match your signer's configurationlet api_key = get_env_var_for_signer(&config.api_key_env, signer_name)?;let api_secret = get_env_var_for_signer(&config.api_secret_env, signer_name)?;let wallet_id = get_env_var_for_signer(&config.wallet_id_env, signer_name)?;// Call the constructor from solana-keychain crateSigner::from_your_service(api_key, api_secret, wallet_id).await.map_err(|e| {KoraError::SigningError(format!("Failed to create YourService signer '{signer_name}': {}",sanitize_error!(e)))})}}
注意:方法名 Signer::from_your_service() 应与您在 solana-keychain
crate 中实现的方法名一致。
步骤 4:添加验证逻辑
在 validate_individual_signer_config 方法中为您的签名器配置添加验证:
impl SignerConfig {pub fn validate_individual_signer_config(&self, index: usize) -> Result<(), KoraError> {// ... existing validationmatch &self.config {// ... existing casesSignerTypeConfig::YourService { config } => {Self::validate_your_service_config(config, &self.name)}}}// Add this new validation methodfn validate_your_service_config(config: &YourServiceSignerConfig,signer_name: &str,) -> Result<(), KoraError> {// Update the environment variable names to match your signer's configurationlet env_vars = [("api_key_env", &config.api_key_env),("api_secret_env", &config.api_secret_env),("wallet_id_env", &config.wallet_id_env),];for (field_name, env_var) in env_vars {if env_var.is_empty() {return Err(KoraError::ValidationError(format!("YourService signer '{signer_name}' must specify non-empty {field_name}")));}}Ok(())}}
步骤 5:导出您的配置
在 crates/lib/src/signer/mod.rs
中将您的新配置结构体添加到模块导出(如果是公开的,则在文件顶部):
pub use config::{MemorySignerConfig,PrivySignerConfig,SignerTypeConfig,TurnkeySignerConfig,VaultSignerConfig,YourServiceSignerConfig, // Add this// ... other exports};
测试您的集成
添加测试模拟构建器
为了使测试更容易,在 crates/lib/src/tests/config_mock.rs 中为
SignerPoolConfigBuilder 添加一个构建器方法:
impl SignerPoolConfigBuilder {// ... existing methodspub fn with_your_service_signer(mut self,name: String,api_key_env: String,api_secret_env: String,wallet_id_env: String,weight: Option<u32>,) -> Self {let signer = SignerConfig {name,weight,config: SignerTypeConfig::YourService {config: YourServiceSignerConfig {api_key_env,api_secret_env,wallet_id_env,},},};self.config.signers.push(signer);self}}
这使得其他测试可以轻松创建包含您的签名器的模拟配置:
use crate::tests::config_mock::SignerPoolConfigBuilder;let config = SignerPoolConfigBuilder::new().with_your_service_signer("yourservice_test".to_string(),"YOUR_SERVICE_API_KEY".to_string(),"YOUR_SERVICE_API_SECRET".to_string(),"YOUR_SERVICE_WALLET_ID".to_string(),Some(1)).build();
环境变量
将示例环境变量添加到以下文件中:
.env.example(项目根目录).env(项目根目录,用于本地测试)./sdks/ts/.env.example./sdks/ts/.env
# YourService Signer ConfigurationYOUR_SERVICE_API_KEY=your_api_key_hereYOUR_SERVICE_API_SECRET=your_api_secret_hereYOUR_SERVICE_WALLET_ID=your_wallet_id_here
集成测试
每个集成阶段都是 tests/Cargo.toml 中独立的 [[test]] 目标。每个目标都会通过 harness_context 启动一个嵌入式 surfnet 和一个 Kora 节点,并从零开始初始化数据。Kora 将配置保存在进程全局状态中,因此新增签名器需要新建一个目标,而不是在现有目标中新增模块。
1. 添加签名器固件
在 tests/src/common/fixtures/ 中创建签名器配置:
# tests/src/common/fixtures/signers-your-service.toml[signer_pool]strategy = "round_robin"[[signers]]name = "yourservice_main"type = "your_service"api_key_env = "YOUR_SERVICE_API_KEY"api_secret_env = "YOUR_SERVICE_API_SECRET"wallet_id_env = "YOUR_SERVICE_WALLET_ID"
2. 添加测试目标
在 tests/Cargo.toml 中注册该阶段:
[[test]]name = "your_service"path = "your_service/main.rs"
然后创建 tests/your_service/main.rs。它会将测试框架指向您的固件,并且必须至少包含一个用于测试签名器的 #[tokio::test]:
#[path = "../src/common/mod.rs"]mod common;use common::*;use jsonrpsee::rpc_params;pub async fn ctx() -> TestContext {harness_context(KoraSpec {config: "tests/src/common/fixtures/kora-test.toml",signers: "tests/src/common/fixtures/signers-your-service.toml",initialize_payments_atas: false,}).await}#[tokio::test]async fn test_your_service_signs_as_fee_payer() {let ctx = ctx().await;let response: serde_json::Value = ctx.rpc_call("getPayerSigner", rpc_params![]).await.expect("Failed to get payer signer");response.assert_success();assert!(response["signer_address"].as_str().is_some());}
同时添加一个 signTransaction 测试,以便运行签名器的签名路径,而不仅仅是密钥查找。tests/multi_signer/ 是一个可供参考复制的完整示例。
3. 运行测试
just installexport YOUR_SERVICE_API_KEY="your_key"export YOUR_SERVICE_API_SECRET="your_secret"export YOUR_SERVICE_WALLET_ID="your_wallet"# Run only your phasecargo test -p tests --test your_service# Run every integration phasejust integration-test
文档要求
提交 PR 时,请包含:
1. 更新签名器指南
按照
ADDING_SIGNERS.md
指南添加签名器文档,说明前置条件、设置和使用方法。
## YourService Signer[YourService](https://yourservice.com) provides [brief description of yourservice].### Prerequisites- YourService account- API credentials- Funded wallet### Setup1. Get your API credentials from [dashboard link]2. Create a wallet...3. Configure environment variables:\```bash YOUR_SERVICE_API_KEY="your_api_key"YOUR_SERVICE_API_SECRET="your_api_secret"YOUR_SERVICE_WALLET_ID="your_wallet_id" \```### Configure signers.toml\```toml [signer_pool] strategy = "round_robin"[[signers]] name = "yourservice_main" type = "your_service" api_key_env ="YOUR_SERVICE_API_KEY" api_secret_env = "YOUR_SERVICE_API_SECRET" wallet_id_env= "YOUR_SERVICE_WALLET_ID" weight = 1 \```### Run Kora with YourService Signer\```bash kora rpc start --signers-config signers.toml \```
2. 更新 README
将您的服务添加到主 README 的 signer 列表中。
提交检查清单
- 您的 signer 已在
solana-keychaincrate 中受到支持 - 已将
solana-keychain依赖项更新至 Cargo.toml 中的最新版本 - 已为您的 signer 添加配置结构体
- 已添加
SignerTypeConfig变体 - 已在
build_signer_from_config中添加构建逻辑 - 已在
validate_individual_signer_config中添加验证逻辑 - 已在
mod.rs中导出配置结构体 - (可选)已在
config_mock.rs中添加测试 mock 构建方法 - 代码编译无警告
- 所有测试通过(
just test) - 已按照以下文档添加说明文档
ADDING_SIGNERS.md - 已创建示例配置文件(
.toml和.env.example) - 无硬编码值或密钥
- 错误信息具有参考价值
- 遵循 Rust 命名规范(snake_case)
- 代码检查通过(
make lint) - 联系 Kora 团队提供 API 密钥以进行集成测试
获取帮助
- 关于 signer 实现:在
solana-keychain代码仓库中提交 issue - 关于 Kora 集成:在 Kora 代码仓库中提交 issue 进行设计讨论
- 加入我们的社区频道
- 查阅
crates/lib/src/signer/config.rs中现有的 signer 配置
PR 示例结构
适用于 Kora 代码仓库:
feat(signer): add YourService signer configuration support- Add YourServiceSignerConfig struct- Add YourService variant to SignerTypeConfig enum- Add build and validation logic for YourService- Add example configuration files- Add documentation to SIGNERS.md- Add integration tests
欢迎加入 Kora 生态系统!我们非常高兴能将您的密钥管理方案纳入平台之中。
Is this page helpful?