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

@credenceid/online-verifier

v0.1.4

Published

A framework-agnostic frontend SDK for identity verification

Readme

@credenceid/online-verifier

A framework-agnostic frontend SDK for integrating identity verification directly into your web applications. Built with native Web Components and TypeScript, it allows you to securely verify user identities using multiple protocols: DC API (ISO 18013-5 mdoc), Google Wallet (OpenID4VP), W3C OpenID4VP (cross-device / QR code), and Annex B OID4VP mdoc.

Because it utilizes native HTML Web Components, it works seamlessly out-of-the-box with Vanilla JS, React, Vue, Angular, Svelte, and more.

Features

  • Framework Agnostic: Drop it into any frontend stack.
  • Multiple Verification Protocols: DC API (mdoc), Google Wallet (OpenID4VP), W3C OpenID4VP (QR / cross-device), and Annex B OID4VP mdoc.
  • Headless Styling: Bring your own CSS. The SDK provides the logic and a clean DOM element; you control the look and feel.
  • Secure by Design: Handles token lifecycle, silent background refreshes, and domain validation automatically.
  • Normalized Responses: All protocols return the same ParsedVerificationResult shape — no per-protocol response parsing needed.
  • Annex B Auto-Resume: Automatically detects wallet redirect codes on page load and resumes sessions in the background.

Installation

npm install @credenceid/online-verifier
# or
yarn add @credenceid/online-verifier

Local Development & Testing

If you want to test the SDK locally before publishing (e.g., when iterating on changes), you can build and pack it into a .tgz tarball and install it directly into any local project.

1. Build the SDK

npm run build

This compiles the TypeScript source and outputs the distributable files to the dist/ directory.

2. Pack the SDK

npm pack

This creates a versioned tarball (e.g., credenceid-online-verifier-0.1.0.tgz) in the current directory. The file contains exactly what would be published to npm.

3. Install the tarball in your project

In the consuming project, install the generated .tgz file using its path:

npm install /path/to/credenceid-online-verifier-1.0.0.tgz

Or using a relative path:

npm install ../Online-verifier-SDK/credenceid-online-verifier-1.0.0.tgz

The SDK will be available under the @credenceid/online-verifier package name, exactly as it would be after an npm registry install.


Environment Configuration

Before running the SDK locally or building for a target environment, create a .env file in the project root and set the backend URL:

# .env  (project root)
OV_API_BASE_URL=https://credenceid.com/cloudsdk/playground/

| Variable | Required | Description | |-------------------|----------|-----------------------------------------------------------------------------| | OV_API_BASE_URL | Yes | Base URL of the Online Verifier backend. All API calls are resolved against this URL. |

Note: The .env file is listed in .gitignore — never commit it. Each developer or deployment environment must supply its own copy.

Local development example

OV_API_BASE_URL=http://localhost:8080

QA example

OV_API_BASE_URL=https://credenceid.com/cloudsdkdev

After creating or updating .env, rebuild the SDK (npm run build) so the variable is picked up by the bundler.


Quick Start

1. Initialize the SDK

Before rendering any UI component, initialize the global VerifierSDK singleton with your CredenceID credentials. This authenticates your domain with the backend.

import { VerifierSDK } from '@credenceid/online-verifier';

VerifierSDK.init({
  licenseKey: 'YOUR_LICENSE_KEY',
  profileId: 'YOUR_PROFILE_ID'
}).then(() => {
  console.log('SDK initialized successfully.');
}).catch((error) => {
  console.error('SDK initialization failed:', error);
});

2. Add a UI Component

Place the desired custom element anywhere in your DOM:

<!-- ISO 18013-5 mdoc via browser DC API -->
<ov-dcapi-btn text="Verify with Mobile ID" class="my-btn"></ov-dcapi-btn>

<!-- Google Wallet (OpenID4VP v1) -->
<ov-google-wallet-btn text="Verify with Google Wallet" class="my-btn"></ov-google-wallet-btn>

<!-- W3C OpenID4VP — shows a deep link for cross-device / QR flows -->
<ov-w3c-btn text="Verify via QR Code" class="my-btn"></ov-w3c-btn>

<!-- Annex B OID4VP mdoc — shows a deep link / QR code -->
<ov-annex-b-btn text="Verify with Wallet App" class="my-btn"></ov-annex-b-btn>

3. Listen for Results

All components emit the same DOM events:

const btn = document.querySelector('ov-dcapi-btn');

btn.addEventListener('ov-success', (event) => {
  const result = event.detail; // ParsedVerificationResult
  console.log('Name:', result.claims.given_name);
  if (result.portrait) {
    document.querySelector('img').src = result.portrait;
  }
});

btn.addEventListener('ov-error', (event) => {
  console.error('Verification failed:', event.detail.message);
});

Verification Protocols

1. DC API — <ov-dcapi-btn> (ISO 18013-5 mdoc)

Uses the browser's native navigator.credentials.get Digital Credentials API. Requires a compatible browser and a wallet app installed on the same device.

<ov-dcapi-btn text="Verify with Mobile ID" class="my-btn"></ov-dcapi-btn>

2. Google Wallet — <ov-google-wallet-btn> (OpenID4VP v1 Unsigned)

Uses navigator.credentials.get with the openid4vp-v1-unsigned protocol, targeting Google Wallet on Android.

<ov-google-wallet-btn text="Verify with Google Wallet" class="my-btn"></ov-google-wallet-btn>

3. W3C OpenID4VP — <ov-w3c-btn> (Cross-Device / QR Code)

Initiates a cross-device flow. The component:

  1. Calls the backend to get a session ID and an openid4vp:// authorization URI.
  2. Emits ov-uri-ready so you can render a QR code.
  3. Shows a "Tap to Open Wallet App" deep link for mobile users.
  4. Polls the backend every second (up to 300 attempts = 5mins) until the wallet responds.
<ov-w3c-btn text="Scan QR to Verify" class="my-btn"></ov-w3c-btn>
const btn = document.querySelector('ov-w3c-btn');

// Use this event to render a QR code with a library of your choice
btn.addEventListener('ov-uri-ready', (event) => {
  const { uri } = event.detail;
  renderQRCode(uri); // e.g. using qrcode.js
});

btn.addEventListener('ov-success', (event) => {
  console.log('Verified:', event.detail.claims);
});

Or via the callback property:

btn.onUriReady = (uri) => renderQRCode(uri);

4. Annex B OID4VP mdoc — <ov-annex-b-btn>

Similar to the W3C flow but uses the Annex B mdoc protocol. The component initiates a session and shows a wallet deep link. It also supports a redirect-based return flow — when the wallet redirects back to your page with a ?response_code= parameter, the SDK automatically resumes the session on init().

<ov-annex-b-btn text="Verify with Wallet" class="my-btn"></ov-annex-b-btn>
const btn = document.querySelector('ov-annex-b-btn');

btn.addEventListener('ov-uri-ready', (event) => {
  renderQRCode(event.detail.uri);
});

btn.addEventListener('ov-success', (event) => {
  console.log('Verified:', event.detail.claims);
});

Annex B Redirect Resume

If the wallet redirects back to your page instead of posting a response, the SDK detects the ?response_code= query parameter automatically during VerifierSDK.init(), cleans the URL, and dispatches one of these global window events:

window.addEventListener('ov-resume-success', (event) => {
  const result = event.detail; // ParsedVerificationResult
  console.log('Resumed verification:', result.claims);
});

window.addEventListener('ov-resume-error', (event) => {
  console.error('Resume failed:', event.detail);
});

No additional setup is required — just listen for these events before calling VerifierSDK.init().


Response Format — ParsedVerificationResult

Every ov-success event and every VerifierClient method returns the same normalized object, regardless of protocol:

interface ParsedVerificationResult {
  success: boolean;
  portrait?: string;      // Ready-to-use base64 data URI: `data:image/jpeg;base64,...`
  claims: IdentityClaims; // Identity attributes (given_name, family_name, birth_date, etc.)
  authStatus: AuthVerificationDetails; // Cryptographic / authentication metadata
  raw: any;               // Original backend response, unmodified
}

Portrait images (portrait, photo, image, picture, face_portrait) are automatically extracted from claims and promoted to the top-level portrait field as a formatted data:image/jpeg;base64,... URI:

btn.addEventListener('ov-success', (event) => {
  const { claims, portrait, authStatus } = event.detail;

  document.querySelector('#name').textContent = claims.given_name;

  if (portrait) {
    document.querySelector('#photo').src = portrait;
  }
});

ResponseFormatter Utility

ResponseFormatter is exported and can be used standalone to parse raw backend responses or format label keys for display.

import { ResponseFormatter } from '@credenceid/online-verifier';

// Parse a raw backend response into a normalized object
const result = ResponseFormatter.parseVerificationResponse(rawData);

// Convert a claim key to a human-readable label
ResponseFormatter.formatLabel('given_name');  // → "Given Name"
ResponseFormatter.formatLabel('birthDate');   // → "Birth Date"

Styling

All components render in the Light DOM, so your global CSS cascades directly into them.

During a verification the component adds an .ov-loading class to the button and disables it. The button text also changes to reflect the current step (Initiating...Waiting for Wallet...).

/* Style to match your brand */
.my-btn {
  background-color: #0f172a;
  color: white;
  padding: 12px 24px;
  border-radius: 6px;
  border: none;
  font-weight: 600;
  cursor: pointer;
}

/* Loading / in-progress state */
.my-btn.ov-loading {
  opacity: 0.7;
  cursor: wait;
}

React Integration

React uses a synthetic event system, so use a useRef to attach the callback properties directly on the element.

TypeScript Setup

Augment the React JSX namespace in your types.d.ts or vite-env.d.ts:

import React from 'react';

declare module 'react' {
  namespace JSX {
    interface IntrinsicElements {
      'ov-dcapi-btn':         React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & { text?: string; class?: string; };
      'ov-google-wallet-btn': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & { text?: string; class?: string; };
      'ov-w3c-btn':           React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & { text?: string; class?: string; };
      'ov-annex-b-btn':       React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & { text?: string; class?: string; };
    }
  }
}

Component Example

import React, { useEffect, useRef, useState } from 'react';
import { VerifierSDK, ParsedVerificationResult } from '@credenceid/online-verifier';

export const VerifyButton = () => {
  const btnRef = useRef<any>(null);
  const [isReady, setIsReady] = useState(false);

  useEffect(() => {
    VerifierSDK.init({
      licenseKey: 'YOUR_LICENSE_KEY',
      profileId: 'YOUR_PROFILE_ID',
    }).then(() => setIsReady(true))
      .catch(err => console.error('Setup failed:', err));
  }, []);

  useEffect(() => {
    if (!btnRef.current) return;

    btnRef.current.onVerificationSuccess = (result: ParsedVerificationResult) => {
      console.log('Verified:', result.claims);
    };

    btnRef.current.onVerificationError = (error: Error) => {
      console.error('Error:', error.message);
    };

    // For W3C / Annex B buttons, also handle the URI ready callback:
    // btnRef.current.onUriReady = (uri: string) => renderQRCode(uri);
  }, [isReady]);

  return (
    <ov-dcapi-btn ref={btnRef} text="Verify with Mobile ID" class="my-btn" />
  );
};

API Reference

VerifierSDK.init(config)

Authenticates the SDK and validates your domain. Automatically handles Annex B redirect resumes via ?response_code= URL parameters.

| Parameter | Type | Description | |--------------|----------|--------------------------------------| | licenseKey | string | Your assigned license key. | | profileId | string | The verification profile to execute. |

Returns: Promise<void> — throws if domain validation fails.


Web Components

| Tag | Default Text | Protocol | |------------------------|--------------------------|--------------------------------| | <ov-dcapi-btn> | "Verify with Mobile ID"| DC API — ISO 18013-5 mdoc | | <ov-google-wallet-btn> | "Verify with Google Wallet" | OpenID4VP v1 Unsigned (Google Wallet) | | <ov-w3c-btn> | "W3C OpenID4VP" | W3C OpenID4VP (cross-device) | | <ov-annex-b-btn> | "Annex B mdoc" | Annex B OID4VP mdoc |

Shared Attributes

| Attribute | Type | Description | |-----------|----------|------------------------------------| | text | string | Overrides the default button label.| | class | string | Standard CSS class(es). |

Shared Events & Callbacks

| DOM Event | JS Callback | Payload | Description | |--------------|---------------------------|--------------------------|-----------------------------------------------------| | ov-success | onVerificationSuccess | ParsedVerificationResult | Verification completed and backend-validated. | | ov-error | onVerificationError | Error | User cancelled, or backend validation failed. |

W3C & Annex B Only

| DOM Event | JS Callback | Payload | Description | |----------------|--------------|-----------------|----------------------------------------------------------| | ov-uri-ready | onUriReady | { uri: string } | The openid4vp:// URI is ready. Use it to render a QR code. |

Global Window Events (Annex B redirect resume)

| Event | Payload | Description | |--------------------|----------------------------|----------------------------------------------| | ov-resume-success| ParsedVerificationResult | Annex B redirect session resumed successfully.| | ov-resume-error | Error | Annex B redirect resume failed. |


VerifierClient Methods

These are accessible via window.VerifierSDK.client or by importing VerifierClient directly. All methods return Promise<ParsedVerificationResult>.

| Method | Description | |----------------------------------------------|----------------------------------------------------------| | verifyDCApi() | DC API flow (same-device, ISO 18013-5 mdoc). | | verifyGoogleWallet() | Google Wallet flow (OpenID4VP v1 Unsigned). | | initiateW3cOpenId() | Starts a W3C session. Returns { sessionId, authUri }. | | pollW3cResult(sessionId, maxAttempts?) | Polls until wallet responds or times out (default 120s). | | initiateAnnexB() | Starts an Annex B session. Returns { sessionId, walletUri }. | | pollAnnexBResult(sessionId, maxAttempts?) | Polls until wallet responds or times out (default 120s). | | resumeAnnexB(responseCode) | Resumes an Annex B session from a redirect response code.|


ResponseFormatter

| Method | Description | |--------------------------------------------|--------------------------------------------------------------| | parseVerificationResponse(rawResponse) | Normalizes DC API, W3C, and Annex B responses into ParsedVerificationResult. | | formatLabel(key) | Converts snake_case or camelCase keys to Title Case for UI display. |