Nieuwe Signers Toevoegen aan Kora

Architectuuroverzicht

Kora gebruikt de externe solana-keychain crate voor alle ondertekeningsbewerkingen. Deze architectuur biedt een uniforme ondertekeningsinterface voor het ondertekenen van Solana-transacties. Om een nieuwe signer aan Kora toe te voegen, moet u:

  1. Ten eerste: Uw signer-implementatie toevoegen aan de solana-keychain crate
  2. Ten tweede: Configuratieondersteuning voor uw signer toevoegen in Kora

Stapsgewijze Integratiehandleiding

Snelle Integratie Checklist

Deel 1: Signer Toevoegen aan solana-keychain Crate

Deel 2: Kora Configuratieondersteuning Toevoegen

  • Werk de dependency in Cargo.toml bij zodat de solana-keychain crate de nieuwste versie gebruikt (die uw signer bevat)
  • Voeg een configuratiestruct toe voor de omgevingsvariabelen van uw signer
  • Werk de SignerTypeConfig enum bij in crates/lib/src/signer/config.rs
  • Voeg validatielogica toe voor de configuratie van uw signer
  • Voeg bouwlogica toe om uw signer vanuit de configuratie te construeren
  • Exporteer de configuratiestruct in crates/lib/src/signer/mod.rs
  • (Optioneel) Voeg een test mock builder toe in crates/lib/src/tests/config_mock.rs
  • Werk voorbeeldconfiguratiebestanden bij
  • Werk testscripts bij om uw signer op te nemen (zie hieronder)
  • Werk documentatie bij om uw signer op te nemen (zie hieronder)
  • Dien een PR in bij de Kora repository

Voeg Signer-ondersteuning toe in Kora

Zorg er eerst voor dat je signer wordt ondersteund in de solana-keychain crate. Als dat niet het geval is, volg dan de handleiding op: https://github.com/solana-foundation/solana-keychain/blob/main/docs/ADDING_SIGNERS.md

Stap 1: Update Cargo.toml

Werk de dependency in Cargo.toml bij zodat de solana-keychain crate de nieuwste versie gebruikt (die je signer bevat):

[dependencies]
solana-keychain = { version = "X.Y.Z", default-features = false, features = [
"all",
"sdk-v3",
] }

Stap 2: Definieer je configuratiestruct

Voeg in crates/lib/src/signer/config.rs een nieuwe configuratiestruct toe voor je signer die definieert welke omgevingsvariabelen nodig zijn. Bijvoorbeeld:

/// 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,
}

Stap 2: Voeg je signer toe aan de SignerTypeConfig Enum

Voeg je signer-variant toe aan de SignerTypeConfig enum in crates/lib/src/signer/config.rs:

/// Signer type-specific configuration
#[derive(Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SignerTypeConfig {
// Existing signer variants
Memory { #[serde(flatten)] config: MemorySignerConfig },
// ... existing variants ...
// Add your signer here
YourService {
#[serde(flatten)]
config: YourServiceSignerConfig,
},
}

Stap 3: Voeg bouwlogica toe

Voeg in hetzelfde bestand (config.rs) een methode toe om je signer te bouwen vanuit de configuratie in de SignerConfig implementatie:

impl SignerConfig {
pub async fn build_signer_from_config(config: &SignerConfig) -> Result<Signer, KoraError> {
match &config.config {
// ... existing cases
SignerTypeConfig::YourService { config: your_service_config } => {
Self::build_your_service_signer(your_service_config, &config.name).await
}
}
}
// Add this new method
async fn build_your_service_signer(
config: &YourServiceSignerConfig,
signer_name: &str,
) -> Result<Signer, KoraError> {
// Update the environment variable names to match your signer's configuration
let 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 crate
Signer::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)
))
})
}
}

Let op: De methodenaam Signer::from_your_service() moet overeenkomen met wat je hebt geïmplementeerd in de solana-keychain crate.

Stap 4: Voeg validatielogica toe

Voeg validatie toe voor de configuratie van je signer in de validate_individual_signer_config methode:

impl SignerConfig {
pub fn validate_individual_signer_config(&self, index: usize) -> Result<(), KoraError> {
// ... existing validation
match &self.config {
// ... existing cases
SignerTypeConfig::YourService { config } => {
Self::validate_your_service_config(config, &self.name)
}
}
}
// Add this new validation method
fn validate_your_service_config(
config: &YourServiceSignerConfig,
signer_name: &str,
) -> Result<(), KoraError> {
// Update the environment variable names to match your signer's configuration
let 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(())
}
}

Stap 5: Exporteer je configuratie

Voeg je nieuwe configuratiestruct toe aan de module-exports in crates/lib/src/signer/mod.rs (of bovenaan het bestand als het publiek is):

pub use config::{
MemorySignerConfig,
PrivySignerConfig,
SignerTypeConfig,
TurnkeySignerConfig,
VaultSignerConfig,
YourServiceSignerConfig, // Add this
// ... other exports
};

Testen van je integratie

Voeg testmock-builder toe

Om het testen gemakkelijker te maken, voeg je een builder-methode toe aan SignerPoolConfigBuilder in crates/lib/src/tests/config_mock.rs:

impl SignerPoolConfigBuilder {
// ... existing methods
pub 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
}
}

Hierdoor kunnen andere tests eenvoudig mock-configuraties aanmaken die je signer bevatten:

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();

Omgevingsvariabelen

Voeg de voorbeeldomgevingsvariabelen toe aan de volgende bestanden:

  • .env.example (root van het project)
  • .env (root van het project, voor lokaal testen)
  • ./sdks/ts/.env.example
  • ./sdks/ts/.env
# YourService Signer Configuration
YOUR_SERVICE_API_KEY=your_api_key_here
YOUR_SERVICE_API_SECRET=your_api_secret_here
YOUR_SERVICE_WALLET_ID=your_wallet_id_here

Integratietests

Elke integratiefase is een eigen [[test]]-target in tests/Cargo.toml. Elke target start via harness_context een ingebedde surfnet plus een Kora-node op, volledig vanaf nul opgezet. Kora bewaart de configuratie in een procesbrede globale status, dus voor een nieuwe signer is een nieuwe target nodig in plaats van een nieuwe module in een bestaande.

1. Een Signer-fixture Toevoegen

Maak een signerconfiguratie aan in 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. Een Testtarget Toevoegen

Registreer de fase in tests/Cargo.toml:

[[test]]
name = "your_service"
path = "your_service/main.rs"

Maak daarna tests/your_service/main.rs aan. Dit bestand laat de harness naar je fixture verwijzen en moet minstens één #[tokio::test] bevatten die de signer 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());
}

Voeg ook een signTransaction-test toe, zodat het ondertekeningspad van de signer wordt doorlopen en niet alleen de sleutelopzoeking. tests/multi_signer/ is een compleet voorbeeld om van te kopiëren.

3. Tests Uitvoeren

just install
export YOUR_SERVICE_API_KEY="your_key"
export YOUR_SERVICE_API_SECRET="your_secret"
export YOUR_SERVICE_WALLET_ID="your_wallet"
# Run only your phase
cargo test -p tests --test your_service
# Run every integration phase
just integration-test

Documentatievereisten

Voeg bij het indienen van je PR het volgende toe:

1. Werk de Signers-gids Bij

Voeg signerdocumentatie toe volgens de ADDING_SIGNERS.md gids, waarin de vereisten, installatie en gebruik worden uitgelegd.

## YourService Signer
[YourService](https://yourservice.com) provides [brief description of your
service].
### Prerequisites
- YourService account
- API credentials
- Funded wallet
### Setup
1. 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 bijwerken

Voeg je service toe aan de validator-lijst in de hoofd-README.

Indieningschecklist

  • Je signer wordt ondersteund in de solana-keychain crate
  • solana-keychain afhankelijkheid bijgewerkt in Cargo.toml naar de nieuwste versie
  • Configuratiestruct toegevoegd voor je signer
  • SignerTypeConfig variant toegevoegd
  • Bouwlogica toegevoegd in build_signer_from_config
  • Validatielogica toegevoegd in validate_individual_signer_config
  • Configuratiestruct geëxporteerd in mod.rs
  • (Optioneel) Testmock-bouwmethode toegevoegd in config_mock.rs
  • Code compileert zonder waarschuwingen
  • Alle tests slagen (just test)
  • Documentatie toegevoegd conform ADDING_SIGNERS.md
  • Voorbeeldconfiguratiebestanden aangemaakt (.toml en .env.example)
  • Geen hardgecodeerde waarden of geheimen
  • Foutmeldingen zijn informatief
  • Volgt Rust-naamgevingsconventies (snake_case)
  • Linting slaagt (make lint)
  • Neem contact op met het Kora-team met API-sleutels voor integratietesten

Hulp krijgen

  • Voor signer-implementatie: Open een issue in de solana-keychain repository
  • Voor Kora-integratie: Open een issue in de Kora-repository voor ontwerpbesprekingen
  • Sluit je aan bij onze communitykanalen
  • Bekijk bestaande signer-configuraties in crates/lib/src/signer/config.rs

Voorbeeld PR-structuur

Voor de Kora-repository:

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

Welkom in het Kora-ecosysteem! We zijn blij dat je sleutelbeheeroplossing deel uitmaakt van het platform.

Is this page helpful?

© 2026 Solana Foundation. Alle rechten voorbehouden.