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
@@ -0,0 +1,120 @@
1
+ /**
2
+ * IPEX Admit preparation over borrowed protocol owners.
3
+ *
4
+ * Reads accepted Grants and their graph truth from the Habery, Exchanger and
5
+ * registry store only; it records no admission. Embedders that keep admitted
6
+ * records (the wallet) call it before and after their own inventory writes.
7
+ */
8
+ import { SerderACDC, Vrsn_2_0 } from "cesr-ts";
9
+ import { call } from "effection";
10
+ import { evaluateChain } from "../../acdc/chaining.js";
11
+ import { ValidationError } from "../../core/errors.js";
12
+ import { loadNests } from "../../db/exchange/exchange-nests.js";
13
+ import { isLocalGroupHab } from "../multisig/group-members.js";
14
+ import { envelopeFromFrame } from "../protocol/parsering.js";
15
+ import { ipexExnBody } from "./ipex-building.js";
16
+ import { anchorExchange, exchangeWire, IpexDiscloser } from "./ipex-discloser.js";
17
+ import { walkIpexGraph } from "./ipex-graph.js";
18
+ import { authenticateIpexNode, issuedNodeVerdict } from "./ipex-node-authentication.js";
19
+ import { ipexGrantWalk } from "./ipex-v2.js";
20
+ /** Borrow concrete owners only; no constructor opens a store or starts a worker. */
21
+ export class IpexAdmitter {
22
+ constructor(hby, registry, exc) {
23
+ Object.defineProperty(this, "hby", {
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true,
27
+ value: hby
28
+ });
29
+ Object.defineProperty(this, "registry", {
30
+ enumerable: true,
31
+ configurable: true,
32
+ writable: true,
33
+ value: registry
34
+ });
35
+ Object.defineProperty(this, "exc", {
36
+ enumerable: true,
37
+ configurable: true,
38
+ writable: true,
39
+ value: exc
40
+ });
41
+ }
42
+ /** Authenticate accepted outer evidence through existing replay, without current node policy. */
43
+ async accepted(said, route) {
44
+ const body = this.hby.db.exns.get([said]);
45
+ if (!body || body.said !== said || body.route !== route || body.pvrsn.major !== 2 || !this.exc.complete(said)) {
46
+ throw new ValidationError("Accepted ACDC v2 exchange at the exact route is required.");
47
+ }
48
+ for await (const _chunk of this.exc.replay(said)) { /* replay authenticates retained outer factors */ }
49
+ return body;
50
+ }
51
+ /** New use requires current node evidence and a valid root under shared issued-state policy. */
52
+ graphAccepted(grant, origin) {
53
+ if (!this.exc.verifyAccepted(grant, "/ipex/grant"))
54
+ return false;
55
+ const graph = walkIpexGraph(origin, loadNests(this.hby.db, grant), ipexGrantWalk(this.exc));
56
+ if (!graph)
57
+ return false;
58
+ const verdicts = new Map();
59
+ for (const [said, node] of graph.nodes) {
60
+ const auth = authenticateIpexNode(node.body, envelopeFromFrame(node), this.hby.db, this.registry);
61
+ verdicts.set(said, issuedNodeVerdict(auth));
62
+ }
63
+ return evaluateChain(graph, verdicts, this.hby.db)?.kind === "valid";
64
+ }
65
+ /** Resolve only the origin actually carried by this accepted Grant. */
66
+ origin(grant) {
67
+ const origins = grant.sad.a && grant.sad.a.o;
68
+ if (!Array.isArray(origins) || origins.length !== 1 || typeof origins[0] !== "string") {
69
+ throw new ValidationError("Wallet admission requires one disclosed origin.");
70
+ }
71
+ if (!loadNests(this.hby.db, grant.said).some((node) => node.body instanceof SerderACDC && node.body.said === origins[0])) {
72
+ throw new ValidationError("Accepted Grant origin is missing.");
73
+ }
74
+ return origins[0];
75
+ }
76
+ /** Freeze an unsigned response only after explicit consent, exact prior authentication and current root truth. */
77
+ *prepareAdmitBody(grant, holder, { consent = false, message = "", gvrsn = Vrsn_2_0 } = {}) {
78
+ if (consent !== true)
79
+ throw new ValidationError("Explicit consent is required.");
80
+ if (gvrsn.major < 2)
81
+ throw new ValidationError("ACDC v2 Admit requires attachment genus 2 or later.");
82
+ const g = yield* call(() => this.accepted(grant, "/ipex/grant")), hab = this.hby.habs.get(holder);
83
+ if (!hab || g.sad.ri !== holder)
84
+ throw new ValidationError("Grant must address the intended local holder.");
85
+ const response = this.hby.db.erpy.get([grant]);
86
+ if (response && this.exc.complete(response.qb64)) {
87
+ throw new ValidationError("Grant already has an accepted response.");
88
+ }
89
+ if (!this.graphAccepted(grant, this.origin(g))) {
90
+ throw new ValidationError("Current authenticated graph acceptance is required before signing.");
91
+ }
92
+ return ipexExnBody(holder, "/ipex/admit", [], { message, prior: g, gvrsn });
93
+ }
94
+ /** Sign an individual response; group approval consumes the same unsigned body through its own exact-stream owner. */
95
+ *prepareAdmit(grant, holder, { consent = false, message = "", gvrsn = Vrsn_2_0, receiptor, auths } = {}) {
96
+ if (consent !== true)
97
+ throw new ValidationError("Explicit consent is required.");
98
+ if (gvrsn.major < 2)
99
+ throw new ValidationError("ACDC v2 Admit requires attachment genus 2 or later.");
100
+ const hab = this.hby.habs.get(holder);
101
+ if (!hab)
102
+ throw new ValidationError("Grant must address the intended local holder.");
103
+ if (isLocalGroupHab(this.hby, hab)) {
104
+ throw new ValidationError("ACDC v2 wallet admission requires a single-signature holder.");
105
+ }
106
+ const admit = yield* this.prepareAdmitBody(grant, holder, { consent, message, gvrsn });
107
+ const anchored = admit.sad.a.ax?.[0] === true;
108
+ if (anchored && !receiptor)
109
+ throw new ValidationError("Anchored Admit requires its actual receipt owner.");
110
+ const source = anchored ? yield* anchorExchange(this.hby, receiptor, hab, admit, auths) : undefined;
111
+ if (!this.graphAccepted(grant, this.origin(this.hby.db.exns.get([grant])))) {
112
+ throw new ValidationError("Current authenticated graph acceptance is required after source receipts.");
113
+ }
114
+ return {
115
+ admit,
116
+ wire: exchangeWire(hab, admit, undefined, source, gvrsn),
117
+ support: source ? new IpexDiscloser(this.hby, this.registry, this.exc, receiptor).kel(hab) : new Uint8Array(),
118
+ };
119
+ }
120
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Legacy (v1) IPEX conversation for a single-signature controller: send an
3
+ * apply, offer, agree or spurn, read where a conversation stands and observe it
4
+ * until the peer replies. Owned by the library so that every host (CLI, wallet,
5
+ * service) runs one implementation.
6
+ *
7
+ * Operations follow the workflow contract. `sendIpexApply`, `sendIpexOffer`,
8
+ * `sendIpexAgree` and `sendIpexSpurn` are explicit: each validates the accepted
9
+ * prior message, signs exactly one exchange, accepts it locally, hands it to the
10
+ * Poster and returns once that delivery attempt has an outcome. They never wait
11
+ * for the peer. `ipexExchangeStatus` is a pure synchronous read of durable
12
+ * state. `waitForIpexExchange` only observes: it starts no worker and returns a
13
+ * timed-out value instead of throwing.
14
+ *
15
+ * Boundaries:
16
+ * - Dependencies are narrow collaborators, not an AgentRuntime (ADR-0013). The
17
+ * host owns their lifetimes and must be running the Poster worker so the
18
+ * delivery attempt can complete (`withRuntimeWorkers` for a one-shot host).
19
+ * - Recipients arrive as resolved AIDs; contact lookup is a host concern.
20
+ * - Group controllers do not use these operations: their propose/approve split
21
+ * needs the multisig coordinator, which the group proposal API will own.
22
+ * - Durable state records acceptance, not delivery, so there is no "sent but
23
+ * unanswered" read distinct from `awaiting-reply`; a send's return value is
24
+ * the evidence that it was sent.
25
+ */
26
+ import { concatBytes, Counter } from "cesr-ts";
27
+ import { sleep } from "effection";
28
+ import { ValidationError } from "../../core/errors.js";
29
+ import { exchange } from "../../core/exchange/protocol-exchanging.js";
30
+ import { CREDENTIAL_MAILBOX_TOPIC } from "../../core/mailbox/mailbox-topics.js";
31
+ import { isLocalGroupHab } from "../multisig/group-members.js";
32
+ import { systemClock } from "../runtime/runtime-clock.js";
33
+ import { credentialSaidFromGrant } from "./ipex-credentialing.js";
34
+ import { sendCredentialStream } from "./ipex-grouping.js";
35
+ import { IPEX_AGREE_ROUTE, IPEX_APPLY_ROUTE, IPEX_GRANT_ROUTE, IPEX_OFFER_ROUTE, IPEX_SPURN_ROUTE, validateIpexReply, } from "./ipexing.js";
36
+ /**
37
+ * Require a local single-signature sender.
38
+ *
39
+ * @throws ValidationError when `sender` is not a local AID of `hby` or is a group AID.
40
+ */
41
+ export function requireIpexSender(hby, sender) {
42
+ if (!sender.pre || hby.habs.get(sender.pre) !== sender) {
43
+ throw new ValidationError(`No local AID found for sender ${sender.pre || "<missing>"}.`);
44
+ }
45
+ if (isLocalGroupHab(hby, sender)) {
46
+ throw new ValidationError(`Sender ${sender.pre} is a group AID; single-signature IPEX operations do not apply.`);
47
+ }
48
+ }
49
+ /**
50
+ * Validate an accepted predecessor and its known parties before any local signing.
51
+ *
52
+ * @throws ValidationError when the prior is not accepted, has the wrong route or
53
+ * parties, or already has an accepted response.
54
+ */
55
+ export function requireIpexPrior(hby, sender, recipient, said, verb) {
56
+ const prior = hby.db.exns.get([said]);
57
+ if (!prior)
58
+ throw new ValidationError("Prior IPEX exchange is not accepted.");
59
+ validateIpexReply(prior, verb, sender, recipient);
60
+ if (hby.db.erpy.get([said])) {
61
+ throw new ValidationError("Prior IPEX exchange already has an accepted response; resume the existing exchange.");
62
+ }
63
+ }
64
+ /**
65
+ * Accept one signed exchange locally and confirm it was accepted.
66
+ *
67
+ * @param wire Signed exchange followed by its attachments.
68
+ * @param refusal Message for the infrastructure failure of a local exchange that was not accepted.
69
+ * @param prior Said of the message this one answers; its status changes too.
70
+ */
71
+ export function* acceptIpexExchange(deps, exn, wire, genus, refusal, prior) {
72
+ yield* deps.reactor.processBytes(concatBytes(Counter.makeGVC(genus), wire), { local: true });
73
+ yield* deps.protocol.processEscrowsOnce();
74
+ if (!deps.protocol.exc.complete(exn.said))
75
+ throw new ValidationError(refusal);
76
+ if (prior)
77
+ deps.changes?.push({ kind: "ipex", id: prior });
78
+ deps.changes?.push({ kind: "ipex", id: exn.said });
79
+ }
80
+ /**
81
+ * Sign one prepared exchange, accept it locally and deliver it. A spurn goes out
82
+ * as a one-message stream; every other verb as a queued message with a
83
+ * completion notice. A failed delivery outcome throws its original error; the
84
+ * accepted exchange stays stored.
85
+ */
86
+ function* signAcceptAndSend(deps, sender, recipient, [exn, attachments], prior) {
87
+ const genus = exn.gvrsn ?? exn.pvrsn;
88
+ const wire = concatBytes(sender.endorse(exn, { pipelined: false, gvrsn: genus }), attachments);
89
+ yield* acceptIpexExchange(deps, exn, wire, genus, "Local IPEX exchange was not accepted.", prior);
90
+ if (exn.route === IPEX_SPURN_ROUTE) {
91
+ return { exn, deliveries: yield* sendCredentialStream(deps.postman, sender, recipient, [wire]) };
92
+ }
93
+ const evt = deps.postman.send({ src: sender.pre, dest: recipient, topic: CREDENTIAL_MAILBOX_TOPIC, msg: wire }, { notify: true });
94
+ const outcome = yield* deps.postman.wait(evt);
95
+ if (outcome.kin === "failed")
96
+ throw outcome.error;
97
+ return { exn, deliveries: outcome.deliveries };
98
+ }
99
+ /**
100
+ * Send an `/ipex/apply` asking `recipient` for a credential of `schema`.
101
+ * An apply starts a conversation, so there is no prior to validate and sending
102
+ * it twice sends two distinct applies.
103
+ *
104
+ * @throws ValidationError for a sender that is not a local single-signature AID or a refused local exchange.
105
+ */
106
+ export function* sendIpexApply(deps, sender, { recipient, schema, attrs = {}, message = "" }) {
107
+ requireIpexSender(deps.hby, sender);
108
+ const prepared = exchange(IPEX_APPLY_ROUTE, { m: message, s: schema, a: attrs, i: recipient }, {
109
+ sender: sender.pre,
110
+ recipient,
111
+ });
112
+ return yield* signAcceptAndSend(deps, sender, recipient, prepared);
113
+ }
114
+ /**
115
+ * Send an `/ipex/offer` carrying one embedded ACDC, optionally answering an apply.
116
+ *
117
+ * @throws ValidationError as for {@link requireIpexPrior} when `apply` is given.
118
+ */
119
+ export function* sendIpexOffer(deps, sender, { recipient, acdc, apply, message = "" }) {
120
+ requireIpexSender(deps.hby, sender);
121
+ if (apply)
122
+ requireIpexPrior(deps.hby, sender.pre, recipient, apply, "offer");
123
+ const prepared = exchange(IPEX_OFFER_ROUTE, { m: message }, {
124
+ sender: sender.pre,
125
+ recipient,
126
+ dig: apply,
127
+ embeds: { acdc },
128
+ });
129
+ return yield* signAcceptAndSend(deps, sender, recipient, prepared, apply || undefined);
130
+ }
131
+ /**
132
+ * Send an `/ipex/agree` answering an accepted offer.
133
+ *
134
+ * @throws ValidationError as for {@link requireIpexPrior}.
135
+ */
136
+ export function* sendIpexAgree(deps, sender, { recipient, offer, message = "" }) {
137
+ requireIpexSender(deps.hby, sender);
138
+ requireIpexPrior(deps.hby, sender.pre, recipient, offer, "agree");
139
+ const prepared = exchange(IPEX_AGREE_ROUTE, { m: message }, { sender: sender.pre, recipient, dig: offer });
140
+ return yield* signAcceptAndSend(deps, sender, recipient, prepared, offer);
141
+ }
142
+ /**
143
+ * Send an `/ipex/spurn` rejecting an accepted apply, offer, agree or grant.
144
+ *
145
+ * @throws ValidationError as for {@link requireIpexPrior}.
146
+ */
147
+ export function* sendIpexSpurn(deps, sender, { recipient, prior, message = "" }) {
148
+ requireIpexSender(deps.hby, sender);
149
+ requireIpexPrior(deps.hby, sender.pre, recipient, prior, "spurn");
150
+ const prepared = exchange(IPEX_SPURN_ROUTE, { m: message }, { sender: sender.pre, recipient, dig: prior });
151
+ return yield* signAcceptAndSend(deps, sender, recipient, prepared, prior);
152
+ }
153
+ /**
154
+ * Pure synchronous status of the accepted exchange `said`, derived from the
155
+ * exchange store, the reply index and (for grants) the saved-credential index.
156
+ * Mutates nothing.
157
+ */
158
+ export function ipexExchangeStatus(deps, said) {
159
+ const exn = deps.hby.db.exns.get([said]);
160
+ if (!exn)
161
+ return { state: "unknown" };
162
+ const route = exn.route ?? "";
163
+ const credentialSaid = route === IPEX_GRANT_ROUTE ? credentialSaidFromGrant(exn) : null;
164
+ const credential = credentialSaid
165
+ ? { credential: { said: credentialSaid, saved: !!deps.reger.saved.get([credentialSaid]) } }
166
+ : {};
167
+ const response = deps.hby.db.erpy.get([said]);
168
+ if (!response)
169
+ return { state: "awaiting-reply", route, ...credential };
170
+ const replySaid = response.qb64;
171
+ const reply = { said: replySaid, route: deps.hby.db.exns.get([replySaid])?.route ?? null };
172
+ return { state: "replied", route, reply, ...credential };
173
+ }
174
+ function reached(status, until) {
175
+ if (until === "credential-saved")
176
+ return status.state !== "unknown" && !!status.credential?.saved;
177
+ return status.state === "replied";
178
+ }
179
+ /**
180
+ * Observe `said` until the wanted state holds or the budget expires. A wait
181
+ * that is already satisfied returns at once. Starts no worker: the host's own
182
+ * poller and escrow loop make the peer's reply or the credential arrive.
183
+ *
184
+ * @returns `settled`, or `timed-out`; both carry the status read at return.
185
+ */
186
+ export function* waitForIpexExchange(deps, said, { timeoutMs, until = "replied", pollMs = 250, clock = systemClock }) {
187
+ const deadline = clock.now() + timeoutMs;
188
+ while (true) {
189
+ const status = ipexExchangeStatus(deps, said);
190
+ if (reached(status, until))
191
+ return { outcome: "settled", status };
192
+ const remaining = deadline - clock.now();
193
+ if (remaining <= 0)
194
+ return { outcome: "timed-out", status, timeoutMs };
195
+ yield* sleep(Math.min(pollMs, remaining));
196
+ }
197
+ }