keri-ts 0.10.5 → 1.0.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.
- package/README.md +12 -5
- package/esm/keri/npm/src/_dnt.polyfills.js +36 -0
- package/esm/keri/npm/src/_dnt.shims.js +2 -2
- package/esm/keri/npm/src/acdc/messaging.js +5 -0
- package/esm/keri/npm/src/acdc/observing.js +96 -0
- package/esm/keri/npm/src/acdc/regbasing.js +89 -0
- package/esm/keri/npm/src/acdc/regengine.js +355 -0
- package/esm/keri/npm/src/acdc/regeventing.js +273 -0
- package/esm/keri/npm/src/acdc/registering.js +177 -0
- package/esm/keri/npm/src/acdc/registraring.js +300 -0
- package/esm/keri/npm/src/acdc/scheming.js +306 -0
- package/esm/keri/npm/src/app/abortable.js +64 -0
- package/esm/keri/npm/src/app/agent-runtime.js +276 -163
- package/esm/keri/npm/src/app/authenticating.js +6 -3
- package/esm/keri/npm/src/app/byte-source.js +123 -0
- package/esm/keri/npm/src/app/cesr-egress.js +294 -0
- package/esm/keri/npm/src/app/cesr-http.js +63 -76
- package/esm/keri/npm/src/app/challenging.js +13 -8
- package/esm/keri/npm/src/app/cli/annotate.js +12 -92
- package/esm/keri/npm/src/app/cli/benchmark.js +18 -196
- package/esm/keri/npm/src/app/cli/challenge.js +16 -14
- package/esm/keri/npm/src/app/cli/common/context.js +1 -4
- package/esm/keri/npm/src/app/cli/common/existing.js +0 -16
- package/esm/keri/npm/src/app/cli/db-dump.js +3 -17
- package/esm/keri/npm/src/app/cli/delegate.js +37 -55
- package/esm/keri/npm/src/app/cli/did.js +14 -23
- package/esm/keri/npm/src/app/cli/ends.js +3 -5
- package/esm/keri/npm/src/app/cli/exchange.js +0 -2
- package/esm/keri/npm/src/app/cli/incept.js +5 -7
- package/esm/keri/npm/src/app/cli/init.js +3 -9
- package/esm/keri/npm/src/app/cli/ipex.js +140 -61
- package/esm/keri/npm/src/app/cli/loc.js +7 -10
- package/esm/keri/npm/src/app/cli/multisig.js +146 -60
- package/esm/keri/npm/src/app/cli/notifications.js +1 -0
- package/esm/keri/npm/src/app/cli/oobi.js +3 -5
- package/esm/keri/npm/src/app/cli/output.js +22 -0
- package/esm/keri/npm/src/app/cli/query.js +28 -29
- package/esm/keri/npm/src/app/cli/rotate.js +3 -5
- package/esm/keri/npm/src/app/cli/vc.js +3 -4
- package/esm/keri/npm/src/app/cli/verifier.js +7 -17
- package/esm/keri/npm/src/app/credential-workflows.js +25 -47
- package/esm/keri/npm/src/app/cue-runtime.js +24 -56
- package/esm/keri/npm/src/app/delegating.js +30 -12
- package/esm/keri/npm/src/app/endpoint-roleing.js +32 -28
- package/esm/keri/npm/src/app/essr.js +170 -0
- package/esm/keri/npm/src/app/exchanging.js +652 -128
- package/esm/keri/npm/src/app/forwarding.js +274 -438
- package/esm/keri/npm/src/app/grouping.js +333 -97
- package/esm/keri/npm/src/app/habbing.js +123 -306
- package/esm/keri/npm/src/app/httping.js +106 -32
- package/esm/keri/npm/src/app/ipex-credentialing.js +40 -37
- package/esm/keri/npm/src/app/ipex-graph.js +407 -0
- package/esm/keri/npm/src/app/ipex-grouping.js +33 -75
- package/esm/keri/npm/src/app/ipex-node-authentication.js +108 -0
- package/esm/keri/npm/src/app/ipex-v2.js +438 -0
- package/esm/keri/npm/src/app/ipexing.js +5 -9
- package/esm/keri/npm/src/app/keeping.js +8 -0
- package/esm/keri/npm/src/app/mailbox-director.js +285 -179
- package/esm/keri/npm/src/app/mailbox-sse.js +224 -101
- package/esm/keri/npm/src/app/mailboxing.js +19 -21
- package/esm/keri/npm/src/app/multisig-workflows.js +147 -225
- package/esm/keri/npm/src/app/notifying.js +20 -15
- package/esm/keri/npm/src/app/oobi-replies.js +111 -0
- package/esm/keri/npm/src/app/oobiery.js +141 -120
- package/esm/keri/npm/src/app/parsering.js +253 -232
- package/esm/keri/npm/src/app/query-replies.js +100 -0
- package/esm/keri/npm/src/app/querying.js +286 -194
- package/esm/keri/npm/src/app/reactor.js +255 -64
- package/esm/keri/npm/src/app/reply-streams.js +185 -0
- package/esm/keri/npm/src/app/respondant.js +268 -42
- package/esm/keri/npm/src/app/signaling.js +34 -25
- package/esm/keri/npm/src/app/socket-source.js +163 -0
- package/esm/keri/npm/src/app/stored-replies.js +53 -0
- package/esm/keri/npm/src/app/tcp-conversation.js +85 -0
- package/esm/keri/npm/src/app/tcp-egress.js +251 -0
- package/esm/keri/npm/src/app/verifier-agent.js +76 -41
- package/esm/keri/npm/src/app/verifying.js +25 -28
- package/esm/keri/npm/src/app/version.js +2 -2
- package/esm/keri/npm/src/app/witnessing.js +318 -233
- package/esm/keri/npm/src/core/attachment-countering.js +2 -2
- package/esm/keri/npm/src/core/deck.js +9 -9
- package/esm/keri/npm/src/core/dispatch.js +27 -58
- package/esm/keri/npm/src/core/errors.js +5 -10
- package/esm/keri/npm/src/core/eventing.js +246 -356
- package/esm/keri/npm/src/core/exchange-proofing.js +60 -0
- package/esm/keri/npm/src/core/kever-decisions.js +5 -10
- package/esm/keri/npm/src/core/kever.js +85 -164
- package/esm/keri/npm/src/core/kram-auth.js +32 -0
- package/esm/keri/npm/src/core/kram-policy.js +303 -0
- package/esm/keri/npm/src/core/kram-pruning.js +186 -0
- package/esm/keri/npm/src/core/kram-signatures.js +90 -0
- package/esm/keri/npm/src/core/kram-staging.js +149 -0
- package/esm/keri/npm/src/core/kram-time.js +91 -0
- package/esm/keri/npm/src/core/kraming.js +78 -0
- package/esm/keri/npm/src/core/protocol-eventing.js +5 -0
- package/esm/keri/npm/src/core/protocol-exchanging.js +40 -0
- package/esm/keri/npm/src/core/protocol-serialization.js +63 -25
- package/esm/keri/npm/src/core/protocol-vdr-eventing.js +10 -11
- package/esm/keri/npm/src/core/records.js +0 -19
- package/esm/keri/npm/src/core/routing.js +184 -124
- package/esm/keri/npm/src/db/basing.js +575 -87
- package/esm/keri/npm/src/db/core/keys.js +2 -2
- package/esm/keri/npm/src/db/core/lmdber.js +19 -25
- package/esm/keri/npm/src/db/core/path-manager.js +2 -4
- package/esm/keri/npm/src/db/escrowing.js +89 -148
- package/esm/keri/npm/src/db/exchange-nests.js +80 -0
- package/esm/keri/npm/src/db/exchange-records.js +7 -0
- package/esm/keri/npm/src/db/index.js +4 -2
- package/esm/keri/npm/src/db/keeping.js +1 -3
- package/esm/keri/npm/src/db/kel-replay.js +43 -0
- package/esm/keri/npm/src/db/kram-factors.js +160 -0
- package/esm/keri/npm/src/db/mailboxing.js +13 -3
- package/esm/keri/npm/src/db/payload-archive.js +402 -0
- package/esm/keri/npm/src/db/payload-store.js +406 -0
- package/esm/keri/npm/src/db/payload-view.js +23 -0
- package/esm/keri/npm/src/db/reger.js +88 -24
- package/esm/keri/npm/src/db/subing.js +9 -0
- package/esm/keri/npm/src/db/tel-replay.js +55 -0
- package/esm/keri/npm/src/db/witness-replay.js +127 -0
- package/esm/keri/npm/src/did/keri/resolving.js +4 -18
- package/esm/keri/npm/src/did/webs/artifacts.js +24 -14
- package/esm/keri/npm/src/did/webs/designated-aliases.js +16 -44
- package/esm/keri/npm/src/did/webs/documenting.js +8 -8
- package/esm/keri/npm/src/did/webs/resolving.js +58 -48
- package/esm/keri/npm/src/npm/deno-shim.js +17 -0
- package/esm/keri/npm/src/runtime/index.js +71 -58
- package/esm/keri/npm/src/time/mod.js +18 -3
- package/esm/keri/npm/src/vdr/credential-tsn.js +230 -0
- package/esm/keri/npm/src/vdr/credentialing.js +8 -32
- package/esm/keri/npm/src/vdr/eventing.js +101 -43
- package/esm/keri/npm/src/vdr/registry-tsn.js +217 -0
- package/esm/keri/npm/src/vdr/tsn-query.js +39 -0
- package/package.json +9 -26
- package/types/_dnt.polyfills.d.ts +49 -0
- package/types/_dnt.polyfills.d.ts.map +1 -1
- package/types/_dnt.shims.d.ts +3 -2
- package/types/_dnt.shims.d.ts.map +1 -1
- package/types/acdc/messaging.d.ts.map +1 -1
- package/types/acdc/observing.d.ts +31 -0
- package/types/acdc/observing.d.ts.map +1 -0
- package/types/acdc/regbasing.d.ts +35 -0
- package/types/acdc/regbasing.d.ts.map +1 -0
- package/types/acdc/regengine.d.ts +68 -0
- package/types/acdc/regengine.d.ts.map +1 -0
- package/types/acdc/regeventing.d.ts +101 -0
- package/types/acdc/regeventing.d.ts.map +1 -0
- package/types/acdc/registering.d.ts +72 -0
- package/types/acdc/registering.d.ts.map +1 -0
- package/types/acdc/registraring.d.ts +87 -0
- package/types/acdc/registraring.d.ts.map +1 -0
- package/types/acdc/scheming.d.ts +28 -0
- package/types/acdc/scheming.d.ts.map +1 -0
- package/types/app/abortable.d.ts +13 -0
- package/types/app/abortable.d.ts.map +1 -0
- package/types/app/agent-runtime.d.ts +46 -77
- package/types/app/agent-runtime.d.ts.map +1 -1
- package/types/app/authenticating.d.ts.map +1 -1
- package/types/app/byte-source.d.ts +16 -0
- package/types/app/byte-source.d.ts.map +1 -0
- package/types/app/cesr-egress.d.ts +45 -0
- package/types/app/cesr-egress.d.ts.map +1 -0
- package/types/app/cesr-http.d.ts +8 -13
- package/types/app/cesr-http.d.ts.map +1 -1
- package/types/app/challenging.d.ts +6 -0
- package/types/app/challenging.d.ts.map +1 -1
- package/types/app/cli/annotate.d.ts +2 -7
- package/types/app/cli/annotate.d.ts.map +1 -1
- package/types/app/cli/benchmark.d.ts +2 -9
- package/types/app/cli/benchmark.d.ts.map +1 -1
- package/types/app/cli/challenge.d.ts.map +1 -1
- package/types/app/cli/common/context.d.ts +0 -1
- package/types/app/cli/common/context.d.ts.map +1 -1
- package/types/app/cli/common/existing.d.ts +0 -1
- package/types/app/cli/common/existing.d.ts.map +1 -1
- package/types/app/cli/db-dump.d.ts +0 -2
- package/types/app/cli/db-dump.d.ts.map +1 -1
- package/types/app/cli/delegate.d.ts +0 -22
- package/types/app/cli/delegate.d.ts.map +1 -1
- package/types/app/cli/did.d.ts.map +1 -1
- package/types/app/cli/ends.d.ts.map +1 -1
- package/types/app/cli/exchange.d.ts.map +1 -1
- package/types/app/cli/init.d.ts.map +1 -1
- package/types/app/cli/ipex.d.ts +1 -1
- package/types/app/cli/ipex.d.ts.map +1 -1
- package/types/app/cli/loc.d.ts.map +1 -1
- package/types/app/cli/multisig.d.ts.map +1 -1
- package/types/app/cli/notifications.d.ts.map +1 -1
- package/types/app/cli/oobi.d.ts +1 -1
- package/types/app/cli/oobi.d.ts.map +1 -1
- package/types/app/cli/output.d.ts +2 -0
- package/types/app/cli/output.d.ts.map +1 -0
- package/types/app/cli/query.d.ts.map +1 -1
- package/types/app/cli/rotate.d.ts.map +1 -1
- package/types/app/cli/vc.d.ts.map +1 -1
- package/types/app/cli/verifier.d.ts.map +1 -1
- package/types/app/credential-workflows.d.ts +5 -10
- package/types/app/credential-workflows.d.ts.map +1 -1
- package/types/app/cue-runtime.d.ts +3 -29
- package/types/app/cue-runtime.d.ts.map +1 -1
- package/types/app/delegating.d.ts +15 -6
- package/types/app/delegating.d.ts.map +1 -1
- package/types/app/endpoint-roleing.d.ts +7 -5
- package/types/app/endpoint-roleing.d.ts.map +1 -1
- package/types/app/essr.d.ts +58 -0
- package/types/app/essr.d.ts.map +1 -0
- package/types/app/exchanging.d.ts +129 -18
- package/types/app/exchanging.d.ts.map +1 -1
- package/types/app/forwarding.d.ts +91 -93
- package/types/app/forwarding.d.ts.map +1 -1
- package/types/app/grouping.d.ts +92 -9
- package/types/app/grouping.d.ts.map +1 -1
- package/types/app/habbing.d.ts +25 -50
- package/types/app/habbing.d.ts.map +1 -1
- package/types/app/httping.d.ts +10 -1
- package/types/app/httping.d.ts.map +1 -1
- package/types/app/ipex-credentialing.d.ts +11 -5
- package/types/app/ipex-credentialing.d.ts.map +1 -1
- package/types/app/ipex-graph.d.ts +49 -0
- package/types/app/ipex-graph.d.ts.map +1 -0
- package/types/app/ipex-grouping.d.ts +6 -14
- package/types/app/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex-node-authentication.d.ts +27 -0
- package/types/app/ipex-node-authentication.d.ts.map +1 -0
- package/types/app/ipex-v2.d.ts +46 -0
- package/types/app/ipex-v2.d.ts.map +1 -0
- package/types/app/ipexing.d.ts +5 -2
- package/types/app/ipexing.d.ts.map +1 -1
- package/types/app/keeping.d.ts +2 -0
- package/types/app/keeping.d.ts.map +1 -1
- package/types/app/mailbox-director.d.ts +21 -30
- package/types/app/mailbox-director.d.ts.map +1 -1
- package/types/app/mailbox-sse.d.ts +16 -9
- package/types/app/mailbox-sse.d.ts.map +1 -1
- package/types/app/mailboxing.d.ts +4 -6
- package/types/app/mailboxing.d.ts.map +1 -1
- package/types/app/multisig-workflows.d.ts +9 -21
- package/types/app/multisig-workflows.d.ts.map +1 -1
- package/types/app/notifying.d.ts +4 -1
- package/types/app/notifying.d.ts.map +1 -1
- package/types/app/oobi-replies.d.ts +8 -0
- package/types/app/oobi-replies.d.ts.map +1 -0
- package/types/app/oobiery.d.ts +8 -2
- package/types/app/oobiery.d.ts.map +1 -1
- package/types/app/parsering.d.ts +45 -19
- package/types/app/parsering.d.ts.map +1 -1
- package/types/app/query-replies.d.ts +40 -0
- package/types/app/query-replies.d.ts.map +1 -0
- package/types/app/querying.d.ts +63 -72
- package/types/app/querying.d.ts.map +1 -1
- package/types/app/reactor.d.ts +72 -50
- package/types/app/reactor.d.ts.map +1 -1
- package/types/app/reply-streams.d.ts +20 -0
- package/types/app/reply-streams.d.ts.map +1 -0
- package/types/app/respondant.d.ts +40 -20
- package/types/app/respondant.d.ts.map +1 -1
- package/types/app/signaling.d.ts +11 -7
- package/types/app/signaling.d.ts.map +1 -1
- package/types/app/socket-source.d.ts +16 -0
- package/types/app/socket-source.d.ts.map +1 -0
- package/types/app/stored-replies.d.ts +11 -0
- package/types/app/stored-replies.d.ts.map +1 -0
- package/types/app/tcp-conversation.d.ts +27 -0
- package/types/app/tcp-conversation.d.ts.map +1 -0
- package/types/app/tcp-egress.d.ts +49 -0
- package/types/app/tcp-egress.d.ts.map +1 -0
- package/types/app/verifier-agent.d.ts +13 -3
- package/types/app/verifier-agent.d.ts.map +1 -1
- package/types/app/verifying.d.ts +5 -1
- package/types/app/verifying.d.ts.map +1 -1
- package/types/app/version.d.ts +2 -2
- package/types/app/version.d.ts.map +1 -1
- package/types/app/witnessing.d.ts +64 -20
- package/types/app/witnessing.d.ts.map +1 -1
- package/types/core/attachment-countering.d.ts +3 -3
- package/types/core/attachment-countering.d.ts.map +1 -1
- package/types/core/cues.d.ts +76 -38
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/deck.d.ts +1 -0
- package/types/core/deck.d.ts.map +1 -1
- package/types/core/dispatch.d.ts +20 -35
- package/types/core/dispatch.d.ts.map +1 -1
- package/types/core/errors.d.ts +4 -4
- package/types/core/errors.d.ts.map +1 -1
- package/types/core/eventing.d.ts +60 -54
- package/types/core/eventing.d.ts.map +1 -1
- package/types/core/exchange-proofing.d.ts +31 -0
- package/types/core/exchange-proofing.d.ts.map +1 -0
- package/types/core/kever-decisions.d.ts +18 -18
- package/types/core/kever-decisions.d.ts.map +1 -1
- package/types/core/kever.d.ts +13 -45
- package/types/core/kever.d.ts.map +1 -1
- package/types/core/kram-auth.d.ts +23 -0
- package/types/core/kram-auth.d.ts.map +1 -0
- package/types/core/kram-policy.d.ts +43 -0
- package/types/core/kram-policy.d.ts.map +1 -0
- package/types/core/kram-pruning.d.ts +38 -0
- package/types/core/kram-pruning.d.ts.map +1 -0
- package/types/core/kram-signatures.d.ts +29 -0
- package/types/core/kram-signatures.d.ts.map +1 -0
- package/types/core/kram-staging.d.ts +30 -0
- package/types/core/kram-staging.d.ts.map +1 -0
- package/types/core/kram-time.d.ts +47 -0
- package/types/core/kram-time.d.ts.map +1 -0
- package/types/core/kraming.d.ts +42 -0
- package/types/core/kraming.d.ts.map +1 -0
- package/types/core/protocol-eventing.d.ts +5 -0
- package/types/core/protocol-eventing.d.ts.map +1 -1
- package/types/core/protocol-exchanging.d.ts +12 -0
- package/types/core/protocol-exchanging.d.ts.map +1 -1
- package/types/core/protocol-serialization.d.ts +21 -2
- package/types/core/protocol-serialization.d.ts.map +1 -1
- package/types/core/protocol-vdr-eventing.d.ts +7 -5
- package/types/core/protocol-vdr-eventing.d.ts.map +1 -1
- package/types/core/records.d.ts +18 -51
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +58 -23
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/basing.d.ts +98 -14
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/keys.d.ts.map +1 -1
- package/types/db/core/lmdber.d.ts +3 -1
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/path-manager.d.ts.map +1 -1
- package/types/db/escrowing.d.ts +24 -47
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange-nests.d.ts +15 -0
- package/types/db/exchange-nests.d.ts.map +1 -0
- package/types/db/exchange-records.d.ts +33 -0
- package/types/db/exchange-records.d.ts.map +1 -0
- package/types/db/index.d.ts +4 -2
- package/types/db/index.d.ts.map +1 -1
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/kel-replay.d.ts +14 -0
- package/types/db/kel-replay.d.ts.map +1 -0
- package/types/db/koming.d.ts +1 -1
- package/types/db/koming.d.ts.map +1 -1
- package/types/db/kram-factors.d.ts +11 -0
- package/types/db/kram-factors.d.ts.map +1 -0
- package/types/db/mailboxing.d.ts +2 -1
- package/types/db/mailboxing.d.ts.map +1 -1
- package/types/db/payload-archive.d.ts +70 -0
- package/types/db/payload-archive.d.ts.map +1 -0
- package/types/db/payload-store.d.ts +40 -0
- package/types/db/payload-store.d.ts.map +1 -0
- package/types/db/payload-view.d.ts +4 -0
- package/types/db/payload-view.d.ts.map +1 -0
- package/types/db/reger.d.ts +15 -7
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/subing.d.ts +6 -1
- package/types/db/subing.d.ts.map +1 -1
- package/types/db/tel-replay.d.ts +21 -0
- package/types/db/tel-replay.d.ts.map +1 -0
- package/types/db/witness-replay.d.ts +16 -0
- package/types/db/witness-replay.d.ts.map +1 -0
- package/types/did/keri/resolving.d.ts +5 -10
- package/types/did/keri/resolving.d.ts.map +1 -1
- package/types/did/webs/artifacts.d.ts +5 -1
- package/types/did/webs/artifacts.d.ts.map +1 -1
- package/types/did/webs/designated-aliases.d.ts +5 -3
- package/types/did/webs/designated-aliases.d.ts.map +1 -1
- package/types/did/webs/documenting.d.ts +6 -5
- package/types/did/webs/documenting.d.ts.map +1 -1
- package/types/did/webs/resolving.d.ts.map +1 -1
- package/types/npm/deno-shim.d.ts +3 -0
- package/types/npm/deno-shim.d.ts.map +1 -0
- package/types/runtime/index.d.ts +72 -58
- package/types/runtime/index.d.ts.map +1 -1
- package/types/time/mod.d.ts +4 -2
- package/types/time/mod.d.ts.map +1 -1
- package/types/vdr/credential-tsn.d.ts +23 -0
- package/types/vdr/credential-tsn.d.ts.map +1 -0
- package/types/vdr/credentialing.d.ts +2 -12
- package/types/vdr/credentialing.d.ts.map +1 -1
- package/types/vdr/eventing.d.ts +23 -4
- package/types/vdr/eventing.d.ts.map +1 -1
- package/types/vdr/registry-tsn.d.ts +28 -0
- package/types/vdr/registry-tsn.d.ts.map +1 -0
- package/types/vdr/tsn-query.d.ts +27 -0
- package/types/vdr/tsn-query.d.ts.map +1 -0
- package/esm/keri/npm/src/app/query-transport.js +0 -121
- package/esm/keri/npm/src/db/mailbox-inbox.js +0 -206
- package/esm/keri/npm/src/db/outboxing.js +0 -328
- package/types/app/query-transport.d.ts +0 -13
- package/types/app/query-transport.d.ts.map +0 -1
- package/types/db/mailbox-inbox.d.ts +0 -72
- package/types/db/mailbox-inbox.d.ts.map +0 -1
- package/types/db/outboxing.d.ts +0 -160
- package/types/db/outboxing.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -15,17 +15,24 @@ npm install keri-ts
|
|
|
15
15
|
- `keri-ts/runtime`: explicit non-browser-safe runtime surface
|
|
16
16
|
- `keri-ts/db`: explicit LMDB-backed storage surface
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
Those three entrypoints are the general library surfaces. `keri-ts/cli` is the
|
|
19
|
+
separate command-helper boundary used by Tufa. Runnable CLI/server ownership
|
|
20
|
+
lives in `@keri-ts/tufa`.
|
|
21
|
+
|
|
22
|
+
The runtime exports deliberate operations and data contracts. Scheduling details,
|
|
23
|
+
handler installation, reply-slot state and constructor helpers remain internal;
|
|
24
|
+
implementation-module exports do not automatically become package API. npm deep
|
|
25
|
+
imports such as `keri-ts/app/...` and `keri-ts/core/...` are not supported. Import
|
|
26
|
+
runtime operations from `keri-ts/runtime` and storage from `keri-ts/db`.
|
|
20
27
|
|
|
21
28
|
## Maintainer Docs
|
|
22
29
|
|
|
23
30
|
- `docs/ARCHITECTURE_MAP.md`: package and module ownership map
|
|
24
|
-
- `docs/design-docs/
|
|
31
|
+
- `docs/design-docs/credentials/ACDC_TEL_VERIFIER.md`:
|
|
25
32
|
credential stack ownership and failure modes
|
|
26
|
-
- `docs/design-docs/
|
|
33
|
+
- `docs/design-docs/kel/DELEGATION_AND_ENDPOINTS.md`:
|
|
27
34
|
delegation, group coordination, and endpoint-role mental model
|
|
28
|
-
- `docs/design-docs/
|
|
35
|
+
- `docs/design-docs/cesr/ATTACHMENT_COUNTER_GVRSN.md`:
|
|
29
36
|
attachment counter versioning and replay boundaries
|
|
30
37
|
|
|
31
38
|
## License
|
|
@@ -125,6 +125,42 @@ export let import_meta_ponyfill = ((...args) => {
|
|
|
125
125
|
//@ts-ignore
|
|
126
126
|
return import_meta_ponyfill(...args);
|
|
127
127
|
});
|
|
128
|
+
function findLastIndex(self, callbackfn, that) {
|
|
129
|
+
const boundFunc = that === undefined ? callbackfn : callbackfn.bind(that);
|
|
130
|
+
let index = self.length - 1;
|
|
131
|
+
while (index >= 0) {
|
|
132
|
+
const result = boundFunc(self[index], index, self);
|
|
133
|
+
if (result) {
|
|
134
|
+
return index;
|
|
135
|
+
}
|
|
136
|
+
index--;
|
|
137
|
+
}
|
|
138
|
+
return -1;
|
|
139
|
+
}
|
|
140
|
+
function findLast(self, callbackfn, that) {
|
|
141
|
+
const index = self.findLastIndex(callbackfn, that);
|
|
142
|
+
return index === -1 ? undefined : self[index];
|
|
143
|
+
}
|
|
144
|
+
if (!Array.prototype.findLastIndex) {
|
|
145
|
+
Array.prototype.findLastIndex = function (callbackfn, that) {
|
|
146
|
+
return findLastIndex(this, callbackfn, that);
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (!Array.prototype.findLast) {
|
|
150
|
+
Array.prototype.findLast = function (callbackfn, that) {
|
|
151
|
+
return findLast(this, callbackfn, that);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (!Uint8Array.prototype.findLastIndex) {
|
|
155
|
+
Uint8Array.prototype.findLastIndex = function (callbackfn, that) {
|
|
156
|
+
return findLastIndex(this, callbackfn, that);
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (!Uint8Array.prototype.findLast) {
|
|
160
|
+
Uint8Array.prototype.findLast = function (callbackfn, that) {
|
|
161
|
+
return findLast(this, callbackfn, that);
|
|
162
|
+
};
|
|
163
|
+
}
|
|
128
164
|
// https://github.com/tc39/proposal-accessible-object-hasownproperty/blob/main/polyfill.js
|
|
129
165
|
if (!Object.hasOwn) {
|
|
130
166
|
Object.defineProperty(Object, "hasOwn", {
|
|
@@ -62,6 +62,11 @@ function schemaSaidAndSad(schema, fallback, kind) {
|
|
|
62
62
|
if (typeof schema === "string") {
|
|
63
63
|
return [schema, schema];
|
|
64
64
|
}
|
|
65
|
+
// Supplied content-bound JSON resources keep their identity across body kinds.
|
|
66
|
+
// Default/unbound schema construction retains its frozen format-specific IDs.
|
|
67
|
+
const resource = defaultSchema(cloneMapperValue(schema), Kinds.json);
|
|
68
|
+
if (schema.$id === resource[0])
|
|
69
|
+
return resource;
|
|
65
70
|
return defaultSchema(cloneMapperValue(schema), kind);
|
|
66
71
|
}
|
|
67
72
|
function withIssuee(attribute, issuee) {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** Explicit public registry intake; this TypeScript integration is beyond frozen KERIpy 927. */
|
|
2
|
+
import { Diger, Ilks, ParserError } from "cesr-ts";
|
|
3
|
+
import { DatabaseNotOpenError, DatabaseOperationError } from "../core/errors.js";
|
|
4
|
+
import { RegistryEventer } from "./regengine.js";
|
|
5
|
+
import { validateRip, validateUpdate } from "./regeventing.js";
|
|
6
|
+
/**
|
|
7
|
+
* Borrow accepted public KEL state and one registry store without habitats, aliases or handles.
|
|
8
|
+
* Reconstruct the engine's issuer from stored inception after reopen. Intake uses the engine's
|
|
9
|
+
* full tuple/witness anchor policy, distinct from digest-only observer vetting. Each accepted
|
|
10
|
+
* event commits independently; a later failure preserves the already accepted prefix.
|
|
11
|
+
* Parsed evidence stays borrowed. This installs no automatic parser or runtime route.
|
|
12
|
+
*/
|
|
13
|
+
export class RegistryObserver {
|
|
14
|
+
constructor(db, store) {
|
|
15
|
+
Object.defineProperty(this, "db", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: db
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(this, "store", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: store
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Stage parsed events before inception, otherwise delegate ordinary validation and acceptance. */
|
|
29
|
+
processEvent(serder) {
|
|
30
|
+
const result = serder.ilk === Ilks.rip ? validateRip(serder) : validateUpdate(serder, serder.regid ?? "");
|
|
31
|
+
if (result.kind === "reject")
|
|
32
|
+
return result;
|
|
33
|
+
const event = result.event;
|
|
34
|
+
// Unknown registry routing cannot rely on a stored RIP to validate its qualified SAID.
|
|
35
|
+
try {
|
|
36
|
+
if (new Diger({ qb64: event.regid }).qb64 !== event.regid)
|
|
37
|
+
return { kind: "reject", reason: "registry" };
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (!(error instanceof ParserError))
|
|
41
|
+
throw error;
|
|
42
|
+
return { kind: "reject", reason: "registry" };
|
|
43
|
+
}
|
|
44
|
+
if (event.sn > BigInt(Number.MAX_SAFE_INTEGER))
|
|
45
|
+
return { kind: "reject", reason: "ordinalRange" };
|
|
46
|
+
let engine = this.engine(event.regid);
|
|
47
|
+
if (engine && !(engine instanceof RegistryEventer))
|
|
48
|
+
return engine;
|
|
49
|
+
if (event.ilk === Ilks.rip) {
|
|
50
|
+
if (!event.issuer)
|
|
51
|
+
return { kind: "reject", reason: "issuer" };
|
|
52
|
+
engine ??= new RegistryEventer(this.db, event.issuer, this.store, event.regid);
|
|
53
|
+
}
|
|
54
|
+
if (engine) {
|
|
55
|
+
return engine.processEvent(serder);
|
|
56
|
+
}
|
|
57
|
+
// Issuer/anchor discovery is impossible until RIP arrives; the existing anchor escrow owns this body.
|
|
58
|
+
const baser = this.store.baser;
|
|
59
|
+
if (baser.readonly)
|
|
60
|
+
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
61
|
+
return baser.env.transactionSync(() => {
|
|
62
|
+
this.store.putEvent(serder);
|
|
63
|
+
this.store.escrowMissingAnchor(event.regid, Number(event.sn), event.said);
|
|
64
|
+
return { kind: "escrow", reason: "inception", event };
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/** Retry one registry after inception/KEL dependencies arrive; never scan every registry implicitly. */
|
|
68
|
+
processEscrows(regid) {
|
|
69
|
+
const engine = this.engine(regid);
|
|
70
|
+
if (!(engine instanceof RegistryEventer))
|
|
71
|
+
return;
|
|
72
|
+
engine.processEscrows();
|
|
73
|
+
}
|
|
74
|
+
/** Stored inception is durable issuer identity, including while its anchor is still absent. */
|
|
75
|
+
engine(regid) {
|
|
76
|
+
if (!this.store.baser.env)
|
|
77
|
+
throw new DatabaseNotOpenError("Registry observer store is closed.");
|
|
78
|
+
const rip = this.store.event(regid);
|
|
79
|
+
if (!rip) {
|
|
80
|
+
if (this.store.head(regid) || this.store.seqSaider(regid, 0)) {
|
|
81
|
+
throw new Error("Corrupt observer registry inception.");
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
if (rip.said !== regid)
|
|
86
|
+
throw new Error("Corrupt observer registry inception.");
|
|
87
|
+
// evts also owns valid BUP bodies; naming one as a registry is remote misuse, not store corruption.
|
|
88
|
+
if (rip.ilk !== Ilks.rip && rip.verify())
|
|
89
|
+
return { kind: "reject", reason: "registry" };
|
|
90
|
+
const result = validateRip(rip);
|
|
91
|
+
if (result.kind !== "valid" || result.event.regid !== regid || !result.event.issuer) {
|
|
92
|
+
throw new Error("Corrupt observer registry inception.");
|
|
93
|
+
}
|
|
94
|
+
return new RegistryEventer(this.db, result.event.issuer, this.store, regid);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
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";
|
|
5
|
+
import { B64OnIoSetSuber, CatCesrSuber, CesrOnSuber, CesrSuber, SerderSuber } from "../db/subing.js";
|
|
6
|
+
/**
|
|
7
|
+
* Own one environment for public registry TEL bodies, accepted ordinals and heads.
|
|
8
|
+
* Mirrors frozen KERIpy RegBaser's typed tables; opening neither verifies
|
|
9
|
+
* evidence nor migrates rows. Every current store has anchor and escrow tables.
|
|
10
|
+
* Construction stays closed; callers own reopen and joined close.
|
|
11
|
+
*/
|
|
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
|
+
return this.env.getBinary(b(name)) !== undefined;
|
|
18
|
+
}
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
super(options, {
|
|
21
|
+
tailDirPath: "keri/acdc/reg",
|
|
22
|
+
cleanTailDirPath: "keri/clean/acdc/reg",
|
|
23
|
+
altTailDirPath: options.compat ? ".keri/acdc/reg" : ".tufa/acdc/reg",
|
|
24
|
+
altCleanTailDirPath: options.compat ? ".keri/clean/acdc/reg" : ".tufa/clean/acdc/reg",
|
|
25
|
+
tempPrefix: "keri_acdc_reg_",
|
|
26
|
+
});
|
|
27
|
+
/** Event-SAID -> parsed rip/bup body; body presence alone is not acceptance. */
|
|
28
|
+
Object.defineProperty(this, "evts", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
configurable: true,
|
|
31
|
+
writable: true,
|
|
32
|
+
value: void 0
|
|
33
|
+
});
|
|
34
|
+
/** Registry-SAID + ordinal -> accepted event SAID; this is the acceptance marker. */
|
|
35
|
+
Object.defineProperty(this, "tels", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: void 0
|
|
40
|
+
});
|
|
41
|
+
/** Registry-SAID -> current accepted head SAID; physical heds. is rebuildable from tels. */
|
|
42
|
+
Object.defineProperty(this, "heads", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: void 0
|
|
47
|
+
});
|
|
48
|
+
/** Event-SAID -> earliest verified KEL source couple, in the current store. */
|
|
49
|
+
Object.defineProperty(this, "ancs", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
writable: true,
|
|
53
|
+
value: void 0
|
|
54
|
+
});
|
|
55
|
+
/** Insertion-ordered missing-anchor event-SAID tuples by registry and ordinal. */
|
|
56
|
+
Object.defineProperty(this, "maes", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: void 0
|
|
61
|
+
});
|
|
62
|
+
/** Insertion-ordered out-of-order event-SAID tuples by registry and ordinal. */
|
|
63
|
+
Object.defineProperty(this, "ooes", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: void 0
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/** Rebind the same environment's typed tables after every joined reopen. */
|
|
71
|
+
*reopen(options = {}) {
|
|
72
|
+
const opened = yield* super.reopen(options);
|
|
73
|
+
if (!opened)
|
|
74
|
+
return false;
|
|
75
|
+
try {
|
|
76
|
+
this.evts = new SerderSuber(this, { subkey: "evts.", ctor: SerderACDC });
|
|
77
|
+
this.tels = new CesrOnSuber(this, { subkey: "tels.", ctor: Saider });
|
|
78
|
+
this.heads = new CesrSuber(this, { subkey: "heds.", ctor: Saider });
|
|
79
|
+
this.ancs = new CatCesrSuber(this, { subkey: "ancs.", ctor: [NumberPrimitive, Diger] });
|
|
80
|
+
this.maes = new B64OnIoSetSuber(this, { subkey: "maes." });
|
|
81
|
+
this.ooes = new B64OnIoSetSuber(this, { subkey: "ooes." });
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
yield* this.close();
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/** Shared TEL validation, accepted-state publication, anchoring and retry for local and foreign registries. */
|
|
2
|
+
import { Diger, Ilks, NumberPrimitive, } from "cesr-ts";
|
|
3
|
+
import { DatabaseNotOpenError, DatabaseOperationError } from "../core/errors.js";
|
|
4
|
+
import { validateRip, validateUpdate, verifyRegistryAnchor, } from "./regeventing.js";
|
|
5
|
+
/**
|
|
6
|
+
* Borrow the issuer's accepted KEL and registry store; no keys or handles are acquired.
|
|
7
|
+
* The local facade and foreign observer share this accepted-state engine.
|
|
8
|
+
* Publication is atomic; binding this instance happens only after successful commit.
|
|
9
|
+
*/
|
|
10
|
+
export class RegistryEventer {
|
|
11
|
+
constructor(db, issuer, store, regk = null) {
|
|
12
|
+
Object.defineProperty(this, "db", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: db
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "issuer", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: issuer
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "store", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: store
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "regk", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: regk
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/** Validated accepted head metadata; local construction may inspect it without duplicating acceptance checks. */
|
|
38
|
+
get acceptedHeadEvent() {
|
|
39
|
+
return this.regk ? this.acceptedHead(this.regk) : null;
|
|
40
|
+
}
|
|
41
|
+
/** Read the accepted head only after validating its body and ordinal marker. */
|
|
42
|
+
get head() {
|
|
43
|
+
const event = this.acceptedHeadEvent;
|
|
44
|
+
return event ? this.store.head(event.regid) : null;
|
|
45
|
+
}
|
|
46
|
+
/** Accepted TEL ordinal, retaining -1n for a staged but unaccepted inception. */
|
|
47
|
+
get sn() {
|
|
48
|
+
return this.acceptedHeadEvent?.sn ?? -1n;
|
|
49
|
+
}
|
|
50
|
+
/** Return an accepted inception; a corrupt marker/body pair throws. */
|
|
51
|
+
get regser() {
|
|
52
|
+
return this.regk ? this.acceptedAt(this.regk, 0) : null;
|
|
53
|
+
}
|
|
54
|
+
/** Retry newly visible anchors, then advance the contiguous accepted chain. */
|
|
55
|
+
processEscrows() {
|
|
56
|
+
this.processMissingAnchors();
|
|
57
|
+
this.processQueued();
|
|
58
|
+
}
|
|
59
|
+
/** Authenticate a complete explicit source couple or discover one for a stored event. */
|
|
60
|
+
anchorMsg(said, number, diger) {
|
|
61
|
+
const serder = this.store.event(said);
|
|
62
|
+
if (!serder)
|
|
63
|
+
return { kind: "reject", reason: "event" };
|
|
64
|
+
if (serder.said !== said)
|
|
65
|
+
throw new Error("Corrupt escrowed registry event.");
|
|
66
|
+
const result = this.regk === null || serder.ilk === Ilks.rip
|
|
67
|
+
? validateRip(serder, this.issuer)
|
|
68
|
+
: validateUpdate(serder, this.regk);
|
|
69
|
+
if (result.kind === "reject")
|
|
70
|
+
return result;
|
|
71
|
+
const event = result.event;
|
|
72
|
+
if (this.regk !== null && event.regid !== this.regk)
|
|
73
|
+
return { kind: "reject", reason: "registry" };
|
|
74
|
+
if (event.sn > BigInt(Number.MAX_SAFE_INTEGER))
|
|
75
|
+
return { kind: "reject", reason: "ordinalRange" };
|
|
76
|
+
const occupied = this.acceptedEvent(event);
|
|
77
|
+
if (occupied?.kind === "reject")
|
|
78
|
+
return occupied;
|
|
79
|
+
const prior = event.sn > 0n ? this.acceptedAt(event.regid, Number(event.sn) - 1) : null;
|
|
80
|
+
if (prior && prior.said !== event.prior)
|
|
81
|
+
return { kind: "reject", reason: "prior" };
|
|
82
|
+
if ((number === undefined) !== (diger === undefined))
|
|
83
|
+
return { kind: "reject", reason: "anchor" };
|
|
84
|
+
if (number && diger) {
|
|
85
|
+
if (!verifyRegistryAnchor(event, { db: this.db, issuer: this.issuer, number, diger })) {
|
|
86
|
+
return { kind: "reject", reason: "anchor" };
|
|
87
|
+
}
|
|
88
|
+
this.store.putAnchor(said, number, diger);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.discoverAnchor(event);
|
|
92
|
+
}
|
|
93
|
+
if (!this.store.anchor(said))
|
|
94
|
+
return { kind: "reject", reason: "anchor" };
|
|
95
|
+
return this.processEvent(serder);
|
|
96
|
+
}
|
|
97
|
+
/** Advance only the next ordinal, committing one verified winner per transaction. */
|
|
98
|
+
processQueued() {
|
|
99
|
+
if (this.regk === null)
|
|
100
|
+
return;
|
|
101
|
+
while (true) {
|
|
102
|
+
const head = this.acceptedHead(this.regk);
|
|
103
|
+
if (!head)
|
|
104
|
+
return;
|
|
105
|
+
const sn = head.sn + 1n;
|
|
106
|
+
if (sn > BigInt(Number.MAX_SAFE_INTEGER))
|
|
107
|
+
return;
|
|
108
|
+
const candidates = this.store.baser.ooes.get(this.regk, Number(sn)).map(([said]) => said);
|
|
109
|
+
candidates.sort((a, b) => this.compareAnchors(a, b));
|
|
110
|
+
let advanced = false;
|
|
111
|
+
for (const said of candidates) {
|
|
112
|
+
const event = this.replayCandidate(said, Number(sn));
|
|
113
|
+
if (!event || !this.store.anchor(said))
|
|
114
|
+
continue;
|
|
115
|
+
const decision = this.processOne(event.serder);
|
|
116
|
+
if (decision.kind === "accept") {
|
|
117
|
+
advanced = true;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!advanced)
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** Retry anchor escrow by ordinal, arbitrating siblings before entering normal acceptance. */
|
|
126
|
+
processMissingAnchors() {
|
|
127
|
+
if (this.regk === null)
|
|
128
|
+
return;
|
|
129
|
+
const slots = new Map();
|
|
130
|
+
// Finish the read cursor before writes.
|
|
131
|
+
for (const [, sn, [said]] of this.store.baser.maes.getTopItemIter(this.regk)) {
|
|
132
|
+
if (!Number.isSafeInteger(sn) || sn < 0)
|
|
133
|
+
throw new RangeError("Unsafe registry escrow ordinal.");
|
|
134
|
+
const candidates = slots.get(sn) ?? [];
|
|
135
|
+
candidates.push(said);
|
|
136
|
+
slots.set(sn, candidates);
|
|
137
|
+
}
|
|
138
|
+
for (const [sn, saids] of [...slots].sort(([a], [b]) => a - b)) {
|
|
139
|
+
const candidates = [];
|
|
140
|
+
for (const said of saids) {
|
|
141
|
+
const event = this.replayCandidate(said, sn);
|
|
142
|
+
if (!event)
|
|
143
|
+
continue;
|
|
144
|
+
this.discoverAnchor(event);
|
|
145
|
+
candidates.push(event);
|
|
146
|
+
}
|
|
147
|
+
candidates.sort((a, b) => this.compareAnchors(a.said, b.said));
|
|
148
|
+
for (const event of candidates) {
|
|
149
|
+
const result = this.processEvent(event.serder);
|
|
150
|
+
if (result.kind === "reject" || result.kind === "duplicate") {
|
|
151
|
+
this.store.clearEscrows(this.regk, sn, event.said);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Prune unrecoverable candidates; corrupt records and storage failures still propagate. */
|
|
157
|
+
replayCandidate(said, sn) {
|
|
158
|
+
const serder = this.store.event(said);
|
|
159
|
+
if (!serder) {
|
|
160
|
+
this.store.clearEscrows(this.regk, sn, said);
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
if (serder.said !== said)
|
|
164
|
+
throw new Error("Corrupt escrowed registry event.");
|
|
165
|
+
const result = serder.ilk === Ilks.rip
|
|
166
|
+
? validateRip(serder, this.issuer)
|
|
167
|
+
: validateUpdate(serder, this.regk);
|
|
168
|
+
if (result.kind === "valid") {
|
|
169
|
+
const event = result.event;
|
|
170
|
+
if (event.regid === this.regk && event.sn === BigInt(sn)) {
|
|
171
|
+
const existing = this.acceptedEvent(event);
|
|
172
|
+
const prior = sn > 0 ? this.acceptedAt(event.regid, sn - 1) : null;
|
|
173
|
+
if (!existing && (!prior || prior.said === event.prior))
|
|
174
|
+
return event;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
this.store.clearEscrows(this.regk, sn, said);
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
/** Earliest verified anchor wins; digest then event SAID break ties using code-point order. */
|
|
181
|
+
compareAnchors(left, right) {
|
|
182
|
+
const a = this.store.anchor(left), b = this.store.anchor(right);
|
|
183
|
+
if (a && !b)
|
|
184
|
+
return -1;
|
|
185
|
+
if (!a && b)
|
|
186
|
+
return 1;
|
|
187
|
+
if (a && b) {
|
|
188
|
+
if (a[0].num !== b[0].num)
|
|
189
|
+
return a[0].num < b[0].num ? -1 : 1;
|
|
190
|
+
if (a[1].qb64 !== b[1].qb64)
|
|
191
|
+
return a[1].qb64 < b[1].qb64 ? -1 : 1;
|
|
192
|
+
}
|
|
193
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
194
|
+
}
|
|
195
|
+
/** Accept one parsed event, then advance ready successors without recursive replay. */
|
|
196
|
+
processEvent(serder) {
|
|
197
|
+
const decision = this.processOne(serder);
|
|
198
|
+
if (decision.kind === "accept")
|
|
199
|
+
this.processQueued();
|
|
200
|
+
return decision;
|
|
201
|
+
}
|
|
202
|
+
/** Decide and persist one event; callers own subsequent chain progression. */
|
|
203
|
+
processOne(serder) {
|
|
204
|
+
if (this.regk === null || serder.ilk === Ilks.rip)
|
|
205
|
+
return this.processInception(serder);
|
|
206
|
+
const result = validateUpdate(serder, this.regk);
|
|
207
|
+
if (result.kind === "reject")
|
|
208
|
+
return result;
|
|
209
|
+
const event = result.event;
|
|
210
|
+
// Preserve protocol precision until the existing ordinal storage seam can represent it.
|
|
211
|
+
if (event.sn > BigInt(Number.MAX_SAFE_INTEGER))
|
|
212
|
+
return { kind: "reject", reason: "ordinalRange" };
|
|
213
|
+
const prior = this.acceptedAt(event.regid, Number(event.sn) - 1);
|
|
214
|
+
if (prior && prior.said !== event.prior)
|
|
215
|
+
return { kind: "reject", reason: "prior" };
|
|
216
|
+
const previous = this.acceptedEvent(event);
|
|
217
|
+
if (previous)
|
|
218
|
+
return previous;
|
|
219
|
+
const env = this.store.baser.env;
|
|
220
|
+
if (!env)
|
|
221
|
+
throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
|
|
222
|
+
if (this.store.baser.readonly)
|
|
223
|
+
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
224
|
+
return env.transactionSync(() => {
|
|
225
|
+
const prior = this.acceptedAt(event.regid, Number(event.sn) - 1);
|
|
226
|
+
if (prior && prior.said !== event.prior)
|
|
227
|
+
return { kind: "reject", reason: "prior" };
|
|
228
|
+
const previous = this.acceptedEvent(event);
|
|
229
|
+
if (previous)
|
|
230
|
+
return previous;
|
|
231
|
+
this.store.putEvent(serder);
|
|
232
|
+
this.discoverAnchor(event);
|
|
233
|
+
if (!this.store.anchor(event.said)) {
|
|
234
|
+
this.store.escrowMissingAnchor(event.regid, Number(event.sn), event.said);
|
|
235
|
+
return { kind: "escrow", reason: "anchor", event };
|
|
236
|
+
}
|
|
237
|
+
this.store.baser.maes.rem(event.regid, Number(event.sn), [event.said]);
|
|
238
|
+
if (!prior) {
|
|
239
|
+
this.store.escrowOutOfOrder(event.regid, Number(event.sn), event.said);
|
|
240
|
+
return { kind: "escrow", reason: "order", event };
|
|
241
|
+
}
|
|
242
|
+
const head = this.acceptedHead(event.regid);
|
|
243
|
+
if (head && head.sn >= event.sn)
|
|
244
|
+
throw new Error("Registry update would downgrade accepted head.");
|
|
245
|
+
this.commit(event);
|
|
246
|
+
return { kind: "accept", event };
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/** Validate, anchor and accept one inception, or retain its body in anchor escrow. */
|
|
250
|
+
processInception(serder) {
|
|
251
|
+
const result = validateRip(serder, this.issuer);
|
|
252
|
+
if (result.kind === "reject")
|
|
253
|
+
return result;
|
|
254
|
+
const event = result.event;
|
|
255
|
+
if (this.regk !== null && this.regk !== event.regid)
|
|
256
|
+
return { kind: "reject", reason: "registry" };
|
|
257
|
+
const previous = this.acceptedEvent(event);
|
|
258
|
+
if (previous) {
|
|
259
|
+
if (previous.kind === "duplicate")
|
|
260
|
+
this.regk = event.regid;
|
|
261
|
+
return previous;
|
|
262
|
+
}
|
|
263
|
+
const env = this.store.baser.env;
|
|
264
|
+
if (!env)
|
|
265
|
+
throw new DatabaseNotOpenError("Registry acceptance requires an open backing store.");
|
|
266
|
+
if (this.store.baser.readonly)
|
|
267
|
+
throw new DatabaseOperationError("Cannot write readonly registry storage.");
|
|
268
|
+
const decision = env.transactionSync(() => {
|
|
269
|
+
const previous = this.acceptedEvent(event);
|
|
270
|
+
if (previous)
|
|
271
|
+
return previous;
|
|
272
|
+
if (this.store.head(event.regid))
|
|
273
|
+
throw new Error("Registry head exists without its accepted inception.");
|
|
274
|
+
this.store.putEvent(serder);
|
|
275
|
+
this.discoverAnchor(event);
|
|
276
|
+
if (!this.store.anchor(event.said)) {
|
|
277
|
+
this.store.escrowMissingAnchor(event.regid, 0, event.said);
|
|
278
|
+
return { kind: "escrow", reason: "anchor", event };
|
|
279
|
+
}
|
|
280
|
+
this.commit(event);
|
|
281
|
+
return { kind: "accept", event };
|
|
282
|
+
});
|
|
283
|
+
if (decision.kind !== "reject")
|
|
284
|
+
this.regk = event.regid;
|
|
285
|
+
return decision;
|
|
286
|
+
}
|
|
287
|
+
/** Replay is read-only; first acceptance repeats this check under its write transaction. */
|
|
288
|
+
acceptedEvent(event) {
|
|
289
|
+
const existing = this.acceptedAt(event.regid, Number(event.sn));
|
|
290
|
+
if (!existing)
|
|
291
|
+
return null;
|
|
292
|
+
if (existing.said !== event.said)
|
|
293
|
+
return { kind: "reject", reason: "duplicity" };
|
|
294
|
+
return { kind: "duplicate", event };
|
|
295
|
+
}
|
|
296
|
+
/** Accepted markers require a matching body at the exact ordinal, unlike mere staged bodies. */
|
|
297
|
+
acceptedAt(regid, sn) {
|
|
298
|
+
const marker = this.store.seqSaider(regid, sn);
|
|
299
|
+
if (!marker)
|
|
300
|
+
return null;
|
|
301
|
+
const body = this.store.event(marker.qb64);
|
|
302
|
+
if (!body)
|
|
303
|
+
throw new Error("Corrupt accepted registry event.");
|
|
304
|
+
const result = body.ilk === Ilks.rip
|
|
305
|
+
? validateRip(body, this.issuer)
|
|
306
|
+
: validateUpdate(body, regid);
|
|
307
|
+
if (result?.kind !== "valid" || result.event.said !== marker.qb64
|
|
308
|
+
|| result.event.sn !== BigInt(sn) || result.event.regid !== regid) {
|
|
309
|
+
throw new Error("Corrupt accepted registry event.");
|
|
310
|
+
}
|
|
311
|
+
return result.event.serder;
|
|
312
|
+
}
|
|
313
|
+
/** An accepted head must identify this registry's body and its matching accepted ordinal. */
|
|
314
|
+
acceptedHead(regid) {
|
|
315
|
+
const marker = this.store.head(regid);
|
|
316
|
+
if (!marker)
|
|
317
|
+
return null;
|
|
318
|
+
const body = this.store.event(marker.qb64);
|
|
319
|
+
if (!body)
|
|
320
|
+
throw new Error("Corrupt registry head.");
|
|
321
|
+
const result = body.ilk === Ilks.rip
|
|
322
|
+
? validateRip(body, this.issuer)
|
|
323
|
+
: validateUpdate(body, regid);
|
|
324
|
+
if (result?.kind !== "valid" || result.event.said !== marker.qb64 || result.event.regid !== regid
|
|
325
|
+
|| result.event.sn > BigInt(Number.MAX_SAFE_INTEGER))
|
|
326
|
+
throw new Error("Corrupt registry head.");
|
|
327
|
+
if (this.acceptedAt(regid, Number(result.event.sn))?.said !== marker.qb64) {
|
|
328
|
+
throw new Error("Corrupt registry head ordinal.");
|
|
329
|
+
}
|
|
330
|
+
return result.event;
|
|
331
|
+
}
|
|
332
|
+
/** Publish one verified winner and remove all siblings from its decided slot atomically. */
|
|
333
|
+
commit(event) {
|
|
334
|
+
this.store.accept(event.regid, Number(event.sn), event.serder);
|
|
335
|
+
this.store.baser.maes.rem(event.regid, Number(event.sn));
|
|
336
|
+
this.store.baser.ooes.rem(event.regid, Number(event.sn));
|
|
337
|
+
}
|
|
338
|
+
/** Keep an already verified anchor or discover the earliest fully witnessed seal. */
|
|
339
|
+
discoverAnchor(event) {
|
|
340
|
+
if (this.store.anchor(event.said))
|
|
341
|
+
return;
|
|
342
|
+
const anchor = this.db.fetchLastSealingEventByEventSeal(this.issuer, {
|
|
343
|
+
i: event.regid,
|
|
344
|
+
s: event.serder.sad.n,
|
|
345
|
+
d: event.said,
|
|
346
|
+
});
|
|
347
|
+
if (!anchor)
|
|
348
|
+
return;
|
|
349
|
+
const number = NumberPrimitive.fromNum(BigInt(anchor.sn));
|
|
350
|
+
const diger = new Diger({ qb64: anchor.said });
|
|
351
|
+
if (verifyRegistryAnchor(event, { db: this.db, issuer: this.issuer, number, diger })) {
|
|
352
|
+
this.store.putAnchor(event.said, number, diger);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|