Self Integration

Why Identity Verification Matters

Open-source collaboration platforms face several challenges without identity verification:

  • Fake accounts / Sybil attacks: Multiple fake accounts can distort rewards or spam the system.

  • Unverified human contribution: Without zk-based identity verification, it's impossible to ensure contributions are made by real participants.

  • Economic misuse: Only verified contributors should be allowed to stake and claim rewards to maintain fairness.

By integrating Self, Creo ensures that every participant is human, unique, and verifiable.

How Self is Used in Creo

1. Wallet-Linked User Verification

  • Contributors connect their wallet via RainbowKit / Wagmi.

  • The wallet address acts as the userId for Self verification.

  • When a contributor completes the verification flow, Self generates a nullifier that uniquely maps to their wallet.

// Frontend snippet
const userId = address // Wallet address used as userId
const selfApp = new SelfAppBuilder({
  appName: "Creo",
  userId,
  endpoint: "/api/verify",
  userIdType: "hex",
}).build()

2. Backend Verification

  • Creo runs a backend endpoint using SelfBackendVerifier.

  • The backend validates zk proofs submitted by users, generating a nullifier and userIdentifier.

  • These are published in real-time to Creo’s frontend via Server-Sent Events (SSE).

const result = await selfBackendVerifier.verify(
  attestationId,
  proof,
  publicSignals,
  userContextData
)
const nullifier = result.discloseOutput?.nullifier
const userIdentifier = result.userData?.userIdentifier

3. Nullifier Mapping on Smart Contracts

  • Each verified user’s nullifier is stored in the DecentralizedIssueTracker contract:

mapping(address => uint256) public addressToNullifier;
mapping(uint256 => address) public nullifierToAddress;
  • Rules enforced via smart contracts:

    • Only verified addresses (addressToNullifier != 0) can create issues, take issues, or claim rewards.

    • Each nullifier is unique, preventing duplicate accounts or Sybil attacks.

    • The system maintains a one-attempt-per-issue rule using nullifiers.

4. Frontend Integration

  • The Self QR code is displayed to users for verification.

  • Upon successful verification, the nullifier and userIdentifier are fetched in real-time and displayed:

<SelfQRcodeWrapper
  selfApp={selfApp}
  onSuccess={() => console.log("Verified!")}
  onError={() => console.error("Verification failed")}
/>
  • This ensures that staking, deadline assignments, and AI-assisted grading only occur for verified humans.

Benefits for Creo

  1. Sybil & DoS Resistance: Staking is restricted to verified users, preventing fake accounts or mass spam registrations.

  2. Verified Contributions: zk-proof identity verification ensures that all contributions come from legitimate humans.

  3. Fair Incentives: Only verified users can stake and claim rewards, ensuring predictable and fair economic flows.

  4. Integration with AI Agents: Verified identities allow AI agents to trust that contributions come from real participants, enabling accurate grading and reputation tracking.

Technical Stack for Self Integration

  • Frontend: React / Next.js + RainbowKit + Self QR code wrapper

  • Backend: Next.js API routes using SelfBackendVerifier

  • Blockchain: Celo Mainnet smart contracts storing nullifiers and enforcing rules

  • Real-time updates: SSE endpoint (/api/verify/stream) to propagate verification state

  • Security: One-attempt-per-issue enforcement, unique nullifiers, zk-based verification

Workflow Summary

  1. User connects wallet → generates userId.

  2. User scans Self QR code → completes zk verification.

  3. Backend verifies zk proof → returns nullifier & userIdentifier.

  4. Nullifier mapped to wallet in smart contract → user allowed to stake, claim, and contribute.

  5. Frontend displays verification state in real-time → gates Creo actions.

Last updated