@did-btcr2/method 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"did-btcr2.js","sourceRoot":"","sources":["../../src/did-btcr2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"did-btcr2.js","sourceRoot":"","sources":["../../src/did-btcr2.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,28 @@ export interface CASBroadcastOptions extends BroadcastOptions {
23
23
  * During resolution, the CAS Announcement is retrieved from the sidecar (or CAS)
24
24
  * and used to look up the individual signed update for the DID being resolved.
25
25
  *
26
+ * ## CAS announcement hash chain
27
+ *
28
+ * Resolution links an on-chain signal to a signed update through two hashes, with
29
+ * an encoding transition at each hop. The write path ({@link broadcastSignal})
30
+ * produces both hashes; the read path ({@link processSignals}) re-derives them:
31
+ *
32
+ * 1. **Signal hop.** The OP_RETURN payload is `canonicalHash(announcement)` in
33
+ * **hex**: this is `signal.signalBytes` and the lookup key into `sidecar.casMap`.
34
+ * Broadcast emits `hash(canonicalize(announcement))`; the resolver keys `casMap`
35
+ * by `canonicalHash(announcement, { encoding: 'hex' })`. These are the same bytes,
36
+ * so `signalBytes === canonicalHash(announcement, hex)`.
37
+ * 2. **Update hop.** Each `announcement[did]` is `canonicalHash(signedUpdate)` in
38
+ * **base64urlnopad** (per spec). It is decoded back to **hex** to key
39
+ * `sidecar.updateMap`, so `hex(decode(announcement[did])) === canonicalHash(signedUpdate, hex)`.
40
+ *
41
+ * Both links are enforced when sidecar data is supplied via `Resolver.provide()`
42
+ * (which validates the provided announcement and update against the need's hash),
43
+ * and structurally when sidecar maps are pre-loaded (they are keyed by
44
+ * `canonicalHash`, so a mismatched entry simply misses the lookup). The two
45
+ * encoding transitions (hex for on-chain and map keys, base64urlnopad for
46
+ * announcement values) are the subtle part: a regression test pins them.
47
+ *
26
48
  * @class CASBeacon
27
49
  * @type {CASBeacon}
28
50
  * @extends {SinglePartyBeacon}
@@ -1 +1 @@
1
- {"version":3,"file":"cas-beacon.d.ts","sourceRoot":"","sources":["../../../../src/core/beacon/cas-beacon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAY,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAiB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEhG;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,SAAU,SAAQ,iBAAiB;IAC9C;;;OAGG;gBACS,OAAO,EAAE,aAAa;IAIlC;;;;;;;;;;;;OAYG;IACH,cAAc,CACZ,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,EAC5B,OAAO,EAAE,WAAW,GACnB,mBAAmB;IAsDtB;;;;;;;;;;;;;;;OAeG;IACG,eAAe,CACnB,YAAY,EAAE,iBAAiB,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,iBAAiB,CAAC;CAuB9B"}
1
+ {"version":3,"file":"cas-beacon.d.ts","sourceRoot":"","sources":["../../../../src/core/beacon/cas-beacon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAY,MAAM,gBAAgB,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAiB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEhG;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,SAAU,SAAQ,iBAAiB;IAC9C;;;OAGG;gBACS,OAAO,EAAE,aAAa;IAIlC;;;;;;;;;;;;OAYG;IACH,cAAc,CACZ,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,EAC5B,OAAO,EAAE,WAAW,GACnB,mBAAmB;IAsDtB;;;;;;;;;;;;;;;OAeG;IACG,eAAe,CACnB,YAAY,EAAE,iBAAiB,EAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,iBAAiB,CAAC;CAuB9B"}
@@ -1,5 +1,19 @@
1
1
  import type { BitcoinConnection } from '@did-btcr2/bitcoin';
2
2
  import type { BeaconService, BeaconSignal } from './interfaces.js';
3
+ /**
4
+ * Parses a scriptPubKey asm string and returns the beacon signal hash if and only
5
+ * if the output is exactly `OP_RETURN OP_PUSHBYTES_32 <32-byte hex>`.
6
+ *
7
+ * Beacon signals encode a single 32-byte update or announcement hash in an
8
+ * OP_RETURN data push. Any other shape (a bare `OP_RETURN`, a push of the wrong
9
+ * size, or a non-hex payload) is not a valid signal and returns `null`, so a
10
+ * malformed or adversarial on-chain output cannot be mistaken for a real signal
11
+ * downstream.
12
+ *
13
+ * @param {string | undefined} asm The scriptPubKey asm string to parse.
14
+ * @returns {string | null} The lowercased 32-byte hex hash, or `null` if not a valid signal.
15
+ */
16
+ export declare function extractOpReturnSignal(asm: string | undefined): string | null;
3
17
  /**
4
18
  * Static utility class for discovering Beacon Signals on the Bitcoin blockchain.
5
19
  * Extracted from `Resolver` for single-responsibility and independent testability.
@@ -1 +1 @@
1
- {"version":3,"file":"signal-discovery.d.ts","sourceRoot":"","sources":["../../../../src/core/beacon/signal-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEA,MAAM,oBAAoB,CAAC;AAM9C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE;;;;;GAKG;AACH,qBAAa,qBAAqB;IAEhC;;;;;;OAMG;WACU,OAAO,CAClB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,EACpC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IA0EnD;;;;;OAKG;WACU,QAAQ,CACnB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,EACpC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;CA4HpD"}
1
+ {"version":3,"file":"signal-discovery.d.ts","sourceRoot":"","sources":["../../../../src/core/beacon/signal-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEA,MAAM,oBAAoB,CAAC;AAM9C,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAmB5E;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB;IAEhC;;;;;;OAMG;WACU,OAAO,CAClB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,EACpC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IAiEnD;;;;;OAKG;WACU,QAAQ,CACnB,cAAc,EAAE,KAAK,CAAC,aAAa,CAAC,EACpC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;CAyHpD"}
@@ -31,6 +31,13 @@ export interface ResolutionOptions extends DidResolutionOptions {
31
31
  * Includes Singleton beacon updates, CAS announcements, and SMT proofs.
32
32
  */
33
33
  sidecar?: Sidecar;
34
+ /**
35
+ * Maximum number of multi-round beacon-discovery passes before resolution
36
+ * fails. Each pass applies the updates found so far, then looks for new beacon
37
+ * services those updates added. A document whose updates keep adding beacon
38
+ * services would otherwise drive discovery without bound. Default: 10.
39
+ */
40
+ maxDiscoveryRounds?: number;
34
41
  }
35
42
  /**
36
43
  * {@link https://dcdpr.github.io/did-btcr2/terminology.html#smt-proof | SMT Proof}
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../src/core/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../src/core/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAkB,SAAQ,oBAAoB;IAC7D;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
@@ -4,6 +4,13 @@ import type { BeaconService, BeaconSignal, BlockMetadata } from './beacon/interf
4
4
  import type { DidComponents } from './identifier.js';
5
5
  import type { SMTProof } from './interfaces.js';
6
6
  import type { CASAnnouncement, Sidecar, SidecarData } from './types.js';
7
+ /**
8
+ * Default upper bound on multi-round beacon discovery. Each round applies the
9
+ * updates found so far and looks for beacon services those updates added; a
10
+ * document whose updates keep adding services would otherwise loop unbounded.
11
+ * Overridable via `ResolutionOptions.maxDiscoveryRounds`.
12
+ */
13
+ export declare const DEFAULT_MAX_DISCOVERY_ROUNDS = 10;
7
14
  /**
8
15
  * The response object for DID Resolution.
9
16
  */
@@ -105,6 +112,7 @@ export declare class Resolver {
105
112
  versionId?: string;
106
113
  versionTime?: string;
107
114
  genesisDocument?: object;
115
+ maxDiscoveryRounds?: number;
108
116
  });
109
117
  /**
110
118
  * Implements subsection {@link https://dcdpr.github.io/did-btcr2/operations/resolve.html#if-genesis_bytes-is-a-secp256k1-public-key | 7.2.d.1 if genesis bytes is a secp256k1 Public Key}.
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../src/core/resolver.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"did-btcr2.d.ts","sourceRoot":"","sources":["../../src/did-btcr2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAS3C,OAAO,KAAK,EACV,SAAS,EAAC,MAAM,YAAY,CAAC;AAQ/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEvF,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,YAAW,SAAS;IACxC;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,CAAW;IAEpC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,GAAG,aAAa,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAezF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,OAAO,CACZ,GAAG,EAAE,MAAM,EACX,iBAAiB,GAAE,iBAAsB,GACxC,QAAQ;IAsBX;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,MAAM,CAAC,EACZ,cAAc,EACd,OAAO,EACP,eAAe,EACf,oBAAoB,EACpB,QAAQ,GACT,EAAE;QACD,cAAc,EAAE,gBAAgB,CAAC;QACjC,OAAO,EAAE,cAAc,EAAE,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO;IA2DX;;;;;;;;;OASG;IACH,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,EAAG,QAAQ,CAAC,EAAE,MAAM,GAAG,qBAAqB;CA0BlG"}
1
+ {"version":3,"file":"did-btcr2.d.ts","sourceRoot":"","sources":["../../src/did-btcr2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,QAAQ,EACR,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAS3C,OAAO,KAAK,EACV,SAAS,EAAC,MAAM,YAAY,CAAC;AAQ/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEvF,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,YAAW,SAAS;IACxC;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,CAAW;IAEpC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,GAAG,aAAa,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAezF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,OAAO,CACZ,GAAG,EAAE,MAAM,EACX,iBAAiB,GAAE,iBAAsB,GACxC,QAAQ;IAuBX;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,MAAM,CAAC,MAAM,CAAC,EACZ,cAAc,EACd,OAAO,EACP,eAAe,EACf,oBAAoB,EACpB,QAAQ,GACT,EAAE;QACD,cAAc,EAAE,gBAAgB,CAAC;QACjC,OAAO,EAAE,cAAc,EAAE,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO;IA2DX;;;;;;;;;OASG;IACH,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,EAAG,QAAQ,CAAC,EAAE,MAAM,GAAG,qBAAqB;CA0BlG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@did-btcr2/method",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "type": "module",
5
5
  "description": "Reference implementation for the did:btcr2 DID method written in TypeScript and JavaScript. did:btcr2 is a censorship resistant DID Method using the Bitcoin blockchain as a Verifiable Data Registry to announce changes to the DID document. This is the core method implementation for the did-btcr2-js monorepo.",
6
6
  "main": "./dist/cjs/index.js",
@@ -80,11 +80,11 @@
80
80
  "helia": "^5.5.1",
81
81
  "multiformats": "^13.4.2",
82
82
  "nostr-tools": "^2.23.3",
83
- "@did-btcr2/cryptosuite": "^9.0.0",
84
83
  "@did-btcr2/bitcoin": "^0.8.0",
85
84
  "@did-btcr2/common": "^9.1.0",
86
- "@did-btcr2/smt": "^0.3.0",
87
- "@did-btcr2/keypair": "^0.13.1"
85
+ "@did-btcr2/keypair": "^0.13.1",
86
+ "@did-btcr2/cryptosuite": "^9.0.0",
87
+ "@did-btcr2/smt": "^0.3.0"
88
88
  },
89
89
  "devDependencies": {
90
90
  "@eslint/js": "^9.39.4",
@@ -26,6 +26,28 @@ export interface CASBroadcastOptions extends BroadcastOptions {
26
26
  * During resolution, the CAS Announcement is retrieved from the sidecar (or CAS)
27
27
  * and used to look up the individual signed update for the DID being resolved.
28
28
  *
29
+ * ## CAS announcement hash chain
30
+ *
31
+ * Resolution links an on-chain signal to a signed update through two hashes, with
32
+ * an encoding transition at each hop. The write path ({@link broadcastSignal})
33
+ * produces both hashes; the read path ({@link processSignals}) re-derives them:
34
+ *
35
+ * 1. **Signal hop.** The OP_RETURN payload is `canonicalHash(announcement)` in
36
+ * **hex**: this is `signal.signalBytes` and the lookup key into `sidecar.casMap`.
37
+ * Broadcast emits `hash(canonicalize(announcement))`; the resolver keys `casMap`
38
+ * by `canonicalHash(announcement, { encoding: 'hex' })`. These are the same bytes,
39
+ * so `signalBytes === canonicalHash(announcement, hex)`.
40
+ * 2. **Update hop.** Each `announcement[did]` is `canonicalHash(signedUpdate)` in
41
+ * **base64urlnopad** (per spec). It is decoded back to **hex** to key
42
+ * `sidecar.updateMap`, so `hex(decode(announcement[did])) === canonicalHash(signedUpdate, hex)`.
43
+ *
44
+ * Both links are enforced when sidecar data is supplied via `Resolver.provide()`
45
+ * (which validates the provided announcement and update against the need's hash),
46
+ * and structurally when sidecar maps are pre-loaded (they are keyed by
47
+ * `canonicalHash`, so a mismatched entry simply misses the lookup). The two
48
+ * encoding transitions (hex for on-chain and map keys, base64urlnopad for
49
+ * announcement values) are the subtle part: a regression test pins them.
50
+ *
29
51
  * @class CASBeacon
30
52
  * @type {CASBeacon}
31
53
  * @extends {SinglePartyBeacon}
@@ -10,6 +10,40 @@ import { ResolveError } from '@did-btcr2/common';
10
10
  import type { BeaconService, BeaconSignal } from './interfaces.js';
11
11
  import { BeaconUtils } from './utils.js';
12
12
 
13
+ /**
14
+ * Parses a scriptPubKey asm string and returns the beacon signal hash if and only
15
+ * if the output is exactly `OP_RETURN OP_PUSHBYTES_32 <32-byte hex>`.
16
+ *
17
+ * Beacon signals encode a single 32-byte update or announcement hash in an
18
+ * OP_RETURN data push. Any other shape (a bare `OP_RETURN`, a push of the wrong
19
+ * size, or a non-hex payload) is not a valid signal and returns `null`, so a
20
+ * malformed or adversarial on-chain output cannot be mistaken for a real signal
21
+ * downstream.
22
+ *
23
+ * @param {string | undefined} asm The scriptPubKey asm string to parse.
24
+ * @returns {string | null} The lowercased 32-byte hex hash, or `null` if not a valid signal.
25
+ */
26
+ export function extractOpReturnSignal(asm: string | undefined): string | null {
27
+ if(!asm) {
28
+ return null;
29
+ }
30
+
31
+ // A standard NULL_DATA beacon output is exactly three asm tokens: the OP_RETURN
32
+ // opcode, the 32-byte push opcode, and the 64-character hex payload.
33
+ const tokens = asm.trim().split(/\s+/);
34
+ if(tokens.length !== 3 || tokens[0] !== 'OP_RETURN' || tokens[1] !== 'OP_PUSHBYTES_32') {
35
+ return null;
36
+ }
37
+
38
+ // The payload must be exactly 32 bytes of hex (64 hex characters).
39
+ const signalHash = tokens[2];
40
+ if(!/^[0-9a-fA-F]{64}$/.test(signalHash)) {
41
+ return null;
42
+ }
43
+
44
+ return signalHash.toLowerCase();
45
+ }
46
+
13
47
  /**
14
48
  * Static utility class for discovering Beacon Signals on the Bitcoin blockchain.
15
49
  * Extracted from `Resolver` for single-responsibility and independent testability.
@@ -62,23 +96,14 @@ export class BeaconSignalDiscovery {
62
96
  * value: 0
63
97
  * }
64
98
  */
65
- if(!signalVout || !signalVout.scriptpubkey_asm.includes('OP_RETURN')) {
66
- continue;
67
- }
68
-
69
- // Construct output map for easier access
70
- const outputMap = new Map<string, string | number>(Object.entries(signalVout));
71
-
72
- // Grab the signal vout scriptpubkey
73
- const signalVoutScriptPubkey = outputMap.get('scriptpubkey_asm') as string;
74
-
75
- // If the signal vout scriptpubkey does not exist, continue to next signal
76
- if(!signalVoutScriptPubkey){
99
+ if(!signalVout) {
77
100
  continue;
78
101
  }
79
102
 
80
- // Extract hex string hash of the signal bytes from the scriptpubkey
81
- const updateHash = signalVoutScriptPubkey.split(' ').slice(-1)[0];
103
+ // A beacon signal output must be exactly `OP_RETURN OP_PUSHBYTES_32 <32-byte hash>`.
104
+ // Reject any other shape (bare OP_RETURN, wrong push size, non-hex payload) so a
105
+ // malformed on-chain output cannot masquerade as a phantom signal downstream.
106
+ const updateHash = extractOpReturnSignal(signalVout.scriptpubkey_asm);
82
107
  if(!updateHash) {
83
108
  continue;
84
109
  }
@@ -192,21 +217,18 @@ export class BeaconSignalDiscovery {
192
217
  continue;
193
218
  }
194
219
 
195
- // Look for 'OP_RETURN' in the scriptPubKey asm
220
+ // A beacon signal output must be exactly `OP_RETURN OP_PUSHBYTES_32 <32-byte hash>`.
221
+ // Reject any other shape so a malformed on-chain output cannot masquerade as a
222
+ // phantom signal downstream.
196
223
  const txVoutScriptPubkeyAsm = prevout.vout[vin.vout].scriptPubKey.asm;
197
- if(!txVoutScriptPubkeyAsm.includes('OP_RETURN')) {
224
+ const updateHash = extractOpReturnSignal(txVoutScriptPubkeyAsm);
225
+ if(!updateHash) {
198
226
  continue;
199
227
  }
200
228
 
201
229
  // Log the found txid and beacon
202
230
  console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
203
231
 
204
- // Extract hex string hash of the signal bytes from the scriptpubkey
205
- const updateHash = txVoutScriptPubkeyAsm.split(' ').slice(-1)[0];
206
- if(!updateHash) {
207
- continue;
208
- }
209
-
210
232
  // Push the beacon signal object to the beacon signals array for that beacon service
211
233
  beaconServiceSignals.get(beaconService)?.push({
212
234
  tx,
@@ -35,6 +35,14 @@ export interface ResolutionOptions extends DidResolutionOptions {
35
35
  * Includes Singleton beacon updates, CAS announcements, and SMT proofs.
36
36
  */
37
37
  sidecar?: Sidecar;
38
+
39
+ /**
40
+ * Maximum number of multi-round beacon-discovery passes before resolution
41
+ * fails. Each pass applies the updates found so far, then looks for new beacon
42
+ * services those updates added. A document whose updates keep adding beacon
43
+ * services would otherwise drive discovery without bound. Default: 10.
44
+ */
45
+ maxDiscoveryRounds?: number;
38
46
  }
39
47
 
40
48
  /**
@@ -36,6 +36,14 @@ import type { SMTProof } from './interfaces.js';
36
36
  import type { CASAnnouncement, Sidecar, SidecarData } from './types.js';
37
37
  import { equalBytes } from '@noble/curves/utils.js';
38
38
 
39
+ /**
40
+ * Default upper bound on multi-round beacon discovery. Each round applies the
41
+ * updates found so far and looks for beacon services those updates added; a
42
+ * document whose updates keep adding services would otherwise loop unbounded.
43
+ * Overridable via `ResolutionOptions.maxDiscoveryRounds`.
44
+ */
45
+ export const DEFAULT_MAX_DISCOVERY_ROUNDS = 10;
46
+
39
47
  /**
40
48
  * The response object for DID Resolution.
41
49
  */
@@ -111,6 +119,38 @@ export interface BeaconProcessResult {
111
119
  needs: Array<DataNeed>;
112
120
  }
113
121
 
122
+ // ─── provide() payload guards ────────────────────────────────────────────────
123
+ // Runtime shape checks so a malformed payload fails fast at the provide()
124
+ // boundary rather than flowing downstream as an unchecked `as` cast.
125
+
126
+ /** True if `value` is a non-null, non-array object. */
127
+ function isRecord(value: unknown): value is Record<string, unknown> {
128
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
129
+ }
130
+
131
+ /** True if `value` has the shape of a CAS Announcement (a flat record of string hashes). */
132
+ function isCASAnnouncement(value: unknown): value is CASAnnouncement {
133
+ return isRecord(value) && Object.values(value).every(v => typeof v === 'string');
134
+ }
135
+
136
+ /** True if `value` has the shape of a signed BTCR2 update. */
137
+ function isSignedBTCR2Update(value: unknown): value is SignedBTCR2Update {
138
+ if(!isRecord(value)) return false;
139
+ return Array.isArray(value.patch)
140
+ && typeof value.sourceHash === 'string'
141
+ && typeof value.targetHash === 'string'
142
+ && typeof value.targetVersionId === 'number'
143
+ && isRecord(value.proof);
144
+ }
145
+
146
+ /** True if `value` has the shape of an SMT inclusion / non-inclusion proof. */
147
+ function isSMTProof(value: unknown): value is SMTProof {
148
+ if(!isRecord(value)) return false;
149
+ return typeof value.id === 'string'
150
+ && typeof value.collapsed === 'string'
151
+ && Array.isArray(value.hashes);
152
+ }
153
+
114
154
  /**
115
155
  * Different possible Resolver states representing phases in the resolution process.
116
156
  */
@@ -163,6 +203,11 @@ export class Resolver {
163
203
  #unsortedUpdates: Array<[SignedBTCR2Update, BlockMetadata]> = [];
164
204
  #resolvedResponse: DidResolutionResponse | null = null;
165
205
 
206
+ /** Upper bound on multi-round beacon-discovery passes; see {@link DEFAULT_MAX_DISCOVERY_ROUNDS}. */
207
+ readonly #maxDiscoveryRounds: number;
208
+ /** Count of beacon-discovery passes driven by updates adding new beacon services. */
209
+ #discoveryRounds = 0;
210
+
166
211
  /**
167
212
  * @internal Use {@link DidBtcr2.resolve} to create instances.
168
213
  */
@@ -170,13 +215,14 @@ export class Resolver {
170
215
  didComponents: DidComponents,
171
216
  sidecarData: SidecarData,
172
217
  currentDocument: DidDocument | null,
173
- options?: { versionId?: string; versionTime?: string; genesisDocument?: object }
218
+ options?: { versionId?: string; versionTime?: string; genesisDocument?: object; maxDiscoveryRounds?: number }
174
219
  ) {
175
220
  this.#didComponents = didComponents;
176
221
  this.#sidecarData = sidecarData;
177
222
  this.#currentDocument = currentDocument;
178
223
  this.#versionId = options?.versionId;
179
224
  this.#versionTime = options?.versionTime;
225
+ this.#maxDiscoveryRounds = options?.maxDiscoveryRounds ?? DEFAULT_MAX_DISCOVERY_ROUNDS;
180
226
 
181
227
  // If a genesis document was provided (from sidecar), pre-seed it for validation
182
228
  if(options?.genesisDocument) {
@@ -653,6 +699,17 @@ export class Resolver {
653
699
  });
654
700
 
655
701
  if(hasNewServices) {
702
+ // Bound multi-round discovery: a document whose updates keep adding
703
+ // beacon services would otherwise loop without end. Fail closed once
704
+ // the configured number of rounds is exceeded.
705
+ if(++this.#discoveryRounds > this.#maxDiscoveryRounds) {
706
+ throw new ResolveError(
707
+ `Exceeded maximum beacon-discovery rounds (${this.#maxDiscoveryRounds}); `
708
+ + 'the DID document may chain beacon services without terminating.',
709
+ INVALID_DID_DOCUMENT,
710
+ { maxDiscoveryRounds: this.#maxDiscoveryRounds }
711
+ );
712
+ }
656
713
  // Loop back to discover signals for new beacon services
657
714
  this.#phase = ResolverPhase.BeaconDiscovery;
658
715
  continue;
@@ -697,42 +754,85 @@ export class Resolver {
697
754
  provide(need: DataNeed, data: object | Map<BeaconService, Array<BeaconSignal>> | CASAnnouncement | SignedBTCR2Update | SMTProof): void {
698
755
  switch(need.kind) {
699
756
  case 'NeedGenesisDocument': {
757
+ if(!isRecord(data)) {
758
+ throw new ResolveError(
759
+ 'Provided data for NeedGenesisDocument must be a document object.',
760
+ INVALID_DID_UPDATE, { kind: need.kind }
761
+ );
762
+ }
700
763
  this.#providedGenesisDocument = data;
701
764
  break;
702
765
  }
703
766
 
704
767
  case 'NeedBeaconSignals': {
705
- const signals = data as Map<BeaconService, Array<BeaconSignal>>;
706
- for(const [service, serviceSignals] of signals) {
768
+ if(!(data instanceof Map)) {
769
+ throw new ResolveError(
770
+ 'Provided data for NeedBeaconSignals must be a Map of beacon services to signals.',
771
+ INVALID_DID_UPDATE, { kind: need.kind }
772
+ );
773
+ }
774
+ for(const [service, serviceSignals] of data) {
707
775
  this.#beaconServicesSignals.set(service, serviceSignals);
708
776
  }
709
777
  break;
710
778
  }
711
779
 
712
780
  case 'NeedCASAnnouncement': {
713
- const announcement = data as CASAnnouncement;
714
- this.#sidecarData.casMap.set(canonicalHash(announcement, { encoding: 'hex' }), announcement);
781
+ if(!isCASAnnouncement(data)) {
782
+ throw new ResolveError(
783
+ 'Provided data for NeedCASAnnouncement is not a CAS announcement.',
784
+ INVALID_DID_UPDATE, { kind: need.kind }
785
+ );
786
+ }
787
+ // Fail fast if the provided announcement is not the one the on-chain
788
+ // signal requested: its canonical hash must equal the need's hash.
789
+ const announcementHash = canonicalHash(data, { encoding: 'hex' });
790
+ if(announcementHash !== need.announcementHash) {
791
+ throw new ResolveError(
792
+ `CAS announcement hash mismatch: expected ${need.announcementHash}, got ${announcementHash}.`,
793
+ INVALID_DID_UPDATE, { expected: need.announcementHash, actual: announcementHash }
794
+ );
795
+ }
796
+ this.#sidecarData.casMap.set(announcementHash, data);
715
797
  break;
716
798
  }
717
799
 
718
800
  case 'NeedSignedUpdate': {
719
- const update = data as SignedBTCR2Update;
720
- this.#sidecarData.updateMap.set(canonicalHash(update, { encoding: 'hex' }), update);
801
+ if(!isSignedBTCR2Update(data)) {
802
+ throw new ResolveError(
803
+ 'Provided data for NeedSignedUpdate is not a signed BTCR2 update.',
804
+ INVALID_DID_UPDATE, { kind: need.kind }
805
+ );
806
+ }
807
+ // Fail fast if the provided update is not the one the on-chain signal
808
+ // requested: its canonical hash must equal the need's hash.
809
+ const updateHash = canonicalHash(data, { encoding: 'hex' });
810
+ if(updateHash !== need.updateHash) {
811
+ throw new ResolveError(
812
+ `Signed update hash mismatch: expected ${need.updateHash}, got ${updateHash}.`,
813
+ INVALID_DID_UPDATE, { expected: need.updateHash, actual: updateHash }
814
+ );
815
+ }
816
+ this.#sidecarData.updateMap.set(updateHash, data);
721
817
  break;
722
818
  }
723
819
 
724
820
  case 'NeedSMTProof': {
725
- const smtNeed = need as NeedSMTProof;
726
- const proof = data as SMTProof;
821
+ if(!isSMTProof(data)) {
822
+ throw new ResolveError(
823
+ 'Provided data for NeedSMTProof is not an SMT proof.',
824
+ INVALID_DID_UPDATE, { kind: need.kind }
825
+ );
826
+ }
727
827
  // proof.id is base64url per spec; smtRootHash is the hex on-chain signal.
728
- const proofIdHex = encodeHash(decodeHash(proof.id, 'base64urlnopad'), 'hex');
729
- if(proofIdHex !== smtNeed.smtRootHash) {
828
+ const proofIdHex = encodeHash(decodeHash(data.id, 'base64urlnopad'), 'hex');
829
+ if(proofIdHex !== need.smtRootHash) {
730
830
  throw new ResolveError(
731
- `SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${proofIdHex}`,
732
- INVALID_DID_UPDATE, { expected: smtNeed.smtRootHash, actual: proofIdHex }
831
+ `SMT proof root hash mismatch: expected ${need.smtRootHash}, got ${proofIdHex}`,
832
+ INVALID_DID_UPDATE, { expected: need.smtRootHash, actual: proofIdHex }
733
833
  );
734
834
  }
735
- this.#sidecarData.smtMap.set(smtNeed.smtRootHash, proof);
835
+ this.#sidecarData.smtMap.set(need.smtRootHash, data);
736
836
  break;
737
837
  }
738
838
  }
package/src/did-btcr2.ts CHANGED
@@ -124,9 +124,10 @@ export class DidBtcr2 implements DidMethod {
124
124
 
125
125
  // Return the sans-I/O state machine
126
126
  return new Resolver(didComponents, sidecarData, currentDocument, {
127
- versionId : resolutionOptions.versionId,
128
- versionTime : resolutionOptions.versionTime,
129
- genesisDocument : resolutionOptions.sidecar?.genesisDocument
127
+ versionId : resolutionOptions.versionId,
128
+ versionTime : resolutionOptions.versionTime,
129
+ genesisDocument : resolutionOptions.sidecar?.genesisDocument,
130
+ maxDiscoveryRounds : resolutionOptions.maxDiscoveryRounds
130
131
  });
131
132
  }
132
133