Skip to main content

The three layers

Identity

A human verifies once (Smile ID hosted flow). Contra issues an Albus credential, signed by a BabyJubJub issuer key. PII never leaves Contra.

Compliance Engine

Workflows + sessions orchestrate the verification recipe (KYC, AML, biometric, phone, address). Outcome → a signed ContraToken.

On-chain Credential

The credential becomes a Groth16 proof, verified on-chain by KycVerifier.sol. The agent is minted on canonical ERC-8004 IdentityRegistry (0x8004A169…). Any contract can read its tier permissionlessly.

The data path

What goes on-chain (and what doesn’t)

On-chainOff-chain
Agent ID + ZK commitmentRaw name / DOB / document number
Issuer key (Ax, Ay) — allowlistedSmile job ID + raw images
Tier (1 / 2 / 3) + validUntilThe Albus credential (encrypted, KV)
keccak256(issuer pubkey)The session’s expected_details
The chain learns “verified, tier X, trusted issuer, until Y” — never PII.

Composability

Contra reads + writes are intentionally permissionless:
  • Any smart contract calls SSIAgentV2.getEffectiveKycTier(agentId) for free.
  • Off-chain backends call GET /v1/compliance/:address (free, on-chain read mirror).
  • Paid endpoints (verification, on-chain mint) are gated by either x-api-key (developers) or x402 (agents — pay-per-call USDC).