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
ERC20Verifierto 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
- Deploy a verifier contract (Universal Verifier or ERC20Verifier) to Redbelly Network.
- Call
setZKPRequeston the contract for each verification criterion, using the samerequestIdvalues you will use as queryidin the SDK. - Set
circuitIdto anOnChainvariant (e.g.credentialAtomicQuerySigV2OnChain) in each query. - Pass
onChainMetaDatawith yourcontract_addressandmethod_idto theAvererWebSdkcomponent. - Handle
data.onChain.txHashin youronSuccesscallback to confirm the transaction.
For more on choosing between off-chain and on-chain approaches, see Proof Methods.