Developer Integration Guide

Datum structure (Compliance UTXO)

{
  "merkle_root": "0xabc123...",
  "sanctions_epoch": 452,
  "midnight_ref": "0xdeadbeef#0",
  "fairway_sig": "sig(fairway_key, hash(root || epoch || midnight_ref))"
}

Leaf structure (Merkle tree)

{
  "address": "addr1...",
  "claims": ["KYC2", "EU_RESIDENT"],
  "kyc_verified_at": "2025-03-15T10:00:00Z"
}

Aiken Policy Engine (simplified)

validator eligibility {
  fn check(ctx: ScriptContext, proof: MerkleProof, leaf: Leaf, max_age: Int) -> Bool {
    let utxo = get_ref_input(ctx, FAIRWAY_UTXO_REF)

    // 1. Verify Merkle proof
    let ok_proof = verify_merkle(proof, utxo.datum.merkle_root, leaf)

    // 2. Verify Fairway signature
    let payload = hash(utxo.datum.merkle_root || utxo.datum.sanctions_epoch || utxo.datum.midnight_ref)
    let ok_sig = verify_signature(FAIRWAY_PUBKEY, payload, utxo.datum.fairway_sig)

    // 3. Check sanctions epoch freshness
    let ok_epoch = utxo.datum.sanctions_epoch == current_sanctions_epoch()

    // 4. Check KYC timestamp freshness
    let age = ctx.tx.now - leaf.kyc_verified_at
    let ok_kyc = age <= max_age

    ok_proof && ok_sig && ok_epoch && ok_kyc
  }
}

Protocol-defined max_age → institutions decide (3mo/6mo/12mo).

Fairway just records kyc_verified_at → not prescriptive.

Last updated

Was this helpful?