Skip to main content
Use these patterns to choose how your app creates or reuses proofs. In most products, reuse-or-create is the default.

Privacy and visibility

Raw client.verify() defaults to private stored receipts. VerifyGate create mode defaults to unlisted public so gates work without extra options. Full matrix: Security and trust.
OptionWhen to use
privacyLevel: 'private'Raw SDK default. Owner or authorized-session access.
privacyLevel: 'public'Policy checks without owner session; pair with publicDisplay.
publicDisplay: falseUnlisted: eligible in checks; still public to anyone with the proof id.
publicDisplay: trueListed / discoverable (requires privacyLevel: 'public').

Hide original content

Set storeOriginalContent: false when your product should retain only proof metadata/hash/policy status, not original bytes (hash-only mode). Example (unlisted public, typical for gates):
options: {
  privacyLevel: 'public',
  publicDisplay: false,
}

Reuse-first flow

Use this as the default UX. It minimizes user prompts while still issuing new proofs when needed. VerifyGate already defaults create mode to unlisted public; add proofOptions only when you need listed public or private.
<VerifyGate
  requiredVerifiers={['ownership-basic']}
  strategy="reuse-or-create"
>
  <Protected />
</VerifyGate>

Fresh Proof Flow

Use this when the action is high stakes and you need a newly created assertion.
<VerifyGate
  requiredVerifiers={['wallet-risk']}
  strategy="fresh"
>
  <Protected />
</VerifyGate>

Hosted Interactive Flow

Interactive verifiers hand off to NEUS hosted verification (/verify).
<VerifyGate
  requiredVerifiers={['ownership-social']}
  hostedCheckoutUrl="https://neus.network/verify"
/>

Policy checks from your app

Use the SDK gateCheck helper instead of downloading full proof payloads for every decision.
const result = await client.gateCheck({
  address: '0x...',
  verifierIds: ['token-holding'],
  contractAddress: '0x...',
  minBalance: '1',
  chainId: 8453,
});