@did-btcr2/method 0.26.0 → 0.27.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 (282) hide show
  1. package/README.md +86 -233
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/browser.js +24111 -20342
  4. package/dist/browser.mjs +24111 -20342
  5. package/dist/cjs/index.js +2463 -2174
  6. package/dist/esm/core/aggregation/cohort.js +178 -0
  7. package/dist/esm/core/aggregation/cohort.js.map +1 -0
  8. package/dist/esm/core/aggregation/errors.js +22 -0
  9. package/dist/esm/core/aggregation/errors.js.map +1 -0
  10. package/dist/esm/core/{beacon/aggregation/cohort → aggregation}/messages/base.js +0 -1
  11. package/dist/esm/core/aggregation/messages/base.js.map +1 -0
  12. package/dist/esm/core/aggregation/messages/constants.js +26 -0
  13. package/dist/esm/core/aggregation/messages/constants.js.map +1 -0
  14. package/dist/esm/core/aggregation/messages/factories.js +113 -0
  15. package/dist/esm/core/aggregation/messages/factories.js.map +1 -0
  16. package/dist/esm/core/aggregation/messages/guards.js +37 -0
  17. package/dist/esm/core/aggregation/messages/guards.js.map +1 -0
  18. package/dist/esm/core/aggregation/messages/index.js +5 -0
  19. package/dist/esm/core/aggregation/messages/index.js.map +1 -0
  20. package/dist/esm/core/aggregation/participant.js +376 -0
  21. package/dist/esm/core/aggregation/participant.js.map +1 -0
  22. package/dist/esm/core/aggregation/phases.js +39 -0
  23. package/dist/esm/core/aggregation/phases.js.map +1 -0
  24. package/dist/esm/core/aggregation/runner/events.js +2 -0
  25. package/dist/esm/core/aggregation/runner/events.js.map +1 -0
  26. package/dist/esm/core/aggregation/runner/index.js +5 -0
  27. package/dist/esm/core/aggregation/runner/index.js.map +1 -0
  28. package/dist/esm/core/aggregation/runner/participant-runner.js +282 -0
  29. package/dist/esm/core/aggregation/runner/participant-runner.js.map +1 -0
  30. package/dist/esm/core/aggregation/runner/service-runner.js +290 -0
  31. package/dist/esm/core/aggregation/runner/service-runner.js.map +1 -0
  32. package/dist/esm/core/aggregation/runner/typed-emitter.js +80 -0
  33. package/dist/esm/core/aggregation/runner/typed-emitter.js.map +1 -0
  34. package/dist/esm/core/aggregation/service.js +416 -0
  35. package/dist/esm/core/aggregation/service.js.map +1 -0
  36. package/dist/esm/core/aggregation/signing-session.js +133 -0
  37. package/dist/esm/core/aggregation/signing-session.js.map +1 -0
  38. package/dist/esm/core/aggregation/transport/didcomm.js +32 -0
  39. package/dist/esm/core/aggregation/transport/didcomm.js.map +1 -0
  40. package/dist/esm/core/aggregation/transport/error.js +12 -0
  41. package/dist/esm/core/aggregation/transport/error.js.map +1 -0
  42. package/dist/esm/core/aggregation/transport/factory.js +20 -0
  43. package/dist/esm/core/aggregation/transport/factory.js.map +1 -0
  44. package/dist/esm/core/aggregation/transport/index.js +6 -0
  45. package/dist/esm/core/aggregation/transport/index.js.map +1 -0
  46. package/dist/esm/core/aggregation/transport/nostr.js +262 -0
  47. package/dist/esm/core/aggregation/transport/nostr.js.map +1 -0
  48. package/dist/esm/core/aggregation/transport/transport.js +2 -0
  49. package/dist/esm/core/aggregation/transport/transport.js.map +1 -0
  50. package/dist/esm/core/beacon/beacon.js +80 -0
  51. package/dist/esm/core/beacon/beacon.js.map +1 -1
  52. package/dist/esm/core/beacon/cas-beacon.js +15 -56
  53. package/dist/esm/core/beacon/cas-beacon.js.map +1 -1
  54. package/dist/esm/core/beacon/error.js +0 -10
  55. package/dist/esm/core/beacon/error.js.map +1 -1
  56. package/dist/esm/core/beacon/fee-estimator.js +30 -0
  57. package/dist/esm/core/beacon/fee-estimator.js.map +1 -0
  58. package/dist/esm/core/beacon/singleton-beacon.js +10 -53
  59. package/dist/esm/core/beacon/singleton-beacon.js.map +1 -1
  60. package/dist/esm/core/beacon/smt-beacon.js +85 -9
  61. package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
  62. package/dist/esm/core/identifier.js +13 -0
  63. package/dist/esm/core/identifier.js.map +1 -1
  64. package/dist/esm/core/resolver.js +9 -0
  65. package/dist/esm/core/resolver.js.map +1 -1
  66. package/dist/esm/index.js +14 -24
  67. package/dist/esm/index.js.map +1 -1
  68. package/dist/types/core/aggregation/cohort.d.ts +94 -0
  69. package/dist/types/core/aggregation/cohort.d.ts.map +1 -0
  70. package/dist/types/core/aggregation/errors.d.ts +14 -0
  71. package/dist/types/core/aggregation/errors.d.ts.map +1 -0
  72. package/dist/types/core/{beacon/aggregation/cohort → aggregation}/messages/base.d.ts +7 -1
  73. package/dist/types/core/aggregation/messages/base.d.ts.map +1 -0
  74. package/dist/types/core/aggregation/messages/constants.d.ts +23 -0
  75. package/dist/types/core/aggregation/messages/constants.d.ts.map +1 -0
  76. package/dist/types/core/aggregation/messages/factories.d.ts +177 -0
  77. package/dist/types/core/aggregation/messages/factories.d.ts.map +1 -0
  78. package/dist/types/core/aggregation/messages/guards.d.ts +11 -0
  79. package/dist/types/core/aggregation/messages/guards.d.ts.map +1 -0
  80. package/dist/types/core/aggregation/messages/index.d.ts +5 -0
  81. package/dist/types/core/aggregation/messages/index.d.ts.map +1 -0
  82. package/dist/types/core/aggregation/participant.d.ts +101 -0
  83. package/dist/types/core/aggregation/participant.d.ts.map +1 -0
  84. package/dist/types/core/aggregation/phases.d.ts +49 -0
  85. package/dist/types/core/aggregation/phases.d.ts.map +1 -0
  86. package/dist/types/core/aggregation/runner/events.d.ts +89 -0
  87. package/dist/types/core/aggregation/runner/events.d.ts.map +1 -0
  88. package/dist/types/core/aggregation/runner/index.d.ts +5 -0
  89. package/dist/types/core/aggregation/runner/index.d.ts.map +1 -0
  90. package/dist/types/core/aggregation/runner/participant-runner.d.ts +107 -0
  91. package/dist/types/core/aggregation/runner/participant-runner.d.ts.map +1 -0
  92. package/dist/types/core/aggregation/runner/service-runner.d.ts +102 -0
  93. package/dist/types/core/aggregation/runner/service-runner.d.ts.map +1 -0
  94. package/dist/types/core/aggregation/runner/typed-emitter.d.ts +41 -0
  95. package/dist/types/core/aggregation/runner/typed-emitter.d.ts.map +1 -0
  96. package/dist/types/core/aggregation/service.d.ts +112 -0
  97. package/dist/types/core/aggregation/service.d.ts.map +1 -0
  98. package/dist/types/core/aggregation/signing-session.d.ts +69 -0
  99. package/dist/types/core/aggregation/signing-session.d.ts.map +1 -0
  100. package/dist/types/core/aggregation/transport/didcomm.d.ts +20 -0
  101. package/dist/types/core/aggregation/transport/didcomm.d.ts.map +1 -0
  102. package/dist/types/core/{beacon/aggregation/communication → aggregation/transport}/error.d.ts +2 -2
  103. package/dist/types/core/aggregation/transport/error.d.ts.map +1 -0
  104. package/dist/types/core/aggregation/transport/factory.d.ts +13 -0
  105. package/dist/types/core/aggregation/transport/factory.d.ts.map +1 -0
  106. package/dist/types/core/aggregation/transport/index.d.ts +6 -0
  107. package/dist/types/core/aggregation/transport/index.d.ts.map +1 -0
  108. package/dist/types/core/aggregation/transport/nostr.d.ts +55 -0
  109. package/dist/types/core/aggregation/transport/nostr.d.ts.map +1 -0
  110. package/dist/types/core/aggregation/transport/transport.d.ts +37 -0
  111. package/dist/types/core/aggregation/transport/transport.d.ts.map +1 -0
  112. package/dist/types/core/beacon/beacon.d.ts +37 -2
  113. package/dist/types/core/beacon/beacon.d.ts.map +1 -1
  114. package/dist/types/core/beacon/cas-beacon.d.ts +19 -7
  115. package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
  116. package/dist/types/core/beacon/error.d.ts +0 -6
  117. package/dist/types/core/beacon/error.d.ts.map +1 -1
  118. package/dist/types/core/beacon/fee-estimator.d.ts +40 -0
  119. package/dist/types/core/beacon/fee-estimator.d.ts.map +1 -0
  120. package/dist/types/core/beacon/interfaces.d.ts +8 -0
  121. package/dist/types/core/beacon/interfaces.d.ts.map +1 -1
  122. package/dist/types/core/beacon/singleton-beacon.d.ts +9 -2
  123. package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
  124. package/dist/types/core/beacon/smt-beacon.d.ts +27 -7
  125. package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
  126. package/dist/types/core/identifier.d.ts +8 -0
  127. package/dist/types/core/identifier.d.ts.map +1 -1
  128. package/dist/types/core/interfaces.d.ts +2 -2
  129. package/dist/types/core/resolver.d.ts +11 -1
  130. package/dist/types/core/resolver.d.ts.map +1 -1
  131. package/dist/types/index.d.ts +9 -24
  132. package/dist/types/index.d.ts.map +1 -1
  133. package/package.json +31 -30
  134. package/src/core/aggregation/cohort.ts +247 -0
  135. package/src/core/aggregation/errors.ts +25 -0
  136. package/src/core/{beacon/aggregation/cohort → aggregation}/messages/base.ts +8 -3
  137. package/src/core/aggregation/messages/constants.ts +28 -0
  138. package/src/core/aggregation/messages/factories.ts +240 -0
  139. package/src/core/aggregation/messages/guards.ts +55 -0
  140. package/src/core/aggregation/messages/index.ts +4 -0
  141. package/src/core/aggregation/participant.ts +510 -0
  142. package/src/core/aggregation/phases.ts +82 -0
  143. package/src/core/aggregation/runner/events.ts +77 -0
  144. package/src/core/aggregation/runner/index.ts +4 -0
  145. package/src/core/aggregation/runner/participant-runner.ts +360 -0
  146. package/src/core/aggregation/runner/service-runner.ts +365 -0
  147. package/src/core/aggregation/runner/typed-emitter.ts +87 -0
  148. package/src/core/aggregation/service.ts +547 -0
  149. package/src/core/aggregation/signing-session.ts +209 -0
  150. package/src/core/aggregation/transport/didcomm.ts +42 -0
  151. package/src/core/aggregation/transport/error.ts +13 -0
  152. package/src/core/aggregation/transport/factory.ts +29 -0
  153. package/src/core/aggregation/transport/index.ts +5 -0
  154. package/src/core/aggregation/transport/nostr.ts +333 -0
  155. package/src/core/aggregation/transport/transport.ts +46 -0
  156. package/src/core/beacon/beacon.ts +122 -2
  157. package/src/core/beacon/cas-beacon.ts +28 -76
  158. package/src/core/beacon/error.ts +0 -12
  159. package/src/core/beacon/fee-estimator.ts +52 -0
  160. package/src/core/beacon/interfaces.ts +10 -1
  161. package/src/core/beacon/singleton-beacon.ts +14 -75
  162. package/src/core/beacon/smt-beacon.ts +109 -11
  163. package/src/core/identifier.ts +17 -0
  164. package/src/core/interfaces.ts +2 -2
  165. package/src/core/resolver.ts +25 -2
  166. package/src/index.ts +15 -29
  167. package/dist/esm/core/beacon/aggregation/cohort/index.js +0 -237
  168. package/dist/esm/core/beacon/aggregation/cohort/index.js.map +0 -1
  169. package/dist/esm/core/beacon/aggregation/cohort/messages/base.js.map +0 -1
  170. package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js +0 -11
  171. package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js.map +0 -1
  172. package/dist/esm/core/beacon/aggregation/cohort/messages/index.js +0 -98
  173. package/dist/esm/core/beacon/aggregation/cohort/messages/index.js.map +0 -1
  174. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +0 -31
  175. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +0 -1
  176. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +0 -29
  177. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +0 -1
  178. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +0 -27
  179. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +0 -1
  180. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +0 -23
  181. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +0 -1
  182. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +0 -28
  183. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +0 -1
  184. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +0 -29
  185. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +0 -1
  186. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +0 -30
  187. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +0 -1
  188. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +0 -30
  189. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +0 -1
  190. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js +0 -30
  191. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +0 -1
  192. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +0 -31
  193. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +0 -1
  194. package/dist/esm/core/beacon/aggregation/cohort/status.js +0 -8
  195. package/dist/esm/core/beacon/aggregation/cohort/status.js.map +0 -1
  196. package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js +0 -121
  197. package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js.map +0 -1
  198. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js +0 -245
  199. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js.map +0 -1
  200. package/dist/esm/core/beacon/aggregation/communication/error.js +0 -12
  201. package/dist/esm/core/beacon/aggregation/communication/error.js.map +0 -1
  202. package/dist/esm/core/beacon/aggregation/communication/factory.js +0 -21
  203. package/dist/esm/core/beacon/aggregation/communication/factory.js.map +0 -1
  204. package/dist/esm/core/beacon/aggregation/communication/service.js +0 -2
  205. package/dist/esm/core/beacon/aggregation/communication/service.js.map +0 -1
  206. package/dist/esm/core/beacon/aggregation/coordinator.js +0 -343
  207. package/dist/esm/core/beacon/aggregation/coordinator.js.map +0 -1
  208. package/dist/esm/core/beacon/aggregation/participant.js +0 -435
  209. package/dist/esm/core/beacon/aggregation/participant.js.map +0 -1
  210. package/dist/esm/core/beacon/aggregation/session/index.js +0 -244
  211. package/dist/esm/core/beacon/aggregation/session/index.js.map +0 -1
  212. package/dist/esm/core/beacon/aggregation/session/status.js +0 -11
  213. package/dist/esm/core/beacon/aggregation/session/status.js.map +0 -1
  214. package/dist/types/core/beacon/aggregation/cohort/index.d.ts +0 -136
  215. package/dist/types/core/beacon/aggregation/cohort/index.d.ts.map +0 -1
  216. package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts.map +0 -1
  217. package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts +0 -11
  218. package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts.map +0 -1
  219. package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts +0 -65
  220. package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts.map +0 -1
  221. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts +0 -29
  222. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts.map +0 -1
  223. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts +0 -26
  224. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts.map +0 -1
  225. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts +0 -24
  226. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts.map +0 -1
  227. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts +0 -20
  228. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts.map +0 -1
  229. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts +0 -25
  230. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts.map +0 -1
  231. package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts +0 -25
  232. package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts.map +0 -1
  233. package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts +0 -26
  234. package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts.map +0 -1
  235. package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts +0 -26
  236. package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts.map +0 -1
  237. package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts +0 -26
  238. package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts.map +0 -1
  239. package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts +0 -27
  240. package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts.map +0 -1
  241. package/dist/types/core/beacon/aggregation/cohort/status.d.ts +0 -8
  242. package/dist/types/core/beacon/aggregation/cohort/status.d.ts.map +0 -1
  243. package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts +0 -89
  244. package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts.map +0 -1
  245. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts +0 -103
  246. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts.map +0 -1
  247. package/dist/types/core/beacon/aggregation/communication/error.d.ts.map +0 -1
  248. package/dist/types/core/beacon/aggregation/communication/factory.d.ts +0 -10
  249. package/dist/types/core/beacon/aggregation/communication/factory.d.ts.map +0 -1
  250. package/dist/types/core/beacon/aggregation/communication/service.d.ts +0 -36
  251. package/dist/types/core/beacon/aggregation/communication/service.d.ts.map +0 -1
  252. package/dist/types/core/beacon/aggregation/coordinator.d.ts +0 -116
  253. package/dist/types/core/beacon/aggregation/coordinator.d.ts.map +0 -1
  254. package/dist/types/core/beacon/aggregation/participant.d.ts +0 -192
  255. package/dist/types/core/beacon/aggregation/participant.d.ts.map +0 -1
  256. package/dist/types/core/beacon/aggregation/session/index.d.ts +0 -156
  257. package/dist/types/core/beacon/aggregation/session/index.d.ts.map +0 -1
  258. package/dist/types/core/beacon/aggregation/session/status.d.ts +0 -11
  259. package/dist/types/core/beacon/aggregation/session/status.d.ts.map +0 -1
  260. package/src/core/beacon/aggregation/cohort/index.ts +0 -305
  261. package/src/core/beacon/aggregation/cohort/messages/constants.ts +0 -12
  262. package/src/core/beacon/aggregation/cohort/messages/index.ts +0 -143
  263. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.ts +0 -44
  264. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +0 -40
  265. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.ts +0 -35
  266. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in.ts +0 -34
  267. package/src/core/beacon/aggregation/cohort/messages/keygen/subscribe.ts +0 -36
  268. package/src/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.ts +0 -39
  269. package/src/core/beacon/aggregation/cohort/messages/sign/authorization-request.ts +0 -40
  270. package/src/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.ts +0 -40
  271. package/src/core/beacon/aggregation/cohort/messages/sign/request-signature.ts +0 -40
  272. package/src/core/beacon/aggregation/cohort/messages/sign/signature-authorization.ts +0 -41
  273. package/src/core/beacon/aggregation/cohort/status.ts +0 -7
  274. package/src/core/beacon/aggregation/communication/adapter/did-comm.ts +0 -148
  275. package/src/core/beacon/aggregation/communication/adapter/nostr.ts +0 -323
  276. package/src/core/beacon/aggregation/communication/error.ts +0 -13
  277. package/src/core/beacon/aggregation/communication/factory.ts +0 -25
  278. package/src/core/beacon/aggregation/communication/service.ts +0 -42
  279. package/src/core/beacon/aggregation/coordinator.ts +0 -419
  280. package/src/core/beacon/aggregation/participant.ts +0 -517
  281. package/src/core/beacon/aggregation/session/index.ts +0 -301
  282. package/src/core/beacon/aggregation/session/status.ts +0 -18
@@ -0,0 +1,360 @@
1
+ import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
2
+ import type { SchnorrKeyPair } from '@did-btcr2/keypair';
3
+ import type { BaseMessage } from '../messages/base.js';
4
+ import {
5
+ AGGREGATED_NONCE,
6
+ AUTHORIZATION_REQUEST,
7
+ COHORT_ADVERT,
8
+ COHORT_OPT_IN_ACCEPT,
9
+ COHORT_READY,
10
+ DISTRIBUTE_AGGREGATED_DATA,
11
+ } from '../messages/constants.js';
12
+ import type {
13
+ CohortAdvert,
14
+ PendingSigningRequest,
15
+ PendingValidation} from '../participant.js';
16
+ import {
17
+ AggregationParticipant
18
+ } from '../participant.js';
19
+ import { ParticipantCohortPhase } from '../phases.js';
20
+ import type { Transport } from '../transport/transport.js';
21
+ import type { AggregationParticipantEvents } from './events.js';
22
+ import { TypedEventEmitter } from './typed-emitter.js';
23
+
24
+ /** Decision callback: filter discovered cohorts. Default rejects all. */
25
+ export type ShouldJoin = (advert: CohortAdvert) => Promise<boolean>;
26
+
27
+ /** Data callback: provide a signed BTCR2 update for a joined cohort. */
28
+ export type OnProvideUpdate = (info: {
29
+ cohortId: string;
30
+ beaconAddress: string;
31
+ }) => Promise<SignedBTCR2Update>;
32
+
33
+ /** Decision callback: approve or reject aggregated data. */
34
+ export type OnValidateData = (info: PendingValidation) => Promise<{ approved: boolean }>;
35
+
36
+ /** Decision callback: approve or reject signing. */
37
+ export type OnApproveSigning = (info: PendingSigningRequest) => Promise<{ approved: boolean }>;
38
+
39
+ export interface AggregationParticipantRunnerOptions {
40
+ /** Underlying transport. */
41
+ transport: Transport;
42
+
43
+ /** Participant identity. */
44
+ did: string;
45
+ keys: SchnorrKeyPair;
46
+
47
+ /**
48
+ * Filter discovered cohorts. Returns true to join, false to skip.
49
+ * Default: rejects all cohorts (caller MUST override or no cohorts will be joined).
50
+ */
51
+ shouldJoin?: ShouldJoin;
52
+
53
+ /**
54
+ * Provide a signed BTCR2 update for the cohort.
55
+ * REQUIRED — no sensible default.
56
+ */
57
+ onProvideUpdate: OnProvideUpdate;
58
+
59
+ /**
60
+ * Approve or reject aggregated data.
61
+ * Default: approve if validation matches the submitted update's hash.
62
+ */
63
+ onValidateData?: OnValidateData;
64
+
65
+ /**
66
+ * Approve or reject the signing request.
67
+ * Default: approve.
68
+ */
69
+ onApproveSigning?: OnApproveSigning;
70
+ }
71
+
72
+ /**
73
+ * High-level facade for an Aggregation Participant.
74
+ *
75
+ * Long-running listener: waits for cohort adverts, applies the `shouldJoin`
76
+ * filter, and drives each accepted cohort through the full protocol to
77
+ * completion in parallel.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const transport = new NostrTransport({ relays: [RELAY] });
82
+ * transport.registerActor(myDid, myKeys);
83
+ *
84
+ * const runner = new AggregationParticipantRunner({
85
+ * transport,
86
+ * did: myDid,
87
+ * keys: myKeys,
88
+ * shouldJoin: async (advert) => advert.beaconType === 'CASBeacon',
89
+ * onProvideUpdate: async ({ beaconAddress }) => {
90
+ * return Update.sign(myDid, unsigned, vm, secretKey);
91
+ * },
92
+ * });
93
+ *
94
+ * runner.on('cohort-complete', ({ beaconAddress }) => {
95
+ * console.log(`Add to DID document: bitcoin:${beaconAddress}`);
96
+ * });
97
+ *
98
+ * await runner.start();
99
+ * ```
100
+ *
101
+ * For full manual control, drop down to the underlying state machine via
102
+ * `runner.session`. The state machine has no transport coupling and exposes
103
+ * every protocol decision as an explicit method.
104
+ *
105
+ * @class AggregationParticipantRunner
106
+ * @extends TypedEventEmitter<AggregationParticipantEvents>
107
+ */
108
+ export class AggregationParticipantRunner extends TypedEventEmitter<AggregationParticipantEvents> {
109
+ /** Direct access to the underlying state machine for advanced use. */
110
+ readonly session: AggregationParticipant;
111
+
112
+ readonly #transport: Transport;
113
+ readonly #did: string;
114
+ readonly #shouldJoin: ShouldJoin;
115
+ readonly #onProvideUpdate: OnProvideUpdate;
116
+ readonly #onValidateData: OnValidateData;
117
+ readonly #onApproveSigning: OnApproveSigning;
118
+
119
+ #handlersRegistered = false;
120
+ #stopped = false;
121
+
122
+ constructor(options: AggregationParticipantRunnerOptions) {
123
+ super();
124
+ this.#transport = options.transport;
125
+ this.#did = options.did;
126
+ this.#shouldJoin = options.shouldJoin ?? (async () => false);
127
+ this.#onProvideUpdate = options.onProvideUpdate;
128
+ this.#onValidateData = options.onValidateData ?? (async (info) => ({ approved: info.matches }));
129
+ this.#onApproveSigning = options.onApproveSigning ?? (async () => ({ approved: true }));
130
+
131
+ this.session = new AggregationParticipant({ did: options.did, keys: options.keys });
132
+ }
133
+
134
+ /**
135
+ * Start listening for cohorts. The runner stays active until {@link stop}
136
+ * is called or the underlying transport disconnects.
137
+ */
138
+ async start(): Promise<void> {
139
+ this.#registerHandlers();
140
+ }
141
+
142
+ /** Stop the runner. Does not unregister transport handlers. */
143
+ stop(): void {
144
+ this.#stopped = true;
145
+ }
146
+
147
+ /**
148
+ * Single-shot helper: start, join the first cohort that passes `shouldJoin`,
149
+ * drive it to completion, and resolve. Convenient for tests and demos.
150
+ */
151
+ static async joinFirst(
152
+ options: AggregationParticipantRunnerOptions
153
+ ): Promise<{ cohortId: string; beaconAddress: string }> {
154
+ return new Promise((resolve, reject) => {
155
+ const runner = new AggregationParticipantRunner(options);
156
+ runner.once('cohort-complete', (info) => {
157
+ runner.stop();
158
+ resolve(info);
159
+ });
160
+ runner.on('error', reject);
161
+ runner.start().catch(reject);
162
+ });
163
+ }
164
+
165
+ /**
166
+ * Internal: handler registration with the transport. Idempotent and safe to call multiple times,
167
+ * but only registers handlers once.
168
+ */
169
+ #registerHandlers(): void {
170
+ if (this.#handlersRegistered) return;
171
+ this.#handlersRegistered = true;
172
+
173
+ this.#transport.registerMessageHandler(this.#did, COHORT_ADVERT, this.#handleAdvert.bind(this));
174
+ this.#transport.registerMessageHandler(this.#did, COHORT_OPT_IN_ACCEPT, this.#handleOptInAccept.bind(this));
175
+ this.#transport.registerMessageHandler(this.#did, COHORT_READY, this.#handleCohortReady.bind(this));
176
+ this.#transport.registerMessageHandler(this.#did, DISTRIBUTE_AGGREGATED_DATA, this.#handleDistributeData.bind(this));
177
+ this.#transport.registerMessageHandler(this.#did, AUTHORIZATION_REQUEST, this.#handleAuthorizationRequest.bind(this));
178
+ this.#transport.registerMessageHandler(this.#did, AGGREGATED_NONCE, this.#handleAggregatedNonce.bind(this));
179
+ }
180
+
181
+ /**
182
+ * Internal: handler for cohort adverts. Applies the `shouldJoin` filter and joins if approved.
183
+ * @param {BaseMessage} msg - The received cohort advert message.
184
+ * @returns {Promise<void>} Resolves when processing is complete.
185
+ */
186
+ async #handleAdvert(msg: BaseMessage): Promise<void> {
187
+ if (this.#stopped) return;
188
+ try {
189
+ this.session.receive(msg);
190
+
191
+ const advert = this.session.discoveredCohorts.get(msg.body?.cohortId ?? '');
192
+ if (!advert) return;
193
+ this.emit('cohort-discovered', advert);
194
+
195
+ // Register the service's communication key for encrypted message routing
196
+ if (advert.serviceCommunicationPk) {
197
+ this.#transport.registerPeer(advert.serviceDid, advert.serviceCommunicationPk);
198
+ }
199
+
200
+ const join = await this.#shouldJoin(advert);
201
+ if (!join) return;
202
+
203
+ await this.#sendAll(this.session.joinCohort(advert.cohortId));
204
+ this.emit('cohort-joined', { cohortId: advert.cohortId });
205
+ } catch (err) {
206
+ this.emit('error', err as Error);
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Internal: handler for opt-in accept messages. Updates the session state accordingly.
212
+ * @param {BaseMessage} msg - The received opt-in accept message.
213
+ */
214
+ #handleOptInAccept(msg: BaseMessage): void {
215
+ if (this.#stopped) return;
216
+ try {
217
+ this.session.receive(msg);
218
+ } catch (err) {
219
+ this.emit('error', err as Error);
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Internal: handler for cohort ready messages. Updates the session state, emits a 'cohort-ready'
225
+ * event, and triggers the update submission flow via the `onProvideUpdate` callback.
226
+ * @param {BaseMessage} msg - The received cohort ready message.
227
+ * @returns {Promise<void>} Resolves when processing is complete.
228
+ */
229
+ async #handleCohortReady(msg: BaseMessage): Promise<void> {
230
+ if (this.#stopped) return;
231
+ try {
232
+ this.session.receive(msg);
233
+
234
+ const cohortId = msg.body?.cohortId;
235
+ if (!cohortId) return;
236
+
237
+ const info = this.session.joinedCohorts.get(cohortId);
238
+ if (!info) return;
239
+ this.emit('cohort-ready', { cohortId, beaconAddress: info.beaconAddress });
240
+
241
+ // Construct the signed update via caller callback and submit
242
+ const signedUpdate = await this.#onProvideUpdate({
243
+ cohortId,
244
+ beaconAddress : info.beaconAddress,
245
+ });
246
+ await this.#sendAll(this.session.submitUpdate(cohortId, signedUpdate));
247
+ this.emit('update-submitted', { cohortId });
248
+ } catch (err) {
249
+ this.emit('error', err as Error);
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Internal: handler for distribute aggregated data messages. Updates the session state, emits a
255
+ * 'validation-requested' event, and triggers the validation decision flow via the `onValidateData`
256
+ * callback. Depending on the decision, sends an approval or rejection message.
257
+ * @param {BaseMessage} msg - The received distribute aggregated data message.
258
+ * @returns {Promise<void>} Resolves when processing is complete.
259
+ * @throws {Error} If an error occurs during message processing or callback execution.
260
+ */
261
+ async #handleDistributeData(msg: BaseMessage): Promise<void> {
262
+ if (this.#stopped) return;
263
+ try {
264
+ this.session.receive(msg);
265
+
266
+ const cohortId = msg.body?.cohortId;
267
+ if (!cohortId) return;
268
+
269
+ const validation = this.session.pendingValidations.get(cohortId);
270
+ if (!validation) return;
271
+ this.emit('validation-requested', validation);
272
+
273
+ const decision = await this.#onValidateData(validation);
274
+ if (decision.approved) {
275
+ await this.#sendAll(this.session.approveValidation(cohortId));
276
+ } else {
277
+ await this.#sendAll(this.session.rejectValidation(cohortId));
278
+ this.emit('cohort-failed', { cohortId, reason: 'Validation rejected by participant' });
279
+ }
280
+ } catch (err) {
281
+ this.emit('error', err as Error);
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Internal: handler for authorization request messages. Updates the session state, emits a
287
+ * 'signing-requested' event, and triggers the signing approval flow via the `onApproveSigning`
288
+ * callback. Depending on the decision, sends a nonce approval message or emits a 'cohort-failed'
289
+ * event.
290
+ * @param {BaseMessage} msg - The received authorization request message.
291
+ * @returns {Promise<void>} Resolves when processing is complete.
292
+ * @throws {Error} If an error occurs during message processing or callback execution.
293
+ */
294
+ async #handleAuthorizationRequest(msg: BaseMessage): Promise<void> {
295
+ if (this.#stopped) return;
296
+ try {
297
+ this.session.receive(msg);
298
+
299
+ const cohortId = msg.body?.cohortId;
300
+ if (!cohortId) return;
301
+
302
+ const req = this.session.pendingSigningRequests.get(cohortId);
303
+ if (!req) return;
304
+ this.emit('signing-requested', req);
305
+
306
+ const decision = await this.#onApproveSigning(req);
307
+ if (!decision.approved) {
308
+ this.emit('cohort-failed', { cohortId, reason: 'Signing rejected by participant' });
309
+ return;
310
+ }
311
+
312
+ await this.#sendAll(this.session.approveNonce(cohortId));
313
+ } catch (err) {
314
+ this.emit('error', err as Error);
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Internal: handler for aggregated nonce messages. Updates the session state, triggers partial
320
+ * signature generation, and sends the partial signature to the aggregator. If the cohort reaches
321
+ * completion after processing the nonce, emits a 'cohort-complete' event.
322
+ * @param {BaseMessage} msg - The received aggregated nonce message.
323
+ * @returns {Promise<void>} Resolves when processing is complete.
324
+ * @throws {Error} If an error occurs during message processing or partial signature generation.
325
+ */
326
+ async #handleAggregatedNonce(msg: BaseMessage): Promise<void> {
327
+ if (this.#stopped) return;
328
+ try {
329
+ this.session.receive(msg);
330
+
331
+ const cohortId = msg.body?.cohortId;
332
+ if (!cohortId) return;
333
+
334
+ await this.#sendAll(this.session.generatePartialSignature(cohortId));
335
+
336
+ // Check if we've reached completion
337
+ if (this.session.getCohortPhase(cohortId) === ParticipantCohortPhase.Complete) {
338
+ const info = this.session.joinedCohorts.get(cohortId);
339
+ if (info) {
340
+ this.emit('cohort-complete', { cohortId, beaconAddress: info.beaconAddress });
341
+ }
342
+ }
343
+ } catch (err) {
344
+ this.emit('error', err as Error);
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Internal: send helper to ensure messages are sent sequentially. This is important for protocol
350
+ * correctness, as some transports may not guarantee message order if sent in parallel.
351
+ * @param {BaseMessage[]} msgs - The messages to send.
352
+ * @returns {Promise<void>} Resolves when all messages have been sent.
353
+ * @throws {Error} If an error occurs during message sending.
354
+ */
355
+ async #sendAll(msgs: BaseMessage[]): Promise<void> {
356
+ for (const m of msgs) {
357
+ await this.#transport.sendMessage(m, this.#did, m.to);
358
+ }
359
+ }
360
+ }