@did-btcr2/method 0.33.0 → 0.34.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.
Files changed (51) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/browser.js +183 -9
  3. package/dist/browser.mjs +183 -9
  4. package/dist/cjs/index.js +198 -23
  5. package/dist/esm/core/aggregation/runner/aggregation-runner.js +66 -0
  6. package/dist/esm/core/aggregation/runner/aggregation-runner.js.map +1 -0
  7. package/dist/esm/core/aggregation/runner/index.js +1 -0
  8. package/dist/esm/core/aggregation/runner/index.js.map +1 -1
  9. package/dist/esm/core/aggregation/transport/in-memory.js +146 -0
  10. package/dist/esm/core/aggregation/transport/in-memory.js.map +1 -0
  11. package/dist/esm/core/aggregation/transport/index.js +1 -0
  12. package/dist/esm/core/aggregation/transport/index.js.map +1 -1
  13. package/dist/esm/core/beacon/beacon.js +10 -8
  14. package/dist/esm/core/beacon/beacon.js.map +1 -1
  15. package/dist/esm/core/beacon/cas-beacon.js +4 -4
  16. package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
  17. package/dist/esm/core/beacon/factory.js +1 -1
  18. package/dist/esm/core/beacon/singleton-beacon.js +4 -4
  19. package/dist/esm/core/beacon/singleton-beacon.js.map +1 -1
  20. package/dist/esm/core/beacon/smt-beacon.js +4 -4
  21. package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
  22. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts +56 -0
  23. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts.map +1 -0
  24. package/dist/types/core/aggregation/runner/index.d.ts +1 -0
  25. package/dist/types/core/aggregation/runner/index.d.ts.map +1 -1
  26. package/dist/types/core/aggregation/transport/in-memory.d.ts +64 -0
  27. package/dist/types/core/aggregation/transport/in-memory.d.ts.map +1 -0
  28. package/dist/types/core/aggregation/transport/index.d.ts +1 -0
  29. package/dist/types/core/aggregation/transport/index.d.ts.map +1 -1
  30. package/dist/types/core/beacon/beacon.d.ts +12 -10
  31. package/dist/types/core/beacon/beacon.d.ts.map +1 -1
  32. package/dist/types/core/beacon/cas-beacon.d.ts +4 -4
  33. package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
  34. package/dist/types/core/beacon/factory.d.ts +3 -3
  35. package/dist/types/core/beacon/factory.d.ts.map +1 -1
  36. package/dist/types/core/beacon/singleton-beacon.d.ts +4 -4
  37. package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
  38. package/dist/types/core/beacon/smt-beacon.d.ts +4 -4
  39. package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
  40. package/dist/types/core/resolver.d.ts +1 -1
  41. package/package.json +4 -4
  42. package/src/core/aggregation/runner/aggregation-runner.ts +96 -0
  43. package/src/core/aggregation/runner/index.ts +1 -0
  44. package/src/core/aggregation/transport/in-memory.ts +174 -0
  45. package/src/core/aggregation/transport/index.ts +1 -0
  46. package/src/core/beacon/beacon.ts +12 -10
  47. package/src/core/beacon/cas-beacon.ts +4 -4
  48. package/src/core/beacon/factory.ts +3 -3
  49. package/src/core/beacon/singleton-beacon.ts +4 -4
  50. package/src/core/beacon/smt-beacon.ts +4 -4
  51. package/src/core/resolver.ts +1 -1
package/dist/browser.js CHANGED
@@ -93157,6 +93157,7 @@ a=end-of-candidates
93157
93157
  AggregationParticipant: () => AggregationParticipant,
93158
93158
  AggregationParticipantError: () => AggregationParticipantError,
93159
93159
  AggregationParticipantRunner: () => AggregationParticipantRunner,
93160
+ AggregationRunner: () => AggregationRunner,
93160
93161
  AggregationService: () => AggregationService,
93161
93162
  AggregationServiceError: () => AggregationServiceError,
93162
93163
  AggregationServiceRunner: () => AggregationServiceRunner,
@@ -93164,7 +93165,6 @@ a=end-of-candidates
93164
93165
  BECH32M_CHARS: () => BECH32M_CHARS,
93165
93166
  BTCR2_DID_DOCUMENT_CONTEXT: () => BTCR2_DID_DOCUMENT_CONTEXT,
93166
93167
  BaseMessage: () => BaseMessage,
93167
- Beacon: () => Beacon,
93168
93168
  BeaconError: () => BeaconError,
93169
93169
  BeaconFactory: () => BeaconFactory,
93170
93170
  BeaconSignalDiscovery: () => BeaconSignalDiscovery,
@@ -93199,7 +93199,9 @@ a=end-of-candidates
93199
93199
  HttpTransportError: () => HttpTransportError,
93200
93200
  ID_PLACEHOLDER_VALUE: () => ID_PLACEHOLDER_VALUE,
93201
93201
  Identifier: () => Identifier,
93202
+ InMemoryBus: () => InMemoryBus,
93202
93203
  InMemoryRateLimitStore: () => InMemoryRateLimitStore,
93204
+ InMemoryTransport: () => InMemoryTransport,
93203
93205
  InboxBuffer: () => InboxBuffer,
93204
93206
  NONCE_CONTRIBUTION: () => NONCE_CONTRIBUTION,
93205
93207
  NonceCache: () => NonceCache,
@@ -93221,6 +93223,7 @@ a=end-of-candidates
93221
93223
  ServiceCohortPhase: () => ServiceCohortPhase,
93222
93224
  SigningSessionError: () => SigningSessionError,
93223
93225
  SigningSessionPhase: () => SigningSessionPhase,
93226
+ SinglePartyBeacon: () => SinglePartyBeacon,
93224
93227
  SingletonBeacon: () => SingletonBeacon,
93225
93228
  SingletonBeaconError: () => SingletonBeaconError,
93226
93229
  StaticFeeEstimator: () => StaticFeeEstimator,
@@ -111126,6 +111129,120 @@ ${value2}`;
111126
111129
  }
111127
111130
  };
111128
111131
 
111132
+ // src/core/aggregation/transport/in-memory.ts
111133
+ init_shim();
111134
+ init_utils();
111135
+ var InMemoryBus = class {
111136
+ #transports = /* @__PURE__ */ new Set();
111137
+ /** Attach a transport to this bus. Called by the transport's constructor. */
111138
+ register(transport) {
111139
+ this.#transports.add(transport);
111140
+ }
111141
+ /** Detach a transport from this bus. */
111142
+ unregister(transport) {
111143
+ this.#transports.delete(transport);
111144
+ }
111145
+ /**
111146
+ * Deliver a message. With no `recipient` the message is broadcast to every
111147
+ * actor on the bus; otherwise it is routed to the single transport that owns
111148
+ * the recipient DID.
111149
+ */
111150
+ async deliver(message2, _sender, recipient) {
111151
+ const type = message2.type;
111152
+ if (!type) return;
111153
+ const replacer = (_k, v) => v instanceof Uint8Array ? { __bytes: bytesToHex(v) } : v;
111154
+ const reviver = (_k, v) => v && typeof v === "object" && "__bytes" in v ? hexToBytes(v.__bytes) : v;
111155
+ const raw = JSON.parse(JSON.stringify(message2, replacer), reviver);
111156
+ const serialized = { ...raw, ...raw.body ?? {} };
111157
+ if (!recipient) {
111158
+ for (const t2 of this.#transports) {
111159
+ await t2.dispatchBroadcast(type, serialized);
111160
+ }
111161
+ return;
111162
+ }
111163
+ for (const t2 of this.#transports) {
111164
+ if (t2.hasActor(recipient)) {
111165
+ await t2.dispatchDirected(recipient, type, serialized);
111166
+ return;
111167
+ }
111168
+ }
111169
+ }
111170
+ };
111171
+ var InMemoryTransport = class {
111172
+ name = "in-memory";
111173
+ bus;
111174
+ #actors = /* @__PURE__ */ new Map();
111175
+ #peers = /* @__PURE__ */ new Map();
111176
+ /** @param bus Shared bus. Pass the same bus to connect multiple transports. */
111177
+ constructor(bus = new InMemoryBus()) {
111178
+ this.bus = bus;
111179
+ this.bus.register(this);
111180
+ }
111181
+ start() {
111182
+ }
111183
+ registerActor(did, keys) {
111184
+ this.#actors.set(did, { keys, handlers: /* @__PURE__ */ new Map() });
111185
+ }
111186
+ getActorPk(did) {
111187
+ return this.#actors.get(did)?.keys.publicKey.compressed;
111188
+ }
111189
+ /** True if `did` is registered on this transport. Used by the bus for routing. */
111190
+ hasActor(did) {
111191
+ return this.#actors.has(did);
111192
+ }
111193
+ registerPeer(did, communicationPk) {
111194
+ this.#peers.set(did, communicationPk);
111195
+ }
111196
+ getPeerPk(did) {
111197
+ return this.#peers.get(did);
111198
+ }
111199
+ registerMessageHandler(actorDid, messageType, handler) {
111200
+ const actor = this.#actors.get(actorDid);
111201
+ if (actor) actor.handlers.set(messageType, handler);
111202
+ }
111203
+ unregisterMessageHandler(actorDid, messageType) {
111204
+ const actor = this.#actors.get(actorDid);
111205
+ if (actor) actor.handlers.delete(messageType);
111206
+ }
111207
+ unregisterActor(did) {
111208
+ const actor = this.#actors.get(did);
111209
+ if (!actor) return;
111210
+ actor.handlers.clear();
111211
+ this.#actors.delete(did);
111212
+ this.#peers.delete(did);
111213
+ }
111214
+ async sendMessage(message2, sender, recipient) {
111215
+ await this.bus.deliver(message2, sender, recipient);
111216
+ }
111217
+ publishRepeating(message2, sender, intervalMs, recipient) {
111218
+ let stopped = false;
111219
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111220
+ });
111221
+ const timer = setInterval(() => {
111222
+ if (stopped) return;
111223
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111224
+ });
111225
+ }, intervalMs);
111226
+ return () => {
111227
+ if (stopped) return;
111228
+ stopped = true;
111229
+ clearInterval(timer);
111230
+ };
111231
+ }
111232
+ /** Deliver a broadcast message to every actor on this transport that handles `type`. */
111233
+ async dispatchBroadcast(type, message2) {
111234
+ for (const actor of this.#actors.values()) {
111235
+ const handler = actor.handlers.get(type);
111236
+ if (handler) await handler(message2);
111237
+ }
111238
+ }
111239
+ /** Deliver a directed message to the recipient actor's handler for `type`. */
111240
+ async dispatchDirected(recipientDid, type, message2) {
111241
+ const handler = this.#actors.get(recipientDid)?.handlers.get(type);
111242
+ if (handler) await handler(message2);
111243
+ }
111244
+ };
111245
+
111129
111246
  // src/core/aggregation/transport/didcomm.ts
111130
111247
  init_shim();
111131
111248
  var DidCommTransport = class {
@@ -111866,6 +111983,63 @@ ${value2}`;
111866
111983
  }
111867
111984
  };
111868
111985
 
111986
+ // src/core/aggregation/runner/aggregation-runner.ts
111987
+ init_shim();
111988
+ var AggregationRunner = class {
111989
+ /**
111990
+ * Run a cohort of ONE participant entirely in-process and return the
111991
+ * aggregated MuSig2 result.
111992
+ *
111993
+ * One party plays both the coordinating service and the lone participant,
111994
+ * connected over an {@link InMemoryTransport} (no relay or HTTP server). This
111995
+ * makes the single-participant aggregate-beacon path — the N=1 corner of the
111996
+ * two-axis beacon matrix (see ADR 037) — first-class, useful for generating
111997
+ * and reproducing single-participant aggregate test vectors.
111998
+ *
111999
+ * The service advertises a cohort with `minParticipants: 1`; the participant
112000
+ * joins, submits its update, and the two complete keygen, data distribution,
112001
+ * validation, and a one-signer MuSig2 P2TR key-path signing round.
112002
+ *
112003
+ * @param options Service + participant identities, cohort config, and the
112004
+ * update / tx-data callbacks.
112005
+ * @returns The {@link AggregationResult} (cohort id, aggregated signature, signed tx).
112006
+ */
112007
+ static async solo(options2) {
112008
+ const transport = new InMemoryTransport(new InMemoryBus());
112009
+ transport.registerActor(options2.service.did, options2.service.keys);
112010
+ transport.registerActor(options2.participant.did, options2.participant.keys);
112011
+ transport.registerPeer(options2.participant.did, options2.participant.keys.publicKey.compressed);
112012
+ transport.registerPeer(options2.service.did, options2.service.keys.publicKey.compressed);
112013
+ transport.start();
112014
+ const service = new AggregationServiceRunner({
112015
+ transport,
112016
+ did: options2.service.did,
112017
+ keys: options2.service.keys,
112018
+ config: { minParticipants: 1, network: options2.config.network, beaconType: options2.config.beaconType },
112019
+ onProvideTxData: options2.onProvideTxData,
112020
+ cohortTtlMs: options2.cohortTtlMs,
112021
+ phaseTimeoutMs: options2.phaseTimeoutMs,
112022
+ // In-process bus with the participant already listening: a single advert
112023
+ // suffices, so disable the republish loop (no dangling interval).
112024
+ advertRepeatIntervalMs: 0
112025
+ });
112026
+ const participant = new AggregationParticipantRunner({
112027
+ transport,
112028
+ did: options2.participant.did,
112029
+ keys: options2.participant.keys,
112030
+ shouldJoin: async () => true,
112031
+ onProvideUpdate: options2.onProvideUpdate
112032
+ });
112033
+ await participant.start();
112034
+ try {
112035
+ return await service.run();
112036
+ } finally {
112037
+ participant.stop();
112038
+ service.stop();
112039
+ }
112040
+ }
112041
+ };
112042
+
111869
112043
  // src/core/beacon/beacon.ts
111870
112044
  init_shim();
111871
112045
  init_utils();
@@ -112036,7 +112210,7 @@ ${value2}`;
112036
112210
  tx.finalize();
112037
112211
  return tx.hex;
112038
112212
  }
112039
- var Beacon = class {
112213
+ var SinglePartyBeacon = class {
112040
112214
  /**
112041
112215
  * The Beacon service configuration parsed from the DID Document.
112042
112216
  */
@@ -112173,7 +112347,7 @@ ${value2}`;
112173
112347
 
112174
112348
  // src/core/beacon/cas-beacon.ts
112175
112349
  init_shim();
112176
- var CASBeacon = class extends Beacon {
112350
+ var CASBeacon = class extends SinglePartyBeacon {
112177
112351
  /**
112178
112352
  * Creates an instance of CASBeacon.
112179
112353
  * @param {BeaconService} service The service of the Beacon.
@@ -112233,7 +112407,7 @@ ${value2}`;
112233
112407
  * Creates a CAS Announcement mapping the DID to the update hash, broadcasts the hash of the
112234
112408
  * announcement via OP_RETURN, and optionally publishes the announcement off-chain via the
112235
112409
  * supplied `casPublish` callback. UTXO selection, PSBT construction, fee estimation, signing,
112236
- * and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112410
+ * and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112237
112411
  *
112238
112412
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112239
112413
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112261,7 +112435,7 @@ ${value2}`;
112261
112435
 
112262
112436
  // src/core/beacon/singleton-beacon.ts
112263
112437
  init_shim();
112264
- var SingletonBeacon = class extends Beacon {
112438
+ var SingletonBeacon = class extends SinglePartyBeacon {
112265
112439
  /**
112266
112440
  * Creates an instance of SingletonBeacon.
112267
112441
  * @param {BeaconService} service The BeaconService object representing the funded beacon to announce the update to.
@@ -112298,7 +112472,7 @@ ${value2}`;
112298
112472
  *
112299
112473
  * The signal bytes embedded in OP_RETURN are the SHA-256 canonical hash of the signed update.
112300
112474
  * UTXO selection, PSBT construction, fee estimation, signing, and broadcast are delegated to
112301
- * {@link Beacon.buildSignAndBroadcast}.
112475
+ * {@link SinglePartyBeacon.buildSignAndBroadcast}.
112302
112476
  *
112303
112477
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112304
112478
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112317,7 +112491,7 @@ ${value2}`;
112317
112491
  // src/core/beacon/smt-beacon.ts
112318
112492
  init_shim();
112319
112493
  init_utils();
112320
- var SMTBeacon = class extends Beacon {
112494
+ var SMTBeacon = class extends SinglePartyBeacon {
112321
112495
  /**
112322
112496
  * Creates an instance of SMTBeacon.
112323
112497
  * @param {BeaconService} service The Beacon service.
@@ -112393,7 +112567,7 @@ ${value2}`;
112393
112567
  * Builds a single-entry Sparse Merkle Tree from the signed update, then broadcasts the tree's
112394
112568
  * root hash via OP_RETURN. For multi-party aggregation, use the {@link AggregationService}
112395
112569
  * subsystem directly instead of this method. UTXO selection, PSBT construction, fee estimation,
112396
- * signing, and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112570
+ * signing, and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112397
112571
  *
112398
112572
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112399
112573
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112419,7 +112593,7 @@ ${value2}`;
112419
112593
  /**
112420
112594
  * Establish a Beacon instance based on the provided service and optional sidecar data.
112421
112595
  * @param {BeaconService} service The beacon service configuration.
112422
- * @returns {Beacon} The established Beacon instance.
112596
+ * @returns {SinglePartyBeacon} The established Beacon instance.
112423
112597
  */
112424
112598
  static establish(service) {
112425
112599
  switch (service.type) {
package/dist/browser.mjs CHANGED
@@ -110994,6 +110994,120 @@ var TransportFactory = class {
110994
110994
  }
110995
110995
  };
110996
110996
 
110997
+ // src/core/aggregation/transport/in-memory.ts
110998
+ init_shim();
110999
+ init_utils();
111000
+ var InMemoryBus = class {
111001
+ #transports = /* @__PURE__ */ new Set();
111002
+ /** Attach a transport to this bus. Called by the transport's constructor. */
111003
+ register(transport) {
111004
+ this.#transports.add(transport);
111005
+ }
111006
+ /** Detach a transport from this bus. */
111007
+ unregister(transport) {
111008
+ this.#transports.delete(transport);
111009
+ }
111010
+ /**
111011
+ * Deliver a message. With no `recipient` the message is broadcast to every
111012
+ * actor on the bus; otherwise it is routed to the single transport that owns
111013
+ * the recipient DID.
111014
+ */
111015
+ async deliver(message2, _sender, recipient) {
111016
+ const type = message2.type;
111017
+ if (!type) return;
111018
+ const replacer = (_k, v) => v instanceof Uint8Array ? { __bytes: bytesToHex(v) } : v;
111019
+ const reviver = (_k, v) => v && typeof v === "object" && "__bytes" in v ? hexToBytes(v.__bytes) : v;
111020
+ const raw = JSON.parse(JSON.stringify(message2, replacer), reviver);
111021
+ const serialized = { ...raw, ...raw.body ?? {} };
111022
+ if (!recipient) {
111023
+ for (const t2 of this.#transports) {
111024
+ await t2.dispatchBroadcast(type, serialized);
111025
+ }
111026
+ return;
111027
+ }
111028
+ for (const t2 of this.#transports) {
111029
+ if (t2.hasActor(recipient)) {
111030
+ await t2.dispatchDirected(recipient, type, serialized);
111031
+ return;
111032
+ }
111033
+ }
111034
+ }
111035
+ };
111036
+ var InMemoryTransport = class {
111037
+ name = "in-memory";
111038
+ bus;
111039
+ #actors = /* @__PURE__ */ new Map();
111040
+ #peers = /* @__PURE__ */ new Map();
111041
+ /** @param bus Shared bus. Pass the same bus to connect multiple transports. */
111042
+ constructor(bus = new InMemoryBus()) {
111043
+ this.bus = bus;
111044
+ this.bus.register(this);
111045
+ }
111046
+ start() {
111047
+ }
111048
+ registerActor(did, keys) {
111049
+ this.#actors.set(did, { keys, handlers: /* @__PURE__ */ new Map() });
111050
+ }
111051
+ getActorPk(did) {
111052
+ return this.#actors.get(did)?.keys.publicKey.compressed;
111053
+ }
111054
+ /** True if `did` is registered on this transport. Used by the bus for routing. */
111055
+ hasActor(did) {
111056
+ return this.#actors.has(did);
111057
+ }
111058
+ registerPeer(did, communicationPk) {
111059
+ this.#peers.set(did, communicationPk);
111060
+ }
111061
+ getPeerPk(did) {
111062
+ return this.#peers.get(did);
111063
+ }
111064
+ registerMessageHandler(actorDid, messageType, handler) {
111065
+ const actor = this.#actors.get(actorDid);
111066
+ if (actor) actor.handlers.set(messageType, handler);
111067
+ }
111068
+ unregisterMessageHandler(actorDid, messageType) {
111069
+ const actor = this.#actors.get(actorDid);
111070
+ if (actor) actor.handlers.delete(messageType);
111071
+ }
111072
+ unregisterActor(did) {
111073
+ const actor = this.#actors.get(did);
111074
+ if (!actor) return;
111075
+ actor.handlers.clear();
111076
+ this.#actors.delete(did);
111077
+ this.#peers.delete(did);
111078
+ }
111079
+ async sendMessage(message2, sender, recipient) {
111080
+ await this.bus.deliver(message2, sender, recipient);
111081
+ }
111082
+ publishRepeating(message2, sender, intervalMs, recipient) {
111083
+ let stopped = false;
111084
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111085
+ });
111086
+ const timer = setInterval(() => {
111087
+ if (stopped) return;
111088
+ void this.sendMessage(message2, sender, recipient).catch(() => {
111089
+ });
111090
+ }, intervalMs);
111091
+ return () => {
111092
+ if (stopped) return;
111093
+ stopped = true;
111094
+ clearInterval(timer);
111095
+ };
111096
+ }
111097
+ /** Deliver a broadcast message to every actor on this transport that handles `type`. */
111098
+ async dispatchBroadcast(type, message2) {
111099
+ for (const actor of this.#actors.values()) {
111100
+ const handler = actor.handlers.get(type);
111101
+ if (handler) await handler(message2);
111102
+ }
111103
+ }
111104
+ /** Deliver a directed message to the recipient actor's handler for `type`. */
111105
+ async dispatchDirected(recipientDid, type, message2) {
111106
+ const handler = this.#actors.get(recipientDid)?.handlers.get(type);
111107
+ if (handler) await handler(message2);
111108
+ }
111109
+ };
111110
+
110997
111111
  // src/core/aggregation/transport/didcomm.ts
110998
111112
  init_shim();
110999
111113
  var DidCommTransport = class {
@@ -111734,6 +111848,63 @@ var AggregationParticipantRunner = class _AggregationParticipantRunner extends T
111734
111848
  }
111735
111849
  };
111736
111850
 
111851
+ // src/core/aggregation/runner/aggregation-runner.ts
111852
+ init_shim();
111853
+ var AggregationRunner = class {
111854
+ /**
111855
+ * Run a cohort of ONE participant entirely in-process and return the
111856
+ * aggregated MuSig2 result.
111857
+ *
111858
+ * One party plays both the coordinating service and the lone participant,
111859
+ * connected over an {@link InMemoryTransport} (no relay or HTTP server). This
111860
+ * makes the single-participant aggregate-beacon path — the N=1 corner of the
111861
+ * two-axis beacon matrix (see ADR 037) — first-class, useful for generating
111862
+ * and reproducing single-participant aggregate test vectors.
111863
+ *
111864
+ * The service advertises a cohort with `minParticipants: 1`; the participant
111865
+ * joins, submits its update, and the two complete keygen, data distribution,
111866
+ * validation, and a one-signer MuSig2 P2TR key-path signing round.
111867
+ *
111868
+ * @param options Service + participant identities, cohort config, and the
111869
+ * update / tx-data callbacks.
111870
+ * @returns The {@link AggregationResult} (cohort id, aggregated signature, signed tx).
111871
+ */
111872
+ static async solo(options2) {
111873
+ const transport = new InMemoryTransport(new InMemoryBus());
111874
+ transport.registerActor(options2.service.did, options2.service.keys);
111875
+ transport.registerActor(options2.participant.did, options2.participant.keys);
111876
+ transport.registerPeer(options2.participant.did, options2.participant.keys.publicKey.compressed);
111877
+ transport.registerPeer(options2.service.did, options2.service.keys.publicKey.compressed);
111878
+ transport.start();
111879
+ const service = new AggregationServiceRunner({
111880
+ transport,
111881
+ did: options2.service.did,
111882
+ keys: options2.service.keys,
111883
+ config: { minParticipants: 1, network: options2.config.network, beaconType: options2.config.beaconType },
111884
+ onProvideTxData: options2.onProvideTxData,
111885
+ cohortTtlMs: options2.cohortTtlMs,
111886
+ phaseTimeoutMs: options2.phaseTimeoutMs,
111887
+ // In-process bus with the participant already listening: a single advert
111888
+ // suffices, so disable the republish loop (no dangling interval).
111889
+ advertRepeatIntervalMs: 0
111890
+ });
111891
+ const participant = new AggregationParticipantRunner({
111892
+ transport,
111893
+ did: options2.participant.did,
111894
+ keys: options2.participant.keys,
111895
+ shouldJoin: async () => true,
111896
+ onProvideUpdate: options2.onProvideUpdate
111897
+ });
111898
+ await participant.start();
111899
+ try {
111900
+ return await service.run();
111901
+ } finally {
111902
+ participant.stop();
111903
+ service.stop();
111904
+ }
111905
+ }
111906
+ };
111907
+
111737
111908
  // src/core/beacon/beacon.ts
111738
111909
  init_shim();
111739
111910
  init_utils();
@@ -111904,7 +112075,7 @@ async function signSingletonInput(tx, inputIdx, kind, signer, prevOutScript, amo
111904
112075
  tx.finalize();
111905
112076
  return tx.hex;
111906
112077
  }
111907
- var Beacon = class {
112078
+ var SinglePartyBeacon = class {
111908
112079
  /**
111909
112080
  * The Beacon service configuration parsed from the DID Document.
111910
112081
  */
@@ -112041,7 +112212,7 @@ var Beacon = class {
112041
112212
 
112042
112213
  // src/core/beacon/cas-beacon.ts
112043
112214
  init_shim();
112044
- var CASBeacon = class extends Beacon {
112215
+ var CASBeacon = class extends SinglePartyBeacon {
112045
112216
  /**
112046
112217
  * Creates an instance of CASBeacon.
112047
112218
  * @param {BeaconService} service The service of the Beacon.
@@ -112101,7 +112272,7 @@ var CASBeacon = class extends Beacon {
112101
112272
  * Creates a CAS Announcement mapping the DID to the update hash, broadcasts the hash of the
112102
112273
  * announcement via OP_RETURN, and optionally publishes the announcement off-chain via the
112103
112274
  * supplied `casPublish` callback. UTXO selection, PSBT construction, fee estimation, signing,
112104
- * and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112275
+ * and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112105
112276
  *
112106
112277
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112107
112278
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112129,7 +112300,7 @@ init_shim();
112129
112300
 
112130
112301
  // src/core/beacon/singleton-beacon.ts
112131
112302
  init_shim();
112132
- var SingletonBeacon = class extends Beacon {
112303
+ var SingletonBeacon = class extends SinglePartyBeacon {
112133
112304
  /**
112134
112305
  * Creates an instance of SingletonBeacon.
112135
112306
  * @param {BeaconService} service The BeaconService object representing the funded beacon to announce the update to.
@@ -112166,7 +112337,7 @@ var SingletonBeacon = class extends Beacon {
112166
112337
  *
112167
112338
  * The signal bytes embedded in OP_RETURN are the SHA-256 canonical hash of the signed update.
112168
112339
  * UTXO selection, PSBT construction, fee estimation, signing, and broadcast are delegated to
112169
- * {@link Beacon.buildSignAndBroadcast}.
112340
+ * {@link SinglePartyBeacon.buildSignAndBroadcast}.
112170
112341
  *
112171
112342
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112172
112343
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112185,7 +112356,7 @@ var SingletonBeacon = class extends Beacon {
112185
112356
  // src/core/beacon/smt-beacon.ts
112186
112357
  init_shim();
112187
112358
  init_utils();
112188
- var SMTBeacon = class extends Beacon {
112359
+ var SMTBeacon = class extends SinglePartyBeacon {
112189
112360
  /**
112190
112361
  * Creates an instance of SMTBeacon.
112191
112362
  * @param {BeaconService} service The Beacon service.
@@ -112261,7 +112432,7 @@ var SMTBeacon = class extends Beacon {
112261
112432
  * Builds a single-entry Sparse Merkle Tree from the signed update, then broadcasts the tree's
112262
112433
  * root hash via OP_RETURN. For multi-party aggregation, use the {@link AggregationService}
112263
112434
  * subsystem directly instead of this method. UTXO selection, PSBT construction, fee estimation,
112264
- * signing, and broadcast are delegated to {@link Beacon.buildSignAndBroadcast}.
112435
+ * signing, and broadcast are delegated to {@link SinglePartyBeacon.buildSignAndBroadcast}.
112265
112436
  *
112266
112437
  * @param {SignedBTCR2Update} signedUpdate The signed BTCR2 update to broadcast.
112267
112438
  * @param {Signer} signer Signer that produces the ECDSA signature for the Bitcoin transaction.
@@ -112287,7 +112458,7 @@ var BeaconFactory = class {
112287
112458
  /**
112288
112459
  * Establish a Beacon instance based on the provided service and optional sidecar data.
112289
112460
  * @param {BeaconService} service The beacon service configuration.
112290
- * @returns {Beacon} The established Beacon instance.
112461
+ * @returns {SinglePartyBeacon} The established Beacon instance.
112291
112462
  */
112292
112463
  static establish(service) {
112293
112464
  switch (service.type) {
@@ -128807,6 +128978,7 @@ export {
128807
128978
  AggregationParticipant,
128808
128979
  AggregationParticipantError,
128809
128980
  AggregationParticipantRunner,
128981
+ AggregationRunner,
128810
128982
  AggregationService,
128811
128983
  AggregationServiceError,
128812
128984
  AggregationServiceRunner,
@@ -128814,7 +128986,6 @@ export {
128814
128986
  BECH32M_CHARS,
128815
128987
  BTCR2_DID_DOCUMENT_CONTEXT,
128816
128988
  BaseMessage,
128817
- Beacon,
128818
128989
  BeaconError,
128819
128990
  BeaconFactory,
128820
128991
  BeaconSignalDiscovery,
@@ -128849,7 +129020,9 @@ export {
128849
129020
  HttpTransportError,
128850
129021
  ID_PLACEHOLDER_VALUE,
128851
129022
  Identifier,
129023
+ InMemoryBus,
128852
129024
  InMemoryRateLimitStore,
129025
+ InMemoryTransport,
128853
129026
  InboxBuffer,
128854
129027
  NONCE_CONTRIBUTION,
128855
129028
  NonceCache,
@@ -128871,6 +129044,7 @@ export {
128871
129044
  ServiceCohortPhase,
128872
129045
  SigningSessionError,
128873
129046
  SigningSessionPhase,
129047
+ SinglePartyBeacon,
128874
129048
  SingletonBeacon,
128875
129049
  SingletonBeaconError,
128876
129050
  StaticFeeEstimator,