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
@@ -1,15 +1,14 @@
1
1
  import { WireParseError } from "cesr-ts";
2
2
  import { call, resource, spawn, suspend } from "effection";
3
- import { Dhke } from "../../acdc/dhking.js";
4
3
  import { RegistryObserver } from "../../acdc/observing.js";
5
4
  import { createRegery as createAcdcRegery } from "../../acdc/registraring.js";
6
5
  import { RegistryRoot } from "../../acdc/salting.js";
7
- import { Unblind } from "../../acdc/unblinding.js";
8
6
  import { Deck } from "../../core/deck.js";
9
- import { DatabaseNotOpenError, ValidationError } from "../../core/errors.js";
7
+ import { DatabaseNotOpenError } from "../../core/errors.js";
10
8
  import { Kevery } from "../../core/kel/eventing.js";
11
9
  import { Kramer } from "../../core/mailbox/kraming.js";
12
10
  import { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../../core/mailbox/mailbox-topics.js";
11
+ import { Roles } from "../../core/roles.js";
13
12
  import { Revery } from "../../core/routing.js";
14
13
  import { openOwner } from "../../db/core/store-owner.js";
15
14
  import { Mailboxer } from "../../db/mailbox/mailboxing.js";
@@ -28,10 +27,12 @@ import { loadChallengeHandlers } from "../identity/challenging.js";
28
27
  import { Anchorer, loadDelegationHandlers } from "../identity/delegating.js";
29
28
  import { loadIpexHandlers } from "../ipex/ipexing.js";
30
29
  import { ForwardHandler } from "../mailbox/forward-handler.js";
30
+ import { KEL_PUBLISHER_PACING, KelPublisher, kelPublisherDo } from "../mailbox/kel-publisher.js";
31
31
  import { MailboxDirector } from "../mailbox/mailbox-director.js";
32
- import { MailboxPoller } from "../mailbox/mailbox-poller.js";
32
+ import { MAILBOX_POLLER_PACING, MailboxPoller, } from "../mailbox/mailbox-poller.js";
33
33
  import { mailboxerOptionsForHabery } from "../mailbox/mailboxing.js";
34
34
  import { mailboxTopicForRoute } from "../mailbox/topic-routing.js";
35
+ import { Counselor } from "../multisig/counseling.js";
35
36
  import { loadMultisigHandlers } from "../multisig/grouping.js";
36
37
  import { noterOptionsForHabery, Notifier } from "../notifications/notifying.js";
37
38
  import { Signaler } from "../notifications/signaling.js";
@@ -41,7 +42,11 @@ import { QueryReplies } from "../queries/query-replies.js";
41
42
  import { WitnessInquisitor } from "../queries/witness-inquisitor.js";
42
43
  import { Receiptor } from "../witness/receipting.js";
43
44
  import { cueDo } from "./cue-runtime.js";
44
- import { runtimeTurn } from "./runtime-turn.js";
45
+ import { doEvery, PROTOCOL_PACING } from "./doing.js";
46
+ import { IpexAuxiliaries } from "./ipex-auxiliaries.js";
47
+ import { composeOwners, operationOwnersDo, OWNER_PACING, } from "./operation-owners.js";
48
+ import { signalerChangeSink } from "./workflow-contract.js";
49
+ import { observeUntil } from "./workflow-contract.js";
45
50
  /**
46
51
  * Create the shared runtime composition root used by CLI commands and
47
52
  * `tufa agent`.
@@ -59,15 +64,6 @@ import { runtimeTurn } from "./runtime-turn.js";
59
64
  * @throws Dependency mismatch/acquisition errors propagate after owned resource cleanup.
60
65
  */
61
66
  export function* createAgentRuntime(hby, http, clock, options = {}) {
62
- const selected = options.ipexAuxiliary;
63
- if (selected) {
64
- if (options.kram?.enabled !== true) {
65
- throw new ValidationError("IPEX auxiliary runtime requires explicitly enabled KRAM");
66
- }
67
- if (!selected.hab.pre || hby.habs.get(selected.hab.pre) !== selected.hab) {
68
- throw new ValidationError("IPEX auxiliary runtime requires its actual local habitat");
69
- }
70
- }
71
67
  const injectedSignaler = options.signaler ?? options.notifier?.signaler;
72
68
  if ((options.notifier && options.notifier.signator !== hby.signator)
73
69
  || (options.noter && options.notifier && options.noter !== options.notifier.noter)
@@ -102,8 +98,6 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
102
98
  const acdc = options.acdc ?? (!hby.readonly ? (yield* openAcdcRegeryForHabery(hby)) : null);
103
99
  const ownsAcdcRegery = options.acdc === undefined && acdc !== null;
104
100
  const acdcRegery = acdc;
105
- if (selected && !acdc)
106
- throw new ValidationError("IPEX auxiliary runtime requires a v2 registry");
107
101
  // Acquire after stores, before processors/consumers: reverse teardown joins consumers, clears cues, closes stores.
108
102
  const cues = yield* resource(function* (provide) {
109
103
  const owned = new Deck();
@@ -135,25 +129,21 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
135
129
  const kvy = new Kevery(hby.db, { cues: protocolCues, rvy: revery, messagePolicy: options.messagePolicy, kramer });
136
130
  const exc = new Exchanger(hby, { cues: protocolCues, now });
137
131
  const registry = acdc ? new RegistryObserver(hby.db, acdc.store) : null;
138
- const ipexAuxiliary = selected && registry
132
+ // Every runtime with a v2 registry store owns the per-identifier DH and Unblind owners: one dispatch path.
133
+ const ipex = registry
139
134
  ? yield* resource(function* (provide) {
140
- const auxiliary = selected.kind === "dhke"
141
- ? { kind: "dhke", owner: new Dhke({ hab: selected.hab, exc, registryStore: registry.store, rvy: revery, now }) }
142
- : {
143
- kind: "unblind",
144
- owner: new Unblind({ hab: selected.hab, exc, registry, states: selected.states, rvy: revery, now }),
145
- };
135
+ const owners = new IpexAuxiliaries(exc, registry, revery, now, options.kram?.enabled === true);
146
136
  try {
147
- revery.rtr.addRoute(auxiliary.kind === "dhke" ? Dhke.Route : Unblind.Route, auxiliary.owner);
148
- yield* provide(auxiliary);
137
+ owners.registerReplyRoutes(revery.rtr);
138
+ yield* provide(owners);
149
139
  }
150
140
  finally {
151
- auxiliary.owner.close();
141
+ owners.close();
152
142
  }
153
143
  })
154
144
  : null;
155
145
  const replies = new QueryReplies(cues);
156
- const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies, ipexAuxiliary?.owner);
146
+ const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies, ipex ?? undefined);
157
147
  const reactor = new Reactor(protocol);
158
148
  loadChallengeHandlers(hby.db, exc);
159
149
  loadDelegationHandlers(hby, exc, notifier);
@@ -165,7 +155,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
165
155
  grantWalk: options.grantWalk,
166
156
  });
167
157
  // Construction adopts stored copies an earlier handler-less Exchanger left unescrowed.
168
- const registryRoot = options.registryRoots !== "refuse" && acdc ? new RegistryRoot(hby, acdc, notifier) : null;
158
+ const registryRoot = options.registryRoots !== "refuse" && acdc
159
+ ? new RegistryRoot(hby, acdc, notifier, options.operationStores?.changes ?? (signaler ? signalerChangeSink(signaler) : undefined))
160
+ : null;
169
161
  if (registryRoot)
170
162
  exc.addHandler(registryRoot);
171
163
  const mailboxDirector = yield* resource(function* (provide) {
@@ -204,7 +196,25 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
204
196
  // Copies ride the credential topic; the refuser adds no mailbox topic of its own.
205
197
  if (options.registryRoots === "refuse")
206
198
  exc.addHandler(new RouteRefuser(RegistryRoot.Route));
207
- const mailboxPoller = new MailboxPoller(hby, mailboxDirector, http, clock, {});
199
+ const kelPublisher = new KelPublisher({
200
+ hby,
201
+ http,
202
+ clock,
203
+ changes: signaler ? signalerChangeSink(signaler) : undefined,
204
+ retry: options.kelPublishRetry,
205
+ });
206
+ const mailboxPoller = new MailboxPoller(hby, mailboxDirector, http, clock, {
207
+ onPolled: (pre, mailbox) => kelPublisher.prompt(pre, mailbox),
208
+ onUnauthorized: (pre, mailbox) => kelPublisher.repair(pre, mailbox),
209
+ timeouts: options.mailboxPolling,
210
+ });
211
+ // A mailbox role accepted from a reply (a group member's approved add, an OOBI) is acted on at the next tock.
212
+ revery.onEndRole = (cid, role) => {
213
+ if (role !== Roles.mailbox)
214
+ return;
215
+ kelPublisher.prompt(cid);
216
+ mailboxPoller.prompt(cid);
217
+ };
208
218
  for (const topic of [
209
219
  DELEGATE_MAILBOX_TOPIC,
210
220
  CREDENTIAL_MAILBOX_TOPIC,
@@ -224,6 +234,36 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
224
234
  }
225
235
  });
226
236
  const delegating = new Anchorer(hby, postman, querying, protocol, http, clock);
237
+ // Group receipting reaches TCP-only witnesses as `WitnessReceiptor` does, as KERIpy's Counselor does.
238
+ const groupReceiptor = new Receiptor(hby, protocol, http, clock);
239
+ const counselor = new Counselor(hby, {
240
+ receipt: (pre, options) => groupReceiptor.receipt(pre, { ...options, allowTcp: true }),
241
+ get: (pre, options) => groupReceiptor.get(pre, options),
242
+ }, clock, signaler ? signalerChangeSink(signaler) : undefined, { anchorer: delegating, querying }, {
243
+ rotated: (cue) => {
244
+ kelPublisher.rotated.push(cue);
245
+ owned?.rootReplicator?.prompt(cue.pre);
246
+ },
247
+ }, options.counselorReceiptRetry);
248
+ const owned = acdc && ipex
249
+ ? composeOwners({
250
+ hby,
251
+ acdc,
252
+ exc,
253
+ protocol,
254
+ reactor,
255
+ postman,
256
+ receiptor: new Receiptor(hby, protocol, http, clock),
257
+ ipex,
258
+ clock,
259
+ registryRoot,
260
+ mux,
261
+ counselor,
262
+ retry: options.operationRetry,
263
+ queryResendMs: options.issuanceQueryResendMs,
264
+ changes: signaler ? signalerChangeSink(signaler) : undefined,
265
+ }, options.operationStores)
266
+ : null;
227
267
  const oobiery = new Oobiery(hby, protocol, revery, http, cues);
228
268
  oobiery.registerReplyRoutes(revery.rtr);
229
269
  const authenticator = new Authenticator(hby, http);
@@ -239,7 +279,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
239
279
  replies,
240
280
  exc,
241
281
  mux,
242
- ipexAuxiliary,
282
+ ipex,
283
+ operations: owned?.operations ?? null,
284
+ rootReplicator: owned?.rootReplicator ?? null,
243
285
  oobiery,
244
286
  authenticator,
245
287
  mailboxDirector,
@@ -247,6 +289,12 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
247
289
  mailboxPoller,
248
290
  postman,
249
291
  delegating,
292
+ counselor,
293
+ kelPublisher,
294
+ ownerPacing: options.ownerPacing ?? OWNER_PACING,
295
+ publisherPacing: options.publisherPacing ?? KEL_PUBLISHER_PACING,
296
+ protocolPacing: options.protocolPacing ?? PROTOCOL_PACING,
297
+ pollerPacing: options.pollerPacing ?? MAILBOX_POLLER_PACING,
250
298
  querying,
251
299
  replyStreams,
252
300
  vdr,
@@ -264,7 +312,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
264
312
  const failures = [];
265
313
  const cleanup = [
266
314
  function* () {
267
- ipexAuxiliary?.owner.close();
315
+ ipex?.close();
268
316
  },
269
317
  function* () {
270
318
  yield* querying.close();
@@ -485,6 +533,7 @@ export function runtimePendingState(runtime) {
485
533
  delegationPending: runtime.hby.db.dpwe.cnt() > 0
486
534
  || runtime.hby.db.dune.cnt() > 0
487
535
  || runtime.hby.db.dpub.cnt() > 0,
536
+ groupPending: runtime.hby.db.gpse.cnt() > 0 || runtime.hby.db.gdee.cnt() > 0 || runtime.hby.db.gpwe.cnt() > 0,
488
537
  queriesPending: runtime.querying.hasPendingWork(),
489
538
  deliveriesPending: runtime.querying.hasPendingDelivery || runtime.postman.hasPending,
490
539
  };
@@ -506,6 +555,9 @@ export function runtimeHasPendingWork(runtime) {
506
555
  }
507
556
  /**
508
557
  * Return true once OOBI acceptance and its ingress/query dependencies settle.
558
+ * This is a whole-runtime drain predicate: any unrelated pending cue, query,
559
+ * delegation or OOBI keeps it false. A command or request that asked for one
560
+ * OOBI must wait with `waitForOobi` (`app/bootstrap/oobi-resolving.ts`) instead.
509
561
  * Background receipt delivery is not remote acknowledgement of OOBI acceptance;
510
562
  * static OOBI servers may refuse unsolicited posts. Runtime close still joins I/O.
511
563
  *
@@ -536,14 +588,10 @@ export function* runAgentRuntimeUntil(runtime, done, options) {
536
588
  if (done())
537
589
  return;
538
590
  const { timeoutMs, ...workerOptions } = options;
539
- const deadline = Date.now() + timeoutMs;
540
591
  const worker = yield* spawn(() => runAgentRuntime(runtime, workerOptions));
541
592
  try {
542
- while (!done()) {
543
- if (Date.now() >= deadline)
544
- throw new Error(`Runtime did not converge within ${timeoutMs}ms.`);
545
- yield* runtimeTurn();
546
- }
593
+ if (!(yield* observeUntil(done, { timeoutMs })))
594
+ throw new Error(`Runtime did not converge within ${timeoutMs}ms.`);
547
595
  }
548
596
  finally {
549
597
  yield* worker.halt();
@@ -572,52 +620,55 @@ export { runtimeTurn } from "./runtime-turn.js";
572
620
  */
573
621
  export function* runAgentRuntime(runtime, options = {}) {
574
622
  runtime.querying.configure({ hab: options.hab });
623
+ const pacing = runtime.protocolPacing;
575
624
  const telReceiptor = runtime.vdr ? new Receiptor(runtime.hby, runtime.protocol, runtime.http, runtime.clock) : null;
576
625
  const tasks = [
577
626
  yield* spawn(() => runtime.querying.deliverDo()),
578
627
  yield* spawn(() => runtime.postman.deliverDo()),
579
628
  ...(runtime.vdr && telReceiptor
580
629
  ? [
581
- yield* spawn(function* () {
582
- while (true) {
583
- yield* publishPendingTel(runtime.hby, runtime.vdr.publication, telReceiptor, runtime.http, runtime.clock);
584
- yield* runtimeTurn();
585
- }
586
- }),
630
+ yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => publishPendingTel(runtime.hby, runtime.vdr.publication, telReceiptor, runtime.http, runtime.clock))),
587
631
  ]
588
632
  : []),
589
633
  yield* spawn(function* () {
590
- yield* cueDo(runtime, options);
634
+ yield* cueDo(runtime, options, pacing);
591
635
  }),
592
636
  yield* spawn(function* () {
593
- yield* runtime.protocol.escrowDo();
637
+ yield* runtime.protocol.escrowDo(runtime.clock);
594
638
  }),
595
639
  yield* spawn(function* () {
596
- yield* runtime.oobiery.oobiDo();
640
+ yield* runtime.oobiery.oobiDo(runtime.clock, pacing);
597
641
  }),
598
642
  yield* spawn(function* () {
599
- yield* runtime.authenticator.authDo();
643
+ yield* runtime.authenticator.authDo(runtime.clock, pacing);
600
644
  }),
601
645
  ...(runtime.signaler
602
646
  ? [
603
647
  yield* spawn(function* () {
604
- yield* runtime.signaler.signalDo();
648
+ yield* runtime.signaler.signalDo(runtime.clock, pacing);
605
649
  }),
606
650
  ]
607
651
  : []),
608
652
  ...(options.pollMailbox ?? true
609
653
  ? [
610
654
  yield* spawn(function* () {
611
- yield* runtime.mailboxPoller.pollDo((batch) => settleMailboxPollBatch(runtime, batch));
655
+ yield* runtime.mailboxPoller.pollDo((batch) => settleMailboxPollBatch(runtime, batch), runtime.pollerPacing);
612
656
  }),
613
657
  ]
614
658
  : []),
615
- yield* spawn(function* () {
616
- while (true) {
617
- yield* runtime.delegating.processAllOnce();
618
- yield* runtimeTurn();
619
- }
620
- }),
659
+ yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => runtime.delegating.processAllOnce())),
660
+ yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => runtime.counselor.processOnce())),
661
+ yield* spawn(() => kelPublisherDo(runtime.kelPublisher, runtime.clock, runtime.publisherPacing)),
662
+ ...(runtime.operations && runtime.ipex
663
+ ? [
664
+ yield* spawn(() => operationOwnersDo({
665
+ operations: runtime.operations,
666
+ rootReplicator: runtime.rootReplicator,
667
+ ipex: runtime.ipex,
668
+ clock: runtime.clock,
669
+ }, runtime.ownerPacing)),
670
+ ]
671
+ : []),
621
672
  ];
622
673
  try {
623
674
  return yield* suspend();
@@ -1,4 +1,4 @@
1
- import { runtimeTurn } from "./runtime-turn.js";
1
+ import { doEvery, PROTOCOL_PACING } from "./doing.js";
2
2
  /**
3
3
  * Use an explicitly selected or sole local habitat; never guess among hosted identities.
4
4
  *
@@ -53,9 +53,6 @@ export function* processCuesOnce(runtime, { hab, queryCues } = {}) {
53
53
  * @param runtime Borrowed composed runtime containing the actual cue consumers.
54
54
  * @param options Explicit signer and optional command-owned query cue destination.
55
55
  */
56
- export function* cueDo(runtime, options = {}) {
57
- while (true) {
58
- yield* processCuesOnce(runtime, options);
59
- yield* runtimeTurn();
60
- }
56
+ export function* cueDo(runtime, options = {}, pacing = PROTOCOL_PACING) {
57
+ return yield* doEvery(runtime.clock, pacing.tockMs, () => processCuesOnce(runtime, options));
61
58
  }
@@ -0,0 +1,87 @@
1
+ import { DEFAULT_RETRY_POLICY, RetryBackoff } from "./retry-backoff.js";
2
+ /** Flatten an error and its `cause` chain to one line of text, so a reader sees the transport's own reason. */
3
+ export function describeFailure(error) {
4
+ const parts = [];
5
+ for (let e = error, depth = 0; e !== undefined && e !== null && depth < 8; depth++) {
6
+ parts.push(e instanceof Error ? (e.message || e.name) : String(e));
7
+ e = e instanceof Error ? e.cause : undefined;
8
+ }
9
+ return parts.join(" <- ");
10
+ }
11
+ /** The queue and its retry state for one live operation. */
12
+ export class DeliveryOutbox {
13
+ constructor(policy = DEFAULT_RETRY_POLICY) {
14
+ Object.defineProperty(this, "queue", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: []
19
+ });
20
+ Object.defineProperty(this, "backoff", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: void 0
25
+ });
26
+ /** Destinations the transport reported for everything delivered so far. */
27
+ Object.defineProperty(this, "delivered", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: []
32
+ });
33
+ this.backoff = new RetryBackoff(policy);
34
+ }
35
+ /** Messages still waiting. */
36
+ get length() {
37
+ return this.queue.length;
38
+ }
39
+ /** Consecutive delivery failures of the head message. */
40
+ get attempts() {
41
+ return this.backoff.attempts;
42
+ }
43
+ /** The latest delivery error, or null. */
44
+ get lastError() {
45
+ return this.backoff.last;
46
+ }
47
+ /** The retry state of the head message, or null while nothing is failing. */
48
+ get failure() {
49
+ return this.backoff.attempts === 0
50
+ ? null
51
+ : {
52
+ attempts: this.backoff.attempts,
53
+ reason: describeFailure(this.backoff.last),
54
+ retryAt: new Date(this.backoff.next).toISOString(),
55
+ };
56
+ }
57
+ /** Queue a message behind the others. */
58
+ enqueue(message) {
59
+ this.queue.push(message);
60
+ }
61
+ /**
62
+ * Deliver the queued messages in order. A failure keeps the message and schedules a retry; it throws only when
63
+ * `boundMs` is given and failures have lasted that long.
64
+ *
65
+ * @returns True when the queue is empty, false while a message waits for its retry.
66
+ */
67
+ *drain(transport, clock, boundMs) {
68
+ while (this.queue.length) {
69
+ const now = clock.now();
70
+ if (!this.backoff.due(now))
71
+ return false;
72
+ try {
73
+ const { src, dest, msg, topic } = this.queue[0];
74
+ this.delivered.push(...yield* transport.deliver({ src, dest, msg: typeof msg === "function" ? msg() : msg, topic }));
75
+ this.queue.shift();
76
+ this.backoff.succeeded();
77
+ }
78
+ catch (error) {
79
+ this.backoff.failed(now, error);
80
+ if (boundMs !== undefined && this.backoff.exhausted(now, boundMs))
81
+ throw error;
82
+ return false;
83
+ }
84
+ }
85
+ return true;
86
+ }
87
+ }
@@ -0,0 +1,17 @@
1
+ import { waitOnClock } from "./workflow-contract.js";
2
+ /** Milliseconds between passes of the protocol-facing background loops: KERIpy's Doist cycle, as the escrow loop uses. */
3
+ export const PROTOCOL_TOCK_MS = 31.25;
4
+ /** Tocks between full sweeps of a loop that has one: 1920 tocks of 31.25 ms is a minute. */
5
+ export const PROTOCOL_SWEEP_TOCKS = 1920;
6
+ /** The production pacing of the protocol-facing background loops. */
7
+ export const PROTOCOL_PACING = Object.freeze({
8
+ tockMs: PROTOCOL_TOCK_MS,
9
+ sweepTocks: PROTOCOL_SWEEP_TOCKS,
10
+ });
11
+ /** Run `pass` forever: pass 0, wait `tockMs` on `clock`, pass 1, and so on. A thrown error ends the doer. */
12
+ export function* doEvery(clock, tockMs, pass) {
13
+ for (let tock = 0;; tock++) {
14
+ yield* pass(tock);
15
+ yield* waitOnClock(clock, tockMs);
16
+ }
17
+ }
@@ -0,0 +1,207 @@
1
+ import { Dhke } from "../../acdc/dhking.js";
2
+ import { Unblind } from "../../acdc/unblinding.js";
3
+ import { ValidationError } from "../../core/errors.js";
4
+ import { isLocalGroupHab } from "../multisig/group-members.js";
5
+ /** Per-identifier DH and Unblind owners behind one query receiver and one reply route each. */
6
+ export class IpexAuxiliaries {
7
+ /**
8
+ * @param exc Exchanger shared by every owner.
9
+ * @param registry Public registry observer shared by every owner.
10
+ * @param rvy Reply verifier whose router the owners' routes are registered on.
11
+ * @param now Receiver clock shared by every owner.
12
+ * @param kram Whether KRAM is enabled; with it off, `approve` of either owner throws.
13
+ */
14
+ constructor(exc, registry, rvy, now,
15
+ /** Whether the runtime's KRAM is on; DH and Unblind approval need the rows only KRAM writes. */
16
+ kram) {
17
+ Object.defineProperty(this, "exc", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: exc
22
+ });
23
+ Object.defineProperty(this, "registry", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: registry
28
+ });
29
+ Object.defineProperty(this, "rvy", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: rvy
34
+ });
35
+ Object.defineProperty(this, "now", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: now
40
+ });
41
+ Object.defineProperty(this, "kram", {
42
+ enumerable: true,
43
+ configurable: true,
44
+ writable: true,
45
+ value: kram
46
+ });
47
+ /** Unused: `claims` decides which queries this receiver takes. */
48
+ Object.defineProperty(this, "resource", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: "/ipex"
53
+ });
54
+ Object.defineProperty(this, "dhkes", {
55
+ enumerable: true,
56
+ configurable: true,
57
+ writable: true,
58
+ value: new Map()
59
+ });
60
+ Object.defineProperty(this, "unblinds", {
61
+ enumerable: true,
62
+ configurable: true,
63
+ writable: true,
64
+ value: new Map()
65
+ });
66
+ Object.defineProperty(this, "restored", {
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true,
70
+ value: false
71
+ });
72
+ }
73
+ /** Every live DH owner, for hosts draining their completion cues. */
74
+ dhkeOwners() {
75
+ return this.dhkes.values();
76
+ }
77
+ /** Every live Unblind owner, for hosts delivering the replies they owe. */
78
+ unblindOwners() {
79
+ if (!this.restored) {
80
+ // A request persisted before a restart is owed its reply by an owner nothing has created yet.
81
+ this.restored = true;
82
+ const owed = new Set([...this.exc.hby.db.heldu.getTopItemIter()].map(([[pre]]) => pre));
83
+ for (const pre of owed) {
84
+ const hab = this.exc.hby.habs.get(pre);
85
+ if (!hab)
86
+ continue;
87
+ try {
88
+ this.unblind(hab);
89
+ }
90
+ catch (error) {
91
+ if (!(error instanceof ValidationError))
92
+ throw error;
93
+ }
94
+ }
95
+ }
96
+ return this.unblinds.values();
97
+ }
98
+ /** Register the DH and Unblind reply routes once; owners are looked up on each reply. */
99
+ registerReplyRoutes(rtr) {
100
+ rtr.addRoute(Dhke.Route, { processReply: (args) => this.reply("dhke", args) });
101
+ rtr.addRoute(Unblind.Route, { processReply: (args) => this.reply("unblind", args) });
102
+ }
103
+ /** The DH owner for `hab`, created on first use and recreated when `hab` is no longer the owner's object. */
104
+ dhke(hab) {
105
+ const current = this.dhkes.get(hab.pre);
106
+ if (current?.hab === hab)
107
+ return current;
108
+ const owner = new Dhke({
109
+ hab,
110
+ exc: this.exc,
111
+ registryStore: this.registry.store,
112
+ rvy: this.rvy,
113
+ now: this.now,
114
+ kram: this.kram,
115
+ });
116
+ current?.close();
117
+ this.dhkes.set(hab.pre, owner);
118
+ return owner;
119
+ }
120
+ /** The Unblind owner for `hab`, created on first use and recreated when `hab` is no longer the owner's object. */
121
+ unblind(hab) {
122
+ const current = this.unblinds.get(hab.pre);
123
+ if (current?.hab === hab)
124
+ return current;
125
+ const owner = new Unblind({ hab, exc: this.exc, registry: this.registry, rvy: this.rvy, kram: this.kram });
126
+ current?.close();
127
+ this.unblinds.set(hab.pre, owner);
128
+ return owner;
129
+ }
130
+ /** Close and unregister both owners of `pre`; process-local approvals and retries are cleared. */
131
+ release(pre) {
132
+ this.restored = false;
133
+ for (const owners of [this.dhkes, this.unblinds]) {
134
+ owners.get(pre)?.close();
135
+ owners.delete(pre);
136
+ }
137
+ }
138
+ /** Close every owner; the runtime calls this on explicit close and scope exit. */
139
+ close() {
140
+ for (const owner of [...this.dhkes.values(), ...this.unblinds.values()])
141
+ owner.close();
142
+ this.dhkes.clear();
143
+ this.unblinds.clear();
144
+ }
145
+ claims(serder) {
146
+ return this.select(serder) !== null;
147
+ }
148
+ processQuery(envelope) {
149
+ return this.select(envelope.serder)?.processQuery(envelope) ?? { kind: "drop", reason: "missingProcessor" };
150
+ }
151
+ reply(kind, args) {
152
+ const owner = this.claimant(kind, args.serder.pre, args.serder.sad?.a?.x);
153
+ if (!owner)
154
+ throw new ValidationError(`No resource is registered to handle route ${args.route}`);
155
+ return owner.processReply(args);
156
+ }
157
+ select(serder) {
158
+ const kind = serder.route === Dhke.Route ? "dhke" : serder.route === Unblind.Route ? "unblind" : null;
159
+ return kind && this.claimant(kind, serder.pre, serder.sad?.q?.x);
160
+ }
161
+ /**
162
+ * The owner of the one local identifier party to the transaction, created now if needed; absent or
163
+ * ambiguous means unowned. Parties come from live owners (approved operations) and from the store.
164
+ */
165
+ claimant(kind, sender, xid) {
166
+ if (!sender || typeof xid !== "string")
167
+ return null;
168
+ const owners = kind === "dhke" ? this.dhkes : this.unblinds;
169
+ const habs = this.exc.hby.habs;
170
+ const parties = new Set();
171
+ for (const [pre, owner] of owners)
172
+ if (owner.inTransaction(sender, xid))
173
+ parties.add(pre);
174
+ if (kind === "dhke") {
175
+ for (const recipient of Dhke.recipients(this.exc.hby.db, sender, xid)) {
176
+ if (habs.has(recipient))
177
+ parties.add(recipient);
178
+ }
179
+ }
180
+ else {
181
+ for (const pre of habs.keys()) {
182
+ if (Unblind.recipients(this.exc.hby.db, pre, xid).includes(sender))
183
+ parties.add(pre);
184
+ }
185
+ }
186
+ const group = habs.get(sender);
187
+ if (group && isLocalGroupHab(this.exc.hby, group))
188
+ parties.add(sender);
189
+ if (parties.size !== 1)
190
+ return null;
191
+ const [pre] = parties;
192
+ const hab = habs.get(pre);
193
+ if (!hab) {
194
+ this.release(pre);
195
+ return null;
196
+ }
197
+ try {
198
+ return kind === "dhke" ? this.dhke(hab) : this.unblind(hab);
199
+ }
200
+ catch (error) {
201
+ // A group without a local signing member cannot own the route.
202
+ if (error instanceof ValidationError)
203
+ return null;
204
+ throw error;
205
+ }
206
+ }
207
+ }