API, flow, options — request, decode, verify time-bound IDs.
- Quick Start
- Flow Overview
- Methods Overview
- ConnectorId and HashId
- Request and Expiry
- Decode and Verify
- API Reference
- Option Types
- Reference
Flow: connectorId → hashId → instance (via create) → request → decode → verify.
import trustless from '@neabyte/trustless-id'
// Connector ID (same on both sides)
const connectorId = 'trustless://auth/example.com:0.1.0?service=none'
// One-time hashId per session
const hashId = trustless.generate(connectorId)
// Instance for connector (same on client and verifier)
const instance = trustless.create(connectorId)
// Request with 10s expiry window; send requestId to verifier (QR / link / form)
const requestId = instance.request(hashId, 10)
// Client: decode to code and show to user
const codeId = instance.decode(hashId, requestId)
if (codeId !== null) {
// Verifier: check user-entered secret
const ok = instance.verify(requestId, codeId)
}- Connector — Both client and verifier use the same
connectorId(e.g. service URL). - Hash — Client calls
trustless.generate(connectorId)once per session; returns a 197-char hexhashId(unique per call). This is the session identifier. - Instance — Both sides call
trustless.create(connectorId)to get an instance (forrequest,decode,verify) bound to that connector. - Request — Client calls
instance.request(hashId, expireTime?)to getrequestId. SendrequestIdto the verifier (e.g. QR, link, form). - Decode — Client calls
instance.decode(hashId, requestId)to get numericcodeId, ornullif invalid/expired. Client shows the code to the user so they can type it at the verifier. The verifier does not calldecode. - Verify — User enters the code at the verifier. Verifier calls
instance.verify(requestId, secret)only; returnstruewhen not expired and code matches.
| Method | Type | Returns | Description |
|---|---|---|---|
trustless.create(connectorId) |
static | instance | Factory: new instance bound to connector. |
trustless.generate(connectorId) |
static | HashId |
One-time 197-char hex hash. |
instance.request(hashId, expireTime?) |
instance | RequestId |
Encoded payload string or '' if hashId invalid. |
instance.decode(hashId, requestId) |
instance | CodeId | null |
Client: numeric code when valid (show to user). |
instance.verify(requestId, secret) |
instance | boolean |
Verifier: true when not expired and code matches. |
-
ConnectorId — Any non-secret string that identifies the connector (e.g.
trustless://auth/example.com:0.1.0?service=none). Trimmed before hashing. Same value on both sides yields the same encryption key. -
HashId — 197 lowercase hex chars from
trustless.generate(connectorId). Includes timestamp and random nonce; different on every call. Used by the client when callingdecode(hashId, requestId)to obtain the code to show the user. The verifier does not needhashId; it only receivesrequestIdand the user-entered code and callsverify(requestId, secret).const hashId = trustless.generate(connectorId) // hashId.length === 197, /^[0-9a-f]{197}$/.test(hashId) === true
-
request(hashId, expireTime?) — Validates
hashId(197 hex chars), then encodeshashId+ current time slot + window. Returns fixed-lengthRequestIdor''ifhashIdinvalid. -
expireTime — Window in seconds (1–60). Default 10. Clamped via
Cipher.clampWindow. SamehashIdand same window in the same time slot yields the samerequestIdand samecodeId.const requestId = instance.request(hashId, 10) const requestIdLong = instance.request(hashId, 60) // requestId length: 6 (slot) + 2 (window) + 197 (hashId) = 205
-
decode(hashId, requestId) — Decodes with instance key; checks expiry; ensures payload
hashIdmatches argument; returns derived numeric code ornull. Code is in range0–1e10. -
verify(requestId, secret) — Decodes, checks expiry, derives expected code, compares to
secret.secretcan be number or string (digits only); returnstruewhen match and not expired.const codeId = instance.decode(hashId, requestId) if (codeId !== null) { instance.verify(requestId, codeId) === true instance.verify(requestId, String(codeId)) === true }
Create an instance bound to the given connector. The instance key is a hash of the trimmed connectorId.
connectorId<ConnectorId>: Caller identifier (string, trimmed).- Returns: New instance (use for
request,decode,verify).
Generate a one-time 197-char hex hash. Uses connectorId + timestamp + random nonce. Call once per session; each call returns a different value.
connectorId<ConnectorId>: Same identifier as used forcreate.- Returns:
<HashId>197 lowercase hex characters.
Build the encoded request payload for the given hash and optional expiry window.
hashId<HashId>: 197-char hex fromgenerate.expireTime<ExpireTime | undefined>: Window in seconds (1–60). Default 10.- Returns:
<RequestId>Encoded string of length 205, or''ifhashIdinvalid.
Client only. Decode request payload and return the numeric code when hash matches and not expired. Use the returned code to show the user so they can enter it at the verifier.
hashId<HashId>: Expected hash for this session.requestId<RequestId>: Encoded payload fromrequest.- Returns:
<CodeId | null>Integer in 0–1e10, or null when invalid/expired/wrong hash.
Verifier only. Check that the user-provided secret matches the derived code and the payload is not expired.
requestId<RequestId>: Encoded payload (received from client, e.g. via QR).secret<VerifySecret>: Number or string of digits (user-entered code).- Returns:
<boolean>True when not expired and code matches.
Types are exported for TypeScript: import type { CodeId, ConnectorId, DecodedPayload, ExpireTime, HashId, RequestId, VerifySecret } from '@neabyte/trustless-id'.
- ConnectorId:
<string>— Caller identifier. - HashId:
<string>— 197-char hex fromgenerate. - RequestId:
<string>— Encoded payload fromrequest. - CodeId:
<number>— Numeric code fromdecode(0–1e10). - ExpireTime:
<number>— Window in seconds (1–60). - VerifySecret:
<string | number>— Value forverify. - DecodedPayload:
{ hashId: HashId, slot: number, window: number }— Internal decoded parts (slot base-36, window in seconds).
- README — Installation and quick start.
- Tests under
tests/— Trustless flow, Cipher, Security, Expiration, EdgeCases.