Reference

Technical documentation for NEUS Network integration.

Table of Contents


SDK Reference

Installation

npm install @neus/sdk

Basic Usage

import { NeusClient } from '@neus/sdk';

// In browser apps, prefer a same-origin server route to avoid CORS
const client = new NeusClient({ apiUrl: '/api/neus' });
const proof = await client.verify({
  verifier: 'ownership-basic',
  content: 'Hello NEUS'
});
// See also: Verifier pages → ./verifiers/ownership-basic.md

Configuration

const client = new NeusClient({
  apiUrl: 'https://api.neus.network', // Default (server-side). In browsers use /api/neus
  timeout: 30000                      // Request timeout in ms
});

Methods

verify(params)

Create verification proof.

Auto Mode (Recommended):

const proof = await client.verify({
  verifier: 'ownership-basic',
  content: 'Content to verify'
});
// Pitfalls: address normalization and timestamp window; see ./api/README.md#troubleshooting

Manual Mode (Advanced):

const proof = await client.verify({
  verifierIds: ['ownership-basic'],
  data: { content: 'Content', owner: walletAddress },
  walletAddress: '0x...',
  signature: '0x...',
  signedTimestamp: Date.now()
});

getStatus(qHash)

Get verification status.

const status = await client.getStatus(qHash);
console.log('Success:', status.success);
console.log('Status:', status.data.status);
// See also: Polling helper → `pollProofStatus`

getPrivateStatus(qHash, wallet)

Access private proof with wallet signature.

const privateData = await client.getPrivateStatus(qHash, window.ethereum);

pollProofStatus(qHash, options)

Wait for verification completion.

const finalStatus = await client.pollProofStatus(qHash, {
  interval: 3000,
  timeout: 60000,
  onProgress: (status) => console.log('Status:', status.status)
});
// See also: API status endpoints → ./api/README.md

HTTP API

Authentication

All requests require wallet signatures (EIP-191). See also: Message format and helpers → ./api/README.md#standard-message-format

Standard Signing String Format

NEUS Verification Request
Wallet: {lowercase_wallet_address}
Chain: {chain_id_number}
Verifiers: {verifier1,verifier2,...}
Data: {deterministic_json_string}
Timestamp: {unix_milliseconds}

Endpoints

Create Verification

POST /api/v1/verification

Request:

{
  "verifierIds": ["ownership-basic"],
  "data": {"content": "Hello", "owner": "0x..."},
  "walletAddress": "0x...",
  "signature": "0x...",
  "signedTimestamp": 1678886400000,
  "chainId": 84532,
  "options": {"privacyLevel": "private"}
}

See also: Privacy and options → ./PRIVACY.md

Get Status

GET /api/v1/verification/status/{qHash}

Build Signing String (Helper)

POST /api/v1/verification/standardize

Optional helper to get the exact string format if needed for troubleshooting.

Diagnose Issues

POST /api/v1/verification/diagnose

Debug signature verification problems.


Verifier Specifications

ownership-basic

Purpose: Content ownership verification

Required Fields:

  • content (string) - Content to verify

  • owner (address) - Owner wallet address

  • reference (object) - Reference information

    • type (string) - Reference type: url, ipfs, tx, other

    • id (string) - Reference identifier

Example:

{
  verifier: 'ownership-basic',
  data: {
    content: 'My original article',
    owner: '0x...',
    reference: { type: 'url', id: 'https://example.com' }
  }
}

nft-ownership

Purpose: NFT ownership verification

Required Fields:

  • ownerAddress (address) - NFT owner wallet

  • contractAddress (address) - NFT contract address

  • tokenId (string) - NFT token ID

  • chainId (number) - Blockchain chain ID

Optional Fields:

  • tokenType (string) - 'erc721' or 'erc1155' (default: 'erc721')

Example:

{
  verifier: 'nft-ownership',
  data: {
    ownerAddress: '0x...',
    contractAddress: '0x...',
    tokenId: '1234',
    chainId: 1
  }
}

token-holding

Purpose: Token balance verification

Required Fields:

  • ownerAddress (address) - Token holder wallet

  • contractAddress (address) - ERC20 contract address

  • minBalance (string) - Minimum balance (human-readable)

  • chainId (number) - Blockchain chain ID

Example:

{
  verifier: 'token-holding',
  data: {
    ownerAddress: '0x...',
    contractAddress: '0x...',
    minBalance: '100.0',
    chainId: 1
  }
}

ownership-licensed

Purpose: Licensed content ownership verification

Required Fields:

  • content (string) - Licensed content description/title

  • owner (address) - License owner wallet address

  • license (object) - License NFT details

    • contractAddress (address) - License NFT contract

    • tokenId (string) - License token ID

    • chainId (number) - Mainnet chain where license is verified (e.g., 1)

    • ownerAddress (address) - Expected license holder

    • type (string, optional) - 'erc721' | 'erc1155' (default: 'erc721')

Optional Fields:

  • reference (object) - Reference to the licensed content

    • type (string) - 'url' | 'ipfs' | 'tx' | 'other'

    • id (string) - Reference identifier

Example:

{
  verifier: 'ownership-licensed',
  data: {
    content: 'Pro Tools License',
    owner: '0x...',
    license: {
      contractAddress: '0x...',
      tokenId: '1',
      chainId: 1,
      ownerAddress: '0x...',
      type: 'erc721'
    }
  }
}

Privacy Controls

Privacy Levels

  • public - Anyone can see proof details

  • private - Only wallet owner can access details

Options

{
  options: {
    privacyLevel: 'private',        // public | private
    publicDisplay: false,           // Enable public UI display
    storeOriginalContent: false,    // Store content in proof
    enableIpfs: false,              // Create IPFS snapshot
    targetChains: [11155111, 80002] // Cross-chain storage (testnet)
  }
}

Accessing Private Proofs

// Private proofs require a wallet signature from the proof owner
const privateData = await client.getPrivateStatus(qHash, wallet);

Multi-Language Support

NEUS works with any programming language via HTTP API.

Universal Flow

  1. Get Standard Signing String

  2. Sign with your wallet library

  3. Submit verification request

Language Examples

Multi-language signing utilities: See signing helpers in the repository: signing helpers


React Widgets

Installation

npm install @neus/widgets

VerifyGate

Gate content behind verification requirements.

import { VerifyGate } from '@neus/widgets';

<VerifyGate 
  requiredVerifiers={['nft-ownership']}
  onVerified={(result) => console.log('Verified:', result.qHash)}
>
  <PremiumContent />
</VerifyGate>

Props:

  • requiredVerifiers - Array of verifier IDs

  • onVerified - Callback when verification succeeds

  • disabled - Disable verification button

  • style - CSS styles for container

ProofBadge

Display verification status with an optional status dot.

import { ProofBadge } from '@neus/widgets';

// In dev, pass a proof object to avoid cross-origin status fetches
<ProofBadge qHash="0x..." proof={{ status: 'verified' }} />
<ProofBadge qHash="0x..." size="md" showDot={false} />
<ProofBadge qHash="0x..." labelOverride="Verified Content" />

Props:

  • qHash - Proof identifier (required)

  • size - Badge size: 'sm' | 'md' (default: 'sm')

  • showDot - Show status dot (default: true)

  • labelOverride - Custom label text

  • uiLinkBase - Base URL for proof links (default: 'https://neus.network')


Error Handling

Common Error Codes

  • 4001 - User rejected wallet signature

  • INVALID_WALLET_ADDRESS - Wallet address format incorrect

  • SIGNATURE_INVALID - Signature verification failed

  • VERIFIER_NOT_FOUND - Invalid verifier ID

  • RATE_LIMIT_EXCEEDED - Too many requests

Error Handling Pattern

try {
  const proof = await client.verify({
    verifier: 'ownership-basic',
    content: 'My content'
  });
} catch (error) {
  if (error.code === 4001) {
    // User cancelled - handle gracefully
    console.log('User cancelled verification');
  } else {
    // Technical error - show user-friendly message
    console.error('Verification failed:', error.message);
  }
}

Debugging Signatures

If getting signature errors:

  1. Use /verification/standardize endpoint

  2. Sign the exact returned string

  3. Use /verification/diagnose if still failing


Contract Information

Deployments

Base Sepolia (Hub Chain - 84532):

  • NEUSVerifierRegistry: 0x728Ba14b52d4811e2eDcE37c7e419AB47B0A17Df

  • NEUSVoucherHub: 0xD524bd93e51b29C63b921994BF2BA61f8f49FB6C

  • NEUSToken: 0xBe5F4fe3ba4C28DBfB5d9518b6F68F68844e3854

Cross-Chain Storage (Testnet):

  • Ethereum Sepolia (11155111): 0x4eE5346a253bA26508FC99FAa49932561205359C

  • Polygon Amoy (80002): 0x5746f86E6BC6AcCF34286Bc8E8803CcAc4a0306d

  • Arbitrum Sepolia (421614): 0x0095E6e6A1CA0E05e56920aeaDc0c8bDDEADcdC1

  • Optimism Sepolia (11155420): 0x24f9Af19693D163576ac49DF3b7a75934bB3B1b4

ABIs

Contract ABIs available at:

  • network/abis/NEUSVerifierRegistry.json

  • network/abis/NEUSVoucherHub.json

  • network/abis/NEUSVoucherSpoke.json

  • network/abis/NEUSToken.json


Support


For quick integration, start with QUICKSTART.md.

Last updated

Was this helpful?