Aller au contenu principal

Node / TypeScript SDK

Idiomatic TypeScript client. Zero external runtime dependencies - uses Node's built-in fetch and node:crypto.

Install​

npm install @corezt/ztxbas

Requires Node 18 or newer.

Import​

import { Client, ChallengeDeniedError } from '@corezt/ztxbas';

Minimal end-to-end​

const c = new Client(
'https://ztxbas.example.com',
'app_YOUR_APPLICATION_ID',
'YOUR_HMAC_SECRET_HEX',
);

await c.registerUser({ email: 'alice@example.com' });
await c.registerOrigin({
origin: 'https://app.example.com',
display_name: 'Example App',
});

const ch = await c.createChallenge({
user_email: 'alice@example.com',
origin: 'https://app.example.com',
});

const claims = await c.pollChallenge(ch.challenge_id);
console.log(claims.email, claims.origin);

Errors as typed subclasses​

Every SDK-thrown error inherits from ZtxbasError. Match with instanceof:

import {
ChallengeDeniedError,
ChallengeExpiredError,
UnregisteredOriginError,
} from '@corezt/ztxbas';

try {
await c.pollChallenge(ch.challenge_id);
} catch (e) {
if (e instanceof ChallengeDeniedError) { /* user Denied */ }
else if (e instanceof ChallengeExpiredError) { /* TTL elapsed */ }
else if (e instanceof UnregisteredOriginError) { /* programmer error */ }
else throw e;
}

Verify-only mode​

import { Verifier } from '@corezt/ztxbas';

const v = new Verifier(
'https://ztxbas.example.com/.well-known/jwks.json',
{ expectedIssuer: 'https://ztxbas.example.com' },
);
const claims = await v.verify(jwtFromMobile);

Repo and reference​