keri-ts 2.2.4 → 2.2.6

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 (256) hide show
  1. package/esm/keri/npm/src/_dnt.polyfills.js +14 -14
  2. package/esm/keri/npm/src/acdc/dhking.js +29 -2
  3. package/esm/keri/npm/src/acdc/observing.js +10 -3
  4. package/esm/keri/npm/src/acdc/query-resend.js +74 -0
  5. package/esm/keri/npm/src/acdc/regengine.js +39 -9
  6. package/esm/keri/npm/src/acdc/regeventing.js +5 -3
  7. package/esm/keri/npm/src/acdc/registering.js +19 -0
  8. package/esm/keri/npm/src/acdc/salting.js +4 -0
  9. package/esm/keri/npm/src/acdc/unblinding.js +38 -3
  10. package/esm/keri/npm/src/app/bootstrap/authenticating.js +32 -10
  11. package/esm/keri/npm/src/app/bootstrap/oobiery.js +363 -30
  12. package/esm/keri/npm/src/app/credentials/credential-importing.js +33 -4
  13. package/esm/keri/npm/src/app/credentials/root-replicator.js +27 -15
  14. package/esm/keri/npm/src/app/credentials/schema-resolving.js +5 -1
  15. package/esm/keri/npm/src/app/credentials/tel-publishing.js +16 -7
  16. package/esm/keri/npm/src/app/delivery/forwarding.js +205 -44
  17. package/esm/keri/npm/src/app/delivery/relaying.js +232 -0
  18. package/esm/keri/npm/src/app/delivery/respondant.js +8 -5
  19. package/esm/keri/npm/src/app/exchanges/exchange-messaging.js +1 -1
  20. package/esm/keri/npm/src/app/exchanges/exchanging.js +65 -9
  21. package/esm/keri/npm/src/app/identity/delegating.js +66 -9
  22. package/esm/keri/npm/src/app/identity/habbing.js +190 -71
  23. package/esm/keri/npm/src/app/identity/keeping.js +111 -39
  24. package/esm/keri/npm/src/app/identity/retire-identifier.js +98 -0
  25. package/esm/keri/npm/src/app/ipex/disclosure-replaying.js +116 -0
  26. package/esm/keri/npm/src/app/ipex/group-ipex.js +122 -25
  27. package/esm/keri/npm/src/app/ipex/group-issuance.js +137 -37
  28. package/esm/keri/npm/src/app/ipex/ipex-discloser.js +94 -31
  29. package/esm/keri/npm/src/app/ipex/ipex-grouping.js +53 -3
  30. package/esm/keri/npm/src/app/ipex/ipex-v2.js +7 -2
  31. package/esm/keri/npm/src/app/ipex/issuance.js +147 -44
  32. package/esm/keri/npm/src/app/ipex/pending-presentations.js +4 -2
  33. package/esm/keri/npm/src/app/ipex/presenting.js +3 -18
  34. package/esm/keri/npm/src/app/ipex/receive-issuance.js +2 -1
  35. package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +39 -11
  36. package/esm/keri/npm/src/app/mailbox/agent-inbox.js +292 -0
  37. package/esm/keri/npm/src/app/mailbox/forward-handler.js +298 -52
  38. package/esm/keri/npm/src/app/mailbox/kel-publisher.js +26 -31
  39. package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +70 -62
  40. package/esm/keri/npm/src/app/mailbox/mailboxing.js +20 -4
  41. package/esm/keri/npm/src/app/multisig/counseling.js +71 -27
  42. package/esm/keri/npm/src/app/multisig/group-members.js +41 -5
  43. package/esm/keri/npm/src/app/multisig/grouping.js +50 -2
  44. package/esm/keri/npm/src/app/multisig/multisig-workflows.js +3 -18
  45. package/esm/keri/npm/src/app/multisig/proposing.js +1 -16
  46. package/esm/keri/npm/src/app/multisig/rejoin-group.js +99 -0
  47. package/esm/keri/npm/src/app/multisig/replace-member.js +29 -8
  48. package/esm/keri/npm/src/app/protocol/parsering.js +45 -17
  49. package/esm/keri/npm/src/app/protocol/protocol-processing.js +47 -21
  50. package/esm/keri/npm/src/app/queries/query-replies.js +0 -22
  51. package/esm/keri/npm/src/app/queries/relay-refresh.js +81 -0
  52. package/esm/keri/npm/src/app/queries/witness-inquisitor.js +180 -34
  53. package/esm/keri/npm/src/app/runtime/agent-runtime.js +42 -73
  54. package/esm/keri/npm/src/app/runtime/cue-runtime.js +45 -5
  55. package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +8 -1
  56. package/esm/keri/npm/src/app/runtime/operation-owners.js +26 -56
  57. package/esm/keri/npm/src/app/runtime/workflow-contract.js +7 -4
  58. package/esm/keri/npm/src/app/transport/http-client.js +20 -2
  59. package/esm/keri/npm/src/app/transport/message-source.js +2 -1
  60. package/esm/keri/npm/src/app/transport/messengering.js +39 -8
  61. package/esm/keri/npm/src/app/witness/ingress.js +7 -0
  62. package/esm/keri/npm/src/app/witness/receipt-client.js +43 -16
  63. package/esm/keri/npm/src/app/witness/receipting.js +62 -20
  64. package/esm/keri/npm/src/cli/messaging/multisig.js +4 -3
  65. package/esm/keri/npm/src/core/errors.js +73 -0
  66. package/esm/keri/npm/src/core/kel/delegation-ancestry.js +11 -2
  67. package/esm/keri/npm/src/core/kel/eventing.js +25 -28
  68. package/esm/keri/npm/src/core/kel/kever.js +15 -9
  69. package/esm/keri/npm/src/core/mailbox/kram-policy.js +16 -0
  70. package/esm/keri/npm/src/core/mailbox/kram-pruning.js +25 -6
  71. package/esm/keri/npm/src/core/mailbox/kram-time.js +34 -6
  72. package/esm/keri/npm/src/core/mailbox/kraming.js +58 -2
  73. package/esm/keri/npm/src/core/missing-anchor-query.js +20 -0
  74. package/esm/keri/npm/src/core/routing.js +18 -25
  75. package/esm/keri/npm/src/core/scheming.js +12 -5
  76. package/esm/keri/npm/src/core/wire-fields.js +126 -0
  77. package/esm/keri/npm/src/db/basing.js +4 -13
  78. package/esm/keri/npm/src/db/core/indexeddb-persistence.js +3 -2
  79. package/esm/keri/npm/src/db/core/webdber.js +85 -27
  80. package/esm/keri/npm/src/db/mailbox/mailboxing.js +13 -0
  81. package/esm/keri/npm/src/db/subing.js +4 -0
  82. package/esm/keri/npm/src/runtime/index.js +11 -5
  83. package/esm/keri/npm/src/time/mod.js +5 -0
  84. package/esm/keri/npm/src/vdr/credential-tsn-record.js +2 -7
  85. package/esm/keri/npm/src/vdr/eventing.js +71 -28
  86. package/esm/keri/npm/src/vdr/registry-tsn-record.js +3 -13
  87. package/esm/keri/npm/src/version.js +2 -2
  88. package/package.json +1 -1
  89. package/types/_dnt.polyfills.d.ts +9 -9
  90. package/types/_dnt.polyfills.d.ts.map +1 -1
  91. package/types/acdc/dhking.d.ts +8 -0
  92. package/types/acdc/dhking.d.ts.map +1 -1
  93. package/types/acdc/observing.d.ts +5 -1
  94. package/types/acdc/observing.d.ts.map +1 -1
  95. package/types/acdc/query-resend.d.ts +24 -0
  96. package/types/acdc/query-resend.d.ts.map +1 -0
  97. package/types/acdc/regengine.d.ts +19 -1
  98. package/types/acdc/regengine.d.ts.map +1 -1
  99. package/types/acdc/regeventing.d.ts.map +1 -1
  100. package/types/acdc/registering.d.ts +6 -0
  101. package/types/acdc/registering.d.ts.map +1 -1
  102. package/types/acdc/salting.d.ts.map +1 -1
  103. package/types/acdc/unblinding.d.ts +13 -1
  104. package/types/acdc/unblinding.d.ts.map +1 -1
  105. package/types/app/bootstrap/authenticating.d.ts +12 -2
  106. package/types/app/bootstrap/authenticating.d.ts.map +1 -1
  107. package/types/app/bootstrap/oobiery.d.ts +144 -7
  108. package/types/app/bootstrap/oobiery.d.ts.map +1 -1
  109. package/types/app/credentials/credential-importing.d.ts +8 -0
  110. package/types/app/credentials/credential-importing.d.ts.map +1 -1
  111. package/types/app/credentials/root-replicator.d.ts +19 -8
  112. package/types/app/credentials/root-replicator.d.ts.map +1 -1
  113. package/types/app/credentials/schema-resolving.d.ts.map +1 -1
  114. package/types/app/credentials/tel-publishing.d.ts +4 -2
  115. package/types/app/credentials/tel-publishing.d.ts.map +1 -1
  116. package/types/app/delivery/forwarding.d.ts +90 -5
  117. package/types/app/delivery/forwarding.d.ts.map +1 -1
  118. package/types/app/delivery/relaying.d.ts +144 -0
  119. package/types/app/delivery/relaying.d.ts.map +1 -0
  120. package/types/app/delivery/respondant.d.ts +9 -2
  121. package/types/app/delivery/respondant.d.ts.map +1 -1
  122. package/types/app/exchanges/exchanging.d.ts +36 -0
  123. package/types/app/exchanges/exchanging.d.ts.map +1 -1
  124. package/types/app/identity/delegating.d.ts +6 -0
  125. package/types/app/identity/delegating.d.ts.map +1 -1
  126. package/types/app/identity/habbing.d.ts +106 -19
  127. package/types/app/identity/habbing.d.ts.map +1 -1
  128. package/types/app/identity/keeping.d.ts +54 -19
  129. package/types/app/identity/keeping.d.ts.map +1 -1
  130. package/types/app/identity/retire-identifier.d.ts +24 -0
  131. package/types/app/identity/retire-identifier.d.ts.map +1 -0
  132. package/types/app/ipex/disclosure-replaying.d.ts +61 -0
  133. package/types/app/ipex/disclosure-replaying.d.ts.map +1 -0
  134. package/types/app/ipex/group-ipex.d.ts +60 -14
  135. package/types/app/ipex/group-ipex.d.ts.map +1 -1
  136. package/types/app/ipex/group-issuance.d.ts +54 -8
  137. package/types/app/ipex/group-issuance.d.ts.map +1 -1
  138. package/types/app/ipex/ipex-discloser.d.ts +39 -2
  139. package/types/app/ipex/ipex-discloser.d.ts.map +1 -1
  140. package/types/app/ipex/ipex-grouping.d.ts +23 -2
  141. package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
  142. package/types/app/ipex/ipex-v2.d.ts +5 -2
  143. package/types/app/ipex/ipex-v2.d.ts.map +1 -1
  144. package/types/app/ipex/issuance.d.ts +46 -16
  145. package/types/app/ipex/issuance.d.ts.map +1 -1
  146. package/types/app/ipex/pending-presentations.d.ts +4 -2
  147. package/types/app/ipex/pending-presentations.d.ts.map +1 -1
  148. package/types/app/ipex/presenting.d.ts.map +1 -1
  149. package/types/app/ipex/receive-issuance.d.ts +2 -1
  150. package/types/app/ipex/receive-issuance.d.ts.map +1 -1
  151. package/types/app/ipex/unblinding-workflow.d.ts +13 -2
  152. package/types/app/ipex/unblinding-workflow.d.ts.map +1 -1
  153. package/types/app/mailbox/agent-inbox.d.ts +126 -0
  154. package/types/app/mailbox/agent-inbox.d.ts.map +1 -0
  155. package/types/app/mailbox/forward-handler.d.ts +114 -14
  156. package/types/app/mailbox/forward-handler.d.ts.map +1 -1
  157. package/types/app/mailbox/kel-publisher.d.ts +12 -22
  158. package/types/app/mailbox/kel-publisher.d.ts.map +1 -1
  159. package/types/app/mailbox/mailbox-poller.d.ts +40 -24
  160. package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
  161. package/types/app/mailbox/mailboxing.d.ts +19 -5
  162. package/types/app/mailbox/mailboxing.d.ts.map +1 -1
  163. package/types/app/multisig/counseling.d.ts +32 -11
  164. package/types/app/multisig/counseling.d.ts.map +1 -1
  165. package/types/app/multisig/group-members.d.ts +17 -1
  166. package/types/app/multisig/group-members.d.ts.map +1 -1
  167. package/types/app/multisig/grouping.d.ts +17 -1
  168. package/types/app/multisig/grouping.d.ts.map +1 -1
  169. package/types/app/multisig/multisig-workflows.d.ts +0 -8
  170. package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
  171. package/types/app/multisig/proposing.d.ts +4 -19
  172. package/types/app/multisig/proposing.d.ts.map +1 -1
  173. package/types/app/multisig/rejoin-group.d.ts +119 -0
  174. package/types/app/multisig/rejoin-group.d.ts.map +1 -0
  175. package/types/app/multisig/replace-member.d.ts +15 -1
  176. package/types/app/multisig/replace-member.d.ts.map +1 -1
  177. package/types/app/protocol/parsering.d.ts +21 -2
  178. package/types/app/protocol/parsering.d.ts.map +1 -1
  179. package/types/app/protocol/protocol-processing.d.ts +25 -5
  180. package/types/app/protocol/protocol-processing.d.ts.map +1 -1
  181. package/types/app/queries/query-replies.d.ts +4 -8
  182. package/types/app/queries/query-replies.d.ts.map +1 -1
  183. package/types/app/queries/relay-refresh.d.ts +26 -0
  184. package/types/app/queries/relay-refresh.d.ts.map +1 -0
  185. package/types/app/queries/witness-inquisitor.d.ts +56 -5
  186. package/types/app/queries/witness-inquisitor.d.ts.map +1 -1
  187. package/types/app/runtime/agent-runtime.d.ts +34 -3
  188. package/types/app/runtime/agent-runtime.d.ts.map +1 -1
  189. package/types/app/runtime/cue-runtime.d.ts +15 -3
  190. package/types/app/runtime/cue-runtime.d.ts.map +1 -1
  191. package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -1
  192. package/types/app/runtime/operation-owners.d.ts +16 -26
  193. package/types/app/runtime/operation-owners.d.ts.map +1 -1
  194. package/types/app/runtime/workflow-contract.d.ts +21 -6
  195. package/types/app/runtime/workflow-contract.d.ts.map +1 -1
  196. package/types/app/transport/http-client.d.ts +9 -0
  197. package/types/app/transport/http-client.d.ts.map +1 -1
  198. package/types/app/transport/message-source.d.ts +6 -3
  199. package/types/app/transport/message-source.d.ts.map +1 -1
  200. package/types/app/transport/messengering.d.ts +10 -1
  201. package/types/app/transport/messengering.d.ts.map +1 -1
  202. package/types/app/witness/ingress.d.ts +1 -0
  203. package/types/app/witness/ingress.d.ts.map +1 -1
  204. package/types/app/witness/receipt-client.d.ts +19 -1
  205. package/types/app/witness/receipt-client.d.ts.map +1 -1
  206. package/types/app/witness/receipting.d.ts +24 -1
  207. package/types/app/witness/receipting.d.ts.map +1 -1
  208. package/types/cli/messaging/multisig.d.ts.map +1 -1
  209. package/types/core/cues.d.ts +53 -1
  210. package/types/core/cues.d.ts.map +1 -1
  211. package/types/core/errors.d.ts +32 -0
  212. package/types/core/errors.d.ts.map +1 -1
  213. package/types/core/kel/delegation-ancestry.d.ts.map +1 -1
  214. package/types/core/kel/eventing.d.ts.map +1 -1
  215. package/types/core/kel/kever-decisions.d.ts +3 -1
  216. package/types/core/kel/kever-decisions.d.ts.map +1 -1
  217. package/types/core/kel/kever.d.ts +7 -1
  218. package/types/core/kel/kever.d.ts.map +1 -1
  219. package/types/core/mailbox/kram-policy.d.ts +12 -0
  220. package/types/core/mailbox/kram-policy.d.ts.map +1 -1
  221. package/types/core/mailbox/kram-pruning.d.ts +5 -1
  222. package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
  223. package/types/core/mailbox/kram-time.d.ts +26 -2
  224. package/types/core/mailbox/kram-time.d.ts.map +1 -1
  225. package/types/core/mailbox/kraming.d.ts +14 -1
  226. package/types/core/mailbox/kraming.d.ts.map +1 -1
  227. package/types/core/missing-anchor-query.d.ts +34 -0
  228. package/types/core/missing-anchor-query.d.ts.map +1 -0
  229. package/types/core/routing.d.ts +3 -7
  230. package/types/core/routing.d.ts.map +1 -1
  231. package/types/core/scheming.d.ts.map +1 -1
  232. package/types/core/wire-fields.d.ts +56 -0
  233. package/types/core/wire-fields.d.ts.map +1 -0
  234. package/types/db/basing.d.ts.map +1 -1
  235. package/types/db/core/indexeddb-persistence.d.ts +3 -2
  236. package/types/db/core/indexeddb-persistence.d.ts.map +1 -1
  237. package/types/db/core/webdber.d.ts +32 -6
  238. package/types/db/core/webdber.d.ts.map +1 -1
  239. package/types/db/exchange/exchange-records.d.ts +4 -0
  240. package/types/db/exchange/exchange-records.d.ts.map +1 -1
  241. package/types/db/mailbox/mailboxing.d.ts +10 -1
  242. package/types/db/mailbox/mailboxing.d.ts.map +1 -1
  243. package/types/db/subing.d.ts +2 -0
  244. package/types/db/subing.d.ts.map +1 -1
  245. package/types/runtime/index.d.ts +20 -14
  246. package/types/runtime/index.d.ts.map +1 -1
  247. package/types/time/mod.d.ts +2 -0
  248. package/types/time/mod.d.ts.map +1 -1
  249. package/types/vdr/credential-tsn-record.d.ts.map +1 -1
  250. package/types/vdr/eventing.d.ts +32 -1
  251. package/types/vdr/eventing.d.ts.map +1 -1
  252. package/types/vdr/registry-tsn-record.d.ts.map +1 -1
  253. package/types/version.d.ts +2 -2
  254. package/esm/keri/npm/src/app/runtime/signer-conditions.js +0 -51
  255. package/types/app/runtime/signer-conditions.d.ts +0 -32
  256. package/types/app/runtime/signer-conditions.d.ts.map +0 -1
@@ -129,14 +129,21 @@ function parseSchemaJson(raw) {
129
129
  }
130
130
  return parsed;
131
131
  }
132
+ /**
133
+ * Decode credential data for validation. The bytes are a remote credential's body, which need not be JSON (a CBOR or
134
+ * MGPK ACDC); data that does not decode fails validation as a `ValidationError`, like KERIpy's `json.loads` failure.
135
+ */
132
136
  function parseSchemaData(raw) {
133
- if (raw instanceof Uint8Array) {
134
- return JSON.parse(new TextDecoder().decode(raw));
137
+ if (!(raw instanceof Uint8Array) && typeof raw !== "string")
138
+ return raw;
139
+ try {
140
+ return JSON.parse(typeof raw === "string" ? raw : new TextDecoder().decode(raw));
135
141
  }
136
- if (typeof raw === "string") {
137
- return JSON.parse(raw);
142
+ catch (error) {
143
+ if (!(error instanceof SyntaxError))
144
+ throw error;
145
+ throw new ValidationError(`Credential data is not JSON: ${error.message}`);
138
146
  }
139
- return raw;
140
147
  }
141
148
  function verifySchemaSaid(sed, kind) {
142
149
  const id = sed.$id;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Guarded readers for the field values of remote messages.
3
+ *
4
+ * A remote message can parse and verify its SAID while a field value is still not a valid value for its type: a
5
+ * non-hex or over-wide sequence number, a key that is not a verification key, a next-key digest that is not a digest,
6
+ * a prefix that is not a prefix. The cesr accessors and primitive constructors throw on such values, and a throw out
7
+ * of a processor ends its loop (the mailbox poller, the escrow doer, HTTP ingress). Processor boundaries therefore read
8
+ * remote field values through these readers and turn a null into their own typed refusal (ADR-0005) before any escrow
9
+ * decision or store write: `Kevery.decideEvent` and `processReceipt`, the reply route handlers and `Revery`'s
10
+ * datetime read, `Exchanger` admission and `queryEnvelopeFromDispatch`. Accepted KEL events are remote-authored too:
11
+ * their raw `a` seals are read through `readEventSeal` wherever an anchor is searched.
12
+ *
13
+ * Only the cesr codec's own malformed-input taxonomy (`ParserError` and its subclasses) is read as malformed input, and
14
+ * only while constructing a primitive from a string the message carried. That construction reads no store, so a
15
+ * `ParserError` there cannot be corrupt durable state or I/O; every other error propagates. Numbers are checked as
16
+ * text before any `BigInt` conversion, so cesr's `SyntaxError`/`RangeError` for bad hex is never relied on.
17
+ */
18
+ import { Dater, Diger, Ilks, NumberPrimitive, ParserError, Prefixer, SealEvent, Verfer, } from "cesr-ts";
19
+ import { encodeDateTimeToDater } from "../time/mod.js";
20
+ /** Construct `Type` from qualified text, or null when the text is not a valid value of that type. */
21
+ function readQualified(Type, value) {
22
+ if (typeof value !== "string" || !value)
23
+ return null;
24
+ try {
25
+ return new Type({ qb64: value });
26
+ }
27
+ catch (error) {
28
+ if (error instanceof ParserError)
29
+ return null;
30
+ throw error;
31
+ }
32
+ }
33
+ /** Read an identifier prefix (`i`, `di`, `cid`, `eid`, ...), or null when it is not one. */
34
+ export function readPrefixer(value) {
35
+ return readQualified(Prefixer, value);
36
+ }
37
+ /** Read a digest (`d` of a key state notice, a next-key digest), or null when it is not one. */
38
+ export function readDiger(value) {
39
+ return readQualified(Diger, value);
40
+ }
41
+ /** Read a verification key (a current key, a witness), or null when it is not one. */
42
+ export function readVerfer(value) {
43
+ return readQualified(Verfer, value);
44
+ }
45
+ /** Read a datetime (`dt`) as a Dater, or null when it does not encode as one. */
46
+ export function readDater(value) {
47
+ return typeof value === "string" ? readQualified(Dater, encodeDateTimeToDater(value)) : null;
48
+ }
49
+ /** Read a URL, or null when it does not parse. */
50
+ export function readUrl(value) {
51
+ return URL.canParse(value) ? new URL(value) : null;
52
+ }
53
+ /**
54
+ * Read a KERI ordinal: lower- or upper-case hex text, or a non-negative integer number or bigint, as cesr's numeric
55
+ * ladder accepts them. Null when it is none of those or exceeds `Number.MAX_SAFE_INTEGER`, the largest value the KEL
56
+ * processors can compare exactly as a number.
57
+ */
58
+ export function readOrdinal(value) {
59
+ let ordinal;
60
+ if (typeof value === "string") {
61
+ if (!/^[0-9a-f]+$/iu.test(value))
62
+ return null;
63
+ ordinal = BigInt(`0x${value}`);
64
+ }
65
+ else if (typeof value === "number") {
66
+ if (!Number.isSafeInteger(value) || value < 0)
67
+ return null;
68
+ ordinal = BigInt(value);
69
+ }
70
+ else if (typeof value === "bigint") {
71
+ ordinal = value;
72
+ }
73
+ else {
74
+ return null;
75
+ }
76
+ return ordinal >= 0n && ordinal <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(ordinal) : null;
77
+ }
78
+ /** Read a message's `s`, which cesr's `sner` reads only as hex text; null when absent or malformed. */
79
+ export function readSequenceNumber(serder) {
80
+ const sn = serder.ked?.s;
81
+ return typeof sn === "string" ? readOrdinal(sn) : null;
82
+ }
83
+ /**
84
+ * Name the first field of a KEL event whose value the key-state machine would fail to decode, or null when all decode.
85
+ *
86
+ * Covers what `Kever` and escrow persistence decode beyond `i` and `s` (which `decideEvent` reads first): current keys
87
+ * `k` and next-key digests `n` of establishment events, witnesses `b` and witness changes `br`/`ba`, the witness
88
+ * threshold `bt`, and the delegator `di` of a delegated inception. Thresholds (`kt`, `nt`) already decode to null and are
89
+ * rejected by `Kever`; raw seals in `a` are not decoded here.
90
+ */
91
+ export function kelEventFieldDefect(serder) {
92
+ const ked = serder.ked ?? {};
93
+ const ilk = serder.ilk;
94
+ const bad = (label, values, read) => {
95
+ const value = values.find((entry) => read(entry) === null);
96
+ return value === undefined ? null : `${label} ${JSON.stringify(value)}`;
97
+ };
98
+ return bad("key", serder.keys, readVerfer)
99
+ ?? bad("next key digest", serder.ndigs, readDiger)
100
+ ?? bad("witness", serder.backs, readVerfer)
101
+ ?? bad("witness cut", serder.cuts, readVerfer)
102
+ ?? bad("witness add", serder.adds, readVerfer)
103
+ ?? (ked.bt !== undefined && ked.bt !== null && readOrdinal(ked.bt) === null
104
+ ? `witness threshold ${JSON.stringify(ked.bt)}`
105
+ : null)
106
+ ?? (ilk === Ilks.dip && serder.delpre !== null && !readPrefixer(serder.delpre)
107
+ ? `delegator ${JSON.stringify(serder.delpre)}`
108
+ : null);
109
+ }
110
+ /**
111
+ * Read one raw `a` entry as an event seal `{i, s, d}`, or null when it is another seal shape or carries a value that
112
+ * does not decode.
113
+ *
114
+ * An accepted event's seals are not value-checked at acceptance (KERIpy keeps them as raw dicts), so any identifier can
115
+ * anchor junk in its own KEL. Anchor searches (delegation approval, sealing-event lookup) therefore read each entry
116
+ * through this reader and skip a null instead of throwing. KERIpy filters by the same field shape
117
+ * (`tuple(seal) == SealEvent._fields`) and compares raw strings, so a malformed value can never match a real event.
118
+ */
119
+ export function readEventSeal(value) {
120
+ if (!SealEvent.isSad(value))
121
+ return null;
122
+ const pre = readPrefixer(value.i);
123
+ const sn = readOrdinal(value.s);
124
+ const said = readDiger(value.d);
125
+ return pre && sn !== null && said ? SealEvent.fromTuple([pre, NumberPrimitive.fromNum(BigInt(sn)), said]) : null;
126
+ }
@@ -1,11 +1,12 @@
1
1
  /** KERI event-log databaser built on `LMDBer` composition. */
2
- import { b, Cigar, Dater, Diger, Ilks, Labeler, Noncer, NumberPrimitive, NumDex, Prefixer, Saider, SealEvent, SerderKERI, Siger, t, Texter, Verfer, Verser, Vrsn_1_0, } from "cesr-ts";
2
+ import { b, Cigar, Dater, Diger, Ilks, Labeler, Noncer, NumberPrimitive, NumDex, Prefixer, Saider, SerderKERI, Siger, t, Texter, Verfer, Verser, Vrsn_1_0, } from "cesr-ts";
3
3
  import { action } from "effection";
4
4
  import { attachmentCounterPayloadQb64b, attachmentCounterQb64b, attachmentOrdinal, resolveAttachmentGvrsn, } from "../core/attachment-countering.js";
5
5
  import { DatabaseOperationError, ValidationError } from "../core/errors.js";
6
6
  import { Kever } from "../core/kel/kever.js";
7
7
  import { consoleLogger } from "../core/logger.js";
8
8
  import { CacheTypeRecord, EndpointRecord, EventSourceRecord, HabitatRecord, KelPublishedRecord, KeyStateRecord, LocationRecord, MsgCacheRecord, ObservedRecord, OobiRecord, RootSentRecord, TopicsRecord, TxnMsgCacheRecord, WellKnownAuthN, } from "../core/records.js";
9
+ import { readEventSeal } from "../core/wire-fields.js";
9
10
  import { encodeDateTimeToDater, makeNowIso8601 } from "../time/mod.js";
10
11
  import { dgKey, splitOnKey } from "./core/keys.js";
11
12
  import { StoreOwner } from "./core/store-owner.js";
@@ -29,19 +30,9 @@ function isEventSealRecord(value) {
29
30
  && value.s instanceof NumberPrimitive
30
31
  && value.d instanceof Diger;
31
32
  }
33
+ /** Accept an already-typed event seal, or read a raw `{i, s, d}` entry; null for other shapes or bad values. */
32
34
  function normalizeEventSeal(value) {
33
- if (isEventSealRecord(value)) {
34
- return value;
35
- }
36
- if (!SealEvent.isSad(value)) {
37
- return null;
38
- }
39
- try {
40
- return SealEvent.fromSad(value);
41
- }
42
- catch {
43
- return null;
44
- }
35
+ return isEventSealRecord(value) ? value : readEventSeal(value);
45
36
  }
46
37
  function eventSealsEqual(left, right) {
47
38
  return left.i.qb64 === right.i.qb64
@@ -25,8 +25,9 @@
25
25
  *
26
26
  * Another tab's upgrade or delete fires `versionchange` here. The connection
27
27
  * closes at once so that tab is never blocked, and this adapter is then lost:
28
- * its next `load` or `write` rejects, which latches the queue, because writing
29
- * on after another context deleted the database would break prefix durability.
28
+ * its next `load` or `write` rejects, and so does every retry of it (a write never
29
+ * reconnects), which latches the queue, because writing on after another context
30
+ * deleted the database would break prefix durability.
30
31
  * Recovery is a new open, whose `meta` reconnects. Single-writer exclusion is
31
32
  * the composition's job, not this adapter's.
32
33
  *
@@ -9,50 +9,84 @@
9
9
  * Invariant: once the queue is joined with no failure, the mirror and the
10
10
  * persisted rows are byte-identical, which is why `reopen` joins before it loads.
11
11
  */
12
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
13
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
14
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
15
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
16
- };
17
12
  var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
18
13
  if (kind === "m") throw new TypeError("Private method is not writable");
19
14
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
20
15
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
21
16
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
22
17
  };
23
- var _PersistenceQueue_instances, _PersistenceQueue_tail, _PersistenceQueue_failure, _PersistenceQueue_append, _PersistenceQueue_settled, _WebDBer_instances, _WebDBer_persistence, _WebDBer_queue, _WebDBer_pendingTables, _WebDBer_connected, _WebDBer_enqueue, _WebDBer_takePendingTables, _WebDBer_carryPendingTables;
18
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
19
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
20
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
21
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
22
+ };
23
+ var _PersistenceQueue_instances, _PersistenceQueue_tail, _PersistenceQueue_failure, _PersistenceQueue_retrying, _PersistenceQueue_retryDelays, _PersistenceQueue_append, _PersistenceQueue_attempt, _PersistenceQueue_latched, _PersistenceQueue_settled, _WebDBer_instances, _WebDBer_persistence, _WebDBer_queue, _WebDBer_pendingTables, _WebDBer_connected, _WebDBer_enqueue, _WebDBer_takePendingTables, _WebDBer_carryPendingTables;
24
24
  import { bytesEqual, bytesHex } from "cesr-ts";
25
25
  import { call, ensure } from "effection";
26
- import { DatabaseOperationError } from "../../core/errors.js";
26
+ import { PersistenceLatchedError, PersistenceReadError } from "../../core/errors.js";
27
27
  import { MemStore } from "./memstore.js";
28
+ /** Delays in milliseconds before each retry of a failed task: four attempts in about half a second. */
29
+ export const PERSISTENCE_RETRY_DELAYS = Object.freeze([25, 100, 400]);
30
+ const pause = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28
31
  /**
29
32
  * The persistence order of one composition. Tasks run strictly one at a time,
30
33
  * outside any Effection scope, so cancelling a waiter never cancels a write.
31
34
  *
32
- * The first failure latches: every later task is skipped, because applying a
33
- * later batch over a lost earlier one would break prefix durability.
35
+ * A failed task is retried in place on a fixed short schedule while it holds
36
+ * the head of the queue, so no later task runs ahead of it. Every task the
37
+ * library enqueues is safe to re-run: an adapter `write` applies one batch
38
+ * atomically and idempotently, `clear` deletes what may already be gone, and
39
+ * `close` releases what may already be released. A task that fails through its
40
+ * retries latches the queue for good: every later task is skipped, because
41
+ * applying a later batch over a lost earlier one would break prefix
42
+ * durability. Recovery is a new composition with a new queue.
34
43
  */
35
44
  export class PersistenceQueue {
36
- constructor() {
45
+ /** @param retryDelays Delays before each retry; its length is the number of retries. */
46
+ constructor(retryDelays = PERSISTENCE_RETRY_DELAYS) {
37
47
  _PersistenceQueue_instances.add(this);
38
48
  _PersistenceQueue_tail.set(this, Promise.resolve());
39
49
  _PersistenceQueue_failure.set(this, null);
50
+ _PersistenceQueue_retrying.set(this, false);
51
+ _PersistenceQueue_retryDelays.set(this, void 0);
52
+ __classPrivateFieldSet(this, _PersistenceQueue_retryDelays, [...retryDelays], "f");
40
53
  }
41
- /** Append a task, which is skipped if an earlier one failed. */
54
+ /** Append a task, retried on failure; skipped once the queue has latched. Run only re-runnable tasks here. */
42
55
  enqueue(task) {
43
56
  __classPrivateFieldGet(this, _PersistenceQueue_instances, "m", _PersistenceQueue_append).call(this, task, false);
44
57
  }
45
- /** Append connection teardown, which still runs after a failure so a handle is not left open. */
58
+ /** Append connection teardown, which still runs, once, after a latch so a handle is not left open. */
46
59
  release(task) {
47
60
  __classPrivateFieldGet(this, _PersistenceQueue_instances, "m", _PersistenceQueue_append).call(this, task, true);
48
61
  }
49
- /** Refuse new work once latched. The original failure is the cause. */
62
+ /**
63
+ * Run `task` after everything enqueued before this call, and resolve with its result. It sees every earlier
64
+ * commit durable, except after a latch, when it runs anyway and sees only the durable prefix; check `status()`.
65
+ * Nothing enqueued after it runs until it settles. A throwing `task` rejects only this caller, with
66
+ * `PersistenceReadError`; it is not retried and never latches the queue.
67
+ */
68
+ read(task) {
69
+ const result = __classPrivateFieldGet(this, _PersistenceQueue_tail, "f").then(async () => {
70
+ try {
71
+ return await task();
72
+ }
73
+ catch (error) {
74
+ throw new PersistenceReadError("Persistence read failed", { cause: error });
75
+ }
76
+ });
77
+ __classPrivateFieldSet(this, _PersistenceQueue_tail, result.then(() => { }, () => { }), "f");
78
+ return result;
79
+ }
80
+ /** The queue's state now; `retrying` lasts only while the head task is between attempts. */
81
+ status() {
82
+ if (__classPrivateFieldGet(this, _PersistenceQueue_failure, "f"))
83
+ return "latched";
84
+ return __classPrivateFieldGet(this, _PersistenceQueue_retrying, "f") ? "retrying" : "healthy";
85
+ }
86
+ /** Refuse new work once latched, with `PersistenceLatchedError` whose cause is the original failure. */
50
87
  assertHealthy() {
51
- if (__classPrivateFieldGet(this, _PersistenceQueue_failure, "f")) {
52
- throw new DatabaseOperationError("Persistence failed; this composition accepts no more commits", {
53
- cause: __classPrivateFieldGet(this, _PersistenceQueue_failure, "f").error,
54
- });
55
- }
88
+ if (__classPrivateFieldGet(this, _PersistenceQueue_failure, "f"))
89
+ throw __classPrivateFieldGet(this, _PersistenceQueue_instances, "m", _PersistenceQueue_latched).call(this, __classPrivateFieldGet(this, _PersistenceQueue_failure, "f").error);
56
90
  }
57
91
  /** Wait until everything enqueued before this call is durable. Halting cancels only the wait. */
58
92
  *flushed() {
@@ -68,22 +102,46 @@ export class PersistenceQueue {
68
102
  });
69
103
  }
70
104
  }
71
- _PersistenceQueue_tail = new WeakMap(), _PersistenceQueue_failure = new WeakMap(), _PersistenceQueue_instances = new WeakSet(), _PersistenceQueue_append = function _PersistenceQueue_append(task, always) {
105
+ _PersistenceQueue_tail = new WeakMap(), _PersistenceQueue_failure = new WeakMap(), _PersistenceQueue_retrying = new WeakMap(), _PersistenceQueue_retryDelays = new WeakMap(), _PersistenceQueue_instances = new WeakSet(), _PersistenceQueue_append = function _PersistenceQueue_append(task, always) {
72
106
  __classPrivateFieldSet(this, _PersistenceQueue_tail, __classPrivateFieldGet(this, _PersistenceQueue_tail, "f").then(async () => {
73
- if (__classPrivateFieldGet(this, _PersistenceQueue_failure, "f") && !always)
107
+ if (!__classPrivateFieldGet(this, _PersistenceQueue_failure, "f"))
108
+ return await __classPrivateFieldGet(this, _PersistenceQueue_instances, "m", _PersistenceQueue_attempt).call(this, task);
109
+ if (!always)
74
110
  return;
75
111
  try {
76
112
  await task();
77
113
  }
78
- catch (error) {
79
- __classPrivateFieldSet(this, _PersistenceQueue_failure, __classPrivateFieldGet(this, _PersistenceQueue_failure, "f") ?? { error }, "f");
114
+ catch {
115
+ // Already latched; the recorded failure is the one reported.
80
116
  }
81
117
  }), "f");
118
+ }, _PersistenceQueue_attempt =
119
+ /** Run `task`, retrying it in place on the schedule, and latch with its first failure when every attempt fails. */
120
+ async function _PersistenceQueue_attempt(task) {
121
+ let first = null;
122
+ try {
123
+ for (let attempt = 0;; attempt++) {
124
+ try {
125
+ return await task();
126
+ }
127
+ catch (error) {
128
+ first ??= { error };
129
+ if (attempt >= __classPrivateFieldGet(this, _PersistenceQueue_retryDelays, "f").length) {
130
+ __classPrivateFieldSet(this, _PersistenceQueue_failure, first, "f");
131
+ return;
132
+ }
133
+ }
134
+ __classPrivateFieldSet(this, _PersistenceQueue_retrying, true, "f");
135
+ await pause(__classPrivateFieldGet(this, _PersistenceQueue_retryDelays, "f")[attempt]);
136
+ }
137
+ }
138
+ finally {
139
+ __classPrivateFieldSet(this, _PersistenceQueue_retrying, false, "f");
140
+ }
141
+ }, _PersistenceQueue_latched = function _PersistenceQueue_latched(cause) {
142
+ return new PersistenceLatchedError("Persistence failed; this composition accepts no more commits", { cause });
82
143
  }, _PersistenceQueue_settled = function _PersistenceQueue_settled() {
83
- return __classPrivateFieldGet(this, _PersistenceQueue_tail, "f").then(() => {
84
- if (__classPrivateFieldGet(this, _PersistenceQueue_failure, "f"))
85
- throw __classPrivateFieldGet(this, _PersistenceQueue_failure, "f").error;
86
- });
144
+ return __classPrivateFieldGet(this, _PersistenceQueue_tail, "f").then(() => this.assertHealthy());
87
145
  };
88
146
  function sameValue(a, c) {
89
147
  return a === null || c === null ? a === c : bytesEqual(a, c);
@@ -120,7 +178,7 @@ function netVersion(changes) {
120
178
  * readable even though it was never persisted, and every later transaction
121
179
  * throws before touching the mirror, so the mirror stops changing. The durable
122
180
  * state is a prefix of the commit sequence. Recovery is a new composition, with
123
- * a new queue, loading that prefix; there is no retry.
181
+ * a new queue, loading that prefix; the queue's own retries happen before it latches.
124
182
  */
125
183
  export class WebDBer extends MemStore {
126
184
  constructor(options, persistence, queue) {
@@ -15,8 +15,21 @@
15
15
  */
16
16
  import { Diger, MtrDex } from "cesr-ts";
17
17
  import { DatabaseNotOpenError } from "../../core/errors.js";
18
+ import { MAX_KEY_BYTES } from "../core/dber.js";
19
+ import { onKey } from "../core/keys.js";
18
20
  import { StoreOwner } from "../core/store-owner.js";
19
21
  import { CesrOnSuber, Suber } from "../subing.js";
22
+ /**
23
+ * Whether `topic` can index a stored message: its `.tpcs` row key, `<topic>.<32 hex ordinal>`, fits the store's key
24
+ * limit (ADR-0015). A longer topic makes {@link Mailboxer.storeMsg} fail with `DatabaseKeyError`, a store fault, so a
25
+ * caller holding a topic another party chose checks it here before storing.
26
+ *
27
+ * @param topic Complete mailbox topic key, as `mailboxTopicKey` builds it.
28
+ * @returns True when a message can be stored under the topic.
29
+ */
30
+ export function storableTopic(topic) {
31
+ return onKey(topic, 0).length <= MAX_KEY_BYTES;
32
+ }
20
33
  /** Raw-byte value family used for stored mailbox message bodies. */
21
34
  class BytesSuber extends Suber {
22
35
  _ser(val) {
@@ -838,6 +838,10 @@ export class CryptSignerSuber extends SignerSuber {
838
838
  : val;
839
839
  return this.db.setVal(this.sdb, this._tokey(keys), signerToStored(stored));
840
840
  }
841
+ /** Whether a signer is stored at `keys`; reads the raw row and never decrypts it. */
842
+ has(keys) {
843
+ return this.db.getVal(this.sdb, this._tokey(keys)) !== null;
844
+ }
841
845
  /**
842
846
  * Read one signer, decrypting the stored ciphertext when a decrypter exists.
843
847
  *
@@ -33,6 +33,7 @@ export { importCredentialStream, } from "../app/credentials/credential-importing
33
33
  export { deliverCredentialRevocation, revokeCredential, } from "../app/credentials/credential-revoking.js";
34
34
  export { createCredential, credentialRegistryRecords, credentialRegistryStatus, exportCredentialStream, inceptCredentialRegistry, listCredentials, pinSchemaBytes, } from "../app/credentials/credential-workflows.js";
35
35
  export { Poster, } from "../app/delivery/forwarding.js";
36
+ export { assertRelay, relayAuthorized, relayEndpoint, relayOnboarding, RelayOnlyError, relayOnlyHttpClient, relayRefusal, RelayUnauthorizedError, RelayUnresolvedError, } from "../app/delivery/relaying.js";
36
37
  export { EssrRecipient, } from "../app/exchanges/essr.js";
37
38
  export { createExchangeMessage, sendExchangeMessage, } from "../app/exchanges/exchange-messaging.js";
38
39
  export { Exchanger, RouteRefuser, } from "../app/exchanges/exchanging.js";
@@ -43,15 +44,17 @@ export { beginDelegation, completeEvent, DELEGATION_WAIT_TIMEOUT_MS, delegationS
43
44
  export { acceptedEventReplayMessage, Hab, Habery, openHabery, } from "../app/identity/habbing.js";
44
45
  export { Algos, Manager, SignerNotHeldError, } from "../app/identity/keeping.js";
45
46
  export { Organizer, } from "../app/identity/organizing.js";
47
+ export { exportDisclosureStream, listGroupDisclosures, } from "../app/ipex/disclosure-replaying.js";
46
48
  export { IpexAdmitter } from "../app/ipex/ipex-admitting.js";
47
49
  export { ipexExnBody, prepareIpexExn } from "../app/ipex/ipex-building.js";
48
50
  export { credentialPresentationArtifacts, credentialSaidFromGrant, ipexCredentialAdmit, ipexCredentialGrant, processCredentialPresentationArtifacts, storedGrantArtifacts, } from "../app/ipex/ipex-credentialing.js";
49
- export { anchorExchange as anchorIpexExchange, exchangeWire, IpexDiscloser, storedExchangeWire, } from "../app/ipex/ipex-discloser.js";
51
+ export { anchorExchange as anchorIpexExchange, attachPresentationProof, exchangeWire, IpexDiscloser, storedExchangeWire, } from "../app/ipex/ipex-discloser.js";
50
52
  export { walkIpexGraph } from "../app/ipex/ipex-graph.js";
51
53
  export { approveStoredMultisigIpexWrappers, prepareAcdcV2GroupIpex, publishInitialGroupIpex, requireAcdcV2GroupUse, sendCompletedGroupIpex, } from "../app/ipex/ipex-grouping.js";
52
54
  export { acceptedRegistryEvidence, authenticateIpexNode, issuedNodeVerdict, } from "../app/ipex/ipex-node-authentication.js";
53
55
  export { ipexGrantWalk } from "../app/ipex/ipex-v2.js";
54
56
  export { IPEX_GRANT_ROUTE, IPEX_ROUTES, ipexAdmitExn, ipexAgreeExn, ipexApplyExn, ipexGrantExn, ipexOfferExn, ipexSpurnExn, } from "../app/ipex/ipexing.js";
57
+ export { keepRawArrival } from "../app/mailbox/agent-inbox.js";
55
58
  export { KEL_PUBLISHER_PACING, KEL_PUBLISHER_SWEEP_TOCKS, KEL_PUBLISHER_TOCK_MS, KelPublisher, kelPublisherDo, } from "../app/mailbox/kel-publisher.js";
56
59
  export { addMailbox, completeGroupMailbox, completeMailboxAdmin, mailboxAdminUrl, mailboxStatus, proposeGroupMailbox, removeMailbox, requireMailboxEndpointUrl, waitForMailboxState, } from "../app/mailbox/mailbox-admin.js";
57
60
  export { MailboxDirector, } from "../app/mailbox/mailbox-director.js";
@@ -64,11 +67,11 @@ export { Multiplexor, MULTISIG_ROUTES, multisigExn, multisigExnBody, multisigInc
64
67
  export { signGroupMessage } from "../app/multisig/multisig-messaging.js";
65
68
  export { approveAcdcV2Registry, publishAcdcV2Registry } from "../app/multisig/multisig-workflows.js";
66
69
  export { approveGroupProposal, dismissGroupProposal, findGroupProposal, listGroupProposals, } from "../app/multisig/proposals.js";
67
- export { proposeCredentialIssue, proposeCredentialRegistry, proposeCredentialRevocation, proposeGroupInception, proposeGroupInteraction, proposeGroupRotation, proposeRegistryEvent, settleProposedRotation, } from "../app/multisig/proposing.js";
70
+ export { proposeCredentialIssue, proposeCredentialRegistry, proposeCredentialRevocation, proposeGroupInception, proposeGroupInteraction, proposeGroupRotation, proposeRegistryEvent, } from "../app/multisig/proposing.js";
71
+ export { rejoinGroup, } from "../app/multisig/rejoin-group.js";
68
72
  export { replaceGroupMember, } from "../app/multisig/replace-member.js";
69
73
  export { Notifier, } from "../app/notifications/notifying.js";
70
74
  export { Signal, Signaler, } from "../app/notifications/signaling.js";
71
- export { SignerConditions } from "../app/runtime/signer-conditions.js";
72
75
  export { RawRecord } from "../core/records.js";
73
76
  export { Verifier, } from "../app/credentials/verifying.js";
74
77
  export { witnessKeyStateGet, witnessQueryGet, witnessReceiptGet, witnessReceiptPost, } from "../app/witness/http-endpoints.js";
@@ -87,12 +90,13 @@ export { deliverRegistryRoots, replicateRootCopies, replicateRootCopy, resealRoo
87
90
  export { RootReplicator, } from "../app/credentials/root-replicator.js";
88
91
  export { publishPendingTel } from "../app/credentials/tel-publishing.js";
89
92
  export { Deck } from "../core/deck.js";
90
- export { AppError, DatabaseError, DatabaseKeyError, DatabaseNotOpenError, DatabaseOperationError, InvalidPathNameError, PathError, PresentationClosedError, ValidationError, } from "../core/errors.js";
93
+ export { AppError, DatabaseError, DatabaseKeyError, DatabaseNotOpenError, DatabaseOperationError, InvalidPathNameError, KramRefusedError, MissingDurableStateError, PathError, PersistenceLatchedError, PersistenceReadError, PresentationClosedError, ValidationError, } from "../core/errors.js";
91
94
  export { verifyExchangeProofs } from "../core/exchange/exchange-proofing.js";
92
95
  export { exchange } from "../core/exchange/protocol-exchanging.js";
93
96
  export { Kevery, } from "../core/kel/eventing.js";
94
97
  export { Kever, } from "../core/kel/kever.js";
95
98
  export { consoleLogger, getLogLevel, LOG_LEVELS, noopLogger, setLogLevel, } from "../core/logger.js";
99
+ export { isKramLateReason, } from "../core/mailbox/kram-time.js";
96
100
  export { DEFAULT_KRAM_CACHES, Kramer } from "../core/mailbox/kraming.js";
97
101
  export { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, normalizeMbxTopicCursor, OOBI_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../core/mailbox/mailbox-topics.js";
98
102
  export { incept, interact, query, reply, rotate } from "../core/protocol-eventing.js";
@@ -145,13 +149,15 @@ export { abandonUnblinding, answerUnblind, requestUnblind, unblindingKey, Unblin
145
149
  // Fixed-tock doers.
146
150
  export { doEvery } from "../app/runtime/doing.js";
147
151
  // Operations owners composed by the runtime.
148
- export { OWNER_PACING, OWNER_SWEEP_TOCKS, OWNER_TOCK_MS, OwnerHealth, } from "../app/runtime/operation-owners.js";
152
+ export { OWNER_PACING, OWNER_SWEEP_TOCKS, OWNER_TOCK_MS, } from "../app/runtime/operation-owners.js";
149
153
  // Library delegator approval (list, approve, status, wait, dismiss).
150
154
  export { approveDelegation, DELEGATION_APPROVAL_TIMEOUT_MS, delegationApprovalStatus, dismissDelegation, listPendingDelegations, proposeGroupDelegationApproval, requestDelegatedEvent, settleDelegationApproval, waitForDelegationAnchor, waitForDelegationApproval, waitForPendingDelegation, } from "../app/identity/delegation-approval.js";
151
155
  // Library TEL completion status/waits and challenge respond/status/wait.
152
156
  export { REGISTRY_WAIT_POLL_MS, registryEventRef, registryEventStatus, settleRegistryEvent, waitForRegistryEvent, } from "../app/credentials/registry-settling.js";
153
157
  export { issuedCredentialStatus, telEventStatus, waitForIssuedCredential, waitForTelEvent, } from "../app/credentials/tel-completion.js";
154
158
  export { challengeStatus, respondToChallenge, waitForChallengeResponse, } from "../app/identity/challenging.js";
159
+ // Runtime-level retirement: retireHab plus mailbox workers, cursors and KEL publisher rows.
160
+ export { retireIdentifier, retireIdentifierRefusal, } from "../app/identity/retire-identifier.js";
155
161
  // Library legacy IPEX conversation (apply, offer, agree, spurn; status and wait).
156
162
  export { ipexExchangeStatus, requireIpexPrior, requireIpexSender, sendIpexAgree, sendIpexApply, sendIpexOffer, sendIpexSpurn, waitForIpexExchange, } from "../app/ipex/ipex-conversation.js";
157
163
  // Library legacy IPEX grant, admit and credential settle.
@@ -44,3 +44,8 @@ export function timestampMicros(value) {
44
44
  const epoch = Date.parse(`${base}${zone}`);
45
45
  return Number.isFinite(epoch) ? BigInt(epoch) * 1000n + BigInt(fraction.padEnd(6, "0")) : null;
46
46
  }
47
+ /** Format epoch microseconds in the same fixed-width UTC text as `makeNowIso8601`, keeping microsecond precision. */
48
+ export function timestampFromMicros(micros) {
49
+ const whole = makeNowIso8601(new Date(Number(micros / 1000n)));
50
+ return whole.replace(/\.\d{6}/, `.${(micros % 1000000n).toString().padStart(6, "0")}`);
51
+ }
@@ -1,5 +1,5 @@
1
- import { Diger } from "cesr-ts";
2
1
  import { VcStateRecord } from "../core/records.js";
2
+ import { readDiger } from "../core/wire-fields.js";
3
3
  import { timestampMicros } from "../time/mod.js";
4
4
  import { qualifiedPrefix } from "./registry-tsn-record.js";
5
5
  /** Legacy storage ordinals are safe integers even though protocol numbers may be wider. */
@@ -9,12 +9,7 @@ function ordinal(value) {
9
9
  }
10
10
  /** Require the full qualified digest rather than accepting trailing bytes. */
11
11
  function qualifiedDigest(value) {
12
- try {
13
- return typeof value === "string" && new Diger({ qb64: value }).qb64 === value;
14
- }
15
- catch {
16
- return false;
17
- }
12
+ return readDiger(value)?.qb64 === value;
18
13
  }
19
14
  /** Validate unknown fields and construct an owned record without erasing its guarantees. */
20
15
  export function credentialRecord(data) {