npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@noviuz/kyc-server

v2.0.0

Published

Partner-server helper that HMAC-signs the Noviuz hosted-KYC session mint (Tier-1 credential) and returns a sessionId. Node-only — never bundle for the browser.

Readme

@noviuz/kyc-server

Node/edge server SDK for Noviuz partners: mints hosted-KYC sessions against the Noviuz backend (noviuz-app) with a server-only Bearer secret — the market-standard pattern (Stripe, Plaid) — and returns the sessionId your frontend passes to @noviuz/kyc-js.

Never bundle this package for the browser. It carries your server-only secret. The package throws at import time if it detects a window global.

Install

npm install @noviuz/kyc-server     # Node >= 18 (global fetch), or any Workers/edge runtime

Quick start (Bearer — recommended)

The @noviuz/kyc-server/bearer entry is Workers-safe (plain fetch, no node:crypto) — it runs on Node, Cloudflare Workers / Pages Functions, Vercel/Netlify edge, Deno, and Lambda.

import { createSessionClient } from '@noviuz/kyc-server/bearer';

const kyc = createSessionClient({
  baseUrl: 'https://api.noviuz.com', // origin only — no path, credentials, query, or fragment
  secretKey: process.env.NOVIUZ_SECRET_KEY!, // server-only Bearer secret; never in the browser
  timeoutMs: 10_000, // optional; default 10s
  // allowInsecureLocalhost: true, // ONLY for http://localhost|127.0.0.1|::1 during local dev
});

// In your session endpoint (e.g. POST /kyc/session on YOUR server):
const session = await kyc.mintSession(
  {
    customerType: 'individual', // or 'business'
    verificationMethods: ['pix', 'openfinance'], // optional rail allowlist
    merchantId: 'NVZ123', // optional
    orderId: 'order_42', // optional
  },
  { idempotencyKey: crypto.randomUUID() }, // REQUIRED — same key + same body replays the same session
);

// Hand ONLY the sessionId to your frontend:
res.json({ sessionId: session.sessionId });

Authoritative result reconciliation

The hosted page's redirect/callback outcome is a notification, not a decision — always reconcile the true outcome server-to-server before acting on it (e.g. before granting access or releasing funds):

const result = await kyc.getResult(sessionId); // GET .../result — read-only, never mutates state
// result: { status, sessionId, referenceId?, euid?, noviuz_euid? } — see @noviuz/kyc-contracts
switch (result.status) {
  case 'approved':
    /* … */ break;
  case 'rejected':
  case 'expired':
  case 'cancelled':
  case 'under_review':
    /* … */ break;
}

getResult throws a typed KycMintError for 401 (UNAUTHORIZED), 404 (NOT_FOUND — unknown session or a session owned by another operator; the two are deliberately indistinguishable), 409 (NOT_TERMINAL — no decision yet, retry later), 410 (EXPIRED), and 429 (RATE_LIMITED). The 200 body is runtime-validated against @noviuz/kyc-contracts's kycResultSchema — a malformed or unexpected shape throws MALFORMED_RESPONSE instead of propagating a broken result into your app.

Frontend side — open with the server-minted sessionId; treat the callback as a notification and reconcile server-side before acting on it (never persist a value straight off the callback):

NoviuzKyc.open({
  sessionId,
  onSuccess: (result) => reconcileOnYourServer(result.sessionId), // notification — not a decision
  onError: (error) => console.error(error.code, error.message),
});

API

createSessionClient(options): MintClient@noviuz/kyc-server/bearer

| Option | Type | Default | Notes | | --- | --- | --- | --- | | baseUrl | string | — | Origin only (https://api.noviuz.com) — no path, embedded credentials, query, or fragment. HTTPS required. | | secretKey | string | — | Server-only secret, sent as Authorization: Bearer <secretKey>. Must be non-blank. Keep it in a secret manager. | | timeoutMs | number | 10000 | Per-request timeout (AbortController). | | fetch | typeof fetch | global | Injectable for tests/instrumentation. | | allowInsecureLocalhost | boolean | false | Opt-in to allow plaintext http:// — ONLY for localhost/127.0.0.1/::1. Never set for a remote/production origin. |

mintSession(params, options): Promise<SessionInit>

POSTs params ({ customerType, verificationMethods?, merchantId?, orderId? }) to /api/v1/kyc/sessions with a required options.idempotencyKey, sent as the Idempotency-Key header — production Bearer mint is idempotent per the v2 contract: the same key + the same body replays the original minted session; the same key + a different body is a conflict. The response is runtime-validated — a malformed response throws KycMintError('MALFORMED_RESPONSE') instead of propagating a broken shape into your app.

getResult(sessionId): Promise<KycResultV2>

See Authoritative result reconciliation above.

KycMintError

Typed failures with a stable code and the HTTP status. Bearer mint surfaces INVALID_CREDENTIAL, IP_NOT_ALLOWED (403), RATE_LIMITED (429), INVALID_REQUEST (other 4xx), NETWORK, TIMEOUT, and MALFORMED_RESPONSE. getResult surfaces UNAUTHORIZED (401), NOT_FOUND (404), NOT_TERMINAL (409), EXPIRED (410), RATE_LIMITED (429), NETWORK, TIMEOUT, and MALFORMED_RESPONSE — a dedicated mapping, since the result endpoint's status semantics differ from mint's. (MISSING_HEADERS, INVALID_SIGNATURE, and NONCE_REUSED only arise in the HMAC mode below.) Error messages never echo your secret, headers, or the response body.

Advanced: HMAC request-signing (non-live only)

Bearer is the only production auth mode. A live-environment mint presenting X-Api-Key (this HMAC mode) is hard-rejected 401, fail-closed — the backend refuses to boot live with anything but Bearer (v2 contract §3.2). HMAC exists only for non-live (dev/staging) environments during the migration window; do not build a production integration on it.

The main @noviuz/kyc-server export offers a request-signing mode for teams that need per-request HMAC signatures in a non-live environment instead of a static Bearer secret. It is Node-only (uses node:crypto), so it is not Workers-safe. For production, use Bearer.

import { createSessionClient } from '@noviuz/kyc-server';

const kyc = createSessionClient({
  baseUrl: 'https://api.noviuz.com',
  credential: {
    apiKey: process.env.NOVIUZ_API_KEY!,
    signingSecret: process.env.NOVIUZ_SIGNING_SECRET!,
  },
  timeoutMs: 10_000,
  retries: 2, // optional; retries transient failures only, each freshly signed
});

Each request carries X-Api-Key, X-Timestamp, X-Nonce, and X-Signature, where the signature is HMAC-SHA256(secret, "{timestamp}.{method}.{path}.{sha256(body)}") — a byte-exact replica of the backend's compute_signature.

Known limitation: X-Nonce is sent but not part of the signed message, so the backend's replay check only catches byte-identical replays; a captured signed request can be replayed with a fresh nonce within the timestamp-tolerance window. Blast radius is orphan sessions — a replayed mint can only create an unauthorized session, never approve a KYC or move funds. Fixed when the signing contract adds the nonce (noviuz-app protocol v2).

Security checklist

  • ✅ Secrets only from env/secret manager — never in code or the frontend.
  • ✅ This package never logs or echoes the secret, auth headers, or response bodies.
  • ✅ Node ≥ 18 (or a fetch-capable edge runtime), TLS-only baseUrl (enforced).
  • ✅ Session IDs are short-lived, single-flow tokens — safe to hand to the browser.