@zyphe-sdk/node
Install the package:
- pnpm
- npm
- Yarn
- Bun
pnpm add @zyphe-sdk/node
npm install --save @zyphe-sdk/node
yarn add @zyphe-sdk/node
bun add @zyphe-sdk/node
1. Webhook Signature Verification
This package provides the core webhook signature verification logic for Zyphe. It enables secure verification of incoming webhook requests in Node.js using HMAC-SHA256 signatures.
Basic Usage
import { verifyWebhookSignatureHeader } from '@zyphe-sdk/node'
const secretHex = '<your-hex-encoded-secret>'
const rawBodyString = '...' // The raw request body as a string
const signatureHeader = 't=1234567890,v0=abcdef...' // The signature header from the webhook
const isValid = verifyWebhookSignatureHeader(secretHex, rawBodyString, signatureHeader)
if (isValid) {
// Signature is valid
} else {
// Signature is invalid
}
secretHex: The hex-encoded secret key used to sign the webhook.rawBodyString: The raw request body as a string (must match exactly what was sent).signatureHeader: The signature header string, e.g.t=1234567890,v0=abcdef....- Returns:
trueif the signature is valid, orfalseotherwise.
Advanced Utilities
parseSignatureHeader(signatureHeader)– Parse the signature header into timestamp and signature.hexToBytes(hex)/bufferToHex(buffer)– Convert between hex and bytes.timingSafeEqual(a, b)– Constant-time string comparison.- Error codes/messages for robust error handling.
2. Verification Session Management
You can programmatically create verification sessions and construct user-facing URLs for onboarding flows.
Create a Verification Session
import { createVerificationSession } from '@zyphe-sdk/node'
const response = await createVerificationSession(
{
email: 'user@example.com', // required
flowId: '<flowId>', // required
flowStepId: '<flowStepId>', // required
isSandbox: false, // required
customData: {
// optional
walletAddress: '0x123...',
// ...any extra data you want to pass
},
},
{
apiKey: '<your-api-key>',
environment: 'staging', // or "production", "local"
handoffBaseUrl: 'https://your-app.com', // optional
primaryColor: '#000000', // optional
secondaryColor: '#ffffff', // optional
isFullscreen: true, // optional
},
)
customData(optional): Pass any extra data you want to associate with the verification session. This will be available in the webhook payload and session data.- The function returns a Promise resolving to the API response. Handle errors as needed (e.g., try/catch or checking for error fields).
Construct a Verification Session URL
import { constructVerificationSessionUrl } from '@zyphe-sdk/node'
const url = constructVerificationSessionUrl({
flowParams: {
flowId: '...',
flowStepId: '...',
email: 'user@example.com',
product: 'kyc', // or "kyb" if supported
isSandbox: false,
customData: { walletAddress: '0x123...' }, // optional
},
verificationSession: response.data, // from createVerificationSession
opts: {
apiKey: '<your-api-key>',
environment: 'staging',
handoffBaseUrl: 'https://your-app.com', // optional
primaryColor: '#000000', // optional
secondaryColor: '#ffffff', // optional
isFullscreen: true, // optional
},
})
- The constructed URL includes all relevant parameters and can be used to embed or redirect users to the verification flow.
- Optional fields (like
handoffBaseUrl,primaryColor, etc.) will be appended as query parameters if provided.
Types
InitializeZypheFlowParams: Parameters for initializing a verification flow.SDKOptions: Configuration for the SDK.SdkCreateVerificationRequestResponse: API response type for session creation.
Error Handling
- If session creation fails, the function may throw or return an error object depending on usage context. Always check for errors and handle them appropriately.
- Example:
try {
const response = await createVerificationSession(...);
if (response.error) {
// Handle error
console.error(response.error);
} else {
// Success
}
} catch (err) {
// Handle thrown errors (e.g., network issues)
console.error(err);
}
3. Complete Verification Steps
The Node SDK also includes helpers for completing document selection, document verification, and liveness steps from your backend.
Typical flow:
- Create a verification session with
createVerificationSession. - Check the current step with
getNextStepDetailsif you need to branch dynamically. - Complete document selection with
completeDocumentSelectionStepwhen the next step isdocument-selection. - Upload document images with
completeDvStepwhen the next step is a document verification step. - Complete liveness with
completeLivenessStepwhen the flow requires liveness.
Inspect the Next Step
import { getNextStepDetails, type SDKOptions } from '@zyphe-sdk/node'
const opts: SDKOptions = {
apiKey: '<your-secret-api-key>',
environment: 'staging',
}
const { error, data: nextStep } = await getNextStepDetails(
{
flowId: '<flow-id>',
email: 'user@example.com',
isSandbox: true,
},
opts,
)
if (error) {
console.error(error)
} else {
console.log('Next step:', nextStep)
}
- Use
getNextStepDetailsto decide whether to ask for document selection, document images, liveness capture, or another step. - This helper calls the
sdk_get_next_stependpoint documented indocs/openapi/sdk-get-next-step.api.mdx.
Complete Document Selection and Document Verification
import { completeDocumentSelectionStep, completeDvStep, createVerificationSession, DocumentType, type SDKOptions } from '@zyphe-sdk/node'
import { readFile } from 'node:fs/promises'
async function readBase64File(filePath: string) {
return (await readFile(filePath)).toString('base64')
}
const opts: SDKOptions = {
apiKey: '<your-secret-api-key>',
environment: 'staging',
}
const verificationSessionResponse = await createVerificationSession(
{
email: 'user@example.com',
flowId: '<flow-id>',
flowStepId: '<document-selection-step-id>',
isSandbox: true,
},
opts,
)
if (verificationSessionResponse.error || !verificationSessionResponse.data) {
throw new Error('Failed to create verification session')
}
await completeDocumentSelectionStep(
{
verificationSession: verificationSessionResponse.data,
payload: {
country: 'IT',
documentType: DocumentType.IDENTITY_CARD,
},
},
opts,
)
const dvResult = await completeDvStep(
{
verificationSession: verificationSessionResponse.data,
countryCode: 'IT',
images: {
type: 'DOUBLE_SIDED_DOCUMENT',
frontImage: await readBase64File('./front.jpg'),
backImage: await readBase64File('./back.jpg'),
},
},
opts,
)
console.log('DV step completed')
console.log(dvResult)
- This example follows
../zyphe-sdk/examples/node-complete-step-dv/src/index.ts. - Use
DocumentType.IDENTITY_CARD,DocumentType.DRIVING_LICENSE, orDocumentType.PASSPORTwhen selecting the document type. completeDvStepaccepts either:type: 'DOUBLE_SIDED_DOCUMENT'withfrontImageandbackImagetype: 'SINGLE_SIDED_DOCUMENT'with a singleimage
- Image values must be base64-encoded strings.
- The SDK returns the API response for the submitted document job, including the verification request ID and job ID.
Complete a Liveness Step
import { completeLivenessStep, createVerificationSession, type SDKOptions } from '@zyphe-sdk/node'
import { readFile } from 'node:fs/promises'
async function readBinaryFile(filePath: string) {
return new Uint8Array(await readFile(filePath))
}
const opts: SDKOptions = {
apiKey: '<your-secret-api-key>',
environment: 'staging',
}
const verificationSessionResponse = await createVerificationSession(
{
email: 'user@example.com',
flowId: '<flow-id>',
flowStepId: '<liveness-step-id>',
isSandbox: true,
},
opts,
)
if (verificationSessionResponse.error || !verificationSessionResponse.data) {
throw new Error('Failed to create verification session')
}
const calibrationImage = await readBinaryFile('./calibration.jpg')
const video = await readBinaryFile('./liveness.mp4')
const movementImages = await Promise.all(['./movement-1.jpg', './movement-2.jpg'].map((filePath) => readBinaryFile(filePath)))
const livenessResult = await completeLivenessStep(
{
verificationSession: verificationSessionResponse.data,
frontImage: Buffer.from(calibrationImage),
video: Buffer.from(video),
movementImages: movementImages.map((image) => Buffer.from(image)),
},
opts,
)
console.log('Liveness step completed')
console.log(livenessResult)
- This example follows
../zyphe-sdk/examples/node-complete-step-liveness/src/index.ts. completeLivenessStepfirst fetches the challenge configuration, uploads the required assets to the provided presigned URLs, and then calls the final liveness processing endpoint.- For active liveness challenges, you must provide a
videoand the same number ofmovementImagesrequested by the challenge. frontImageis the calibration image uploaded before the final liveness submission.
4. Flow Results
You can use the Node SDK to list flow results for a flow and fetch a single flow result by ID.
List Flow Results
import { listFlowResults, type SDKOptions } from '@zyphe-sdk/node'
const opts: SDKOptions = {
apiKey: '<your-secret-api-key>',
environment: 'staging',
}
const { error, data } = await listFlowResults(
{
organizationId: '<organization-id>',
flowSlug: '<flow-slug>',
isSandbox: true,
pagination: {
take: 10,
skip: 0,
},
},
opts,
)
if (error) {
console.error(error)
} else {
console.log('Total flow results:', data?.totalCount ?? 0)
console.log('Current page:', data?.page ?? [])
}
organizationId: The organization that owns the flow results.flowSlug: The flow slug used to scope the results.isSandbox: Set totruefor sandbox data andfalsefor production data.pagination(optional): Usetake,skip,sort, andfilterto control paging.locale(optional): Localize fields that support translated values.- Returns: A Promise resolving to a paginated response with
totalCountand apagearray of flow results.
Get a Flow Result
import { getFlowResult, type SDKOptions } from '@zyphe-sdk/node'
const opts: SDKOptions = {
apiKey: '<your-secret-api-key>',
environment: 'staging',
}
const { error, data: flowResult } = await getFlowResult(
{
organizationId: '<organization-id>',
flowResultId: '<flow-result-id>',
isSandbox: true,
},
opts,
)
if (error) {
console.error(error)
} else {
console.log('Flow result:', flowResult)
}
flowResultId: The ID of the specific flow result you want to retrieve.- Returns: A Promise resolving to the full flow result payload, including result collections such as
dvResults,poaResults, andamlResultswhen available.
5. Types and Configuration
InitializeZypheFlowParams,SDKOptions,SdkCreateVerificationRequestResponse– for type-safe integration.Environments,EnvironmentConfigs,API_KEY_HEADER– for environment and API configuration.