وثائق سولاناKoraالمساهمون

إضافة موقعين جدد إلى Kora

نظرة عامة على البنية

تستخدم Kora حزمة solana-keychain الخارجية لجميع عمليات التوقيع. توفر هذه البنية واجهة توقيع موحدة لتوقيع معاملات سولانا. لإضافة موقع جديد إلى Kora، ستحتاج إلى:

  1. أولاً: أضف تنفيذ الموقع الخاص بك إلى حزمة solana-keychain
  2. ثانياً: أضف دعم التكوين للموقع الخاص بك في Kora

دليل التكامل خطوة بخطوة

قائمة التحقق السريعة للتكامل

الجزء الأول: إضافة الموقع إلى حزمة solana-keychain

الجزء الثاني: إضافة دعم تكوين Kora

  • حدّث تبعية Cargo.toml بحيث تستخدم حزمة solana-keychain أحدث إصدار (الذي يتضمن الموقع الخاص بك)
  • أضف بنية التكوين لمتغيرات البيئة الخاصة بالموقع الخاص بك
  • حدّث تعداد SignerTypeConfig في crates/lib/src/signer/config.rs
  • أضف منطق التحقق من صحة تكوين الموقع الخاص بك
  • أضف منطق البناء لإنشاء الموقع الخاص بك من التكوين
  • صدّر بنية التكوين في crates/lib/src/signer/mod.rs
  • (اختياري) أضف منشئ نموذج اختبار في crates/lib/src/tests/config_mock.rs
  • حدّث ملفات التكوين النموذجية
  • حدّث نصوص الاختبار لتشمل الموقع الخاص بك (انظر أدناه)
  • حدّث الوثائق لتشمل الموقع الخاص بك (انظر أدناه)
  • قدم طلب سحب إلى مستودع Kora

إضافة دعم الموقّع في Kora

أولاً، تأكد من أن الموقّع الخاص بك مدعوم في حزمة solana-keychain. إذا لم يكن مدعومًا، اتبع الدليل في: https://github.com/solana-foundation/solana-keychain/blob/main/docs/ADDING_SIGNERS.md

الخطوة 1: تحديث Cargo.toml

قم بتحديث تبعية Cargo.toml بحيث تستخدم حزمة solana-keychain الإصدار الأحدث (الذي يتضمن الموقّع الخاص بك):

[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

أضف متغير الموقّع الخاص بك إلى تعداد SignerTypeConfig في 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,
},
}

الخطوة 3: إضافة منطق البناء

في نفس الملف (config.rs)، أضف طريقة لبناء الموقّع الخاص بك من الإعدادات في تنفيذ SignerConfig:

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)
))
})
}
}

ملاحظة: يجب أن يتطابق اسم الطريقة Signer::from_your_service() مع ما قمت بتنفيذه في حزمة solana-keychain.

الخطوة 4: إضافة منطق التحقق

أضف التحقق من إعدادات الموقّع الخاص بك في طريقة validate_individual_signer_config:

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

الخطوة 5: تصدير الإعدادات الخاصة بك

أضف هيكل الإعدادات الجديد إلى صادرات الوحدة في crates/lib/src/signer/mod.rs (أو في أعلى الملف إذا كان عامًا):

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

اختبار التكامل الخاص بك

إضافة منشئ وهمي للاختبار

لتسهيل الاختبار، أضف طريقة منشئ إلى SignerPoolConfigBuilder في 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
}
}

يتيح ذلك للاختبارات الأخرى إنشاء إعدادات وهمية بسهولة تتضمن موقعك:

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

اختبارات التكامل

كل مرحلة تكامل هي هدف [[test]] مستقل في tests/Cargo.toml. يقوم كل هدف بتشغيل surfnet مضمّن وعقدة Kora عبر harness_context، ويبدأ من الصفر ببيانات مهيّأة حديثًا. تحتفظ 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. يوجّه هذا الملف أداة الاختبار (harness) إلى التهيئة التجريبية الخاصة بك، ويجب أن يحتوي على اختبار واحد على الأقل بالوسم #[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 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

متطلبات التوثيق

عند إرسال طلب السحب الخاص بك، قم بتضمين:

1. تحديث دليل الموقعين

أضف توثيق الموقع باتباع دليل ADDING_SIGNERS.md الذي يشرح المتطلبات الأساسية والإعداد والاستخدام.

## 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

أضف خدمتك إلى قائمة الموقّعين في ملف README الرئيسي.

قائمة مراجعة التقديم

  • يتم دعم الموقّع الخاص بك في الحزمة solana-keychain
  • تم تحديث اعتماد solana-keychain في Cargo.toml إلى أحدث إصدار
  • تمت إضافة بنية الإعداد الخاصة بالموقّع
  • تمت إضافة متغير SignerTypeConfig
  • تمت إضافة منطق البناء في build_signer_from_config
  • تمت إضافة منطق التحقق في validate_individual_signer_config
  • تم تصدير بنية الإعداد في mod.rs
  • (اختياري) تمت إضافة طريقة بناء النموذج الاختباري في config_mock.rs
  • يتم تجميع الكود دون تحذيرات
  • جميع الاختبارات ناجحة (just test)
  • تمت إضافة التوثيق وفقاً لـ ADDING_SIGNERS.md
  • تم إنشاء ملفات الإعداد النموذجية (.toml و .env.example)
  • لا توجد قيم مضمّنة أو أسرار مشفّرة
  • رسائل الخطأ مفيدة وواضحة
  • يتبع اصطلاحات تسمية Rust (snake_case)
  • يجتاز فحص الكود (make lint)
  • تواصل مع فريق Kora للحصول على مفاتيح API لاختبار التكامل

الحصول على المساعدة

  • لتنفيذ الموقّع: افتح تذكرة في مستودع solana-keychain
  • لتكامل Kora: افتح تذكرة في مستودع Kora لمناقشات التصميم
  • انضم إلى قنوات مجتمعنا
  • راجع إعدادات الموقّعين الموجودة في crates/lib/src/signer/config.rs

مثال على هيكل طلب السحب (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?