Spec
Technical specification for building verifiers that integrate with NEUS Network.
Verifier IDs
Use kebab‑case:
[a-z0-9-]{1,48}
(e.g.,ownership-basic
,nft-ownership
)ID maps on‑chain as:
bytes32 verifierId = keccak256(bytes(verificationType))
Use exact same string across SDK/API/docs
Request Structure
{
"verifierIds": ["ownership-basic"],
"data": { /* verifier-specific input */ },
"walletAddress": "0x...",
"signature": "0x...",
"signedTimestamp": 1730000000000,
"chainId": 84532,
"options": {
"privacyLevel": "private|public",
"targetChains": [11155111, 80002], // TESTNET chains only
"enableIpfs": false,
"publicDisplay": false,
"storeOriginalContent": false
}
}
Response Structure
{
"success": true,
"status": "verified",
"data": {
"qHash": "0x...",
"verifierIds": ["ownership-basic"],
"verifiedVerifiers": [
{
"verifierId": "ownership-basic",
"verified": true,
"data": { /* verifier-specific result */ },
"status": "verified",
"zkInfo": { "zkStatus": "zk_not_required" }
}
]
}
}
Verifier Schemas (current)
ownership-basic
Input:
{
"content": "string (required)",
"owner": "address (required)",
"reference": {
"type": "string (required) - url|ipfs|tx|other",
"id": "string (required)"
}
}
Output:
{
"owner": "0x...",
"reference": {"type": "content", "id": "..."},
"verifierContentHash": "0x...",
"timestamp": 1730000000000
}
nft-ownership
Input:
{
"ownerAddress": "address (required)",
"contractAddress": "address (required)",
"tokenId": "string (required)",
"chainId": "number (required) - 1|137|42161|10|8453",
"tokenType": "string (optional) - erc721|erc1155"
}
Output:
{
"input": {
"ownerAddress": "0x...",
"contractAddress": "0x...",
"tokenId": "1234",
"chainId": 1,
"tokenType": "erc721"
},
"onChainData": {
"actualOwner": "0x..." // ERC721
},
"verificationTimestamp": 1730000000000
}
token-holding
Input:
{
"ownerAddress": "address (required)",
"contractAddress": "address (required)",
"minBalance": "string (required) - human-readable format",
"chainId": "number (required) - 1|137|42161|10|8453"
}
ownership-licensed
Input:
{
"content": "string (required)",
"owner": "address (required)",
"license": {
"contractAddress": "address (required)",
"tokenId": "string (required)",
"chainId": "number (required) - 1|137|42161|10|8453",
"ownerAddress": "address (required)",
"type": "string (optional) - erc721|erc1155"
},
"reference": {
"type": "string (optional) - url|ipfs|tx|other",
"id": "string (optional)"
}
}
Output:
{
"content": "Pro Tools License",
"license": {
"contractAddress": "0x...",
"tokenId": "1",
"chainId": 1,
"ownerAddress": "0x...",
"type": "erc721"
},
"onChainData": {
"actualOwner": "0x..."
},
"verificationTimestamp": 1730000000000
}
Output:
{
"input": {
"ownerAddress": "0x...",
"contractAddress": "0x...",
"minBalance": "100.0",
"chainId": 1
},
"onChainData": {
"requiredMinBalance": "100.0"
},
"verificationTimestamp": 1730000000000
}
Manual Signing
import { buildVerificationRequest } from '@neus/sdk';
const { message, request } = buildVerificationRequest({
verifierIds: ['ownership-basic'],
data: { content: 'Hello' },
walletAddress: '0x...',
options: { targetChains: [11155111] } // TESTNET storage only
});
const signature = await wallet.signMessage(message);
await fetch('/api/v1/verification', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ ...request, signature })
});
Validation
import { validateVerifierPayload } from '@neus/sdk';
const validation = validateVerifierPayload('verifier-id', data);
if (!validation.valid) {
console.error('Validation failed:', validation.error);
}
Network Configuration
Asset verification: Use mainnet chains (1, 137, 42161, 10, 8453)
Proof storage: Use testnet chains (11155111, 80002, 421614, 11155420)
Hub chain: 84532 (Base Sepolia) - never include in targetChains
Contributing
See contributing.md for submission process and review criteria.
Last updated
Was this helpful?