@did-btcr2/aggregation 0.1.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 (233) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +19 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/browser.js +24017 -0
  5. package/dist/browser.mjs +24011 -0
  6. package/dist/cjs/index.js +5690 -0
  7. package/dist/cjs/package.json +1 -0
  8. package/dist/esm/beacon-strategy.js +76 -0
  9. package/dist/esm/beacon-strategy.js.map +1 -0
  10. package/dist/esm/cohort.js +316 -0
  11. package/dist/esm/cohort.js.map +1 -0
  12. package/dist/esm/conditions.js +102 -0
  13. package/dist/esm/conditions.js.map +1 -0
  14. package/dist/esm/errors.js +22 -0
  15. package/dist/esm/errors.js.map +1 -0
  16. package/dist/esm/fallback-spend.js +132 -0
  17. package/dist/esm/fallback-spend.js.map +1 -0
  18. package/dist/esm/index.js +21 -0
  19. package/dist/esm/index.js.map +1 -0
  20. package/dist/esm/logger.js +15 -0
  21. package/dist/esm/logger.js.map +1 -0
  22. package/dist/esm/messages/base.js +36 -0
  23. package/dist/esm/messages/base.js.map +1 -0
  24. package/dist/esm/messages/bodies.js +149 -0
  25. package/dist/esm/messages/bodies.js.map +1 -0
  26. package/dist/esm/messages/constants.js +37 -0
  27. package/dist/esm/messages/constants.js.map +1 -0
  28. package/dist/esm/messages/factories.js +139 -0
  29. package/dist/esm/messages/factories.js.map +1 -0
  30. package/dist/esm/messages/guards.js +40 -0
  31. package/dist/esm/messages/guards.js.map +1 -0
  32. package/dist/esm/messages/index.js +6 -0
  33. package/dist/esm/messages/index.js.map +1 -0
  34. package/dist/esm/participant.js +588 -0
  35. package/dist/esm/participant.js.map +1 -0
  36. package/dist/esm/phases.js +45 -0
  37. package/dist/esm/phases.js.map +1 -0
  38. package/dist/esm/recovery-policy.js +156 -0
  39. package/dist/esm/recovery-policy.js.map +1 -0
  40. package/dist/esm/recovery-spend.js +106 -0
  41. package/dist/esm/recovery-spend.js.map +1 -0
  42. package/dist/esm/runner/aggregation-runner.js +75 -0
  43. package/dist/esm/runner/aggregation-runner.js.map +1 -0
  44. package/dist/esm/runner/events.js +2 -0
  45. package/dist/esm/runner/events.js.map +1 -0
  46. package/dist/esm/runner/index.js +6 -0
  47. package/dist/esm/runner/index.js.map +1 -0
  48. package/dist/esm/runner/participant-runner.js +407 -0
  49. package/dist/esm/runner/participant-runner.js.map +1 -0
  50. package/dist/esm/runner/service-runner.js +701 -0
  51. package/dist/esm/runner/service-runner.js.map +1 -0
  52. package/dist/esm/runner/typed-emitter.js +80 -0
  53. package/dist/esm/runner/typed-emitter.js.map +1 -0
  54. package/dist/esm/service.js +774 -0
  55. package/dist/esm/service.js.map +1 -0
  56. package/dist/esm/signer.js +33 -0
  57. package/dist/esm/signer.js.map +1 -0
  58. package/dist/esm/signing-session.js +195 -0
  59. package/dist/esm/signing-session.js.map +1 -0
  60. package/dist/esm/transport/didcomm.js +41 -0
  61. package/dist/esm/transport/didcomm.js.map +1 -0
  62. package/dist/esm/transport/error.js +12 -0
  63. package/dist/esm/transport/error.js.map +1 -0
  64. package/dist/esm/transport/factory.js +29 -0
  65. package/dist/esm/transport/factory.js.map +1 -0
  66. package/dist/esm/transport/http/client.js +342 -0
  67. package/dist/esm/transport/http/client.js.map +1 -0
  68. package/dist/esm/transport/http/envelope.js +126 -0
  69. package/dist/esm/transport/http/envelope.js.map +1 -0
  70. package/dist/esm/transport/http/errors.js +11 -0
  71. package/dist/esm/transport/http/errors.js.map +1 -0
  72. package/dist/esm/transport/http/inbox-buffer.js +45 -0
  73. package/dist/esm/transport/http/inbox-buffer.js.map +1 -0
  74. package/dist/esm/transport/http/index.js +12 -0
  75. package/dist/esm/transport/http/index.js.map +1 -0
  76. package/dist/esm/transport/http/nonce-cache.js +38 -0
  77. package/dist/esm/transport/http/nonce-cache.js.map +1 -0
  78. package/dist/esm/transport/http/protocol.js +28 -0
  79. package/dist/esm/transport/http/protocol.js.map +1 -0
  80. package/dist/esm/transport/http/rate-limiter.js +45 -0
  81. package/dist/esm/transport/http/rate-limiter.js.map +1 -0
  82. package/dist/esm/transport/http/request-auth.js +100 -0
  83. package/dist/esm/transport/http/request-auth.js.map +1 -0
  84. package/dist/esm/transport/http/server.js +475 -0
  85. package/dist/esm/transport/http/server.js.map +1 -0
  86. package/dist/esm/transport/http/sse-stream.js +110 -0
  87. package/dist/esm/transport/http/sse-stream.js.map +1 -0
  88. package/dist/esm/transport/http/sse-writer.js +25 -0
  89. package/dist/esm/transport/http/sse-writer.js.map +1 -0
  90. package/dist/esm/transport/in-memory.js +149 -0
  91. package/dist/esm/transport/in-memory.js.map +1 -0
  92. package/dist/esm/transport/index.js +8 -0
  93. package/dist/esm/transport/index.js.map +1 -0
  94. package/dist/esm/transport/nostr.js +491 -0
  95. package/dist/esm/transport/nostr.js.map +1 -0
  96. package/dist/esm/transport/transport.js +2 -0
  97. package/dist/esm/transport/transport.js.map +1 -0
  98. package/dist/types/beacon-strategy.d.ts +56 -0
  99. package/dist/types/beacon-strategy.d.ts.map +1 -0
  100. package/dist/types/cohort.d.ts +188 -0
  101. package/dist/types/cohort.d.ts.map +1 -0
  102. package/dist/types/conditions.d.ts +86 -0
  103. package/dist/types/conditions.d.ts.map +1 -0
  104. package/dist/types/errors.d.ts +14 -0
  105. package/dist/types/errors.d.ts.map +1 -0
  106. package/dist/types/fallback-spend.d.ts +94 -0
  107. package/dist/types/fallback-spend.d.ts.map +1 -0
  108. package/dist/types/index.d.ts +17 -0
  109. package/dist/types/index.d.ts.map +1 -0
  110. package/dist/types/logger.d.ts +22 -0
  111. package/dist/types/logger.d.ts.map +1 -0
  112. package/dist/types/messages/base.d.ts +58 -0
  113. package/dist/types/messages/base.d.ts.map +1 -0
  114. package/dist/types/messages/bodies.d.ts +177 -0
  115. package/dist/types/messages/bodies.d.ts.map +1 -0
  116. package/dist/types/messages/constants.d.ts +31 -0
  117. package/dist/types/messages/constants.d.ts.map +1 -0
  118. package/dist/types/messages/factories.d.ts +217 -0
  119. package/dist/types/messages/factories.d.ts.map +1 -0
  120. package/dist/types/messages/guards.d.ts +11 -0
  121. package/dist/types/messages/guards.d.ts.map +1 -0
  122. package/dist/types/messages/index.d.ts +6 -0
  123. package/dist/types/messages/index.d.ts.map +1 -0
  124. package/dist/types/participant.d.ts +162 -0
  125. package/dist/types/participant.d.ts.map +1 -0
  126. package/dist/types/phases.d.ts +55 -0
  127. package/dist/types/phases.d.ts.map +1 -0
  128. package/dist/types/recovery-policy.d.ts +132 -0
  129. package/dist/types/recovery-policy.d.ts.map +1 -0
  130. package/dist/types/recovery-spend.d.ts +94 -0
  131. package/dist/types/recovery-spend.d.ts.map +1 -0
  132. package/dist/types/runner/aggregation-runner.d.ts +72 -0
  133. package/dist/types/runner/aggregation-runner.d.ts.map +1 -0
  134. package/dist/types/runner/events.d.ts +147 -0
  135. package/dist/types/runner/events.d.ts.map +1 -0
  136. package/dist/types/runner/index.d.ts +6 -0
  137. package/dist/types/runner/index.d.ts.map +1 -0
  138. package/dist/types/runner/participant-runner.d.ts +122 -0
  139. package/dist/types/runner/participant-runner.d.ts.map +1 -0
  140. package/dist/types/runner/service-runner.d.ts +228 -0
  141. package/dist/types/runner/service-runner.d.ts.map +1 -0
  142. package/dist/types/runner/typed-emitter.d.ts +41 -0
  143. package/dist/types/runner/typed-emitter.d.ts.map +1 -0
  144. package/dist/types/service.d.ts +177 -0
  145. package/dist/types/service.d.ts.map +1 -0
  146. package/dist/types/signer.d.ts +50 -0
  147. package/dist/types/signer.d.ts.map +1 -0
  148. package/dist/types/signing-session.d.ts +81 -0
  149. package/dist/types/signing-session.d.ts.map +1 -0
  150. package/dist/types/transport/didcomm.d.ts +23 -0
  151. package/dist/types/transport/didcomm.d.ts.map +1 -0
  152. package/dist/types/transport/error.d.ts +8 -0
  153. package/dist/types/transport/error.d.ts.map +1 -0
  154. package/dist/types/transport/factory.d.ts +28 -0
  155. package/dist/types/transport/factory.d.ts.map +1 -0
  156. package/dist/types/transport/http/client.d.ts +56 -0
  157. package/dist/types/transport/http/client.d.ts.map +1 -0
  158. package/dist/types/transport/http/envelope.d.ts +64 -0
  159. package/dist/types/transport/http/envelope.d.ts.map +1 -0
  160. package/dist/types/transport/http/errors.d.ts +9 -0
  161. package/dist/types/transport/http/errors.d.ts.map +1 -0
  162. package/dist/types/transport/http/inbox-buffer.d.ts +32 -0
  163. package/dist/types/transport/http/inbox-buffer.d.ts.map +1 -0
  164. package/dist/types/transport/http/index.d.ts +12 -0
  165. package/dist/types/transport/http/index.d.ts.map +1 -0
  166. package/dist/types/transport/http/nonce-cache.d.ts +26 -0
  167. package/dist/types/transport/http/nonce-cache.d.ts.map +1 -0
  168. package/dist/types/transport/http/protocol.d.ts +53 -0
  169. package/dist/types/transport/http/protocol.d.ts.map +1 -0
  170. package/dist/types/transport/http/rate-limiter.d.ts +41 -0
  171. package/dist/types/transport/http/rate-limiter.d.ts.map +1 -0
  172. package/dist/types/transport/http/request-auth.d.ts +50 -0
  173. package/dist/types/transport/http/request-auth.d.ts.map +1 -0
  174. package/dist/types/transport/http/server.d.ts +118 -0
  175. package/dist/types/transport/http/server.d.ts.map +1 -0
  176. package/dist/types/transport/http/sse-stream.d.ts +34 -0
  177. package/dist/types/transport/http/sse-stream.d.ts.map +1 -0
  178. package/dist/types/transport/http/sse-writer.d.ts +12 -0
  179. package/dist/types/transport/http/sse-writer.d.ts.map +1 -0
  180. package/dist/types/transport/in-memory.d.ts +64 -0
  181. package/dist/types/transport/in-memory.d.ts.map +1 -0
  182. package/dist/types/transport/index.d.ts +8 -0
  183. package/dist/types/transport/index.d.ts.map +1 -0
  184. package/dist/types/transport/nostr.d.ts +153 -0
  185. package/dist/types/transport/nostr.d.ts.map +1 -0
  186. package/dist/types/transport/transport.d.ts +62 -0
  187. package/dist/types/transport/transport.d.ts.map +1 -0
  188. package/package.json +128 -0
  189. package/src/beacon-strategy.ts +142 -0
  190. package/src/cohort.ts +422 -0
  191. package/src/conditions.ts +172 -0
  192. package/src/errors.ts +25 -0
  193. package/src/fallback-spend.ts +223 -0
  194. package/src/index.ts +23 -0
  195. package/src/logger.ts +33 -0
  196. package/src/messages/base.ts +80 -0
  197. package/src/messages/bodies.ts +328 -0
  198. package/src/messages/constants.ts +40 -0
  199. package/src/messages/factories.ts +297 -0
  200. package/src/messages/guards.ts +61 -0
  201. package/src/messages/index.ts +5 -0
  202. package/src/participant.ts +779 -0
  203. package/src/phases.ts +91 -0
  204. package/src/recovery-policy.ts +237 -0
  205. package/src/recovery-spend.ts +192 -0
  206. package/src/runner/aggregation-runner.ts +125 -0
  207. package/src/runner/events.ts +129 -0
  208. package/src/runner/index.ts +5 -0
  209. package/src/runner/participant-runner.ts +488 -0
  210. package/src/runner/service-runner.ts +891 -0
  211. package/src/runner/typed-emitter.ts +87 -0
  212. package/src/service.ts +1000 -0
  213. package/src/signer.ts +67 -0
  214. package/src/signing-session.ts +290 -0
  215. package/src/transport/didcomm.ts +59 -0
  216. package/src/transport/error.ts +13 -0
  217. package/src/transport/factory.ts +65 -0
  218. package/src/transport/http/client.ts +409 -0
  219. package/src/transport/http/envelope.ts +204 -0
  220. package/src/transport/http/errors.ts +11 -0
  221. package/src/transport/http/inbox-buffer.ts +53 -0
  222. package/src/transport/http/index.ts +11 -0
  223. package/src/transport/http/nonce-cache.ts +43 -0
  224. package/src/transport/http/protocol.ts +57 -0
  225. package/src/transport/http/rate-limiter.ts +75 -0
  226. package/src/transport/http/request-auth.ts +164 -0
  227. package/src/transport/http/server.ts +617 -0
  228. package/src/transport/http/sse-stream.ts +121 -0
  229. package/src/transport/http/sse-writer.ts +23 -0
  230. package/src/transport/in-memory.ts +178 -0
  231. package/src/transport/index.ts +7 -0
  232. package/src/transport/nostr.ts +576 -0
  233. package/src/transport/transport.ts +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"participant-runner.d.ts","sourceRoot":"","sources":["../../../src/runner/participant-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAWzD,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EACL,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,yEAAyE;AACzE,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpE,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB,KAAK,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;AAExC,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEzF,oDAAoD;AACpD,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAE/F,MAAM,WAAW,mCAAmC;IAClD,4BAA4B;IAC5B,SAAS,EAAE,SAAS,CAAC;IAErB,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB;;;OAGG;IACH,eAAe,EAAE,eAAe,CAAC;IAEjC;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,4BAA6B,SAAQ,iBAAiB,CAAC,4BAA4B,CAAC;;IAC/F,sEAAsE;IACtE,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;gBAY7B,OAAO,EAAE,mCAAmC;IAexD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,8EAA8E;IAC9E,IAAI,IAAI,IAAI;IA6BZ;;;;OAIG;WACU,SAAS,CACpB,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,kBAAkB,CAAC;IAY9B;;;;;;;;;;;;;;;OAeG;WACU,YAAY,CACvB,OAAO,EAAE,mCAAmC,EAC5C,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAiRjC"}
@@ -0,0 +1,228 @@
1
+ import type { SchnorrKeyPair } from '@did-btcr2/keypair';
2
+ import type { AggregationResult, CohortConfig, PendingOptIn, SigningTxData } from '../service.js';
3
+ import { AggregationService } from '../service.js';
4
+ import type { Transport } from '../transport/transport.js';
5
+ import type { FeeEstimator } from '@did-btcr2/bitcoin';
6
+ import type { AggregationServiceEvents } from './events.js';
7
+ import { TypedEventEmitter } from './typed-emitter.js';
8
+ /** Decision callback: accept or reject a participant's opt-in. */
9
+ export type OnOptInReceived = (optIn: PendingOptIn) => Promise<{
10
+ accepted: boolean;
11
+ }>;
12
+ /** Decision callback: finalize keygen now, or wait for more participants. */
13
+ export type OnReadyToFinalize = (info: {
14
+ acceptedCount: number;
15
+ minRequired: number;
16
+ }) => Promise<{
17
+ finalize: boolean;
18
+ }>;
19
+ /** Data callback: provide the Bitcoin transaction data to sign. */
20
+ export type OnProvideTxData = (info: {
21
+ cohortId: string;
22
+ beaconAddress: string;
23
+ signalBytes: Uint8Array;
24
+ /**
25
+ * Fee estimator the runner is configured with (the runner's `feeEstimator`
26
+ * option, or a static 5 sat/vB default). Forward it to the beacon transaction
27
+ * builder so a dynamic rate injected at the runner is honored, rather than
28
+ * hard-coding a rate inside this callback (ADR 045).
29
+ */
30
+ feeEstimator: FeeEstimator;
31
+ }) => Promise<SigningTxData>;
32
+ export interface AggregationServiceRunnerOptions {
33
+ /** Underlying transport (NostrTransport, MockTransport, etc.). */
34
+ transport: Transport;
35
+ /** This service's identity. */
36
+ did: string;
37
+ keys: SchnorrKeyPair;
38
+ /**
39
+ * Default cohort configuration for the {@link AggregationServiceRunner.run}
40
+ * convenience path. Optional: omit it when driving the runner with
41
+ * {@link AggregationServiceRunner.advertiseCohort}, which takes a per-cohort
42
+ * config and can be called many times on one runner.
43
+ */
44
+ config?: CohortConfig;
45
+ /**
46
+ * Decide whether to accept a participant's opt-in.
47
+ * Default: auto-accept all opt-ins.
48
+ */
49
+ onOptInReceived?: OnOptInReceived;
50
+ /**
51
+ * Decide whether to finalize keygen now or wait for more participants.
52
+ * Called after each accepted opt-in once minParticipants is reached.
53
+ * Default: finalize as soon as minParticipants is reached.
54
+ */
55
+ onReadyToFinalize?: OnReadyToFinalize;
56
+ /**
57
+ * Provide the Bitcoin transaction data to sign.
58
+ * REQUIRED - no sensible default.
59
+ */
60
+ onProvideTxData: OnProvideTxData;
61
+ /**
62
+ * Fee estimator passed to {@link OnProvideTxData} so the beacon transaction the
63
+ * callback builds is sized at a chosen rate. Inject a dynamic estimator (a mempool
64
+ * API or Bitcoin Core `estimatesmartfee`) here as the single standard point for
65
+ * fee-rate selection, instead of hard-coding a rate inside the callback (ADR 045).
66
+ * Defaults to a static 5 sat/vB estimator.
67
+ */
68
+ feeEstimator?: FeeEstimator;
69
+ /**
70
+ * Maximum canonicalized byte-length of a signed update body. Submissions
71
+ * above this cap are rejected and surfaced via the `message-rejected` event.
72
+ * Defaults to {@link DEFAULT_MAX_UPDATE_SIZE_BYTES} (256 KiB).
73
+ */
74
+ maxUpdateSizeBytes?: number;
75
+ /**
76
+ * Overall wall-clock budget for each cohort, from advertise to
77
+ * signing-complete. On expiry the cohort is dropped, `cohort-failed` is
78
+ * emitted, and that cohort's completion rejects with a timeout error. Other
79
+ * cohorts on the same runner are unaffected. Leave undefined to disable.
80
+ */
81
+ cohortTtlMs?: number;
82
+ /**
83
+ * Maximum time allowed between phase transitions for a cohort. Protects
84
+ * against stalled cohorts (e.g. a participant vanishing mid-protocol). Reset
85
+ * automatically on every observed phase change. Applied per cohort. Leave
86
+ * undefined to disable.
87
+ */
88
+ phaseTimeoutMs?: number;
89
+ /**
90
+ * Re-publish COHORT_ADVERT on this interval until a cohort's keygen is
91
+ * finalized. Works around relays that don't backfill historical events to
92
+ * late subscribers - a republish gives late joiners a window to discover the
93
+ * advert without protocol changes. The first publish is immediate;
94
+ * subsequent publishes fire every `advertRepeatIntervalMs` until that
95
+ * cohort's keygen completes, fails, or is stopped. Defaults to
96
+ * {@link DEFAULT_ADVERT_REPEAT_INTERVAL_MS} (60 s). Set to 0 to publish
97
+ * once and never retry.
98
+ */
99
+ advertRepeatIntervalMs?: number;
100
+ /**
101
+ * When a cohort stalls (phase timeout) while the optimistic n-of-n signing
102
+ * round is in flight, fall back to the k-of-n script path instead of failing
103
+ * the cohort (graceful liveness, ADR 042). Off by default: enabling it trades a
104
+ * cheaper/private key-path spend for a larger script-path spend whenever the
105
+ * optimistic round does not complete in time. A stall outside the signing
106
+ * phases still fails the cohort. Operators can also drive the fallback
107
+ * explicitly via {@link AggregationServiceRunner.triggerFallback}.
108
+ */
109
+ autoFallbackOnStall?: boolean;
110
+ }
111
+ /** Default cadence for re-publishing COHORT_ADVERT until keygen completes: 60 seconds. */
112
+ export declare const DEFAULT_ADVERT_REPEAT_INTERVAL_MS = 60000;
113
+ /**
114
+ * High-level facade for running an Aggregation Service over a Transport.
115
+ *
116
+ * Wires the {@link AggregationService} state machine to a {@link Transport},
117
+ * encapsulating message handler registration, outgoing message dispatch,
118
+ * and decision callback orchestration.
119
+ *
120
+ * A single runner is a long-lived multiplexer: it advertises and drives many
121
+ * cohorts concurrently over one transport. Each advertised cohort owns an
122
+ * independent completion promise and fails in isolation - a stalled or failed
123
+ * cohort never settles its siblings (see ADR 040). Use
124
+ * {@link AggregationServiceRunner.advertiseCohort} for the multi-cohort path;
125
+ * {@link AggregationServiceRunner.run} is a thin single-cohort convenience over
126
+ * it.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const transport = new NostrTransport({ relays: [RELAY] });
131
+ * transport.registerActor(serviceDid, serviceKeys);
132
+ *
133
+ * const runner = new AggregationServiceRunner({
134
+ * transport,
135
+ * did: serviceDid,
136
+ * keys: serviceKeys,
137
+ * onProvideTxData: async ({ beaconAddress, signalBytes, feeEstimator }) => {
138
+ * // Forward feeEstimator so a dynamic rate injected at the runner is honored.
139
+ * return await buildBeaconTransaction(beaconAddress, signalBytes, bitcoin, feeEstimator);
140
+ * },
141
+ * });
142
+ *
143
+ * runner.on('keygen-complete', ({ cohortId, beaconAddress }) => console.log(beaconAddress));
144
+ * runner.on('signing-complete', ({ cohortId, signature }) => console.log('done', cohortId));
145
+ *
146
+ * // Multi-cohort: advertise several cohorts; each completion resolves independently.
147
+ * const a = runner.advertiseCohort({ minParticipants: 2, network: 'mutinynet', beaconType: 'CASBeacon' });
148
+ * const b = runner.advertiseCohort({ minParticipants: 3, network: 'mutinynet', beaconType: 'SMTBeacon' });
149
+ * const [ra, rb] = await Promise.all([a.completion, b.completion]);
150
+ *
151
+ * // Single-cohort convenience (requires `config` in the options):
152
+ * // const result = await runner.run();
153
+ * ```
154
+ *
155
+ * For full manual control, drop down to the underlying state machine via
156
+ * `runner.session`. The state machine has no transport coupling and exposes
157
+ * every protocol decision as an explicit method.
158
+ *
159
+ * @class AggregationServiceRunner
160
+ */
161
+ export declare class AggregationServiceRunner extends TypedEventEmitter<AggregationServiceEvents> {
162
+ #private;
163
+ /** Direct access to the underlying state machine for advanced use. */
164
+ readonly session: AggregationService;
165
+ constructor(options: AggregationServiceRunnerOptions);
166
+ /**
167
+ * Advertise a new cohort and begin driving it to completion. Callable many
168
+ * times on one runner; each cohort runs concurrently and independently.
169
+ *
170
+ * @param config Per-cohort conditions + network (see {@link CohortConfig}).
171
+ * @returns The new cohort's id and a `completion` promise that resolves with
172
+ * that cohort's {@link AggregationResult} (or rejects if it fails/stalls).
173
+ * @throws If the runner has been stopped, or the config is invalid
174
+ * (fail-fast via `createCohort`).
175
+ */
176
+ advertiseCohort(config: CohortConfig): {
177
+ cohortId: string;
178
+ completion: Promise<AggregationResult>;
179
+ };
180
+ /**
181
+ * Run a single cohort to completion using the `config` supplied in the
182
+ * runner options. Thin convenience over {@link advertiseCohort} for the
183
+ * single-cohort case (and the path {@link AggregationRunner.solo} rides).
184
+ *
185
+ * @returns {Promise<AggregationResult>} The final result with signature and signed tx.
186
+ */
187
+ run(): Promise<AggregationResult>;
188
+ /**
189
+ * Wait for every currently-outstanding cohort to settle and return the
190
+ * successful results. Dynamic drain: cohorts advertised while this is pending
191
+ * are included, and it resolves only once no cohorts remain. Failed cohorts
192
+ * are surfaced via `error` / `cohort-failed` events and their rejected
193
+ * `completion` promises; they are omitted from the returned array (this
194
+ * method does not throw). Bound long-running cohorts with `cohortTtlMs` /
195
+ * `phaseTimeoutMs` or this may never resolve.
196
+ *
197
+ * @returns {Promise<AggregationResult[]>} Results of the cohorts that completed.
198
+ */
199
+ runAll(): Promise<AggregationResult[]>;
200
+ /**
201
+ * Abandon the optimistic n-of-n key path for a cohort and collect k-of-n
202
+ * fallback (script-path) signatures instead (ADR 042). Idempotent and safe
203
+ * against the optimistic completion: it commits the cohort to the fallback
204
+ * path synchronously (the `committedPath` latch) before sending anything, so a
205
+ * late optimistic signature can no longer complete-and-broadcast a competing
206
+ * spend of the same UTXO. No-op if the cohort is unknown, already settled, or
207
+ * already committed to a path.
208
+ *
209
+ * Wired automatically to the phase-stall timer when `autoFallbackOnStall` is
210
+ * set; otherwise call it from an operator decision (a UI "fall back now"
211
+ * action). Throws only if the underlying state machine rejects the transition
212
+ * (e.g. signing has not started).
213
+ */
214
+ triggerFallback(cohortId: string): Promise<void>;
215
+ /**
216
+ * Stop a single cohort early without affecting the rest of the runner. Drops
217
+ * the cohort's state machine state; its `completion` promise rejects with a
218
+ * stopped error.
219
+ */
220
+ stopCohort(cohortId: string): void;
221
+ /**
222
+ * Stop the whole runner. Fails every outstanding cohort, then detaches the
223
+ * shared transport handlers so a restart or a new runner doesn't inherit
224
+ * stale dispatch. Safe to call repeatedly.
225
+ */
226
+ stop(): void;
227
+ }
228
+ //# sourceMappingURL=service-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-runner.d.ts","sourceRoot":"","sources":["../../../src/runner/service-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Tiny strongly-typed event emitter.
3
+ *
4
+ * Browser-compatible (no Node.js `events` module). Uses a generic event map
5
+ * to give compile-time safety on event names and listener signatures.
6
+ *
7
+ * @example
8
+ * type MyEvents = {
9
+ * 'connected': [{ host: string }];
10
+ * 'data': [Uint8Array];
11
+ * 'error': [Error];
12
+ * };
13
+ *
14
+ * class MyClient extends TypedEventEmitter<MyEvents> {
15
+ * doStuff() {
16
+ * this.emit('connected', { host: 'example.com' }); // ✓ typed
17
+ * this.emit('data', new Uint8Array([1, 2])); // ✓ typed
18
+ * }
19
+ * }
20
+ *
21
+ * const client = new MyClient();
22
+ * client.on('connected', ({ host }) => console.log(host)); // ✓ typed
23
+ */
24
+ export type EventMap = Record<string, ReadonlyArray<unknown>>;
25
+ export type Listener<Args extends ReadonlyArray<unknown>> = (...args: Args) => void;
26
+ export declare class TypedEventEmitter<Events extends EventMap> {
27
+ #private;
28
+ /** Subscribe to an event. */
29
+ on<K extends keyof Events>(event: K, listener: Listener<Events[K]>): this;
30
+ /** Subscribe to an event, automatically unsubscribing after the first call. */
31
+ once<K extends keyof Events>(event: K, listener: Listener<Events[K]>): this;
32
+ /** Unsubscribe a specific listener. */
33
+ off<K extends keyof Events>(event: K, listener: Listener<Events[K]>): this;
34
+ /** Emit an event to all subscribed listeners. */
35
+ emit<K extends keyof Events>(event: K, ...args: Events[K]): boolean;
36
+ /** Remove all listeners (optionally for a specific event). */
37
+ removeAllListeners<K extends keyof Events>(event?: K): this;
38
+ /** Number of listeners for an event. */
39
+ listenerCount<K extends keyof Events>(event: K): number;
40
+ }
41
+ //# sourceMappingURL=typed-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typed-emitter.d.ts","sourceRoot":"","sources":["../../../src/runner/typed-emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;AAE9D,MAAM,MAAM,QAAQ,CAAC,IAAI,SAAS,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;AAEpF,qBAAa,iBAAiB,CAAC,MAAM,SAAS,QAAQ;;IAGpD,6BAA6B;IAC7B,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAUzE,+EAA+E;IAC/E,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ3E,uCAAuC;IACvC,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAK1E,iDAAiD;IACjD,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,OAAO;IAcnE,8DAA8D;IAC9D,kBAAkB,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAS3D,wCAAwC;IACxC,aAAa,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM;CAGxD"}
@@ -0,0 +1,177 @@
1
+ import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
2
+ import type { CompressedSecp256k1PublicKey } from '@did-btcr2/keypair';
3
+ import type { Transaction } from '@scure/btc-signer';
4
+ import { AggregationCohort } from './cohort.js';
5
+ import { type CohortConditions } from './conditions.js';
6
+ import type { BaseMessage } from './messages/base.js';
7
+ import type { ServiceCohortPhaseType } from './phases.js';
8
+ /**
9
+ * Cohort configuration set by the service operator: the advertised cohort
10
+ * {@link CohortConditions} plus the Bitcoin network. `beaconType` and
11
+ * `minParticipants` are required; the other conditions are optional (absent =
12
+ * unconstrained). See ADR 039.
13
+ */
14
+ export interface CohortConfig extends CohortConditions {
15
+ network: string;
16
+ }
17
+ /** Pending opt-in awaiting service operator approval. */
18
+ export interface PendingOptIn {
19
+ cohortId: string;
20
+ participantDid: string;
21
+ participantPk: Uint8Array;
22
+ communicationPk: Uint8Array;
23
+ }
24
+ /** Validation tracking progress. */
25
+ export interface ValidationProgress {
26
+ approved: ReadonlySet<string>;
27
+ rejected: ReadonlySet<string>;
28
+ pending: ReadonlySet<string>;
29
+ total: number;
30
+ }
31
+ /** Final aggregation result for a cohort. */
32
+ export interface AggregationResult {
33
+ cohortId: string;
34
+ /**
35
+ * The 64-byte aggregated MuSig2 signature for the optimistic key path. Empty
36
+ * for a `script-path` result: the k-of-n fallback embeds k separate signatures
37
+ * directly in the witness of {@link signedTx}, with no single aggregate sig.
38
+ */
39
+ signature: Uint8Array;
40
+ signedTx: Transaction;
41
+ /**
42
+ * Which Taproot spend path produced {@link signedTx}: `key-path` is the
43
+ * optimistic n-of-n MuSig2 spend, `script-path` is the k-of-n fallback (ADR
44
+ * 042). Absent is treated as `key-path` for backward compatibility.
45
+ */
46
+ path?: 'key-path' | 'script-path';
47
+ }
48
+ /** Transaction data needed to start a signing session. */
49
+ export interface SigningTxData {
50
+ tx: Transaction;
51
+ prevOutScripts: Uint8Array[];
52
+ prevOutValues: bigint[];
53
+ }
54
+ /** Reason an incoming message was silently dropped by the state machine. */
55
+ export type RejectionReason = 'WRONG_VERSION' | 'UPDATE_TOO_LARGE' | 'UPDATE_VERIFICATION_FAILED' | 'UPDATE_MALFORMED';
56
+ /** Record of a silently-dropped inbound message. Drained by the runner to emit events. */
57
+ export interface Rejection {
58
+ /** DID of the sender whose message was rejected. */
59
+ from: string;
60
+ /** Machine-readable code. */
61
+ code: RejectionReason;
62
+ /** Human-readable reason. */
63
+ reason: string;
64
+ }
65
+ /** Default maximum canonicalized byte-length of a submitted BTCR2 update. */
66
+ export declare const DEFAULT_MAX_UPDATE_SIZE_BYTES: number;
67
+ export interface AggregationServiceParams {
68
+ did: string;
69
+ /**
70
+ * The service's compressed communication public key (placed in cohort adverts).
71
+ * The coordinator never signs - it aggregates public nonces and partial
72
+ * signatures - so it is given a public key only, never a secret-bearing
73
+ * keypair (see ADR 038).
74
+ */
75
+ publicKey: CompressedSecp256k1PublicKey;
76
+ /**
77
+ * Maximum canonicalized byte-length of a signed update body accepted by the
78
+ * service. Submissions above this cap are silently dropped and surfaced as
79
+ * `UPDATE_TOO_LARGE` rejections. Defaults to {@link DEFAULT_MAX_UPDATE_SIZE_BYTES}.
80
+ */
81
+ maxUpdateSizeBytes?: number;
82
+ }
83
+ /**
84
+ * Sans-I/O state machine for an Aggregation Service.
85
+ *
86
+ * Manages multiple cohorts simultaneously. The service operator drives the
87
+ * state machine via `receive()` (for incoming messages) and explicit action
88
+ * methods (advertising, accepting opt-ins, finalizing keygen, building
89
+ * aggregated data, starting signing). All outgoing messages are returned for
90
+ * the caller to send via whatever transport.
91
+ *
92
+ * @class AggregationService
93
+ */
94
+ export declare class AggregationService {
95
+ #private;
96
+ readonly did: string;
97
+ readonly publicKey: CompressedSecp256k1PublicKey;
98
+ readonly maxUpdateSizeBytes: number;
99
+ constructor({ did, publicKey, maxUpdateSizeBytes }: AggregationServiceParams);
100
+ receive(message: BaseMessage): void;
101
+ /**
102
+ * Drain the rejection log for a cohort. Used by runners to surface silent
103
+ * drops (bad proof, oversized update, wrong version, etc.) as structured
104
+ * events without breaking the sans-I/O state machine contract.
105
+ */
106
+ drainRejections(cohortId: string): Array<Rejection>;
107
+ /**
108
+ * Create a new cohort with the given config. Returns the cohort ID.
109
+ * Cohort starts in `Created` phase - call `advertise()` to broadcast.
110
+ */
111
+ createCohort(config: CohortConfig): string;
112
+ /**
113
+ * Advertise a cohort to discover participants.
114
+ * Returns the advert message to broadcast.
115
+ */
116
+ advertise(cohortId: string): BaseMessage[];
117
+ /** Pending opt-ins awaiting operator approval. */
118
+ pendingOptIns(cohortId: string): ReadonlyMap<string, PendingOptIn>;
119
+ /**
120
+ * Service operator accepts a participant's opt-in.
121
+ * Returns the accept message to send.
122
+ */
123
+ acceptParticipant(cohortId: string, participantDid: string): BaseMessage[];
124
+ /**
125
+ * Finalize cohort keygen: compute MuSig2 Taproot beacon address and send
126
+ * COHORT_READY messages to all accepted participants.
127
+ */
128
+ finalizeKeygen(cohortId: string): BaseMessage[];
129
+ /** Updates collected so far for a cohort. */
130
+ collectedUpdates(cohortId: string): ReadonlyMap<string, SignedBTCR2Update>;
131
+ /**
132
+ * Build the aggregated data structure (CAS Announcement or SMT tree) and
133
+ * return distribute messages to send to all participants for validation.
134
+ */
135
+ buildAndDistribute(cohortId: string): BaseMessage[];
136
+ validationProgress(cohortId: string): ValidationProgress;
137
+ /**
138
+ * Start a signing session by creating auth requests for all participants.
139
+ * The caller provides the transaction data - typically built via
140
+ * `buildBeaconTransaction()` against a Bitcoin connection.
141
+ */
142
+ startSigning(cohortId: string, txData: SigningTxData): BaseMessage[];
143
+ /**
144
+ * Generate the aggregated nonce and return messages to send to participants.
145
+ * Call after `validationProgress(cohortId).approved.size === total`.
146
+ */
147
+ sendAggregatedNonce(cohortId: string): BaseMessage[];
148
+ /**
149
+ * Abandon the optimistic n-of-n key path and ask members to authorize the
150
+ * k-of-n fallback (script-path) spend of the SAME beacon transaction (graceful
151
+ * liveness, ADR 042). Reuses the in-flight signing session's transaction and
152
+ * spent output, so the announcement and its outputs are unchanged: only the
153
+ * witness path differs. Returns one FALLBACK_AUTHORIZATION_REQUEST per
154
+ * participant.
155
+ *
156
+ * Callable once optimistic signing has started (the session and its tx exist)
157
+ * and before it completes. A cohort can take exactly one of the two paths: the
158
+ * caller (runner) must commit to fallback and stop driving the optimistic path.
159
+ */
160
+ startFallbackSigning(cohortId: string): BaseMessage[];
161
+ getResult(cohortId: string): AggregationResult | undefined;
162
+ getCohortPhase(cohortId: string): ServiceCohortPhaseType | undefined;
163
+ getCohort(cohortId: string): AggregationCohort | undefined;
164
+ /**
165
+ * Get the signing session ID for a cohort, if a signing session has been started.
166
+ * @param {string} cohortId - The cohort ID.
167
+ * @returns {string | undefined} The session ID, or undefined if no session is active.
168
+ */
169
+ getSigningSessionId(cohortId: string): string | undefined;
170
+ get cohorts(): ReadonlyArray<AggregationCohort>;
171
+ /**
172
+ * Remove a cohort from the state map. Used by runners to GC state on cohort
173
+ * completion, failure, or expiry. No-op if the cohort doesn't exist.
174
+ */
175
+ removeCohort(cohortId: string): void;
176
+ }
177
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { SchnorrKeyPair } from '@did-btcr2/keypair';
2
+ /**
3
+ * A signing capability for MuSig2 aggregation.
4
+ *
5
+ * MuSig2 (BIP-327) cannot be driven through a generic `sign(message)` primitive:
6
+ * both nonce generation and partial signing need the raw 32-byte secret scalar
7
+ * (see ADR 038). Rather than hand that scalar around as a long-lived field, the
8
+ * participant holds an `AggregationSigner` and materializes the secret only for
9
+ * the duration of a single operation via {@link AggregationSigner.withSecret},
10
+ * which is responsible for wiping its working copy afterward.
11
+ *
12
+ * This is the seam a non-extractable / KMS-backed signer (or a session-scoped
13
+ * signer that destroys its key after the cohort completes) plugs into without
14
+ * changing the participant state machine.
15
+ *
16
+ * @interface AggregationSigner
17
+ */
18
+ export interface AggregationSigner {
19
+ /** Compressed 33-byte public key. Not secret; always available. */
20
+ readonly publicKey: Uint8Array;
21
+ /**
22
+ * Materialize the raw 32-byte secret key, pass it to `fn`, and zeroize the
23
+ * working copy before returning - even if `fn` throws. The secret must not
24
+ * escape the callback.
25
+ *
26
+ * @typeParam T The callback's return type (e.g. a nonce contribution or partial signature).
27
+ * @param {(secretKey: Uint8Array) => T} fn Operation that needs the raw secret for its duration.
28
+ * @returns {T} Whatever `fn` returns.
29
+ */
30
+ withSecret<T>(fn: (secretKey: Uint8Array) => T): T;
31
+ }
32
+ /**
33
+ * {@link AggregationSigner} backed by an in-memory {@link SchnorrKeyPair}.
34
+ *
35
+ * The keypair is held privately (never exposed as a public field) and each
36
+ * `withSecret` call pulls a fresh copy of the secret bytes, hands it to the
37
+ * callback, and wipes that copy on return. The underlying keypair is the
38
+ * caller's to own and destroy; this signer never mutates or destroys it.
39
+ *
40
+ * @class KeyPairAggregationSigner
41
+ * @implements {AggregationSigner}
42
+ */
43
+ export declare class KeyPairAggregationSigner implements AggregationSigner {
44
+ #private;
45
+ readonly publicKey: Uint8Array;
46
+ /** @param {SchnorrKeyPair} keys The keypair whose secret backs this signer. */
47
+ constructor(keys: SchnorrKeyPair);
48
+ withSecret<T>(fn: (secretKey: Uint8Array) => T): T;
49
+ }
50
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAE/B;;;;;;;;OAQG;IACH,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC,CAAC;CACpD;AAED;;;;;;;;;;GAUG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;;IAChE,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAG/B,+EAA+E;gBACnE,IAAI,EAAE,cAAc;IAKhC,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,UAAU,KAAK,CAAC,GAAG,CAAC;CAUnD"}
@@ -0,0 +1,81 @@
1
+ import type { Transaction } from '@scure/btc-signer';
2
+ import type { AggregationCohort } from './cohort.js';
3
+ import type { SigningSessionPhaseType } from './phases.js';
4
+ type PublicKeyHex = string;
5
+ type Nonce = Uint8Array;
6
+ export interface SigningSessionParams {
7
+ id?: string;
8
+ cohort: AggregationCohort;
9
+ pendingTx: Transaction;
10
+ prevOutScripts?: Uint8Array[];
11
+ prevOutValues?: bigint[];
12
+ }
13
+ /**
14
+ * MuSig2 signing session for a beacon transaction.
15
+ *
16
+ * Implements the BIP-327 signing protocol over a Taproot key-path-only
17
+ * transaction. The session is used by both AggregationService (collecting
18
+ * nonces and partial signatures, computing the final signature) and
19
+ * AggregationParticipant (generating their nonce and partial signature).
20
+ *
21
+ * @class BeaconSigningSession
22
+ */
23
+ export declare class BeaconSigningSession {
24
+ #private;
25
+ /** Unique identifier for this signing session. */
26
+ id: string;
27
+ /** The cohort this session signs for. */
28
+ cohort: AggregationCohort;
29
+ /** The Bitcoin transaction being signed. */
30
+ pendingTx: Transaction;
31
+ /** Previous output scripts for Taproot sighash computation (BIP-341). */
32
+ prevOutScripts: Uint8Array[];
33
+ /** Previous output values for Taproot sighash computation. */
34
+ prevOutValues: bigint[];
35
+ /** Map of participant publicKey-hex to public nonce contribution. */
36
+ nonceContributions: Map<PublicKeyHex, Nonce>;
37
+ /** Aggregated MuSig2 nonce (66 bytes). */
38
+ aggregatedNonce?: Uint8Array;
39
+ /** Map of participant DID to partial signature. */
40
+ partialSignatures: Map<string, Uint8Array>;
41
+ /** Final 64-byte Schnorr signature. */
42
+ signature?: Uint8Array;
43
+ /** Current signing session phase. */
44
+ phase: SigningSessionPhaseType;
45
+ constructor({ id, cohort, pendingTx, prevOutScripts, prevOutValues }: SigningSessionParams);
46
+ /**
47
+ * Computes the Taproot sighash (BIP-341) for the first input.
48
+ */
49
+ get sigHash(): Uint8Array;
50
+ addNonceContribution(participantDid: string, nonceContribution: Uint8Array): void;
51
+ generateAggregatedNonce(): Uint8Array;
52
+ addPartialSignature(participantDid: string, partialSig: Uint8Array): void;
53
+ generateFinalSignature(): Uint8Array;
54
+ /**
55
+ * Generates a fresh MuSig2 nonce contribution for the participant.
56
+ * Stores the secret nonce internally for use in `generatePartialSignature()`.
57
+ */
58
+ generateNonceContribution(participantPublicKey: Uint8Array, participantSecretKey: Uint8Array): Uint8Array;
59
+ /**
60
+ * Generates a partial signature using the participant's secret key + secret nonce.
61
+ * Requires the aggregated nonce to have been set first (via the service).
62
+ *
63
+ * Clears the stored secret nonce after use on every path (success or throw)
64
+ * via {@link clearSecrets}. JS cannot truly erase memory (GC may relocate
65
+ * buffers), but overwriting the bytes shortens the exposure window and
66
+ * prevents accidental reuse or serialization of a spent nonce - reuse of a
67
+ * MuSig2 nonce leaks the secret key.
68
+ */
69
+ generatePartialSignature(participantSecretKey: Uint8Array): Uint8Array;
70
+ /**
71
+ * Zeroize any retained secret nonce. Safe to call repeatedly and on any path
72
+ * (completion, failure, or teardown of an abandoned session). Callers that
73
+ * drop a session before it reaches a partial signature should invoke this so
74
+ * the secret nonce does not linger on the live object.
75
+ */
76
+ clearSecrets(): void;
77
+ isComplete(): boolean;
78
+ isFailed(): boolean;
79
+ }
80
+ export {};
81
+ //# sourceMappingURL=signing-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signing-session.d.ts","sourceRoot":"","sources":["../../src/signing-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG3D,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,KAAK,GAAG,UAAU,CAAC;AAExB,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,WAAW,CAAC;IACvB,cAAc,CAAC,EAAE,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;GASG;AACH,qBAAa,oBAAoB;;IAC/B,kDAAkD;IAC3C,EAAE,EAAE,MAAM,CAAC;IAElB,yCAAyC;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAEjC,4CAA4C;IACrC,SAAS,EAAE,WAAW,CAAC;IAE9B,yEAAyE;IAClE,cAAc,EAAE,UAAU,EAAE,CAAC;IAEpC,8DAA8D;IACvD,aAAa,EAAE,MAAM,EAAE,CAAC;IAE/B,qEAAqE;IAC9D,kBAAkB,EAAE,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAa;IAEhE,0CAA0C;IACnC,eAAe,CAAC,EAAE,UAAU,CAAC;IAEpC,mDAAmD;IAC5C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAa;IAE9D,uCAAuC;IAChC,SAAS,CAAC,EAAE,UAAU,CAAC;IAE9B,qCAAqC;IAC9B,KAAK,EAAE,uBAAuB,CAAC;gBAW1B,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,EAAE,oBAAoB;IAS1F;;OAEG;IACH,IAAI,OAAO,IAAI,UAAU,CAaxB;IAEM,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,UAAU,GAAG,IAAI;IAgCjF,uBAAuB,IAAI,UAAU;IAYrC,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI;IA0BzE,sBAAsB,IAAI,UAAU;IA4D3C;;;OAGG;IACI,yBAAyB,CAAC,oBAAoB,EAAE,UAAU,EAAE,oBAAoB,EAAE,UAAU,GAAG,UAAU;IAOhH;;;;;;;;;OASG;IACI,wBAAwB,CAAC,oBAAoB,EAAE,UAAU,GAAG,UAAU;IAqB7E;;;;;OAKG;IACI,YAAY,IAAI,IAAI;IAOpB,UAAU,IAAI,OAAO;IAIrB,QAAQ,IAAI,OAAO;CAG3B"}
@@ -0,0 +1,23 @@
1
+ import type { SchnorrKeyPair } from '@did-btcr2/keypair';
2
+ import type { BaseMessage } from '../messages/base.js';
3
+ import type { MessageHandler, Transport } from './transport.js';
4
+ /**
5
+ * DIDComm Transport (stub).
6
+ *
7
+ * @class DidCommTransport
8
+ * @implements {Transport}
9
+ */
10
+ export declare class DidCommTransport implements Transport {
11
+ name: string;
12
+ start(): void;
13
+ registerActor(_did: string, _keys: SchnorrKeyPair): void;
14
+ getActorPk(_did: string): Uint8Array | undefined;
15
+ registerPeer(_did: string, _communicationPk: Uint8Array): void;
16
+ getPeerPk(_did: string): Uint8Array | undefined;
17
+ registerMessageHandler(_actorDid: string, _messageType: string, _handler: MessageHandler): void;
18
+ unregisterMessageHandler(_actorDid: string, _messageType: string): void;
19
+ unregisterActor(_did: string): void;
20
+ sendMessage(_message: BaseMessage, _sender: string, _recipient?: string): Promise<void>;
21
+ publishRepeating(_message: BaseMessage, _sender: string, _intervalMs: number, _recipient?: string): () => void;
22
+ }
23
+ //# sourceMappingURL=didcomm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"didcomm.d.ts","sourceRoot":"","sources":["../../../src/transport/didcomm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhE;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IACzC,IAAI,EAAE,MAAM,CAAa;IAEzB,KAAK,IAAI,IAAI;IAIb,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAIxD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIhD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,gBAAgB,EAAE,UAAU,GAAG,IAAI;IAI9D,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI/C,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI;IAI/F,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAIvE,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI7B,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F,gBAAgB,CACrB,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,IAAI;CAGd"}
@@ -0,0 +1,8 @@
1
+ import { MethodError } from '@did-btcr2/common';
2
+ export declare class TransportError extends MethodError {
3
+ constructor(message: string, type?: string, data?: Record<string, any>);
4
+ }
5
+ export declare class TransportAdapterError extends MethodError {
6
+ constructor(message: string, type?: string, data?: Record<string, any>);
7
+ }
8
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/transport/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,qBAAa,cAAe,SAAQ,WAAW;gBACjC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAyB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGzF;AAED,qBAAa,qBAAsB,SAAQ,WAAW;gBACxC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAgC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGhG"}