Bind a KYC nullifier to an identity group — the Sybil-resistance gate.
nullifier is an opaque 32-byte value derived off-chain from the verified
document (HMAC of doc# + issuing country under a server pepper) — never raw
PII. Attestor-gated like update_group_score. The invariant: a nullifier
maps to exactly one commitment, so one verified human (one stable
nullifier) can only ever KYC a single identity group, no matter how many
fresh secrets they generate. Re-binding the same commitment is idempotent;
binding it to a different commitment is rejected (NullifierAlreadyBound).
On success the group is marked KYC-verified (kyc_verified: true), which the
lending pool reads as the credit gate.
fn bind_kyc(
env: soroban_sdk::Env,
attestor: soroban_sdk::Address,
commitment: soroban_sdk::BytesN<32>,
nullifier: soroban_sdk::BytesN<32>,
) -> Result<(), soroban_sdk::Error>
Remove a wallet from its identity group.
fn leave_group(
env: soroban_sdk::Env,
wallet: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>
fn __constructor(env: soroban_sdk::Env, admin: soroban_sdk::Address)
Whether an identity group has completed KYC (a nullifier is bound).
fn is_kyc_verified(env: soroban_sdk::Env, commitment: soroban_sdk::BytesN<32>) -> bool
Register a wallet as a member of the identity group identified by commitment.
If an identity VK has been registered (set_identity_vk), proof_bytes
must be a valid Groth16 proof whose public input equals commitment —
i.e. the caller proves knowledge of the secret without revealing it.
If no VK is set, registration is optimistic (proof ignored).
fn register_wallet(
env: soroban_sdk::Env,
wallet: soroban_sdk::Address,
commitment: soroban_sdk::BytesN<32>,
proof_bytes: soroban_sdk::Bytes,
) -> Result<(), soroban_sdk::Error>
Register the Groth16 verification key for the Poseidon identity circuit.
Admin-only. Once set, register_wallet requires a valid proof that the
caller knows the secret behind the commitment being registered.
fn set_identity_vk(
env: soroban_sdk::Env,
vk_bytes: soroban_sdk::Bytes,
) -> Result<(), soroban_sdk::Error>
Update the aggregated group attestation for a commitment.
Attestor-gated (fixes the prior missing-auth bug): attestor must be a
registered attestor in the AttestorRegistry and must authorize the call,
so an arbitrary caller can no longer overwrite a group's shared score
(e.g. force VERY_LOW for free good terms, or grief a victim group).
fn update_group_score(
env: soroban_sdk::Env,
attestor: soroban_sdk::Address,
commitment: soroban_sdk::BytesN<32>,
attestation: AttestationData,
) -> Result<(), soroban_sdk::Error>
Return the aggregated attestation for an identity group, if any.
Overlays the group's KYC status: if the commitment has a bound nullifier
(bind_kyc), kyc_verified is forced true even when a later
update_group_score stored an attestation with it false — KYC, once
bound, is not silently dropped by a re-score.
fn get_group_attestation(
env: soroban_sdk::Env,
commitment: soroban_sdk::BytesN<32>,
) -> Option
Set the AttestorRegistry contract address. Admin-only. Once set,
update_group_score requires the caller to be a registered attestor.
fn set_attestor_registry(
env: soroban_sdk::Env,
contract_id: soroban_sdk::Address,
) -> Result<(), soroban_sdk::Error>