keri-ts 2.1.0 → 2.2.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 (294) 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 +164 -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 +327 -0
  27. package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -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 +34 -11
  33. package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
  34. package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
  35. package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
  36. package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
  37. package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
  38. package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
  39. package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
  40. package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
  41. package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
  42. package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
  43. package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
  44. package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
  45. package/esm/keri/npm/src/app/mailbox/mailboxing.js +10 -5
  46. package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
  47. package/esm/keri/npm/src/app/multisig/group-members.js +18 -0
  48. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +94 -139
  49. package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
  50. package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
  51. package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
  52. package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
  53. package/esm/keri/npm/src/app/protocol/protocol-processing.js +9 -3
  54. package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
  55. package/esm/keri/npm/src/app/runtime/agent-runtime.js +106 -55
  56. package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
  57. package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
  58. package/esm/keri/npm/src/app/runtime/doing.js +17 -0
  59. package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
  60. package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
  61. package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
  62. package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
  63. package/esm/keri/npm/src/app/transport/http-client.js +25 -6
  64. package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
  65. package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
  66. package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
  67. package/esm/keri/npm/src/cli/credentials/ipex.js +157 -190
  68. package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
  69. package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
  70. package/esm/keri/npm/src/cli/endpoints/oobi.js +10 -13
  71. package/esm/keri/npm/src/cli/identity/challenge.js +8 -34
  72. package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
  73. package/esm/keri/npm/src/cli/identity/incept.js +15 -32
  74. package/esm/keri/npm/src/cli/identity/interact.js +5 -17
  75. package/esm/keri/npm/src/cli/identity/rotate.js +8 -36
  76. package/esm/keri/npm/src/cli/index.js +3 -1
  77. package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
  78. package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
  79. package/esm/keri/npm/src/cli/messaging/multisig.js +163 -284
  80. package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
  81. package/esm/keri/npm/src/core/kel/eventing.js +66 -10
  82. package/esm/keri/npm/src/core/mailbox/kram-policy.js +39 -6
  83. package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
  84. package/esm/keri/npm/src/core/records.js +23 -0
  85. package/esm/keri/npm/src/core/routing.js +13 -0
  86. package/esm/keri/npm/src/db/basing.js +34 -2
  87. package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
  88. package/esm/keri/npm/src/db/indexeddb.js +98 -0
  89. package/esm/keri/npm/src/db/keeping.js +11 -2
  90. package/esm/keri/npm/src/db/store-lock.js +150 -0
  91. package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
  92. package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
  93. package/esm/keri/npm/src/npm/db.browser.js +2 -0
  94. package/esm/keri/npm/src/npm/index.browser.js +9 -0
  95. package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
  96. package/esm/keri/npm/src/npm/runtime-web.js +3 -0
  97. package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
  98. package/esm/keri/npm/src/runtime/index.js +51 -4
  99. package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
  100. package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
  101. package/esm/keri/npm/src/runtime/web.js +10 -0
  102. package/esm/keri/npm/src/vdr/tel-publication.js +16 -0
  103. package/esm/keri/npm/src/version.js +2 -2
  104. package/package.json +15 -2
  105. package/types/acdc/authoring.d.ts +54 -0
  106. package/types/acdc/authoring.d.ts.map +1 -0
  107. package/types/acdc/custody.d.ts +77 -0
  108. package/types/acdc/custody.d.ts.map +1 -0
  109. package/types/acdc/dhking.d.ts +94 -3
  110. package/types/acdc/dhking.d.ts.map +1 -1
  111. package/types/acdc/regbasing.d.ts +4 -0
  112. package/types/acdc/regbasing.d.ts.map +1 -1
  113. package/types/acdc/salting.d.ts +6 -1
  114. package/types/acdc/salting.d.ts.map +1 -1
  115. package/types/acdc/scheming.d.ts +2 -0
  116. package/types/acdc/scheming.d.ts.map +1 -1
  117. package/types/acdc/unblinding.d.ts +58 -19
  118. package/types/acdc/unblinding.d.ts.map +1 -1
  119. package/types/app/bootstrap/authenticating.d.ts +3 -1
  120. package/types/app/bootstrap/authenticating.d.ts.map +1 -1
  121. package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
  122. package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
  123. package/types/app/bootstrap/oobiery.d.ts +3 -1
  124. package/types/app/bootstrap/oobiery.d.ts.map +1 -1
  125. package/types/app/credentials/credential-revoking.d.ts +3 -0
  126. package/types/app/credentials/credential-revoking.d.ts.map +1 -1
  127. package/types/app/credentials/credential-workflows.d.ts +5 -0
  128. package/types/app/credentials/credential-workflows.d.ts.map +1 -1
  129. package/types/app/credentials/registry-settling.d.ts +85 -0
  130. package/types/app/credentials/registry-settling.d.ts.map +1 -0
  131. package/types/app/credentials/root-replicating.d.ts +56 -44
  132. package/types/app/credentials/root-replicating.d.ts.map +1 -1
  133. package/types/app/credentials/root-replicator.d.ts +105 -0
  134. package/types/app/credentials/root-replicator.d.ts.map +1 -0
  135. package/types/app/credentials/tel-completion.d.ts +55 -0
  136. package/types/app/credentials/tel-completion.d.ts.map +1 -0
  137. package/types/app/delivery/forwarding.d.ts +6 -0
  138. package/types/app/delivery/forwarding.d.ts.map +1 -1
  139. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  140. package/types/app/identity/challenging.d.ts +54 -0
  141. package/types/app/identity/challenging.d.ts.map +1 -1
  142. package/types/app/identity/delegating.d.ts +21 -4
  143. package/types/app/identity/delegating.d.ts.map +1 -1
  144. package/types/app/identity/delegation-approval.d.ts +228 -0
  145. package/types/app/identity/delegation-approval.d.ts.map +1 -0
  146. package/types/app/identity/event-completion.d.ts +151 -0
  147. package/types/app/identity/event-completion.d.ts.map +1 -0
  148. package/types/app/identity/habbing.d.ts +67 -2
  149. package/types/app/identity/habbing.d.ts.map +1 -1
  150. package/types/app/identity/keeping.d.ts +49 -3
  151. package/types/app/identity/keeping.d.ts.map +1 -1
  152. package/types/app/ipex/group-ipex.d.ts +247 -0
  153. package/types/app/ipex/group-ipex.d.ts.map +1 -0
  154. package/types/app/ipex/group-issuance.d.ts +281 -0
  155. package/types/app/ipex/group-issuance.d.ts.map +1 -0
  156. package/types/app/ipex/ipex-admitting.d.ts +47 -0
  157. package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
  158. package/types/app/ipex/ipex-conversation.d.ts +195 -0
  159. package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
  160. package/types/app/ipex/ipex-discloser.d.ts +156 -0
  161. package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
  162. package/types/app/ipex/ipex-granting.d.ts +145 -0
  163. package/types/app/ipex/ipex-granting.d.ts.map +1 -0
  164. package/types/app/ipex/ipex-grouping.d.ts +18 -0
  165. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  166. package/types/app/ipex/issuance.d.ts +443 -0
  167. package/types/app/ipex/issuance.d.ts.map +1 -0
  168. package/types/app/ipex/pending-presentations.d.ts +25 -0
  169. package/types/app/ipex/pending-presentations.d.ts.map +1 -0
  170. package/types/app/ipex/presentation-files.d.ts +47 -0
  171. package/types/app/ipex/presentation-files.d.ts.map +1 -0
  172. package/types/app/ipex/presenting.d.ts +298 -0
  173. package/types/app/ipex/presenting.d.ts.map +1 -0
  174. package/types/app/ipex/receive-issuance.d.ts +99 -0
  175. package/types/app/ipex/receive-issuance.d.ts.map +1 -0
  176. package/types/app/ipex/unblinding-workflow.d.ts +255 -0
  177. package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
  178. package/types/app/mailbox/ipex-arrival.d.ts +104 -0
  179. package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
  180. package/types/app/mailbox/kel-publisher.d.ts +141 -0
  181. package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
  182. package/types/app/mailbox/kel-publishing.d.ts +70 -0
  183. package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
  184. package/types/app/mailbox/kel-submission.d.ts +18 -0
  185. package/types/app/mailbox/kel-submission.d.ts.map +1 -0
  186. package/types/app/mailbox/mailbox-admin.d.ts +113 -0
  187. package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
  188. package/types/app/mailbox/mailbox-poller.d.ts +92 -3
  189. package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
  190. package/types/app/mailbox/mailboxing.d.ts +3 -0
  191. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  192. package/types/app/multisig/counseling.d.ts +196 -0
  193. package/types/app/multisig/counseling.d.ts.map +1 -0
  194. package/types/app/multisig/group-members.d.ts +11 -0
  195. package/types/app/multisig/group-members.d.ts.map +1 -1
  196. package/types/app/multisig/grouping.d.ts +39 -20
  197. package/types/app/multisig/grouping.d.ts.map +1 -1
  198. package/types/app/multisig/multisig-workflows.d.ts +91 -22
  199. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  200. package/types/app/multisig/proposals.d.ts +129 -0
  201. package/types/app/multisig/proposals.d.ts.map +1 -0
  202. package/types/app/multisig/proposing.d.ts +125 -0
  203. package/types/app/multisig/proposing.d.ts.map +1 -0
  204. package/types/app/notifications/signaling.d.ts +3 -1
  205. package/types/app/notifications/signaling.d.ts.map +1 -1
  206. package/types/app/protocol/parsering.d.ts +13 -0
  207. package/types/app/protocol/parsering.d.ts.map +1 -1
  208. package/types/app/protocol/protocol-processing.d.ts +7 -1
  209. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  210. package/types/app/queries/query-workflows.d.ts +98 -0
  211. package/types/app/queries/query-workflows.d.ts.map +1 -0
  212. package/types/app/runtime/agent-runtime.d.ts +72 -25
  213. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  214. package/types/app/runtime/cue-runtime.d.ts +2 -1
  215. package/types/app/runtime/cue-runtime.d.ts.map +1 -1
  216. package/types/app/runtime/delivery-outbox.d.ts +68 -0
  217. package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
  218. package/types/app/runtime/doing.d.ts +27 -0
  219. package/types/app/runtime/doing.d.ts.map +1 -0
  220. package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
  221. package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
  222. package/types/app/runtime/operation-owners.d.ts +137 -0
  223. package/types/app/runtime/operation-owners.d.ts.map +1 -0
  224. package/types/app/runtime/retry-backoff.d.ts +49 -0
  225. package/types/app/runtime/retry-backoff.d.ts.map +1 -0
  226. package/types/app/runtime/workflow-contract.d.ts +79 -0
  227. package/types/app/runtime/workflow-contract.d.ts.map +1 -0
  228. package/types/app/transport/http-client.d.ts.map +1 -1
  229. package/types/cli/common/event-completion.d.ts +26 -0
  230. package/types/cli/common/event-completion.d.ts.map +1 -0
  231. package/types/cli/common/runtime-workers.d.ts +23 -0
  232. package/types/cli/common/runtime-workers.d.ts.map +1 -0
  233. package/types/cli/credentials/ipex.d.ts.map +1 -1
  234. package/types/cli/credentials/vc.d.ts +1 -1
  235. package/types/cli/credentials/vc.d.ts.map +1 -1
  236. package/types/cli/endpoints/did.d.ts.map +1 -1
  237. package/types/cli/endpoints/oobi.d.ts +3 -1
  238. package/types/cli/endpoints/oobi.d.ts.map +1 -1
  239. package/types/cli/identity/challenge.d.ts +1 -1
  240. package/types/cli/identity/challenge.d.ts.map +1 -1
  241. package/types/cli/identity/delegate.d.ts +14 -1
  242. package/types/cli/identity/delegate.d.ts.map +1 -1
  243. package/types/cli/identity/incept.d.ts.map +1 -1
  244. package/types/cli/identity/interact.d.ts.map +1 -1
  245. package/types/cli/identity/rotate.d.ts.map +1 -1
  246. package/types/cli/index.d.ts +3 -1
  247. package/types/cli/index.d.ts.map +1 -1
  248. package/types/cli/messaging/group-join.d.ts +53 -0
  249. package/types/cli/messaging/group-join.d.ts.map +1 -0
  250. package/types/cli/messaging/group-wait.d.ts +34 -0
  251. package/types/cli/messaging/group-wait.d.ts.map +1 -0
  252. package/types/cli/messaging/multisig.d.ts +28 -5
  253. package/types/cli/messaging/multisig.d.ts.map +1 -1
  254. package/types/cli/messaging/root-copy-lines.d.ts +39 -0
  255. package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
  256. package/types/core/cues.d.ts +11 -0
  257. package/types/core/cues.d.ts.map +1 -1
  258. package/types/core/kel/eventing.d.ts.map +1 -1
  259. package/types/core/mailbox/kram-policy.d.ts +14 -0
  260. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  261. package/types/core/mailbox/kraming.d.ts +1 -1
  262. package/types/core/mailbox/kraming.d.ts.map +1 -1
  263. package/types/core/records.d.ts +61 -0
  264. package/types/core/records.d.ts.map +1 -1
  265. package/types/core/routing.d.ts +6 -0
  266. package/types/core/routing.d.ts.map +1 -1
  267. package/types/db/basing.d.ts +8 -2
  268. package/types/db/basing.d.ts.map +1 -1
  269. package/types/db/core/indexeddb-persistence.d.ts +59 -0
  270. package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
  271. package/types/db/indexeddb.d.ts +37 -0
  272. package/types/db/indexeddb.d.ts.map +1 -0
  273. package/types/db/keeping.d.ts +5 -2
  274. package/types/db/keeping.d.ts.map +1 -1
  275. package/types/db/store-lock.d.ts +72 -0
  276. package/types/db/store-lock.d.ts.map +1 -0
  277. package/types/npm/db-indexeddb.d.ts +4 -0
  278. package/types/npm/db-indexeddb.d.ts.map +1 -0
  279. package/types/npm/runtime-web.d.ts +4 -0
  280. package/types/npm/runtime-web.d.ts.map +1 -0
  281. package/types/runtime/index.d.ts +41 -6
  282. package/types/runtime/index.d.ts.map +1 -1
  283. package/types/runtime/web/output-barrier.d.ts +30 -0
  284. package/types/runtime/web/output-barrier.d.ts.map +1 -0
  285. package/types/runtime/web/persistent-storage.d.ts +36 -0
  286. package/types/runtime/web/persistent-storage.d.ts.map +1 -0
  287. package/types/runtime/web.d.ts +11 -0
  288. package/types/runtime/web.d.ts.map +1 -0
  289. package/types/vdr/tel-publication.d.ts +6 -0
  290. package/types/vdr/tel-publication.d.ts.map +1 -1
  291. package/types/version.d.ts +2 -2
  292. package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
  293. package/types/cli/common/tel-completion.d.ts +0 -8
  294. package/types/cli/common/tel-completion.d.ts.map +0 -1
@@ -1,30 +1,43 @@
1
- import { action, spawn } from "effection";
2
- import { resealRegistryRoots, } from "../../app/credentials/root-replicating.js";
3
- import { resolveDelegationCommunicationHab } from "../../app/identity/delegating.js";
4
- import { endpointRoleAccepted, groupSigningMembers, isLocalGroupHab, localGroupMember, proposeGroupEndpointRole, } from "../../app/identity/endpoint-roleing.js";
5
- import { uniqueMembers } from "../../app/multisig/group-members.js";
6
- import { MULTISIG_ICP_ROUTE, MULTISIG_IXN_ROUTE, MULTISIG_REV_ROUTE, MULTISIG_ROT_ROUTE, MULTISIG_VCP_ROUTE, } from "../../app/multisig/grouping.js";
7
- import { approvePendingMultisigProposal, commitAcceptedGroupMembers, eventAccepted, publishProposal, routeForKelEvent, } from "../../app/multisig/multisig-workflows.js";
8
- import { runAgentRuntime } from "../../app/runtime/agent-runtime.js";
9
- import { Receiptor, WitnessReceiptor } from "../../app/witness/receipting.js";
1
+ /**
2
+ * `tufa multisig ...` command implementation.
3
+ *
4
+ * The command surface follows KLI's group lifecycle model and calls the library's
5
+ * proposal API; a command only parses, resolves the user's choices, waits on the
6
+ * Counselor under runtime workers and returns what to print:
7
+ * - `incept`, `rotate`, and `interact` propose a group KEL event (`proposeGroup*`)
8
+ * and publish a `/multisig/*` EXN to the other members
9
+ * - `join` approves one stored proposal the user consents to
10
+ * (`approveGroupProposal`) and signs nothing else; see `group-join.ts`
11
+ */
12
+ import { Ilks } from "cesr-ts";
13
+ import { action } from "effection";
14
+ import { registryEventRef, registryEventStatus, settleRegistryEvent } from "../../app/credentials/registry-settling.js";
15
+ import { telEventStatus, waitForIssuedCredential, waitForTelEvent, } from "../../app/credentials/tel-completion.js";
16
+ import { endpointRoleAccepted, isLocalGroupHab, localGroupMember, proposeGroupEndpointRole, } from "../../app/identity/endpoint-roleing.js";
17
+ import { MULTISIG_REV_ROUTE, MULTISIG_ROT_ROUTE, MULTISIG_VCP_ROUTE } from "../../app/multisig/grouping.js";
18
+ import { routeForKelEvent } from "../../app/multisig/multisig-workflows.js";
19
+ import { proposeGroupInception, proposeGroupInteraction, proposeGroupRotation, settleProposedRotation, } from "../../app/multisig/proposing.js";
20
+ import { observeUntil } from "../../app/runtime/workflow-contract.js";
10
21
  import { ValidationError } from "../../core/errors.js";
11
22
  import { isV2RegistryRoute } from "../../core/exchange/protocol-exchanging.js";
12
23
  import { Roles } from "../../core/roles.js";
13
24
  import { withAgentRuntime } from "../common/context.js";
14
25
  import { loadOptionObject, loadRotateFileOptions, parseBooleanOption, parseCountOption, parseDataItems, parseFileData, parseKeriVersionOption, parseNumberOption, parseStringListOption, parseStringOption, parseThresholdOption, } from "../common/parsing.js";
15
- import { waitForIssuedCredential, waitForTelPublication } from "../common/tel-completion.js";
16
- import { resolveWitnessAuths } from "../common/witness-auth.js";
17
- const MULTISIG_TOPIC = "multisig";
26
+ import { withRuntimeWorkers } from "../common/runtime-workers.js";
27
+ import { joinProposal } from "./group-join.js";
28
+ import { counselInputs, finishAcceptedEvent, supplyDelegationProxy, supplyWitnessAuths, waitForAcceptance, } from "./group-wait.js";
29
+ import { rootCopyLine } from "./root-copy-lines.js";
18
30
  /**
19
31
  * Re-seal held registry roots to members an accepted group rotation added or
20
32
  * rekeyed, as KERIpy `kli multisig rotate|join`. Runs while the command's
21
33
  * runtime worker delivers; every outcome is returned, none fails the rotation.
22
34
  */
23
35
  function* resealAfterRotation(hby, runtime, group, rotation) {
24
- const ghab = hby.habs.get(group), root = runtime.registryRoot;
25
- if (!ghab || !root)
36
+ const replicating = runtime.rootReplicator;
37
+ if (!hby.habs.get(group) || !replicating)
26
38
  return [];
27
- return yield* resealRegistryRoots(root, runtime.postman, runtime.clock, ghab, rotation);
39
+ replicating.prompt(group);
40
+ return (yield* replicating.processOnce()).map(rootCopyLine);
28
41
  }
29
42
  function requireText(value, label) {
30
43
  if (!value) {
@@ -76,8 +89,9 @@ export function* multisigInceptCommand(args) {
76
89
  throw new ValidationError("Multisig inception config must include non-empty aids.");
77
90
  }
78
91
  return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
79
- const member = requireHabByAlias(hby, alias);
80
- const created = hby.makeGroupHab(group, member, smids, rmids, undefined, {
92
+ const sent = yield* proposeGroupInception(proposeDeps(hby, runtime), requireHabByAlias(hby, alias), group, {
93
+ smids,
94
+ rmids,
81
95
  isith: options.isith,
82
96
  nsith: options.nsith,
83
97
  toad: options.toad,
@@ -85,33 +99,13 @@ export function* multisigInceptCommand(args) {
85
99
  delpre: options.delpre,
86
100
  data: options.data ?? [],
87
101
  version: commandArgs.version,
88
- });
89
- const { deliveries, messages } = yield* publishProposal(hby, runtime.protocol, runtime.postman, member, uniqueMembers([...smids, ...rmids]), {
90
- route: MULTISIG_ICP_ROUTE,
91
- attrs: { smids, rmids, ...(options.delpre ? { delegator: options.delpre } : {}) },
92
- }, created.message);
93
- const accepted = yield* waitForGroupAcceptance(hby, runtime, created.serder, multisigApprovalOptions(hby, {
94
- ...commandArgs,
95
- group,
96
- auto: true,
97
- }));
98
- let delegationPhase = null;
99
- if (accepted) {
100
- yield* receiptAcceptedEvent(hby, created.hab.pre, commandArgs, runtime);
101
- delegationPhase = yield* completeDelegationIfNeeded(hby, runtime, created.hab.pre, commandArgs.proxy);
102
- }
103
- return {
104
- route: MULTISIG_ICP_ROUTE,
105
- group: created.hab.pre,
106
- accepted,
107
- messages,
108
- deliveries,
109
- state: hby.db.getState(created.hab.pre),
110
- delegationPhase: delegationPhase,
111
- };
102
+ }, counselInputs(hby, commandArgs.proxy, options.delpre !== undefined, group));
103
+ const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
104
+ const delegationPhase = accepted ? yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs) : null;
105
+ return { ...groupEventResult(hby, sent, accepted), delegationPhase };
112
106
  });
113
107
  }
114
- /** Poll for and approve one pending group multisig event. */
108
+ /** Approve one stored group multisig proposal the user consents to. */
115
109
  export function* multisigJoinCommand(args) {
116
110
  const commandArgs = {
117
111
  name: parseStringOption(args.name, "name"),
@@ -133,53 +127,48 @@ export function* multisigJoinCommand(args) {
133
127
  };
134
128
  const name = requireText(commandArgs.name, "Name");
135
129
  return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
136
- const approval = multisigApprovalOptions(hby, commandArgs);
137
- const result = yield* waitForOneApproval(hby, runtime, approval);
138
- if (!result) {
139
- const local = yield* waitForLocalGroupCompletion(hby, runtime, approval);
130
+ const deadline = approvalDeadline(commandArgs);
131
+ const joined = yield* joinProposal(approvalDeps(hby, runtime), {
132
+ group: commandArgs.group,
133
+ said: commandArgs.said,
134
+ deadline,
135
+ confirm: proposal => approvePrompt(commandArgs, proposal),
136
+ groupAlias: proposal => chooseGroupAlias(hby, commandArgs, proposal.group),
137
+ registryName: proposal => chooseRegistryName(commandArgs, proposal.embedded),
138
+ inputs: () => ({ fallbackAfterMs: 0 }),
139
+ });
140
+ if (!joined) {
141
+ const local = yield* completeLocalGroupEvent(hby, runtime, commandArgs, deadline);
140
142
  if (!local) {
141
143
  throw new ValidationError("No matching stored multisig proposal was available to join.");
142
144
  }
143
- if (local.accepted) {
144
- yield* receiptAcceptedEvent(hby, local.group, commandArgs, runtime);
145
- if (local.route === MULTISIG_ICP_ROUTE || local.route === MULTISIG_ROT_ROUTE) {
146
- yield* completeDelegationIfNeeded(hby, runtime, local.group, commandArgs.proxy);
147
- }
148
- if (local.route === MULTISIG_ROT_ROUTE) {
149
- return { ...local, rootCopies: yield* resealAfterRotation(hby, runtime, local.group, local.embedded) };
150
- }
151
- }
152
145
  return local;
153
146
  }
147
+ const { event, ...result } = joined.result;
154
148
  if (result.tel) {
155
149
  const { publication, reger } = runtime.vdr;
156
150
  const tel = result.tel;
157
151
  if (result.route === MULTISIG_VCP_ROUTE || result.route === MULTISIG_REV_ROUTE) {
158
- yield* waitForTelPublication(publication, tel.pre, tel.sn, approval.deadline);
152
+ yield* waitForTelEvent({ publication }, tel.pre, tel.sn, { deadline });
159
153
  result.accepted = reger.tels.getOn(tel.pre, tel.sn)?.qb64 === result.embedded;
160
154
  }
161
155
  else {
162
- yield* waitForIssuedCredential(publication, tel.pre, approval.deadline);
156
+ yield* waitForIssuedCredential({ publication }, tel.pre, { deadline });
163
157
  result.accepted = reger.saved.get(tel.pre) !== null;
164
158
  }
165
- tel.publicationComplete = publication.complete(tel.pre, tel.sn);
159
+ tel.publicationComplete = telEventStatus({ publication }, tel.pre, tel.sn).state === "complete";
166
160
  return result;
167
161
  }
168
162
  if (isV2RegistryRoute(result.route)) {
169
- result.accepted = yield* settleRegistryApproval(hby, runtime, result, commandArgs, approval.deadline);
163
+ supplyWitnessAuths(hby, runtime, event, commandArgs);
164
+ result.accepted = yield* settleRegistryApproval(hby, runtime, result, deadline);
170
165
  return result;
171
166
  }
172
- if (result.accepted) {
173
- yield* receiptAcceptedEvent(hby, result.group, commandArgs, runtime);
174
- if (result.route === MULTISIG_ICP_ROUTE
175
- || result.route === MULTISIG_ROT_ROUTE) {
176
- yield* completeDelegationIfNeeded(hby, runtime, result.group, commandArgs.proxy);
177
- }
178
- if (result.route === MULTISIG_ROT_ROUTE) {
179
- return { ...result, rootCopies: yield* resealAfterRotation(hby, runtime, result.group, result.embedded) };
180
- }
181
- }
182
- return result;
167
+ if (!event)
168
+ return result;
169
+ // No scheduling point separates the approval from here, so the Counselor has not yet used its defaults.
170
+ supplyDelegationProxy(hby, runtime, event, commandArgs.proxy);
171
+ return yield* finishJoinedEvent(hby, runtime, result, event, commandArgs);
183
172
  });
184
173
  }
185
174
  /** Create or begin one group interaction event. */
@@ -204,26 +193,11 @@ export function* multisigInteractCommand(args) {
204
193
  const group = requireText(commandArgs.group ?? commandArgs.alias, "Group");
205
194
  const data = parseDataItems(commandArgs.data);
206
195
  return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
207
- const created = hby.interactGroupHab(group, undefined, { data, version: commandArgs.version });
208
- const smids = groupSigningMembers(hby, created.hab.pre);
209
- const { deliveries, messages } = yield* publishProposal(hby, runtime.protocol, runtime.postman, localGroupMember(hby, created.hab.pre), smids, { route: MULTISIG_IXN_ROUTE, attrs: { gid: created.hab.pre, smids } }, created.message);
210
- const accepted = yield* waitForGroupAcceptance(hby, runtime, created.serder, multisigApprovalOptions(hby, {
211
- ...commandArgs,
212
- group,
213
- auto: true,
214
- }));
215
- if (accepted) {
216
- yield* receiptAcceptedEvent(hby, created.hab.pre, commandArgs, runtime);
217
- }
218
- return {
219
- route: MULTISIG_IXN_ROUTE,
220
- group: created.hab.pre,
221
- accepted,
222
- messages,
223
- deliveries,
224
- state: hby.db.getState(created.hab.pre),
225
- delegationPhase: null,
226
- };
196
+ const sent = yield* proposeGroupInteraction(proposeDeps(hby, runtime), requireGroupHab(hby, group), data, { fallbackAfterMs: 0 }, commandArgs.version);
197
+ const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
198
+ if (accepted)
199
+ yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs);
200
+ return groupEventResult(hby, sent, accepted);
227
201
  });
228
202
  }
229
203
  /** Rotate or begin rotation of one group identifier. */
@@ -258,7 +232,10 @@ export function* multisigRotateCommand(args) {
258
232
  const group = requireText(commandArgs.group ?? commandArgs.alias, "Group");
259
233
  const options = mergeRotateOptions(commandArgs);
260
234
  return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
261
- const rotated = hby.rotateGroupHab(group, commandArgs.smids, commandArgs.rmids, {
235
+ const groupHab = requireGroupHab(hby, group);
236
+ const sent = yield* proposeGroupRotation(proposeDeps(hby, runtime), groupHab, {
237
+ smids: commandArgs.smids,
238
+ rmids: commandArgs.rmids,
262
239
  isith: options.isith,
263
240
  nsith: options.nsith,
264
241
  toad: options.toad,
@@ -266,34 +243,17 @@ export function* multisigRotateCommand(args) {
266
243
  adds: options.witsAdd,
267
244
  data: options.data ?? [],
268
245
  version: commandArgs.version,
269
- });
270
- const smids = commandArgs.smids?.length ? commandArgs.smids : groupSigningMembers(hby, rotated.hab.pre);
271
- const rmids = commandArgs.rmids?.length ? commandArgs.rmids : smids;
272
- const { deliveries, messages } = yield* publishProposal(hby, runtime.protocol, runtime.postman, localGroupMember(hby, rotated.hab.pre), uniqueMembers([...smids, ...rmids]), { route: MULTISIG_ROT_ROUTE, attrs: { gid: rotated.hab.pre, smids, rmids } }, rotated.message);
273
- const accepted = yield* waitForGroupAcceptance(hby, runtime, rotated.serder, multisigApprovalOptions(hby, {
274
- ...commandArgs,
275
- group,
276
- auto: true,
277
- }));
246
+ }, counselInputs(hby, commandArgs.proxy, !!hby.db.getKever(groupHab.pre)?.delpre, group));
247
+ const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
278
248
  let delegationPhase = null;
279
249
  let rootCopies = [];
280
250
  if (accepted) {
281
251
  // The proposer's own acceptance must commit the rotated membership as a joiner's does.
282
- commitAcceptedGroupMembers(hby, rotated.serder, smids, rmids);
283
- yield* receiptAcceptedEvent(hby, rotated.hab.pre, commandArgs, runtime);
284
- delegationPhase = yield* completeDelegationIfNeeded(hby, runtime, rotated.hab.pre, commandArgs.proxy);
285
- rootCopies = yield* resealAfterRotation(hby, runtime, rotated.hab.pre, rotated.serder.said);
252
+ settleProposedRotation({ hby }, sent);
253
+ delegationPhase = yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs);
254
+ rootCopies = yield* resealAfterRotation(hby, runtime, sent.group, sent.event.said);
286
255
  }
287
- return {
288
- route: MULTISIG_ROT_ROUTE,
289
- group: rotated.hab.pre,
290
- accepted,
291
- messages,
292
- deliveries,
293
- state: hby.db.getState(rotated.hab.pre),
294
- delegationPhase: delegationPhase,
295
- rootCopies,
296
- };
256
+ return { ...groupEventResult(hby, sent, accepted), delegationPhase, rootCopies };
297
257
  });
298
258
  }
299
259
  /** Propose one group multisig reply such as `/end/role/add`. */
@@ -318,12 +278,12 @@ export function* multisigRpyCommand(args) {
318
278
  return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
319
279
  const groupHab = requireHabByAlias(hby, group);
320
280
  const result = yield* proposeGroupEndpointRole(hby, runtime.protocol, runtime.postman, groupHab, { eid, role, allow: commandArgs.allow });
281
+ // The reply is accepted when the other members' contributions reach this runtime.
321
282
  const accepted = commandArgs.approvalTimeoutSeconds > 0
322
- ? yield* waitForReplyAcceptance(hby, runtime, groupHab.pre, role, eid, multisigApprovalOptions(hby, {
323
- ...commandArgs,
324
- group: groupHab.pre,
325
- auto: true,
326
- }))
283
+ ? yield* observeUntil(() => endpointRoleAccepted(hby, groupHab.pre, role, eid), {
284
+ timeoutMs: Math.max(0, approvalDeadline(commandArgs) - Date.now()),
285
+ pollMs: 250,
286
+ })
327
287
  : result.accepted;
328
288
  return { ...result, accepted };
329
289
  });
@@ -340,13 +300,7 @@ function* withMultisigRuntime(args, name, use) {
340
300
  const signer = selected && isLocalGroupHab(context.hby, selected)
341
301
  ? localGroupMember(context.hby, selected.pre)
342
302
  : selected;
343
- const worker = yield* spawn(() => runAgentRuntime(context.runtime, { hab: signer }));
344
- try {
345
- return yield* use(context);
346
- }
347
- finally {
348
- yield* worker.halt();
349
- }
303
+ return yield* withRuntimeWorkers(context.runtime, { hab: signer }, () => use(context));
350
304
  });
351
305
  }
352
306
  function requireHabByAlias(hby, alias) {
@@ -356,6 +310,12 @@ function requireHabByAlias(hby, alias) {
356
310
  }
357
311
  return hab;
358
312
  }
313
+ function requireGroupHab(hby, group) {
314
+ const hab = hby.habByName(group);
315
+ if (!hab)
316
+ throw new ValidationError(`Group alias ${group} is invalid.`);
317
+ return hab;
318
+ }
359
319
  function mergeRotateOptions(args) {
360
320
  const options = args.file && args.file !== "" ? loadRotateFileOptions(args.file) : {};
361
321
  if (args.isith !== undefined) {
@@ -384,23 +344,76 @@ function mergeRotateOptions(args) {
384
344
  }
385
345
  return options;
386
346
  }
387
- function multisigApprovalOptions(hby, args) {
388
- // An existing group constrains approval; a new alias only names the group
389
- // after its inception proposal is selected and approved.
347
+ /** Deadline of this command's approval wait, measured from when the wait starts. */
348
+ function approvalDeadline(args) {
349
+ return Date.now() + args.approvalTimeoutSeconds * 1000;
350
+ }
351
+ function proposeDeps(hby, runtime) {
352
+ return { hby, protocol: runtime.protocol, postman: runtime.postman, counselor: runtime.counselor };
353
+ }
354
+ function approvalDeps(hby, runtime) {
390
355
  return {
391
- group: args.group ? groupHabByAliasOrPrefix(hby, args.group)?.pre : undefined,
392
- said: args.said,
393
- deadline: Date.now() + args.approvalTimeoutSeconds * 1000,
394
- callbacks: multisigApprovalCallbacks(hby, args),
356
+ hby,
357
+ exc: runtime.exc,
358
+ reactor: runtime.reactor,
359
+ protocol: runtime.protocol,
360
+ postman: runtime.postman,
361
+ notifier: runtime.notifier,
362
+ registryStore: runtime.acdc?.store ?? null,
363
+ vdr: runtime.vdr,
364
+ counselor: runtime.counselor,
395
365
  };
396
366
  }
397
- function multisigApprovalCallbacks(hby, args) {
367
+ function groupEventResult(hby, sent, accepted) {
398
368
  return {
399
- approveProposal: (context) => approvePrompt(args, context),
400
- chooseGroupAlias: (groupPre) => chooseGroupAlias(hby, args, groupPre),
401
- chooseRegistryName: (regk) => chooseRegistryName(args, regk),
369
+ route: sent.route,
370
+ group: sent.group,
371
+ accepted,
372
+ messages: sent.messages,
373
+ deliveries: sent.deliveries,
374
+ state: hby.db.getState(sent.group),
375
+ delegationPhase: null,
402
376
  };
403
377
  }
378
+ /**
379
+ * A joined event that this approval completed has nothing left to wait for from other
380
+ * members; finish its receipts and delegation. One that still needs other members
381
+ * returns at once and stays counseled in the store.
382
+ */
383
+ function* finishJoinedEvent(hby, runtime, result, event, args) {
384
+ if (!result.accepted)
385
+ return result;
386
+ yield* finishAcceptedEvent(hby, runtime, event, args);
387
+ if (result.route !== MULTISIG_ROT_ROUTE)
388
+ return result;
389
+ return { ...result, rootCopies: yield* resealAfterRotation(hby, runtime, result.group, result.embedded) };
390
+ }
391
+ /** Resume a locally authored group event named by `--group` when no proposal was left to join. */
392
+ function* completeLocalGroupEvent(hby, runtime, args, deadline) {
393
+ if (!args.group || args.said)
394
+ return null;
395
+ const groupHab = hby.habByName(args.group) ?? hby.habs.get(args.group);
396
+ if (!groupHab?.pre || !isLocalGroupHab(hby, groupHab))
397
+ return null;
398
+ const serder = hby.db.getKever(groupHab.pre)?.serder ?? hby.db.getEvtSerder(groupHab.pre, groupHab.pre);
399
+ const route = serder && routeForKelEvent(serder);
400
+ if (!serder?.said || serder.sn === null || !route)
401
+ return null;
402
+ const event = { pre: groupHab.pre, sn: serder.sn, said: serder.said };
403
+ const delegated = serder.ilk === Ilks.dip || serder.ilk === Ilks.drt;
404
+ runtime.counselor.start(event, counselInputs(hby, args.proxy, delegated, groupHab.pre));
405
+ const accepted = yield* waitForAcceptance(hby, runtime, event, deadline);
406
+ const result = {
407
+ route,
408
+ said: "",
409
+ embedded: serder.said,
410
+ group: groupHab.pre,
411
+ accepted,
412
+ deliveries: [],
413
+ messages: [],
414
+ };
415
+ return yield* finishJoinedEvent(hby, runtime, result, event, args);
416
+ }
404
417
  function chooseRegistryName(args, regk) {
405
418
  if (args.registryName) {
406
419
  return args.registryName;
@@ -439,70 +452,38 @@ function chooseGroupAlias(hby, args, groupPre) {
439
452
  return group;
440
453
  }
441
454
  }
442
- function approvePrompt(args, context) {
455
+ /** Ask whether to join a proposal; `--auto` answers yes without asking, only for the join command that set it. */
456
+ export function approvePrompt(args, proposal) {
443
457
  if (args.auto) {
444
458
  return true;
445
459
  }
446
460
  console.log(JSON.stringify({
447
- route: context.route,
448
- group: context.group,
449
- embedded: context.embedded,
461
+ route: `/multisig/${proposal.kind}`,
462
+ group: proposal.group,
463
+ embedded: proposal.embedded,
450
464
  }, null, 2));
451
465
  const yn = prompt("\nJoin [Y|n]? ");
452
466
  return yn === null || yn === "" || yn === "y" || yn === "Y";
453
467
  }
454
- /**
455
- * Collect witness receipts for the current accepted multisig event using explicit runtime collaborators.
456
- *
457
- * @param hby Borrowed local identities and accepted-state stores.
458
- * @param pre Accepted group event subject.
459
- * @param args Witness authentication and HTTP endpoint mode choices.
460
- * @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
461
- * @param sn Accepted event ordinal to receipt; defaults to the current event.
462
- */
463
- function* receiptAcceptedEvent(hby, pre, args, runtime, sn) {
464
- const kever = hby.db.getKever(pre);
465
- if (!kever || kever.wits.length === 0) {
466
- return;
467
- }
468
- const auths = resolveWitnessAuths(kever.wits, args.code ?? [], {
469
- codeTime: args.codeTime,
470
- promptMissing: args.authenticate ?? false,
471
- });
472
- if (args.endpoint) {
473
- const receiptor = new Receiptor(hby, runtime.protocol, runtime.http, runtime.clock);
474
- yield* receiptor.receipt(pre, { sn: sn ?? kever.sn, auths });
475
- }
476
- else {
477
- const witDoer = new WitnessReceiptor(hby, runtime.protocol, runtime.http, runtime.clock);
478
- yield* witDoer.submit(pre, { sn: sn ?? kever.sn, auths });
479
- }
480
- }
481
468
  /**
482
469
  * Settle one approved v2 RIP/BUP as KERIpy's join Counselor does: wait for the group's KEL acceptance of
483
- * the exact anchor, converge that anchor's witness receipts, and let the anchor escrow accept the TEL event.
484
- * The TEL event needs a fully witnessed anchor, so receipting only after TEL acceptance would never accept it.
470
+ * the exact anchor and let the anchor escrow accept the TEL event. The Counselor, started by the approval,
471
+ * converges the anchor's witness receipts, which the TEL event needs.
485
472
  *
486
473
  * @returns Whether the approved TEL event is accepted before the approval deadline.
487
474
  */
488
- function* settleRegistryApproval(hby, runtime, result, args, deadline) {
475
+ function* settleRegistryApproval(hby, runtime, result, deadline) {
489
476
  const store = runtime.acdc?.store, tel = store?.event(result.embedded);
490
477
  const anc = hby.db.exns.get([result.said])?.sad?.a?.anc;
491
478
  if (!store || !tel || typeof tel.sad?.n !== "string" || typeof anc !== "string")
492
479
  return result.accepted;
493
- const regid = tel.ilk === "rip" ? tel.said : tel.regid, sn = Number(BigInt(`0x${tel.sad.n}`));
494
- let receipted = false;
480
+ const anchor = hby.db.getEvtSerder(result.group, anc);
481
+ const ref = registryEventRef(tel, { pre: result.group, sn: anchor?.sn ?? 0, said: anc });
482
+ const deps = { db: hby.db, store, protocol: runtime.protocol };
495
483
  while (true) {
496
- if (store.seqEvent(regid, sn)?.said === tel.said)
484
+ if (registryEventStatus(deps, ref).state === "accepted")
497
485
  return true;
498
- const anchor = hby.db.getEvtSerder(result.group, anc);
499
- if (!receipted && anchor && hby.db.kels.getLast(result.group, anchor.sn) === anc) {
500
- if (!hby.db.fullyWitnessed(anchor))
501
- yield* receiptAcceptedEvent(hby, result.group, args, runtime, anchor.sn);
502
- receipted = true;
503
- }
504
- yield* runtime.protocol.processEscrowsOnce();
505
- if (store.seqEvent(regid, sn)?.said === tel.said)
486
+ if ((yield* settleRegistryEvent(deps, ref)).state === "accepted")
506
487
  return true;
507
488
  if (Date.now() >= deadline)
508
489
  return false;
@@ -517,108 +498,6 @@ function nonNegativeNumber(value, fallback, label) {
517
498
  }
518
499
  return parsed;
519
500
  }
520
- /** Approve stored proposals until the target event is accepted or the deadline expires. */
521
- function* waitForGroupAcceptance(hby, runtime, serder, options) {
522
- if (eventAccepted(hby, serder)) {
523
- return true;
524
- }
525
- while (true) {
526
- yield* approvePendingMultisigProposal(hby, runtime, options);
527
- if (eventAccepted(hby, serder)) {
528
- return true;
529
- }
530
- if (Date.now() >= options.deadline)
531
- break;
532
- yield* sleep(Math.min(250, options.deadline - Date.now()));
533
- }
534
- return eventAccepted(hby, serder);
535
- }
536
- /** Wait for one stored proposal while the command host owns background progress. */
537
- function* waitForOneApproval(hby, runtime, options) {
538
- while (true) {
539
- const result = yield* approvePendingMultisigProposal(hby, runtime, options);
540
- if (result) {
541
- return result;
542
- }
543
- if (Date.now() >= options.deadline)
544
- break;
545
- yield* sleep(Math.min(250, options.deadline - Date.now()));
546
- }
547
- return null;
548
- }
549
- /** Wait for a locally authored group event to complete through stored approvals. */
550
- function* waitForLocalGroupCompletion(hby, runtime, options) {
551
- if (!options.group || options.said) {
552
- return null;
553
- }
554
- const groupHab = groupHabByAliasOrPrefix(hby, options.group);
555
- if (!groupHab?.pre) {
556
- return null;
557
- }
558
- const serder = localGroupJoinSerder(hby, groupHab.pre);
559
- if (!serder) {
560
- return null;
561
- }
562
- const route = routeForKelEvent(serder);
563
- if (!route) {
564
- return null;
565
- }
566
- const accepted = yield* waitForGroupAcceptance(hby, runtime, serder, options);
567
- return {
568
- route,
569
- said: "",
570
- embedded: serder.said ?? "",
571
- group: groupHab.pre,
572
- accepted,
573
- deliveries: [],
574
- messages: [],
575
- };
576
- }
577
- /** Approve stored proposals until the endpoint reply is accepted or the deadline expires. */
578
- function* waitForReplyAcceptance(hby, runtime, groupPre, role, eid, options) {
579
- if (endpointRoleAccepted(hby, groupPre, role, eid)) {
580
- return true;
581
- }
582
- while (true) {
583
- yield* approvePendingMultisigProposal(hby, runtime, options);
584
- if (endpointRoleAccepted(hby, groupPre, role, eid)) {
585
- return true;
586
- }
587
- if (Date.now() >= options.deadline)
588
- break;
589
- yield* sleep(Math.min(250, options.deadline - Date.now()));
590
- }
591
- return endpointRoleAccepted(hby, groupPre, role, eid);
592
- }
593
- /** Complete the delegation workflow for an accepted delegated group event. */
594
- function* completeDelegationIfNeeded(hby, runtime, pre, proxy) {
595
- const kever = hby.db.getKever(pre);
596
- if (!kever?.delpre) {
597
- return null;
598
- }
599
- const communicationHab = resolveDelegationCommunicationHab(hby, proxy);
600
- if (!communicationHab) {
601
- throw new ValidationError(`Delegated group event for ${pre} requires --proxy <alias>.`);
602
- }
603
- runtime.delegating.beginLatest(pre, kever.sn, { communicationHab });
604
- const deadline = Date.now() + 120_000;
605
- while (!runtime.delegating.complete(pre, kever.sn)) {
606
- if (Date.now() >= deadline)
607
- throw new Error("Runtime did not converge within 120000ms.");
608
- yield* sleep(Math.min(250, deadline - Date.now()));
609
- }
610
- return runtime.delegating.workflowStatus(pre, kever.sner.numh).phase;
611
- }
612
- function groupHabByAliasOrPrefix(hby, group) {
613
- return hby.habByName(group) ?? hby.habs.get(group) ?? null;
614
- }
615
- function localGroupJoinSerder(hby, groupPre) {
616
- const kever = hby.db.getKever(groupPre);
617
- if (kever?.serder) {
618
- return kever.serder;
619
- }
620
- return hby.db.getEvtSerder(groupPre, groupPre);
621
- }
622
501
  function* sleep(ms) {
623
502
  yield* action((resolve) => {
624
503
  const id = setTimeout(resolve, ms);
@@ -0,0 +1,31 @@
1
+ /** The operator command that resends a copy automatic replication did not send. */
2
+ export const RootCopyRecoveryCommand = "tufa vc registry root send";
3
+ function errorText(error) {
4
+ return error instanceof Error ? error.message : String(error);
5
+ }
6
+ /** Map one typed copy result to its `root_copy` line. */
7
+ export function rootCopyLine(result) {
8
+ const line = {
9
+ phase: "root_copy",
10
+ gid: result.group,
11
+ registry: result.registry,
12
+ sender: result.sender,
13
+ recipient: result.recipient,
14
+ transmitted: false,
15
+ };
16
+ if (result.exchange !== undefined)
17
+ line.exchange = result.exchange;
18
+ if (result.kin === "sent")
19
+ return { ...line, transmitted: true };
20
+ return { ...line, error: errorText(result.error), recovery: RootCopyRecoveryCommand };
21
+ }
22
+ /** Map an unexaminable rotation to its `root_copy` line. */
23
+ export function rootResealLine(examination) {
24
+ return {
25
+ phase: "root_copy",
26
+ gid: examination.group,
27
+ rotation: examination.rotation,
28
+ transmitted: false,
29
+ error: examination.error.message,
30
+ };
31
+ }