Node and React SDKs
Get a token in the browser with the React SDK, then apply the grant on your server with the Node SDK.
Install
Version 0.1.0 packages are ready for publication but not yet published. Until then, build and install them from the repository directories.
# After npm publication:
npm install @nolgard/node
npm install @nolgard/react reactRequires Node.js 18+ or an edge runtime with fetch, and React 18+. Both SDKs include ESM and TypeScript declarations. Neither bundles runtime dependencies.
Server
import { createNolgard } from '@nolgard/node';
const nolgard = createNolgard({
secret: process.env.NOLGARD_SECRET,
// baseUrl: 'https://nolgard.com',
// timeoutMs: 2500,
});
const result = await nolgard.verify({
token, action: 'signup', remoteIp,
account: { id: accountId, email },
headers: { 'user-agent': userAgent },
});
if (!result.success || result.decision === 'block') return deny();
// Apply share and credits server-side. If requires is non-null,
// complete that requirement before issuing more access.
return applyGrant(result.grant, result.ref);grant contains {share, credits, requires}. Share is 0–1. Credits is a number or null. Requires is step-up, payment, or null. Observe mode also returns wouldGrant. A valid token does not grant full access.
Fail-open policy
Timeouts, network failures, malformed JSON, HTTP 5xx and 429 return {success:true, decision:'allow', grant:{share:1, credits:null, requires:null}, failOpen:true}. This SDK-generated response has no event reference. Normal responses keep the server fields and add failOpen:false.
HTTP 401 throws NolgardConfigError. Fix the secret. Other unsuccessful statuses throw NolgardRequestError. The SDK does not retry. Only verify fails open. Feedback, clusters and step-up reject on errors.
React
import { NolgardScript, useNolgard } from '@nolgard/react';
function Signup() {
const { ready, execute, stepUp } = useNolgard();
async function submit() {
const token = await execute('signup');
const result = await sendToYourBackend({ token });
if (result.grant.requires === 'step-up') {
const proof = await stepUp({ ref: result.ref });
await sendProofToYourBackend(proof);
}
}
return <button disabled={!ready} onClick={submit}>Sign up</button>;
}
function App() {
return <><NolgardScript siteKey="pk_your_site" /><Signup /></>;
}The component loads https://nolgard.com/v1/client.js once with data-site-key, even across Strict Mode remounts. Use one site key per page. The hook waits for the browser readiness promise. Catch execute and step-up errors in your app.
stepUp({ref, email?, method?}) returns a proof. Method is pow or email. Send the proof to your server and call nolgard.verifyStepUp(proof). Require success and enforce the returned grant. Never send a secret to the browser. With React Server Components, use a client component.
Usage
nolgard.usage.track({ accountId, units: 100, quota: 5000 });
const { accepted, flagged, dropped } = await nolgard.usage.flush();
// flagged: [{ accountId, reasons: string[] }]
// nolgard.usage.dropped: lifetime drop countOptional event fields: units, ip, userAgent, ts (epoch milliseconds), quota. The SDK batches at 100 events or 5 seconds and sends at most 500 per request. flush() drains the queue and never rejects. Failed batches are dropped and counted rather than retried. Report failures with onUsageError(error, dropped).
Await flush before ending a serverless invocation or exiting. The queue lives in memory; it is not a billing ledger. Node timers do not keep the process running.
Feedback and clusters
await nolgard.feedback('ev_123', 'fraud'); // or 'legit'
const { size, accounts } = await nolgard.cluster(accountId);
const proof = await nolgard.verifyStepUp(stepUpToken);
if (!proof.success) return deny();Requests use POST and carry the configured secret. See test keys and feedback, clusters, and step-up checks for the underlying API.