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

@interop/ed25519-signature

v7.1.2

Published

Ed25519 Linked Data / Data Integrity signature suites (Ed25519Signature2020, eddsa-rdfc-2022, eddsa-jcs-2022) in TypeScript.

Readme

@interop/ed25519-signature

Node.js CI NPM Version

Ed25519 Linked Data / Data Integrity signature suites for use with jsonld-signatures, in TypeScript.

One package providing all three Ed25519 Verifiable Credential proof flavors, unified on the DataIntegrityProof container model:

| Suite | proof.type | proof.cryptosuite | Canonicalization | | ---------------------- | ---------------------- | ------------------- | ---------------- | | Ed25519Signature2020 | Ed25519Signature2020 | (absent) | RDFC-1.0 | | eddsa-rdfc-2022 | DataIntegrityProof | eddsa-rdfc-2022 | RDFC-1.0 | | eddsa-jcs-2022 | DataIntegrityProof | eddsa-jcs-2022 | JCS (RFC 8785) |

This is a TypeScript rewrite and rename-in-place of @digitalbazaar/ed25519-signature-2020 (v6). The full design and migration history live in refactor-plan.md; contributor-facing architecture notes are in CLAUDE.md.

Table of Contents

Background

Lets a downstream consumer issue and verify all three Ed25519 proof types -- as they appear mixed in VC proof arrays and DID documents -- through one package, one container concept (DataIntegrityProof), one key library (@interop/ed25519-verification-key, which reads Multikey + 2020 + 2018 + JWK), and one toolchain.

The legacy Ed25519Signature2020 suite is implemented as a thin subclass of DataIntegrityProof rather than a LinkedDataSignature subclass, so the container, key library, and signing payload are shared with the data-integrity suites. Its signed bytes are byte-identical to the legacy @digitalbazaar/ed25519-signature-2020 suite (a pinned acceptance test).

Related spec: Verifiable Credential Data Integrity / EdDSA Cryptosuites.

Install

Node.js 20+ and modern browsers are supported. This package is ESM-only.

npm install @interop/ed25519-signature

@interop/jsonld-signatures is an optional peer dependency -- install it alongside if you use the jsigs.sign / jsigs.verify entry points shown below.

Subpath imports

Each suite has its own subpath export, so a JCS-only consumer is not forced to pull in the heavy jsonld / rdf-canonize machinery that only the RDFC suites need (the package is sideEffects: false for tree-shaking). Prefer the leaf-scoped import for the suite you actually use:

import { Ed25519Signature2020 } from '@interop/ed25519-signature/ed25519-signature-2020'
import { eddsaRdfc2022 } from '@interop/ed25519-signature/eddsa-rdfc-2022'
import {
  createSignCryptosuite,
  createVerifyCryptosuite
} from '@interop/ed25519-signature/eddsa-jcs-2022'

A convenience root barrel re-exports everything (plus createSigner / createVerifier) for when bundle size is not a concern:

import {
  Ed25519Signature2020,
  eddsaRdfc2022,
  createSigner
} from '@interop/ed25519-signature'

Usage

The examples share this setup:

import jsigs from '@interop/jsonld-signatures'
import { Ed25519VerificationKey } from '@interop/ed25519-verification-key'

const {
  purposes: { AssertionProofPurpose }
} = jsigs

const controller = 'https://example.edu/issuers/565049'
const keyPair = await Ed25519VerificationKey.from({
  type: 'Ed25519VerificationKey2020',
  controller,
  id: controller + '#z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T',
  publicKeyMultibase: 'z6MknCCLeeHBUaHu4aHSVLDCYQW9gjVJ7a63FpMvtuVMy53T',
  privateKeyMultibase:
    'zrv2EET2WWZ8T1Jbg4fEH5cQxhbUS22XxdweypUbjWVzv1YD6VqYuW6LH7heQCNYQCuoKaDwvv2qCWz3uBzG2xesqmf'
})

// Provide a documentLoader that resolves the VC contexts, the key, and its
// controller. See test/node/documentLoader.ts for a securityLoader()-based one.

Ed25519Signature2020

A class extending DataIntegrityProof. Pass keyPair.signer() directly -- the constructor injects the required algorithm for you.

import { Ed25519Signature2020 } from '@interop/ed25519-signature/ed25519-signature-2020'

const credential = {
  '@context': [
    'https://www.w3.org/2018/credentials/v1',
    {
      AlumniCredential: 'https://schema.org#AlumniCredential',
      alumniOf: 'https://schema.org#alumniOf'
    },
    'https://w3id.org/security/suites/ed25519-2020/v1'
  ],
  id: 'http://example.edu/credentials/1872',
  type: ['VerifiableCredential', 'AlumniCredential'],
  issuer: controller,
  issuanceDate: '2010-01-01T19:23:24Z',
  credentialSubject: {
    id: 'https://example.edu/students/alice',
    alumniOf: 'Example University'
  }
}

const signed = await jsigs.sign(
  { ...credential },
  {
    suite: new Ed25519Signature2020({ signer: keyPair.signer() }),
    purpose: new AssertionProofPurpose(),
    documentLoader
  }
)
// signed.proof.type === 'Ed25519Signature2020'  (no `cryptosuite` field)

const result = await jsigs.verify(signed, {
  suite: new Ed25519Signature2020(),
  purpose: new AssertionProofPurpose(),
  documentLoader
})
// result.verified === true

eddsa-rdfc-2022

A static cryptosuite object used with a bare DataIntegrityProof. On the sign side, wrap the key with createSigner (see below).

import { DataIntegrityProof } from '@interop/data-integrity-proof'
import { eddsaRdfc2022 } from '@interop/ed25519-signature/eddsa-rdfc-2022'
import { createSigner } from '@interop/ed25519-signature'

// The VC @context must include 'https://w3id.org/security/data-integrity/v2'.
const signed = await jsigs.sign(
  { ...diCredential },
  {
    suite: new DataIntegrityProof({
      cryptosuite: eddsaRdfc2022,
      signer: createSigner(keyPair)
    }),
    purpose: new AssertionProofPurpose(),
    documentLoader
  }
)
// signed.proof.type === 'DataIntegrityProof', signed.proof.cryptosuite === 'eddsa-rdfc-2022'

const result = await jsigs.verify(signed, {
  suite: new DataIntegrityProof({ cryptosuite: eddsaRdfc2022 }),
  purpose: new AssertionProofPurpose(),
  documentLoader
})

eddsa-jcs-2022

Split sign / verify factories (not a single object). The sign cryptosuite's createVerifier throws, as a sign-only guard.

import { DataIntegrityProof } from '@interop/data-integrity-proof'
import {
  createSignCryptosuite,
  createVerifyCryptosuite
} from '@interop/ed25519-signature/eddsa-jcs-2022'
import { createSigner } from '@interop/ed25519-signature'

const signed = await jsigs.sign(
  { ...diCredential },
  {
    suite: new DataIntegrityProof({
      cryptosuite: createSignCryptosuite(),
      signer: createSigner(keyPair)
    }),
    purpose: new AssertionProofPurpose(),
    documentLoader
  }
)
// signed.proof.cryptosuite === 'eddsa-jcs-2022'

const result = await jsigs.verify(signed, {
  suite: new DataIntegrityProof({ cryptosuite: createVerifyCryptosuite() }),
  purpose: new AssertionProofPurpose(),
  documentLoader
})

JCS verification enforces the spec's context-prefix ordering check: the document's @context must start with the proof's @context, in order.

Verifying a mixed proof set

A single VC can carry one of each proof type in its proof array; pass all the matching suites to one jsigs.verify call and they are disambiguated by matchProof:

const result = await jsigs.verify(signed, {
  suite: [
    new Ed25519Signature2020(),
    new DataIntegrityProof({ cryptosuite: eddsaRdfc2022 }),
    new DataIntegrityProof({ cryptosuite: createVerifyCryptosuite() })
  ],
  purpose: new AssertionProofPurpose(),
  documentLoader
})

Note the proof-set semantics of jsonld-signatures: result.verified is true if any matched proof verifies. Inspect result.results for the per-proof outcome.

API asymmetry across suites

The three suites expose deliberately different shapes, because the specs do -- a class (Ed25519Signature2020), a static cryptosuite object (eddsa-rdfc-2022), and sign/verify factories (eddsa-jcs-2022). This is intentional; don't try to abstract over it.

The createSigner requirement

DataIntegrityProof asserts signer.algorithm === 'Ed25519' at construction. In the Digital Bazaar ecosystem the key library supplies that property; @interop/ed25519-verification-key does not (yet), so when using a bare DataIntegrityProof (the rdfc / jcs suites) wrap the key with createSigner:

import { createSigner } from '@interop/ed25519-signature'
new DataIntegrityProof({
  cryptosuite: eddsaRdfc2022,
  signer: createSigner(keyPair)
})

The Ed25519Signature2020 class does this for you, so there you can pass keyPair.signer() directly. createSigner is idempotent (algorithm ?? 'Ed25519'), so it becomes a no-op once the key library sets algorithm itself.

Contribute

PRs accepted. See CLAUDE.md for toolchain, project layout, and the testing rules (notably: never hand-roll JSON-LD @context documents in tests).

License

New BSD License (3-clause)