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

@vpdev2/vc-sdk

v3.3.0

Published

React SDK for VeroCompliance due diligence workflows with configurable API endpoints and comprehensive step coverage

Readme

VeroCompliance SDK

A comprehensive React SDK for VeroCompliance due diligence workflows with configurable API endpoints, dynamic form generation, and complete workflow step coverage.

Features

  • ✅ Configurable API Endpoints - Support for both Host Controller and Application Service patterns
  • ✅ Complete Workflow Coverage - All 9 workflow step types supported
  • ✅ Dynamic Applicant Form - 23 configurable form fields for applicant creation
  • 🎨 Backend-Driven Theming - Multi-tenant theme customization with 6 presets, custom logo, colors, and CSS (NEW v1.2.0)
  • ✅ React Hooks - Clean API with hooks for each workflow step
  • ✅ Pre-built Components - Ready-to-use UI components with Tailwind CSS
  • ✅ Dynamic Form Validation - Automatic zod schema generation from API rules
  • ✅ Identity Provider Integration - Sumsub, Onfido, and SardinAI support
  • ✅ TypeScript - Full type safety with types generated from C# DTOs
  • ✅ Session Token Auth - Server-side token creation with optional externalRefId scoping guard
  • ✅ Dark Mode - Built-in dark mode support

Installation

npm install @vpdev2/verocompliance
# or
yarn add @vpdev2/verocompliance
# or
pnpm add @vpdev2/verocompliance

Quick Start

Step 1 — Server: create a session token

Create a short-lived session token on your backend. The API key and secret never leave your server.

// ── Server-side (Next.js API route, Express, etc.) ──
import { VeroComplianceSession } from '@vpdev2/verocompliance';

export async function POST() {
  const { accessToken, expiresInSeconds } = await VeroComplianceSession.createToken({
    baseUrl:       'https://api.example.com',
    clientId:      'your-client-id',           // or tenantId: 1
    apiKey:        process.env.VEROCOMPLIANCE_API_KEY!,
    secretKey:     process.env.VEROCOMPLIANCE_SECRET_KEY!,
    externalRefId: 'USER-12345',               // optional — scopes the token to this user
  });
  return Response.json({ accessToken, expiresInSeconds });
}

| Parameter | Type | Required | Description | |---|---|---|---| | baseUrl | string | Yes | VeroCompliance API base URL | | apiKey | string | Yes | Your tenant API key | | secretKey | string | Yes | Your tenant secret key | | tenantId | number | One of | Numeric tenant ID (provide this or clientId) | | clientId | string | One of | String client ID (provide this or tenantId) | | externalRefId | string | No | When set, the returned token is scoped: all API calls made with it can only create or access applicants matching this externalRefId. Tokens created without it remain unrestricted (backward-compatible). |

Step 2 — Client: initialize the SDK

Pass the token to the frontend SDK via getAccessToken:

import { VeroComplianceProvider } from '@vpdev2/verocompliance';

function App() {
  return (
    <VeroComplianceProvider
      config={{
        getAccessToken: () => fetchSessionToken(), // returns the accessToken string
        clientId: 'your-client-id',
        baseUrl: 'https://api.example.com',
        endpoints: { pattern: 'host-controller' },
        applicantForm: {
          externalRefId: 'USER-12345',
        },
        // Optional: Configure identity providers (e.g., SardinAI)
        identityProviders: {
          sardinai: process.env.SARDINAI_CLIENT_ID ? {
            clientId: process.env.SARDINAI_CLIENT_ID,
            environment: 'sandbox', // or 'production'
            region: 'us',           // 'us', 'eu', 'ca', or 'au'
            enableBiometrics: true,
            enablePortScanning: false,
          } : undefined,
        },
      }}
    >
      <YourApp />
    </VeroComplianceProvider>
  );
}

Tip: You can also pass apiKey directly instead of getAccessToken for quick testing, but session tokens are recommended for production since they keep your secret key on the server.

Step 3 — Use the workflow component

import { KycWorkflow } from '@vpdev2/verocompliance';

function KYCPage() {
  return (
    <KycWorkflow
      applicantId={applicantId}
      onComplete={(result) => console.log('Complete:', result)}
      onError={(error) => console.error('Error:', error)}
      onAppropriatenessOutcome={(outcome) => console.log('Appropriateness:', outcome)}
    />
  );
}

Appropriateness test outcome

When the workflow contains a MiFID appropriateness test, the optional onAppropriatenessOutcome callback (available on both VeroCompliance and KycWorkflow) reports the canonical outcome:

{
  testId: number;
  completionMode: 'PassRequired' | 'CompletionRequired';
  result: 'Passed' | 'FailedExhausted' | 'FailedContinued';
  attempts: number;
  passed: boolean;
  warningAcknowledged: boolean;   // true only for FailedContinued
  acknowledgedAt?: string;        // ISO-8601
  startedAt?: string;
  completedAt: string;
}

The test's completion mode is configured server-side per test. With PassRequired (the default) the investor must pass to continue; with CompletionRequired an investor who fails is clearly warned that they may lack sufficient knowledge/experience, may retake within the configured limits, and may continue after explicitly acknowledging the warning (FailedContinued).

Step 4 — Or build custom UI with hooks

import { useKycWorkflow, useQuestionnaire } from '@vpdev2/verocompliance';

function CustomKYC() {
  const { progress, currentStep, moveToNext } = useKycWorkflow(applicantId);
  const questionnaire = useQuestionnaire(applicantId);

  // Build your custom UI...
}

Workflow steps

KycWorkflow renders the step VeroCompliance says is current (currentStep.action):

| Step type | Step | What the applicant sees | |---|---|---| | 0 | IdentitySdk | The configured identity provider (Sumsub, Onfido or SardinAI) | | 1 | RiskScoring | The risk criteria that ask the applicant for input | | 2 | Questionaries | The questionnaire selected for the applicant | | 3 | AdditionalData | The Additional Data questions configured in VeroCompliance, or the built-in investor-type question (below) | | 4 | AppropriatenessTest | The appropriateness test, with its timer and retry limits | | 5 | UploadDocument | The documents to upload | | 6 | ManualReview | The review status while an administrator decides | | 7 | Overview | An overview the applicant confirms before continuing | | 8 | InvestorCategorization | Investor-type radios sent with SetInvestorCategorization. VeroCompliance does not send this step type |

Step names in the stepper

Each step is named by the first of these that has a value:

  1. an Additional Data step's definition title;
  2. the step's displayName from VeroCompliance;
  3. its name, unless that is only the step type (IdentitySdk, Overview, ManualReview), which VeroCompliance sends for a step with no content of its own;
  4. the SDK's name for the step type, from the stepNames translations (stepNames.identity for the identity step). SDK Configuration → Translations overrides them per language.

Identity step: the review page

Unless SDK Configuration disables it, the identity step opens on a review page, and the provider starts when the applicant confirms. First the built-in fields they changed there are saved:

  • only the changed ones go, and a field left empty keeps its saved value;
  • they're sent with ApplicantRegistrationRequest for the applicant under way, with the current workflow's key and webSdk: false, so no second OnApplicantCreated webhook is sent;
  • this is done before IdentityRequest, because VeroCompliance picks the provider by the applicant's country and hands the provider their details.

If VeroCompliance refuses the change with a 400, the page shows its message (for example ApplicantFlow.Immutable once an identity check has its result) and the provider doesn't start. Any other failure shows a generic error.

Additional Data step

The step calls GetAdditionalData when it opens, and shows a spinner until it answers.

With a definition. When the applicant's current Additional Data step has a definition in VeroCompliance, the result carries it as definition. The step then shows its title and description, and each question as a group of radio cards: the question's label, its description, and each option's label and description. Required questions are marked with * and must be answered before the step submits. An answer the applicant saved before is preselected while it is still one of the question's options. The step sends one item per answered question to SetAdditionalData, in the definition's order:

{ applicantId, items: [{ paramName: question.key, value: option.value }, /* … */] }

If VeroCompliance refuses the answers with a 400 (ApplicantFlow.InvalidAdditionalData), the step shows the server's message. Any other failure shows a generic error.

The stepper names the step after the definition's title, which VeroCompliance also sends as title on the flow step.

Without a definition. When definition is null, missing or has no questions, or GetAdditionalData fails, the step shows the built-in investor-type question (Individual, Sophisticated, High net worth) and sends { paramName: 'investor_type', value }, exactly as SDK versions before definitions did.

Text. Every title, label and description may be plain text or a $t:key marker. Markers resolve through the SDK's translations, bundled and tenant overrides alike, as backend text does elsewhere in the SDK, and fall back to the raw key when there is no translation. The text is always rendered as plain text, never as HTML.

Documentation

Core Features

Backend Integration

Migration & Changes

  • Migration Guide - Migrate from custom form to dynamic configuration (v1.0.0 → v1.1.0)
  • Changelog - Version history and changes

License

MIT