@did-btcr2/method 0.54.1 → 0.56.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/cjs/index.js CHANGED
@@ -60,7 +60,7 @@ __export(index_exports, {
60
60
  buildAggregationBeaconTx: () => buildAggregationBeaconTx,
61
61
  deriveSingletonAddress: () => deriveSingletonAddress,
62
62
  detectSingletonScriptKind: () => detectSingletonScriptKind,
63
- extractOpReturnSignal: () => extractOpReturnSignal,
63
+ extractOpReturnSignalHash: () => extractOpReturnSignalHash,
64
64
  getAggregationCommunicationKey: () => getAggregationCommunicationKey,
65
65
  isMultikeyVerificationMethod: () => isMultikeyVerificationMethod,
66
66
  opReturnScript: () => opReturnScript,
@@ -694,15 +694,16 @@ var BeaconFactory = class {
694
694
 
695
695
  // src/core/beacon/signal-discovery.ts
696
696
  var import_bitcoin3 = require("@did-btcr2/bitcoin");
697
- var import_common8 = require("@did-btcr2/common");
697
+ var import_common9 = require("@did-btcr2/common");
698
698
 
699
699
  // src/core/beacon/utils.ts
700
700
  var import_bitcoin2 = require("@did-btcr2/bitcoin");
701
- var import_common7 = require("@did-btcr2/common");
701
+ var import_common8 = require("@did-btcr2/common");
702
702
  var import_btc_signer2 = require("@scure/btc-signer");
703
703
 
704
704
  // src/utils/appendix.ts
705
705
  var import_dids = require("@web5/dids");
706
+ var import_common6 = require("@did-btcr2/common");
706
707
  var Appendix = class _Appendix {
707
708
  /**
708
709
  * Extracts a DID fragment from a given input
@@ -744,10 +745,10 @@ var Appendix = class _Appendix {
744
745
  * Extracts the verification methods from a given DID Document.
745
746
  * @param didDocument The DID Document to extract the verification methods from
746
747
  * @returns An array of DidVerificationMethod objects
747
- * @throws TypeError if the didDocument is not provided
748
+ * @throws {DidDocumentError} if the didDocument is not provided
748
749
  */
749
750
  static getVerificationMethods(didDocument) {
750
- if (!didDocument) throw new TypeError(`Required parameter missing: 'didDocument'`);
751
+ if (!didDocument) throw new import_common6.DidDocumentError(`Required parameter missing: 'didDocument'`);
751
752
  const verificationMethods = [];
752
753
  verificationMethods.push(...didDocument.verificationMethod?.filter(_Appendix.isDidVerificationMethod) ?? []);
753
754
  Object.keys(import_dids.DidVerificationRelationship).forEach((relationship) => {
@@ -851,7 +852,7 @@ var Appendix = class _Appendix {
851
852
  };
852
853
 
853
854
  // src/core/identifier.ts
854
- var import_common6 = require("@did-btcr2/common");
855
+ var import_common7 = require("@did-btcr2/common");
855
856
  var import_keypair = require("@did-btcr2/keypair");
856
857
  var import_base = require("@scure/base");
857
858
  var Identifier = class _Identifier {
@@ -871,33 +872,33 @@ var Identifier = class _Identifier {
871
872
  */
872
873
  static encode(genesisBytes, options) {
873
874
  const { idType, version = 1, network = "bitcoin" } = options;
874
- if (!(idType in import_common6.IdentifierTypes)) {
875
- throw new import_common6.IdentifierError('Expected "idType" to be "KEY" or "EXTERNAL"', import_common6.INVALID_DID, { idType });
875
+ if (!(idType in import_common7.IdentifierTypes)) {
876
+ throw new import_common7.IdentifierError('Expected "idType" to be "KEY" or "EXTERNAL"', import_common7.INVALID_DID, { idType });
876
877
  }
877
878
  if (version !== 1) {
878
- throw new import_common6.IdentifierError('Expected "version" to be 1', import_common6.INVALID_DID, { version });
879
+ throw new import_common7.IdentifierError('Expected "version" to be 1', import_common7.INVALID_DID, { version });
879
880
  }
880
881
  if (typeof network !== "string") {
881
- throw new import_common6.IdentifierError('Expected "network" to be a known network name', import_common6.INVALID_DID, { network });
882
+ throw new import_common7.IdentifierError('Expected "network" to be a known network name', import_common7.INVALID_DID, { network });
882
883
  }
883
- const networkValue = import_common6.BitcoinNetworkNames[network];
884
+ const networkValue = import_common7.BitcoinNetworkNames[network];
884
885
  if (networkValue === void 0) {
885
- throw new import_common6.IdentifierError('Invalid "network" name', import_common6.INVALID_DID, { network });
886
+ throw new import_common7.IdentifierError('Invalid "network" name', import_common7.INVALID_DID, { network });
886
887
  }
887
888
  if (idType === "KEY") {
888
889
  try {
889
890
  new import_keypair.CompressedSecp256k1PublicKey(genesisBytes);
890
891
  } catch {
891
- throw new import_common6.IdentifierError(
892
+ throw new import_common7.IdentifierError(
892
893
  'Expected "genesisBytes" to be a valid compressed secp256k1 public key',
893
- import_common6.INVALID_DID,
894
+ import_common7.INVALID_DID,
894
895
  { genesisBytes }
895
896
  );
896
897
  }
897
898
  } else if (genesisBytes.length !== 32) {
898
- throw new import_common6.IdentifierError(
899
+ throw new import_common7.IdentifierError(
899
900
  'Expected "genesisBytes" to be a 32-byte hash for EXTERNAL identifiers',
900
- import_common6.INVALID_DID,
901
+ import_common7.INVALID_DID,
901
902
  { genesisBytes }
902
903
  );
903
904
  }
@@ -917,50 +918,50 @@ var Identifier = class _Identifier {
917
918
  static decode(identifier) {
918
919
  const components = identifier.split(":");
919
920
  if (components.length !== 3) {
920
- throw new import_common6.IdentifierError(`Invalid did: ${identifier}`, import_common6.INVALID_DID, { identifier });
921
+ throw new import_common7.IdentifierError(`Invalid did: ${identifier}`, import_common7.INVALID_DID, { identifier });
921
922
  }
922
923
  const [scheme, method, encoded] = components;
923
924
  if (scheme !== "did") {
924
- throw new import_common6.IdentifierError(`Invalid did: ${identifier}`, import_common6.INVALID_DID, { identifier });
925
+ throw new import_common7.IdentifierError(`Invalid did: ${identifier}`, import_common7.INVALID_DID, { identifier });
925
926
  }
926
927
  if (method !== "btcr2") {
927
- throw new import_common6.IdentifierError(`Invalid did method: ${method}`, import_common6.METHOD_NOT_SUPPORTED, { identifier });
928
+ throw new import_common7.IdentifierError(`Invalid did method: ${method}`, import_common7.METHOD_NOT_SUPPORTED, { identifier });
928
929
  }
929
930
  if (!encoded) {
930
- throw new import_common6.IdentifierError(`Invalid method-specific id: ${identifier}`, import_common6.INVALID_DID, { identifier });
931
+ throw new import_common7.IdentifierError(`Invalid method-specific id: ${identifier}`, import_common7.INVALID_DID, { identifier });
931
932
  }
932
933
  const { prefix: hrp, bytes: dataBytes } = import_base.bech32m.decodeToBytes(encoded);
933
934
  if (!["x", "k"].includes(hrp)) {
934
- throw new import_common6.IdentifierError(`Invalid hrp: ${hrp}`, import_common6.INVALID_DID, { identifier });
935
+ throw new import_common7.IdentifierError(`Invalid hrp: ${hrp}`, import_common7.INVALID_DID, { identifier });
935
936
  }
936
937
  if (!dataBytes || dataBytes.length < 1) {
937
- throw new import_common6.IdentifierError(`Failed to decode id: ${encoded}`, import_common6.INVALID_DID, { identifier });
938
+ throw new import_common7.IdentifierError(`Failed to decode id: ${encoded}`, import_common7.INVALID_DID, { identifier });
938
939
  }
939
940
  const idType = hrp === "k" ? "KEY" : "EXTERNAL";
940
941
  const btcr2Version = dataBytes[0] >>> 4;
941
942
  if (btcr2Version !== 0) {
942
- throw new import_common6.IdentifierError(`Invalid btcr2_version (expected 0): ${btcr2Version}`, import_common6.INVALID_DID, { identifier });
943
+ throw new import_common7.IdentifierError(`Invalid btcr2_version (expected 0): ${btcr2Version}`, import_common7.INVALID_DID, { identifier });
943
944
  }
944
945
  const version = 1;
945
946
  const networkValue = dataBytes[0] & 15;
946
- const networkName = import_common6.BitcoinNetworkNames[networkValue];
947
+ const networkName = import_common7.BitcoinNetworkNames[networkValue];
947
948
  let network;
948
949
  if (typeof networkName === "string") {
949
950
  network = networkName;
950
951
  } else if (networkValue >= 12 && networkValue <= 14) {
951
952
  network = networkValue - 11;
952
953
  } else {
953
- throw new import_common6.IdentifierError(`Invalid network: ${networkValue}`, import_common6.INVALID_DID, { identifier });
954
+ throw new import_common7.IdentifierError(`Invalid network: ${networkValue}`, import_common7.INVALID_DID, { identifier });
954
955
  }
955
956
  const genesisBytes = dataBytes.slice(1);
956
957
  if (idType === "KEY") {
957
958
  try {
958
959
  new import_keypair.CompressedSecp256k1PublicKey(genesisBytes);
959
960
  } catch {
960
- throw new import_common6.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common6.INVALID_DID, { identifier });
961
+ throw new import_common7.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common7.INVALID_DID, { identifier });
961
962
  }
962
963
  } else if (genesisBytes.length !== 32) {
963
- throw new import_common6.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common6.INVALID_DID, { identifier });
964
+ throw new import_common7.IdentifierError(`Invalid genesisBytes: ${genesisBytes}`, import_common7.INVALID_DID, { identifier });
964
965
  }
965
966
  return { idType, hrp, version, network, genesisBytes };
966
967
  }
@@ -989,9 +990,9 @@ var Identifier = class _Identifier {
989
990
  static getPublicKey(did) {
990
991
  const { idType, genesisBytes } = _Identifier.decode(did);
991
992
  if (idType !== "KEY") {
992
- throw new import_common6.IdentifierError(
993
+ throw new import_common7.IdentifierError(
993
994
  `Cannot extract public key from EXTERNAL DID: ${did}. EXTERNAL DIDs encode a document hash, not a public key.`,
994
- import_common6.INVALID_DID,
995
+ import_common7.INVALID_DID,
995
996
  { did, idType }
996
997
  );
997
998
  }
@@ -1022,7 +1023,7 @@ var BeaconUtils = class {
1022
1023
  */
1023
1024
  static parseBitcoinAddress(uri) {
1024
1025
  if (!uri.startsWith("bitcoin:")) {
1025
- throw new import_common7.MethodError("Invalid Bitcoin URI format", "BEACON_SERVICE_ERROR", { uri });
1026
+ throw new import_common8.MethodError("Invalid Bitcoin URI format", "BEACON_SERVICE_ERROR", { uri });
1026
1027
  }
1027
1028
  return uri.replace("bitcoin:", "").split("?")[0];
1028
1029
  }
@@ -1103,7 +1104,7 @@ var BeaconUtils = class {
1103
1104
  const p2wpkhAddr = (0, import_btc_signer2.p2wpkh)(publicKey, network).address;
1104
1105
  const p2trAddr = (0, import_btc_signer2.p2tr)(publicKey.slice(1, 33), void 0, network).address;
1105
1106
  if (!p2pkhAddr || !p2wpkhAddr || !p2trAddr) {
1106
- throw new import_common7.DidMethodError("Failed to generate bitcoin addresses");
1107
+ throw new import_common8.DidMethodError("Failed to generate bitcoin addresses");
1107
1108
  }
1108
1109
  return [
1109
1110
  {
@@ -1138,16 +1139,6 @@ var BeaconUtils = class {
1138
1139
  static parseBeaconServiceEndpoint(beacon) {
1139
1140
  return { ...beacon, serviceEndpoint: beacon.serviceEndpoint.replace("bitcoin:", "") };
1140
1141
  }
1141
- /**
1142
- * Create a map of address => beaconService with address field.
1143
- * @param {Array<BeaconService>} beacons The list of beacon services.
1144
- * @returns {Map<string, BeaconService>} A map of address => beaconService.
1145
- */
1146
- static getBeaconServicesMap(beacons) {
1147
- return new Map(
1148
- beacons.map(this.parseBeaconServiceEndpoint).map((beacon) => [beacon.serviceEndpoint, beacon])
1149
- );
1150
- }
1151
1142
  /**
1152
1143
  * Get the beacon service ids from a list of beacon services.
1153
1144
  * @param {DidDocument} didDocument The DID Document to extract the services from.
@@ -1159,21 +1150,53 @@ var BeaconUtils = class {
1159
1150
  };
1160
1151
 
1161
1152
  // src/core/beacon/signal-discovery.ts
1162
- function extractOpReturnSignal(asm) {
1163
- if (!asm) {
1164
- return null;
1165
- }
1166
- const tokens = asm.trim().split(/\s+/);
1167
- if (tokens.length !== 3 || tokens[0] !== "OP_RETURN" || tokens[1] !== "OP_PUSHBYTES_32") {
1153
+ var BEACON_SIGNAL_SCRIPT = /^6a20([0-9a-f]{64})$/i;
1154
+ function extractOpReturnSignalHash(scriptPubKey) {
1155
+ if (!scriptPubKey) {
1168
1156
  return null;
1169
1157
  }
1170
- const signalHash = tokens[2];
1171
- if (!/^[0-9a-fA-F]{64}$/.test(signalHash)) {
1158
+ const signal = BEACON_SIGNAL_SCRIPT.exec(scriptPubKey.trim());
1159
+ if (!signal) {
1172
1160
  return null;
1173
1161
  }
1174
- return signalHash.toLowerCase();
1162
+ return signal[1].toLowerCase();
1175
1163
  }
1176
- var BeaconSignalDiscovery = class {
1164
+ var BeaconSignalDiscovery = class _BeaconSignalDiscovery {
1165
+ /**
1166
+ * Determines whether a candidate transaction spends an output controlled by the given
1167
+ * beacon address.
1168
+ *
1169
+ * A Beacon Signal is a transaction that *spends from* a Beacon Address, but an address
1170
+ * transaction listing returns every transaction touching the address in either
1171
+ * direction. Without this check, anyone able to pay dust to a beacon address could
1172
+ * attach an arbitrary 32-byte OP_RETURN and have it read as a signal, so the input side
1173
+ * has to be inspected before a transaction is treated as one.
1174
+ *
1175
+ * Esplora embeds the spent output in `vin[].prevout`; when a backend omits it the
1176
+ * funding transaction is fetched instead, so a missing field cannot silently drop a
1177
+ * real signal.
1178
+ *
1179
+ * @param {RawTransactionRest} tx The candidate transaction.
1180
+ * @param {string} address The beacon address the transaction must spend from.
1181
+ * @param {BitcoinConnection} bitcoin Bitcoin network connection to use for REST calls.
1182
+ * @returns {Promise<boolean>} True if at least one input spends an output of the beacon address.
1183
+ */
1184
+ static async spendsFromAddress(tx, address, bitcoin) {
1185
+ for (const vin of tx.vin ?? []) {
1186
+ if (vin.is_coinbase) {
1187
+ continue;
1188
+ }
1189
+ let prevout = vin.prevout;
1190
+ if (!prevout && vin.txid) {
1191
+ const fundingTx = await bitcoin.rest.transaction.get(vin.txid);
1192
+ prevout = fundingTx?.vout?.[vin.vout];
1193
+ }
1194
+ if (prevout?.scriptpubkey_address === address) {
1195
+ return true;
1196
+ }
1197
+ }
1198
+ return false;
1199
+ }
1177
1200
  /**
1178
1201
  * Retrieves the beacon signals for the given array of BeaconService objects
1179
1202
  * using an esplora/electrs REST API connection via a bitcoin I/O driver.
@@ -1186,21 +1209,23 @@ var BeaconSignalDiscovery = class {
1186
1209
  const currentBlockCount = await bitcoin.rest.block.count();
1187
1210
  for (const beaconService of beaconServices) {
1188
1211
  beaconServiceSignals.set(beaconService, []);
1189
- const beaconSignals = await bitcoin.rest.address.getTxs(
1190
- BeaconUtils.parseBitcoinAddress(beaconService.serviceEndpoint)
1191
- );
1212
+ const beaconAddress = BeaconUtils.parseBitcoinAddress(beaconService.serviceEndpoint);
1213
+ const beaconSignals = await bitcoin.rest.address.getTxs(beaconAddress);
1192
1214
  if (!beaconSignals || !beaconSignals.length) {
1193
1215
  continue;
1194
1216
  }
1195
1217
  for (const beaconSignal of beaconSignals) {
1196
- const signalVout = beaconSignal.vout.slice(-1)[0];
1197
- if (!signalVout) {
1218
+ const lastSignalVout = beaconSignal.vout.slice(-1)[0];
1219
+ if (!lastSignalVout) {
1198
1220
  continue;
1199
1221
  }
1200
- const updateHash = extractOpReturnSignal(signalVout.scriptpubkey_asm);
1222
+ const updateHash = extractOpReturnSignalHash(lastSignalVout.scriptpubkey);
1201
1223
  if (!updateHash) {
1202
1224
  continue;
1203
1225
  }
1226
+ if (!await _BeaconSignalDiscovery.spendsFromAddress(beaconSignal, beaconAddress, bitcoin)) {
1227
+ continue;
1228
+ }
1204
1229
  const confirmations = currentBlockCount - beaconSignal.status.block_height + 1;
1205
1230
  beaconServiceSignals.get(beaconService)?.push({
1206
1231
  tx: beaconSignal,
@@ -1228,10 +1253,12 @@ var BeaconSignalDiscovery = class {
1228
1253
  }
1229
1254
  const rpc = bitcoin.rpc;
1230
1255
  if (!rpc) {
1231
- throw new import_common8.ResolveError("RPC connection is not available", "RPC_CONNECTION_ERROR", bitcoin);
1256
+ throw new import_common9.ResolveError("RPC connection is not available", "RPC_CONNECTION_ERROR", bitcoin);
1232
1257
  }
1233
1258
  const targetHeight = await rpc.getBlockCount();
1234
- const beaconServicesMap = BeaconUtils.getBeaconServicesMap(beaconServices);
1259
+ const beaconServicesMap = new Map(
1260
+ beaconServices.map((service) => [BeaconUtils.parseBitcoinAddress(service.serviceEndpoint), service])
1261
+ );
1235
1262
  let height = 0;
1236
1263
  let block = await bitcoin.rpc.getBlock({ height });
1237
1264
  console.info(`Searching for beacon signals, please wait ...`);
@@ -1240,6 +1267,15 @@ var BeaconSignalDiscovery = class {
1240
1267
  if (tx.txid === import_bitcoin3.GENESIS_TX_ID) {
1241
1268
  continue;
1242
1269
  }
1270
+ const lastSignalVout = tx.vout.slice(-1)[0];
1271
+ if (!lastSignalVout) {
1272
+ continue;
1273
+ }
1274
+ const updateHash = extractOpReturnSignalHash(lastSignalVout.scriptPubKey?.hex);
1275
+ if (!updateHash) {
1276
+ continue;
1277
+ }
1278
+ const signaled = /* @__PURE__ */ new Set();
1243
1279
  for (const vin of tx.vin) {
1244
1280
  if (vin.coinbase) {
1245
1281
  continue;
@@ -1262,15 +1298,11 @@ var BeaconSignalDiscovery = class {
1262
1298
  continue;
1263
1299
  }
1264
1300
  const beaconService = beaconServicesMap.get(scriptPubKey.address);
1265
- if (!beaconService) {
1266
- continue;
1267
- }
1268
- const txVoutScriptPubkeyAsm = prevout.vout[vin.vout].scriptPubKey.asm;
1269
- const updateHash = extractOpReturnSignal(txVoutScriptPubkeyAsm);
1270
- if (!updateHash) {
1301
+ if (!beaconService || signaled.has(beaconService)) {
1271
1302
  continue;
1272
1303
  }
1273
- console.info(`Tx ${tx.txid} contains beacon service address ${scriptPubKey.address} and OP_RETURN!`, tx);
1304
+ signaled.add(beaconService);
1305
+ console.info(`Tx ${tx.txid} contains beacon address ${scriptPubKey.address}`);
1274
1306
  beaconServiceSignals.get(beaconService)?.push({
1275
1307
  tx,
1276
1308
  signalBytes: updateHash,
@@ -1295,27 +1327,27 @@ var BeaconSignalDiscovery = class {
1295
1327
  };
1296
1328
 
1297
1329
  // src/core/did-sender-resolver.ts
1298
- var import_common13 = require("@did-btcr2/common");
1330
+ var import_common14 = require("@did-btcr2/common");
1299
1331
  var import_cryptosuite3 = require("@did-btcr2/cryptosuite");
1300
1332
  var import_keypair4 = require("@did-btcr2/keypair");
1301
1333
 
1302
1334
  // src/core/resolver.ts
1303
1335
  var import_bitcoin5 = require("@did-btcr2/bitcoin");
1304
- var import_common12 = require("@did-btcr2/common");
1336
+ var import_common13 = require("@did-btcr2/common");
1305
1337
  var import_cryptosuite2 = require("@did-btcr2/cryptosuite");
1306
1338
  var import_keypair3 = require("@did-btcr2/keypair");
1307
1339
 
1308
1340
  // src/did-btcr2.ts
1309
- var import_common11 = require("@did-btcr2/common");
1341
+ var import_common12 = require("@did-btcr2/common");
1310
1342
  var import_dids2 = require("@web5/dids");
1311
1343
 
1312
1344
  // src/core/updater.ts
1313
- var import_common10 = require("@did-btcr2/common");
1345
+ var import_common11 = require("@did-btcr2/common");
1314
1346
  var import_cryptosuite = require("@did-btcr2/cryptosuite");
1315
1347
 
1316
1348
  // src/utils/did-document.ts
1317
1349
  var import_bitcoin4 = require("@did-btcr2/bitcoin");
1318
- var import_common9 = require("@did-btcr2/common");
1350
+ var import_common10 = require("@did-btcr2/common");
1319
1351
  var import_keypair2 = require("@did-btcr2/keypair");
1320
1352
  var import_utils4 = require("@web5/dids/utils");
1321
1353
  var import_btc_signer3 = require("@scure/btc-signer");
@@ -1343,16 +1375,16 @@ var DidVerificationMethod = class {
1343
1375
  secretKeyMultibase;
1344
1376
  constructor({ id, type, controller, publicKeyMultibase, secretKeyMultibase }) {
1345
1377
  if (type !== MULTIKEY_VERIFICATION_METHOD_TYPE) {
1346
- throw new import_common9.DidDocumentError(
1378
+ throw new import_common10.DidDocumentError(
1347
1379
  `Invalid verification method: type must be "${MULTIKEY_VERIFICATION_METHOD_TYPE}"`,
1348
- import_common9.INVALID_DID_DOCUMENT,
1380
+ import_common10.INVALID_DID_DOCUMENT,
1349
1381
  { id, type }
1350
1382
  );
1351
1383
  }
1352
1384
  if (typeof publicKeyMultibase !== "string" || !publicKeyMultibase.startsWith(MULTIKEY_PUBLIC_KEY_MULTIBASE_PREFIX)) {
1353
- throw new import_common9.DidDocumentError(
1385
+ throw new import_common10.DidDocumentError(
1354
1386
  `Invalid verification method: publicKeyMultibase must start with "${MULTIKEY_PUBLIC_KEY_MULTIBASE_PREFIX}"`,
1355
- import_common9.INVALID_DID_DOCUMENT,
1387
+ import_common10.INVALID_DID_DOCUMENT,
1356
1388
  { id, publicKeyMultibase }
1357
1389
  );
1358
1390
  }
@@ -1382,20 +1414,20 @@ var DidDocument = class _DidDocument {
1382
1414
  deactivated;
1383
1415
  constructor(document) {
1384
1416
  if (!document.id) {
1385
- throw new import_common9.DidDocumentError("DID Document must have an id", import_common9.INVALID_DID_DOCUMENT, document);
1417
+ throw new import_common10.DidDocumentError("DID Document must have an id", import_common10.INVALID_DID_DOCUMENT, document);
1386
1418
  }
1387
- const idType = document.id.includes("k1") ? import_common9.IdentifierTypes.KEY : import_common9.IdentifierTypes.EXTERNAL;
1419
+ const idType = document.id.includes("k1") ? import_common10.IdentifierTypes.KEY : import_common10.IdentifierTypes.EXTERNAL;
1388
1420
  const isGenesis = document.id === ID_PLACEHOLDER_VALUE;
1389
1421
  const { id, verificationMethod: vm, service } = document;
1390
1422
  if (!isGenesis) {
1391
1423
  if (!_DidDocument.isValidId(id)) {
1392
- throw new import_common9.DidDocumentError(`Invalid id: ${id}`, import_common9.INVALID_DID_DOCUMENT, document);
1424
+ throw new import_common10.DidDocumentError(`Invalid id: ${id}`, import_common10.INVALID_DID_DOCUMENT, document);
1393
1425
  }
1394
1426
  if (!_DidDocument.isValidVerificationMethods(vm)) {
1395
- throw new import_common9.DidDocumentError("Invalid verificationMethod: " + vm, import_common9.INVALID_DID_DOCUMENT, document);
1427
+ throw new import_common10.DidDocumentError("Invalid verificationMethod: " + vm, import_common10.INVALID_DID_DOCUMENT, document);
1396
1428
  }
1397
1429
  if (!_DidDocument.isValidServices(service)) {
1398
- throw new import_common9.DidDocumentError("Invalid service: " + service, import_common9.INVALID_DID_DOCUMENT, document);
1430
+ throw new import_common10.DidDocumentError("Invalid service: " + service, import_common10.INVALID_DID_DOCUMENT, document);
1399
1431
  }
1400
1432
  }
1401
1433
  this.id = document.id;
@@ -1405,7 +1437,7 @@ var DidDocument = class _DidDocument {
1405
1437
  "https://www.w3.org/ns/did/v1.1",
1406
1438
  "https://btcr2.dev/context/v1"
1407
1439
  ];
1408
- if (idType === import_common9.IdentifierTypes.KEY) {
1440
+ if (idType === import_common10.IdentifierTypes.KEY) {
1409
1441
  const keyRef = `${this.id}#initialKey`;
1410
1442
  this.authentication = document.authentication || [keyRef];
1411
1443
  this.assertionMethod = document.assertionMethod || [keyRef];
@@ -1491,19 +1523,19 @@ var DidDocument = class _DidDocument {
1491
1523
  */
1492
1524
  static isValid(didDocument) {
1493
1525
  if (!this.isValidContext(didDocument?.["@context"])) {
1494
- throw new import_common9.DidDocumentError('Invalid "@context"', import_common9.INVALID_DID_DOCUMENT, didDocument);
1526
+ throw new import_common10.DidDocumentError('Invalid "@context"', import_common10.INVALID_DID_DOCUMENT, didDocument);
1495
1527
  }
1496
1528
  if (!this.isValidId(didDocument?.id)) {
1497
- throw new import_common9.DidDocumentError('Invalid "id"', import_common9.INVALID_DID_DOCUMENT, didDocument);
1529
+ throw new import_common10.DidDocumentError('Invalid "id"', import_common10.INVALID_DID_DOCUMENT, didDocument);
1498
1530
  }
1499
1531
  if (!this.isValidVerificationMethods(didDocument?.verificationMethod)) {
1500
- throw new import_common9.DidDocumentError('Invalid "verificationMethod"', import_common9.INVALID_DID_DOCUMENT, didDocument);
1532
+ throw new import_common10.DidDocumentError('Invalid "verificationMethod"', import_common10.INVALID_DID_DOCUMENT, didDocument);
1501
1533
  }
1502
1534
  if (!this.isValidServices(didDocument?.service)) {
1503
- throw new import_common9.DidDocumentError('Invalid "service"', import_common9.INVALID_DID_DOCUMENT, didDocument);
1535
+ throw new import_common10.DidDocumentError('Invalid "service"', import_common10.INVALID_DID_DOCUMENT, didDocument);
1504
1536
  }
1505
1537
  if (!this.isValidVerificationRelationships(didDocument)) {
1506
- throw new import_common9.DidDocumentError("Invalid verification relationships", import_common9.INVALID_DID_DOCUMENT, didDocument);
1538
+ throw new import_common10.DidDocumentError("Invalid verification relationships", import_common10.INVALID_DID_DOCUMENT, didDocument);
1507
1539
  }
1508
1540
  return true;
1509
1541
  }
@@ -1591,16 +1623,16 @@ var DidDocument = class _DidDocument {
1591
1623
  */
1592
1624
  validateGenesis() {
1593
1625
  if (this.id !== ID_PLACEHOLDER_VALUE) {
1594
- throw new import_common9.DidDocumentError("Invalid GenesisDocument ID", import_common9.INVALID_DID_DOCUMENT, this);
1626
+ throw new import_common10.DidDocumentError("Invalid GenesisDocument ID", import_common10.INVALID_DID_DOCUMENT, this);
1595
1627
  }
1596
1628
  if (!this.verificationMethod.every((vm) => vm.id.includes(ID_PLACEHOLDER_VALUE) && vm.controller === ID_PLACEHOLDER_VALUE)) {
1597
- throw new import_common9.DidDocumentError("Invalid GenesisDocument verificationMethod", import_common9.INVALID_DID_DOCUMENT, this);
1629
+ throw new import_common10.DidDocumentError("Invalid GenesisDocument verificationMethod", import_common10.INVALID_DID_DOCUMENT, this);
1598
1630
  }
1599
1631
  if (!this.service.every((svc) => svc.id.includes(ID_PLACEHOLDER_VALUE))) {
1600
- throw new import_common9.DidDocumentError("Invalid GenesisDocument service", import_common9.INVALID_DID_DOCUMENT, this);
1632
+ throw new import_common10.DidDocumentError("Invalid GenesisDocument service", import_common10.INVALID_DID_DOCUMENT, this);
1601
1633
  }
1602
1634
  if (!_DidDocument.isValidVerificationRelationships(this)) {
1603
- throw new import_common9.DidDocumentError("Invalid GenesisDocument assertionMethod", import_common9.INVALID_DID_DOCUMENT, this);
1635
+ throw new import_common10.DidDocumentError("Invalid GenesisDocument assertionMethod", import_common10.INVALID_DID_DOCUMENT, this);
1604
1636
  }
1605
1637
  return true;
1606
1638
  }
@@ -1610,7 +1642,7 @@ var DidDocument = class _DidDocument {
1610
1642
  */
1611
1643
  toIntermediate() {
1612
1644
  if (this.id.includes("k1")) {
1613
- throw new import_common9.DidDocumentError("Cannot convert a key identifier to an intermediate document", import_common9.INVALID_DID_DOCUMENT, this);
1645
+ throw new import_common10.DidDocumentError("Cannot convert a key identifier to an intermediate document", import_common10.INVALID_DID_DOCUMENT, this);
1614
1646
  }
1615
1647
  return new GenesisDocument(this);
1616
1648
  }
@@ -1635,7 +1667,7 @@ var GenesisDocument = class _GenesisDocument extends DidDocument {
1635
1667
  * @returns {GenesisDocument} The GenesisDocument representation of the DidDocument.
1636
1668
  */
1637
1669
  static fromDidDocument(didDocument) {
1638
- const intermediateDocument = import_common9.JSONUtils.cloneReplace(didDocument, DID_REGEX, ID_PLACEHOLDER_VALUE);
1670
+ const intermediateDocument = import_common10.JSONUtils.cloneReplace(didDocument, DID_REGEX, ID_PLACEHOLDER_VALUE);
1639
1671
  return new _GenesisDocument(intermediateDocument);
1640
1672
  }
1641
1673
  /**
@@ -1692,7 +1724,7 @@ var GenesisDocument = class _GenesisDocument extends DidDocument {
1692
1724
  * @returns {Bytes} The genesis bytes.
1693
1725
  */
1694
1726
  static toGenesisBytes(genesisDocument) {
1695
- return (0, import_common9.hash)((0, import_common9.canonicalize)(genesisDocument));
1727
+ return (0, import_common10.hash)((0, import_common10.canonicalize)(genesisDocument));
1696
1728
  }
1697
1729
  };
1698
1730
 
@@ -1737,26 +1769,26 @@ var Updater = class _Updater {
1737
1769
  patch: patches,
1738
1770
  targetHash: "",
1739
1771
  targetVersionId: sourceVersionId + 1,
1740
- sourceHash: (0, import_common10.canonicalHash)(sourceDocument)
1772
+ sourceHash: (0, import_common11.canonicalHash)(sourceDocument)
1741
1773
  };
1742
- const targetDocument = import_common10.JSONPatch.apply(sourceDocument, patches);
1774
+ const targetDocument = import_common11.JSONPatch.apply(sourceDocument, patches);
1743
1775
  if (targetDocument.id !== sourceDocument.id) {
1744
- throw new import_common10.UpdateError(
1776
+ throw new import_common11.UpdateError(
1745
1777
  `Patches must not change the DID document id (source "${sourceDocument.id}" to target "${targetDocument.id}").`,
1746
- import_common10.INVALID_DID_UPDATE,
1778
+ import_common11.INVALID_DID_UPDATE,
1747
1779
  { sourceId: sourceDocument.id, targetId: targetDocument.id }
1748
1780
  );
1749
1781
  }
1750
1782
  try {
1751
1783
  DidDocument.isValid(targetDocument);
1752
1784
  } catch (error) {
1753
- throw new import_common10.UpdateError(
1785
+ throw new import_common11.UpdateError(
1754
1786
  "Error validating targetDocument: " + (error instanceof Error ? error.message : String(error)),
1755
- import_common10.INVALID_DID_UPDATE,
1787
+ import_common11.INVALID_DID_UPDATE,
1756
1788
  targetDocument
1757
1789
  );
1758
1790
  }
1759
- unsignedUpdate.targetHash = (0, import_common10.canonicalHash)(targetDocument);
1791
+ unsignedUpdate.targetHash = (0, import_common11.canonicalHash)(targetDocument);
1760
1792
  return unsignedUpdate;
1761
1793
  }
1762
1794
  /**
@@ -1770,18 +1802,18 @@ var Updater = class _Updater {
1770
1802
  */
1771
1803
  static sign(did, unsignedUpdate, verificationMethod, signer) {
1772
1804
  if (!did.startsWith("did:btcr2:")) {
1773
- throw new import_common10.UpdateError(
1805
+ throw new import_common11.UpdateError(
1774
1806
  `Expected a did:btcr2 identifier for the root capability; got "${did}".`,
1775
- import_common10.INVALID_DID_UPDATE,
1807
+ import_common11.INVALID_DID_UPDATE,
1776
1808
  { did }
1777
1809
  );
1778
1810
  }
1779
1811
  const controller = verificationMethod.controller;
1780
1812
  const hashIdx = verificationMethod.id.indexOf("#");
1781
1813
  if (hashIdx < 0) {
1782
- throw new import_common10.UpdateError(
1814
+ throw new import_common11.UpdateError(
1783
1815
  `Verification method id must contain a fragment (e.g. "${verificationMethod.id}#initialKey"); got "${verificationMethod.id}".`,
1784
- import_common10.INVALID_DID_UPDATE,
1816
+ import_common11.INVALID_DID_UPDATE,
1785
1817
  { verificationMethodId: verificationMethod.id }
1786
1818
  );
1787
1819
  }
@@ -1789,9 +1821,9 @@ var Updater = class _Updater {
1789
1821
  const multikey = import_cryptosuite.SchnorrMultikey.fromSigner(id, controller, signer);
1790
1822
  const signerKey = multikey.publicKey.multibase.encoded;
1791
1823
  if (verificationMethod.publicKeyMultibase && signerKey !== verificationMethod.publicKeyMultibase) {
1792
- throw new import_common10.UpdateError(
1824
+ throw new import_common11.UpdateError(
1793
1825
  `Signing key does not match verification method "${verificationMethod.id}": the signer's public key differs from the method's published publicKeyMultibase.`,
1794
- import_common10.INVALID_DID_UPDATE,
1826
+ import_common11.INVALID_DID_UPDATE,
1795
1827
  {
1796
1828
  verificationMethodId: verificationMethod.id,
1797
1829
  expected: verificationMethod.publicKeyMultibase,
@@ -1908,16 +1940,16 @@ var Updater = class _Updater {
1908
1940
  switch (need.kind) {
1909
1941
  case "NeedSigningKey": {
1910
1942
  if (this.#state.phase !== "Sign") {
1911
- throw new import_common10.UpdateError(
1943
+ throw new import_common11.UpdateError(
1912
1944
  `Cannot provide NeedSigningKey: updater phase is ${this.#state.phase}, expected Sign.`,
1913
- import_common10.INVALID_DID_UPDATE,
1945
+ import_common11.INVALID_DID_UPDATE,
1914
1946
  { phase: this.#state.phase }
1915
1947
  );
1916
1948
  }
1917
1949
  if (!data) {
1918
- throw new import_common10.UpdateError(
1950
+ throw new import_common11.UpdateError(
1919
1951
  "NeedSigningKey requires a Signer.",
1920
- import_common10.INVALID_DID_UPDATE
1952
+ import_common11.INVALID_DID_UPDATE
1921
1953
  );
1922
1954
  }
1923
1955
  const unsignedUpdate = this.#state.unsignedUpdate;
@@ -1932,18 +1964,18 @@ var Updater = class _Updater {
1932
1964
  }
1933
1965
  case "NeedFunding": {
1934
1966
  if (this.#state.phase !== "Fund") {
1935
- throw new import_common10.UpdateError(
1967
+ throw new import_common11.UpdateError(
1936
1968
  `Cannot provide NeedFunding: updater phase is ${this.#state.phase}, expected Fund.`,
1937
- import_common10.INVALID_DID_UPDATE,
1969
+ import_common11.INVALID_DID_UPDATE,
1938
1970
  { phase: this.#state.phase }
1939
1971
  );
1940
1972
  }
1941
1973
  if (data !== void 0) {
1942
1974
  const proof = data;
1943
1975
  if (typeof proof.utxoCount !== "number" || !Number.isFinite(proof.utxoCount) || proof.utxoCount < 1) {
1944
- throw new import_common10.UpdateError(
1976
+ throw new import_common11.UpdateError(
1945
1977
  `NeedFunding proof must have utxoCount >= 1; got ${String(proof.utxoCount)}.`,
1946
- import_common10.INVALID_DID_UPDATE,
1978
+ import_common11.INVALID_DID_UPDATE,
1947
1979
  { utxoCount: proof.utxoCount }
1948
1980
  );
1949
1981
  }
@@ -1957,9 +1989,9 @@ var Updater = class _Updater {
1957
1989
  }
1958
1990
  case "NeedBroadcast": {
1959
1991
  if (this.#state.phase !== "Broadcast") {
1960
- throw new import_common10.UpdateError(
1992
+ throw new import_common11.UpdateError(
1961
1993
  `Cannot provide NeedBroadcast: updater phase is ${this.#state.phase}, expected Broadcast.`,
1962
- import_common10.INVALID_DID_UPDATE,
1994
+ import_common11.INVALID_DID_UPDATE,
1963
1995
  { phase: this.#state.phase }
1964
1996
  );
1965
1997
  }
@@ -1995,9 +2027,9 @@ var DidBtcr2 = class {
1995
2027
  static create(genesisBytes, options) {
1996
2028
  const { idType, version = 1, network = "bitcoin" } = options || {};
1997
2029
  if (!idType) {
1998
- throw new import_common11.MethodError(
2030
+ throw new import_common12.MethodError(
1999
2031
  "idType is required for creating a did:btcr2 identifier",
2000
- import_common11.INVALID_DID_DOCUMENT,
2032
+ import_common12.INVALID_DID_DOCUMENT,
2001
2033
  options
2002
2034
  );
2003
2035
  }
@@ -2027,7 +2059,7 @@ var DidBtcr2 = class {
2027
2059
  static resolve(did, resolutionOptions = {}) {
2028
2060
  const didComponents = Identifier.decode(did);
2029
2061
  const sidecarData = Resolver.sidecarData(resolutionOptions.sidecar);
2030
- const currentDocument = didComponents.hrp === import_common11.IdentifierHrp.k ? Resolver.deterministic(didComponents) : null;
2062
+ const currentDocument = didComponents.hrp === import_common12.IdentifierHrp.k ? Resolver.deterministic(didComponents) : null;
2031
2063
  return new Resolver(didComponents, sidecarData, currentDocument, {
2032
2064
  versionId: resolutionOptions.versionId,
2033
2065
  versionTime: resolutionOptions.versionTime,
@@ -2066,39 +2098,39 @@ var DidBtcr2 = class {
2066
2098
  beaconId
2067
2099
  }) {
2068
2100
  if (!sourceDocument.capabilityInvocation?.some((vr) => vr === verificationMethodId)) {
2069
- throw new import_common11.UpdateError(
2101
+ throw new import_common12.UpdateError(
2070
2102
  "Invalid verificationMethodId: not authorized for capabilityInvocation",
2071
- import_common11.INVALID_DID_DOCUMENT,
2103
+ import_common12.INVALID_DID_DOCUMENT,
2072
2104
  sourceDocument
2073
2105
  );
2074
2106
  }
2075
2107
  const verificationMethod = this.getSigningMethod(sourceDocument, verificationMethodId);
2076
2108
  if (!verificationMethod) {
2077
- throw new import_common11.UpdateError(
2109
+ throw new import_common12.UpdateError(
2078
2110
  "Invalid verificationMethod: not found in source document",
2079
- import_common11.INVALID_DID_DOCUMENT,
2111
+ import_common12.INVALID_DID_DOCUMENT,
2080
2112
  { sourceDocument, verificationMethodId }
2081
2113
  );
2082
2114
  }
2083
2115
  if (verificationMethod.type !== MULTIKEY_VERIFICATION_METHOD_TYPE) {
2084
- throw new import_common11.UpdateError(
2116
+ throw new import_common12.UpdateError(
2085
2117
  `Invalid verificationMethod: verificationMethod.type must be "${MULTIKEY_VERIFICATION_METHOD_TYPE}"`,
2086
- import_common11.INVALID_DID_DOCUMENT,
2118
+ import_common12.INVALID_DID_DOCUMENT,
2087
2119
  verificationMethod
2088
2120
  );
2089
2121
  }
2090
2122
  if (!verificationMethod.publicKeyMultibase?.startsWith(MULTIKEY_PUBLIC_KEY_MULTIBASE_PREFIX)) {
2091
- throw new import_common11.UpdateError(
2123
+ throw new import_common12.UpdateError(
2092
2124
  `Invalid verificationMethodId: publicKeyMultibase prefix must start with "${MULTIKEY_PUBLIC_KEY_MULTIBASE_PREFIX}"`,
2093
- import_common11.INVALID_DID_DOCUMENT,
2125
+ import_common12.INVALID_DID_DOCUMENT,
2094
2126
  verificationMethod
2095
2127
  );
2096
2128
  }
2097
2129
  const beaconService = sourceDocument.service.filter((service) => service.id === beaconId).filter((service) => !!service).shift();
2098
2130
  if (!beaconService) {
2099
- throw new import_common11.UpdateError(
2131
+ throw new import_common12.UpdateError(
2100
2132
  "No beacon service found for provided beaconId",
2101
- import_common11.INVALID_DID_UPDATE,
2133
+ import_common12.INVALID_DID_UPDATE,
2102
2134
  { sourceDocument, beaconId }
2103
2135
  );
2104
2136
  }
@@ -2124,7 +2156,7 @@ var DidBtcr2 = class {
2124
2156
  methodId ??= "#initialKey";
2125
2157
  const parsedDid = import_dids2.Did.parse(didDocument.id);
2126
2158
  if (parsedDid && parsedDid.method !== this.methodName) {
2127
- throw new import_common11.MethodError(`Method not supported: ${parsedDid.method}`, import_common11.METHOD_NOT_SUPPORTED, { identifier: didDocument.id });
2159
+ throw new import_common12.MethodError(`Method not supported: ${parsedDid.method}`, import_common12.METHOD_NOT_SUPPORTED, { identifier: didDocument.id });
2128
2160
  }
2129
2161
  const verificationMethod = didDocument.verificationMethod?.find(
2130
2162
  (vm) => Appendix.extractDidFragment(vm.id) === (Appendix.extractDidFragment(methodId) ?? Appendix.extractDidFragment(didDocument.assertionMethod?.[0]))
@@ -2155,6 +2187,11 @@ function isSMTProof(value) {
2155
2187
  if (!isRecord(value)) return false;
2156
2188
  return typeof value.id === "string" && typeof value.collapsed === "string" && Array.isArray(value.hashes);
2157
2189
  }
2190
+ function relationshipMethodId(documentId, entry) {
2191
+ const id = isRecord(entry) ? entry.id : entry;
2192
+ if (typeof id !== "string" || id.length === 0) return void 0;
2193
+ return id.startsWith("#") ? `${documentId}${id}` : id;
2194
+ }
2158
2195
  var Resolver = class _Resolver {
2159
2196
  // --- Immutable inputs ---
2160
2197
  #didComponents;
@@ -2244,14 +2281,14 @@ var Resolver = class _Resolver {
2244
2281
  * @throws {ResolveError} InvalidDidDocument if not conformant to DID Core v1.1
2245
2282
  */
2246
2283
  static external(didComponents, genesisDocument) {
2247
- const genesisDocumentHash = (0, import_common12.canonicalHashBytes)(genesisDocument);
2284
+ const genesisDocumentHash = (0, import_common13.canonicalHashBytes)(genesisDocument);
2248
2285
  if (!(0, import_utils6.equalBytes)(didComponents.genesisBytes, genesisDocumentHash)) {
2249
- throw new import_common12.ResolveError(
2286
+ throw new import_common13.ResolveError(
2250
2287
  `Initial document mismatch: genesisBytes !== genesisDocumentHash`,
2251
- import_common12.INVALID_DID_DOCUMENT,
2288
+ import_common13.INVALID_DID_DOCUMENT,
2252
2289
  {
2253
- genesisBytes: (0, import_common12.encode)(didComponents.genesisBytes, "hex"),
2254
- genesisDocumentHash: (0, import_common12.encode)(genesisDocumentHash, "hex")
2290
+ genesisBytes: (0, import_common13.encode)(didComponents.genesisBytes, "hex"),
2291
+ genesisDocumentHash: (0, import_common13.encode)(genesisDocumentHash, "hex")
2255
2292
  }
2256
2293
  );
2257
2294
  }
@@ -2270,17 +2307,17 @@ var Resolver = class _Resolver {
2270
2307
  const updateMap = /* @__PURE__ */ new Map();
2271
2308
  if (sidecar.updates?.length)
2272
2309
  for (const update of sidecar.updates) {
2273
- updateMap.set((0, import_common12.canonicalHash)(update, { encoding: "hex" }), update);
2310
+ updateMap.set((0, import_common13.canonicalHash)(update, { encoding: "hex" }), update);
2274
2311
  }
2275
2312
  const casMap = /* @__PURE__ */ new Map();
2276
2313
  if (sidecar.casUpdates?.length)
2277
2314
  for (const update of sidecar.casUpdates) {
2278
- casMap.set((0, import_common12.canonicalHash)(update, { encoding: "hex" }), update);
2315
+ casMap.set((0, import_common13.canonicalHash)(update, { encoding: "hex" }), update);
2279
2316
  }
2280
2317
  const smtMap = /* @__PURE__ */ new Map();
2281
2318
  if (sidecar.smtProofs?.length)
2282
2319
  for (const proof of sidecar.smtProofs) {
2283
- smtMap.set((0, import_common12.encode)((0, import_common12.decode)(proof.id, "base64urlnopad"), "hex"), proof);
2320
+ smtMap.set((0, import_common13.encode)((0, import_common13.decode)(proof.id, "base64urlnopad"), "hex"), proof);
2284
2321
  }
2285
2322
  return { updateMap, casMap, smtMap };
2286
2323
  }
@@ -2311,38 +2348,38 @@ var Resolver = class _Resolver {
2311
2348
  }
2312
2349
  };
2313
2350
  for (const [update, block] of updates) {
2314
- const currentDocumentHash = (0, import_common12.canonicalHashBytes)(response.didDocument);
2315
- const blocktime = import_common12.DateUtils.blocktimeToTimestamp(block.time);
2316
- response.metadata.updated = import_common12.DateUtils.toISOStringNonFractional(blocktime);
2351
+ const currentDocumentHash = (0, import_common13.canonicalHashBytes)(response.didDocument);
2352
+ const blocktime = import_common13.DateUtils.blocktimeToTimestamp(block.time);
2353
+ response.metadata.updated = import_common13.DateUtils.toISOStringNonFractional(blocktime);
2317
2354
  response.metadata.confirmations = block.confirmations;
2318
2355
  if (update.targetVersionId <= currentVersionId) {
2319
2356
  this.confirmDuplicate(update, updateHashHistory);
2320
2357
  continue;
2321
2358
  }
2322
2359
  if (versionTime) {
2323
- if (blocktime > import_common12.DateUtils.dateStringToTimestamp(versionTime)) {
2360
+ if (blocktime > import_common13.DateUtils.dateStringToTimestamp(versionTime)) {
2324
2361
  return response;
2325
2362
  }
2326
2363
  }
2327
2364
  if (update.targetVersionId === currentVersionId + 1) {
2328
- const sourceHashBytes = (0, import_common12.decode)(update.sourceHash, "base64urlnopad");
2365
+ const sourceHashBytes = (0, import_common13.decode)(update.sourceHash, "base64urlnopad");
2329
2366
  if (!(0, import_utils6.equalBytes)(sourceHashBytes, currentDocumentHash)) {
2330
- throw new import_common12.ResolveError(
2367
+ throw new import_common13.ResolveError(
2331
2368
  `Hash mismatch: update.sourceHash !== currentDocumentHash`,
2332
- import_common12.INVALID_DID_UPDATE,
2369
+ import_common13.INVALID_DID_UPDATE,
2333
2370
  {
2334
2371
  sourceHash: update.sourceHash,
2335
- currentDocumentHash: (0, import_common12.encode)(currentDocumentHash, "hex")
2372
+ currentDocumentHash: (0, import_common13.encode)(currentDocumentHash, "hex")
2336
2373
  }
2337
2374
  );
2338
2375
  }
2339
2376
  response.didDocument = this.applyUpdate(response.didDocument, update);
2340
- const unsignedUpdate = import_common12.JSONUtils.deleteKeys(update, ["proof"]);
2341
- updateHashHistory.push((0, import_common12.canonicalHashBytes)(unsignedUpdate));
2377
+ const unsignedUpdate = import_common13.JSONUtils.deleteKeys(update, ["proof"]);
2378
+ updateHashHistory.push((0, import_common13.canonicalHashBytes)(unsignedUpdate));
2342
2379
  } else {
2343
- throw new import_common12.ResolveError(
2380
+ throw new import_common13.ResolveError(
2344
2381
  `Version Id Mismatch: targetVersionId cannot be > currentVersionId + 1`,
2345
- import_common12.LATE_PUBLISHING_ERROR,
2382
+ import_common13.LATE_PUBLISHING_ERROR,
2346
2383
  {
2347
2384
  targetVersionId: update.targetVersionId,
2348
2385
  currentVersionId: currentVersionId + 1
@@ -2371,19 +2408,19 @@ var Resolver = class _Resolver {
2371
2408
  */
2372
2409
  static confirmDuplicate(update, updateHashHistory) {
2373
2410
  if (!Number.isInteger(update.targetVersionId) || update.targetVersionId < 2) {
2374
- throw new import_common12.ResolveError(
2411
+ throw new import_common13.ResolveError(
2375
2412
  `Invalid duplicate: targetVersionId must be an integer >= 2`,
2376
- import_common12.INVALID_DID_UPDATE,
2413
+ import_common13.INVALID_DID_UPDATE,
2377
2414
  { targetVersionId: update.targetVersionId }
2378
2415
  );
2379
2416
  }
2380
2417
  const { proof: _, ...unsignedUpdate } = update;
2381
- const unsignedUpdateHash = (0, import_common12.canonicalHashBytes)(unsignedUpdate);
2418
+ const unsignedUpdateHash = (0, import_common13.canonicalHashBytes)(unsignedUpdate);
2382
2419
  const historicalUpdateHash = updateHashHistory[update.targetVersionId - 2];
2383
2420
  if (historicalUpdateHash === void 0) {
2384
- throw new import_common12.ResolveError(
2421
+ throw new import_common13.ResolveError(
2385
2422
  `Invalid duplicate: no applied update in history for targetVersionId`,
2386
- import_common12.LATE_PUBLISHING_ERROR,
2423
+ import_common13.LATE_PUBLISHING_ERROR,
2387
2424
  {
2388
2425
  targetVersionId: update.targetVersionId,
2389
2426
  historyLength: updateHashHistory.length
@@ -2391,12 +2428,12 @@ var Resolver = class _Resolver {
2391
2428
  );
2392
2429
  }
2393
2430
  if (!(0, import_utils6.equalBytes)(historicalUpdateHash, unsignedUpdateHash)) {
2394
- throw new import_common12.ResolveError(
2431
+ throw new import_common13.ResolveError(
2395
2432
  `Invalid duplicate: unsigned update hash does not match historical hash`,
2396
- import_common12.LATE_PUBLISHING_ERROR,
2433
+ import_common13.LATE_PUBLISHING_ERROR,
2397
2434
  {
2398
- unsignedUpdateHash: (0, import_common12.encode)(unsignedUpdateHash, "hex"),
2399
- historicalHash: (0, import_common12.encode)(historicalUpdateHash, "hex")
2435
+ unsignedUpdateHash: (0, import_common13.encode)(unsignedUpdateHash, "hex"),
2436
+ historicalHash: (0, import_common13.encode)(historicalUpdateHash, "hex")
2400
2437
  }
2401
2438
  );
2402
2439
  }
@@ -2411,42 +2448,56 @@ var Resolver = class _Resolver {
2411
2448
  static applyUpdate(currentDocument, update) {
2412
2449
  const capabilityId = update.proof?.capability;
2413
2450
  if (!capabilityId) {
2414
- throw new import_common12.ResolveError("No root capability found in update", import_common12.INVALID_DID_UPDATE, update);
2451
+ throw new import_common13.ResolveError("No root capability found in update", import_common13.INVALID_DID_UPDATE, update);
2415
2452
  }
2416
2453
  const rootCapability = Appendix.dereferenceZcapId(capabilityId);
2417
2454
  const { invocationTarget, controller: rootController } = rootCapability;
2418
2455
  if (![invocationTarget, rootController].every((id) => id === currentDocument.id)) {
2419
- throw new import_common12.ResolveError(
2456
+ throw new import_common13.ResolveError(
2420
2457
  "Invalid root capability",
2421
- import_common12.INVALID_DID_UPDATE,
2458
+ import_common13.INVALID_DID_UPDATE,
2422
2459
  { rootCapability, currentDocument }
2423
2460
  );
2424
2461
  }
2425
2462
  const verificationMethodId = update.proof?.verificationMethod;
2426
2463
  if (!verificationMethodId) {
2427
- throw new import_common12.ResolveError("No verificationMethod found in update", import_common12.INVALID_DID_UPDATE, update);
2464
+ throw new import_common13.ResolveError("No verificationMethod found in update", import_common13.INVALID_DID_UPDATE, update);
2465
+ }
2466
+ const authorizedMethodId = relationshipMethodId(currentDocument.id, verificationMethodId);
2467
+ const authorized = authorizedMethodId !== void 0 && currentDocument.capabilityInvocation?.some(
2468
+ (entry) => relationshipMethodId(currentDocument.id, entry) === authorizedMethodId
2469
+ );
2470
+ if (!authorized) {
2471
+ throw new import_common13.ResolveError(
2472
+ "Invalid update: verificationMethod is not authorized for capabilityInvocation",
2473
+ import_common13.INVALID_DID_UPDATE,
2474
+ {
2475
+ verificationMethodId,
2476
+ capabilityInvocation: currentDocument.capabilityInvocation
2477
+ }
2478
+ );
2428
2479
  }
2429
2480
  const vm = DidBtcr2.getSigningMethod(currentDocument, verificationMethodId);
2430
2481
  const multikey = import_cryptosuite2.SchnorrMultikey.fromVerificationMethod(vm);
2431
2482
  const cryptosuite = new import_cryptosuite2.BIP340Cryptosuite(multikey);
2432
- const canonicalUpdate = (0, import_common12.canonicalize)(update);
2483
+ const canonicalUpdate = (0, import_common13.canonicalize)(update);
2433
2484
  const diProof = new import_cryptosuite2.BIP340DataIntegrityProof(cryptosuite);
2434
2485
  const verificationResult = diProof.verifyProof(canonicalUpdate, "capabilityInvocation");
2435
2486
  if (!verificationResult.verified) {
2436
- throw new import_common12.ResolveError(
2487
+ throw new import_common13.ResolveError(
2437
2488
  "Invalid update: proof not verified",
2438
- import_common12.INVALID_DID_UPDATE,
2489
+ import_common13.INVALID_DID_UPDATE,
2439
2490
  verificationResult
2440
2491
  );
2441
2492
  }
2442
- const updatedDocument = import_common12.JSONPatch.apply(currentDocument, update.patch);
2493
+ const updatedDocument = import_common13.JSONPatch.apply(currentDocument, update.patch);
2443
2494
  DidDocument.validate(updatedDocument);
2444
- const currentDocumentHash = (0, import_common12.canonicalHashBytes)(updatedDocument);
2445
- const updateTargetHash = (0, import_common12.decode)(update.targetHash);
2495
+ const currentDocumentHash = (0, import_common13.canonicalHashBytes)(updatedDocument);
2496
+ const updateTargetHash = (0, import_common13.decode)(update.targetHash);
2446
2497
  if (!(0, import_utils6.equalBytes)(updateTargetHash, currentDocumentHash)) {
2447
- throw new import_common12.ResolveError(
2498
+ throw new import_common13.ResolveError(
2448
2499
  `Invalid update: update.targetHash !== currentDocumentHash`,
2449
- import_common12.INVALID_DID_UPDATE,
2500
+ import_common13.INVALID_DID_UPDATE,
2450
2501
  { updateTargetHash, currentDocumentHash }
2451
2502
  );
2452
2503
  }
@@ -2474,7 +2525,7 @@ var Resolver = class _Resolver {
2474
2525
  this.#phase = "BeaconDiscovery" /* BeaconDiscovery */;
2475
2526
  continue;
2476
2527
  }
2477
- const genesisHash = (0, import_common12.encode)(this.#didComponents.genesisBytes, "hex");
2528
+ const genesisHash = (0, import_common13.encode)(this.#didComponents.genesisBytes, "hex");
2478
2529
  return {
2479
2530
  status: "action-required",
2480
2531
  needs: [{ kind: "NeedGenesisDocument", genesisHash }]
@@ -2543,9 +2594,9 @@ var Resolver = class _Resolver {
2543
2594
  });
2544
2595
  if (hasNewServices) {
2545
2596
  if (++this.#discoveryRounds > this.#maxDiscoveryRounds) {
2546
- throw new import_common12.ResolveError(
2597
+ throw new import_common13.ResolveError(
2547
2598
  `Exceeded the configured maximum of ${this.#maxDiscoveryRounds} beacon-discovery rounds. Raise or remove ResolutionOptions.maxDiscoveryRounds to resolve this DID.`,
2548
- import_common12.INTERNAL_ERROR,
2599
+ import_common13.INTERNAL_ERROR,
2549
2600
  { maxDiscoveryRounds: this.#maxDiscoveryRounds, discoveryRounds: this.#discoveryRounds }
2550
2601
  );
2551
2602
  }
@@ -2576,9 +2627,9 @@ var Resolver = class _Resolver {
2576
2627
  switch (need.kind) {
2577
2628
  case "NeedGenesisDocument": {
2578
2629
  if (!isRecord(data)) {
2579
- throw new import_common12.ResolveError(
2630
+ throw new import_common13.ResolveError(
2580
2631
  "Provided data for NeedGenesisDocument must be a document object.",
2581
- import_common12.INVALID_DID_UPDATE,
2632
+ import_common13.INVALID_DID_UPDATE,
2582
2633
  { kind: need.kind }
2583
2634
  );
2584
2635
  }
@@ -2587,9 +2638,9 @@ var Resolver = class _Resolver {
2587
2638
  }
2588
2639
  case "NeedBeaconSignals": {
2589
2640
  if (!(data instanceof Map)) {
2590
- throw new import_common12.ResolveError(
2641
+ throw new import_common13.ResolveError(
2591
2642
  "Provided data for NeedBeaconSignals must be a Map of beacon services to signals.",
2592
- import_common12.INVALID_DID_UPDATE,
2643
+ import_common13.INVALID_DID_UPDATE,
2593
2644
  { kind: need.kind }
2594
2645
  );
2595
2646
  }
@@ -2600,17 +2651,17 @@ var Resolver = class _Resolver {
2600
2651
  }
2601
2652
  case "NeedCASAnnouncement": {
2602
2653
  if (!isCASAnnouncement(data)) {
2603
- throw new import_common12.ResolveError(
2654
+ throw new import_common13.ResolveError(
2604
2655
  "Provided data for NeedCASAnnouncement is not a CAS announcement.",
2605
- import_common12.INVALID_DID_UPDATE,
2656
+ import_common13.INVALID_DID_UPDATE,
2606
2657
  { kind: need.kind }
2607
2658
  );
2608
2659
  }
2609
- const announcementHash = (0, import_common12.canonicalHash)(data, { encoding: "hex" });
2660
+ const announcementHash = (0, import_common13.canonicalHash)(data, { encoding: "hex" });
2610
2661
  if (announcementHash !== need.announcementHash) {
2611
- throw new import_common12.ResolveError(
2662
+ throw new import_common13.ResolveError(
2612
2663
  `CAS announcement hash mismatch: expected ${need.announcementHash}, got ${announcementHash}.`,
2613
- import_common12.INVALID_DID_UPDATE,
2664
+ import_common13.INVALID_DID_UPDATE,
2614
2665
  { expected: need.announcementHash, actual: announcementHash }
2615
2666
  );
2616
2667
  }
@@ -2619,17 +2670,17 @@ var Resolver = class _Resolver {
2619
2670
  }
2620
2671
  case "NeedSignedUpdate": {
2621
2672
  if (!isSignedBTCR2Update(data)) {
2622
- throw new import_common12.ResolveError(
2673
+ throw new import_common13.ResolveError(
2623
2674
  "Provided data for NeedSignedUpdate is not a signed BTCR2 update.",
2624
- import_common12.INVALID_DID_UPDATE,
2675
+ import_common13.INVALID_DID_UPDATE,
2625
2676
  { kind: need.kind }
2626
2677
  );
2627
2678
  }
2628
- const updateHash = (0, import_common12.canonicalHash)(data, { encoding: "hex" });
2679
+ const updateHash = (0, import_common13.canonicalHash)(data, { encoding: "hex" });
2629
2680
  if (updateHash !== need.updateHash) {
2630
- throw new import_common12.ResolveError(
2681
+ throw new import_common13.ResolveError(
2631
2682
  `Signed update hash mismatch: expected ${need.updateHash}, got ${updateHash}.`,
2632
- import_common12.INVALID_DID_UPDATE,
2683
+ import_common13.INVALID_DID_UPDATE,
2633
2684
  { expected: need.updateHash, actual: updateHash }
2634
2685
  );
2635
2686
  }
@@ -2638,17 +2689,17 @@ var Resolver = class _Resolver {
2638
2689
  }
2639
2690
  case "NeedSMTProof": {
2640
2691
  if (!isSMTProof(data)) {
2641
- throw new import_common12.ResolveError(
2692
+ throw new import_common13.ResolveError(
2642
2693
  "Provided data for NeedSMTProof is not an SMT proof.",
2643
- import_common12.INVALID_DID_UPDATE,
2694
+ import_common13.INVALID_DID_UPDATE,
2644
2695
  { kind: need.kind }
2645
2696
  );
2646
2697
  }
2647
- const proofIdHex = (0, import_common12.encode)((0, import_common12.decode)(data.id, "base64urlnopad"), "hex");
2698
+ const proofIdHex = (0, import_common13.encode)((0, import_common13.decode)(data.id, "base64urlnopad"), "hex");
2648
2699
  if (proofIdHex !== need.smtRootHash) {
2649
- throw new import_common12.ResolveError(
2700
+ throw new import_common13.ResolveError(
2650
2701
  `SMT proof root hash mismatch: expected ${need.smtRootHash}, got ${proofIdHex}`,
2651
- import_common12.INVALID_DID_UPDATE,
2702
+ import_common13.INVALID_DID_UPDATE,
2652
2703
  { expected: need.smtRootHash, actual: proofIdHex }
2653
2704
  );
2654
2705
  }
@@ -2663,17 +2714,17 @@ var Resolver = class _Resolver {
2663
2714
  function getAggregationCommunicationKey(document) {
2664
2715
  const invocation = document.capabilityInvocation?.[0];
2665
2716
  if (invocation === void 0) {
2666
- throw new import_common13.DidDocumentError(
2717
+ throw new import_common14.DidDocumentError(
2667
2718
  "Cannot derive aggregation communication key: capabilityInvocation is absent",
2668
- import_common13.INVALID_DID_DOCUMENT,
2719
+ import_common14.INVALID_DID_DOCUMENT,
2669
2720
  { id: document.id }
2670
2721
  );
2671
2722
  }
2672
2723
  const vm = typeof invocation === "string" ? document.verificationMethod?.find((method) => method.id === invocation) : invocation;
2673
2724
  if (!vm) {
2674
- throw new import_common13.DidDocumentError(
2725
+ throw new import_common14.DidDocumentError(
2675
2726
  `Cannot derive aggregation communication key: capabilityInvocation[0] "${invocation}" does not resolve to a verification method`,
2676
- import_common13.INVALID_DID_DOCUMENT,
2727
+ import_common14.INVALID_DID_DOCUMENT,
2677
2728
  { id: document.id, invocation }
2678
2729
  );
2679
2730
  }
@@ -2695,12 +2746,12 @@ function resolveBtcr2SenderPk(did, opts) {
2695
2746
  }
2696
2747
 
2697
2748
  // src/utils/did-document-builder.ts
2698
- var import_common14 = require("@did-btcr2/common");
2749
+ var import_common15 = require("@did-btcr2/common");
2699
2750
  var DidDocumentBuilder = class {
2700
2751
  document = {};
2701
2752
  constructor(initialDocument) {
2702
2753
  if (!initialDocument.id) {
2703
- throw new import_common14.DidDocumentError('Missing required "id" property', import_common14.INVALID_DID_DOCUMENT, initialDocument);
2754
+ throw new import_common15.DidDocumentError('Missing required "id" property', import_common15.INVALID_DID_DOCUMENT, initialDocument);
2704
2755
  }
2705
2756
  this.document.id = initialDocument.id;
2706
2757
  this.document.verificationMethod = initialDocument.verificationMethod ?? [];
@@ -2790,7 +2841,7 @@ var DidDocumentBuilder = class {
2790
2841
  buildAggregationBeaconTx,
2791
2842
  deriveSingletonAddress,
2792
2843
  detectSingletonScriptKind,
2793
- extractOpReturnSignal,
2844
+ extractOpReturnSignalHash,
2794
2845
  getAggregationCommunicationKey,
2795
2846
  isMultikeyVerificationMethod,
2796
2847
  opReturnScript,