Skip to main content
SDK for proof creation, hosted handoff, polling. Prefer over raw HTTP when you can.

Install

npm install @neus/sdk

Create a Proof (Browser Wallet Flow)

This path requests a wallet signature in the browser and submits the verification request:
import { NeusClient } from '@neus/sdk';

const client = new NeusClient({ apiUrl: 'https://api.neus.network' });

const res = await client.verify({
  verifier: 'ownership-basic',
  content: 'Hello NEUS',
});

const proofId = res.proofId;
const record = await client.getProof(proofId);

Client Configuration

const client = new NeusClient({
  // Optional: API base URL (default: https://api.neus.network)
  apiUrl: 'https://api.neus.network',
  // Optional: public app attribution ID (non-secret)
  appId: 'neus-network',
  // Optional: request timeout (ms)
  timeout: 30000,
});

Verification Options

OptionWhen to Use
persist: trueStore the proof when you need a reusable proof receipt
ipfs: true / pin: trueUse when you need IPFS-backed storage
strategy: 'reuse-or-create'Check existing proof first, create if missing. Default.
strategy: 'fresh'Always create new proof. Use for high-stakes checks.
strategy: 'reuse'Only check existing proofs; never create.
See Verification Patterns for privacy levels and widget options.

Create a Proof (manual signing)

If the wallet signs in your app, get the signing string from the API first:
import { standardizeVerificationRequest, signMessage } from '@neus/sdk';

const provider = window.ethereum;
const walletAddress = '0x1111111111111111111111111111111111111111';
const signedTimestamp = Date.now();
const body = {
  verifierIds: ['ownership-basic'],
  data: {
    owner: walletAddress,
    content: 'Hello NEUS',
    reference: { type: 'url', id: 'https://example.com' }
  },
  walletAddress,
  signedTimestamp,
};

const standardized = await standardizeVerificationRequest(body, {
  apiUrl: 'https://api.neus.network',
});

const signature = await signMessage({
  provider,
  walletAddress,
  message: standardized.signerString
});

const res = await client.verify({
  ...body,
  signature,
  options: { privacyLevel: 'private' }
});
This is the advanced path. With MCP, manual signing is typically unnecessary.

What Verifiers Are Available?

Verifier catalog: API is authoritative for IDs, schema, metadata.
GET /api/v1/verification/verifiers
The SDK may ship fallbacks or examples; always treat the API response as authoritative for production.

Gate checks: gateCheck vs checkGate

MethodUse when
gateCheck()Production allow/deny. Calls GET /api/v1/proofs/check; server-enforced eligibility.
checkGate()Preview against proofs you already loaded. Not for security-sensitive allow/deny vs gateCheck().

App Attribution (appId)

Set appId on the client to attribute usage and analytics to your app. appId is a public identifier, not a secret.
const client = new NeusClient({
  apiUrl: 'https://api.neus.network',
  appId: 'acme-web',
});

Hosted Checkout URL Builder

Use getHostedCheckoutUrl for a single typed entry point: Supported query keys: gateId, returnUrl, verifiers, preset, mode, intent, and origin.
import { getHostedCheckoutUrl } from '@neus/sdk';

const url = getHostedCheckoutUrl({
  gateId: 'my-gate',
  returnUrl: 'https://myapp.com/callback',
  verifiers: ['ownership-social'],
  mode: 'popup',
  origin: window.location.origin,
  intent: 'login',
});
// => https://neus.network/verify?gateId=my-gate&returnUrl=...&verifiers=...&mode=popup&origin=...

Gate checks from your servers

Use gateCheck for allow/deny without loading full proof payloads:
const res = await client.gateCheck({
  address: 'YOUR_WALLET_OR_DID',
  verifierIds: ['token-holding'],
  contractAddress: '0x...',
  minBalance: '100',
  chainId: 8453, // asset verifiers need chainId
  since: Date.now() - 60 * 60 * 1000
});

if (!res.data?.eligible) {
  throw new Error('Access denied');
}
gateCheck uses public and unlisted proofs by default. Private proofs count only when that user is signed in. For the strictest live checks, create a fresh proof and wait for verified status.

Polling

pollProofStatus() backs off automatically on rate limits (429) and transient errors.

Advanced: Private Proof Operations

// Private proof by proof receipt ID
const privateData = await client.getPrivateProof(proofId, window.ethereum);

// Private proofs by wallet/DID (requires owner signature)
const privateProofs = await client.getPrivateProofsByWallet(
  'YOUR_WALLET_OR_DID',
  { limit: 50, offset: 0 },
  window.ethereum
);

// Revoke your proof
await client.revokeOwnProof(proofId, window.ethereum);

React Widgets

For UI gating, see Widgets.
import { VerifyGate, ProofBadge } from '@neus/sdk/widgets';