did-btcr2-js

@did-btcr2/cryptosuite

TypeScript implementation of the Data Integrity BIP340 Cryptosuite v0.1 specification.

Part of the did-btcr2-js monorepo.

Summary

This package produces and verifies the Data Integrity proofs that authenticate every did:btcr2 update. A signed update is a JSON document plus a proof block carrying a BIP-340 Schnorr signature over the JCS-canonicalized payload.

The cryptosuite is what links the abstract Signer interface from @did-btcr2/keypair to the on-disk shape of a signed DID update.

Install

npm install @did-btcr2/cryptosuite

Or with pnpm:

pnpm add @did-btcr2/cryptosuite

Key Exports

Concern Entry point
Build / verify proofs BIP340Cryptosuite, Cryptosuite, VerificationResult
Proof primitive BIP340DataIntegrityProof, DataIntegrityProof, DataIntegrityProofObject
Update payload types UnsignedBTCR2Update, SignedBTCR2Update, BTCR2Update
Verification method wrapper SchnorrMultikey, Multikey, MultikeyObject
Construction helpers FromSecretKey, FromPublicKey, FromPublicKeyMultibaseParams
Cryptosuite config DataIntegrityConfig

Quick Start

Sign an update

import { SchnorrMultikey } from '@did-btcr2/cryptosuite';
import { SchnorrKeyPair } from '@did-btcr2/keypair';

const kp        = SchnorrKeyPair.generate();
const multikey  = SchnorrMultikey.fromSecretKey({
  did : 'did:btcr2:k1q5p...',
  id  : '#initialKey',
  keyPair: kp,
});

const unsigned = { /* UnsignedBTCR2Update: patches + targetHash */ };
const signed   = multikey.toCryptosuite().createProof(unsigned);
// signed.proof.cryptosuite === 'bip340-jcs-2025'

Verify a signed update

import { SchnorrMultikey } from '@did-btcr2/cryptosuite';

// Reconstruct the multikey from the DID verification method.
const multikey = SchnorrMultikey.fromVerificationMethod(verificationMethod);
const result   = multikey.toCryptosuite().verifyProof(signedUpdate);

if (!result.verified) {
  throw new Error(`DI proof failed: ${result.error?.message}`);
}

Sign via an external Signer (HSM, KMS, hardware wallet)

import { SchnorrMultikey } from '@did-btcr2/cryptosuite';

const multikey = SchnorrMultikey.fromPublicKey({
  did     : 'did:btcr2:k1q5p...',
  id      : '#initialKey',
  keyPair : watchOnlyKeyPair,        // public key only
  externalSigner: kmsSigner,         // any Signer implementation
});

const signed = multikey.toCryptosuite().createProof(unsigned);

The cryptosuite validates that externalSigner.publicKey matches the pair at construction time, so a mismatch throws immediately.

Architecture Principles

Build & Test

# From packages/cryptosuite/
pnpm build              # Compile ESM + CJS + type declarations
pnpm build:tests        # Compile tests to tests/compiled/
pnpm test               # Run the test suite with coverage
pnpm lint               # ESLint (zero warnings tolerated)

Documentation