keri-ts 2.0.1 → 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 (450) 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/chaining.js +223 -89
  4. package/esm/keri/npm/src/acdc/custody.js +164 -0
  5. package/esm/keri/npm/src/acdc/dhking.js +244 -32
  6. package/esm/keri/npm/src/acdc/observing.js +2 -2
  7. package/esm/keri/npm/src/acdc/regbasing.js +30 -29
  8. package/esm/keri/npm/src/acdc/regengine.js +4 -6
  9. package/esm/keri/npm/src/acdc/registering.js +13 -10
  10. package/esm/keri/npm/src/acdc/registraring.js +4 -9
  11. package/esm/keri/npm/src/acdc/salting.js +143 -26
  12. package/esm/keri/npm/src/acdc/scheming.js +93 -54
  13. package/esm/keri/npm/src/acdc/unblinding.js +120 -99
  14. package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
  15. package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
  16. package/esm/keri/npm/src/app/bootstrap/oobiery.js +5 -7
  17. package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
  18. package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
  19. package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
  20. package/esm/keri/npm/src/app/credentials/root-replicating.js +131 -0
  21. package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
  22. package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
  23. package/esm/keri/npm/src/app/credentials/verifying.js +12 -3
  24. package/esm/keri/npm/src/app/delivery/forwarding.js +64 -9
  25. package/esm/keri/npm/src/app/exchanges/exchanging.js +24 -15
  26. package/esm/keri/npm/src/app/identity/challenging.js +50 -0
  27. package/esm/keri/npm/src/app/identity/configing.js +17 -43
  28. package/esm/keri/npm/src/app/identity/delegating.js +77 -77
  29. package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
  30. package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
  31. package/esm/keri/npm/src/app/identity/habbing.js +183 -41
  32. package/esm/keri/npm/src/app/identity/keeping.js +78 -5
  33. package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
  34. package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
  35. package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
  36. package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
  37. package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
  38. package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
  39. package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
  40. package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
  41. package/esm/keri/npm/src/app/ipex/ipex-grouping.js +42 -16
  42. package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
  43. package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
  44. package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
  45. package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
  46. package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
  47. package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
  48. package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
  49. package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
  50. package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
  51. package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
  52. package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
  53. package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
  54. package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
  55. package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
  56. package/esm/keri/npm/src/app/mailbox/mailboxing.js +15 -14
  57. package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
  58. package/esm/keri/npm/src/app/multisig/group-members.js +32 -0
  59. package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
  60. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +101 -141
  61. package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
  62. package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
  63. package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
  64. package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
  65. package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
  66. package/esm/keri/npm/src/app/protocol/protocol-processing.js +44 -6
  67. package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
  68. package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
  69. package/esm/keri/npm/src/app/runtime/agent-runtime.js +113 -65
  70. package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
  71. package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
  72. package/esm/keri/npm/src/app/runtime/doing.js +17 -0
  73. package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
  74. package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
  75. package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
  76. package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
  77. package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
  78. package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
  79. package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
  80. package/esm/keri/npm/src/app/transport/http-client.js +25 -6
  81. package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
  82. package/esm/keri/npm/src/app/transport/message-source.js +1 -1
  83. package/esm/keri/npm/src/app/transport/messengering.js +3 -4
  84. package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
  85. package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
  86. package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
  87. package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
  88. package/esm/keri/npm/src/cli/common/context.js +2 -2
  89. package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
  90. package/esm/keri/npm/src/cli/common/existing.js +3 -5
  91. package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
  92. package/esm/keri/npm/src/cli/credentials/ipex.js +159 -191
  93. package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
  94. package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
  95. package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
  96. package/esm/keri/npm/src/cli/endpoints/oobi.js +12 -15
  97. package/esm/keri/npm/src/cli/identity/challenge.js +9 -35
  98. package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
  99. package/esm/keri/npm/src/cli/identity/incept.js +17 -34
  100. package/esm/keri/npm/src/cli/identity/init.js +4 -3
  101. package/esm/keri/npm/src/cli/identity/interact.js +7 -19
  102. package/esm/keri/npm/src/cli/identity/rotate.js +10 -38
  103. package/esm/keri/npm/src/cli/index.js +3 -1
  104. package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
  105. package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
  106. package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
  107. package/esm/keri/npm/src/cli/messaging/multisig.js +187 -250
  108. package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
  109. package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
  110. package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
  111. package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
  112. package/esm/keri/npm/src/core/bytes.js +9 -0
  113. package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
  114. package/esm/keri/npm/src/core/kel/eventing.js +67 -12
  115. package/esm/keri/npm/src/core/kel/kever.js +11 -9
  116. package/esm/keri/npm/src/core/mailbox/kram-policy.js +41 -9
  117. package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
  118. package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
  119. package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
  120. package/esm/keri/npm/src/core/records.js +23 -0
  121. package/esm/keri/npm/src/core/routing.js +15 -2
  122. package/esm/keri/npm/src/db/basing.js +183 -205
  123. package/esm/keri/npm/src/db/core/dber.js +1062 -0
  124. package/esm/keri/npm/src/db/core/index.js +4 -2
  125. package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
  126. package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
  127. package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
  128. package/esm/keri/npm/src/db/core/memstore.js +532 -0
  129. package/esm/keri/npm/src/db/core/path-manager.js +109 -223
  130. package/esm/keri/npm/src/db/core/store-owner.js +104 -0
  131. package/esm/keri/npm/src/db/core/webdber.js +252 -0
  132. package/esm/keri/npm/src/db/escrowing.js +2 -2
  133. package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
  134. package/esm/keri/npm/src/db/indexeddb.js +98 -0
  135. package/esm/keri/npm/src/db/keeping.js +38 -123
  136. package/esm/keri/npm/src/db/koming.js +1 -1
  137. package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
  138. package/esm/keri/npm/src/db/lmdb.js +6 -0
  139. package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
  140. package/esm/keri/npm/src/db/noting.js +11 -55
  141. package/esm/keri/npm/src/db/reger.js +43 -105
  142. package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
  143. package/esm/keri/npm/src/db/store-lock.js +150 -0
  144. package/esm/keri/npm/src/db/subing.js +1 -1
  145. package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
  146. package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
  147. package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
  148. package/esm/keri/npm/src/npm/db.browser.js +2 -0
  149. package/esm/keri/npm/src/npm/index.browser.js +9 -0
  150. package/esm/keri/npm/src/npm/runtime-node.js +3 -0
  151. package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
  152. package/esm/keri/npm/src/npm/runtime-web.js +3 -0
  153. package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
  154. package/esm/keri/npm/src/runtime/index.js +58 -12
  155. package/esm/keri/npm/src/runtime/node.js +14 -0
  156. package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
  157. package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
  158. package/esm/keri/npm/src/runtime/web.js +10 -0
  159. package/esm/keri/npm/src/vdr/eventing.js +1 -1
  160. package/esm/keri/npm/src/vdr/tel-publication.js +19 -3
  161. package/esm/keri/npm/src/version.js +2 -2
  162. package/package.json +24 -4
  163. package/types/acdc/authoring.d.ts +54 -0
  164. package/types/acdc/authoring.d.ts.map +1 -0
  165. package/types/acdc/chaining.d.ts +56 -6
  166. package/types/acdc/chaining.d.ts.map +1 -1
  167. package/types/acdc/custody.d.ts +77 -0
  168. package/types/acdc/custody.d.ts.map +1 -0
  169. package/types/acdc/dhking.d.ts +94 -3
  170. package/types/acdc/dhking.d.ts.map +1 -1
  171. package/types/acdc/regbasing.d.ts +11 -6
  172. package/types/acdc/regbasing.d.ts.map +1 -1
  173. package/types/acdc/regengine.d.ts.map +1 -1
  174. package/types/acdc/registering.d.ts +8 -4
  175. package/types/acdc/registering.d.ts.map +1 -1
  176. package/types/acdc/registraring.d.ts.map +1 -1
  177. package/types/acdc/salting.d.ts +59 -7
  178. package/types/acdc/salting.d.ts.map +1 -1
  179. package/types/acdc/scheming.d.ts +2 -0
  180. package/types/acdc/scheming.d.ts.map +1 -1
  181. package/types/acdc/unblinding.d.ts +58 -19
  182. package/types/acdc/unblinding.d.ts.map +1 -1
  183. package/types/app/bootstrap/authenticating.d.ts +3 -1
  184. package/types/app/bootstrap/authenticating.d.ts.map +1 -1
  185. package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
  186. package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
  187. package/types/app/bootstrap/oobiery.d.ts +3 -1
  188. package/types/app/bootstrap/oobiery.d.ts.map +1 -1
  189. package/types/app/credentials/credential-revoking.d.ts +3 -0
  190. package/types/app/credentials/credential-revoking.d.ts.map +1 -1
  191. package/types/app/credentials/credential-workflows.d.ts +5 -0
  192. package/types/app/credentials/credential-workflows.d.ts.map +1 -1
  193. package/types/app/credentials/registry-settling.d.ts +85 -0
  194. package/types/app/credentials/registry-settling.d.ts.map +1 -0
  195. package/types/app/credentials/root-replicating.d.ts +97 -0
  196. package/types/app/credentials/root-replicating.d.ts.map +1 -0
  197. package/types/app/credentials/root-replicator.d.ts +105 -0
  198. package/types/app/credentials/root-replicator.d.ts.map +1 -0
  199. package/types/app/credentials/tel-completion.d.ts +55 -0
  200. package/types/app/credentials/tel-completion.d.ts.map +1 -0
  201. package/types/app/credentials/verifying.d.ts +2 -1
  202. package/types/app/credentials/verifying.d.ts.map +1 -1
  203. package/types/app/delivery/forwarding.d.ts +16 -0
  204. package/types/app/delivery/forwarding.d.ts.map +1 -1
  205. package/types/app/exchanges/exchanging.d.ts +2 -0
  206. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  207. package/types/app/identity/challenging.d.ts +54 -0
  208. package/types/app/identity/challenging.d.ts.map +1 -1
  209. package/types/app/identity/configing.d.ts +7 -5
  210. package/types/app/identity/configing.d.ts.map +1 -1
  211. package/types/app/identity/delegating.d.ts +21 -4
  212. package/types/app/identity/delegating.d.ts.map +1 -1
  213. package/types/app/identity/delegation-approval.d.ts +228 -0
  214. package/types/app/identity/delegation-approval.d.ts.map +1 -0
  215. package/types/app/identity/event-completion.d.ts +151 -0
  216. package/types/app/identity/event-completion.d.ts.map +1 -0
  217. package/types/app/identity/habbing.d.ts +90 -7
  218. package/types/app/identity/habbing.d.ts.map +1 -1
  219. package/types/app/identity/keeping.d.ts +50 -4
  220. package/types/app/identity/keeping.d.ts.map +1 -1
  221. package/types/app/identity/lmdb-habery.d.ts +6 -0
  222. package/types/app/identity/lmdb-habery.d.ts.map +1 -0
  223. package/types/app/ipex/group-ipex.d.ts +247 -0
  224. package/types/app/ipex/group-ipex.d.ts.map +1 -0
  225. package/types/app/ipex/group-issuance.d.ts +281 -0
  226. package/types/app/ipex/group-issuance.d.ts.map +1 -0
  227. package/types/app/ipex/ipex-admitting.d.ts +47 -0
  228. package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
  229. package/types/app/ipex/ipex-conversation.d.ts +195 -0
  230. package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
  231. package/types/app/ipex/ipex-discloser.d.ts +156 -0
  232. package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
  233. package/types/app/ipex/ipex-granting.d.ts +145 -0
  234. package/types/app/ipex/ipex-granting.d.ts.map +1 -0
  235. package/types/app/ipex/ipex-graph.d.ts +4 -4
  236. package/types/app/ipex/ipex-graph.d.ts.map +1 -1
  237. package/types/app/ipex/ipex-grouping.d.ts +18 -0
  238. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  239. package/types/app/ipex/ipex-v2.d.ts +11 -2
  240. package/types/app/ipex/ipex-v2.d.ts.map +1 -1
  241. package/types/app/ipex/ipexing.d.ts +3 -0
  242. package/types/app/ipex/ipexing.d.ts.map +1 -1
  243. package/types/app/ipex/issuance.d.ts +443 -0
  244. package/types/app/ipex/issuance.d.ts.map +1 -0
  245. package/types/app/ipex/pending-presentations.d.ts +25 -0
  246. package/types/app/ipex/pending-presentations.d.ts.map +1 -0
  247. package/types/app/ipex/presentation-files.d.ts +47 -0
  248. package/types/app/ipex/presentation-files.d.ts.map +1 -0
  249. package/types/app/ipex/presenting.d.ts +298 -0
  250. package/types/app/ipex/presenting.d.ts.map +1 -0
  251. package/types/app/ipex/receive-issuance.d.ts +99 -0
  252. package/types/app/ipex/receive-issuance.d.ts.map +1 -0
  253. package/types/app/ipex/unblinding-workflow.d.ts +255 -0
  254. package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
  255. package/types/app/mailbox/ipex-arrival.d.ts +104 -0
  256. package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
  257. package/types/app/mailbox/kel-publisher.d.ts +141 -0
  258. package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
  259. package/types/app/mailbox/kel-publishing.d.ts +70 -0
  260. package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
  261. package/types/app/mailbox/kel-submission.d.ts +18 -0
  262. package/types/app/mailbox/kel-submission.d.ts.map +1 -0
  263. package/types/app/mailbox/mailbox-admin.d.ts +113 -0
  264. package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
  265. package/types/app/mailbox/mailbox-poller.d.ts +92 -3
  266. package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
  267. package/types/app/mailbox/mailboxing.d.ts +4 -1
  268. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  269. package/types/app/multisig/counseling.d.ts +196 -0
  270. package/types/app/multisig/counseling.d.ts.map +1 -0
  271. package/types/app/multisig/group-members.d.ts +20 -0
  272. package/types/app/multisig/group-members.d.ts.map +1 -1
  273. package/types/app/multisig/grouping.d.ts +39 -20
  274. package/types/app/multisig/grouping.d.ts.map +1 -1
  275. package/types/app/multisig/multisig-workflows.d.ts +93 -23
  276. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  277. package/types/app/multisig/proposals.d.ts +129 -0
  278. package/types/app/multisig/proposals.d.ts.map +1 -0
  279. package/types/app/multisig/proposing.d.ts +125 -0
  280. package/types/app/multisig/proposing.d.ts.map +1 -0
  281. package/types/app/notifications/notifying.d.ts +1 -1
  282. package/types/app/notifications/notifying.d.ts.map +1 -1
  283. package/types/app/notifications/signaling.d.ts +3 -1
  284. package/types/app/notifications/signaling.d.ts.map +1 -1
  285. package/types/app/protocol/parsering.d.ts +16 -1
  286. package/types/app/protocol/parsering.d.ts.map +1 -1
  287. package/types/app/protocol/protocol-processing.d.ts +9 -1
  288. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  289. package/types/app/queries/query-workflows.d.ts +98 -0
  290. package/types/app/queries/query-workflows.d.ts.map +1 -0
  291. package/types/app/runtime/agent-runtime.d.ts +79 -25
  292. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  293. package/types/app/runtime/cue-runtime.d.ts +2 -1
  294. package/types/app/runtime/cue-runtime.d.ts.map +1 -1
  295. package/types/app/runtime/delivery-outbox.d.ts +68 -0
  296. package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
  297. package/types/app/runtime/doing.d.ts +27 -0
  298. package/types/app/runtime/doing.d.ts.map +1 -0
  299. package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
  300. package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
  301. package/types/app/runtime/operation-owners.d.ts +137 -0
  302. package/types/app/runtime/operation-owners.d.ts.map +1 -0
  303. package/types/app/runtime/retry-backoff.d.ts +49 -0
  304. package/types/app/runtime/retry-backoff.d.ts.map +1 -0
  305. package/types/app/runtime/workflow-contract.d.ts +79 -0
  306. package/types/app/runtime/workflow-contract.d.ts.map +1 -0
  307. package/types/app/transport/byte-source.d.ts +13 -10
  308. package/types/app/transport/byte-source.d.ts.map +1 -1
  309. package/types/app/transport/cesr-egress.d.ts +21 -7
  310. package/types/app/transport/cesr-egress.d.ts.map +1 -1
  311. package/types/app/transport/file-bytes.d.ts +11 -0
  312. package/types/app/transport/file-bytes.d.ts.map +1 -0
  313. package/types/app/transport/http-client.d.ts +3 -0
  314. package/types/app/transport/http-client.d.ts.map +1 -1
  315. package/types/app/transport/http-messenger.d.ts +15 -10
  316. package/types/app/transport/http-messenger.d.ts.map +1 -1
  317. package/types/app/transport/message-source.d.ts +1 -1
  318. package/types/app/transport/messengering.d.ts +2 -2
  319. package/types/app/transport/messengering.d.ts.map +1 -1
  320. package/types/app/transport/node-http-client.d.ts +10 -0
  321. package/types/app/transport/node-http-client.d.ts.map +1 -0
  322. package/types/app/transport/tcp-dialer.d.ts +21 -0
  323. package/types/app/transport/tcp-dialer.d.ts.map +1 -0
  324. package/types/cli/common/event-completion.d.ts +26 -0
  325. package/types/cli/common/event-completion.d.ts.map +1 -0
  326. package/types/cli/common/existing.d.ts.map +1 -1
  327. package/types/cli/common/runtime-workers.d.ts +23 -0
  328. package/types/cli/common/runtime-workers.d.ts.map +1 -0
  329. package/types/cli/credentials/ipex.d.ts.map +1 -1
  330. package/types/cli/credentials/vc.d.ts +1 -1
  331. package/types/cli/credentials/vc.d.ts.map +1 -1
  332. package/types/cli/endpoints/did.d.ts.map +1 -1
  333. package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
  334. package/types/cli/endpoints/oobi.d.ts +3 -1
  335. package/types/cli/endpoints/oobi.d.ts.map +1 -1
  336. package/types/cli/identity/challenge.d.ts +1 -1
  337. package/types/cli/identity/challenge.d.ts.map +1 -1
  338. package/types/cli/identity/delegate.d.ts +14 -1
  339. package/types/cli/identity/delegate.d.ts.map +1 -1
  340. package/types/cli/identity/incept.d.ts.map +1 -1
  341. package/types/cli/identity/init.d.ts.map +1 -1
  342. package/types/cli/identity/interact.d.ts.map +1 -1
  343. package/types/cli/identity/rotate.d.ts.map +1 -1
  344. package/types/cli/index.d.ts +4 -2
  345. package/types/cli/index.d.ts.map +1 -1
  346. package/types/cli/messaging/group-join.d.ts +53 -0
  347. package/types/cli/messaging/group-join.d.ts.map +1 -0
  348. package/types/cli/messaging/group-wait.d.ts +34 -0
  349. package/types/cli/messaging/group-wait.d.ts.map +1 -0
  350. package/types/cli/messaging/multisig.d.ts +36 -4
  351. package/types/cli/messaging/multisig.d.ts.map +1 -1
  352. package/types/cli/messaging/root-copy-lines.d.ts +39 -0
  353. package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
  354. package/types/cli/tools/annotate.d.ts.map +1 -1
  355. package/types/cli/tools/benchmark.d.ts.map +1 -1
  356. package/types/cli/tools/db-dump.d.ts.map +1 -1
  357. package/types/core/bytes.d.ts +2 -0
  358. package/types/core/bytes.d.ts.map +1 -1
  359. package/types/core/cues.d.ts +11 -0
  360. package/types/core/cues.d.ts.map +1 -1
  361. package/types/core/kel/delegation-ancestry.d.ts +41 -0
  362. package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
  363. package/types/core/kel/eventing.d.ts.map +1 -1
  364. package/types/core/kel/kever.d.ts +5 -4
  365. package/types/core/kel/kever.d.ts.map +1 -1
  366. package/types/core/mailbox/kram-policy.d.ts +14 -0
  367. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  368. package/types/core/mailbox/kram-pruning.d.ts +1 -3
  369. package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
  370. package/types/core/mailbox/kraming.d.ts +1 -1
  371. package/types/core/mailbox/kraming.d.ts.map +1 -1
  372. package/types/core/records.d.ts +61 -0
  373. package/types/core/records.d.ts.map +1 -1
  374. package/types/core/routing.d.ts +6 -0
  375. package/types/core/routing.d.ts.map +1 -1
  376. package/types/db/basing.d.ts +22 -25
  377. package/types/db/basing.d.ts.map +1 -1
  378. package/types/db/core/dber.d.ts +505 -0
  379. package/types/db/core/dber.d.ts.map +1 -0
  380. package/types/db/core/index.d.ts +4 -2
  381. package/types/db/core/index.d.ts.map +1 -1
  382. package/types/db/core/indexeddb-persistence.d.ts +59 -0
  383. package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
  384. package/types/db/core/lmdb-opener.d.ts +17 -0
  385. package/types/db/core/lmdb-opener.d.ts.map +1 -0
  386. package/types/db/core/lmdber.d.ts +60 -383
  387. package/types/db/core/lmdber.d.ts.map +1 -1
  388. package/types/db/core/memstore.d.ts +129 -0
  389. package/types/db/core/memstore.d.ts.map +1 -0
  390. package/types/db/core/path-manager.d.ts +22 -45
  391. package/types/db/core/path-manager.d.ts.map +1 -1
  392. package/types/db/core/store-owner.d.ts +59 -0
  393. package/types/db/core/store-owner.d.ts.map +1 -0
  394. package/types/db/core/webdber.d.ts +127 -0
  395. package/types/db/core/webdber.d.ts.map +1 -0
  396. package/types/db/escrowing.d.ts +3 -3
  397. package/types/db/escrowing.d.ts.map +1 -1
  398. package/types/db/exchange/exchange-nests.d.ts.map +1 -1
  399. package/types/db/indexeddb.d.ts +37 -0
  400. package/types/db/indexeddb.d.ts.map +1 -0
  401. package/types/db/keeping.d.ts +14 -25
  402. package/types/db/keeping.d.ts.map +1 -1
  403. package/types/db/koming.d.ts +7 -8
  404. package/types/db/koming.d.ts.map +1 -1
  405. package/types/db/lmdb-stores.d.ts +45 -0
  406. package/types/db/lmdb-stores.d.ts.map +1 -0
  407. package/types/db/lmdb.d.ts +7 -0
  408. package/types/db/lmdb.d.ts.map +1 -0
  409. package/types/db/mailbox/mailboxing.d.ts +7 -21
  410. package/types/db/mailbox/mailboxing.d.ts.map +1 -1
  411. package/types/db/noting.d.ts +7 -12
  412. package/types/db/noting.d.ts.map +1 -1
  413. package/types/db/reger.d.ts +7 -11
  414. package/types/db/reger.d.ts.map +1 -1
  415. package/types/db/replay/witness-replay.d.ts +0 -2
  416. package/types/db/replay/witness-replay.d.ts.map +1 -1
  417. package/types/db/store-lock.d.ts +72 -0
  418. package/types/db/store-lock.d.ts.map +1 -0
  419. package/types/db/subing.d.ts +24 -25
  420. package/types/db/subing.d.ts.map +1 -1
  421. package/types/npm/db-indexeddb.d.ts +4 -0
  422. package/types/npm/db-indexeddb.d.ts.map +1 -0
  423. package/types/npm/db-lmdb.d.ts +4 -0
  424. package/types/npm/db-lmdb.d.ts.map +1 -0
  425. package/types/npm/runtime-node.d.ts +4 -0
  426. package/types/npm/runtime-node.d.ts.map +1 -0
  427. package/types/npm/runtime-web.d.ts +4 -0
  428. package/types/npm/runtime-web.d.ts.map +1 -0
  429. package/types/runtime/index.d.ts +48 -14
  430. package/types/runtime/index.d.ts.map +1 -1
  431. package/types/runtime/node.d.ts +15 -0
  432. package/types/runtime/node.d.ts.map +1 -0
  433. package/types/runtime/web/output-barrier.d.ts +30 -0
  434. package/types/runtime/web/output-barrier.d.ts.map +1 -0
  435. package/types/runtime/web/persistent-storage.d.ts +36 -0
  436. package/types/runtime/web/persistent-storage.d.ts.map +1 -0
  437. package/types/runtime/web.d.ts +11 -0
  438. package/types/runtime/web.d.ts.map +1 -0
  439. package/types/vdr/tel-publication.d.ts +6 -0
  440. package/types/vdr/tel-publication.d.ts.map +1 -1
  441. package/types/version.d.ts +2 -2
  442. package/esm/keri/npm/src/acdc/relating.js +0 -59
  443. package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
  444. package/esm/keri/npm/src/db/baser-defaults.js +0 -11
  445. package/types/acdc/relating.d.ts +0 -21
  446. package/types/acdc/relating.d.ts.map +0 -1
  447. package/types/cli/common/tel-completion.d.ts +0 -8
  448. package/types/cli/common/tel-completion.d.ts.map +0 -1
  449. package/types/db/baser-defaults.d.ts +0 -5
  450. package/types/db/baser-defaults.d.ts.map +0 -1
@@ -1,7 +1,8 @@
1
1
  /** Public ACDC registry database layout and joined LMDB lifecycle. */
2
- import { b, Diger, NumberPrimitive, Saider, SerderACDC } from "cesr-ts";
3
- import { DatabaseNotOpenError } from "../core/errors.js";
4
- import { LMDBer } from "../db/core/lmdber.js";
2
+ import { Diger, NumberPrimitive, Saider, SerderACDC } from "cesr-ts";
3
+ import { DerivedUpdateRecord } from "../core/records.js";
4
+ import { StoreOwner } from "../db/core/store-owner.js";
5
+ import { Komer } from "../db/koming.js";
5
6
  import { B64OnIoSetSuber, BytesSuber, CatCesrSuber, CesrOnSuber, CesrSuber, SerderSuber } from "../db/subing.js";
6
7
  /**
7
8
  * Own one environment for public registry TEL bodies, accepted ordinals and heads.
@@ -9,24 +10,9 @@ import { B64OnIoSetSuber, BytesSuber, CatCesrSuber, CesrOnSuber, CesrSuber, Serd
9
10
  * evidence nor migrates rows. Every current store has anchor and escrow tables.
10
11
  * Construction stays closed; callers own reopen and joined close.
11
12
  */
12
- export class RegBaser extends LMDBer {
13
- /** Named databases are root entries; testing presence opens no additional handles. */
14
- hasTable(name) {
15
- if (!this.env)
16
- throw new DatabaseNotOpenError("Registry environment is closed.");
17
- // Native lmdb-js exposes its C-string terminator in root metadata keys;
18
- // the Deno backend also supports the unterminated representation.
19
- return this.env.getBinary(b(name)) !== undefined
20
- || this.env.getBinary(b(`${name}\0`)) !== undefined;
21
- }
22
- constructor(options = {}) {
23
- super(options, {
24
- tailDirPath: "keri/acdc/reg",
25
- cleanTailDirPath: "keri/clean/acdc/reg",
26
- altTailDirPath: options.compat ? ".keri/acdc/reg" : ".tufa/acdc/reg",
27
- altCleanTailDirPath: options.compat ? ".keri/clean/acdc/reg" : ".tufa/clean/acdc/reg",
28
- tempPrefix: "keri_acdc_reg_",
29
- });
13
+ export class RegBaser extends StoreOwner {
14
+ constructor() {
15
+ super(...arguments);
30
16
  /** Event-SAID -> parsed rip/bup body; body presence alone is not acceptance. */
31
17
  Object.defineProperty(this, "evts", {
32
18
  enumerable: true,
@@ -55,6 +41,13 @@ export class RegBaser extends LMDBer {
55
41
  writable: true,
56
42
  value: void 0
57
43
  });
44
+ /** keri-ts only. BUP SAID -> public blind-derivation coordinates; never a salt or opening. */
45
+ Object.defineProperty(this, "dvus", {
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true,
49
+ value: void 0
50
+ });
58
51
  /** Event-SAID -> earliest verified KEL source couple, in the current store. */
59
52
  Object.defineProperty(this, "ancs", {
60
53
  enumerable: true,
@@ -79,17 +72,18 @@ export class RegBaser extends LMDBer {
79
72
  }
80
73
  /** Rebind the same environment's typed tables after every joined reopen. */
81
74
  *reopen(options = {}) {
82
- const opened = yield* super.reopen(options);
75
+ const opened = yield* this.store.reopen(options);
83
76
  if (!opened)
84
77
  return false;
85
78
  try {
86
- this.evts = new SerderSuber(this, { subkey: "evts.", ctor: SerderACDC });
87
- this.tels = new CesrOnSuber(this, { subkey: "tels.", ctor: Saider });
88
- this.heads = new CesrSuber(this, { subkey: "heds.", ctor: Saider });
89
- this.openings = new BytesSuber(this, { subkey: "openings." });
90
- this.ancs = new CatCesrSuber(this, { subkey: "ancs.", ctor: [NumberPrimitive, Diger] });
91
- this.maes = new B64OnIoSetSuber(this, { subkey: "maes." });
92
- this.ooes = new B64OnIoSetSuber(this, { subkey: "ooes." });
79
+ this.evts = new SerderSuber(this.store, { subkey: "evts.", ctor: SerderACDC });
80
+ this.tels = new CesrOnSuber(this.store, { subkey: "tels.", ctor: Saider });
81
+ this.heads = new CesrSuber(this.store, { subkey: "heds.", ctor: Saider });
82
+ this.openings = new BytesSuber(this.store, { subkey: "openings." });
83
+ this.dvus = new Komer(this.store, { subkey: "dvus.", recordClass: DerivedUpdateRecord });
84
+ this.ancs = new CatCesrSuber(this.store, { subkey: "ancs.", ctor: [NumberPrimitive, Diger] });
85
+ this.maes = new B64OnIoSetSuber(this.store, { subkey: "maes." });
86
+ this.ooes = new B64OnIoSetSuber(this.store, { subkey: "ooes." });
93
87
  return true;
94
88
  }
95
89
  catch (error) {
@@ -98,3 +92,10 @@ export class RegBaser extends LMDBer {
98
92
  }
99
93
  }
100
94
  }
95
+ /** Placement of this store kind. */
96
+ Object.defineProperty(RegBaser, "Family", {
97
+ enumerable: true,
98
+ configurable: true,
99
+ writable: true,
100
+ value: { tail: "acdc/reg" }
101
+ });
@@ -256,12 +256,11 @@ export class RegistryEventer {
256
256
  const previous = this.acceptedEvent(event);
257
257
  if (previous)
258
258
  return previous;
259
- const env = this.store.baser.env;
260
- if (!env)
259
+ if (!this.store.baser.opened)
261
260
  throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
262
261
  if (this.store.baser.readonly)
263
262
  throw new DatabaseOperationError("Cannot write readonly registry storage.");
264
- return env.transactionSync(() => {
263
+ return this.store.baser.transaction(() => {
265
264
  const prior = this.acceptedAt(event.regid, Number(event.sn) - 1);
266
265
  if (prior && prior.said !== event.prior)
267
266
  return { kind: "reject", reason: "prior" };
@@ -303,12 +302,11 @@ export class RegistryEventer {
303
302
  this.regk = event.regid;
304
303
  return previous;
305
304
  }
306
- const env = this.store.baser.env;
307
- if (!env)
305
+ if (!this.store.baser.opened)
308
306
  throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
309
307
  if (this.store.baser.readonly)
310
308
  throw new DatabaseOperationError("Cannot write readonly registry storage.");
311
- const decision = env.transactionSync(() => {
309
+ const decision = this.store.baser.transaction(() => {
312
310
  const previous = this.acceptedEvent(event);
313
311
  if (previous)
314
312
  return previous;
@@ -37,10 +37,13 @@ function retainedOpening(raw) {
37
37
  export class RegistryRecord extends RawRecord {
38
38
  }
39
39
  /** Acquire one backing owner; failures/cancellation join cleanup before ownership transfers. */
40
- export function* openRegistry({ web = false, reopen = true, ...options } = {}) {
41
- if (web)
42
- throw new ValidationError("web registry backend is not yet supported by V2 Regery");
43
- const baser = new RegBaser(options);
40
+ export function* openRegistry({ reopen = true, opener, ...options } = {}) {
41
+ if (!opener)
42
+ throw new ValidationError("A registry store needs a store opener.");
43
+ return yield* adoptRegistry(new RegBaser(opener.create(RegBaser.Family, options)), reopen);
44
+ }
45
+ /** Take ownership of a constructed registry owner, reopening it unless told otherwise. */
46
+ export function* adoptRegistry(baser, reopen = true) {
44
47
  let delivered = false;
45
48
  try {
46
49
  if (reopen && !(yield* baser.reopen()))
@@ -81,7 +84,7 @@ export class RegistryStore {
81
84
  writable: true,
82
85
  value: null
83
86
  });
84
- Object.defineProperty(this, "aliasEnv", {
87
+ Object.defineProperty(this, "aliasTable", {
85
88
  enumerable: true,
86
89
  configurable: true,
87
90
  writable: true,
@@ -90,13 +93,13 @@ export class RegistryStore {
90
93
  }
91
94
  /** Local alias mapper is optional; refresh it after the owner's reopen. */
92
95
  get records() {
93
- if (!this.baser.env)
96
+ if (!this.baser.opened)
94
97
  throw new DatabaseNotOpenError("Registry backing store is closed.");
95
- if (this.aliasEnv !== this.baser.env) {
98
+ if (this.aliasTable !== this.baser.evts.sdb) {
96
99
  this.aliases = this.baser.hasTable("regs.")
97
- ? new Komer(this.baser, { subkey: "regs.", recordClass: RegistryRecord })
100
+ ? new Komer(this.baser.store, { subkey: "regs.", recordClass: RegistryRecord })
98
101
  : null;
99
- this.aliasEnv = this.baser.env;
102
+ this.aliasTable = this.baser.evts.sdb;
100
103
  }
101
104
  return this.aliases;
102
105
  }
@@ -110,7 +113,7 @@ export class RegistryStore {
110
113
  if (!records) {
111
114
  if (this.baser.readonly)
112
115
  throw new DatabaseOperationError("Cannot create readonly registry aliases.");
113
- records = this.aliases = new Komer(this.baser, { subkey: "regs.", recordClass: RegistryRecord });
116
+ records = this.aliases = new Komer(this.baser.store, { subkey: "regs.", recordClass: RegistryRecord });
114
117
  }
115
118
  return records;
116
119
  }
@@ -13,12 +13,8 @@ export function* createRegery({ hby, baser, ...options }) {
13
13
  try {
14
14
  if (!baser) {
15
15
  baser = yield* openRegistry({
16
- name: hby.name,
17
- base: hby.base,
18
- temp: hby.temp,
19
- headDirPath: hby.headDirPath,
20
- compat: hby.compat,
21
- readonly: hby.readonly,
16
+ ...hby.storeIdentity(),
17
+ opener: hby.opener,
22
18
  ...options,
23
19
  });
24
20
  }
@@ -90,12 +86,11 @@ export class Regery {
90
86
  const rip = regcept(hab.pre, options);
91
87
  if (this.regs.has(rip.said))
92
88
  throw new ValidationError(`Registry already exists: ${rip.said}`);
93
- const env = this.baser.env;
94
- if (!env)
89
+ if (!this.baser.opened)
95
90
  throw new DatabaseNotOpenError("Registry backing store is closed.");
96
91
  const records = this.store.initializeRecords();
97
92
  const registry = new Registry(hab, this.store, name);
98
- env.transactionSync(() => {
93
+ this.baser.transaction(() => {
99
94
  if (records.get(name))
100
95
  throw new ValidationError(`Registry alias already exists: ${name}`);
101
96
  const result = registry.processEvent(rip);
@@ -1,8 +1,10 @@
1
1
  /**
2
- * Explicit encrypted copies of existing registry roots.
2
+ * Encrypted copies of existing registry roots.
3
3
  *
4
4
  * `RegistryRoot` replicates held roots to individual members with ESSR `exn`
5
5
  * messages, ported from KERIpy `keri.acdc.salting` (kentbull/keripy v2-spec).
6
+ * Operators send them explicitly; group issuance completion and accepted group
7
+ * rotations also send them, fire and forget (`app/credentials/root-replicating.ts`).
6
8
  *
7
9
  * Local profile, not a KERI, ACDC or #1740 standard. Upstream KERIpy uses ESSR
8
10
  * only as the v1 `/essr/req` transport envelope on direct sends.
@@ -19,9 +21,12 @@
19
21
  * dependency escrow (`Baser.rrpe`, no timeout) that `processEscrows` retries.
20
22
  */
21
23
  import { concatBytes, Counter, Dater, Diger, Encrypter, essrChunks, Kinds, LabelDex, makeBlindUuid, MtrDex, ParserError, Prefixer, Saider, Salter, Texter, unblindBlindState, unblindBoundState, Vrsn_2_0, } from "cesr-ts";
22
- import { groupWitnesserSelection, isLocalGroupHab } from "../app/multisig/group-members.js";
24
+ import { groupWitnesserSelection, isLocalGroupHab, localGroupMember } from "../app/multisig/group-members.js";
23
25
  import { ValidationError } from "../core/errors.js";
26
+ import { Kever } from "../core/kel/kever.js";
24
27
  import { exchange } from "../core/protocol-eventing.js";
28
+ import { dgKey } from "../db/core/keys.js";
29
+ import { hasNests, loadNests } from "../db/exchange/exchange-nests.js";
25
30
  import { makeNowIso8601 } from "../time/mod.js";
26
31
  import { validateRip, validateUpdate, verifyRegistryAnchor, vetBlind } from "./regeventing.js";
27
32
  /** A stored registry-root copy that can never be retained as received. */
@@ -65,9 +70,9 @@ function contribution(db, member, verfers) {
65
70
  const event = db.getEvtSerder(member, said);
66
71
  if (!event?.estive)
67
72
  continue;
68
- const index = keys.indexOf(event.verfers[0]?.qb64 ?? "");
73
+ const key = event.verfers[0]?.qb64 ?? "", index = keys.indexOf(key);
69
74
  if (index >= 0)
70
- return { sn, index };
75
+ return { sn, index, key };
71
76
  }
72
77
  return null;
73
78
  }
@@ -172,7 +177,7 @@ export function rootExn(hab, recipient, gid, registry, root, { event, td }) {
172
177
  * keeps the copy escrowed rather than refusing it.
173
178
  */
174
179
  export class RegistryRoot {
175
- constructor(hby, rgy, notifier = null) {
180
+ constructor(hby, rgy, notifier = null, changes) {
176
181
  Object.defineProperty(this, "resource", {
177
182
  enumerable: true,
178
183
  configurable: true,
@@ -203,11 +208,19 @@ export class RegistryRoot {
203
208
  writable: true,
204
209
  value: void 0
205
210
  });
211
+ /** Told `{kind: "root", id: registry}` after a copy is retained, so an embedder that waited for the root can act. */
212
+ Object.defineProperty(this, "changes", {
213
+ enumerable: true,
214
+ configurable: true,
215
+ writable: true,
216
+ value: void 0
217
+ });
206
218
  if (rgy.hby !== hby)
207
219
  throw new ValidationError("registry root replication requires the Habery's registry owner");
208
220
  this.hby = hby;
209
221
  this.rgy = rgy;
210
222
  this.notifier = notifier;
223
+ this.changes = changes;
211
224
  if (!hby.readonly)
212
225
  this.reconcile();
213
226
  }
@@ -290,14 +303,8 @@ export class RegistryRoot {
290
303
  }
291
304
  return rip;
292
305
  }
293
- /**
294
- * Return current signing member AIDs added by one accepted group rotation.
295
- *
296
- * Members, not keys, are compared: a continuing member usually rotates its
297
- * own key, so it contributes to both establishments. Candidates are the AIDs
298
- * with accepted key state in this Habery.
299
- */
300
- newcomers(ghab, rotation) {
306
+ /** Return `ghab`'s accepted `rotation` and the establishment before it; ValidationError otherwise. */
307
+ rotation(ghab, rotation) {
301
308
  const db = this.hby.db, pre = ghab.pre;
302
309
  if (!pre || ghab.db !== db || !isLocalGroupHab(this.hby, ghab)) {
303
310
  throw new ValidationError("newcomers require a local group habitat");
@@ -306,29 +313,59 @@ export class RegistryRoot {
306
313
  if (!event || !["rot", "drt"].includes(event.ilk) || db.kels.getLast(pre, event.sn) !== rotation) {
307
314
  throw new ValidationError("newcomers require an accepted group rotation");
308
315
  }
309
- let prior = null;
310
316
  for (const [, sn, said] of db.kels.getOnItemBackIter(pre, event.sn - 1)) {
311
317
  if (db.kels.getLast(pre, sn) !== said)
312
318
  continue;
313
319
  const candidate = db.getEvtSerder(pre, said);
314
- if (candidate?.estive) {
315
- prior = candidate;
316
- break;
317
- }
320
+ if (candidate?.estive)
321
+ return [event, candidate];
318
322
  }
319
- if (!prior)
320
- throw new ValidationError("rotation has no accepted prior establishment");
323
+ throw new ValidationError("rotation has no accepted prior establishment");
324
+ }
325
+ /**
326
+ * Return current signing member AIDs added by one accepted group rotation.
327
+ *
328
+ * Members, not keys, are compared: a continuing member usually rotates its
329
+ * own key, so it contributes to both establishments. `rekeyed` also returns
330
+ * continuing members whose contributing key changed, the recipients a
331
+ * re-seal must reach under their new key. Candidates are the AIDs with
332
+ * accepted key state in this Habery.
333
+ */
334
+ newcomers(ghab, rotation, { rekeyed = false } = {}) {
335
+ const db = this.hby.db, pre = ghab.pre, [event, prior] = this.rotation(ghab, rotation);
321
336
  const found = [];
322
337
  for (const [keys] of db.states.getTopItemIter()) {
323
338
  const aid = keys.join(".");
324
339
  if (aid === pre || !db.getKever(aid))
325
340
  continue;
326
- const added = contribution(db, aid, event.verfers);
327
- if (added && !contribution(db, aid, prior.verfers) && this.current(aid, pre))
341
+ const added = contribution(db, aid, event.verfers), before = contribution(db, aid, prior.verfers);
342
+ if (added && this.current(aid, pre) && (!before || rekeyed && before.key !== added.key)) {
328
343
  found.push([added.index, aid]);
344
+ }
329
345
  }
330
346
  return found.sort((left, right) => left[0] - right[0]).map(([, aid]) => aid);
331
347
  }
348
+ /**
349
+ * Return the members `ghab`'s local member re-seals held roots to after `rotation`.
350
+ *
351
+ * Only a signer of the accepted rotation that held a key in the prior
352
+ * establishment sends, and it sends to each current signing member that is
353
+ * new in the rotation or whose contributing key changed (`newcomers` with
354
+ * `rekeyed`). Every such signer sends: copies are idempotent, so no single
355
+ * sender is elected. An empty list means nothing is owed.
356
+ */
357
+ resealed(ghab, rotation) {
358
+ const recipients = this.newcomers(ghab, rotation, { rekeyed: true });
359
+ const db = this.hby.db, [event, prior] = this.rotation(ghab, rotation);
360
+ const member = localGroupMember(this.hby, ghab.pre).pre;
361
+ const own = contribution(db, member, event.verfers);
362
+ if (!own || !contribution(db, member, prior.verfers))
363
+ return [];
364
+ const { indices } = Kever.verifyIndexedSignatures(event.raw, db.sigs.get(dgKey(ghab.pre, rotation)), event.verfers);
365
+ if (!indices.includes(own.index))
366
+ return [];
367
+ return recipients.filter(aid => aid !== member);
368
+ }
332
369
  /** Return the current signing member AIDs of `gid` known to this Habery. */
333
370
  members(gid) {
334
371
  const db = this.hby.db, gkever = db.getKever(gid), found = [];
@@ -342,6 +379,11 @@ export class RegistryRoot {
342
379
  }
343
380
  return found.sort((left, right) => left[0] - right[0]).map(([, aid]) => aid);
344
381
  }
382
+ /** Public key by which `member` currently contributes to `gid`, or null while not a known current signing member. */
383
+ contributor(gid, member) {
384
+ const gkever = this.hby.db.getKever(gid);
385
+ return gkever ? contribution(this.hby.db, member, gkever.verfers)?.key ?? null : null;
386
+ }
345
387
  /** Return the registry SAIDs with a root retained locally for `gid`. */
346
388
  held(gid) {
347
389
  const found = [];
@@ -365,10 +407,17 @@ export class RegistryRoot {
365
407
  // sending
366
408
  /**
367
409
  * Return one authorized copy of a root held locally for `gid` or the issuer.
410
+ *
368
411
  * `hab` is the local individual sender. `event` defaults to the registry's
369
- * accepted BUP head.
412
+ * accepted BUP head. `td` is the recipient's verification hint: omitted, it
413
+ * is derived for this registry (`hint`); `""` sends none; any other value is
414
+ * an override. Before sealing, a derived or override hint must let this
415
+ * sender's own root reproduce the BUP `b` commitment, so a copy never carries
416
+ * a hint that cannot verify it. `hinted` refuses with RootUnverified, instead
417
+ * of sending a copy without a hint, when no local evidence yields one;
418
+ * automatic sends set it.
370
419
  */
371
- prepare(hab, recipient, gid, registry, { event, td } = {}) {
420
+ prepare(hab, recipient, gid, registry, { event, td, hinted = false } = {}) {
372
421
  const rip = this.authorize(hab.pre, recipient, gid, registry);
373
422
  let root = null;
374
423
  for (const holder of [gid, rip.issuer]) {
@@ -380,8 +429,74 @@ export class RegistryRoot {
380
429
  }
381
430
  if (!root)
382
431
  throw new ValidationError("no local root is held for this registry");
383
- const [bup] = this.event(registry, event ?? this.rgy.store.headEvent(registry).said, rip);
384
- return rootExn(hab, recipient, gid, registry, root, { event: bup.said, td });
432
+ const [bup, sn] = this.event(registry, event ?? this.rgy.store.headEvent(registry).said, rip);
433
+ const uuid = makeBlindUuid({ salt: root.qb64, sn }).qb64;
434
+ let hint = td;
435
+ if (hint === undefined) {
436
+ hint = this.hint(gid, registry, uuid, bup) ?? undefined;
437
+ if (hint === undefined && hinted) {
438
+ throw new RootUnverified(`no held opening or stored Grant ACDC lets this root reproduce registry ${registry} update ${bup.said}; `
439
+ + "send it with an ACDC hint");
440
+ }
441
+ }
442
+ else if (hint && !this.reproduces(bup.sad.b, uuid, hint, gid)) {
443
+ throw new ValidationError(`the local root does not reproduce registry ${registry} update ${bup.said} with ACDC hint ${hint}`);
444
+ }
445
+ return rootExn(hab, recipient, gid, registry, root, { event: bup.said, td: hint });
446
+ }
447
+ /**
448
+ * Return the ACDC SAID by which `uuid` reproduces `bup`'s commitment, or null.
449
+ *
450
+ * Derived per registry, never shared across registries: the ACDC of the
451
+ * BUP's locally held opening first, then each ACDC of `registry` nested in a
452
+ * locally stored exchange. A candidate counts only when it reproduces the
453
+ * commitment, which is the sender self-check.
454
+ */
455
+ hint(gid, registry, uuid, bup) {
456
+ const held = this.rgy.store.publicOpening(bup.said)?.td.nonce;
457
+ const blid = bup.sad.b;
458
+ if (held && this.reproduces(blid, uuid, held, gid))
459
+ return held;
460
+ for (const td of this.acdcs(registry)) {
461
+ if (this.reproduces(blid, uuid, td, gid))
462
+ return td;
463
+ }
464
+ return null;
465
+ }
466
+ /**
467
+ * Yield SAIDs of ACDCs in `registry` nested in any locally stored exchange.
468
+ *
469
+ * A custodian finds them in its own `/ipex/grant`; a member holding only a
470
+ * received copy finds them nested in the `/multisig/exn` proposal it signed.
471
+ * Nests are walked recursively, so the wrapper depth does not matter, and no
472
+ * index table is needed. An exchange whose stored nests no longer decode is
473
+ * skipped: hint search is advisory and the self-check still guards the copy.
474
+ */
475
+ *acdcs(registry) {
476
+ const db = this.hby.db;
477
+ for (const [keys] of db.exns.getTopItemIter()) {
478
+ const said = keys.join(".");
479
+ if (!hasNests(db, said))
480
+ continue;
481
+ let nests;
482
+ try {
483
+ nests = loadNests(db, said);
484
+ }
485
+ catch (error) {
486
+ if (error instanceof ParserError || error instanceof ValidationError)
487
+ continue;
488
+ throw error;
489
+ }
490
+ yield* RegistryRoot.nested(nests, registry);
491
+ }
492
+ }
493
+ /** Depth-first SAIDs of nested bodies whose `rd` is `registry`. */
494
+ static *nested(nests, registry) {
495
+ for (const nest of nests) {
496
+ if (nest.body.ked?.rd === registry && nest.body.said)
497
+ yield nest.body.said;
498
+ yield* RegistryRoot.nested(nest.nests ?? [], registry);
499
+ }
385
500
  }
386
501
  // receiving
387
502
  /** Recheck exact accepted BUP membership and issuer anchoring; return the BUP and its ordinal. */
@@ -589,6 +704,8 @@ export class RegistryRoot {
589
704
  rd: registry,
590
705
  });
591
706
  }
707
+ if (added)
708
+ this.changes?.push({ kind: "root", id: registry });
592
709
  return added;
593
710
  }
594
711
  /** Try one escrowed copy: true retained, null still pending, false dropped. */
@@ -286,72 +286,111 @@ class SchemaResources {
286
286
  return root;
287
287
  }
288
288
  }
289
+ /** Most closures kept per store; the oldest is evicted first. */
290
+ const COMPILED_SCHEMA_BOUND = 256;
291
+ /**
292
+ * Compiled closures by store, then root SAID. A closure is fully determined by its root SAID: the root and every
293
+ * bundled or `$ref` resource is verified against its SAID when admitted, so a cached closure cannot go stale.
294
+ * Per store, so a store that does not hold the schema still reports it missing; only a valid closure is kept.
295
+ */
296
+ const compiledSchemas = new WeakMap();
297
+ let compilations = 0;
298
+ /** How many schema closures this process has compiled; a diagnostic for tests of the cache. */
299
+ export function schemaCompilationCount() {
300
+ return compilations;
301
+ }
302
+ function isCompiled(value) {
303
+ return "validate" in value;
304
+ }
305
+ /** Compile an admitted closure once; regular-expression and duplicate-id refusals are normal invalid outcomes. */
306
+ function compileClosure(resources, root) {
307
+ const { roots, scopes } = resources;
308
+ // Compile only admitted private copies. Canonical local URNs remove URI-alias ambiguity without changing stored IDs.
309
+ const uri = (said) => `urn:said:${said}`;
310
+ const registered = new Set();
311
+ const copy = (value) => {
312
+ if (Array.isArray(value))
313
+ return value.map(copy);
314
+ if (!object(value))
315
+ return value;
316
+ const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, copy(item)]));
317
+ const owner = scopes.get(value);
318
+ if (!owner)
319
+ return result;
320
+ if ("$id" in value) {
321
+ if (registered.has(owner.said))
322
+ delete result.$id;
323
+ else {
324
+ result.$id = uri(owner.said);
325
+ registered.add(owner.said);
326
+ }
327
+ }
328
+ if ("$ref" in value) {
329
+ const parsed = reference(value.$ref);
330
+ result.$ref = uri(parsed.said ?? owner.said) + parsed.fragment;
331
+ }
332
+ // Python treats these AJV extension/obsolete applicator keywords as annotations.
333
+ for (const key of ["$async", "nullable", "dependencies", "additionalItems"])
334
+ delete result[key];
335
+ return result;
336
+ };
337
+ const validator = new ValidatorCtor({ strict: false, validateFormats: false });
338
+ for (const schema of scopes.keys()) {
339
+ if (!validator.validateSchema(schema))
340
+ throw new InvalidSchema("Invalid Draft 2020-12 schema");
341
+ }
342
+ const copies = roots.map(copy);
343
+ let validate;
344
+ try {
345
+ for (const schema of copies)
346
+ validator.addSchema(schema);
347
+ validate = validator.getSchema(uri(root.said));
348
+ }
349
+ catch (error) {
350
+ if (error instanceof SyntaxError && error.message.includes("regular expression")) {
351
+ return { kind: "invalid", subject: "schema", reason: error.message };
352
+ }
353
+ if (error instanceof Error && /^reference "urn:said:[^"]+" resolves to more than one schema$/.test(error.message)) {
354
+ return { kind: "invalid", subject: "schema", reason: error.message };
355
+ }
356
+ throw error;
357
+ }
358
+ if (!validate)
359
+ throw new Error("Admitted schema was not registered");
360
+ compilations++;
361
+ return { validator, validate };
362
+ }
289
363
  /** Local static schema closure plus a synchronous Draft 2020-12 validator; legacy Schemer behavior is unchanged. */
290
364
  export function validateSchema(acdc, db, override) {
291
- const resources = new SchemaResources(db);
292
365
  try {
366
+ // The closure is always admitted: that verifies every SAID, and the verified root SAID names the cached validator.
367
+ const resources = new SchemaResources(db);
293
368
  const root = resources.admit(override ?? acdc.schema);
294
369
  if (!root) {
295
370
  return resources.missing
296
371
  ? { kind: "missing", said: resources.missing }
297
372
  : { kind: "invalid", subject: "schema", reason: "Invalid ACDC schema field" };
298
373
  }
299
- const { roots, scopes } = resources;
300
- // Compile only admitted private copies. Canonical local URNs remove URI-alias ambiguity without changing stored IDs.
301
- const uri = (said) => `urn:said:${said}`;
302
- const registered = new Set();
303
- const copy = (value) => {
304
- if (Array.isArray(value))
305
- return value.map(copy);
306
- if (!object(value))
307
- return value;
308
- const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, copy(item)]));
309
- const owner = scopes.get(value);
310
- if (!owner)
311
- return result;
312
- if ("$id" in value) {
313
- if (registered.has(owner.said))
314
- delete result.$id;
315
- else {
316
- result.$id = uri(owner.said);
317
- registered.add(owner.said);
318
- }
374
+ // An override object is checked against the document it replaces each time and is never kept.
375
+ const keep = typeof override !== "object";
376
+ let store = compiledSchemas.get(db);
377
+ let compiled = keep ? store?.get(root.said) : undefined;
378
+ if (!compiled) {
379
+ const built = compileClosure(resources, root);
380
+ if (!isCompiled(built))
381
+ return built;
382
+ compiled = built;
383
+ if (keep) {
384
+ if (!store)
385
+ compiledSchemas.set(db, store = new Map());
386
+ if (store.size >= COMPILED_SCHEMA_BOUND)
387
+ store.delete(store.keys().next().value);
388
+ store.set(root.said, compiled);
319
389
  }
320
- if ("$ref" in value) {
321
- const parsed = reference(value.$ref);
322
- result.$ref = uri(parsed.said ?? owner.said) + parsed.fragment;
323
- }
324
- // Python treats these AJV extension/obsolete applicator keywords as annotations.
325
- for (const key of ["$async", "nullable", "dependencies", "additionalItems"])
326
- delete result[key];
327
- return result;
328
- };
329
- const validator = new ValidatorCtor({ strict: false, validateFormats: false });
330
- for (const schema of scopes.keys()) {
331
- if (!validator.validateSchema(schema))
332
- throw new InvalidSchema("Invalid Draft 2020-12 schema");
333
- }
334
- const copies = roots.map(copy);
335
- let validate;
336
- try {
337
- for (const schema of copies)
338
- validator.addSchema(schema);
339
- validate = validator.getSchema(uri(root.said));
340
- }
341
- catch (error) {
342
- if (error instanceof SyntaxError && error.message.includes("regular expression")) {
343
- return { kind: "invalid", subject: "schema", reason: error.message };
344
- }
345
- if (error instanceof Error && /^reference "urn:said:[^"]+" resolves to more than one schema$/.test(error.message)) {
346
- return { kind: "invalid", subject: "schema", reason: error.message };
347
- }
348
- throw error;
349
390
  }
350
- if (!validate)
351
- throw new Error("Admitted schema was not registered");
352
- return validate(acdc.sad)
391
+ return compiled.validate(acdc.sad)
353
392
  ? { kind: "valid" }
354
- : { kind: "invalid", subject: "credential", reason: validator.errorsText(validate.errors) };
393
+ : { kind: "invalid", subject: "credential", reason: compiled.validator.errorsText(compiled.validate.errors) };
355
394
  }
356
395
  catch (error) {
357
396
  if (error instanceof InvalidSchema)