Status: Accepted
Date: 2025-02-19
Commit: ce4da8d
The TypeScript reference implementation of did:btcr2 composes several distinct concerns: cryptographic primitives, DID-document canonicalization, Bitcoin-transaction construction, Sparse Merkle Tree logic, key management, the protocol layer itself, a high-level SDK facade, and a CLI. Packaging all of those as a single flat library had three obvious problems:
did-btcr2 package with everything inside. Simplest to publish; worst for consumer surface and dependency discipline.Option 3. The repo is a pnpm workspace with nine packages under the @did-btcr2/ npm scope, organized by architectural layer:
common : types, canonicalization, hashing, JSON patch, errors
├── keypair : secp256k1 key pairs, BIP340 Schnorr signatures
│ ├── cryptosuite : Data Integrity BIP340 proof creation/verification
│ ├── bitcoin : Bitcoin Core RPC/REST, sans-I/O protocol layers
│ └── kms : key management (generate/import/sign/verify, URN IDs)
├── smt : Optimized Sparse Merkle Tree (no workspace deps)
│
└── method : core did:btcr2: create, resolve, update, beacons
└── api : high-level SDK facade
└── cli : commander.js CLI binary
Inter-package references use the workspace protocol (workspace:^). Dependencies flow strictly downward in the layer graph: no upward imports are permitted.
Positive
common, keypair, cryptosuite, method; no Bitcoin or CLI surface.tsconfig.base.* files so no package can silently relax them.Negative
package.json files to maintain. Version bumps need coordination across packages when they co-evolve (addressed by workspace:^ semver ranges, see ADR 021).Explicitly accepted trade-offs
pnpm-workspace.yaml: workspace package list.tsconfig.base.json: shared TypeScript compiler defaults.