Skip to content

Individual Verification (KYC)

Individual verification uses a Know Your Customer (KYC) flow to verify a person's identity and issue verifiable credentials to their embedded wallet. This is the default mode of the SDK.

Setup

Render the AvererWebSdk component with your eligibility queries. The mode prop defaults to "individual", so you can omit it.

'use client';

import {
  AvererWebSdk,
  AvererSdkProvider,
  type SdkQuery,
  type SdkSuccessRes,
} from '@averer/averer-websdk';

export default function EligibilityPage() {
  const sdkQuery: SdkQuery = [
    {
      id: 5,
      circuitId: 'credentialAtomicQuerySigV2',
      subjectTitle: 'Pass AML & CTF Checks',
      query: {
        allowedIssuers: [
          'did:receptor:redbelly:testnet:31K3oHpCV428AkXUYTL89q6LCvHcSqHirdv7z6LHtu9',
        ],
        type: 'AMLCTFCredential',
        context:
          'https://raw.githubusercontent.com/redbellynetwork/receptor-schema/refs/heads/main/schemas/json-ld/AMLCTFCredential.jsonld',
        skipClaimRevocationCheck: true,
        credentialSubject: {
          amlCheckStatus: { $eq: 'passed' },
        },
      },
    },
  ];

  const handleSuccess = (data: SdkSuccessRes) => {
    if (data.eligibility.passed) {
      console.log('Verification successful', data);
    }
  };

  const handleError = (reason: string) => {
    console.error('Verification failed:', reason);
  };

  return (
    <AvererSdkProvider configId="your-config-id">
      <AvererWebSdk
        appName="My App"
        sdkQuery={sdkQuery}
        onSuccess={handleSuccess}
        onError={handleError}
      />
    </AvererSdkProvider>
  );
}

Available credentials for individuals

Credential Type Purpose
EssentialIdCredential Core identity fields (name, date of birth)
PassportCredential Passport-derived identity data
DriversLicenceCredential Driver's licence-derived identity data
NationalIdCredential National ID-derived identity data
ProofOfAddressCredential Address verification
AMLCTFCredential AML & CTF compliance check
AUSophisticatedWholesaleInvestorCredential Australian sophisticated/wholesale investor status
ComprehensiveIdCredential Extended identity fields
EnhancedIdCredential Enhanced identity fields

For schema URLs and query construction details, see Eligibility Criteria.

On-chain verification

On-chain verification submits zero-knowledge proofs to a verifier smart contract deployed on the Redbelly Network. The contract validates each proof cryptographically and records the result on-chain, giving you a trustless, auditable verification record.

1. Deploy a verifier contract

Before using on-chain verification you need a verifier contract that implements the Privado ID (Iden3) on-chain verification interface. This contract exposes submitZKPResponse (V1) or submitZKPResponseV2 (V2) and stores proof results per (sender, requestId).

You can either:

  • Use the Iden3 Universal Verifier — deploy the reference UniversalVerifier contract to Redbelly, or
  • Extend ERC20Verifier — if your use case involves token gating, inherit from ERC20Verifier to combine ZKP verification with ERC-20 logic.

Follow the Privado on-chain verification tutorial for step-by-step deployment instructions.

2. Register ZKP requests on the contract

After deployment, register one or more ZKP requests on your verifier contract by calling setZKPRequest. Each request maps a requestId to a validator address and the query parameters the contract will verify against.

The requestId you register on-chain must match the id field in your sdkQuery entries. This is how the SDK correlates a proof with the correct on-chain verification rule.

For example, if your SDK query uses id: 3, the contract must have a request registered at requestId = 3.

3. Configure the SDK

Pass the deployed contract address and the submission method to the onChainMetaData prop:

const onChainMetaData = {
  contract_address: '0x1320e9a482116A59BD8751388cceEB7f75160BA5', // must match your deployed verifier contract address
  method_id: 'ade09fcd', // submitZKPResponseV2
};
Field Description
contract_address Must match your deployed verifier contract address on Redbelly Network.
method_id Function selector for the submission method. Use 'ade09fcd' for V2 (recommended) or 'b68967e2' for V1.

V2 vs V1:

Method Selector Behaviour
submitZKPResponseV2 ade09fcd Batches all proofs into a single transaction (recommended).
submitZKPResponse b68967e2 Sends one transaction per proof — higher gas cost.

4. Use on-chain circuits in your queries

Switch the circuitId to an on-chain variant. The SDK detects the OnChain suffix and routes proofs through the contract submission flow.

'use client';

import {
  AvererWebSdk,
  AvererSdkProvider,
  type SdkQuery,
  type SdkSuccessRes,
} from '@averer/averer-websdk';

const WEB3_QUERIES: SdkQuery = [
  {
    id: 3, // must match requestId registered on the verifier contract
    circuitId: 'credentialAtomicQuerySigV2OnChain',
    subjectTitle: '18+ Years Old',
    query: {
      allowedIssuers: ['*'],
      type: 'EssentialIdCredential',
      context:
        'https://raw.githubusercontent.com/redbellynetwork/receptor-schema/refs/heads/main/schemas/json-ld/EssentialIdCredential.jsonld',
      credentialSubject: { birthDate: { $lt: 20070622 } },
    },
  },
];

const onChainMetaData = {
  contract_address: '0x1320e9a482116A59BD8751388cceEB7f75160BA5', // must match your deployed verifier contract address
  method_id: 'ade09fcd', // submitZKPResponseV2
};

export default function OnChainEligibilityPage() {
  const handleSuccess = (data: SdkSuccessRes) => {
    if (data.eligibility.passed) {
      console.log('On-chain proof submitted & verified', data);
      console.log('Tx hash:', data.onChain?.txHash);
    }
  };

  const handleError = (reason: string) => {
    console.error('On-chain verification failed:', reason);
  };

  return (
    <AvererSdkProvider configId="your-config-id">
      <AvererWebSdk
        appName="My App"
        sdkQuery={WEB3_QUERIES}
        onChainMetaData={onChainMetaData}
        onSuccess={handleSuccess}
        onError={handleError}
      />
    </AvererSdkProvider>
  );
}

5. Reading on-chain results

After successful submission the onSuccess callback includes on-chain transaction data:

const handleSuccess = (data: SdkSuccessRes) => {
  if (data.onChain?.txHash) {
    console.log('Transaction hash:', data.onChain.txHash);
    console.log('Contract:', data.onChain.contract_address);
  }
};

You can also verify proof status directly on the contract at any time by calling getProofStatus or isProofVerified:

// Returns whether `sender` has a verified proof for `requestId`
function isProofVerified(address sender, uint64 requestId) view returns (bool);

// Returns full status: isVerified, validatorVersion, blockNumber, blockTimestamp
function getProofStatus(address sender, uint64 requestId) view returns (ProofStatus);

On-chain verification checklist

  1. Deploy a verifier contract (Universal Verifier or ERC20Verifier) to Redbelly Network.
  2. Call setZKPRequest on the contract for each verification criterion, using the same requestId values you will use as query id in the SDK.
  3. Set circuitId to an OnChain variant (e.g. credentialAtomicQuerySigV2OnChain) in each query.
  4. Pass onChainMetaData with your contract_address and method_id to the AvererWebSdk component.
  5. Handle data.onChain.txHash in your onSuccess callback to confirm the transaction.

For more on choosing between off-chain and on-chain approaches, see Proof Methods.