@did-btcr2/method 0.26.0 → 0.28.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 (297) hide show
  1. package/README.md +118 -236
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/browser.js +27665 -23764
  4. package/dist/browser.mjs +27665 -23764
  5. package/dist/cjs/index.js +2661 -2239
  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 +286 -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/core/updater.js +269 -0
  67. package/dist/esm/core/updater.js.map +1 -0
  68. package/dist/esm/did-btcr2.js +30 -42
  69. package/dist/esm/did-btcr2.js.map +1 -1
  70. package/dist/esm/index.js +16 -25
  71. package/dist/esm/index.js.map +1 -1
  72. package/dist/types/core/aggregation/cohort.d.ts +94 -0
  73. package/dist/types/core/aggregation/cohort.d.ts.map +1 -0
  74. package/dist/types/core/aggregation/errors.d.ts +14 -0
  75. package/dist/types/core/aggregation/errors.d.ts.map +1 -0
  76. package/dist/types/core/{beacon/aggregation/cohort → aggregation}/messages/base.d.ts +7 -1
  77. package/dist/types/core/aggregation/messages/base.d.ts.map +1 -0
  78. package/dist/types/core/aggregation/messages/constants.d.ts +23 -0
  79. package/dist/types/core/aggregation/messages/constants.d.ts.map +1 -0
  80. package/dist/types/core/aggregation/messages/factories.d.ts +177 -0
  81. package/dist/types/core/aggregation/messages/factories.d.ts.map +1 -0
  82. package/dist/types/core/aggregation/messages/guards.d.ts +11 -0
  83. package/dist/types/core/aggregation/messages/guards.d.ts.map +1 -0
  84. package/dist/types/core/aggregation/messages/index.d.ts +5 -0
  85. package/dist/types/core/aggregation/messages/index.d.ts.map +1 -0
  86. package/dist/types/core/aggregation/participant.d.ts +101 -0
  87. package/dist/types/core/aggregation/participant.d.ts.map +1 -0
  88. package/dist/types/core/aggregation/phases.d.ts +49 -0
  89. package/dist/types/core/aggregation/phases.d.ts.map +1 -0
  90. package/dist/types/core/aggregation/runner/events.d.ts +89 -0
  91. package/dist/types/core/aggregation/runner/events.d.ts.map +1 -0
  92. package/dist/types/core/aggregation/runner/index.d.ts +5 -0
  93. package/dist/types/core/aggregation/runner/index.d.ts.map +1 -0
  94. package/dist/types/core/aggregation/runner/participant-runner.d.ts +111 -0
  95. package/dist/types/core/aggregation/runner/participant-runner.d.ts.map +1 -0
  96. package/dist/types/core/aggregation/runner/service-runner.d.ts +102 -0
  97. package/dist/types/core/aggregation/runner/service-runner.d.ts.map +1 -0
  98. package/dist/types/core/aggregation/runner/typed-emitter.d.ts +41 -0
  99. package/dist/types/core/aggregation/runner/typed-emitter.d.ts.map +1 -0
  100. package/dist/types/core/aggregation/service.d.ts +112 -0
  101. package/dist/types/core/aggregation/service.d.ts.map +1 -0
  102. package/dist/types/core/aggregation/signing-session.d.ts +69 -0
  103. package/dist/types/core/aggregation/signing-session.d.ts.map +1 -0
  104. package/dist/types/core/aggregation/transport/didcomm.d.ts +20 -0
  105. package/dist/types/core/aggregation/transport/didcomm.d.ts.map +1 -0
  106. package/dist/types/core/{beacon/aggregation/communication → aggregation/transport}/error.d.ts +2 -2
  107. package/dist/types/core/aggregation/transport/error.d.ts.map +1 -0
  108. package/dist/types/core/aggregation/transport/factory.d.ts +13 -0
  109. package/dist/types/core/aggregation/transport/factory.d.ts.map +1 -0
  110. package/dist/types/core/aggregation/transport/index.d.ts +6 -0
  111. package/dist/types/core/aggregation/transport/index.d.ts.map +1 -0
  112. package/dist/types/core/aggregation/transport/nostr.d.ts +55 -0
  113. package/dist/types/core/aggregation/transport/nostr.d.ts.map +1 -0
  114. package/dist/types/core/aggregation/transport/transport.d.ts +37 -0
  115. package/dist/types/core/aggregation/transport/transport.d.ts.map +1 -0
  116. package/dist/types/core/beacon/beacon.d.ts +37 -2
  117. package/dist/types/core/beacon/beacon.d.ts.map +1 -1
  118. package/dist/types/core/beacon/cas-beacon.d.ts +19 -7
  119. package/dist/types/core/beacon/cas-beacon.d.ts.map +1 -1
  120. package/dist/types/core/beacon/error.d.ts +0 -6
  121. package/dist/types/core/beacon/error.d.ts.map +1 -1
  122. package/dist/types/core/beacon/fee-estimator.d.ts +40 -0
  123. package/dist/types/core/beacon/fee-estimator.d.ts.map +1 -0
  124. package/dist/types/core/beacon/interfaces.d.ts +8 -0
  125. package/dist/types/core/beacon/interfaces.d.ts.map +1 -1
  126. package/dist/types/core/beacon/singleton-beacon.d.ts +9 -2
  127. package/dist/types/core/beacon/singleton-beacon.d.ts.map +1 -1
  128. package/dist/types/core/beacon/smt-beacon.d.ts +27 -7
  129. package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
  130. package/dist/types/core/identifier.d.ts +8 -0
  131. package/dist/types/core/identifier.d.ts.map +1 -1
  132. package/dist/types/core/interfaces.d.ts +2 -2
  133. package/dist/types/core/resolver.d.ts +11 -1
  134. package/dist/types/core/resolver.d.ts.map +1 -1
  135. package/dist/types/core/updater.d.ts +178 -0
  136. package/dist/types/core/updater.d.ts.map +1 -0
  137. package/dist/types/did-btcr2.d.ts +23 -23
  138. package/dist/types/did-btcr2.d.ts.map +1 -1
  139. package/dist/types/index.d.ts +11 -25
  140. package/dist/types/index.d.ts.map +1 -1
  141. package/package.json +31 -30
  142. package/src/core/aggregation/cohort.ts +247 -0
  143. package/src/core/aggregation/errors.ts +25 -0
  144. package/src/core/{beacon/aggregation/cohort → aggregation}/messages/base.ts +8 -3
  145. package/src/core/aggregation/messages/constants.ts +28 -0
  146. package/src/core/aggregation/messages/factories.ts +240 -0
  147. package/src/core/aggregation/messages/guards.ts +55 -0
  148. package/src/core/aggregation/messages/index.ts +4 -0
  149. package/src/core/aggregation/participant.ts +510 -0
  150. package/src/core/aggregation/phases.ts +82 -0
  151. package/src/core/aggregation/runner/events.ts +77 -0
  152. package/src/core/aggregation/runner/index.ts +4 -0
  153. package/src/core/aggregation/runner/participant-runner.ts +364 -0
  154. package/src/core/aggregation/runner/service-runner.ts +365 -0
  155. package/src/core/aggregation/runner/typed-emitter.ts +87 -0
  156. package/src/core/aggregation/service.ts +547 -0
  157. package/src/core/aggregation/signing-session.ts +209 -0
  158. package/src/core/aggregation/transport/didcomm.ts +42 -0
  159. package/src/core/aggregation/transport/error.ts +13 -0
  160. package/src/core/aggregation/transport/factory.ts +29 -0
  161. package/src/core/aggregation/transport/index.ts +5 -0
  162. package/src/core/aggregation/transport/nostr.ts +333 -0
  163. package/src/core/aggregation/transport/transport.ts +46 -0
  164. package/src/core/beacon/beacon.ts +122 -2
  165. package/src/core/beacon/cas-beacon.ts +28 -76
  166. package/src/core/beacon/error.ts +0 -12
  167. package/src/core/beacon/fee-estimator.ts +52 -0
  168. package/src/core/beacon/interfaces.ts +10 -1
  169. package/src/core/beacon/singleton-beacon.ts +14 -75
  170. package/src/core/beacon/smt-beacon.ts +109 -11
  171. package/src/core/identifier.ts +17 -0
  172. package/src/core/interfaces.ts +2 -2
  173. package/src/core/resolver.ts +25 -2
  174. package/src/core/updater.ts +415 -0
  175. package/src/did-btcr2.ts +36 -66
  176. package/src/index.ts +17 -30
  177. package/dist/esm/core/beacon/aggregation/cohort/index.js +0 -237
  178. package/dist/esm/core/beacon/aggregation/cohort/index.js.map +0 -1
  179. package/dist/esm/core/beacon/aggregation/cohort/messages/base.js.map +0 -1
  180. package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js +0 -11
  181. package/dist/esm/core/beacon/aggregation/cohort/messages/constants.js.map +0 -1
  182. package/dist/esm/core/beacon/aggregation/cohort/messages/index.js +0 -98
  183. package/dist/esm/core/beacon/aggregation/cohort/messages/index.js.map +0 -1
  184. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js +0 -31
  185. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.js.map +0 -1
  186. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js +0 -29
  187. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.js.map +0 -1
  188. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js +0 -27
  189. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.js.map +0 -1
  190. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js +0 -23
  191. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/opt-in.js.map +0 -1
  192. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js +0 -28
  193. package/dist/esm/core/beacon/aggregation/cohort/messages/keygen/subscribe.js.map +0 -1
  194. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js +0 -29
  195. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.js.map +0 -1
  196. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js +0 -30
  197. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/authorization-request.js.map +0 -1
  198. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js +0 -30
  199. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.js.map +0 -1
  200. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js +0 -30
  201. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/request-signature.js.map +0 -1
  202. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js +0 -31
  203. package/dist/esm/core/beacon/aggregation/cohort/messages/sign/signature-authorization.js.map +0 -1
  204. package/dist/esm/core/beacon/aggregation/cohort/status.js +0 -8
  205. package/dist/esm/core/beacon/aggregation/cohort/status.js.map +0 -1
  206. package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js +0 -121
  207. package/dist/esm/core/beacon/aggregation/communication/adapter/did-comm.js.map +0 -1
  208. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js +0 -245
  209. package/dist/esm/core/beacon/aggregation/communication/adapter/nostr.js.map +0 -1
  210. package/dist/esm/core/beacon/aggregation/communication/error.js +0 -12
  211. package/dist/esm/core/beacon/aggregation/communication/error.js.map +0 -1
  212. package/dist/esm/core/beacon/aggregation/communication/factory.js +0 -21
  213. package/dist/esm/core/beacon/aggregation/communication/factory.js.map +0 -1
  214. package/dist/esm/core/beacon/aggregation/communication/service.js +0 -2
  215. package/dist/esm/core/beacon/aggregation/communication/service.js.map +0 -1
  216. package/dist/esm/core/beacon/aggregation/coordinator.js +0 -343
  217. package/dist/esm/core/beacon/aggregation/coordinator.js.map +0 -1
  218. package/dist/esm/core/beacon/aggregation/participant.js +0 -435
  219. package/dist/esm/core/beacon/aggregation/participant.js.map +0 -1
  220. package/dist/esm/core/beacon/aggregation/session/index.js +0 -244
  221. package/dist/esm/core/beacon/aggregation/session/index.js.map +0 -1
  222. package/dist/esm/core/beacon/aggregation/session/status.js +0 -11
  223. package/dist/esm/core/beacon/aggregation/session/status.js.map +0 -1
  224. package/dist/esm/core/update.js +0 -112
  225. package/dist/esm/core/update.js.map +0 -1
  226. package/dist/types/core/beacon/aggregation/cohort/index.d.ts +0 -136
  227. package/dist/types/core/beacon/aggregation/cohort/index.d.ts.map +0 -1
  228. package/dist/types/core/beacon/aggregation/cohort/messages/base.d.ts.map +0 -1
  229. package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts +0 -11
  230. package/dist/types/core/beacon/aggregation/cohort/messages/constants.d.ts.map +0 -1
  231. package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts +0 -65
  232. package/dist/types/core/beacon/aggregation/cohort/messages/index.d.ts.map +0 -1
  233. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts +0 -29
  234. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.d.ts.map +0 -1
  235. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts +0 -26
  236. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.d.ts.map +0 -1
  237. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts +0 -24
  238. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.d.ts.map +0 -1
  239. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts +0 -20
  240. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/opt-in.d.ts.map +0 -1
  241. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts +0 -25
  242. package/dist/types/core/beacon/aggregation/cohort/messages/keygen/subscribe.d.ts.map +0 -1
  243. package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts +0 -25
  244. package/dist/types/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.d.ts.map +0 -1
  245. package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts +0 -26
  246. package/dist/types/core/beacon/aggregation/cohort/messages/sign/authorization-request.d.ts.map +0 -1
  247. package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts +0 -26
  248. package/dist/types/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.d.ts.map +0 -1
  249. package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts +0 -26
  250. package/dist/types/core/beacon/aggregation/cohort/messages/sign/request-signature.d.ts.map +0 -1
  251. package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts +0 -27
  252. package/dist/types/core/beacon/aggregation/cohort/messages/sign/signature-authorization.d.ts.map +0 -1
  253. package/dist/types/core/beacon/aggregation/cohort/status.d.ts +0 -8
  254. package/dist/types/core/beacon/aggregation/cohort/status.d.ts.map +0 -1
  255. package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts +0 -89
  256. package/dist/types/core/beacon/aggregation/communication/adapter/did-comm.d.ts.map +0 -1
  257. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts +0 -103
  258. package/dist/types/core/beacon/aggregation/communication/adapter/nostr.d.ts.map +0 -1
  259. package/dist/types/core/beacon/aggregation/communication/error.d.ts.map +0 -1
  260. package/dist/types/core/beacon/aggregation/communication/factory.d.ts +0 -10
  261. package/dist/types/core/beacon/aggregation/communication/factory.d.ts.map +0 -1
  262. package/dist/types/core/beacon/aggregation/communication/service.d.ts +0 -36
  263. package/dist/types/core/beacon/aggregation/communication/service.d.ts.map +0 -1
  264. package/dist/types/core/beacon/aggregation/coordinator.d.ts +0 -116
  265. package/dist/types/core/beacon/aggregation/coordinator.d.ts.map +0 -1
  266. package/dist/types/core/beacon/aggregation/participant.d.ts +0 -192
  267. package/dist/types/core/beacon/aggregation/participant.d.ts.map +0 -1
  268. package/dist/types/core/beacon/aggregation/session/index.d.ts +0 -156
  269. package/dist/types/core/beacon/aggregation/session/index.d.ts.map +0 -1
  270. package/dist/types/core/beacon/aggregation/session/status.d.ts +0 -11
  271. package/dist/types/core/beacon/aggregation/session/status.d.ts.map +0 -1
  272. package/dist/types/core/update.d.ts +0 -52
  273. package/dist/types/core/update.d.ts.map +0 -1
  274. package/src/core/beacon/aggregation/cohort/index.ts +0 -305
  275. package/src/core/beacon/aggregation/cohort/messages/constants.ts +0 -12
  276. package/src/core/beacon/aggregation/cohort/messages/index.ts +0 -143
  277. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-advert.ts +0 -44
  278. package/src/core/beacon/aggregation/cohort/messages/keygen/cohort-ready.ts +0 -40
  279. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in-accept.ts +0 -35
  280. package/src/core/beacon/aggregation/cohort/messages/keygen/opt-in.ts +0 -34
  281. package/src/core/beacon/aggregation/cohort/messages/keygen/subscribe.ts +0 -36
  282. package/src/core/beacon/aggregation/cohort/messages/sign/aggregated-nonce.ts +0 -39
  283. package/src/core/beacon/aggregation/cohort/messages/sign/authorization-request.ts +0 -40
  284. package/src/core/beacon/aggregation/cohort/messages/sign/nonce-contribution.ts +0 -40
  285. package/src/core/beacon/aggregation/cohort/messages/sign/request-signature.ts +0 -40
  286. package/src/core/beacon/aggregation/cohort/messages/sign/signature-authorization.ts +0 -41
  287. package/src/core/beacon/aggregation/cohort/status.ts +0 -7
  288. package/src/core/beacon/aggregation/communication/adapter/did-comm.ts +0 -148
  289. package/src/core/beacon/aggregation/communication/adapter/nostr.ts +0 -323
  290. package/src/core/beacon/aggregation/communication/error.ts +0 -13
  291. package/src/core/beacon/aggregation/communication/factory.ts +0 -25
  292. package/src/core/beacon/aggregation/communication/service.ts +0 -42
  293. package/src/core/beacon/aggregation/coordinator.ts +0 -419
  294. package/src/core/beacon/aggregation/participant.ts +0 -517
  295. package/src/core/beacon/aggregation/session/index.ts +0 -301
  296. package/src/core/beacon/aggregation/session/status.ts +0 -18
  297. package/src/core/update.ts +0 -158
@@ -0,0 +1,547 @@
1
+ import type { SignedBTCR2Update } from '@did-btcr2/cryptosuite';
2
+ import type { SchnorrKeyPair } from '@did-btcr2/keypair';
3
+ import { bytesToHex } from '@noble/hashes/utils';
4
+ import type { Transaction } from 'bitcoinjs-lib';
5
+ import { AggregationCohort } from './cohort.js';
6
+ import { AggregationServiceError } from './errors.js';
7
+ import type { BaseMessage } from './messages/base.js';
8
+ import {
9
+ COHORT_OPT_IN,
10
+ NONCE_CONTRIBUTION,
11
+ SIGNATURE_AUTHORIZATION,
12
+ SUBMIT_UPDATE,
13
+ VALIDATION_ACK,
14
+ } from './messages/constants.js';
15
+ import {
16
+ createAuthorizationRequestMessage,
17
+ createCohortAdvertMessage,
18
+ createCohortOptInAcceptMessage,
19
+ createCohortReadyMessage,
20
+ createDistributeAggregatedDataMessage,
21
+ createAggregatedNonceMessage,
22
+ } from './messages/factories.js';
23
+ import type { ServiceCohortPhaseType } from './phases.js';
24
+ import { ServiceCohortPhase } from './phases.js';
25
+ import { BeaconSigningSession } from './signing-session.js';
26
+
27
+ /** Cohort configuration set by the service operator. */
28
+ export interface CohortConfig {
29
+ minParticipants: number;
30
+ network: string;
31
+ beaconType: string;
32
+ }
33
+
34
+ /** Pending opt-in awaiting service operator approval. */
35
+ export interface PendingOptIn {
36
+ cohortId: string;
37
+ participantDid: string;
38
+ participantPk: Uint8Array;
39
+ communicationPk: Uint8Array;
40
+ }
41
+
42
+ /** Validation tracking progress. */
43
+ export interface ValidationProgress {
44
+ approved: ReadonlySet<string>;
45
+ rejected: ReadonlySet<string>;
46
+ pending: ReadonlySet<string>;
47
+ total: number;
48
+ }
49
+
50
+ /** Final aggregation result for a cohort. */
51
+ export interface AggregationResult {
52
+ cohortId: string;
53
+ signature: Uint8Array;
54
+ signedTx: Transaction;
55
+ }
56
+
57
+ /** Transaction data needed to start a signing session. */
58
+ export interface SigningTxData {
59
+ tx: Transaction;
60
+ prevOutScripts: Uint8Array[];
61
+ prevOutValues: bigint[];
62
+ }
63
+
64
+ /** Per-cohort service state — internal. */
65
+ interface ServiceCohortState {
66
+ phase: ServiceCohortPhaseType;
67
+ cohort: AggregationCohort;
68
+ config: CohortConfig;
69
+ pendingOptIns: Map<string, PendingOptIn>;
70
+ acceptedParticipants: Set<string>;
71
+ signingSession?: BeaconSigningSession;
72
+ result?: AggregationResult;
73
+ }
74
+
75
+ export interface AggregationServiceParams {
76
+ did: string;
77
+ keys: SchnorrKeyPair;
78
+ }
79
+
80
+ /**
81
+ * Sans-I/O state machine for an Aggregation Service.
82
+ *
83
+ * Manages multiple cohorts simultaneously. The service operator drives the
84
+ * state machine via `receive()` (for incoming messages) and explicit action
85
+ * methods (advertising, accepting opt-ins, finalizing keygen, building
86
+ * aggregated data, starting signing). All outgoing messages are returned for
87
+ * the caller to send via whatever transport.
88
+ *
89
+ * @class AggregationService
90
+ */
91
+ export class AggregationService {
92
+ readonly did: string;
93
+ readonly keys: SchnorrKeyPair;
94
+
95
+ /** Per-cohort state, keyed by cohortId. */
96
+ #cohortStates: Map<string, ServiceCohortState> = new Map();
97
+
98
+ constructor({ did, keys }: AggregationServiceParams) {
99
+ this.did = did;
100
+ this.keys = keys;
101
+ }
102
+
103
+
104
+ receive(message: BaseMessage): void {
105
+ const type = message.type;
106
+ switch(type) {
107
+ case COHORT_OPT_IN:
108
+ this.#handleOptIn(message);
109
+ break;
110
+ case SUBMIT_UPDATE:
111
+ this.#handleSubmitUpdate(message);
112
+ break;
113
+ case VALIDATION_ACK:
114
+ this.#handleValidationAck(message);
115
+ break;
116
+ case NONCE_CONTRIBUTION:
117
+ this.#handleNonceContribution(message);
118
+ break;
119
+ case SIGNATURE_AUTHORIZATION:
120
+ this.#handleSignatureAuthorization(message);
121
+ break;
122
+ default:
123
+ // Unknown message type — silently ignore
124
+ break;
125
+ }
126
+ }
127
+
128
+
129
+ /**
130
+ * Create a new cohort with the given config. Returns the cohort ID.
131
+ * Cohort starts in `Created` phase — call `advertise()` to broadcast.
132
+ */
133
+ createCohort(config: CohortConfig): string {
134
+ const cohort = new AggregationCohort({
135
+ serviceDid : this.did,
136
+ minParticipants : config.minParticipants,
137
+ network : config.network,
138
+ beaconType : config.beaconType,
139
+ });
140
+ this.#cohortStates.set(cohort.id, {
141
+ phase : ServiceCohortPhase.Created,
142
+ cohort,
143
+ config,
144
+ pendingOptIns : new Map(),
145
+ acceptedParticipants : new Set(),
146
+ });
147
+ return cohort.id;
148
+ }
149
+
150
+ /**
151
+ * Advertise a cohort to discover participants.
152
+ * Returns the advert message to broadcast.
153
+ */
154
+ advertise(cohortId: string): BaseMessage[] {
155
+ const state = this.#cohortStates.get(cohortId);
156
+ if(!state) {
157
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
158
+ }
159
+ if(state.phase !== ServiceCohortPhase.Created) {
160
+ throw new AggregationServiceError(
161
+ `Cannot advertise cohort ${cohortId}: phase is ${state.phase}.`,
162
+ 'INVALID_PHASE', { cohortId, phase: state.phase }
163
+ );
164
+ }
165
+
166
+ const message = createCohortAdvertMessage({
167
+ from : this.did,
168
+ cohortId,
169
+ cohortSize : state.config.minParticipants,
170
+ beaconType : state.config.beaconType,
171
+ network : state.config.network,
172
+ communicationPk : this.keys.publicKey.compressed,
173
+ });
174
+
175
+ state.phase = ServiceCohortPhase.Advertised;
176
+ return [message];
177
+ }
178
+
179
+ /** Pending opt-ins awaiting operator approval. */
180
+ pendingOptIns(cohortId: string): ReadonlyMap<string, PendingOptIn> {
181
+ const state = this.#cohortStates.get(cohortId);
182
+ if(!state) return new Map();
183
+ // Return only those not yet accepted
184
+ const map = new Map<string, PendingOptIn>();
185
+ for(const [did, optIn] of state.pendingOptIns) {
186
+ if(!state.acceptedParticipants.has(did)) {
187
+ map.set(did, optIn);
188
+ }
189
+ }
190
+ return map;
191
+ }
192
+
193
+ #handleOptIn(message: BaseMessage): void {
194
+ const cohortId = message.body?.cohortId;
195
+ if(!cohortId) return;
196
+ const state = this.#cohortStates.get(cohortId);
197
+ if(!state) return;
198
+ if(state.phase !== ServiceCohortPhase.Advertised) return;
199
+
200
+ const participantDid = message.from;
201
+ const participantPk = message.body?.participantPk;
202
+ const communicationPk = message.body?.communicationPk;
203
+ if(!participantPk || !communicationPk) return;
204
+
205
+ state.pendingOptIns.set(participantDid, {
206
+ cohortId,
207
+ participantDid,
208
+ participantPk,
209
+ communicationPk,
210
+ });
211
+ }
212
+
213
+ /**
214
+ * Service operator accepts a participant's opt-in.
215
+ * Returns the accept message to send.
216
+ */
217
+ acceptParticipant(cohortId: string, participantDid: string): BaseMessage[] {
218
+ const state = this.#cohortStates.get(cohortId);
219
+ if(!state) {
220
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
221
+ }
222
+ const optIn = state.pendingOptIns.get(participantDid);
223
+ if(!optIn) {
224
+ throw new AggregationServiceError(
225
+ `No pending opt-in from ${participantDid} for cohort ${cohortId}.`,
226
+ 'NO_OPT_IN', { cohortId, participantDid }
227
+ );
228
+ }
229
+ if(state.acceptedParticipants.has(participantDid)) {
230
+ throw new AggregationServiceError(
231
+ `Participant ${participantDid} already accepted into cohort ${cohortId}.`,
232
+ 'ALREADY_ACCEPTED', { cohortId, participantDid }
233
+ );
234
+ }
235
+
236
+ state.acceptedParticipants.add(participantDid);
237
+ state.cohort.participants.push(participantDid);
238
+ state.cohort.cohortKeys = [...state.cohort.cohortKeys, optIn.participantPk];
239
+
240
+ return [createCohortOptInAcceptMessage({
241
+ from : this.did,
242
+ to : participantDid,
243
+ cohortId,
244
+ })];
245
+ }
246
+
247
+ /**
248
+ * Finalize cohort keygen: compute MuSig2 Taproot beacon address and send
249
+ * COHORT_READY messages to all accepted participants.
250
+ */
251
+ finalizeKeygen(cohortId: string): BaseMessage[] {
252
+ const state = this.#cohortStates.get(cohortId);
253
+ if(!state) {
254
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
255
+ }
256
+ if(state.phase !== ServiceCohortPhase.Advertised) {
257
+ throw new AggregationServiceError(
258
+ `Cannot finalize keygen for cohort ${cohortId}: phase is ${state.phase}.`,
259
+ 'INVALID_PHASE', { cohortId, phase: state.phase }
260
+ );
261
+ }
262
+ if(state.acceptedParticipants.size < state.config.minParticipants) {
263
+ throw new AggregationServiceError(
264
+ `Cohort ${cohortId} has only ${state.acceptedParticipants.size} accepted participants, need ${state.config.minParticipants}.`,
265
+ 'NOT_ENOUGH_PARTICIPANTS', { cohortId }
266
+ );
267
+ }
268
+
269
+ const beaconAddress = state.cohort.computeBeaconAddress();
270
+ state.phase = ServiceCohortPhase.CohortSet;
271
+
272
+ const messages: BaseMessage[] = [];
273
+ for(const participantDid of state.cohort.participants) {
274
+ messages.push(createCohortReadyMessage({
275
+ from : this.did,
276
+ to : participantDid,
277
+ cohortId,
278
+ beaconAddress,
279
+ cohortKeys : state.cohort.cohortKeys,
280
+ }));
281
+ }
282
+ return messages;
283
+ }
284
+
285
+
286
+ /** Updates collected so far for a cohort. */
287
+ collectedUpdates(cohortId: string): ReadonlyMap<string, SignedBTCR2Update> {
288
+ const state = this.#cohortStates.get(cohortId);
289
+ if(!state) return new Map();
290
+ return state.cohort.pendingUpdates;
291
+ }
292
+
293
+ #handleSubmitUpdate(message: BaseMessage): void {
294
+ const cohortId = message.body?.cohortId;
295
+ if(!cohortId) return;
296
+ const state = this.#cohortStates.get(cohortId);
297
+ if(!state) return;
298
+ if(state.phase !== ServiceCohortPhase.CohortSet && state.phase !== ServiceCohortPhase.CollectingUpdates) return;
299
+
300
+ const signedUpdate = message.body?.signedUpdate;
301
+ if(!signedUpdate) return;
302
+
303
+ state.cohort.addUpdate(message.from, signedUpdate as unknown as SignedBTCR2Update);
304
+
305
+ if(state.phase === ServiceCohortPhase.CohortSet) {
306
+ state.phase = ServiceCohortPhase.CollectingUpdates;
307
+ }
308
+ if(state.cohort.hasAllUpdates()) {
309
+ state.phase = ServiceCohortPhase.UpdatesCollected;
310
+ }
311
+ }
312
+
313
+
314
+ /**
315
+ * Build the aggregated data structure (CAS Announcement or SMT tree) and
316
+ * return distribute messages to send to all participants for validation.
317
+ */
318
+ buildAndDistribute(cohortId: string): BaseMessage[] {
319
+ const state = this.#cohortStates.get(cohortId);
320
+ if(!state) {
321
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
322
+ }
323
+ if(state.phase !== ServiceCohortPhase.UpdatesCollected) {
324
+ throw new AggregationServiceError(
325
+ `Cannot build aggregated data for cohort ${cohortId}: phase is ${state.phase}.`,
326
+ 'INVALID_PHASE', { cohortId, phase: state.phase }
327
+ );
328
+ }
329
+
330
+ if(state.config.beaconType === 'CASBeacon') {
331
+ state.cohort.buildCASAnnouncement();
332
+ } else if(state.config.beaconType === 'SMTBeacon') {
333
+ state.cohort.buildSMTTree();
334
+ } else {
335
+ throw new AggregationServiceError(
336
+ `Unsupported beacon type: ${state.config.beaconType}`,
337
+ 'UNSUPPORTED_BEACON_TYPE', { cohortId, beaconType: state.config.beaconType }
338
+ );
339
+ }
340
+
341
+ const signalBytesHex = bytesToHex(state.cohort.signalBytes!);
342
+ state.phase = ServiceCohortPhase.DataDistributed;
343
+
344
+ const messages: BaseMessage[] = [];
345
+ for(const participantDid of state.cohort.participants) {
346
+ messages.push(createDistributeAggregatedDataMessage({
347
+ from : this.did,
348
+ to : participantDid,
349
+ cohortId,
350
+ beaconType : state.config.beaconType,
351
+ signalBytesHex,
352
+ casAnnouncement : state.config.beaconType === 'CASBeacon' ? state.cohort.casAnnouncement : undefined,
353
+ smtProof : state.config.beaconType === 'SMTBeacon' ? state.cohort.smtProofs?.get(participantDid) as unknown as Record<string, unknown> : undefined,
354
+ }));
355
+ }
356
+ return messages;
357
+ }
358
+
359
+ validationProgress(cohortId: string): ValidationProgress {
360
+ const state = this.#cohortStates.get(cohortId);
361
+ if(!state) {
362
+ return { approved: new Set(), rejected: new Set(), pending: new Set(), total: 0 };
363
+ }
364
+ const approved = state.cohort.validationAcks;
365
+ const rejected = state.cohort.validationRejections;
366
+ const allParticipants = new Set(state.cohort.participants);
367
+ const responded = new Set([...approved, ...rejected]);
368
+ const pending = new Set([...allParticipants].filter(p => !responded.has(p)));
369
+ return {
370
+ approved,
371
+ rejected,
372
+ pending,
373
+ total : allParticipants.size,
374
+ };
375
+ }
376
+
377
+ #handleValidationAck(message: BaseMessage): void {
378
+ const cohortId = message.body?.cohortId;
379
+ if(!cohortId) return;
380
+ const state = this.#cohortStates.get(cohortId);
381
+ if(!state) return;
382
+ if(state.phase !== ServiceCohortPhase.DataDistributed) return;
383
+
384
+ const approved = message.body?.approved;
385
+ if(approved === undefined) return;
386
+
387
+ state.cohort.addValidation(message.from, approved);
388
+
389
+ // Transition to Validated only when all participants approved.
390
+ // Transition to Failed when all responses are in but at least one rejected.
391
+ if(state.cohort.isFullyValidated()) {
392
+ state.phase = ServiceCohortPhase.Validated;
393
+ } else if(state.cohort.hasAllValidationResponses()) {
394
+ state.phase = ServiceCohortPhase.Failed;
395
+ }
396
+ }
397
+
398
+
399
+ /**
400
+ * Start a signing session by creating auth requests for all participants.
401
+ * The caller provides the transaction data — typically built via
402
+ * `buildBeaconTransaction()` against a Bitcoin connection.
403
+ */
404
+ startSigning(cohortId: string, txData: SigningTxData): BaseMessage[] {
405
+ const state = this.#cohortStates.get(cohortId);
406
+ if(!state) {
407
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
408
+ }
409
+ if(state.phase !== ServiceCohortPhase.Validated) {
410
+ throw new AggregationServiceError(
411
+ `Cannot start signing for cohort ${cohortId}: phase is ${state.phase}.`,
412
+ 'INVALID_PHASE', { cohortId, phase: state.phase }
413
+ );
414
+ }
415
+
416
+ const session = new BeaconSigningSession({
417
+ cohort : state.cohort,
418
+ pendingTx : txData.tx,
419
+ prevOutScripts : txData.prevOutScripts,
420
+ prevOutValues : txData.prevOutValues,
421
+ });
422
+ state.signingSession = session;
423
+ state.phase = ServiceCohortPhase.SigningStarted;
424
+
425
+ const messages: BaseMessage[] = [];
426
+ for(const participantDid of state.cohort.participants) {
427
+ messages.push(createAuthorizationRequestMessage({
428
+ from : this.did,
429
+ to : participantDid,
430
+ cohortId,
431
+ sessionId : session.id,
432
+ pendingTx : txData.tx.toHex(),
433
+ prevOutValue : txData.prevOutValues[0]?.toString() ?? '0',
434
+ }));
435
+ }
436
+ return messages;
437
+ }
438
+
439
+ #handleNonceContribution(message: BaseMessage): void {
440
+ const cohortId = message.body?.cohortId;
441
+ if(!cohortId) return;
442
+ const state = this.#cohortStates.get(cohortId);
443
+ if(!state || !state.signingSession) return;
444
+ if(state.phase !== ServiceCohortPhase.SigningStarted) return;
445
+
446
+ const sessionId = message.body?.sessionId;
447
+ if(sessionId !== state.signingSession.id) return;
448
+
449
+ const nonceContribution = message.body?.nonceContribution;
450
+ if(!nonceContribution) return;
451
+
452
+ state.signingSession.addNonceContribution(message.from, nonceContribution);
453
+
454
+ if(state.signingSession.nonceContributions.size === state.cohort.participants.length) {
455
+ state.phase = ServiceCohortPhase.NoncesCollected;
456
+ }
457
+ }
458
+
459
+ /**
460
+ * Generate the aggregated nonce and return messages to send to participants.
461
+ * Call after `validationProgress(cohortId).approved.size === total`.
462
+ */
463
+ sendAggregatedNonce(cohortId: string): BaseMessage[] {
464
+ const state = this.#cohortStates.get(cohortId);
465
+ if(!state) {
466
+ throw new AggregationServiceError(`Cohort ${cohortId} not found.`, 'COHORT_NOT_FOUND', { cohortId });
467
+ }
468
+ if(state.phase !== ServiceCohortPhase.NoncesCollected || !state.signingSession) {
469
+ throw new AggregationServiceError(
470
+ `Cannot send aggregated nonce for cohort ${cohortId}: phase is ${state.phase}.`,
471
+ 'INVALID_PHASE', { cohortId, phase: state.phase }
472
+ );
473
+ }
474
+
475
+ const aggregatedNonce = state.signingSession.generateAggregatedNonce();
476
+ state.phase = ServiceCohortPhase.AwaitingPartialSigs;
477
+
478
+ const messages: BaseMessage[] = [];
479
+ for(const participantDid of state.cohort.participants) {
480
+ messages.push(createAggregatedNonceMessage({
481
+ from : this.did,
482
+ to : participantDid,
483
+ cohortId,
484
+ sessionId : state.signingSession.id,
485
+ aggregatedNonce,
486
+ }));
487
+ }
488
+ return messages;
489
+ }
490
+
491
+ #handleSignatureAuthorization(message: BaseMessage): void {
492
+ const cohortId = message.body?.cohortId;
493
+ if(!cohortId) return;
494
+ const state = this.#cohortStates.get(cohortId);
495
+ if(!state || !state.signingSession) return;
496
+ if(state.phase !== ServiceCohortPhase.AwaitingPartialSigs) return;
497
+
498
+ const sessionId = message.body?.sessionId;
499
+ if(sessionId !== state.signingSession.id) return;
500
+
501
+ const partialSignature = message.body?.partialSignature;
502
+ if(!partialSignature) return;
503
+
504
+ state.signingSession.addPartialSignature(message.from, partialSignature);
505
+
506
+ if(state.signingSession.partialSignatures.size === state.cohort.participants.length) {
507
+ // All partial sigs received — generate final signature
508
+ const signature = state.signingSession.generateFinalSignature();
509
+
510
+ // Set Taproot key-path witness
511
+ state.signingSession.pendingTx.setWitness(0, [signature]);
512
+
513
+ state.result = {
514
+ cohortId,
515
+ signature,
516
+ signedTx : state.signingSession.pendingTx,
517
+ };
518
+ state.phase = ServiceCohortPhase.Complete;
519
+ }
520
+ }
521
+
522
+
523
+ getResult(cohortId: string): AggregationResult | undefined {
524
+ return this.#cohortStates.get(cohortId)?.result;
525
+ }
526
+
527
+ getCohortPhase(cohortId: string): ServiceCohortPhaseType | undefined {
528
+ return this.#cohortStates.get(cohortId)?.phase;
529
+ }
530
+
531
+ getCohort(cohortId: string): AggregationCohort | undefined {
532
+ return this.#cohortStates.get(cohortId)?.cohort;
533
+ }
534
+
535
+ /**
536
+ * Get the signing session ID for a cohort, if a signing session has been started.
537
+ * @param {string} cohortId - The cohort ID.
538
+ * @returns {string | undefined} The session ID, or undefined if no session is active.
539
+ */
540
+ getSigningSessionId(cohortId: string): string | undefined {
541
+ return this.#cohortStates.get(cohortId)?.signingSession?.id;
542
+ }
543
+
544
+ get cohorts(): ReadonlyArray<AggregationCohort> {
545
+ return [...this.#cohortStates.values()].map(s => s.cohort);
546
+ }
547
+ }