@did-btcr2/method 0.36.1 → 0.37.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 (164) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/browser.js +1060 -96
  3. package/dist/browser.mjs +1060 -96
  4. package/dist/cjs/index.js +1153 -179
  5. package/dist/esm/core/aggregation/beacon-strategy.js +19 -6
  6. package/dist/esm/core/aggregation/beacon-strategy.js.map +1 -1
  7. package/dist/esm/core/aggregation/cohort.js +142 -33
  8. package/dist/esm/core/aggregation/cohort.js.map +1 -1
  9. package/dist/esm/core/aggregation/conditions.js +27 -0
  10. package/dist/esm/core/aggregation/conditions.js.map +1 -1
  11. package/dist/esm/core/aggregation/fallback-spend.js +132 -0
  12. package/dist/esm/core/aggregation/fallback-spend.js.map +1 -0
  13. package/dist/esm/core/aggregation/messages/base.js.map +1 -1
  14. package/dist/esm/core/aggregation/messages/bodies.js +46 -1
  15. package/dist/esm/core/aggregation/messages/bodies.js.map +1 -1
  16. package/dist/esm/core/aggregation/messages/constants.js +11 -0
  17. package/dist/esm/core/aggregation/messages/constants.js.map +1 -1
  18. package/dist/esm/core/aggregation/messages/factories.js +27 -1
  19. package/dist/esm/core/aggregation/messages/factories.js.map +1 -1
  20. package/dist/esm/core/aggregation/messages/guards.js +4 -1
  21. package/dist/esm/core/aggregation/messages/guards.js.map +1 -1
  22. package/dist/esm/core/aggregation/participant.js +210 -21
  23. package/dist/esm/core/aggregation/participant.js.map +1 -1
  24. package/dist/esm/core/aggregation/phases.js +6 -0
  25. package/dist/esm/core/aggregation/phases.js.map +1 -1
  26. package/dist/esm/core/aggregation/recovery-policy.js +156 -0
  27. package/dist/esm/core/aggregation/recovery-policy.js.map +1 -0
  28. package/dist/esm/core/aggregation/recovery-spend.js +106 -0
  29. package/dist/esm/core/aggregation/recovery-spend.js.map +1 -0
  30. package/dist/esm/core/aggregation/runner/aggregation-runner.js +11 -3
  31. package/dist/esm/core/aggregation/runner/aggregation-runner.js.map +1 -1
  32. package/dist/esm/core/aggregation/runner/participant-runner.js +74 -22
  33. package/dist/esm/core/aggregation/runner/participant-runner.js.map +1 -1
  34. package/dist/esm/core/aggregation/runner/service-runner.js +97 -9
  35. package/dist/esm/core/aggregation/runner/service-runner.js.map +1 -1
  36. package/dist/esm/core/aggregation/service.js +221 -11
  37. package/dist/esm/core/aggregation/service.js.map +1 -1
  38. package/dist/esm/core/aggregation/signing-session.js +3 -3
  39. package/dist/esm/core/aggregation/signing-session.js.map +1 -1
  40. package/dist/esm/core/aggregation/transport/http/envelope.js +3 -3
  41. package/dist/esm/core/aggregation/transport/http/inbox-buffer.js +1 -1
  42. package/dist/esm/core/aggregation/transport/http/nonce-cache.js +1 -1
  43. package/dist/esm/core/aggregation/transport/http/rate-limiter.js +1 -1
  44. package/dist/esm/core/aggregation/transport/http/request-auth.js +1 -1
  45. package/dist/esm/core/aggregation/transport/http/server.js +1 -1
  46. package/dist/esm/core/aggregation/transport/http/sse-stream.js +1 -1
  47. package/dist/esm/core/aggregation/transport/http/sse-writer.js +1 -1
  48. package/dist/esm/core/aggregation/transport/in-memory.js +1 -1
  49. package/dist/esm/core/aggregation/transport/nostr.js +6 -6
  50. package/dist/esm/core/beacon/beacon.js +15 -10
  51. package/dist/esm/core/beacon/beacon.js.map +1 -1
  52. package/dist/esm/core/beacon/cas-beacon.js +6 -6
  53. package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
  54. package/dist/esm/core/beacon/singleton-beacon.js +2 -2
  55. package/dist/esm/core/beacon/singleton-beacon.js.map +1 -1
  56. package/dist/esm/core/beacon/smt-beacon.js +3 -3
  57. package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
  58. package/dist/esm/core/resolver.js +8 -8
  59. package/dist/esm/core/resolver.js.map +1 -1
  60. package/dist/esm/core/updater.js +6 -6
  61. package/dist/esm/core/updater.js.map +1 -1
  62. package/dist/esm/did-btcr2.js +2 -2
  63. package/dist/esm/index.js +3 -0
  64. package/dist/esm/index.js.map +1 -1
  65. package/dist/types/core/aggregation/beacon-strategy.d.ts +8 -4
  66. package/dist/types/core/aggregation/beacon-strategy.d.ts.map +1 -1
  67. package/dist/types/core/aggregation/cohort.d.ts +88 -17
  68. package/dist/types/core/aggregation/cohort.d.ts.map +1 -1
  69. package/dist/types/core/aggregation/conditions.d.ts +28 -0
  70. package/dist/types/core/aggregation/conditions.d.ts.map +1 -1
  71. package/dist/types/core/aggregation/fallback-spend.d.ts +94 -0
  72. package/dist/types/core/aggregation/fallback-spend.d.ts.map +1 -0
  73. package/dist/types/core/aggregation/logger.d.ts +1 -1
  74. package/dist/types/core/aggregation/messages/base.d.ts +6 -0
  75. package/dist/types/core/aggregation/messages/base.d.ts.map +1 -1
  76. package/dist/types/core/aggregation/messages/bodies.d.ts +50 -2
  77. package/dist/types/core/aggregation/messages/bodies.d.ts.map +1 -1
  78. package/dist/types/core/aggregation/messages/constants.d.ts +8 -0
  79. package/dist/types/core/aggregation/messages/constants.d.ts.map +1 -1
  80. package/dist/types/core/aggregation/messages/factories.d.ts +40 -0
  81. package/dist/types/core/aggregation/messages/factories.d.ts.map +1 -1
  82. package/dist/types/core/aggregation/messages/guards.d.ts.map +1 -1
  83. package/dist/types/core/aggregation/participant.d.ts +41 -7
  84. package/dist/types/core/aggregation/participant.d.ts.map +1 -1
  85. package/dist/types/core/aggregation/phases.d.ts +8 -2
  86. package/dist/types/core/aggregation/phases.d.ts.map +1 -1
  87. package/dist/types/core/aggregation/recovery-policy.d.ts +132 -0
  88. package/dist/types/core/aggregation/recovery-policy.d.ts.map +1 -0
  89. package/dist/types/core/aggregation/recovery-spend.d.ts +94 -0
  90. package/dist/types/core/aggregation/recovery-spend.d.ts.map +1 -0
  91. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts +13 -3
  92. package/dist/types/core/aggregation/runner/aggregation-runner.d.ts.map +1 -1
  93. package/dist/types/core/aggregation/runner/events.d.ts +28 -7
  94. package/dist/types/core/aggregation/runner/events.d.ts.map +1 -1
  95. package/dist/types/core/aggregation/runner/participant-runner.d.ts +3 -3
  96. package/dist/types/core/aggregation/runner/participant-runner.d.ts.map +1 -1
  97. package/dist/types/core/aggregation/runner/service-runner.d.ts +28 -3
  98. package/dist/types/core/aggregation/runner/service-runner.d.ts.map +1 -1
  99. package/dist/types/core/aggregation/service.d.ts +26 -2
  100. package/dist/types/core/aggregation/service.d.ts.map +1 -1
  101. package/dist/types/core/aggregation/signing-session.d.ts +2 -2
  102. package/dist/types/core/aggregation/signing-session.d.ts.map +1 -1
  103. package/dist/types/core/aggregation/transport/http/envelope.d.ts +3 -3
  104. package/dist/types/core/aggregation/transport/http/inbox-buffer.d.ts +1 -1
  105. package/dist/types/core/aggregation/transport/http/nonce-cache.d.ts +1 -1
  106. package/dist/types/core/aggregation/transport/http/rate-limiter.d.ts +1 -1
  107. package/dist/types/core/aggregation/transport/http/request-auth.d.ts +1 -1
  108. package/dist/types/core/aggregation/transport/http/server.d.ts +1 -1
  109. package/dist/types/core/aggregation/transport/http/sse-stream.d.ts +2 -2
  110. package/dist/types/core/aggregation/transport/http/sse-writer.d.ts +1 -1
  111. package/dist/types/core/aggregation/transport/in-memory.d.ts +1 -1
  112. package/dist/types/core/aggregation/transport/nostr.d.ts +4 -4
  113. package/dist/types/core/aggregation/transport/transport.d.ts +4 -4
  114. package/dist/types/core/aggregation/transport/transport.d.ts.map +1 -1
  115. package/dist/types/core/beacon/beacon.d.ts +7 -7
  116. package/dist/types/core/beacon/beacon.d.ts.map +1 -1
  117. package/dist/types/core/beacon/cas-beacon.d.ts +2 -2
  118. package/dist/types/core/beacon/interfaces.d.ts +1 -1
  119. package/dist/types/core/resolver.d.ts +3 -3
  120. package/dist/types/core/updater.d.ts +4 -4
  121. package/dist/types/did-btcr2.d.ts +2 -2
  122. package/dist/types/index.d.ts +3 -0
  123. package/dist/types/index.d.ts.map +1 -1
  124. package/package.json +4 -4
  125. package/src/core/aggregation/beacon-strategy.ts +27 -9
  126. package/src/core/aggregation/cohort.ts +171 -35
  127. package/src/core/aggregation/conditions.ts +56 -0
  128. package/src/core/aggregation/fallback-spend.ts +223 -0
  129. package/src/core/aggregation/logger.ts +1 -1
  130. package/src/core/aggregation/messages/base.ts +6 -0
  131. package/src/core/aggregation/messages/bodies.ts +94 -1
  132. package/src/core/aggregation/messages/constants.ts +12 -0
  133. package/src/core/aggregation/messages/factories.ts +57 -0
  134. package/src/core/aggregation/messages/guards.ts +6 -0
  135. package/src/core/aggregation/participant.ts +255 -23
  136. package/src/core/aggregation/phases.ts +9 -0
  137. package/src/core/aggregation/recovery-policy.ts +237 -0
  138. package/src/core/aggregation/recovery-spend.ts +192 -0
  139. package/src/core/aggregation/runner/aggregation-runner.ts +27 -5
  140. package/src/core/aggregation/runner/events.ts +26 -7
  141. package/src/core/aggregation/runner/participant-runner.ts +75 -23
  142. package/src/core/aggregation/runner/service-runner.ts +120 -10
  143. package/src/core/aggregation/service.ts +260 -14
  144. package/src/core/aggregation/signing-session.ts +3 -3
  145. package/src/core/aggregation/transport/http/envelope.ts +3 -3
  146. package/src/core/aggregation/transport/http/inbox-buffer.ts +1 -1
  147. package/src/core/aggregation/transport/http/nonce-cache.ts +1 -1
  148. package/src/core/aggregation/transport/http/rate-limiter.ts +1 -1
  149. package/src/core/aggregation/transport/http/request-auth.ts +1 -1
  150. package/src/core/aggregation/transport/http/server.ts +1 -1
  151. package/src/core/aggregation/transport/http/sse-stream.ts +2 -2
  152. package/src/core/aggregation/transport/http/sse-writer.ts +1 -1
  153. package/src/core/aggregation/transport/in-memory.ts +1 -1
  154. package/src/core/aggregation/transport/nostr.ts +6 -6
  155. package/src/core/aggregation/transport/transport.ts +4 -4
  156. package/src/core/beacon/beacon.ts +16 -11
  157. package/src/core/beacon/cas-beacon.ts +7 -7
  158. package/src/core/beacon/interfaces.ts +1 -1
  159. package/src/core/beacon/singleton-beacon.ts +2 -2
  160. package/src/core/beacon/smt-beacon.ts +3 -3
  161. package/src/core/resolver.ts +8 -8
  162. package/src/core/updater.ts +6 -6
  163. package/src/did-btcr2.ts +2 -2
  164. package/src/index.ts +3 -0
@@ -10,7 +10,9 @@
10
10
  * Guards validate both `type` and the presence of required body fields so they
11
11
  * are safe to use on messages that have round-tripped through JSON / a relay.
12
12
  */
13
- import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
13
+ import { KNOWN_FUNDING_MODELS } from '../conditions.js';
14
+ import { MAX_RECOVERY_SEQUENCE } from '../recovery-policy.js';
15
+ import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, FALLBACK_AUTHORIZATION_REQUEST, FALLBACK_SIGNATURE, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_NONINCLUDED, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
14
16
  // ── Type guards ───────────────────────────────────────────────────────────
15
17
  // Each guard validates `type` plus required body fields so it's safe to use
16
18
  // on messages that have round-tripped through JSON / a relay.
@@ -25,6 +27,16 @@ const optIntMin = (b, k, min) => {
25
27
  const v = b ? b[k] : undefined;
26
28
  return v === undefined || (typeof v === 'number' && Number.isInteger(v) && v >= min);
27
29
  };
30
+ /** Present, an integer, and within [min, max] inclusive. */
31
+ const intInRange = (b, k, min, max) => {
32
+ const v = b ? b[k] : undefined;
33
+ return typeof v === 'number' && Number.isInteger(v) && v >= min && v <= max;
34
+ };
35
+ /** Absent, or present as a string in the allowed set. */
36
+ const optStrOneOf = (b, k, allowed) => {
37
+ const v = b ? b[k] : undefined;
38
+ return v === undefined || (typeof v === 'string' && allowed.includes(v));
39
+ };
28
40
  const hasBool = (b, k) => !!b && typeof b[k] === 'boolean';
29
41
  const hasBytes = (b, k) => !!b && b[k] instanceof Uint8Array;
30
42
  const hasBytesArray = (b, k) => {
@@ -42,6 +54,20 @@ export function isCohortAdvertMessage(m) {
42
54
  && optIntMin(m.body, 'maxParticipants', 1)
43
55
  && hasStr(m.body, 'beaconType')
44
56
  && hasStr(m.body, 'network')
57
+ // Recovery params are mandatory: a participant must see the recovery terms
58
+ // (key + timelock) before funding the beacon UTXO (ADR 042). recoverySequence
59
+ // is range-checked here because the participant funds based on the advert and
60
+ // does not separately run validateCohortConditions: an out-of-range value
61
+ // (e.g. one with the BIP-68 disable bit set) must be rejected before funding.
62
+ && hasStr(m.body, 'recoveryKey')
63
+ && intInRange(m.body, 'recoverySequence', 1, MAX_RECOVERY_SEQUENCE)
64
+ // fundingModel is optional on the wire (absent means the operator-funded
65
+ // default), but when present it must name a known model.
66
+ && optStrOneOf(m.body, 'fundingModel', KNOWN_FUNDING_MODELS)
67
+ // fallbackThreshold is optional (absent means n-1 at keygen); when present it
68
+ // must be a positive integer. The upper bound against the cohort size is
69
+ // checked when the participant recomputes the beacon address.
70
+ && optIntMin(m.body, 'fallbackThreshold', 1)
45
71
  && hasBytes(m.body, 'communicationPk');
46
72
  }
47
73
  export function isCohortOptInMessage(m) {
@@ -64,6 +90,9 @@ export function isSubmitUpdateMessage(m) {
64
90
  && hasStr(m.body, 'cohortId')
65
91
  && !!m.body && typeof m.body.signedUpdate === 'object';
66
92
  }
93
+ export function isSubmitNonIncludedMessage(m) {
94
+ return m.type === SUBMIT_NONINCLUDED && hasStr(m.body, 'cohortId');
95
+ }
67
96
  export function isDistributeAggregatedDataMessage(m) {
68
97
  return m.type === DISTRIBUTE_AGGREGATED_DATA
69
98
  && hasStr(m.body, 'cohortId')
@@ -101,4 +130,20 @@ export function isSignatureAuthorizationMessage(m) {
101
130
  && hasStr(m.body, 'sessionId')
102
131
  && hasBytes(m.body, 'partialSignature');
103
132
  }
133
+ export function isFallbackAuthorizationRequestMessage(m) {
134
+ return m.type === FALLBACK_AUTHORIZATION_REQUEST
135
+ && hasStr(m.body, 'cohortId')
136
+ && hasStr(m.body, 'sessionId')
137
+ && hasStr(m.body, 'pendingTx')
138
+ && hasStr(m.body, 'prevOutScriptHex')
139
+ && hasStr(m.body, 'prevOutValue')
140
+ && hasStr(m.body, 'fallbackLeafScriptHex');
141
+ }
142
+ export function isFallbackSignatureMessage(m) {
143
+ return m.type === FALLBACK_SIGNATURE
144
+ && hasStr(m.body, 'cohortId')
145
+ && hasStr(m.body, 'sessionId')
146
+ && hasBytes(m.body, 'signerPk')
147
+ && hasBytes(m.body, 'fallbackSignature');
148
+ }
104
149
  //# sourceMappingURL=bodies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bodies.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/bodies.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bodies.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/bodies.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,8 @@
7
7
  * - Step 3 (Aggregate & Validate): DISTRIBUTE_AGGREGATED_DATA, VALIDATION_ACK
8
8
  * - Step 4 (Sign & Broadcast): AUTHORIZATION_REQUEST, NONCE_CONTRIBUTION,
9
9
  * AGGREGATED_NONCE, SIGNATURE_AUTHORIZATION
10
+ * - Step 4 fallback (k-of-n script path, ADR 042): FALLBACK_AUTHORIZATION_REQUEST,
11
+ * FALLBACK_SIGNATURE
10
12
  */
11
13
  export const AGGREGATION_MESSAGE_PREFIX = 'https://btcr2.dev/aggregation';
12
14
  // Step 1: Cohort Formation
@@ -16,6 +18,8 @@ export const COHORT_OPT_IN_ACCEPT = `${AGGREGATION_MESSAGE_PREFIX}/keygen/cohort
16
18
  export const COHORT_READY = `${AGGREGATION_MESSAGE_PREFIX}/keygen/cohort_ready`;
17
19
  // Step 2 + 3: Update Submission, Aggregation, Validation
18
20
  export const SUBMIT_UPDATE = `${AGGREGATION_MESSAGE_PREFIX}/update/submit_update`;
21
+ /** A member with no update this round declines explicitly (cooperative non-inclusion). */
22
+ export const SUBMIT_NONINCLUDED = `${AGGREGATION_MESSAGE_PREFIX}/update/submit_nonincluded`;
19
23
  export const DISTRIBUTE_AGGREGATED_DATA = `${AGGREGATION_MESSAGE_PREFIX}/update/distribute_aggregated_data`;
20
24
  export const VALIDATION_ACK = `${AGGREGATION_MESSAGE_PREFIX}/update/validation_ack`;
21
25
  // Step 4: Signing
@@ -23,4 +27,11 @@ export const AUTHORIZATION_REQUEST = `${AGGREGATION_MESSAGE_PREFIX}/sign/authori
23
27
  export const NONCE_CONTRIBUTION = `${AGGREGATION_MESSAGE_PREFIX}/sign/nonce_contribution`;
24
28
  export const AGGREGATED_NONCE = `${AGGREGATION_MESSAGE_PREFIX}/sign/aggregated_nonce`;
25
29
  export const SIGNATURE_AUTHORIZATION = `${AGGREGATION_MESSAGE_PREFIX}/sign/signature_authorization`;
30
+ // Step 4 fallback: k-of-n script-path signing when the optimistic n-of-n key
31
+ // path stalls (graceful liveness, ADR 042). A single standalone BIP-340
32
+ // signature per member, no nonce round.
33
+ /** Service asks members to sign the fallback (k-of-n) script path of the beacon tx. */
34
+ export const FALLBACK_AUTHORIZATION_REQUEST = `${AGGREGATION_MESSAGE_PREFIX}/sign/fallback_authorization_request`;
35
+ /** A member returns a standalone BIP-340 signature over the fallback script-path sighash. */
36
+ export const FALLBACK_SIGNATURE = `${AGGREGATION_MESSAGE_PREFIX}/sign/fallback_signature`;
26
37
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,CAAC;AAE1E,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,0BAA0B,8BAA8B,CAAC;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,0BAA0B,sBAAsB,CAAC;AAEhF,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,0BAA0B,oCAAoC,CAAC;AAC5G,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,0BAA0B,wBAAwB,CAAC;AAEpF,kBAAkB;AAClB,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,0BAA0B,6BAA6B,CAAC;AAChG,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,0BAA0B,0BAA0B,CAAC;AAC1F,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,0BAA0B,wBAAwB,CAAC;AACtF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,0BAA0B,+BAA+B,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,+BAA+B,CAAC;AAE1E,2BAA2B;AAC3B,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,0BAA0B,8BAA8B,CAAC;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,0BAA0B,sBAAsB,CAAC;AAEhF,yDAAyD;AACzD,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,0BAA0B,uBAAuB,CAAC;AAClF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,0BAA0B,4BAA4B,CAAC;AAC5F,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,0BAA0B,oCAAoC,CAAC;AAC5G,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,0BAA0B,wBAAwB,CAAC;AAEpF,kBAAkB;AAClB,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,0BAA0B,6BAA6B,CAAC;AAChG,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,0BAA0B,0BAA0B,CAAC;AAC1F,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,0BAA0B,wBAAwB,CAAC;AACtF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,0BAA0B,+BAA+B,CAAC;AAEpG,6EAA6E;AAC7E,wEAAwE;AACxE,wCAAwC;AACxC,uFAAuF;AACvF,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,0BAA0B,sCAAsC,CAAC;AAClH,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,0BAA0B,0BAA0B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { BaseMessage } from './base.js';
2
- import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
2
+ import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, FALLBACK_AUTHORIZATION_REQUEST, FALLBACK_SIGNATURE, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_NONINCLUDED, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
3
3
  /**
4
4
  * Factory function for creating a Cohort Advert message, which is used to announce the formation of
5
5
  * a new cohort and invite participants to join.
@@ -40,6 +40,15 @@ export function createSubmitUpdateMessage(fields) {
40
40
  const { from, to, ...body } = fields;
41
41
  return new BaseMessage({ type: SUBMIT_UPDATE, from, to, body });
42
42
  }
43
+ /**
44
+ * Factory for a Submit Non-Included message: a member declares it has no update
45
+ * this round (cooperative non-inclusion). Membership is proven by the signed
46
+ * envelope, so the body carries only the cohortId.
47
+ */
48
+ export function createSubmitNonIncludedMessage(fields) {
49
+ const { from, to, ...body } = fields;
50
+ return new BaseMessage({ type: SUBMIT_NONINCLUDED, from, to, body });
51
+ }
43
52
  /**
44
53
  * Factory function for creating a Distribute Aggregated Data message, which is sent by the
45
54
  * aggregator to distribute the aggregated data to participants for validation.
@@ -110,4 +119,21 @@ export function createSignatureAuthorizationMessage(fields) {
110
119
  const { from, to, ...body } = fields;
111
120
  return new BaseMessage({ type: SIGNATURE_AUTHORIZATION, from, to, body });
112
121
  }
122
+ /**
123
+ * Factory for a Fallback Authorization Request: the service asks members to
124
+ * authorize the k-of-n script-path spend of the beacon transaction when the
125
+ * optimistic n-of-n key path stalls (ADR 042).
126
+ */
127
+ export function createFallbackAuthorizationRequestMessage(fields) {
128
+ const { from, to, ...body } = fields;
129
+ return new BaseMessage({ type: FALLBACK_AUTHORIZATION_REQUEST, from, to, body });
130
+ }
131
+ /**
132
+ * Factory for a Fallback Signature: a member's standalone BIP-340 signature over
133
+ * the fallback script-path sighash (no nonce round).
134
+ */
135
+ export function createFallbackSignatureMessage(fields) {
136
+ const { from, to, ...body } = fields;
137
+ return new BaseMessage({ type: FALLBACK_SIGNATURE, from, to, body });
138
+ }
113
139
  //# sourceMappingURL=factories.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factories.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/factories.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"factories.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/factories.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
1
+ import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, FALLBACK_AUTHORIZATION_REQUEST, FALLBACK_SIGNATURE, NONCE_CONTRIBUTION, SIGNATURE_AUTHORIZATION, SUBMIT_NONINCLUDED, SUBMIT_UPDATE, VALIDATION_ACK, } from './constants.js';
2
2
  const KEYGEN_VALUES = new Set([
3
3
  COHORT_ADVERT,
4
4
  COHORT_OPT_IN,
@@ -7,6 +7,7 @@ const KEYGEN_VALUES = new Set([
7
7
  ]);
8
8
  const UPDATE_VALUES = new Set([
9
9
  SUBMIT_UPDATE,
10
+ SUBMIT_NONINCLUDED,
10
11
  DISTRIBUTE_AGGREGATED_DATA,
11
12
  VALIDATION_ACK,
12
13
  ]);
@@ -15,6 +16,8 @@ const SIGN_VALUES = new Set([
15
16
  NONCE_CONTRIBUTION,
16
17
  AGGREGATED_NONCE,
17
18
  SIGNATURE_AUTHORIZATION,
19
+ FALLBACK_AUTHORIZATION_REQUEST,
20
+ FALLBACK_SIGNATURE,
18
21
  ]);
19
22
  /**
20
23
  * Checks if the provided type is a valid aggregation message type.
@@ -1 +1 @@
1
- {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/guards.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC;IACzC,aAAa;IACb,aAAa;IACb,oBAAoB;IACpB,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC;IACzC,aAAa;IACb,0BAA0B;IAC1B,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,WAAW,GAAgB,IAAI,GAAG,CAAC;IACvC,qBAAqB;IACrB,kBAAkB;IAClB,gBAAgB;IAChB,uBAAuB;CACxB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../../../src/core/aggregation/messages/guards.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,0BAA0B,EAC1B,8BAA8B,EAC9B,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC;IACzC,aAAa;IACb,aAAa;IACb,oBAAoB;IACpB,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,aAAa,GAAgB,IAAI,GAAG,CAAC;IACzC,aAAa;IACb,kBAAkB;IAClB,0BAA0B;IAC1B,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,WAAW,GAAgB,IAAI,GAAG,CAAC;IACvC,qBAAqB;IACrB,kBAAkB;IAClB,gBAAgB;IAChB,uBAAuB;IACvB,8BAA8B;IAC9B,kBAAkB;CACnB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
@@ -1,15 +1,54 @@
1
1
  import { canonicalHash } from '@did-btcr2/common';
2
+ import { schnorr } from '@noble/curves/secp256k1.js';
2
3
  import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
3
- import { Transaction } from '@scure/btc-signer';
4
+ import { Script, Transaction } from '@scure/btc-signer';
4
5
  import { getBeaconStrategy } from './beacon-strategy.js';
5
6
  import { AggregationCohort } from './cohort.js';
6
7
  import { AggregationParticipantError } from './errors.js';
8
+ import { fallbackSighash } from './fallback-spend.js';
9
+ import { buildFallbackLeaf } from './recovery-policy.js';
7
10
  import { isCohortAdvertMessage } from './messages/bodies.js';
8
11
  import { AGGREGATION_WIRE_VERSION } from './messages/base.js';
9
- import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, } from './messages/constants.js';
10
- import { createCohortOptInMessage, createNonceContributionMessage, createSignatureAuthorizationMessage, createSubmitUpdateMessage, createValidationAckMessage, } from './messages/factories.js';
12
+ import { AGGREGATED_NONCE, AUTHORIZATION_REQUEST, COHORT_ADVERT, COHORT_OPT_IN_ACCEPT, COHORT_READY, DISTRIBUTE_AGGREGATED_DATA, FALLBACK_AUTHORIZATION_REQUEST, } from './messages/constants.js';
13
+ import { createCohortOptInMessage, createFallbackSignatureMessage, createNonceContributionMessage, createSignatureAuthorizationMessage, createSubmitNonIncludedMessage, createSubmitUpdateMessage, createValidationAckMessage, } from './messages/factories.js';
11
14
  import { ParticipantCohortPhase } from './phases.js';
12
15
  import { BeaconSigningSession } from './signing-session.js';
16
+ /**
17
+ * True if `tx` has an OP_RETURN output whose payload equals the 32-byte signal
18
+ * `signalHex`. A member binds its fallback signature to the exact signal it
19
+ * validated, so a coordinator that drives the fallback output selection cannot
20
+ * anchor a different announcement (a stale signal, or one whose CAS/SMT root
21
+ * omits the member's update) under the member's signature.
22
+ */
23
+ function txEmbedsSignal(tx, signalHex) {
24
+ let expected;
25
+ try {
26
+ expected = hexToBytes(signalHex);
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ if (expected.length === 0)
32
+ return false;
33
+ for (let i = 0; i < tx.outputsLength; i++) {
34
+ const script = tx.getOutput(i)?.script;
35
+ if (!script)
36
+ continue;
37
+ let decoded;
38
+ try {
39
+ decoded = Script.decode(script);
40
+ }
41
+ catch {
42
+ continue;
43
+ }
44
+ if (decoded.length === 2 && decoded[0] === 'RETURN' && decoded[1] instanceof Uint8Array) {
45
+ const payload = decoded[1];
46
+ if (payload.length === expected.length && payload.every((b, j) => b === expected[j]))
47
+ return true;
48
+ }
49
+ }
50
+ return false;
51
+ }
13
52
  /**
14
53
  * Sans-I/O state machine for an Aggregation Participant.
15
54
  *
@@ -36,7 +75,7 @@ export class AggregationParticipant {
36
75
  }
37
76
  /**
38
77
  * Process an incoming message. Updates internal state but never produces
39
- * outgoing messages those come exclusively from action methods.
78
+ * outgoing messages: those come exclusively from action methods.
40
79
  */
41
80
  receive(message) {
42
81
  // Reject messages whose wire version doesn't match what this build speaks.
@@ -63,8 +102,11 @@ export class AggregationParticipant {
63
102
  case AGGREGATED_NONCE:
64
103
  this.#handleAggregatedNonce(message);
65
104
  break;
105
+ case FALLBACK_AUTHORIZATION_REQUEST:
106
+ this.#handleFallbackAuthorizationRequest(message);
107
+ break;
66
108
  default:
67
- // Unknown message type silently ignore
109
+ // Unknown message type, silently ignore
68
110
  break;
69
111
  }
70
112
  }
@@ -109,13 +151,20 @@ export class AggregationParticipant {
109
151
  if (!state || state.phase !== ParticipantCohortPhase.Discovered) {
110
152
  throw new AggregationParticipantError(`Cannot join cohort ${cohortId}: not in Discovered phase.`, 'INVALID_PHASE', { cohortId, phase: state?.phase });
111
153
  }
112
- // Create local cohort to track our view
154
+ // Create local cohort to track our view. Carry the advertised recovery
155
+ // params so validateMembership recomputes the same script-tree beacon
156
+ // address the service derived (ADR 042); a mismatch rejects the cohort.
157
+ const advert = state.advert;
113
158
  const cohort = new AggregationCohort({
114
159
  id: cohortId,
115
160
  serviceDid: state.serviceDid,
116
- minParticipants: state.advert.minParticipants,
117
- network: state.advert.network,
118
- beaconType: state.advert.beaconType,
161
+ minParticipants: advert.minParticipants,
162
+ network: advert.network,
163
+ beaconType: advert.beaconType,
164
+ recoveryKey: advert.recoveryKey ? hexToBytes(advert.recoveryKey) : undefined,
165
+ recoverySequence: advert.recoverySequence,
166
+ fundingModel: advert.fundingModel,
167
+ fallbackThreshold: advert.fallbackThreshold,
119
168
  });
120
169
  state.cohort = cohort;
121
170
  state.phase = ParticipantCohortPhase.OptedIn;
@@ -129,10 +178,10 @@ export class AggregationParticipant {
129
178
  return [optInMessage];
130
179
  }
131
180
  #handleOptInAccept(message) {
132
- // Acknowledgment from service no state change needed
181
+ // Acknowledgment from service, no state change needed
133
182
  void message;
134
183
  }
135
- /** Cohorts that have been finalized beacon address available. */
184
+ /** Cohorts that have been finalized: beacon address available. */
136
185
  get joinedCohorts() {
137
186
  const map = new Map();
138
187
  for (const [id, state] of this.#cohortStates) {
@@ -175,6 +224,7 @@ export class AggregationParticipant {
175
224
  throw new AggregationParticipantError(`Cannot submit update to cohort ${cohortId}: not in CohortReady phase.`, 'INVALID_PHASE', { cohortId, phase: state?.phase });
176
225
  }
177
226
  state.submittedUpdate = signedUpdate;
227
+ state.included = true;
178
228
  state.phase = ParticipantCohortPhase.UpdateSubmitted;
179
229
  const message = createSubmitUpdateMessage({
180
230
  from: this.did,
@@ -184,6 +234,28 @@ export class AggregationParticipant {
184
234
  });
185
235
  return [message];
186
236
  }
237
+ /**
238
+ * User action: decline to submit an update this round (cooperative
239
+ * non-inclusion). The member stays in the cohort and still signs; it will be
240
+ * absent from the CAS Announcement Map, or carry a non-inclusion leaf in the
241
+ * SMT. Returns the SUBMIT_NONINCLUDED message to send.
242
+ */
243
+ declineUpdate(cohortId) {
244
+ const state = this.#cohortStates.get(cohortId);
245
+ if (!state || state.phase !== ParticipantCohortPhase.CohortReady) {
246
+ throw new AggregationParticipantError(`Cannot decline in cohort ${cohortId}: not in CohortReady phase.`, 'INVALID_PHASE', { cohortId, phase: state?.phase });
247
+ }
248
+ // Leave submittedUpdate unset; included=false is the load-bearing signal that
249
+ // the validation handler uses to validate the non-inclusion slot.
250
+ state.included = false;
251
+ state.phase = ParticipantCohortPhase.NonIncluded;
252
+ const message = createSubmitNonIncludedMessage({
253
+ from: this.did,
254
+ to: state.serviceDid,
255
+ cohortId,
256
+ });
257
+ return [message];
258
+ }
187
259
  /** Aggregated data awaiting user validation. */
188
260
  get pendingValidations() {
189
261
  const map = new Map();
@@ -197,9 +269,9 @@ export class AggregationParticipant {
197
269
  /**
198
270
  * The validated aggregated data retained for a cohort, regardless of phase.
199
271
  * Unlike {@link pendingValidations} (which lists only cohorts still awaiting
200
- * the validate decision), this returns the stored validation including the
201
- * participant's sidecar (the CAS Announcement map or its SMT inclusion proof)
202
- * so it is still readable once the cohort reaches Complete. Returns
272
+ * the validate decision), this returns the stored validation, including the
273
+ * participant's sidecar (the CAS Announcement map or its SMT inclusion proof),
274
+ * so it is still readable once the cohort reaches Complete. Returns
203
275
  * undefined before aggregated data has been received.
204
276
  */
205
277
  getValidation(cohortId) {
@@ -210,9 +282,13 @@ export class AggregationParticipant {
210
282
  if (!cohortId)
211
283
  return;
212
284
  const state = this.#cohortStates.get(cohortId);
213
- if (!state || state.phase !== ParticipantCohortPhase.UpdateSubmitted)
285
+ // A submitter is in UpdateSubmitted; a decliner (cooperative non-inclusion)
286
+ // is in NonIncluded. Both validate their own slot in the distributed data.
287
+ if (!state || (state.phase !== ParticipantCohortPhase.UpdateSubmitted && state.phase !== ParticipantCohortPhase.NonIncluded))
214
288
  return;
215
- if (!state.submittedUpdate)
289
+ const declined = state.included === false;
290
+ // A submitter must have its update stored; a decliner has none by design.
291
+ if (!declined && !state.submittedUpdate)
216
292
  return;
217
293
  const beaconType = message.body?.beaconType;
218
294
  if (!beaconType)
@@ -221,11 +297,14 @@ export class AggregationParticipant {
221
297
  if (!strategy)
222
298
  return;
223
299
  const signalBytesHex = message.body?.signalBytesHex ?? '';
224
- const expectedHash = canonicalHash(state.submittedUpdate);
300
+ // Decliner validates its non-inclusion slot (CAS absence / SMT non-inclusion
301
+ // proof); submitter validates inclusion against its update hash.
302
+ const expectedHash = declined ? '' : canonicalHash(state.submittedUpdate);
225
303
  const result = strategy.validateParticipantView({
226
304
  participantDid: this.did,
227
- submittedUpdate: state.submittedUpdate,
228
- expectedHash,
305
+ included: !declined,
306
+ submittedUpdate: declined ? undefined : state.submittedUpdate,
307
+ expectedHash: declined ? undefined : expectedHash,
229
308
  body: message.body,
230
309
  });
231
310
  state.validation = {
@@ -236,6 +315,7 @@ export class AggregationParticipant {
236
315
  matches: result.matches,
237
316
  casAnnouncement: result.casAnnouncement,
238
317
  smtProof: result.smtProof,
318
+ included: !declined,
239
319
  };
240
320
  state.phase = ParticipantCohortPhase.AwaitingValidation;
241
321
  }
@@ -305,6 +385,23 @@ export class AggregationParticipant {
305
385
  };
306
386
  state.phase = ParticipantCohortPhase.AwaitingSigning;
307
387
  }
388
+ /**
389
+ * Bind a signing approval to the announcement the member validated: a beacon
390
+ * transaction MUST carry an OP_RETURN with the exact 32-byte signal stored when
391
+ * the aggregated data was distributed. Both the optimistic nonce approval and
392
+ * the fallback approval sign with SIGHASH_DEFAULT (committing to every output)
393
+ * while the coordinator drives output selection, so without this check a
394
+ * coordinator could anchor a different signal under the member's signature.
395
+ */
396
+ #assertTxAnchorsValidatedSignal(cohortId, state, tx) {
397
+ const signalHex = state.validation?.signalBytesHex;
398
+ if (!signalHex) {
399
+ throw new AggregationParticipantError(`Cohort ${cohortId} has no validated signal to bind the signature to.`, 'MISSING_STATE', { cohortId });
400
+ }
401
+ if (!txEmbedsSignal(tx, signalHex)) {
402
+ throw new AggregationParticipantError(`Transaction for cohort ${cohortId} does not anchor the validated signal.`, 'SIGNAL_MISMATCH', { cohortId });
403
+ }
404
+ }
308
405
  /**
309
406
  * User action: approve signing and generate nonce contribution.
310
407
  */
@@ -316,7 +413,12 @@ export class AggregationParticipant {
316
413
  if (!state.signingRequest || !state.cohort) {
317
414
  throw new AggregationParticipantError(`Cohort ${cohortId} missing signing request or cohort state.`, 'MISSING_STATE', { cohortId });
318
415
  }
319
- const tx = Transaction.fromRaw(hexToBytes(state.signingRequest.pendingTxHex));
416
+ // allowUnknownOutputs: a beacon transaction carries an OP_RETURN signal
417
+ // output, which scure does not classify as a known (spendable) output type;
418
+ // re-parsing the raw tx would otherwise throw.
419
+ const tx = Transaction.fromRaw(hexToBytes(state.signingRequest.pendingTxHex), { allowUnknownOutputs: true });
420
+ // Refuse to sign unless the tx anchors the signal this member validated.
421
+ this.#assertTxAnchorsValidatedSignal(cohortId, state, tx);
320
422
  // Derive UTXO metadata for Taproot sighash (BIP-341). Use the script
321
423
  // supplied by the service in AUTHORIZATION_REQUEST rather than reading
322
424
  // the change output: input and change may use different scripts in future
@@ -359,7 +461,7 @@ export class AggregationParticipant {
359
461
  }
360
462
  /**
361
463
  * User action: generate and return the partial signature.
362
- * In most UIs this is automatic after AwaitingPartialSig but exposing it
464
+ * In most UIs this is automatic after AwaitingPartialSig, but exposing it
363
465
  * as an explicit action lets the client UI confirm before signing if desired.
364
466
  */
365
467
  generatePartialSignature(cohortId) {
@@ -381,6 +483,93 @@ export class AggregationParticipant {
381
483
  partialSignature: partialSig,
382
484
  })];
383
485
  }
486
+ /** Fallback signing requests awaiting user approval (UI: review the fallback spend). */
487
+ get pendingFallbackRequests() {
488
+ const map = new Map();
489
+ for (const [id, state] of this.#cohortStates) {
490
+ if (state.phase === ParticipantCohortPhase.AwaitingFallbackSig && state.fallbackRequest) {
491
+ map.set(id, state.fallbackRequest);
492
+ }
493
+ }
494
+ return map;
495
+ }
496
+ #handleFallbackAuthorizationRequest(message) {
497
+ const cohortId = message.body?.cohortId;
498
+ if (!cohortId)
499
+ return;
500
+ const state = this.#cohortStates.get(cohortId);
501
+ if (!state || !state.cohort)
502
+ return;
503
+ // The service can fall back at any point after the member validated. This
504
+ // includes the local Complete phase a member reaches the moment it sends its
505
+ // optimistic partial signature: the cohort has NOT finalized (the service
506
+ // only falls back before optimistic completion), and those members are
507
+ // exactly the k signers the fallback needs. Signing both the optimistic
508
+ // partial sig and the fallback sig is safe - both authorize the same outputs,
509
+ // and only one witness can ever confirm the single UTXO. A genuinely failed
510
+ // member is excluded. Ignore a duplicate request already being processed.
511
+ const acceptFrom = [
512
+ ParticipantCohortPhase.ValidationSent,
513
+ ParticipantCohortPhase.AwaitingSigning,
514
+ ParticipantCohortPhase.NonceSent,
515
+ ParticipantCohortPhase.AwaitingPartialSig,
516
+ ParticipantCohortPhase.Complete,
517
+ ];
518
+ if (!acceptFrom.includes(state.phase))
519
+ return;
520
+ const sessionId = message.body?.sessionId;
521
+ const pendingTxHex = message.body?.pendingTx;
522
+ const prevOutScriptHex = message.body?.prevOutScriptHex;
523
+ const prevOutValue = message.body?.prevOutValue;
524
+ const fallbackLeafScriptHex = message.body?.fallbackLeafScriptHex;
525
+ if (!sessionId || !pendingTxHex || !prevOutScriptHex || !prevOutValue || !fallbackLeafScriptHex)
526
+ return;
527
+ state.fallbackRequest = { cohortId, sessionId, pendingTxHex, prevOutScriptHex, prevOutValue, fallbackLeafScriptHex };
528
+ // The optimistic path is abandoned; wipe any retained secret nonce for it.
529
+ state.signingSession?.clearSecrets();
530
+ state.phase = ParticipantCohortPhase.AwaitingFallbackSig;
531
+ }
532
+ /**
533
+ * User action: authorize the fallback spend. Recomputes the k-of-n fallback
534
+ * leaf from the member's OWN cohort state (not the service-provided script),
535
+ * computes the BIP-341 script-path sighash over the requested transaction, and
536
+ * returns a standalone BIP-340 signature (no nonce round). The member completes
537
+ * once it has contributed; the service needs only k of these.
538
+ */
539
+ approveFallback(cohortId) {
540
+ const state = this.#cohortStates.get(cohortId);
541
+ if (!state || state.phase !== ParticipantCohortPhase.AwaitingFallbackSig) {
542
+ throw new AggregationParticipantError(`Cannot approve fallback for cohort ${cohortId}: not in AwaitingFallbackSig phase.`, 'INVALID_PHASE', { cohortId, phase: state?.phase });
543
+ }
544
+ if (!state.fallbackRequest || !state.cohort) {
545
+ throw new AggregationParticipantError(`Cohort ${cohortId} missing fallback request or cohort state.`, 'MISSING_STATE', { cohortId });
546
+ }
547
+ const req = state.fallbackRequest;
548
+ const tx = Transaction.fromRaw(hexToBytes(req.pendingTxHex), { allowUnknownOutputs: true });
549
+ const prevOutScript = hexToBytes(req.prevOutScriptHex);
550
+ const prevOutValue = BigInt(req.prevOutValue);
551
+ // Refuse to sign unless the fallback tx anchors the signal this member
552
+ // validated (the coordinator drives output selection on the fallback path).
553
+ this.#assertTxAnchorsValidatedSignal(cohortId, state, tx);
554
+ // Recompute the fallback leaf from our own cohort keys so a malicious service
555
+ // cannot induce a signature over a different leaf than the one the funded
556
+ // address commits to.
557
+ const fallbackLeaf = buildFallbackLeaf({
558
+ cohortKeys: state.cohort.cohortKeys,
559
+ fallbackThreshold: state.cohort.effectiveFallbackThreshold,
560
+ });
561
+ const sighash = fallbackSighash(tx, 0, prevOutScript, prevOutValue, fallbackLeaf);
562
+ const signature = this.#signer.withSecret(secretKey => schnorr.sign(sighash, secretKey));
563
+ state.phase = ParticipantCohortPhase.Complete;
564
+ return [createFallbackSignatureMessage({
565
+ from: this.did,
566
+ to: state.serviceDid,
567
+ cohortId,
568
+ sessionId: req.sessionId,
569
+ signerPk: this.publicKey.slice(1),
570
+ fallbackSignature: signature,
571
+ })];
572
+ }
384
573
  getCohortPhase(cohortId) {
385
574
  return this.#cohortStates.get(cohortId)?.phase;
386
575
  }