Proof creation, hosted URLs, polling. Use instead of ad-hoc HTTP when you can.
Install
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
| Option | When to Use |
|---|
persist: true | Persist a reusable proof ID |
ipfs: true / pin: true | Use 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.
Advanced: manual signing (full control)
Prefer client.verify() above when a browser wallet is available. Use this path only when you must assemble verifierIds / data yourself, then sign the API-standardized string:
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' }
});
Catalog: GET /api/v1/verification/verifiers - treat the response as authoritative (SDK examples are non-normative).
Gate checks: gateCheck vs checkGate
| Method | Use when |
|---|
gateCheck() | Allow/deny via GET /api/v1/proofs/check (server-enforced). |
checkGate() | Preview against proofs you already loaded. Not for security-sensitive allow/deny vs gateCheck(). |
Wallet-link: hosted first, direct when needed
For normal browser UX, route users to Hosted Verify so wallet selection, secondary-wallet signing, and proof creation stay guided. Use direct mode only when your integration already controls the secondary wallet/provider.
const walletLinkData = await client.createWalletLinkData({
primaryWalletAddress: '0xprimary...',
secondaryWalletAddress: '0xsecondary...',
wallet: window.ethereum,
relationshipType: 'linked',
label: 'ops-wallet'
});
const res = await client.verify({
verifier: 'wallet-link',
data: walletLinkData
});
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 on 429 and transient errors.
Advanced: Private Proof Operations
// Private proof by proofId
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);
For UI gating, see Widgets.
import { VerifyGate, ProofBadge } from '@neus/sdk/widgets';