@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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser.js +108 -26
- package/dist/browser.mjs +108 -26
- package/dist/cjs/index.js +110 -26
- package/dist/esm/core/beacon/cas-beacon.js +22 -0
- package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
- package/dist/esm/core/beacon/signal-discovery.js +40 -18
- package/dist/esm/core/beacon/signal-discovery.js.map +1 -1
- package/dist/esm/core/resolver.js +82 -12
- package/dist/esm/core/resolver.js.map +1 -1
- package/dist/esm/did-btcr2.js +2 -1
- package/dist/esm/did-btcr2.js.map +1 -1
- package/dist/types/core/beacon/cas-beacon.d.ts +22 -0
- package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
- package/dist/types/core/beacon/signal-discovery.d.ts +14 -0
- package/dist/types/core/beacon/signal-discovery.d.ts.map +1 -1
- package/dist/types/core/interfaces.d.ts +7 -0
- package/dist/types/core/interfaces.d.ts.map +1 -1
- package/dist/types/core/resolver.d.ts +8 -0
- package/dist/types/core/resolver.d.ts.map +1 -1
- package/dist/types/did-btcr2.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/core/beacon/cas-beacon.ts +22 -0
- package/src/core/beacon/signal-discovery.ts +44 -22
- package/src/core/interfaces.ts +8 -0
- package/src/core/resolver.ts +114 -14
- package/src/did-btcr2.ts +4 -3
package/dist/browser.js
CHANGED
|
@@ -93159,6 +93159,7 @@ a=end-of-candidates
|
|
|
93159
93159
|
CASBeaconError: () => CASBeaconError,
|
|
93160
93160
|
CHANGE_OUTPUT_VBYTES: () => CHANGE_OUTPUT_VBYTES,
|
|
93161
93161
|
DEFAULT_FEE_ESTIMATOR: () => DEFAULT_FEE_ESTIMATOR,
|
|
93162
|
+
DEFAULT_MAX_DISCOVERY_ROUNDS: () => DEFAULT_MAX_DISCOVERY_ROUNDS,
|
|
93162
93163
|
DID_REGEX: () => DID_REGEX,
|
|
93163
93164
|
DUST_LIMIT_SATS: () => DUST_LIMIT_SATS,
|
|
93164
93165
|
DidBtcr2: () => DidBtcr2,
|
|
@@ -93185,6 +93186,7 @@ a=end-of-candidates
|
|
|
93185
93186
|
buildAggregationBeaconTx: () => buildAggregationBeaconTx,
|
|
93186
93187
|
deriveSingletonAddress: () => deriveSingletonAddress,
|
|
93187
93188
|
detectSingletonScriptKind: () => detectSingletonScriptKind,
|
|
93189
|
+
extractOpReturnSignal: () => extractOpReturnSignal,
|
|
93188
93190
|
opReturnScript: () => opReturnScript,
|
|
93189
93191
|
resolveBtcr2SenderPk: () => resolveBtcr2SenderPk,
|
|
93190
93192
|
resolveChangeAddress: () => resolveChangeAddress
|
|
@@ -117693,6 +117695,20 @@ a=end-of-candidates
|
|
|
117693
117695
|
};
|
|
117694
117696
|
|
|
117695
117697
|
// src/core/beacon/signal-discovery.ts
|
|
117698
|
+
function extractOpReturnSignal(asm) {
|
|
117699
|
+
if (!asm) {
|
|
117700
|
+
return null;
|
|
117701
|
+
}
|
|
117702
|
+
const tokens = asm.trim().split(/\s+/);
|
|
117703
|
+
if (tokens.length !== 3 || tokens[0] !== "OP_RETURN" || tokens[1] !== "OP_PUSHBYTES_32") {
|
|
117704
|
+
return null;
|
|
117705
|
+
}
|
|
117706
|
+
const signalHash = tokens[2];
|
|
117707
|
+
if (!/^[0-9a-fA-F]{64}$/.test(signalHash)) {
|
|
117708
|
+
return null;
|
|
117709
|
+
}
|
|
117710
|
+
return signalHash.toLowerCase();
|
|
117711
|
+
}
|
|
117696
117712
|
var BeaconSignalDiscovery = class {
|
|
117697
117713
|
/**
|
|
117698
117714
|
* Retrieves the beacon signals for the given array of BeaconService objects
|
|
@@ -117714,15 +117730,10 @@ a=end-of-candidates
|
|
|
117714
117730
|
}
|
|
117715
117731
|
for (const beaconSignal of beaconSignals) {
|
|
117716
117732
|
const signalVout = beaconSignal.vout.slice(-1)[0];
|
|
117717
|
-
if (!signalVout
|
|
117718
|
-
continue;
|
|
117719
|
-
}
|
|
117720
|
-
const outputMap = new Map(Object.entries(signalVout));
|
|
117721
|
-
const signalVoutScriptPubkey = outputMap.get("scriptpubkey_asm");
|
|
117722
|
-
if (!signalVoutScriptPubkey) {
|
|
117733
|
+
if (!signalVout) {
|
|
117723
117734
|
continue;
|
|
117724
117735
|
}
|
|
117725
|
-
const updateHash =
|
|
117736
|
+
const updateHash = extractOpReturnSignal(signalVout.scriptpubkey_asm);
|
|
117726
117737
|
if (!updateHash) {
|
|
117727
117738
|
continue;
|
|
117728
117739
|
}
|
|
@@ -117791,14 +117802,11 @@ a=end-of-candidates
|
|
|
117791
117802
|
continue;
|
|
117792
117803
|
}
|
|
117793
117804
|
const txVoutScriptPubkeyAsm = prevout.vout[vin.vout].scriptPubKey.asm;
|
|
117794
|
-
|
|
117795
|
-
continue;
|
|
117796
|
-
}
|
|
117797
|
-
console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
|
|
117798
|
-
const updateHash = txVoutScriptPubkeyAsm.split(" ").slice(-1)[0];
|
|
117805
|
+
const updateHash = extractOpReturnSignal(txVoutScriptPubkeyAsm);
|
|
117799
117806
|
if (!updateHash) {
|
|
117800
117807
|
continue;
|
|
117801
117808
|
}
|
|
117809
|
+
console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
|
|
117802
117810
|
beaconServiceSignals.get(beaconService)?.push({
|
|
117803
117811
|
tx,
|
|
117804
117812
|
signalBytes: updateHash,
|
|
@@ -119289,7 +119297,8 @@ a=end-of-candidates
|
|
|
119289
119297
|
return new Resolver(didComponents, sidecarData, currentDocument, {
|
|
119290
119298
|
versionId: resolutionOptions.versionId,
|
|
119291
119299
|
versionTime: resolutionOptions.versionTime,
|
|
119292
|
-
genesisDocument: resolutionOptions.sidecar?.genesisDocument
|
|
119300
|
+
genesisDocument: resolutionOptions.sidecar?.genesisDocument,
|
|
119301
|
+
maxDiscoveryRounds: resolutionOptions.maxDiscoveryRounds
|
|
119293
119302
|
});
|
|
119294
119303
|
}
|
|
119295
119304
|
/**
|
|
@@ -119398,6 +119407,21 @@ a=end-of-candidates
|
|
|
119398
119407
|
|
|
119399
119408
|
// src/core/resolver.ts
|
|
119400
119409
|
init_utils2();
|
|
119410
|
+
var DEFAULT_MAX_DISCOVERY_ROUNDS = 10;
|
|
119411
|
+
function isRecord(value2) {
|
|
119412
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
119413
|
+
}
|
|
119414
|
+
function isCASAnnouncement(value2) {
|
|
119415
|
+
return isRecord(value2) && Object.values(value2).every((v) => typeof v === "string");
|
|
119416
|
+
}
|
|
119417
|
+
function isSignedBTCR2Update(value2) {
|
|
119418
|
+
if (!isRecord(value2)) return false;
|
|
119419
|
+
return Array.isArray(value2.patch) && typeof value2.sourceHash === "string" && typeof value2.targetHash === "string" && typeof value2.targetVersionId === "number" && isRecord(value2.proof);
|
|
119420
|
+
}
|
|
119421
|
+
function isSMTProof(value2) {
|
|
119422
|
+
if (!isRecord(value2)) return false;
|
|
119423
|
+
return typeof value2.id === "string" && typeof value2.collapsed === "string" && Array.isArray(value2.hashes);
|
|
119424
|
+
}
|
|
119401
119425
|
var Resolver = class _Resolver {
|
|
119402
119426
|
// --- Immutable inputs ---
|
|
119403
119427
|
#didComponents;
|
|
@@ -119415,6 +119439,10 @@ a=end-of-candidates
|
|
|
119415
119439
|
#requestCache = /* @__PURE__ */ new Set();
|
|
119416
119440
|
#unsortedUpdates = [];
|
|
119417
119441
|
#resolvedResponse = null;
|
|
119442
|
+
/** Upper bound on multi-round beacon-discovery passes; see {@link DEFAULT_MAX_DISCOVERY_ROUNDS}. */
|
|
119443
|
+
#maxDiscoveryRounds;
|
|
119444
|
+
/** Count of beacon-discovery passes driven by updates adding new beacon services. */
|
|
119445
|
+
#discoveryRounds = 0;
|
|
119418
119446
|
/**
|
|
119419
119447
|
* @internal Use {@link DidBtcr2.resolve} to create instances.
|
|
119420
119448
|
*/
|
|
@@ -119424,6 +119452,7 @@ a=end-of-candidates
|
|
|
119424
119452
|
this.#currentDocument = currentDocument;
|
|
119425
119453
|
this.#versionId = options2?.versionId;
|
|
119426
119454
|
this.#versionTime = options2?.versionTime;
|
|
119455
|
+
this.#maxDiscoveryRounds = options2?.maxDiscoveryRounds ?? DEFAULT_MAX_DISCOVERY_ROUNDS;
|
|
119427
119456
|
if (options2?.genesisDocument) {
|
|
119428
119457
|
this.#providedGenesisDocument = options2.genesisDocument;
|
|
119429
119458
|
}
|
|
@@ -119738,6 +119767,13 @@ a=end-of-candidates
|
|
|
119738
119767
|
return !this.#requestCache.has(address);
|
|
119739
119768
|
});
|
|
119740
119769
|
if (hasNewServices) {
|
|
119770
|
+
if (++this.#discoveryRounds > this.#maxDiscoveryRounds) {
|
|
119771
|
+
throw new ResolveError(
|
|
119772
|
+
`Exceeded maximum beacon-discovery rounds (${this.#maxDiscoveryRounds}); the DID document may chain beacon services without terminating.`,
|
|
119773
|
+
INVALID_DID_DOCUMENT,
|
|
119774
|
+
{ maxDiscoveryRounds: this.#maxDiscoveryRounds }
|
|
119775
|
+
);
|
|
119776
|
+
}
|
|
119741
119777
|
this.#phase = "BeaconDiscovery" /* BeaconDiscovery */;
|
|
119742
119778
|
continue;
|
|
119743
119779
|
}
|
|
@@ -119764,38 +119800,84 @@ a=end-of-candidates
|
|
|
119764
119800
|
provide(need, data) {
|
|
119765
119801
|
switch (need.kind) {
|
|
119766
119802
|
case "NeedGenesisDocument": {
|
|
119803
|
+
if (!isRecord(data)) {
|
|
119804
|
+
throw new ResolveError(
|
|
119805
|
+
"Provided data for NeedGenesisDocument must be a document object.",
|
|
119806
|
+
INVALID_DID_UPDATE,
|
|
119807
|
+
{ kind: need.kind }
|
|
119808
|
+
);
|
|
119809
|
+
}
|
|
119767
119810
|
this.#providedGenesisDocument = data;
|
|
119768
119811
|
break;
|
|
119769
119812
|
}
|
|
119770
119813
|
case "NeedBeaconSignals": {
|
|
119771
|
-
|
|
119772
|
-
|
|
119814
|
+
if (!(data instanceof Map)) {
|
|
119815
|
+
throw new ResolveError(
|
|
119816
|
+
"Provided data for NeedBeaconSignals must be a Map of beacon services to signals.",
|
|
119817
|
+
INVALID_DID_UPDATE,
|
|
119818
|
+
{ kind: need.kind }
|
|
119819
|
+
);
|
|
119820
|
+
}
|
|
119821
|
+
for (const [service, serviceSignals] of data) {
|
|
119773
119822
|
this.#beaconServicesSignals.set(service, serviceSignals);
|
|
119774
119823
|
}
|
|
119775
119824
|
break;
|
|
119776
119825
|
}
|
|
119777
119826
|
case "NeedCASAnnouncement": {
|
|
119778
|
-
|
|
119779
|
-
|
|
119827
|
+
if (!isCASAnnouncement(data)) {
|
|
119828
|
+
throw new ResolveError(
|
|
119829
|
+
"Provided data for NeedCASAnnouncement is not a CAS announcement.",
|
|
119830
|
+
INVALID_DID_UPDATE,
|
|
119831
|
+
{ kind: need.kind }
|
|
119832
|
+
);
|
|
119833
|
+
}
|
|
119834
|
+
const announcementHash = canonicalHash(data, { encoding: "hex" });
|
|
119835
|
+
if (announcementHash !== need.announcementHash) {
|
|
119836
|
+
throw new ResolveError(
|
|
119837
|
+
`CAS announcement hash mismatch: expected ${need.announcementHash}, got ${announcementHash}.`,
|
|
119838
|
+
INVALID_DID_UPDATE,
|
|
119839
|
+
{ expected: need.announcementHash, actual: announcementHash }
|
|
119840
|
+
);
|
|
119841
|
+
}
|
|
119842
|
+
this.#sidecarData.casMap.set(announcementHash, data);
|
|
119780
119843
|
break;
|
|
119781
119844
|
}
|
|
119782
119845
|
case "NeedSignedUpdate": {
|
|
119783
|
-
|
|
119784
|
-
|
|
119846
|
+
if (!isSignedBTCR2Update(data)) {
|
|
119847
|
+
throw new ResolveError(
|
|
119848
|
+
"Provided data for NeedSignedUpdate is not a signed BTCR2 update.",
|
|
119849
|
+
INVALID_DID_UPDATE,
|
|
119850
|
+
{ kind: need.kind }
|
|
119851
|
+
);
|
|
119852
|
+
}
|
|
119853
|
+
const updateHash = canonicalHash(data, { encoding: "hex" });
|
|
119854
|
+
if (updateHash !== need.updateHash) {
|
|
119855
|
+
throw new ResolveError(
|
|
119856
|
+
`Signed update hash mismatch: expected ${need.updateHash}, got ${updateHash}.`,
|
|
119857
|
+
INVALID_DID_UPDATE,
|
|
119858
|
+
{ expected: need.updateHash, actual: updateHash }
|
|
119859
|
+
);
|
|
119860
|
+
}
|
|
119861
|
+
this.#sidecarData.updateMap.set(updateHash, data);
|
|
119785
119862
|
break;
|
|
119786
119863
|
}
|
|
119787
119864
|
case "NeedSMTProof": {
|
|
119788
|
-
|
|
119789
|
-
|
|
119790
|
-
|
|
119791
|
-
|
|
119865
|
+
if (!isSMTProof(data)) {
|
|
119866
|
+
throw new ResolveError(
|
|
119867
|
+
"Provided data for NeedSMTProof is not an SMT proof.",
|
|
119868
|
+
INVALID_DID_UPDATE,
|
|
119869
|
+
{ kind: need.kind }
|
|
119870
|
+
);
|
|
119871
|
+
}
|
|
119872
|
+
const proofIdHex = encode(decode(data.id, "base64urlnopad"), "hex");
|
|
119873
|
+
if (proofIdHex !== need.smtRootHash) {
|
|
119792
119874
|
throw new ResolveError(
|
|
119793
|
-
`SMT proof root hash mismatch: expected ${
|
|
119875
|
+
`SMT proof root hash mismatch: expected ${need.smtRootHash}, got ${proofIdHex}`,
|
|
119794
119876
|
INVALID_DID_UPDATE,
|
|
119795
|
-
{ expected:
|
|
119877
|
+
{ expected: need.smtRootHash, actual: proofIdHex }
|
|
119796
119878
|
);
|
|
119797
119879
|
}
|
|
119798
|
-
this.#sidecarData.smtMap.set(
|
|
119880
|
+
this.#sidecarData.smtMap.set(need.smtRootHash, data);
|
|
119799
119881
|
break;
|
|
119800
119882
|
}
|
|
119801
119883
|
}
|
package/dist/browser.mjs
CHANGED
|
@@ -117646,6 +117646,20 @@ var BeaconUtils = class {
|
|
|
117646
117646
|
};
|
|
117647
117647
|
|
|
117648
117648
|
// src/core/beacon/signal-discovery.ts
|
|
117649
|
+
function extractOpReturnSignal(asm) {
|
|
117650
|
+
if (!asm) {
|
|
117651
|
+
return null;
|
|
117652
|
+
}
|
|
117653
|
+
const tokens = asm.trim().split(/\s+/);
|
|
117654
|
+
if (tokens.length !== 3 || tokens[0] !== "OP_RETURN" || tokens[1] !== "OP_PUSHBYTES_32") {
|
|
117655
|
+
return null;
|
|
117656
|
+
}
|
|
117657
|
+
const signalHash = tokens[2];
|
|
117658
|
+
if (!/^[0-9a-fA-F]{64}$/.test(signalHash)) {
|
|
117659
|
+
return null;
|
|
117660
|
+
}
|
|
117661
|
+
return signalHash.toLowerCase();
|
|
117662
|
+
}
|
|
117649
117663
|
var BeaconSignalDiscovery = class {
|
|
117650
117664
|
/**
|
|
117651
117665
|
* Retrieves the beacon signals for the given array of BeaconService objects
|
|
@@ -117667,15 +117681,10 @@ var BeaconSignalDiscovery = class {
|
|
|
117667
117681
|
}
|
|
117668
117682
|
for (const beaconSignal of beaconSignals) {
|
|
117669
117683
|
const signalVout = beaconSignal.vout.slice(-1)[0];
|
|
117670
|
-
if (!signalVout
|
|
117671
|
-
continue;
|
|
117672
|
-
}
|
|
117673
|
-
const outputMap = new Map(Object.entries(signalVout));
|
|
117674
|
-
const signalVoutScriptPubkey = outputMap.get("scriptpubkey_asm");
|
|
117675
|
-
if (!signalVoutScriptPubkey) {
|
|
117684
|
+
if (!signalVout) {
|
|
117676
117685
|
continue;
|
|
117677
117686
|
}
|
|
117678
|
-
const updateHash =
|
|
117687
|
+
const updateHash = extractOpReturnSignal(signalVout.scriptpubkey_asm);
|
|
117679
117688
|
if (!updateHash) {
|
|
117680
117689
|
continue;
|
|
117681
117690
|
}
|
|
@@ -117744,14 +117753,11 @@ var BeaconSignalDiscovery = class {
|
|
|
117744
117753
|
continue;
|
|
117745
117754
|
}
|
|
117746
117755
|
const txVoutScriptPubkeyAsm = prevout.vout[vin.vout].scriptPubKey.asm;
|
|
117747
|
-
|
|
117748
|
-
continue;
|
|
117749
|
-
}
|
|
117750
|
-
console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
|
|
117751
|
-
const updateHash = txVoutScriptPubkeyAsm.split(" ").slice(-1)[0];
|
|
117756
|
+
const updateHash = extractOpReturnSignal(txVoutScriptPubkeyAsm);
|
|
117752
117757
|
if (!updateHash) {
|
|
117753
117758
|
continue;
|
|
117754
117759
|
}
|
|
117760
|
+
console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
|
|
117755
117761
|
beaconServiceSignals.get(beaconService)?.push({
|
|
117756
117762
|
tx,
|
|
117757
117763
|
signalBytes: updateHash,
|
|
@@ -119242,7 +119248,8 @@ var DidBtcr2 = class {
|
|
|
119242
119248
|
return new Resolver(didComponents, sidecarData, currentDocument, {
|
|
119243
119249
|
versionId: resolutionOptions.versionId,
|
|
119244
119250
|
versionTime: resolutionOptions.versionTime,
|
|
119245
|
-
genesisDocument: resolutionOptions.sidecar?.genesisDocument
|
|
119251
|
+
genesisDocument: resolutionOptions.sidecar?.genesisDocument,
|
|
119252
|
+
maxDiscoveryRounds: resolutionOptions.maxDiscoveryRounds
|
|
119246
119253
|
});
|
|
119247
119254
|
}
|
|
119248
119255
|
/**
|
|
@@ -119351,6 +119358,21 @@ var DidBtcr2 = class {
|
|
|
119351
119358
|
|
|
119352
119359
|
// src/core/resolver.ts
|
|
119353
119360
|
init_utils2();
|
|
119361
|
+
var DEFAULT_MAX_DISCOVERY_ROUNDS = 10;
|
|
119362
|
+
function isRecord(value2) {
|
|
119363
|
+
return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
|
|
119364
|
+
}
|
|
119365
|
+
function isCASAnnouncement(value2) {
|
|
119366
|
+
return isRecord(value2) && Object.values(value2).every((v) => typeof v === "string");
|
|
119367
|
+
}
|
|
119368
|
+
function isSignedBTCR2Update(value2) {
|
|
119369
|
+
if (!isRecord(value2)) return false;
|
|
119370
|
+
return Array.isArray(value2.patch) && typeof value2.sourceHash === "string" && typeof value2.targetHash === "string" && typeof value2.targetVersionId === "number" && isRecord(value2.proof);
|
|
119371
|
+
}
|
|
119372
|
+
function isSMTProof(value2) {
|
|
119373
|
+
if (!isRecord(value2)) return false;
|
|
119374
|
+
return typeof value2.id === "string" && typeof value2.collapsed === "string" && Array.isArray(value2.hashes);
|
|
119375
|
+
}
|
|
119354
119376
|
var Resolver = class _Resolver {
|
|
119355
119377
|
// --- Immutable inputs ---
|
|
119356
119378
|
#didComponents;
|
|
@@ -119368,6 +119390,10 @@ var Resolver = class _Resolver {
|
|
|
119368
119390
|
#requestCache = /* @__PURE__ */ new Set();
|
|
119369
119391
|
#unsortedUpdates = [];
|
|
119370
119392
|
#resolvedResponse = null;
|
|
119393
|
+
/** Upper bound on multi-round beacon-discovery passes; see {@link DEFAULT_MAX_DISCOVERY_ROUNDS}. */
|
|
119394
|
+
#maxDiscoveryRounds;
|
|
119395
|
+
/** Count of beacon-discovery passes driven by updates adding new beacon services. */
|
|
119396
|
+
#discoveryRounds = 0;
|
|
119371
119397
|
/**
|
|
119372
119398
|
* @internal Use {@link DidBtcr2.resolve} to create instances.
|
|
119373
119399
|
*/
|
|
@@ -119377,6 +119403,7 @@ var Resolver = class _Resolver {
|
|
|
119377
119403
|
this.#currentDocument = currentDocument;
|
|
119378
119404
|
this.#versionId = options2?.versionId;
|
|
119379
119405
|
this.#versionTime = options2?.versionTime;
|
|
119406
|
+
this.#maxDiscoveryRounds = options2?.maxDiscoveryRounds ?? DEFAULT_MAX_DISCOVERY_ROUNDS;
|
|
119380
119407
|
if (options2?.genesisDocument) {
|
|
119381
119408
|
this.#providedGenesisDocument = options2.genesisDocument;
|
|
119382
119409
|
}
|
|
@@ -119691,6 +119718,13 @@ var Resolver = class _Resolver {
|
|
|
119691
119718
|
return !this.#requestCache.has(address);
|
|
119692
119719
|
});
|
|
119693
119720
|
if (hasNewServices) {
|
|
119721
|
+
if (++this.#discoveryRounds > this.#maxDiscoveryRounds) {
|
|
119722
|
+
throw new ResolveError(
|
|
119723
|
+
`Exceeded maximum beacon-discovery rounds (${this.#maxDiscoveryRounds}); the DID document may chain beacon services without terminating.`,
|
|
119724
|
+
INVALID_DID_DOCUMENT,
|
|
119725
|
+
{ maxDiscoveryRounds: this.#maxDiscoveryRounds }
|
|
119726
|
+
);
|
|
119727
|
+
}
|
|
119694
119728
|
this.#phase = "BeaconDiscovery" /* BeaconDiscovery */;
|
|
119695
119729
|
continue;
|
|
119696
119730
|
}
|
|
@@ -119717,38 +119751,84 @@ var Resolver = class _Resolver {
|
|
|
119717
119751
|
provide(need, data) {
|
|
119718
119752
|
switch (need.kind) {
|
|
119719
119753
|
case "NeedGenesisDocument": {
|
|
119754
|
+
if (!isRecord(data)) {
|
|
119755
|
+
throw new ResolveError(
|
|
119756
|
+
"Provided data for NeedGenesisDocument must be a document object.",
|
|
119757
|
+
INVALID_DID_UPDATE,
|
|
119758
|
+
{ kind: need.kind }
|
|
119759
|
+
);
|
|
119760
|
+
}
|
|
119720
119761
|
this.#providedGenesisDocument = data;
|
|
119721
119762
|
break;
|
|
119722
119763
|
}
|
|
119723
119764
|
case "NeedBeaconSignals": {
|
|
119724
|
-
|
|
119725
|
-
|
|
119765
|
+
if (!(data instanceof Map)) {
|
|
119766
|
+
throw new ResolveError(
|
|
119767
|
+
"Provided data for NeedBeaconSignals must be a Map of beacon services to signals.",
|
|
119768
|
+
INVALID_DID_UPDATE,
|
|
119769
|
+
{ kind: need.kind }
|
|
119770
|
+
);
|
|
119771
|
+
}
|
|
119772
|
+
for (const [service, serviceSignals] of data) {
|
|
119726
119773
|
this.#beaconServicesSignals.set(service, serviceSignals);
|
|
119727
119774
|
}
|
|
119728
119775
|
break;
|
|
119729
119776
|
}
|
|
119730
119777
|
case "NeedCASAnnouncement": {
|
|
119731
|
-
|
|
119732
|
-
|
|
119778
|
+
if (!isCASAnnouncement(data)) {
|
|
119779
|
+
throw new ResolveError(
|
|
119780
|
+
"Provided data for NeedCASAnnouncement is not a CAS announcement.",
|
|
119781
|
+
INVALID_DID_UPDATE,
|
|
119782
|
+
{ kind: need.kind }
|
|
119783
|
+
);
|
|
119784
|
+
}
|
|
119785
|
+
const announcementHash = canonicalHash(data, { encoding: "hex" });
|
|
119786
|
+
if (announcementHash !== need.announcementHash) {
|
|
119787
|
+
throw new ResolveError(
|
|
119788
|
+
`CAS announcement hash mismatch: expected ${need.announcementHash}, got ${announcementHash}.`,
|
|
119789
|
+
INVALID_DID_UPDATE,
|
|
119790
|
+
{ expected: need.announcementHash, actual: announcementHash }
|
|
119791
|
+
);
|
|
119792
|
+
}
|
|
119793
|
+
this.#sidecarData.casMap.set(announcementHash, data);
|
|
119733
119794
|
break;
|
|
119734
119795
|
}
|
|
119735
119796
|
case "NeedSignedUpdate": {
|
|
119736
|
-
|
|
119737
|
-
|
|
119797
|
+
if (!isSignedBTCR2Update(data)) {
|
|
119798
|
+
throw new ResolveError(
|
|
119799
|
+
"Provided data for NeedSignedUpdate is not a signed BTCR2 update.",
|
|
119800
|
+
INVALID_DID_UPDATE,
|
|
119801
|
+
{ kind: need.kind }
|
|
119802
|
+
);
|
|
119803
|
+
}
|
|
119804
|
+
const updateHash = canonicalHash(data, { encoding: "hex" });
|
|
119805
|
+
if (updateHash !== need.updateHash) {
|
|
119806
|
+
throw new ResolveError(
|
|
119807
|
+
`Signed update hash mismatch: expected ${need.updateHash}, got ${updateHash}.`,
|
|
119808
|
+
INVALID_DID_UPDATE,
|
|
119809
|
+
{ expected: need.updateHash, actual: updateHash }
|
|
119810
|
+
);
|
|
119811
|
+
}
|
|
119812
|
+
this.#sidecarData.updateMap.set(updateHash, data);
|
|
119738
119813
|
break;
|
|
119739
119814
|
}
|
|
119740
119815
|
case "NeedSMTProof": {
|
|
119741
|
-
|
|
119742
|
-
|
|
119743
|
-
|
|
119744
|
-
|
|
119816
|
+
if (!isSMTProof(data)) {
|
|
119817
|
+
throw new ResolveError(
|
|
119818
|
+
"Provided data for NeedSMTProof is not an SMT proof.",
|
|
119819
|
+
INVALID_DID_UPDATE,
|
|
119820
|
+
{ kind: need.kind }
|
|
119821
|
+
);
|
|
119822
|
+
}
|
|
119823
|
+
const proofIdHex = encode(decode(data.id, "base64urlnopad"), "hex");
|
|
119824
|
+
if (proofIdHex !== need.smtRootHash) {
|
|
119745
119825
|
throw new ResolveError(
|
|
119746
|
-
`SMT proof root hash mismatch: expected ${
|
|
119826
|
+
`SMT proof root hash mismatch: expected ${need.smtRootHash}, got ${proofIdHex}`,
|
|
119747
119827
|
INVALID_DID_UPDATE,
|
|
119748
|
-
{ expected:
|
|
119828
|
+
{ expected: need.smtRootHash, actual: proofIdHex }
|
|
119749
119829
|
);
|
|
119750
119830
|
}
|
|
119751
|
-
this.#sidecarData.smtMap.set(
|
|
119831
|
+
this.#sidecarData.smtMap.set(need.smtRootHash, data);
|
|
119752
119832
|
break;
|
|
119753
119833
|
}
|
|
119754
119834
|
}
|
|
@@ -119825,6 +119905,7 @@ export {
|
|
|
119825
119905
|
CASBeaconError,
|
|
119826
119906
|
CHANGE_OUTPUT_VBYTES,
|
|
119827
119907
|
DEFAULT_FEE_ESTIMATOR,
|
|
119908
|
+
DEFAULT_MAX_DISCOVERY_ROUNDS,
|
|
119828
119909
|
DID_REGEX,
|
|
119829
119910
|
DUST_LIMIT_SATS,
|
|
119830
119911
|
DidBtcr2,
|
|
@@ -119851,6 +119932,7 @@ export {
|
|
|
119851
119932
|
buildAggregationBeaconTx,
|
|
119852
119933
|
deriveSingletonAddress,
|
|
119853
119934
|
detectSingletonScriptKind,
|
|
119935
|
+
extractOpReturnSignal,
|
|
119854
119936
|
opReturnScript,
|
|
119855
119937
|
resolveBtcr2SenderPk,
|
|
119856
119938
|
resolveChangeAddress
|