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

@openvtc/rp-sdk

v0.2.0

Published

Server-side SDK for Relying Parties consuming SIOPv2 id_tokens from the OpenVTC browser plugin

Readme

@openvtc/rp-sdk

Server-side SDK for Relying Parties (RPs) consuming SIOPv2 id_tokens from the OpenVTC browser plugin (window.vtaWallet.login).

What this package does

window.vtaWallet.login() POSTs a SIOPv2 self-issued id_token to your /auth/ endpoint. The token is a compact EdDSA JWS signed by the wallet's holder did:key. The signature is not optional — without verifying it, any page can forge a login as any DID.

This SDK is the audited verification path. verifyIdToken:

  • pins alg to EdDSA (no algorithm substitution),
  • enforces SIOPv2 iss === sub,
  • pins aud to your RP DID (no leniency),
  • pins nonce to the challenge you issued (constant-time match),
  • checks iat / exp within a configurable clock-skew window,
  • resolves the issuer DID and verifies the JWS signature against the resolved Ed25519 verification method.

Failure modes surface as IdTokenVerificationError with a typed reason — log it so operators can distinguish misconfigured audience from a forged token.

Why this exists

The browser-plugin demo skips verification — it trusts whatever the wallet POSTs. The demo is widely copy-pasted into production code, inheriting the gap. The May 2026 OpenVTC security review flagged this as a high-severity issue (H2). This SDK is the fix.

Install

npm install @openvtc/rp-sdk

Usage

Verify an id_token

import { verifyIdToken, KeyResolver } from "@openvtc/rp-sdk";

const resolver = new KeyResolver(); // did:key only; see below

const verified = await verifyIdToken({
  idToken: req.body.id_token,
  audience: process.env.RP_DID!,
  nonce: sessionStore.challengeFor(req.body.session_id),
  resolver,
});

// verified.subject is the wallet's holder DID; bind your session to it.
console.log(`logged in: ${verified.subject}`);

Establish a session cookie

import { establishSession } from "@openvtc/rp-sdk";

const accessToken = await myJwtMinter.mint({ sub: verified.subject });
const { subject, cookie } = establishSession(verified, accessToken);

res.cookie(cookie.name, cookie.value, cookie.options);
// SDK sets HttpOnly + Secure + SameSite=Strict by default.

DID resolvers

The bundled KeyResolver handles did:key:z6Mk… (Ed25519 multikey) in-process — no network round-trip, no cache concerns.

For did:peer:2 (the wallet's default for inbound RP-initiated flows), did:webvh, or did:web — implement the DidResolver interface against your preferred resolver. A thin wrapper around affinidi-did-resolver-cache-sdk covers all of them.

import type { DidResolver } from "@openvtc/rp-sdk";

class MultiMethodResolver implements DidResolver {
  async resolveAuthenticationKey(did: string): Promise<Uint8Array> {
    if (did.startsWith("did:key:")) return keyResolver.resolveAuthenticationKey(did);
    // ... did:peer / did:webvh / did:web cases
  }
}

Roadmap

Planned for follow-up minor versions:

  • requireStepUp() middleware — gates routes behind acr=aal2.
  • refreshProxy() middleware — drop-in /auth/refresh proxy.
  • Express + Fastify + Hono framework adapters.
  • DIDComm-transport variant for RPs that prefer the wallet's authcrypt flow over the REST SIOPv2 flow.

License

Apache-2.0