keri-ts 2.1.0 → 2.2.1

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 (300) hide show
  1. package/README.md +30 -2
  2. package/esm/keri/npm/src/acdc/authoring.js +195 -0
  3. package/esm/keri/npm/src/acdc/custody.js +187 -0
  4. package/esm/keri/npm/src/acdc/dhking.js +244 -32
  5. package/esm/keri/npm/src/acdc/regbasing.js +10 -0
  6. package/esm/keri/npm/src/acdc/salting.js +16 -1
  7. package/esm/keri/npm/src/acdc/scheming.js +93 -54
  8. package/esm/keri/npm/src/acdc/unblinding.js +118 -95
  9. package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
  10. package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
  11. package/esm/keri/npm/src/app/bootstrap/oobiery.js +4 -6
  12. package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
  13. package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
  14. package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
  15. package/esm/keri/npm/src/app/credentials/root-replicating.js +68 -60
  16. package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
  17. package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
  18. package/esm/keri/npm/src/app/delivery/forwarding.js +16 -3
  19. package/esm/keri/npm/src/app/exchanges/exchanging.js +14 -4
  20. package/esm/keri/npm/src/app/identity/challenging.js +50 -0
  21. package/esm/keri/npm/src/app/identity/delegating.js +77 -77
  22. package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
  23. package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
  24. package/esm/keri/npm/src/app/identity/habbing.js +129 -6
  25. package/esm/keri/npm/src/app/identity/keeping.js +77 -4
  26. package/esm/keri/npm/src/app/ipex/group-ipex.js +341 -0
  27. package/esm/keri/npm/src/app/ipex/group-issuance.js +905 -0
  28. package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
  29. package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
  30. package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
  31. package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
  32. package/esm/keri/npm/src/app/ipex/ipex-grouping.js +50 -19
  33. package/esm/keri/npm/src/app/ipex/ipex-node-authentication.js +42 -18
  34. package/esm/keri/npm/src/app/ipex/issuance.js +896 -0
  35. package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
  36. package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
  37. package/esm/keri/npm/src/app/ipex/presenting.js +408 -0
  38. package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
  39. package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +667 -0
  40. package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
  41. package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
  42. package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
  43. package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
  44. package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
  45. package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
  46. package/esm/keri/npm/src/app/mailbox/mailboxing.js +10 -5
  47. package/esm/keri/npm/src/app/multisig/counseling.js +488 -0
  48. package/esm/keri/npm/src/app/multisig/group-members.js +18 -0
  49. package/esm/keri/npm/src/app/multisig/multisig-messaging.js +33 -6
  50. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +98 -147
  51. package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
  52. package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
  53. package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
  54. package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
  55. package/esm/keri/npm/src/app/protocol/protocol-processing.js +9 -3
  56. package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
  57. package/esm/keri/npm/src/app/runtime/agent-runtime.js +106 -55
  58. package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
  59. package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
  60. package/esm/keri/npm/src/app/runtime/doing.js +17 -0
  61. package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
  62. package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
  63. package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
  64. package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
  65. package/esm/keri/npm/src/app/transport/http-client.js +25 -6
  66. package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
  67. package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
  68. package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
  69. package/esm/keri/npm/src/cli/credentials/ipex.js +164 -191
  70. package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
  71. package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
  72. package/esm/keri/npm/src/cli/endpoints/oobi.js +10 -13
  73. package/esm/keri/npm/src/cli/identity/challenge.js +8 -34
  74. package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
  75. package/esm/keri/npm/src/cli/identity/incept.js +15 -32
  76. package/esm/keri/npm/src/cli/identity/interact.js +5 -17
  77. package/esm/keri/npm/src/cli/identity/rotate.js +8 -36
  78. package/esm/keri/npm/src/cli/index.js +3 -1
  79. package/esm/keri/npm/src/cli/messaging/group-join.js +83 -0
  80. package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
  81. package/esm/keri/npm/src/cli/messaging/multisig.js +190 -285
  82. package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
  83. package/esm/keri/npm/src/core/kel/eventing.js +66 -10
  84. package/esm/keri/npm/src/core/mailbox/kram-policy.js +39 -6
  85. package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
  86. package/esm/keri/npm/src/core/records.js +23 -0
  87. package/esm/keri/npm/src/core/routing.js +13 -0
  88. package/esm/keri/npm/src/db/basing.js +34 -2
  89. package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
  90. package/esm/keri/npm/src/db/indexeddb.js +98 -0
  91. package/esm/keri/npm/src/db/keeping.js +11 -2
  92. package/esm/keri/npm/src/db/store-lock.js +150 -0
  93. package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
  94. package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
  95. package/esm/keri/npm/src/npm/db.browser.js +2 -0
  96. package/esm/keri/npm/src/npm/index.browser.js +9 -0
  97. package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
  98. package/esm/keri/npm/src/npm/runtime-web.js +3 -0
  99. package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
  100. package/esm/keri/npm/src/runtime/index.js +51 -4
  101. package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
  102. package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
  103. package/esm/keri/npm/src/runtime/web.js +10 -0
  104. package/esm/keri/npm/src/vdr/tel-publication.js +16 -0
  105. package/esm/keri/npm/src/version.js +2 -2
  106. package/package.json +15 -2
  107. package/types/acdc/authoring.d.ts +54 -0
  108. package/types/acdc/authoring.d.ts.map +1 -0
  109. package/types/acdc/custody.d.ts +84 -0
  110. package/types/acdc/custody.d.ts.map +1 -0
  111. package/types/acdc/dhking.d.ts +94 -3
  112. package/types/acdc/dhking.d.ts.map +1 -1
  113. package/types/acdc/regbasing.d.ts +4 -0
  114. package/types/acdc/regbasing.d.ts.map +1 -1
  115. package/types/acdc/salting.d.ts +6 -1
  116. package/types/acdc/salting.d.ts.map +1 -1
  117. package/types/acdc/scheming.d.ts +2 -0
  118. package/types/acdc/scheming.d.ts.map +1 -1
  119. package/types/acdc/unblinding.d.ts +58 -19
  120. package/types/acdc/unblinding.d.ts.map +1 -1
  121. package/types/app/bootstrap/authenticating.d.ts +3 -1
  122. package/types/app/bootstrap/authenticating.d.ts.map +1 -1
  123. package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
  124. package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
  125. package/types/app/bootstrap/oobiery.d.ts +3 -1
  126. package/types/app/bootstrap/oobiery.d.ts.map +1 -1
  127. package/types/app/credentials/credential-revoking.d.ts +3 -0
  128. package/types/app/credentials/credential-revoking.d.ts.map +1 -1
  129. package/types/app/credentials/credential-workflows.d.ts +5 -0
  130. package/types/app/credentials/credential-workflows.d.ts.map +1 -1
  131. package/types/app/credentials/registry-settling.d.ts +85 -0
  132. package/types/app/credentials/registry-settling.d.ts.map +1 -0
  133. package/types/app/credentials/root-replicating.d.ts +56 -44
  134. package/types/app/credentials/root-replicating.d.ts.map +1 -1
  135. package/types/app/credentials/root-replicator.d.ts +105 -0
  136. package/types/app/credentials/root-replicator.d.ts.map +1 -0
  137. package/types/app/credentials/tel-completion.d.ts +55 -0
  138. package/types/app/credentials/tel-completion.d.ts.map +1 -0
  139. package/types/app/delivery/forwarding.d.ts +6 -0
  140. package/types/app/delivery/forwarding.d.ts.map +1 -1
  141. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  142. package/types/app/identity/challenging.d.ts +54 -0
  143. package/types/app/identity/challenging.d.ts.map +1 -1
  144. package/types/app/identity/delegating.d.ts +21 -4
  145. package/types/app/identity/delegating.d.ts.map +1 -1
  146. package/types/app/identity/delegation-approval.d.ts +228 -0
  147. package/types/app/identity/delegation-approval.d.ts.map +1 -0
  148. package/types/app/identity/event-completion.d.ts +151 -0
  149. package/types/app/identity/event-completion.d.ts.map +1 -0
  150. package/types/app/identity/habbing.d.ts +67 -2
  151. package/types/app/identity/habbing.d.ts.map +1 -1
  152. package/types/app/identity/keeping.d.ts +49 -3
  153. package/types/app/identity/keeping.d.ts.map +1 -1
  154. package/types/app/ipex/group-ipex.d.ts +254 -0
  155. package/types/app/ipex/group-ipex.d.ts.map +1 -0
  156. package/types/app/ipex/group-issuance.d.ts +281 -0
  157. package/types/app/ipex/group-issuance.d.ts.map +1 -0
  158. package/types/app/ipex/ipex-admitting.d.ts +47 -0
  159. package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
  160. package/types/app/ipex/ipex-conversation.d.ts +195 -0
  161. package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
  162. package/types/app/ipex/ipex-discloser.d.ts +156 -0
  163. package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
  164. package/types/app/ipex/ipex-granting.d.ts +145 -0
  165. package/types/app/ipex/ipex-granting.d.ts.map +1 -0
  166. package/types/app/ipex/ipex-grouping.d.ts +18 -0
  167. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  168. package/types/app/ipex/ipex-node-authentication.d.ts +9 -1
  169. package/types/app/ipex/ipex-node-authentication.d.ts.map +1 -1
  170. package/types/app/ipex/issuance.d.ts +445 -0
  171. package/types/app/ipex/issuance.d.ts.map +1 -0
  172. package/types/app/ipex/pending-presentations.d.ts +25 -0
  173. package/types/app/ipex/pending-presentations.d.ts.map +1 -0
  174. package/types/app/ipex/presentation-files.d.ts +47 -0
  175. package/types/app/ipex/presentation-files.d.ts.map +1 -0
  176. package/types/app/ipex/presenting.d.ts +300 -0
  177. package/types/app/ipex/presenting.d.ts.map +1 -0
  178. package/types/app/ipex/receive-issuance.d.ts +99 -0
  179. package/types/app/ipex/receive-issuance.d.ts.map +1 -0
  180. package/types/app/ipex/unblinding-workflow.d.ts +257 -0
  181. package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
  182. package/types/app/mailbox/ipex-arrival.d.ts +104 -0
  183. package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
  184. package/types/app/mailbox/kel-publisher.d.ts +141 -0
  185. package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
  186. package/types/app/mailbox/kel-publishing.d.ts +70 -0
  187. package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
  188. package/types/app/mailbox/kel-submission.d.ts +18 -0
  189. package/types/app/mailbox/kel-submission.d.ts.map +1 -0
  190. package/types/app/mailbox/mailbox-admin.d.ts +113 -0
  191. package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
  192. package/types/app/mailbox/mailbox-poller.d.ts +92 -3
  193. package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
  194. package/types/app/mailbox/mailboxing.d.ts +3 -0
  195. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  196. package/types/app/multisig/counseling.d.ts +196 -0
  197. package/types/app/multisig/counseling.d.ts.map +1 -0
  198. package/types/app/multisig/group-members.d.ts +11 -0
  199. package/types/app/multisig/group-members.d.ts.map +1 -1
  200. package/types/app/multisig/grouping.d.ts +39 -20
  201. package/types/app/multisig/grouping.d.ts.map +1 -1
  202. package/types/app/multisig/multisig-messaging.d.ts +23 -6
  203. package/types/app/multisig/multisig-messaging.d.ts.map +1 -1
  204. package/types/app/multisig/multisig-workflows.d.ts +91 -22
  205. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  206. package/types/app/multisig/proposals.d.ts +129 -0
  207. package/types/app/multisig/proposals.d.ts.map +1 -0
  208. package/types/app/multisig/proposing.d.ts +125 -0
  209. package/types/app/multisig/proposing.d.ts.map +1 -0
  210. package/types/app/notifications/signaling.d.ts +3 -1
  211. package/types/app/notifications/signaling.d.ts.map +1 -1
  212. package/types/app/protocol/parsering.d.ts +13 -0
  213. package/types/app/protocol/parsering.d.ts.map +1 -1
  214. package/types/app/protocol/protocol-processing.d.ts +7 -1
  215. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  216. package/types/app/queries/query-workflows.d.ts +98 -0
  217. package/types/app/queries/query-workflows.d.ts.map +1 -0
  218. package/types/app/runtime/agent-runtime.d.ts +72 -25
  219. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  220. package/types/app/runtime/cue-runtime.d.ts +2 -1
  221. package/types/app/runtime/cue-runtime.d.ts.map +1 -1
  222. package/types/app/runtime/delivery-outbox.d.ts +68 -0
  223. package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
  224. package/types/app/runtime/doing.d.ts +27 -0
  225. package/types/app/runtime/doing.d.ts.map +1 -0
  226. package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
  227. package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
  228. package/types/app/runtime/operation-owners.d.ts +137 -0
  229. package/types/app/runtime/operation-owners.d.ts.map +1 -0
  230. package/types/app/runtime/retry-backoff.d.ts +49 -0
  231. package/types/app/runtime/retry-backoff.d.ts.map +1 -0
  232. package/types/app/runtime/workflow-contract.d.ts +79 -0
  233. package/types/app/runtime/workflow-contract.d.ts.map +1 -0
  234. package/types/app/transport/http-client.d.ts.map +1 -1
  235. package/types/cli/common/event-completion.d.ts +26 -0
  236. package/types/cli/common/event-completion.d.ts.map +1 -0
  237. package/types/cli/common/runtime-workers.d.ts +23 -0
  238. package/types/cli/common/runtime-workers.d.ts.map +1 -0
  239. package/types/cli/credentials/ipex.d.ts.map +1 -1
  240. package/types/cli/credentials/vc.d.ts +1 -1
  241. package/types/cli/credentials/vc.d.ts.map +1 -1
  242. package/types/cli/endpoints/did.d.ts.map +1 -1
  243. package/types/cli/endpoints/oobi.d.ts +3 -1
  244. package/types/cli/endpoints/oobi.d.ts.map +1 -1
  245. package/types/cli/identity/challenge.d.ts +1 -1
  246. package/types/cli/identity/challenge.d.ts.map +1 -1
  247. package/types/cli/identity/delegate.d.ts +14 -1
  248. package/types/cli/identity/delegate.d.ts.map +1 -1
  249. package/types/cli/identity/incept.d.ts.map +1 -1
  250. package/types/cli/identity/interact.d.ts.map +1 -1
  251. package/types/cli/identity/rotate.d.ts.map +1 -1
  252. package/types/cli/index.d.ts +3 -1
  253. package/types/cli/index.d.ts.map +1 -1
  254. package/types/cli/messaging/group-join.d.ts +56 -0
  255. package/types/cli/messaging/group-join.d.ts.map +1 -0
  256. package/types/cli/messaging/group-wait.d.ts +34 -0
  257. package/types/cli/messaging/group-wait.d.ts.map +1 -0
  258. package/types/cli/messaging/multisig.d.ts +29 -5
  259. package/types/cli/messaging/multisig.d.ts.map +1 -1
  260. package/types/cli/messaging/root-copy-lines.d.ts +39 -0
  261. package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
  262. package/types/core/cues.d.ts +11 -0
  263. package/types/core/cues.d.ts.map +1 -1
  264. package/types/core/kel/eventing.d.ts.map +1 -1
  265. package/types/core/mailbox/kram-policy.d.ts +14 -0
  266. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  267. package/types/core/mailbox/kraming.d.ts +1 -1
  268. package/types/core/mailbox/kraming.d.ts.map +1 -1
  269. package/types/core/records.d.ts +61 -0
  270. package/types/core/records.d.ts.map +1 -1
  271. package/types/core/routing.d.ts +6 -0
  272. package/types/core/routing.d.ts.map +1 -1
  273. package/types/db/basing.d.ts +8 -2
  274. package/types/db/basing.d.ts.map +1 -1
  275. package/types/db/core/indexeddb-persistence.d.ts +59 -0
  276. package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
  277. package/types/db/indexeddb.d.ts +37 -0
  278. package/types/db/indexeddb.d.ts.map +1 -0
  279. package/types/db/keeping.d.ts +5 -2
  280. package/types/db/keeping.d.ts.map +1 -1
  281. package/types/db/store-lock.d.ts +72 -0
  282. package/types/db/store-lock.d.ts.map +1 -0
  283. package/types/npm/db-indexeddb.d.ts +4 -0
  284. package/types/npm/db-indexeddb.d.ts.map +1 -0
  285. package/types/npm/runtime-web.d.ts +4 -0
  286. package/types/npm/runtime-web.d.ts.map +1 -0
  287. package/types/runtime/index.d.ts +42 -7
  288. package/types/runtime/index.d.ts.map +1 -1
  289. package/types/runtime/web/output-barrier.d.ts +30 -0
  290. package/types/runtime/web/output-barrier.d.ts.map +1 -0
  291. package/types/runtime/web/persistent-storage.d.ts +36 -0
  292. package/types/runtime/web/persistent-storage.d.ts.map +1 -0
  293. package/types/runtime/web.d.ts +11 -0
  294. package/types/runtime/web.d.ts.map +1 -0
  295. package/types/vdr/tel-publication.d.ts +6 -0
  296. package/types/vdr/tel-publication.d.ts.map +1 -1
  297. package/types/version.d.ts +2 -2
  298. package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
  299. package/types/cli/common/tel-completion.d.ts +0 -8
  300. package/types/cli/common/tel-completion.d.ts.map +0 -1
@@ -2,33 +2,35 @@ import { Organizer } from "../identity/organizing.js";
2
2
  /**
3
3
  * Multisig proposal and approval workflows.
4
4
  *
5
- * CLI orchestration owns timed waits, worker lifetimes, prompts and output.
6
5
  * This module publishes proposals and approves stored KEL/RPY/VDR proposals
7
- * without starting or driving background workers.
6
+ * without starting or driving background workers. `approveGroupProposal` is the
7
+ * only caller that approves; it never asks, because calling it is the consent.
8
8
  */
9
- import { attachmentPayload, collectPayload, concatBytes, Counter, Diger, Ilks, NumberPrimitive, NumDex, parseBytes, Prefixer, SerderACDC, SerderKERI, TraitDex, Vrsn_2_0, } from "cesr-ts";
9
+ import { attachmentPayload, collectPayload, concatBytes, Counter, Diger, Ilks, NumberPrimitive, NumDex, parseBytes, Prefixer, SerderACDC, SerderKERI, TraitDex, Verfer, Vrsn_2_0, } from "cesr-ts";
10
10
  import { verifyRegistryAnchor, vetBlind, } from "../../acdc/regeventing.js";
11
11
  import { publicOpeningAttachment } from "../../acdc/registering.js";
12
12
  import { ValidationError } from "../../core/errors.js";
13
- import { isV2RegistryRoute } from "../../core/exchange/protocol-exchanging.js";
14
13
  import { Kever } from "../../core/kel/kever.js";
15
14
  import { messagize } from "../../core/protocol-serialization.js";
16
15
  import { RegistryRecord } from "../../core/records.js";
16
+ import { dgKey } from "../../db/core/keys.js";
17
17
  import { loadNests } from "../../db/exchange/exchange-nests.js";
18
18
  import { Credentialer, Registry, serializeCredential } from "../../vdr/credentialing.js";
19
19
  import { envelopeFromFrame } from "../protocol/parsering.js";
20
20
  import { groupCredentialAnchorReady, validateCredentialIssueProposal, validateCredentialRevocationProposal, validateCredentialSource, validateRegistryName, validateRegistryProposal, } from "../credentials/credential-proposals.js";
21
+ import { telEventStatus } from "../credentials/tel-completion.js";
21
22
  import { endpointRoleAccepted, groupEndorseReply, groupEventKeys, groupSigningMembers, localGroupMember, signLocalGroupEvent, } from "../identity/endpoint-roleing.js";
22
23
  import { Reactor } from "../protocol/reactor.js";
23
24
  import { abortable } from "../runtime/abortable.js";
24
25
  import { collectBytes } from "../transport/byte-source.js";
25
26
  import { findLocalGroupMember as findLocalMember, groupMemberHasKey, uniqueMembers } from "./group-members.js";
26
27
  import { acdcV2RegistryProposal, MULTISIG_ICP_ROUTE, MULTISIG_ISS_ROUTE, MULTISIG_IXN_ROUTE, MULTISIG_REV_ROUTE, MULTISIG_ROT_ROUTE, MULTISIG_RPY_ROUTE, MULTISIG_VCP_ROUTE, multisigChild, multisigChildEvidence, multisigChildGenusAttrs, prepareAcdcV2RegistryExn, prepareMultisigEventExn, prepareMultisigVdrExn, registryProposalEvent, } from "./grouping.js";
27
- import { admitAndSendGroupMessage, groupSendResult, multisigPayloadSaid, prepareGroupMessage, remoteGroupMembers, signGroupMessage, storedGroupMessage, } from "./multisig-messaging.js";
28
+ import { admitAndSendGroupMessage, failedGroupDelivery, groupSendResult, prepareGroupMessage, remoteGroupMembers, signGroupMessage, storedGroupMessage, } from "./multisig-messaging.js";
28
29
  /** Approve one exact ACDC v2 TEL/anchor through existing member signing and ordinary processors.
29
30
  * A returned wrapper records consent, not quorum/witness/TEL completion; retry the accepted-state owners.
31
+ * `resume` reuses this member's recorded anchor signatures after a crash instead of signing again.
30
32
  */
31
- export function* approveAcdcV2Registry(hby, protocol, group, event, { anchor, opening } = {}) {
33
+ export function* approveAcdcV2Registry(hby, protocol, group, event, { anchor, opening, resume } = {}) {
32
34
  const registry = protocol.registry, member = localGroupMember(hby, group.pre);
33
35
  if (!registry || group.db !== hby.db || registry.db !== hby.db) {
34
36
  throw new ValidationError("ACDC v2 group registry owner is unavailable.");
@@ -105,7 +107,10 @@ export function* approveAcdcV2Registry(hby, protocol, group, event, { anchor, op
105
107
  throw new ValidationError("Registry anchor does not extend the current group event.");
106
108
  }
107
109
  const keys = groupEventKeys(hby, group.pre, anchor);
108
- const sigers = signLocalGroupEvent(hby, anchor, groupSigningMembers(hby, group.pre), keys);
110
+ const members = groupSigningMembers(hby, group.pre);
111
+ // A resuming caller reuses the signatures the first attempt recorded in `sigs.` instead of signing the anchor again.
112
+ const sigers = (resume ? recordedLocalSignatures(hby, anchor, group.pre, members) : null)
113
+ ?? signLocalGroupEvent(hby, anchor, members, keys);
109
114
  const own = messagize(anchor, { sigers, gvrsn: Vrsn_2_0 });
110
115
  const tel = concatBytes(event.raw, Counter.enclose({
111
116
  code: "AttachmentGroup",
@@ -130,14 +135,10 @@ export function* publishAcdcV2Registry(hby, postman, group, approval) {
130
135
  notify: true,
131
136
  });
132
137
  const outcome = yield* postman.wait(evt);
133
- if (outcome.kin === "failed")
134
- throw outcome.error;
135
- outcomes.push({
136
- recipient,
137
- exnSaid: approval[0].said,
138
- payloadSaid: approval[0].sad.a.anc,
139
- deliveries: outcome.deliveries,
140
- });
138
+ const ref = { recipient, exnSaid: approval[0].said, payloadSaid: approval[0].sad.a.anc };
139
+ outcomes.push(outcome.kin === "failed"
140
+ ? failedGroupDelivery(ref, outcome.error)
141
+ : { ...ref, outcome: "delivered", deliveries: outcome.deliveries });
141
142
  }
142
143
  return groupSendResult(outcomes);
143
144
  }
@@ -222,109 +223,34 @@ export function routeForKelEvent(serder) {
222
223
  }
223
224
  }
224
225
  /**
225
- * Select accepted coordination evidence before any approval effects.
226
- * An explicit SAID names the outer EXN and survives notification consumption.
227
- * Notices discover candidates; their attributes do not authorize a route or group.
228
- * An explicit accepted wrapper missing its handler index is replayed by the caller.
226
+ * Approve and publish this member's contribution to one `rip` or `bup` proposal.
227
+ * Null when the proposal is not a well-formed one for a joined group; it then stays inert.
229
228
  */
230
- function* pendingMultisigProposals(hby, runtime, notices, options) {
231
- const candidates = options.said ? [options.said] : notices.map(note => note.attrs.d);
232
- const group = options.group && (hby.habByName(options.group)?.pre ?? options.group);
233
- const selected = [];
234
- for (const said of new Set(candidates)) {
235
- if (typeof said !== "string")
236
- continue;
237
- const exn = hby.db.exns.get([said]);
238
- if (!exn?.ked)
239
- continue;
240
- const route = exn.route ?? "";
241
- if (!isKelRoute(route) && !isVdrRoute(route) && route !== MULTISIG_RPY_ROUTE && !isV2RegistryRoute(route)) {
242
- continue;
243
- }
244
- const payloadSaid = multisigPayloadSaid(exn);
245
- if (!payloadSaid)
246
- continue;
247
- const indexed = hby.db.meids.get([payloadSaid]).some(index => index.qb64 === said);
248
- if (!indexed && !options.said)
249
- continue;
250
- const proposalGroup = isKelRoute(route)
251
- ? kelApproval(exn, route, yield* kelChild(hby, runtime, exn, route))?.group
252
- : stringField(payloadSection(exn.ked), "gid");
253
- if (!proposalGroup)
254
- continue;
255
- if (group && group !== proposalGroup) {
256
- if (options.said) {
257
- throw new ValidationError(`Multisig exchange ${said} belongs to group ${proposalGroup}, not ${group}.`);
258
- }
259
- continue;
260
- }
261
- selected.push({ exn, route, indexed });
262
- }
263
- return selected;
264
- }
265
- /** Approve matching stored evidence; host progress and deadlines belong to the caller. */
266
- export function* approvePendingMultisigProposal(hby, runtime, options) {
267
- const notifier = runtime.notifier;
268
- if (!notifier && !options.said) {
269
- throw new ValidationError("Multisig join requires notification storage or an explicit exchange SAID.");
270
- }
271
- const notices = (notifier?.list(0, 100) ?? []);
272
- for (const { exn, route, indexed } of yield* pendingMultisigProposals(hby, runtime, notices, options)) {
273
- if (!indexed) {
274
- // Acceptance commits before the asynchronous handler. Resume that ordinary
275
- // authenticated intake after interruption; never synthesize approval indexes.
276
- const message = yield* abortable(signal => collectBytes(runtime.exc.replay(exn.said, signal)));
277
- yield* runtime.reactor.processBytes(message, { local: true });
278
- const payloadSaid = multisigPayloadSaid(exn);
279
- if (!hby.db.meids.get([payloadSaid]).some(index => index.qb64 === exn.said))
280
- continue;
281
- }
282
- const rgy = isVdrRoute(route) ? runtime.vdr : null;
283
- let result;
284
- if (isKelRoute(route)) {
285
- result = yield* approveKelProposal(hby, runtime, exn, route, options);
286
- }
287
- else if (isVdrRoute(route)) {
288
- result = yield* approveVdrProposal(hby, rgy, runtime, exn, route, options);
289
- }
290
- else if (isV2RegistryRoute(route)) {
291
- const nests = loadNests(hby.db, exn.said);
292
- const proposal = acdcV2RegistryProposal(exn, nests, runtime.acdc?.store ?? null);
293
- const group = proposal?.anchor.pre ? hby.habs.get(proposal.anchor.pre) : null;
294
- if (!proposal || !group)
295
- continue;
296
- const head = group.kever?.serder.said;
297
- if (!head)
298
- throw new ValidationError("Registry approval requires an accepted local group.");
299
- if (!options.callbacks.approveProposal({ route, group: group.pre, embedded: proposal.tel.said }))
300
- continue;
301
- if (group.kever?.serder.said !== head || !acdcV2RegistryProposal(exn, nests, runtime.acdc?.store ?? null)) {
302
- throw new ValidationError("Group or registry changed while approval was pending.");
303
- }
304
- const envelope = envelopeFromFrame(nests[0]), opening = [...envelope.bsqs, ...envelope.bsss];
305
- if (opening.length > 1)
306
- throw new ValidationError("Registry proposal carries multiple openings.");
307
- const approval = yield* approveAcdcV2Registry(hby, runtime.protocol, group, proposal.tel, {
308
- anchor: proposal.anchor,
309
- opening: opening[0],
310
- });
311
- const published = yield* publishAcdcV2Registry(hby, runtime.postman, group, approval);
312
- const regid = proposal.tel.ilk === "rip" ? proposal.tel.said : proposal.tel.regid;
313
- const accepted = runtime.acdc.store.seqEvent(regid, Number(BigInt(`0x${proposal.tel.sad.n}`)))?.said === proposal.tel.said;
314
- result = { route, said: exn.said, embedded: proposal.tel.said, group: group.pre, accepted, ...published };
315
- }
316
- else {
317
- result = yield* approveRpyProposal(hby, runtime, exn, route, options);
318
- }
319
- if (result) {
320
- for (const note of notices) {
321
- if (note.attrs.d === exn.said)
322
- notifier?.remove(note.rid);
323
- }
324
- return result;
325
- }
326
- }
327
- return null;
229
+ export function* approveRegistryV2Proposal(hby, runtime, exn, route, options) {
230
+ const nests = loadNests(hby.db, exn.said);
231
+ const proposal = acdcV2RegistryProposal(exn, nests, runtime.registryStore);
232
+ const group = proposal?.anchor.pre ? hby.habs.get(proposal.anchor.pre) : null;
233
+ if (!proposal || !group)
234
+ return null;
235
+ const head = group.kever?.serder.said;
236
+ if (!head)
237
+ throw new ValidationError("Registry approval requires an accepted local group.");
238
+ if (group.kever?.serder.said !== head || !acdcV2RegistryProposal(exn, nests, runtime.registryStore)) {
239
+ throw new ValidationError("Group or registry changed while approval was pending.");
240
+ }
241
+ const envelope = envelopeFromFrame(nests[0]), opening = [...envelope.bsqs, ...envelope.bsss];
242
+ if (opening.length > 1)
243
+ throw new ValidationError("Registry proposal carries multiple openings.");
244
+ const approval = yield* approveAcdcV2Registry(hby, runtime.protocol, group, proposal.tel, {
245
+ anchor: proposal.anchor,
246
+ opening: opening[0],
247
+ resume: options.resume,
248
+ });
249
+ const published = yield* publishAcdcV2Registry(hby, runtime.postman, group, approval);
250
+ const regid = proposal.tel.ilk === "rip" ? proposal.tel.said : proposal.tel.regid;
251
+ const accepted = runtime.registryStore?.seqEvent(regid, Number(BigInt(`0x${proposal.tel.sad.n}`)))?.said
252
+ === proposal.tel.said;
253
+ return { route, said: exn.said, embedded: proposal.tel.said, group: group.pre, accepted, ...published };
328
254
  }
329
255
  /**
330
256
  * Approve and publish a local contribution to one endpoint-role reply proposal.
@@ -335,10 +261,10 @@ export function* approvePendingMultisigProposal(hby, runtime, options) {
335
261
  * @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
336
262
  * @param exn Stored multisig exchange wrapper.
337
263
  * @param route Selected multisig route identifying the proposal kind.
338
- * @param options Human approval/alias callbacks and workflow choices; refusal leaves the proposal inert.
264
+ * @param options Alias and name choices plus `resume`; a proposal that is not well formed is left inert.
339
265
  * @returns Approval result with protocol acceptance and deliveries, or null for declined/incomplete input.
340
266
  */
341
- function* approveRpyProposal(hby, runtime, exn, route, options) {
267
+ export function* approveRpyProposal(hby, runtime, exn, route, options) {
342
268
  const wrapperSaid = exn.said;
343
269
  if (!wrapperSaid) {
344
270
  return null;
@@ -356,9 +282,6 @@ function* approveRpyProposal(hby, runtime, exn, route, options) {
356
282
  const { event: rpySerder, attachment, genus } = child;
357
283
  const embeddedSaid = rpySerder.said ?? "";
358
284
  const prior = storedGroupMessage(hby.db, member.pre, exn);
359
- if (!prior && !options.callbacks.approveProposal({ route, group: groupPre, embedded: embeddedSaid || "<unknown>" })) {
360
- return null;
361
- }
362
285
  yield* runtime.reactor.processBytes(concatBytes(Counter.makeGVC(genus), rpySerder.raw, attachment), { local: true });
363
286
  let localRpy;
364
287
  if (prior) {
@@ -386,10 +309,10 @@ function* approveRpyProposal(hby, runtime, exn, route, options) {
386
309
  * @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
387
310
  * @param exn Stored multisig exchange wrapper.
388
311
  * @param route Selected multisig route identifying the proposal kind.
389
- * @param options Human approval/alias callbacks and workflow choices; refusal leaves the proposal inert.
312
+ * @param options Alias and name choices plus `resume`; a proposal that is not well formed is left inert.
390
313
  * @returns Approval result with protocol acceptance and deliveries, or null for declined/incomplete input.
391
314
  */
392
- function* approveKelProposal(hby, runtime, exn, route, options) {
315
+ export function* approveKelProposal(hby, runtime, exn, route, options) {
393
316
  const wrapperSaid = exn.said;
394
317
  if (!wrapperSaid) {
395
318
  return null;
@@ -429,17 +352,26 @@ function* approveKelProposal(hby, runtime, exn, route, options) {
429
352
  if (eventAccepted(hby, serder) && !smids.some(mid => hby.habs.has(mid))) {
430
353
  return null;
431
354
  }
432
- if (!options.callbacks.approveProposal({ route, group: groupPre, embedded: embeddedSaid ?? "<unknown>" })) {
433
- return null;
355
+ // Signing writes the member's signatures to `sigs.` when the event is first
356
+ // processed, before any wrapper exists. A resuming caller (explicit consent
357
+ // already given) finds them and reuses them: no second signature and no
358
+ // second join.
359
+ const signed = options.resume ? recordedLocalSignatures(hby, serder, groupPre, smids) : null;
360
+ if (signed) {
361
+ localMessage = messagize(serder, { sigers: signed, pipelined: false, gvrsn: approval.genus });
434
362
  }
435
- if (proposal.route === MULTISIG_ICP_ROUTE || (proposal.route === MULTISIG_ROT_ROUTE && !hby.habs.has(groupPre))) {
436
- const rmids = proposal.attrs.rmids;
437
- const alias = options.callbacks.chooseGroupAlias(groupPre);
438
- hby.joinGroupHab(groupPre, alias, member, smids, rmids.length > 0 ? rmids : smids);
363
+ else {
364
+ if (proposal.route === MULTISIG_ICP_ROUTE || (proposal.route === MULTISIG_ROT_ROUTE && !hby.habs.has(groupPre))) {
365
+ const rmids = proposal.attrs.rmids;
366
+ const alias = options.groupAlias;
367
+ if (!alias)
368
+ throw new ValidationError(`A group alias is required to join ${groupPre}.`);
369
+ hby.joinGroupHab(groupPre, alias, member, smids, rmids.length > 0 ? rmids : smids);
370
+ }
371
+ const keys = groupEventKeys(hby, groupPre, serder);
372
+ const sigers = signLocalGroupEvent(hby, serder, smids, keys);
373
+ localMessage = messagize(serder, { sigers, pipelined: false, gvrsn: approval.genus });
439
374
  }
440
- const keys = groupEventKeys(hby, groupPre, serder);
441
- const sigers = signLocalGroupEvent(hby, serder, smids, keys);
442
- localMessage = messagize(serder, { sigers, pipelined: false, gvrsn: approval.genus });
443
375
  }
444
376
  // Each contribution may already own a counted attachment enclosure. Admit
445
377
  // complete messages separately and let the ordinary KEL owner union proofs.
@@ -466,10 +398,10 @@ function* approveKelProposal(hby, runtime, exn, route, options) {
466
398
  * @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
467
399
  * @param exn Stored multisig exchange wrapper.
468
400
  * @param route Selected multisig route identifying the proposal kind.
469
- * @param options Human approval/alias callbacks and workflow choices; refusal leaves the proposal inert.
401
+ * @param options Alias and name choices plus `resume`; a proposal that is not well formed is left inert.
470
402
  * @returns Approval result with protocol acceptance and deliveries, or null for declined/incomplete input.
471
403
  */
472
- function* approveVdrProposal(hby, rgy, runtime, exn, route, options) {
404
+ export function* approveVdrProposal(hby, rgy, runtime, exn, route, options) {
473
405
  const wrapperSaid = exn.said;
474
406
  if (!wrapperSaid) {
475
407
  return null;
@@ -527,15 +459,14 @@ function* approveVdrProposal(hby, rgy, runtime, exn, route, options) {
527
459
  const prior = storedGroupMessage(hby.db, member.pre, exn);
528
460
  if (!prior && !groupCredentialAnchorReady(hby, groupPre, anchorSerder))
529
461
  return null;
530
- if (!prior && !options.callbacks.approveProposal({ route, group: groupPre, embedded: embeddedSaid || "<unknown>" })) {
531
- return null;
532
- }
533
- // Declined or malformed proposals remain inert; require VDR before signing or intake.
462
+ // Malformed proposals remain inert; require VDR before signing or intake.
534
463
  if (!rgy)
535
464
  throw new ValidationError("Legacy credential registry is unavailable in this runtime.");
536
465
  let registryName;
537
466
  if (proposal.route === MULTISIG_VCP_ROUTE && !prior) {
538
- registryName = options.callbacks.chooseRegistryName(embeddedSerder.pre);
467
+ registryName = options.registryName;
468
+ if (!registryName)
469
+ throw new ValidationError(`A registry name is required for ${embeddedSerder.pre}.`);
539
470
  validateRegistryName(rgy.reger, registryName, embeddedSerder.pre);
540
471
  }
541
472
  const smids = groupSigningMembers(hby, groupPre);
@@ -545,7 +476,8 @@ function* approveVdrProposal(hby, rgy, runtime, exn, route, options) {
545
476
  }
546
477
  else {
547
478
  const keys = groupEventKeys(hby, groupPre, anchorSerder);
548
- const sigers = signLocalGroupEvent(hby, anchorSerder, smids, keys);
479
+ const sigers = (options.resume ? recordedLocalSignatures(hby, anchorSerder, groupPre, smids) : null)
480
+ ?? signLocalGroupEvent(hby, anchorSerder, smids, keys);
549
481
  localAnchor = messagize(anchorSerder, { sigers, pipelined: false, gvrsn: genus });
550
482
  }
551
483
  yield* runtime.reactor.processBytes(concatBytes(Counter.makeGVC(genus), localAnchor), { local: true });
@@ -600,13 +532,32 @@ function* approveVdrProposal(hby, rgy, runtime, exn, route, options) {
600
532
  tel: {
601
533
  pre: embeddedSerder.pre,
602
534
  sn: embeddedSerder.sn,
603
- publicationComplete: rgy.publication.complete(embeddedSerder.pre, embeddedSerder.sn),
535
+ publicationComplete: telEventStatus({ publication: rgy.publication }, embeddedSerder.pre, embeddedSerder.sn).state === "complete",
604
536
  },
605
537
  ...published,
606
538
  };
607
539
  }
540
+ /**
541
+ * This process's verified signatures for a group event, one per local signing
542
+ * member, read from `sigs.`; null unless every local member's key index has one.
543
+ * Remote members' signatures in the same row never count.
544
+ */
545
+ function recordedLocalSignatures(hby, serder, groupPre, smids) {
546
+ if (!hby.habs.has(groupPre) || !serder.pre || !serder.said)
547
+ return null;
548
+ const local = smids.flatMap((mid, index) => hby.habs.has(mid) ? [index] : []);
549
+ const stored = hby.db.sigs.get(dgKey(serder.pre, serder.said));
550
+ if (local.length === 0 || stored.length === 0)
551
+ return null;
552
+ const verfers = groupEventKeys(hby, groupPre, serder).map(qb64 => new Verfer({ qb64 }));
553
+ const { sigers } = Kever.verifyIndexedSignatures(serder.raw, stored, verfers);
554
+ const own = sigers.filter(siger => local.includes(siger.index));
555
+ return local.every(index => own.some(siger => siger.index === index))
556
+ ? own.sort((left, right) => left.index - right.index)
557
+ : null;
558
+ }
608
559
  /** Preserve the recorded signing/rotation participant order during approval and resume. */
609
- function kelApprovalMembers({ proposal }) {
560
+ export function kelApprovalMembers({ proposal }) {
610
561
  if (proposal.route === MULTISIG_IXN_ROUTE)
611
562
  return [...proposal.attrs.smids];
612
563
  return uniqueMembers([...proposal.attrs.smids, ...proposal.attrs.rmids]);
@@ -662,7 +613,7 @@ function kelProposalLabel(route) {
662
613
  }
663
614
  }
664
615
  /** Decode the fields used by approval, preserving existing missing-embed and member-list behavior. */
665
- function kelApproval(exn, route, child) {
616
+ export function kelApproval(exn, route, child) {
666
617
  if (!child)
667
618
  return null;
668
619
  const { event } = child;
@@ -791,7 +742,7 @@ function rpyAttrs(serder) {
791
742
  }
792
743
  return { cid: attrs.cid, role: attrs.role, eid: attrs.eid };
793
744
  }
794
- function payloadSection(ked) {
745
+ export function payloadSection(ked) {
795
746
  return isRecord(ked.a) ? ked.a : {};
796
747
  }
797
748
  function embeddedSection(ked) {
@@ -812,10 +763,10 @@ function stringField(record, field) {
812
763
  function isRecord(value) {
813
764
  return typeof value === "object" && value !== null && !Array.isArray(value);
814
765
  }
815
- function isKelRoute(route) {
766
+ export function isKelRoute(route) {
816
767
  return route === MULTISIG_ICP_ROUTE || route === MULTISIG_ROT_ROUTE || route === MULTISIG_IXN_ROUTE;
817
768
  }
818
- function isVdrRoute(route) {
769
+ export function isVdrRoute(route) {
819
770
  return route === MULTISIG_VCP_ROUTE || route === MULTISIG_ISS_ROUTE || route === MULTISIG_REV_ROUTE;
820
771
  }
821
772
  function requireText(value, label) {