From 70a77cd95f5be0e42875eab2f32c616d5cf721d6 Mon Sep 17 00:00:00 2001 From: EDOHWARES Date: Mon, 30 Mar 2026 12:18:46 +0100 Subject: [PATCH] feat: implement kyc verifier contract --- Cargo.toml | 18 +++++++++------ src/kyc/Cargo.toml | 16 +++++++++++++ src/kyc/lib.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/kyc/Cargo.toml create mode 100644 src/kyc/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 60fc35a..2a3902c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,17 @@ [workspace] -members = ["src/upgradeable", "src/token", "src/escrow_multisig", "src/governance", "src/auth", "src/amm", "src/oracle_consumer", "src/batch", "src/utils"] members = [ - "src/upgradeable", - "src/token", - "src/escrow_multisig", - "src/governance", - "src/flash_loan" + "src/upgradeable", + "src/token", + "src/escrow_multisig", + "src/governance", + "src/auth", + "src/amm", + "src/oracle_consumer", + "src/batch", + "src/utils", + "src/flash_loan", + "src/kyc" ] -members = ["src/upgradeable", "src/token", "src/escrow_multisig", "src/governance", "src/auth", "src/amm", "src/oracle_consumer", "src/batch"] resolver = "2" [package] diff --git a/src/kyc/Cargo.toml b/src/kyc/Cargo.toml new file mode 100644 index 0000000..c1709b7 --- /dev/null +++ b/src/kyc/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "kyc-verifier" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] +path = "lib.rs" +doctest = false + +[dependencies] +soroban-sdk = "22.0.0" + +[dev-dependencies] +soroban-sdk = { version = "22.0.0", features = ["testutils"] } diff --git a/src/kyc/lib.rs b/src/kyc/lib.rs new file mode 100644 index 0000000..c784496 --- /dev/null +++ b/src/kyc/lib.rs @@ -0,0 +1,57 @@ +#![no_std] +use soroban_sdk::{contract, contractimpl, contracttype, symbol_short, Address, Env, Bytes, BytesN}; + +#[contracttype] +pub enum DataKey { + Admin, + VerifierPubKey, + UserKyc(Address), // ExpiresAt (u64) +} + +#[contract] +pub struct KycVerifier; + +#[contractimpl] +impl KycVerifier { + pub fn initialize(env: Env, admin: Address, verifier_pubkey: BytesN<32>) { + if env.storage().instance().has(&DataKey::Admin) { + panic!("already initialized"); + } + admin.require_auth(); + env.storage().instance().set(&DataKey::Admin, &admin); + env.storage().instance().set(&DataKey::VerifierPubKey, &verifier_pubkey); + } + + pub fn set_kyc_status(env: Env, user: Address, signature: BytesN<64>, expires_at: u64) { + // KYC provider signs: user_addr + expires_at + let current_time = env.ledger().timestamp(); + assert!(expires_at > current_time, "proof expired"); + + let mut data = Bytes::new(&env); + data.append(&user.to_xdr(&env)); + data.append(&(expires_at as u128).to_be_bytes().as_slice().into()); // Example message data + + // In real cases, we'd hash the data or use a specific format. + // For simplicity, let's verify ed25519 signature. + let pubkey: BytesN<32> = env.storage().instance().get(&DataKey::VerifierPubKey).unwrap(); + + env.crypto().ed25519_verify(&pubkey, &data, &signature); + + env.storage().persistent().set(&DataKey::UserKyc(user.clone()), &expires_at); + env.events().publish((symbol_short!("kyc_set"), user), expires_at); + } + + pub fn is_kyc_valid(env: Env, user: Address) -> bool { + let current_time = env.ledger().timestamp(); + match env.storage().persistent().get::<_, u64>(&DataKey::UserKyc(user)) { + Some(expiry) => expiry > current_time, + None => false, + } + } + + pub fn update_verifier(env: Env, new_pubkey: BytesN<32>) { + let admin: Address = env.storage().instance().get(&DataKey::Admin).unwrap(); + admin.require_auth(); + env.storage().instance().set(&DataKey::VerifierPubKey, &new_pubkey); + } +}