Store the verification key and Issuer public key. Called once after deploy.
issuer_pub_key — Ed25519 public key (32 bytes) of the trusted KYC issuer.
The Issuer signs Poseidon commitments during KYC (Option A architecture).
Hardcode the real key before mainnet deployment.
fn initialize(
env: soroban_sdk::Env,
vk: StoredVk,
issuer_pub_key: soroban_sdk::BytesN<32>,
) -> Result<(), AgeVerifierError>
Verify a Groth16 proof and mint a soulbound credential to the caller.
pub_inputs — must have exactly 3 elements in this order:
[0] isOldEnough (Fr with value 1)
[1] commitment (Fr = Poseidon(birthDate, addressHash))
[2] addressHash (Fr derived from caller's Stellar address)
nullifier — unique 32-byte value preventing proof replay.
Recommended: random bytes generated client-side per submission.
issuer_sig — Ed25519 signature (64 bytes) from the trusted Issuer over
the raw bytes of commitment (pub_inputs[1]).
The Issuer produces this during KYC after verifying the user's document.
fn verify(
env: soroban_sdk::Env,
proof: Groth16Proof,
pub_inputs: soroban_sdk::Vec,
nullifier: soroban_sdk::BytesN<32>,
issuer_sig: soroban_sdk::BytesN<64>,
) -> Result
Check whether an address hash already has a verified credential.
fn has_credential(env: soroban_sdk::Env, address_hash: soroban_sdk::BytesN<32>) -> bool
Check whether a nullifier has been consumed.
fn is_nullifier_used(env: soroban_sdk::Env, nullifier: soroban_sdk::BytesN<32>) -> bool