Self lets users prove identity attributes (age, nationality, humanity) from passports/ID cards using zero-knowledge proofs — no personal data exposed. Users scan their document's NFC chip in the Self mobile app and share a zk proof with your app.
npm install @selfxyz/qrcode @selfxyz/core
"use client";
import { SelfQRcodeWrapper, SelfAppBuilder } from "@selfxyz/qrcode";
export default function VerifyIdentity({ userId }: { userId: string }) {
const selfApp = new SelfAppBuilder({
appName: "My App",
scope: "my-app-scope",
endpoint: "https://yourapp.com/api/verify",
endpointType: "https",
userId,
userIdType: "hex",
disclosures: {
minimumAge: 18,
},
}).build();
return (
<SelfQRcodeWrapper
selfApp={selfApp}
onSuccess={() => console.log("Verified")}
type="websocket"
darkMode={false}
/>
);
}
// app/api/verify/route.ts
import { SelfBackendVerifier, DefaultConfigStore } from "@selfxyz/core";
export async function POST(req: Request) {
const { proof, publicSignals } = await req.json();
const verifier = new SelfBackendVerifier(
"my-app-scope", // must match frontend scope
"https://yourapp.com/api/verify", // must match frontend endpoint
true, // true = accept mock passports (dev only)
null, // allowedIds (null = all)
new DefaultConfigStore({ // must match frontend disclosures
minimumAge: 18,
})
);
const result = await verifier.verify(proof, publicSignals);
return Response.json({
verified: result.isValid,
nationality: result.credentialSubject?.nationality,
});
}
| Pattern | When to Use | endpoint | endpointType |
|---|---|---|---|
| --------- | ------------ | ------------ | ---------------- |
| Off-chain (backend) | Web apps, APIs, most cases | Your API URL | "https" or "https-staging" |
| On-chain (contract) | DeFi, token gating, airdrops | Contract address (lowercase) | "celo" or "celo-staging" |
| Deep linking | Mobile-first flows | Your API URL | "https" |
SelfVerificationRoot. Use for trustless/permissionless scenarios.references/frontend.md.disclosures must EXACTLY match backend/contract verification config. Mismatched age thresholds, country lists, or OFAC settings cause silent failures.endpoint. Use .toLowerCase()."USA", "IRN", "PRK". Max 40 countries in exclusion lists.mockPassport: true in backend / use "celo-staging" endpoint type. Real passports require mainnet. To create a mock passport: open Self app, tap the Passport button 5 times. Mock testing requires OFAC disabled.@selfxyz/core >= 1.1.0-beta.1.1 = Passport, 2 = Biometric ID Card. Must explicitly allow via allowedIds map.ScopeMismatch = scope/address mismatch or non-lowercase address. Invalid 'to' Address = wrong endpointType (celo vs https). InvalidIdentityCommitmentRoot = real passport on testnet (use mainnet). Invalid Config ID = mock passport on mainnet (use testnet).| Network | Address |
|---|---|
| --------- | --------- |
| Mainnet Hub V2 | 0xe57F4773bd9c9d8b6Cd70431117d353298B9f5BF |
| Sepolia Hub V2 | 0x16ECBA51e18a4a7e61fdC417f0d47AFEeDfbed74 |
| Sepolia Staging Hub V2 | 0x68c931C9a534D37aa78094877F46fE46a49F1A51 |
Load these for deeper integration details:
references/frontend.md — SelfAppBuilder full config, SelfQRcodeWrapper props, deep linking with getUniversalLink, disclosure optionsreferences/backend.md — SelfBackendVerifier constructor details, DefaultConfigStore vs InMemoryConfigStore, verification result schema, dynamic configsreferences/contracts.md — SelfVerificationRoot inheritance pattern, Hub V2 interaction, setVerificationConfigV2, customVerificationHook, getConfigId, userDefinedData patterns共 1 个版本