keri-ts 1.0.0 → 2.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 +23 -0
- package/esm/keri/npm/src/acdc/chaining.js +213 -0
- package/esm/keri/npm/src/acdc/dhking.js +716 -0
- package/esm/keri/npm/src/acdc/messaging.js +2 -0
- package/esm/keri/npm/src/acdc/observing.js +40 -7
- package/esm/keri/npm/src/acdc/regbasing.js +13 -2
- package/esm/keri/npm/src/acdc/regengine.js +71 -23
- package/esm/keri/npm/src/acdc/regeventing.js +163 -44
- package/esm/keri/npm/src/acdc/registering.js +93 -14
- package/esm/keri/npm/src/acdc/relating.js +59 -0
- package/esm/keri/npm/src/acdc/salting.js +720 -0
- package/esm/keri/npm/src/acdc/scheming.js +94 -39
- package/esm/keri/npm/src/acdc/unblinding.js +1042 -0
- package/esm/keri/npm/src/app/{authenticating.js → bootstrap/authenticating.js} +39 -18
- package/esm/keri/npm/src/app/bootstrap/bootstrapping.js +109 -0
- package/esm/keri/npm/src/app/{oobi-replies.js → bootstrap/oobi-replies.js} +8 -6
- package/esm/keri/npm/src/app/{oobiery.js → bootstrap/oobiery.js} +161 -75
- package/esm/keri/npm/src/app/credentials/credential-importing.js +201 -0
- package/esm/keri/npm/src/app/credentials/credential-proposals.js +120 -0
- package/esm/keri/npm/src/app/credentials/credential-revoking.js +165 -0
- package/esm/keri/npm/src/app/credentials/credential-workflows.js +365 -0
- package/esm/keri/npm/src/app/credentials/tel-publishing.js +27 -0
- package/esm/keri/npm/src/app/{verifying.js → credentials/verifying.js} +41 -6
- package/esm/keri/npm/src/app/delivery/forwarding.js +600 -0
- package/esm/keri/npm/src/app/delivery/introducing.js +68 -0
- package/esm/keri/npm/src/app/{reply-streams.js → delivery/reply-streams.js} +52 -7
- package/esm/keri/npm/src/app/delivery/respondant.js +159 -0
- package/esm/keri/npm/src/app/{stored-replies.js → delivery/stored-replies.js} +4 -4
- package/esm/keri/npm/src/app/exchanges/essr.js +111 -0
- package/esm/keri/npm/src/app/exchanges/exchange-messaging.js +66 -0
- package/esm/keri/npm/src/app/exchanges/exchanging.js +1354 -0
- package/esm/keri/npm/src/app/{configing.js → identity/configing.js} +4 -4
- package/esm/keri/npm/src/app/{delegating.js → identity/delegating.js} +99 -29
- package/esm/keri/npm/src/app/{endpoint-roleing.js → identity/endpoint-roleing.js} +36 -36
- package/esm/keri/npm/src/app/{habbing.js → identity/habbing.js} +232 -150
- package/esm/keri/npm/src/app/{keeping.js → identity/keeping.js} +60 -56
- package/esm/keri/npm/src/app/{organizing.js → identity/organizing.js} +47 -21
- package/esm/keri/npm/src/app/ipex/ipex-building.js +162 -0
- package/esm/keri/npm/src/app/{ipex-credentialing.js → ipex/ipex-credentialing.js} +142 -31
- package/esm/keri/npm/src/app/ipex/ipex-graph.js +243 -0
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +664 -0
- package/esm/keri/npm/src/app/{ipex-node-authentication.js → ipex/ipex-node-authentication.js} +83 -6
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +692 -0
- package/esm/keri/npm/src/app/{ipexing.js → ipex/ipexing.js} +58 -1
- package/esm/keri/npm/src/app/mailbox/forward-handler.js +228 -0
- package/esm/keri/npm/src/app/{mailbox-director.js → mailbox/mailbox-director.js} +120 -15
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +305 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-sse.js +254 -0
- package/esm/keri/npm/src/app/{mailboxing.js → mailbox/mailboxing.js} +118 -67
- package/esm/keri/npm/src/app/mailbox/topic-routing.js +54 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +173 -0
- package/esm/keri/npm/src/app/{grouping.js → multisig/grouping.js} +384 -70
- package/esm/keri/npm/src/app/multisig/multisig-messaging.js +164 -0
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +821 -0
- package/esm/keri/npm/src/app/{notifying.js → notifications/notifying.js} +8 -14
- package/esm/keri/npm/src/app/{signaling.js → notifications/signaling.js} +1 -1
- package/esm/keri/npm/src/app/{parsering.js → protocol/parsering.js} +86 -18
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +245 -0
- package/esm/keri/npm/src/app/protocol/reactor.js +55 -0
- package/esm/keri/npm/src/app/{query-replies.js → queries/query-replies.js} +57 -6
- package/esm/keri/npm/src/app/queries/querying.js +306 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +415 -0
- package/esm/keri/npm/src/app/{abortable.js → runtime/abortable.js} +43 -4
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +633 -0
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +61 -0
- package/esm/keri/npm/src/app/runtime/runtime-clock.js +6 -0
- package/esm/keri/npm/src/app/{byte-source.js → transport/byte-source.js} +36 -6
- package/esm/keri/npm/src/app/transport/cesr-egress.js +317 -0
- package/esm/keri/npm/src/app/{cesr-http.js → transport/cesr-http.js} +20 -55
- package/esm/keri/npm/src/app/transport/http-client.js +172 -0
- package/esm/keri/npm/src/app/transport/http-messenger.js +52 -0
- package/esm/keri/npm/src/app/transport/http-stream-messenger.js +60 -0
- package/esm/keri/npm/src/app/transport/httping.js +57 -0
- package/esm/keri/npm/src/app/transport/message-source.js +77 -0
- package/esm/keri/npm/src/app/transport/messengering.js +68 -0
- package/esm/keri/npm/src/app/{socket-source.js → transport/socket-source.js} +39 -2
- package/esm/keri/npm/src/app/transport/tcp-egress.js +377 -0
- package/esm/keri/npm/src/app/transport/tcp-messenger.js +162 -0
- package/esm/keri/npm/src/app/transport/tcp-stream-messenger.js +40 -0
- package/esm/keri/npm/src/app/transport/transport-error.js +14 -0
- package/esm/keri/npm/src/app/witness/http-endpoints.js +185 -0
- package/esm/keri/npm/src/app/witness/ingress.js +148 -0
- package/esm/keri/npm/src/app/witness/receipt-client.js +248 -0
- package/esm/keri/npm/src/app/witness/receipt-messages.js +29 -0
- package/esm/keri/npm/src/app/witness/receipting.js +323 -0
- package/esm/keri/npm/src/app/witness/registration.js +50 -0
- package/esm/keri/npm/src/cli/common/bootstrap.js +12 -0
- package/esm/keri/npm/src/{app/cli → cli}/common/context.js +47 -6
- package/esm/keri/npm/src/{app/cli → cli}/common/existing.js +9 -11
- package/esm/keri/npm/src/cli/common/parsing.js +279 -0
- package/esm/keri/npm/src/cli/common/passcode.js +66 -0
- package/esm/keri/npm/src/cli/common/tel-completion.js +24 -0
- package/esm/keri/npm/src/{app/cli → cli}/common/witness-auth.js +2 -2
- package/esm/keri/npm/src/cli/credentials/ipex.js +702 -0
- package/esm/keri/npm/src/cli/credentials/vc.js +399 -0
- package/esm/keri/npm/src/{app/cli → cli/endpoints}/did.js +63 -36
- package/esm/keri/npm/src/{app/cli → cli/endpoints}/ends.js +33 -28
- package/esm/keri/npm/src/{app/cli → cli/endpoints}/loc.js +16 -11
- package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +134 -0
- package/esm/keri/npm/src/{app/cli → cli/endpoints}/oobi.js +35 -32
- package/esm/keri/npm/src/{app/cli → cli/identity}/aid.js +8 -7
- package/esm/keri/npm/src/{app/cli → cli/identity}/challenge.js +60 -49
- package/esm/keri/npm/src/{app/cli → cli/identity}/delegate.js +61 -26
- package/esm/keri/npm/src/{app/cli → cli/identity}/export.js +9 -8
- package/esm/keri/npm/src/cli/identity/incept.js +181 -0
- package/esm/keri/npm/src/cli/identity/init.js +153 -0
- package/esm/keri/npm/src/cli/identity/interact.js +84 -0
- package/esm/keri/npm/src/{app/cli → cli/identity}/list.js +7 -6
- package/esm/keri/npm/src/{app/cli → cli/identity}/rotate.js +60 -57
- package/esm/keri/npm/src/cli/index.js +38 -0
- package/esm/keri/npm/src/{app/cli → cli/messaging}/exchange.js +24 -22
- package/esm/keri/npm/src/{app/cli → cli/messaging}/multisig.js +165 -156
- package/esm/keri/npm/src/{app/cli → cli/messaging}/notifications.js +26 -22
- package/esm/keri/npm/src/{app/cli → cli}/output.js +1 -1
- package/esm/keri/npm/src/{app/cli → cli/tools}/annotate.js +10 -4
- package/esm/keri/npm/src/{app/cli → cli/tools}/benchmark.js +15 -4
- package/esm/keri/npm/src/{app/cli → cli/tools}/db-dump.js +11 -10
- package/esm/keri/npm/src/{app/cli → cli/tools}/saidify.js +3 -2
- package/esm/keri/npm/src/{app/cli → cli/tools}/sign.js +16 -10
- package/esm/keri/npm/src/{app/cli → cli/tools}/verify.js +10 -10
- package/esm/keri/npm/src/core/attachment-countering.js +31 -1
- package/esm/keri/npm/src/core/{exchange-proofing.js → exchange/exchange-proofing.js} +32 -2
- package/esm/keri/npm/src/core/{protocol-exchanging.js → exchange/protocol-exchanging.js} +26 -4
- package/esm/keri/npm/src/core/genus-framing.js +44 -0
- package/esm/keri/npm/src/core/{eventing.js → kel/eventing.js} +57 -25
- package/esm/keri/npm/src/core/{kever-decisions.js → kel/kever-decisions.js} +24 -12
- package/esm/keri/npm/src/core/{kever.js → kel/kever.js} +4 -4
- package/esm/keri/npm/src/core/logger.js +3 -3
- package/esm/keri/npm/src/core/{kram-policy.js → mailbox/kram-policy.js} +14 -4
- package/esm/keri/npm/src/core/{kram-pruning.js → mailbox/kram-pruning.js} +3 -3
- package/esm/keri/npm/src/core/{kram-signatures.js → mailbox/kram-signatures.js} +1 -1
- package/esm/keri/npm/src/core/{kram-staging.js → mailbox/kram-staging.js} +6 -6
- package/esm/keri/npm/src/core/{kram-time.js → mailbox/kram-time.js} +4 -3
- package/esm/keri/npm/src/core/{kraming.js → mailbox/kraming.js} +2 -2
- package/esm/keri/npm/src/core/protocol-eventing.js +1 -1
- package/esm/keri/npm/src/core/protocol-serialization.js +9 -34
- package/esm/keri/npm/src/core/routing.js +52 -17
- package/esm/keri/npm/src/db/baser-defaults.js +11 -0
- package/esm/keri/npm/src/db/basing.js +89 -232
- package/esm/keri/npm/src/db/core/lmdber.js +102 -63
- package/esm/keri/npm/src/db/escrowing.js +73 -49
- package/esm/keri/npm/src/db/exchange/exchange-nests.js +54 -0
- package/esm/keri/npm/src/db/exchange/exchange-records.js +7 -0
- package/esm/keri/npm/src/db/index.js +5 -4
- package/esm/keri/npm/src/db/keeping.js +122 -3
- package/esm/keri/npm/src/db/{kram-factors.js → mailbox/kram-factors.js} +1 -1
- package/esm/keri/npm/src/db/{mailboxing.js → mailbox/mailboxing.js} +3 -3
- package/esm/keri/npm/src/db/reger.js +38 -29
- package/esm/keri/npm/src/db/{kel-replay.js → replay/kel-replay.js} +11 -4
- package/esm/keri/npm/src/db/{tel-replay.js → replay/tel-replay.js} +34 -0
- package/esm/keri/npm/src/db/{witness-replay.js → replay/witness-replay.js} +2 -2
- package/esm/keri/npm/src/db/subing.js +2 -3
- package/esm/keri/npm/src/did/webs/artifacts.js +15 -18
- package/esm/keri/npm/src/did/webs/designated-aliases.js +5 -7
- package/esm/keri/npm/src/did/webs/resolving.js +73 -56
- package/esm/keri/npm/src/library/index.js +1 -1
- package/esm/keri/npm/src/npm/cli.js +1 -1
- package/esm/keri/npm/src/npm/index.js +1 -1
- package/esm/keri/npm/src/runtime/index.js +79 -47
- package/esm/keri/npm/src/vdr/backer-state.js +55 -0
- package/esm/keri/npm/src/vdr/credential-tsn-record.js +59 -0
- package/esm/keri/npm/src/vdr/credentialing.js +84 -82
- package/esm/keri/npm/src/vdr/eventing.js +592 -204
- package/esm/keri/npm/src/vdr/registry-tsn-record.js +55 -0
- package/esm/keri/npm/src/vdr/revoking.js +90 -0
- package/esm/keri/npm/src/vdr/tel-anchor.js +29 -0
- package/esm/keri/npm/src/vdr/tel-publication.js +178 -0
- package/esm/keri/npm/src/{app/version.js → version.js} +2 -2
- package/package.json +5 -3
- package/types/_dnt.polyfills.d.ts +6 -0
- package/types/_dnt.polyfills.d.ts.map +1 -1
- package/types/acdc/chaining.d.ts +35 -0
- package/types/acdc/chaining.d.ts.map +1 -0
- package/types/acdc/dhking.d.ts +136 -0
- package/types/acdc/dhking.d.ts.map +1 -0
- package/types/acdc/messaging.d.ts.map +1 -1
- package/types/acdc/observing.d.ts +18 -7
- package/types/acdc/observing.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +3 -1
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/regengine.d.ts +9 -4
- package/types/acdc/regengine.d.ts.map +1 -1
- package/types/acdc/regeventing.d.ts +24 -7
- package/types/acdc/regeventing.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +22 -6
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/registraring.d.ts +1 -1
- package/types/acdc/registraring.d.ts.map +1 -1
- package/types/acdc/relating.d.ts +21 -0
- package/types/acdc/relating.d.ts.map +1 -0
- package/types/acdc/salting.d.ts +241 -0
- package/types/acdc/salting.d.ts.map +1 -0
- package/types/acdc/scheming.d.ts +1 -1
- package/types/acdc/scheming.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts +150 -0
- package/types/acdc/unblinding.d.ts.map +1 -0
- package/types/app/bootstrap/authenticating.d.ts +54 -0
- package/types/app/bootstrap/authenticating.d.ts.map +1 -0
- package/types/app/bootstrap/bootstrapping.d.ts +45 -0
- package/types/app/bootstrap/bootstrapping.d.ts.map +1 -0
- package/types/app/{oobi-replies.d.ts → bootstrap/oobi-replies.d.ts} +1 -1
- package/types/app/bootstrap/oobi-replies.d.ts.map +1 -0
- package/types/app/{oobiery.d.ts → bootstrap/oobiery.d.ts} +98 -25
- package/types/app/bootstrap/oobiery.d.ts.map +1 -0
- package/types/app/credentials/credential-importing.d.ts +29 -0
- package/types/app/credentials/credential-importing.d.ts.map +1 -0
- package/types/app/credentials/credential-proposals.d.ts +27 -0
- package/types/app/credentials/credential-proposals.d.ts.map +1 -0
- package/types/app/credentials/credential-revoking.d.ts +44 -0
- package/types/app/credentials/credential-revoking.d.ts.map +1 -0
- package/types/app/credentials/credential-workflows.d.ts +149 -0
- package/types/app/credentials/credential-workflows.d.ts.map +1 -0
- package/types/app/{schema-resolving.d.ts → credentials/schema-resolving.d.ts} +2 -2
- package/types/app/credentials/schema-resolving.d.ts.map +1 -0
- package/types/app/credentials/tel-publishing.d.ts +16 -0
- package/types/app/credentials/tel-publishing.d.ts.map +1 -0
- package/types/app/{verifying.d.ts → credentials/verifying.d.ts} +19 -7
- package/types/app/credentials/verifying.d.ts.map +1 -0
- package/types/app/delivery/forwarding.d.ts +227 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -0
- package/types/app/delivery/introducing.d.ts +21 -0
- package/types/app/delivery/introducing.d.ts.map +1 -0
- package/types/app/delivery/reply-streams.d.ts +49 -0
- package/types/app/delivery/reply-streams.d.ts.map +1 -0
- package/types/app/delivery/respondant.d.ts +52 -0
- package/types/app/delivery/respondant.d.ts.map +1 -0
- package/types/app/{stored-replies.d.ts → delivery/stored-replies.d.ts} +1 -1
- package/types/app/delivery/stored-replies.d.ts.map +1 -0
- package/types/app/exchanges/essr.d.ts +53 -0
- package/types/app/exchanges/essr.d.ts.map +1 -0
- package/types/app/exchanges/exchange-messaging.d.ts +73 -0
- package/types/app/exchanges/exchange-messaging.d.ts.map +1 -0
- package/types/app/exchanges/exchanging.d.ts +379 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -0
- package/types/app/{challenging.d.ts → identity/challenging.d.ts} +3 -3
- package/types/app/identity/challenging.d.ts.map +1 -0
- package/types/app/{configing.d.ts → identity/configing.d.ts} +1 -1
- package/types/app/identity/configing.d.ts.map +1 -0
- package/types/app/{delegating.d.ts → identity/delegating.d.ts} +52 -15
- package/types/app/identity/delegating.d.ts.map +1 -0
- package/types/app/{endpoint-roleing.d.ts → identity/endpoint-roleing.d.ts} +24 -13
- package/types/app/identity/endpoint-roleing.d.ts.map +1 -0
- package/types/app/{habbing.d.ts → identity/habbing.d.ts} +73 -32
- package/types/app/identity/habbing.d.ts.map +1 -0
- package/types/app/{keeping.d.ts → identity/keeping.d.ts} +19 -5
- package/types/app/identity/keeping.d.ts.map +1 -0
- package/types/app/{organizing.d.ts → identity/organizing.d.ts} +19 -4
- package/types/app/identity/organizing.d.ts.map +1 -0
- package/types/app/ipex/ipex-building.d.ts +30 -0
- package/types/app/ipex/ipex-building.d.ts.map +1 -0
- package/types/app/{ipex-credentialing.d.ts → ipex/ipex-credentialing.d.ts} +33 -6
- package/types/app/ipex/ipex-credentialing.d.ts.map +1 -0
- package/types/app/ipex/ipex-graph.d.ts +28 -0
- package/types/app/ipex/ipex-graph.d.ts.map +1 -0
- package/types/app/ipex/ipex-grouping.d.ts +112 -0
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -0
- package/types/app/{ipex-node-authentication.d.ts → ipex/ipex-node-authentication.d.ts} +10 -5
- package/types/app/ipex/ipex-node-authentication.d.ts.map +1 -0
- package/types/app/ipex/ipex-v2.d.ts +71 -0
- package/types/app/ipex/ipex-v2.d.ts.map +1 -0
- package/types/app/{ipexing.d.ts → ipex/ipexing.d.ts} +21 -6
- package/types/app/ipex/ipexing.d.ts.map +1 -0
- package/types/app/mailbox/forward-handler.d.ts +68 -0
- package/types/app/mailbox/forward-handler.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-director.d.ts +252 -0
- package/types/app/mailbox/mailbox-director.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-poller.d.ts +149 -0
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-sse.d.ts +63 -0
- package/types/app/mailbox/mailbox-sse.d.ts.map +1 -0
- package/types/app/{mailboxing.d.ts → mailbox/mailboxing.d.ts} +92 -40
- package/types/app/mailbox/mailboxing.d.ts.map +1 -0
- package/types/app/mailbox/topic-routing.d.ts +18 -0
- package/types/app/mailbox/topic-routing.d.ts.map +1 -0
- package/types/app/multisig/group-members.d.ts +60 -0
- package/types/app/multisig/group-members.d.ts.map +1 -0
- package/types/app/{grouping.d.ts → multisig/grouping.d.ts} +142 -19
- package/types/app/multisig/grouping.d.ts.map +1 -0
- package/types/app/multisig/multisig-messaging.d.ts +97 -0
- package/types/app/multisig/multisig-messaging.d.ts.map +1 -0
- package/types/app/multisig/multisig-workflows.d.ts +85 -0
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -0
- package/types/app/{notifying.d.ts → notifications/notifying.d.ts} +4 -5
- package/types/app/notifications/notifying.d.ts.map +1 -0
- package/types/app/notifications/signaling.d.ts.map +1 -0
- package/types/app/{parsering.d.ts → protocol/parsering.d.ts} +40 -11
- package/types/app/protocol/parsering.d.ts.map +1 -0
- package/types/app/{protocol-host-policy.d.ts → protocol/protocol-host-policy.d.ts} +1 -10
- package/types/app/protocol/protocol-host-policy.d.ts.map +1 -0
- package/types/app/protocol/protocol-processing.d.ts +140 -0
- package/types/app/protocol/protocol-processing.d.ts.map +1 -0
- package/types/app/protocol/reactor.d.ts +43 -0
- package/types/app/protocol/reactor.d.ts.map +1 -0
- package/types/app/queries/query-replies.d.ts +78 -0
- package/types/app/queries/query-replies.d.ts.map +1 -0
- package/types/app/queries/querying.d.ts +155 -0
- package/types/app/queries/querying.d.ts.map +1 -0
- package/types/app/queries/witness-inquisitor.d.ts +150 -0
- package/types/app/queries/witness-inquisitor.d.ts.map +1 -0
- package/types/app/runtime/abortable.d.ts +39 -0
- package/types/app/runtime/abortable.d.ts.map +1 -0
- package/types/app/runtime/agent-runtime.d.ts +348 -0
- package/types/app/runtime/agent-runtime.d.ts.map +1 -0
- package/types/app/runtime/cue-runtime.d.ts +33 -0
- package/types/app/runtime/cue-runtime.d.ts.map +1 -0
- package/types/app/runtime/runtime-clock.d.ts +28 -0
- package/types/app/runtime/runtime-clock.d.ts.map +1 -0
- package/types/app/runtime/runtime-turn.d.ts.map +1 -0
- package/types/app/transport/byte-source.d.ts +41 -0
- package/types/app/transport/byte-source.d.ts.map +1 -0
- package/types/app/transport/cesr-egress.d.ts +117 -0
- package/types/app/transport/cesr-egress.d.ts.map +1 -0
- package/types/app/{cesr-http.d.ts → transport/cesr-http.d.ts} +4 -27
- package/types/app/transport/cesr-http.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts +99 -0
- package/types/app/transport/http-client.d.ts.map +1 -0
- package/types/app/transport/http-messenger.d.ts +37 -0
- package/types/app/transport/http-messenger.d.ts.map +1 -0
- package/types/app/transport/http-stream-messenger.d.ts +30 -0
- package/types/app/transport/http-stream-messenger.d.ts.map +1 -0
- package/types/app/transport/httping.d.ts +19 -0
- package/types/app/transport/httping.d.ts.map +1 -0
- package/types/app/transport/message-source.d.ts +22 -0
- package/types/app/transport/message-source.d.ts.map +1 -0
- package/types/app/transport/messengering.d.ts +41 -0
- package/types/app/transport/messengering.d.ts.map +1 -0
- package/types/app/{socket-source.d.ts → transport/socket-source.d.ts} +8 -0
- package/types/app/transport/socket-source.d.ts.map +1 -0
- package/types/app/transport/tcp-egress.d.ts +118 -0
- package/types/app/transport/tcp-egress.d.ts.map +1 -0
- package/types/app/transport/tcp-messenger.d.ts +69 -0
- package/types/app/transport/tcp-messenger.d.ts.map +1 -0
- package/types/app/transport/tcp-stream-messenger.d.ts +25 -0
- package/types/app/transport/tcp-stream-messenger.d.ts.map +1 -0
- package/types/app/transport/transport-error.d.ts +12 -0
- package/types/app/transport/transport-error.d.ts.map +1 -0
- package/types/app/witness/http-endpoints.d.ts +77 -0
- package/types/app/witness/http-endpoints.d.ts.map +1 -0
- package/types/app/witness/ingress.d.ts +65 -0
- package/types/app/witness/ingress.d.ts.map +1 -0
- package/types/app/witness/receipt-client.d.ts +82 -0
- package/types/app/witness/receipt-client.d.ts.map +1 -0
- package/types/app/witness/receipt-messages.d.ts +21 -0
- package/types/app/witness/receipt-messages.d.ts.map +1 -0
- package/types/app/witness/receipting.d.ts +117 -0
- package/types/app/witness/receipting.d.ts.map +1 -0
- package/types/app/witness/registration.d.ts +27 -0
- package/types/app/witness/registration.d.ts.map +1 -0
- package/types/cli/common/bootstrap.d.ts +5 -0
- package/types/cli/common/bootstrap.d.ts.map +1 -0
- package/types/{app/cli → cli}/common/context.d.ts +10 -5
- package/types/cli/common/context.d.ts.map +1 -0
- package/types/{app/cli → cli}/common/existing.d.ts +2 -4
- package/types/cli/common/existing.d.ts.map +1 -0
- package/types/{app/cli → cli}/common/parsing.d.ts +26 -15
- package/types/cli/common/parsing.d.ts.map +1 -0
- package/types/cli/common/passcode.d.ts +9 -0
- package/types/cli/common/passcode.d.ts.map +1 -0
- package/types/cli/common/rendering.d.ts.map +1 -0
- package/types/cli/common/tel-completion.d.ts +8 -0
- package/types/cli/common/tel-completion.d.ts.map +1 -0
- package/types/{app/cli → cli}/common/witness-auth.d.ts +1 -1
- package/types/cli/common/witness-auth.d.ts.map +1 -0
- package/types/cli/credentials/ipex.d.ts +110 -0
- package/types/cli/credentials/ipex.d.ts.map +1 -0
- package/types/cli/credentials/vc.d.ts +42 -0
- package/types/cli/credentials/vc.d.ts.map +1 -0
- package/types/{app/cli → cli/endpoints}/did.d.ts +5 -1
- package/types/cli/endpoints/did.d.ts.map +1 -0
- package/types/{app/cli → cli/endpoints}/ends.d.ts +9 -1
- package/types/cli/endpoints/ends.d.ts.map +1 -0
- package/types/cli/endpoints/loc.d.ts.map +1 -0
- package/types/cli/endpoints/oobi-clean.d.ts +8 -0
- package/types/cli/endpoints/oobi-clean.d.ts.map +1 -0
- package/types/{app/cli → cli/endpoints}/oobi.d.ts +2 -0
- package/types/cli/endpoints/oobi.d.ts.map +1 -0
- package/types/cli/identity/aid.d.ts.map +1 -0
- package/types/{app/cli → cli/identity}/challenge.d.ts +5 -1
- package/types/cli/identity/challenge.d.ts.map +1 -0
- package/types/cli/identity/delegate.d.ts.map +1 -0
- package/types/cli/identity/export.d.ts.map +1 -0
- package/types/{app/cli → cli/identity}/incept.d.ts +2 -0
- package/types/cli/identity/incept.d.ts.map +1 -0
- package/types/{app/cli → cli/identity}/init.d.ts +2 -0
- package/types/cli/identity/init.d.ts.map +1 -0
- package/types/{app/cli → cli/identity}/interact.d.ts +2 -0
- package/types/cli/identity/interact.d.ts.map +1 -0
- package/types/cli/identity/list.d.ts.map +1 -0
- package/types/{app/cli → cli/identity}/rotate.d.ts +9 -2
- package/types/cli/identity/rotate.d.ts.map +1 -0
- package/types/cli/index.d.ts +39 -0
- package/types/cli/index.d.ts.map +1 -0
- package/types/{app/cli → cli/messaging}/exchange.d.ts +3 -1
- package/types/cli/messaging/exchange.d.ts.map +1 -0
- package/types/cli/messaging/multisig.d.ts +29 -0
- package/types/cli/messaging/multisig.d.ts.map +1 -0
- package/types/cli/messaging/notifications.d.ts.map +1 -0
- package/types/cli/output.d.ts.map +1 -0
- package/types/cli/tools/annotate-color.d.ts.map +1 -0
- package/types/cli/tools/annotate.d.ts.map +1 -0
- package/types/cli/tools/benchmark.d.ts.map +1 -0
- package/types/cli/tools/db-dump.d.ts.map +1 -0
- package/types/cli/tools/saidify.d.ts.map +1 -0
- package/types/{app/cli → cli/tools}/sign.d.ts +2 -0
- package/types/cli/tools/sign.d.ts.map +1 -0
- package/types/cli/tools/verify.d.ts.map +1 -0
- package/types/core/attachment-countering.d.ts +10 -1
- package/types/core/attachment-countering.d.ts.map +1 -1
- package/types/core/cues.d.ts +78 -21
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/{exchange-proofing.d.ts → exchange/exchange-proofing.d.ts} +9 -2
- package/types/core/exchange/exchange-proofing.d.ts.map +1 -0
- package/types/core/{protocol-exchanging.d.ts → exchange/protocol-exchanging.d.ts} +10 -2
- package/types/core/exchange/protocol-exchanging.d.ts.map +1 -0
- package/types/core/genus-framing.d.ts +12 -0
- package/types/core/genus-framing.d.ts.map +1 -0
- package/types/core/{eventing.d.ts → kel/eventing.d.ts} +22 -10
- package/types/core/kel/eventing.d.ts.map +1 -0
- package/types/core/{kever-decisions.d.ts → kel/kever-decisions.d.ts} +21 -8
- package/types/core/kel/kever-decisions.d.ts.map +1 -0
- package/types/core/{kever.d.ts → kel/kever.d.ts} +2 -2
- package/types/core/kel/kever.d.ts.map +1 -0
- package/types/core/kel/witnesses.d.ts.map +1 -0
- package/types/core/logger.d.ts +1 -1
- package/types/core/logger.d.ts.map +1 -1
- package/types/core/{kram-auth.d.ts → mailbox/kram-auth.d.ts} +2 -2
- package/types/core/mailbox/kram-auth.d.ts.map +1 -0
- package/types/core/{kram-policy.d.ts → mailbox/kram-policy.d.ts} +2 -2
- package/types/core/mailbox/kram-policy.d.ts.map +1 -0
- package/types/core/{kram-pruning.d.ts → mailbox/kram-pruning.d.ts} +1 -1
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -0
- package/types/core/{kram-signatures.d.ts → mailbox/kram-signatures.d.ts} +3 -3
- package/types/core/mailbox/kram-signatures.d.ts.map +1 -0
- package/types/core/{kram-staging.d.ts → mailbox/kram-staging.d.ts} +2 -2
- package/types/core/mailbox/kram-staging.d.ts.map +1 -0
- package/types/core/{kram-time.d.ts → mailbox/kram-time.d.ts} +2 -2
- package/types/core/mailbox/kram-time.d.ts.map +1 -0
- package/types/core/{kraming.d.ts → mailbox/kraming.d.ts} +5 -5
- package/types/core/mailbox/kraming.d.ts.map +1 -0
- package/types/core/mailbox/mailbox-topics.d.ts.map +1 -0
- package/types/core/protocol-eventing.d.ts.map +1 -1
- package/types/core/protocol-serialization.d.ts +1 -1
- package/types/core/protocol-serialization.d.ts.map +1 -1
- package/types/core/records.d.ts +1 -1
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +24 -4
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/baser-defaults.d.ts +5 -0
- package/types/db/baser-defaults.d.ts.map +1 -0
- package/types/db/basing.d.ts +32 -44
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/lmdber.d.ts +18 -13
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/escrowing.d.ts +3 -1
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange/exchange-nests.d.ts +12 -0
- package/types/db/exchange/exchange-nests.d.ts.map +1 -0
- package/types/db/exchange/exchange-records.d.ts +38 -0
- package/types/db/exchange/exchange-records.d.ts.map +1 -0
- package/types/db/index.d.ts +5 -4
- package/types/db/index.d.ts.map +1 -1
- package/types/db/keeping.d.ts +19 -1
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/{kram-factors.d.ts → mailbox/kram-factors.d.ts} +2 -2
- package/types/db/mailbox/kram-factors.d.ts.map +1 -0
- package/types/db/{mailboxing.d.ts → mailbox/mailboxing.d.ts} +2 -2
- package/types/db/mailbox/mailboxing.d.ts.map +1 -0
- package/types/db/reger.d.ts +7 -6
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/{kel-replay.d.ts → replay/kel-replay.d.ts} +1 -2
- package/types/db/replay/kel-replay.d.ts.map +1 -0
- package/types/db/{tel-replay.d.ts → replay/tel-replay.d.ts} +11 -1
- package/types/db/replay/tel-replay.d.ts.map +1 -0
- package/types/db/{witness-replay.d.ts → replay/witness-replay.d.ts} +1 -1
- package/types/db/replay/witness-replay.d.ts.map +1 -0
- package/types/db/subing.d.ts.map +1 -1
- package/types/did/keri/resolving.d.ts +1 -1
- package/types/did/keri/resolving.d.ts.map +1 -1
- package/types/did/webs/artifacts.d.ts +5 -5
- package/types/did/webs/artifacts.d.ts.map +1 -1
- package/types/did/webs/designated-aliases.d.ts +1 -2
- package/types/did/webs/designated-aliases.d.ts.map +1 -1
- package/types/did/webs/documenting.d.ts +1 -1
- package/types/did/webs/documenting.d.ts.map +1 -1
- package/types/did/webs/resolving.d.ts +13 -9
- package/types/did/webs/resolving.d.ts.map +1 -1
- package/types/library/index.d.ts +1 -1
- package/types/library/index.d.ts.map +1 -1
- package/types/npm/cli.d.ts +1 -1
- package/types/npm/cli.d.ts.map +1 -1
- package/types/npm/index.d.ts +1 -1
- package/types/npm/index.d.ts.map +1 -1
- package/types/runtime/index.d.ts +86 -51
- package/types/runtime/index.d.ts.map +1 -1
- package/types/vdr/backer-state.d.ts +22 -0
- package/types/vdr/backer-state.d.ts.map +1 -0
- package/types/vdr/credential-tsn-record.d.ts +13 -0
- package/types/vdr/credential-tsn-record.d.ts.map +1 -0
- package/types/vdr/credentialing.d.ts +16 -17
- package/types/vdr/credentialing.d.ts.map +1 -1
- package/types/vdr/eventing.d.ts +60 -18
- package/types/vdr/eventing.d.ts.map +1 -1
- package/types/vdr/registry-tsn-record.d.ts +6 -0
- package/types/vdr/registry-tsn-record.d.ts.map +1 -0
- package/types/vdr/revoking.d.ts +18 -0
- package/types/vdr/revoking.d.ts.map +1 -0
- package/types/vdr/tel-anchor.d.ts +10 -0
- package/types/vdr/tel-anchor.d.ts.map +1 -0
- package/types/vdr/tel-publication.d.ts +49 -0
- package/types/vdr/tel-publication.d.ts.map +1 -0
- package/types/vdr/tsn-query.d.ts +1 -1
- package/types/vdr/tsn-query.d.ts.map +1 -1
- package/types/{app/version.d.ts → version.d.ts} +2 -2
- package/types/version.d.ts.map +1 -0
- package/esm/keri/npm/src/app/agent-runtime.js +0 -544
- package/esm/keri/npm/src/app/cesr-egress.js +0 -294
- package/esm/keri/npm/src/app/cli/common/displaying.js +0 -43
- package/esm/keri/npm/src/app/cli/common/parsing.js +0 -215
- package/esm/keri/npm/src/app/cli/incept.js +0 -185
- package/esm/keri/npm/src/app/cli/index.js +0 -36
- package/esm/keri/npm/src/app/cli/init.js +0 -149
- package/esm/keri/npm/src/app/cli/interact.js +0 -72
- package/esm/keri/npm/src/app/cli/ipex.js +0 -519
- package/esm/keri/npm/src/app/cli/query.js +0 -142
- package/esm/keri/npm/src/app/cli/vc.js +0 -283
- package/esm/keri/npm/src/app/cli/verifier.js +0 -92
- package/esm/keri/npm/src/app/credential-workflows.js +0 -409
- package/esm/keri/npm/src/app/cue-runtime.js +0 -38
- package/esm/keri/npm/src/app/essr.js +0 -170
- package/esm/keri/npm/src/app/exchanging.js +0 -1001
- package/esm/keri/npm/src/app/forwarding.js +0 -936
- package/esm/keri/npm/src/app/group-members.js +0 -37
- package/esm/keri/npm/src/app/httping.js +0 -162
- package/esm/keri/npm/src/app/ipex-graph.js +0 -407
- package/esm/keri/npm/src/app/ipex-grouping.js +0 -276
- package/esm/keri/npm/src/app/ipex-v2.js +0 -438
- package/esm/keri/npm/src/app/mailbox-sse.js +0 -240
- package/esm/keri/npm/src/app/multisig-workflows.js +0 -457
- package/esm/keri/npm/src/app/querying.js +0 -775
- package/esm/keri/npm/src/app/reactor.js +0 -394
- package/esm/keri/npm/src/app/respondant.js +0 -358
- package/esm/keri/npm/src/app/runtime-services.js +0 -22
- package/esm/keri/npm/src/app/tcp-conversation.js +0 -85
- package/esm/keri/npm/src/app/tcp-egress.js +0 -251
- package/esm/keri/npm/src/app/verifier-agent.js +0 -443
- package/esm/keri/npm/src/app/witnessing.js +0 -914
- package/esm/keri/npm/src/core/index.js +0 -23
- package/esm/keri/npm/src/db/exchange-nests.js +0 -80
- package/esm/keri/npm/src/db/exchange-records.js +0 -7
- package/esm/keri/npm/src/db/payload-archive.js +0 -402
- package/esm/keri/npm/src/db/payload-store.js +0 -406
- package/esm/keri/npm/src/db/payload-view.js +0 -23
- package/esm/keri/npm/src/db/verifier-cueing.js +0 -132
- package/esm/keri/npm/src/vdr/credential-tsn.js +0 -230
- package/esm/keri/npm/src/vdr/registry-tsn.js +0 -217
- package/types/app/abortable.d.ts +0 -13
- package/types/app/abortable.d.ts.map +0 -1
- package/types/app/agent-runtime.d.ts +0 -221
- package/types/app/agent-runtime.d.ts.map +0 -1
- package/types/app/authenticating.d.ts +0 -36
- package/types/app/authenticating.d.ts.map +0 -1
- package/types/app/byte-source.d.ts +0 -16
- package/types/app/byte-source.d.ts.map +0 -1
- package/types/app/cesr-egress.d.ts +0 -45
- package/types/app/cesr-egress.d.ts.map +0 -1
- package/types/app/cesr-http.d.ts.map +0 -1
- package/types/app/challenging.d.ts.map +0 -1
- package/types/app/cli/aid.d.ts.map +0 -1
- package/types/app/cli/annotate-color.d.ts.map +0 -1
- package/types/app/cli/annotate.d.ts.map +0 -1
- package/types/app/cli/benchmark.d.ts.map +0 -1
- package/types/app/cli/challenge.d.ts.map +0 -1
- package/types/app/cli/common/context.d.ts.map +0 -1
- package/types/app/cli/common/displaying.d.ts +0 -12
- package/types/app/cli/common/displaying.d.ts.map +0 -1
- package/types/app/cli/common/existing.d.ts.map +0 -1
- package/types/app/cli/common/parsing.d.ts.map +0 -1
- package/types/app/cli/common/rendering.d.ts.map +0 -1
- package/types/app/cli/common/witness-auth.d.ts.map +0 -1
- package/types/app/cli/db-dump.d.ts.map +0 -1
- package/types/app/cli/delegate.d.ts.map +0 -1
- package/types/app/cli/did.d.ts.map +0 -1
- package/types/app/cli/ends.d.ts.map +0 -1
- package/types/app/cli/exchange.d.ts.map +0 -1
- package/types/app/cli/export.d.ts.map +0 -1
- package/types/app/cli/incept.d.ts.map +0 -1
- package/types/app/cli/index.d.ts +0 -37
- package/types/app/cli/index.d.ts.map +0 -1
- package/types/app/cli/init.d.ts.map +0 -1
- package/types/app/cli/interact.d.ts.map +0 -1
- package/types/app/cli/ipex.d.ts +0 -20
- package/types/app/cli/ipex.d.ts.map +0 -1
- package/types/app/cli/list.d.ts.map +0 -1
- package/types/app/cli/loc.d.ts.map +0 -1
- package/types/app/cli/multisig.d.ts +0 -12
- package/types/app/cli/multisig.d.ts.map +0 -1
- package/types/app/cli/notifications.d.ts.map +0 -1
- package/types/app/cli/oobi.d.ts.map +0 -1
- package/types/app/cli/output.d.ts.map +0 -1
- package/types/app/cli/query.d.ts +0 -12
- package/types/app/cli/query.d.ts.map +0 -1
- package/types/app/cli/rotate.d.ts.map +0 -1
- package/types/app/cli/saidify.d.ts.map +0 -1
- package/types/app/cli/sign.d.ts.map +0 -1
- package/types/app/cli/vc.d.ts +0 -20
- package/types/app/cli/vc.d.ts.map +0 -1
- package/types/app/cli/verifier.d.ts +0 -3
- package/types/app/cli/verifier.d.ts.map +0 -1
- package/types/app/cli/verify.d.ts.map +0 -1
- package/types/app/configing.d.ts.map +0 -1
- package/types/app/credential-workflows.d.ts +0 -113
- package/types/app/credential-workflows.d.ts.map +0 -1
- package/types/app/cue-runtime.d.ts +0 -12
- package/types/app/cue-runtime.d.ts.map +0 -1
- package/types/app/delegating.d.ts.map +0 -1
- package/types/app/endpoint-roleing.d.ts.map +0 -1
- package/types/app/essr.d.ts +0 -58
- package/types/app/essr.d.ts.map +0 -1
- package/types/app/exchanging.d.ts +0 -233
- package/types/app/exchanging.d.ts.map +0 -1
- package/types/app/forwarding.d.ts +0 -352
- package/types/app/forwarding.d.ts.map +0 -1
- package/types/app/group-members.d.ts +0 -12
- package/types/app/group-members.d.ts.map +0 -1
- package/types/app/grouping.d.ts.map +0 -1
- package/types/app/habbing.d.ts.map +0 -1
- package/types/app/httping.d.ts +0 -49
- package/types/app/httping.d.ts.map +0 -1
- package/types/app/ipex-credentialing.d.ts.map +0 -1
- package/types/app/ipex-graph.d.ts +0 -49
- package/types/app/ipex-graph.d.ts.map +0 -1
- package/types/app/ipex-grouping.d.ts +0 -43
- package/types/app/ipex-grouping.d.ts.map +0 -1
- package/types/app/ipex-node-authentication.d.ts.map +0 -1
- package/types/app/ipex-v2.d.ts +0 -46
- package/types/app/ipex-v2.d.ts.map +0 -1
- package/types/app/ipexing.d.ts.map +0 -1
- package/types/app/keeping.d.ts.map +0 -1
- package/types/app/mailbox-director.d.ts +0 -140
- package/types/app/mailbox-director.d.ts.map +0 -1
- package/types/app/mailbox-sse.d.ts +0 -32
- package/types/app/mailbox-sse.d.ts.map +0 -1
- package/types/app/mailboxing.d.ts.map +0 -1
- package/types/app/multisig-workflows.d.ts +0 -47
- package/types/app/multisig-workflows.d.ts.map +0 -1
- package/types/app/notifying.d.ts.map +0 -1
- package/types/app/oobi-replies.d.ts.map +0 -1
- package/types/app/oobiery.d.ts.map +0 -1
- package/types/app/organizing.d.ts.map +0 -1
- package/types/app/parsering.d.ts.map +0 -1
- package/types/app/protocol-host-policy.d.ts.map +0 -1
- package/types/app/query-replies.d.ts +0 -40
- package/types/app/query-replies.d.ts.map +0 -1
- package/types/app/querying.d.ts +0 -221
- package/types/app/querying.d.ts.map +0 -1
- package/types/app/reactor.d.ts +0 -138
- package/types/app/reactor.d.ts.map +0 -1
- package/types/app/reply-streams.d.ts +0 -20
- package/types/app/reply-streams.d.ts.map +0 -1
- package/types/app/respondant.d.ts +0 -63
- package/types/app/respondant.d.ts.map +0 -1
- package/types/app/runtime-services.d.ts +0 -26
- package/types/app/runtime-services.d.ts.map +0 -1
- package/types/app/runtime-turn.d.ts.map +0 -1
- package/types/app/schema-resolving.d.ts.map +0 -1
- package/types/app/signaling.d.ts.map +0 -1
- package/types/app/socket-source.d.ts.map +0 -1
- package/types/app/stored-replies.d.ts.map +0 -1
- package/types/app/tcp-conversation.d.ts +0 -27
- package/types/app/tcp-conversation.d.ts.map +0 -1
- package/types/app/tcp-egress.d.ts +0 -49
- package/types/app/tcp-egress.d.ts.map +0 -1
- package/types/app/verifier-agent.d.ts +0 -92
- package/types/app/verifier-agent.d.ts.map +0 -1
- package/types/app/verifying.d.ts.map +0 -1
- package/types/app/version.d.ts.map +0 -1
- package/types/app/witnessing.d.ts +0 -223
- package/types/app/witnessing.d.ts.map +0 -1
- package/types/core/eventing.d.ts.map +0 -1
- package/types/core/exchange-proofing.d.ts.map +0 -1
- package/types/core/index.d.ts +0 -24
- package/types/core/index.d.ts.map +0 -1
- package/types/core/kever-decisions.d.ts.map +0 -1
- package/types/core/kever.d.ts.map +0 -1
- package/types/core/kram-auth.d.ts.map +0 -1
- package/types/core/kram-policy.d.ts.map +0 -1
- package/types/core/kram-pruning.d.ts.map +0 -1
- package/types/core/kram-signatures.d.ts.map +0 -1
- package/types/core/kram-staging.d.ts.map +0 -1
- package/types/core/kram-time.d.ts.map +0 -1
- package/types/core/kraming.d.ts.map +0 -1
- package/types/core/mailbox-topics.d.ts.map +0 -1
- package/types/core/protocol-exchanging.d.ts.map +0 -1
- package/types/core/witnesses.d.ts.map +0 -1
- package/types/db/exchange-nests.d.ts +0 -15
- package/types/db/exchange-nests.d.ts.map +0 -1
- package/types/db/exchange-records.d.ts +0 -33
- package/types/db/exchange-records.d.ts.map +0 -1
- package/types/db/kel-replay.d.ts.map +0 -1
- package/types/db/kram-factors.d.ts.map +0 -1
- package/types/db/mailboxing.d.ts.map +0 -1
- package/types/db/payload-archive.d.ts +0 -70
- package/types/db/payload-archive.d.ts.map +0 -1
- package/types/db/payload-store.d.ts +0 -40
- package/types/db/payload-store.d.ts.map +0 -1
- package/types/db/payload-view.d.ts +0 -4
- package/types/db/payload-view.d.ts.map +0 -1
- package/types/db/tel-replay.d.ts.map +0 -1
- package/types/db/verifier-cueing.d.ts +0 -46
- package/types/db/verifier-cueing.d.ts.map +0 -1
- package/types/db/witness-replay.d.ts.map +0 -1
- package/types/vdr/credential-tsn.d.ts +0 -23
- package/types/vdr/credential-tsn.d.ts.map +0 -1
- package/types/vdr/registry-tsn.d.ts +0 -28
- package/types/vdr/registry-tsn.d.ts.map +0 -1
- /package/esm/keri/npm/src/app/{schema-resolving.js → credentials/schema-resolving.js} +0 -0
- /package/esm/keri/npm/src/app/{challenging.js → identity/challenging.js} +0 -0
- /package/esm/keri/npm/src/app/{protocol-host-policy.js → protocol/protocol-host-policy.js} +0 -0
- /package/esm/keri/npm/src/app/{runtime-turn.js → runtime/runtime-turn.js} +0 -0
- /package/esm/keri/npm/src/{app/cli → cli}/common/rendering.js +0 -0
- /package/esm/keri/npm/src/{app/cli → cli/tools}/annotate-color.js +0 -0
- /package/esm/keri/npm/src/core/{witnesses.js → kel/witnesses.js} +0 -0
- /package/esm/keri/npm/src/core/{kram-auth.js → mailbox/kram-auth.js} +0 -0
- /package/esm/keri/npm/src/core/{mailbox-topics.js → mailbox/mailbox-topics.js} +0 -0
- /package/types/app/{signaling.d.ts → notifications/signaling.d.ts} +0 -0
- /package/types/app/{runtime-turn.d.ts → runtime/runtime-turn.d.ts} +0 -0
- /package/types/{app/cli → cli}/common/rendering.d.ts +0 -0
- /package/types/{app/cli → cli/endpoints}/loc.d.ts +0 -0
- /package/types/{app/cli → cli/identity}/aid.d.ts +0 -0
- /package/types/{app/cli → cli/identity}/delegate.d.ts +0 -0
- /package/types/{app/cli → cli/identity}/export.d.ts +0 -0
- /package/types/{app/cli → cli/identity}/list.d.ts +0 -0
- /package/types/{app/cli → cli/messaging}/notifications.d.ts +0 -0
- /package/types/{app/cli → cli}/output.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/annotate-color.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/annotate.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/benchmark.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/db-dump.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/saidify.d.ts +0 -0
- /package/types/{app/cli → cli/tools}/verify.d.ts +0 -0
- /package/types/core/{witnesses.d.ts → kel/witnesses.d.ts} +0 -0
- /package/types/core/{mailbox-topics.d.ts → mailbox/mailbox-topics.d.ts} +0 -0
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
import { b, bytesEqual, Cigar, Counter, Dater, DeserializeError, Diger, essrChunks, framePayload, NumberPrimitive, Prefixer, Saider, Seqner, ShortageError, UnknownCodeError, } from "cesr-ts";
|
|
2
|
+
import { call } from "effection";
|
|
3
|
+
import { resolveAttachmentGvrsn } from "../../core/attachment-countering.js";
|
|
4
|
+
import { Deck } from "../../core/deck.js";
|
|
5
|
+
import { PathedMaterialGroup, TransIdxSigGroup } from "../../core/dispatch.js";
|
|
6
|
+
import { ValidationError } from "../../core/errors.js";
|
|
7
|
+
import { verifyExchangeProofs, } from "../../core/exchange/exchange-proofing.js";
|
|
8
|
+
import { nestedIpexRoute, supportsNestedExchange } from "../../core/exchange/protocol-exchanging.js";
|
|
9
|
+
import { Kever } from "../../core/kel/kever.js";
|
|
10
|
+
import { consoleLogger } from "../../core/logger.js";
|
|
11
|
+
import { messageAttachmentGroups, serializeMessage } from "../../core/protocol-serialization.js";
|
|
12
|
+
import { hasNests, loadNests, prepareNests, publishNests } from "../../db/exchange/exchange-nests.js";
|
|
13
|
+
import { encodeDateTimeToDater, makeNowIso8601, timestampMicros } from "../../time/mod.js";
|
|
14
|
+
import { groupMemberHasKey } from "../multisig/group-members.js";
|
|
15
|
+
import { abortable } from "../runtime/abortable.js";
|
|
16
|
+
const textDecoder = new TextDecoder();
|
|
17
|
+
const EXCHANGE_ESCROW_TIMEOUT_MS = 10_000;
|
|
18
|
+
/** CESR syntax failures identify malformed evidence; I/O, limits, and hashing failures do not. */
|
|
19
|
+
function malformedEssr(error) {
|
|
20
|
+
return error instanceof DeserializeError || error instanceof ShortageError || error instanceof UnknownCodeError;
|
|
21
|
+
}
|
|
22
|
+
/** Private persisted receipt corruption is an invariant failure, never a remote refusal. */
|
|
23
|
+
function storedReceiverTime(record) {
|
|
24
|
+
const time = record?.receiverTime;
|
|
25
|
+
if (time !== undefined && timestampMicros(time) === null)
|
|
26
|
+
throw new Error("Corrupt exchange receiver receipt");
|
|
27
|
+
return time;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Refuse every exchange on one route so nothing about it is persisted.
|
|
31
|
+
*
|
|
32
|
+
* Ports KERIpy `exchanging.RouteRefuser`. A role that must never accept a
|
|
33
|
+
* route (a service or verifier offered `/registry/root`) registers this
|
|
34
|
+
* instead of leaving the route unhandled: an unhandled route is still
|
|
35
|
+
* authenticated, stored in `exns`/`essrs` and never revisited, while `verify`
|
|
36
|
+
* returning false here makes the Exchanger reject it before any write. It is
|
|
37
|
+
* unversioned, so it refuses every protocol major of the route. Sender
|
|
38
|
+
* authentication and its partial-signature escrow still run first, as for any
|
|
39
|
+
* route.
|
|
40
|
+
*/
|
|
41
|
+
export class RouteRefuser {
|
|
42
|
+
constructor(resource) {
|
|
43
|
+
Object.defineProperty(this, "resource", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true,
|
|
47
|
+
value: void 0
|
|
48
|
+
});
|
|
49
|
+
this.resource = resource;
|
|
50
|
+
}
|
|
51
|
+
/** Log the refusal and reject the exchange. */
|
|
52
|
+
verify(args) {
|
|
53
|
+
consoleLogger.info("Exchange route refused by local policy", {
|
|
54
|
+
route: this.resource,
|
|
55
|
+
said: args.serder.said,
|
|
56
|
+
sender: args.serder.pre,
|
|
57
|
+
});
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/** Unreachable: a refused exchange is never dispatched. */
|
|
61
|
+
handle() { }
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Peer-to-peer XIP/EXN processor for one `Habery`.
|
|
65
|
+
*
|
|
66
|
+
* Responsibilities:
|
|
67
|
+
* - verify exchange-message signatures against accepted sender state
|
|
68
|
+
* - persist accepted exchange artifacts in the dedicated exchange stores
|
|
69
|
+
* - escrow partially verifiable exchange traffic in `epse.` / `epsd.`
|
|
70
|
+
* - dispatch accepted messages to route-specific handlers such as challenge
|
|
71
|
+
*
|
|
72
|
+
* TypeScript design rule:
|
|
73
|
+
* - use typed `accept` / `escrow` / `reject` outcomes instead of KERIpy's
|
|
74
|
+
* exception-only control flow for ordinary branch results
|
|
75
|
+
*
|
|
76
|
+
* Admission prepares actual nested evidence before entering a synchronous LMDB
|
|
77
|
+
* writer, then re-reads retry state and authenticates/persists against that current
|
|
78
|
+
* view. Accepted and pending EXNs share ordinary Baser evidence tables, including
|
|
79
|
+
* main's `essrs.` Texter set. There is no external payload authority to publish
|
|
80
|
+
* or reclaim. Join the LMDB flush before exposing cues or invoking asynchronous
|
|
81
|
+
* handlers; a handler failure does not roll back an already accepted EXN.
|
|
82
|
+
*/
|
|
83
|
+
export class Exchanger {
|
|
84
|
+
/** Bind route handlers, cues and the escrow clock to one habitat database. */
|
|
85
|
+
constructor(hby, { handlers = [], cues, now = Date.now } = {}) {
|
|
86
|
+
Object.defineProperty(this, "hby", {
|
|
87
|
+
enumerable: true,
|
|
88
|
+
configurable: true,
|
|
89
|
+
writable: true,
|
|
90
|
+
value: void 0
|
|
91
|
+
});
|
|
92
|
+
Object.defineProperty(this, "cues", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
configurable: true,
|
|
95
|
+
writable: true,
|
|
96
|
+
value: void 0
|
|
97
|
+
});
|
|
98
|
+
Object.defineProperty(this, "routes", {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
configurable: true,
|
|
101
|
+
writable: true,
|
|
102
|
+
value: new Map()
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(this, "versionedRoutes", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
value: new Map()
|
|
109
|
+
});
|
|
110
|
+
/** Borrow the runtime clock for escrow deadlines and retries. */
|
|
111
|
+
Object.defineProperty(this, "now", {
|
|
112
|
+
enumerable: true,
|
|
113
|
+
configurable: true,
|
|
114
|
+
writable: true,
|
|
115
|
+
value: void 0
|
|
116
|
+
});
|
|
117
|
+
this.now = now;
|
|
118
|
+
this.hby = hby;
|
|
119
|
+
this.cues = cues ?? new Deck();
|
|
120
|
+
for (const handler of handlers) {
|
|
121
|
+
this.addHandler(handler);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Register one route handler for accepted exchange messages. */
|
|
125
|
+
addHandler(handler) {
|
|
126
|
+
if (handler.protocolMajor !== undefined) {
|
|
127
|
+
if (!Number.isSafeInteger(handler.protocolMajor) || handler.protocolMajor < 1) {
|
|
128
|
+
throw new ValidationError("Exchange protocol major must be a positive integer.");
|
|
129
|
+
}
|
|
130
|
+
const versions = this.versionedRoutes.get(handler.resource) ?? new Map();
|
|
131
|
+
if (versions.has(handler.protocolMajor)) {
|
|
132
|
+
throw new ValidationError(`Exchange route ${handler.resource} v${handler.protocolMajor} is already registered.`);
|
|
133
|
+
}
|
|
134
|
+
versions.set(handler.protocolMajor, handler);
|
|
135
|
+
this.versionedRoutes.set(handler.resource, versions);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (this.routes.has(handler.resource)) {
|
|
139
|
+
throw new ValidationError(`Exchange route ${handler.resource} is already registered.`);
|
|
140
|
+
}
|
|
141
|
+
this.routes.set(handler.resource, handler);
|
|
142
|
+
}
|
|
143
|
+
/** Resolve the configured body-version route owner without dispatching or changing evidence. */
|
|
144
|
+
handlerFor(serder) {
|
|
145
|
+
const route = serder.route ?? "";
|
|
146
|
+
return this.versionedRoutes.get(route)?.get(serder.pvrsn.major) ?? this.routes.get(route);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Verify, persist, and dispatch one inbound `exn`.
|
|
150
|
+
*
|
|
151
|
+
* Accepted messages are durably logged before any route-specific side
|
|
152
|
+
* effects run so later reopen and verification paths can reuse the same
|
|
153
|
+
* stored evidence.
|
|
154
|
+
* Returning a reject/escrow decision describes this attempt, not necessarily
|
|
155
|
+
* the absence of an earlier accepted copy; complete(said) checks durable
|
|
156
|
+
* acceptance. Infrastructure and handler errors remain exceptions, so callers
|
|
157
|
+
* must not interpret every thrown error as a remote protocol rejection.
|
|
158
|
+
*/
|
|
159
|
+
processEvent(args) {
|
|
160
|
+
return call(function* () {
|
|
161
|
+
const attempt = yield* this.admit(args);
|
|
162
|
+
if (!attempt)
|
|
163
|
+
throw new Error("A direct exchange input cannot become an obsolete escrow retry");
|
|
164
|
+
return attempt.decision;
|
|
165
|
+
}.bind(this));
|
|
166
|
+
}
|
|
167
|
+
/** Complete only a still-live pending Grant with added proof; serialization cannot extend its original lifetime. */
|
|
168
|
+
acceptPendingGrantProof(args) {
|
|
169
|
+
return call(function* () {
|
|
170
|
+
const attempt = yield* this.admit(args, false, "proof");
|
|
171
|
+
if (!attempt)
|
|
172
|
+
throw new Error("A selected pending Grant proof cannot become an obsolete escrow retry");
|
|
173
|
+
return attempt.decision;
|
|
174
|
+
}.bind(this));
|
|
175
|
+
}
|
|
176
|
+
/** Add authentication to a live prepared Grant without replacing its exact disclosure or renewing its deadline. */
|
|
177
|
+
acceptPreparedGrantContribution(args) {
|
|
178
|
+
return call(function* () {
|
|
179
|
+
const attempt = yield* this.admit(args, false, "contribution");
|
|
180
|
+
if (!attempt)
|
|
181
|
+
throw new Error("A selected prepared Grant contribution cannot become an obsolete escrow retry");
|
|
182
|
+
return attempt.decision;
|
|
183
|
+
}.bind(this));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Prepare nested serialization outside the writer, then decide and persist in
|
|
187
|
+
* one uninterrupted transaction. A retry re-reads current escrow evidence in
|
|
188
|
+
* that writer: work may have accepted/expired while preparation suspended.
|
|
189
|
+
* Flush committed storage before publishing cues and awaiting the route handler.
|
|
190
|
+
* The caller must keep the Baser open through all these completion boundaries.
|
|
191
|
+
*/
|
|
192
|
+
*admit(args, retry = false, selectedGrant) {
|
|
193
|
+
const said = args.serder.said ?? "<unknown>";
|
|
194
|
+
const reject = (reason) => ({ decision: { kind: "reject", said, reason }, cues: [] });
|
|
195
|
+
if (this.hby.db.inWriteTransaction)
|
|
196
|
+
throw new Error("Exchanger must own the admission transaction");
|
|
197
|
+
if (args.serder.ilk !== "exn" && args.serder.ilk !== "xip") {
|
|
198
|
+
return reject(`Unsupported exchange ilk ${args.serder.ilk}.`);
|
|
199
|
+
}
|
|
200
|
+
if (!args.serder.pre || !args.serder.said)
|
|
201
|
+
return reject("Exchange message is missing sender or SAID.");
|
|
202
|
+
if (args.receiverTime !== undefined && timestampMicros(args.receiverTime) === null) {
|
|
203
|
+
throw new Error("Invalid exchange receiver time");
|
|
204
|
+
}
|
|
205
|
+
const route = args.serder.route ?? "";
|
|
206
|
+
const handler = this.handlerFor(args.serder);
|
|
207
|
+
// Freeze implied last-establishment coordinates at receipt, not after child serialization.
|
|
208
|
+
const resolved = this.resolveProofs(args);
|
|
209
|
+
const nests = args.nests?.length
|
|
210
|
+
? yield* abortable((signal) => prepareNests(args.nests, signal))
|
|
211
|
+
: undefined;
|
|
212
|
+
const result = this.hby.db.env.transactionSync(() => {
|
|
213
|
+
if (selectedGrant) {
|
|
214
|
+
const db = this.hby.db;
|
|
215
|
+
const stored = selectedGrant === "proof" ? db.epse.get([said]) : db.exns.get([said]) ?? db.epse.get([said]);
|
|
216
|
+
const deadline = stored && this.exchangeDeadline(stored);
|
|
217
|
+
const expiry = deadline ? timestampMicros(deadline) : null;
|
|
218
|
+
const live = stored && this.isV2Grant(stored) && !db.erpy.get([said])
|
|
219
|
+
&& expiry !== null && this.nowMicros() < expiry;
|
|
220
|
+
const original = !live ? null : selectedGrant === "proof"
|
|
221
|
+
? this.retainedInput(said, { pending: true })
|
|
222
|
+
: { serder: stored, nests: loadNests(db, said) };
|
|
223
|
+
const before = original?.nests ?? [], after = args.nests ?? [];
|
|
224
|
+
if (!original || !bytesEqual(original.serder.raw, args.serder.raw) || before.length !== after.length
|
|
225
|
+
|| before.some((node, index) => !bytesEqual(node.body.raw, after[index].body.raw)))
|
|
226
|
+
return reject("Selected pending Grant proof is expired, terminated or changes the original disclosure");
|
|
227
|
+
if (selectedGrant === "contribution") {
|
|
228
|
+
const retained = db.enst.get([said]);
|
|
229
|
+
if (retained.length !== nests?.length || retained.some((raw, index) => !bytesEqual(b(raw), nests[index]))) {
|
|
230
|
+
return reject("Prepared Grant contribution changes the original nested evidence");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
let status;
|
|
235
|
+
if (retry) {
|
|
236
|
+
status = this.escrowStatus(said);
|
|
237
|
+
if (status.kind === "accepted") {
|
|
238
|
+
this.clearPending(args.serder);
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
if (status.kind === "absent")
|
|
242
|
+
return undefined;
|
|
243
|
+
if (status.kind !== "pending") {
|
|
244
|
+
return {
|
|
245
|
+
...reject(status.kind),
|
|
246
|
+
ejection: this.retireCurrent(args.serder, this.expiryReport(status)),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const current = retry ? this.escrowInput(args.serder) : args;
|
|
251
|
+
const failure = this.verifyEssr(current.serder, current.essrs);
|
|
252
|
+
const admission = failure
|
|
253
|
+
? { decision: failure, cues: [] }
|
|
254
|
+
: this.admitCurrent(current, retry ? this.resolveProofs(current) : resolved, handler, {
|
|
255
|
+
attachments: normalizeAttachments(current.ptds ?? []),
|
|
256
|
+
nests,
|
|
257
|
+
}, selectedGrant === "contribution");
|
|
258
|
+
if (status?.kind === "pending" && admission.decision.kind === "reject" && !admission.decision.preserveEscrow) {
|
|
259
|
+
return {
|
|
260
|
+
...admission,
|
|
261
|
+
ejection: this.retireCurrent(args.serder, {
|
|
262
|
+
family: status.family,
|
|
263
|
+
reason: admission.decision.reason,
|
|
264
|
+
cause: admission.decision.cause,
|
|
265
|
+
}),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
return admission;
|
|
269
|
+
});
|
|
270
|
+
// Durable completion joins the actual LMDB flush; no external file lifetime remains.
|
|
271
|
+
yield* abortable(async () => {
|
|
272
|
+
await this.hby.db.env.flushed;
|
|
273
|
+
});
|
|
274
|
+
if (!result)
|
|
275
|
+
return undefined;
|
|
276
|
+
for (const cue of result.cues)
|
|
277
|
+
this.cues.push(cue);
|
|
278
|
+
if (result.handling && handler)
|
|
279
|
+
yield* call(() => handler.handle(result.handling));
|
|
280
|
+
return { decision: result.decision, ejection: result.ejection };
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check the signed commitment over this attempt's raw fragment concatenation
|
|
284
|
+
* before persistence. On retry these inputs come from retained set members.
|
|
285
|
+
* Match main's separation: valid incoming bytes need not remain reconstructable
|
|
286
|
+
* after equal Texters deduplicate or alternate fragmentations accumulate.
|
|
287
|
+
* Do not normalize parser input or weaken digest verification to conceal that
|
|
288
|
+
* known persistence limitation. Malformed remote CESR yields reject; storage,
|
|
289
|
+
* hashing and other infrastructure errors propagate.
|
|
290
|
+
*/
|
|
291
|
+
verifyEssr(serder, fragments) {
|
|
292
|
+
if (typeof serder.a !== "string")
|
|
293
|
+
return undefined;
|
|
294
|
+
const said = serder.said;
|
|
295
|
+
try {
|
|
296
|
+
const diger = new Diger({ qb64: serder.a });
|
|
297
|
+
if (!fragments || !diger.verifyChunks(fragments.map((texter) => texter.raw))) {
|
|
298
|
+
return { kind: "reject", said, reason: "Exchange ESSR payload digest does not match its signed commitment." };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch (cause) {
|
|
302
|
+
if (!malformedEssr(cause))
|
|
303
|
+
throw cause;
|
|
304
|
+
return {
|
|
305
|
+
kind: "reject",
|
|
306
|
+
said,
|
|
307
|
+
reason: `Invalid exchange ESSR payload: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
308
|
+
cause,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/** Authenticate, validate route policy and write evidence in one uninterrupted owner turn. */
|
|
313
|
+
admitCurrent(args, resolved, handler, prepared, preparedContribution = false) {
|
|
314
|
+
const said = args.serder.said;
|
|
315
|
+
const authentication = this.authenticate(args.serder, resolved, handler, this.cues);
|
|
316
|
+
const cues = [];
|
|
317
|
+
if (authentication.kind === "reject")
|
|
318
|
+
return { decision: authentication, cues };
|
|
319
|
+
let pending = authentication.kind === "escrow"
|
|
320
|
+
? { kind: authentication.kind, said, reason: authentication.reason }
|
|
321
|
+
: undefined;
|
|
322
|
+
const senderQuery = authentication.kind === "escrow" ? authentication.query : undefined;
|
|
323
|
+
const approved = authentication.kind === "verified" ? authentication : undefined;
|
|
324
|
+
const previous = this.hby.db.exchangeMeta.get([said]);
|
|
325
|
+
const receiverTime = storedReceiverTime(previous) ?? args.receiverTime;
|
|
326
|
+
const mailboxAid = args.mailboxAid ?? previous?.mailboxAid ?? null;
|
|
327
|
+
const nests = args.nests?.length ? args.nests : loadNests(this.hby.db, said);
|
|
328
|
+
if (nests.length
|
|
329
|
+
&& (!handler?.acceptsNests || !supportsNestedExchange(args.serder.route ?? "", args.serder.pvrsn.major))) {
|
|
330
|
+
return { decision: { kind: "reject", said, reason: "Nested exchange route is not implemented." }, cues };
|
|
331
|
+
}
|
|
332
|
+
let registryStates = [];
|
|
333
|
+
let missingSchema;
|
|
334
|
+
let needsProof = false;
|
|
335
|
+
const handling = {
|
|
336
|
+
serder: args.serder,
|
|
337
|
+
attachments: prepared.attachments,
|
|
338
|
+
essrs: args.essrs,
|
|
339
|
+
nests,
|
|
340
|
+
mailboxAid,
|
|
341
|
+
receiverTime,
|
|
342
|
+
...(handler?.acceptsSscs && approved?.sscs.length ? { sscs: approved.sscs } : {}),
|
|
343
|
+
};
|
|
344
|
+
if (approved && handler?.verify) {
|
|
345
|
+
const verified = handler.verify({
|
|
346
|
+
...handling,
|
|
347
|
+
...(handler.acceptsEvidence ? { evidence: approved.supplemental } : {}),
|
|
348
|
+
});
|
|
349
|
+
if (verified === false) {
|
|
350
|
+
return {
|
|
351
|
+
decision: {
|
|
352
|
+
kind: "reject",
|
|
353
|
+
said,
|
|
354
|
+
reason: `Exchange route ${args.serder.route ?? ""} failed handler verification.`,
|
|
355
|
+
},
|
|
356
|
+
cues,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if (typeof verified === "object" && verified.kind === "accept")
|
|
360
|
+
registryStates = verified.registryStates;
|
|
361
|
+
if (typeof verified === "object" && verified.kind === "escrow") {
|
|
362
|
+
pending = { ...verified, said };
|
|
363
|
+
missingSchema = verified.schema;
|
|
364
|
+
if (missingSchema !== undefined && new Diger({ qb64: missingSchema }).qb64 !== missingSchema) {
|
|
365
|
+
throw new ValidationError("Route missing-schema dependency must be a complete SAID.");
|
|
366
|
+
}
|
|
367
|
+
needsProof = missingSchema === undefined;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if (pending && this.complete(said)) {
|
|
371
|
+
// The exact prepared-file writer may retain verified added consent while
|
|
372
|
+
// current issuer openings remain unresolved; accepted proof rows stay untouched.
|
|
373
|
+
if (preparedContribution && approved) {
|
|
374
|
+
this.logAcceptedEvent({
|
|
375
|
+
serder: args.serder,
|
|
376
|
+
...approved.retained,
|
|
377
|
+
supplemental: approved.supplemental,
|
|
378
|
+
ptds: args.ptds ?? [],
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return { decision: pending, cues };
|
|
382
|
+
}
|
|
383
|
+
const retainedIpex = args.serder.pvrsn.major === 2 && nestedIpexRoute(args.serder.route ?? "")
|
|
384
|
+
&& this.complete(said);
|
|
385
|
+
if (prepared.nests && !retainedIpex)
|
|
386
|
+
publishNests(this.hby.db, said, prepared.nests);
|
|
387
|
+
let newEscrow = false;
|
|
388
|
+
if (!pending && approved) {
|
|
389
|
+
this.clearEscrow(args.serder, true);
|
|
390
|
+
for (const [node, record] of registryStates)
|
|
391
|
+
this.hby.db.exrs.pin([said, node], record);
|
|
392
|
+
this.logAcceptedEvent({
|
|
393
|
+
serder: args.serder,
|
|
394
|
+
...approved.retained,
|
|
395
|
+
supplemental: approved.supplemental,
|
|
396
|
+
ptds: args.ptds ?? [],
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
const factors = approved?.retained ?? resolved;
|
|
401
|
+
newEscrow = missingSchema === undefined
|
|
402
|
+
? this.escrowPartialSigned(args.serder, factors, args.ptds ?? [])
|
|
403
|
+
: this.escrowMissingSchema(args.serder, missingSchema, factors, args.ptds ?? []);
|
|
404
|
+
}
|
|
405
|
+
// False means an existing qualified member, not a failed write. Exceptions abort the writer.
|
|
406
|
+
for (const texter of args.essrs ?? [])
|
|
407
|
+
this.hby.db.essrs.add([said], texter);
|
|
408
|
+
this.hby.db.exchangeMeta.pin([said], {
|
|
409
|
+
mailboxAid,
|
|
410
|
+
...(receiverTime !== undefined ? { receiverTime } : {}),
|
|
411
|
+
gvrsn: previous?.gvrsn ?? args.gvrsn ?? args.serder.gvrsn ?? args.serder.pvrsn,
|
|
412
|
+
});
|
|
413
|
+
if (pending) {
|
|
414
|
+
if (newEscrow) {
|
|
415
|
+
if (senderQuery)
|
|
416
|
+
cues.push(...this.missingStateCues([senderQuery]));
|
|
417
|
+
if (needsProof)
|
|
418
|
+
cues.push({ kin: "proof", said });
|
|
419
|
+
if (missingSchema)
|
|
420
|
+
cues.push({ kin: "query", q: { r: "schema", said: missingSchema } });
|
|
421
|
+
}
|
|
422
|
+
return { decision: pending, cues };
|
|
423
|
+
}
|
|
424
|
+
return { decision: { kind: "accept", said }, cues, handling };
|
|
425
|
+
}
|
|
426
|
+
/** Retry escrows using ordinary LMDB evidence and retained mailbox provenance. */
|
|
427
|
+
processEscrows() {
|
|
428
|
+
return call(() => this.retryEscrows());
|
|
429
|
+
}
|
|
430
|
+
/** Retry each bounded escrow inside one structured child scope, then each opted-in route handler's own escrow. */
|
|
431
|
+
*retryEscrows() {
|
|
432
|
+
if (this.hby.db.inWriteTransaction)
|
|
433
|
+
throw new Error("Exchanger must own escrow transactions");
|
|
434
|
+
yield* this.retryEscrowType(false);
|
|
435
|
+
if (this.hby.db.emse)
|
|
436
|
+
yield* this.retryEscrowType(true);
|
|
437
|
+
const versioned = [...this.versionedRoutes.values()].flatMap(versions => [...versions.values()]);
|
|
438
|
+
for (const handler of new Set([...this.routes.values(), ...versioned]))
|
|
439
|
+
handler.processEscrows?.();
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Close each cursor before replay; newly discovered dependencies wait for the next finite pass.
|
|
443
|
+
* Terminal diagnostics follow joined evidence cleanup, while acceptance and dependency migration stay silent.
|
|
444
|
+
*
|
|
445
|
+
* @param schema Select missing-schema escrow instead of partial-signature/proof escrow.
|
|
446
|
+
*/
|
|
447
|
+
*retryEscrowType(schema) {
|
|
448
|
+
const table = schema ? this.hby.db.emse : this.hby.db.epse;
|
|
449
|
+
let end;
|
|
450
|
+
// Capture a finite key horizon without retaining bodies or holding a cursor across mutations.
|
|
451
|
+
for (const key of table.sdb.getKeys({ reverse: true, limit: 1 })) {
|
|
452
|
+
end = b(`${textDecoder.decode(key)}\0`);
|
|
453
|
+
}
|
|
454
|
+
if (!end) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
let start;
|
|
458
|
+
for (;;) {
|
|
459
|
+
let physical;
|
|
460
|
+
for (const key of table.sdb.getKeys({ start, end, limit: 1 })) {
|
|
461
|
+
physical = textDecoder.decode(key);
|
|
462
|
+
}
|
|
463
|
+
if (!physical)
|
|
464
|
+
break;
|
|
465
|
+
const keys = physical.split("."), said = keys[0];
|
|
466
|
+
// Skip every schema branch for this EXN, including dependencies inserted by the replay below.
|
|
467
|
+
start = b(schema ? `${said}/` : `${physical}\0`);
|
|
468
|
+
const serder = table.get(keys);
|
|
469
|
+
if (!serder || (serder.ilk !== "exn" && serder.ilk !== "xip") || !serder.pre || serder.said !== said
|
|
470
|
+
|| keys.length !== (schema ? 2 : 1)) {
|
|
471
|
+
throw new Error("Corrupt exchange escrow key or body.");
|
|
472
|
+
}
|
|
473
|
+
if (schema && new Diger({ qb64: keys[1] }).qb64 !== keys[1])
|
|
474
|
+
throw new Error("Corrupt schema escrow dependency.");
|
|
475
|
+
const expired = yield* call(() => this.expirePending(serder));
|
|
476
|
+
if (expired) {
|
|
477
|
+
consoleLogger.warn("Exchanger ejected exchange escrow", {
|
|
478
|
+
said,
|
|
479
|
+
pre: serder.pre,
|
|
480
|
+
route: serder.route,
|
|
481
|
+
...expired,
|
|
482
|
+
});
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
const attempt = yield* call(() => this.admit(this.escrowInput(serder), true));
|
|
486
|
+
if (attempt?.ejection) {
|
|
487
|
+
consoleLogger.warn("Exchanger ejected exchange escrow", {
|
|
488
|
+
said,
|
|
489
|
+
pre: serder.pre,
|
|
490
|
+
route: serder.route,
|
|
491
|
+
...attempt.ejection,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Reconstruct accepted signed wire from ordinary Baser evidence, preserving
|
|
498
|
+
* attachment genus independently of the signed body's protocol version.
|
|
499
|
+
* Revalidate stored sender proofs, then encode retained pathed/nested/ESSR
|
|
500
|
+
* material. ESSR set members follow stored order, which can differ from the
|
|
501
|
+
* originally committed sequence under the documented set limitation; receiving
|
|
502
|
+
* protocol/recipient processing remains responsible for its digest check.
|
|
503
|
+
*
|
|
504
|
+
* @param said Accepted outer EXN SAID; escrow-only evidence cannot be replayed here.
|
|
505
|
+
* @param signal Optional caller cancellation between reconstruction/output steps.
|
|
506
|
+
* @yields Ordinary owned wire chunks; no archive handle or plaintext is created.
|
|
507
|
+
* @throws Missing acceptance, invalid retained authentication and genuine
|
|
508
|
+
* storage/encoding failures remain visible to the consumer.
|
|
509
|
+
*/
|
|
510
|
+
async *replay(said, signal) {
|
|
511
|
+
signal?.throwIfAborted();
|
|
512
|
+
const serder = this.hby.db.exns.get([said]);
|
|
513
|
+
if (!serder)
|
|
514
|
+
throw new ValidationError("Cannot replay an unaccepted exchange.");
|
|
515
|
+
const args = this.retainedInput(said);
|
|
516
|
+
if (!args)
|
|
517
|
+
throw new ValidationError("Invalid stored exchange authentication or evidence.");
|
|
518
|
+
const essrs = args.essrs;
|
|
519
|
+
signal?.throwIfAborted();
|
|
520
|
+
const gvrsn = resolveAttachmentGvrsn(serder, this.hby.db.exchangeMeta.get([said])?.gvrsn);
|
|
521
|
+
// epath retains complete groups; serialization supplies the destination
|
|
522
|
+
// genus's counter and therefore consumes only the path-and-proof payload.
|
|
523
|
+
const evidence = {
|
|
524
|
+
tsgs: args.tsgs,
|
|
525
|
+
cigars: args.cigars,
|
|
526
|
+
sourceSeals: args.sourceSeals,
|
|
527
|
+
pathed: (args.ptds ?? []).map((group) => group.raw.slice(new Counter({ qb64b: group.raw, version: gvrsn }).fullSize)),
|
|
528
|
+
};
|
|
529
|
+
const nested = hasNests(this.hby.db, said);
|
|
530
|
+
{
|
|
531
|
+
const groups = nested ? messageAttachmentGroups(evidence, gvrsn) : [];
|
|
532
|
+
const nests = nested ? [...args.nests ?? []] : [];
|
|
533
|
+
if (nests.length) {
|
|
534
|
+
// Reuse the stored Serder and hydrated endorsements; the shared encoder builds real leaf groups.
|
|
535
|
+
const parent = {
|
|
536
|
+
body: serder,
|
|
537
|
+
attachments: groups,
|
|
538
|
+
gvrsn,
|
|
539
|
+
nests,
|
|
540
|
+
essrs: essrs ? [...essrs] : undefined,
|
|
541
|
+
};
|
|
542
|
+
yield* framePayload(parent).open(signal);
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
signal?.throwIfAborted();
|
|
546
|
+
yield serializeMessage(serder, { ...evidence, gvrsn, genusify: gvrsn.major >= 2 });
|
|
547
|
+
if (essrs) {
|
|
548
|
+
for (const chunk of essrChunks(essrs, { gvrsn })) {
|
|
549
|
+
signal?.throwIfAborted();
|
|
550
|
+
yield chunk;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/** Return true once the named exchange SAID is durably stored as accepted. */
|
|
557
|
+
complete(said) {
|
|
558
|
+
return this.hby.db.exns.get([said])?.said === said;
|
|
559
|
+
}
|
|
560
|
+
/** Original accepted KRAM lifetime; partial-escrow timestamps never authorize live auxiliary work. */
|
|
561
|
+
exchangeDeadline(serder) {
|
|
562
|
+
const said = serder.said, sender = serder.pre;
|
|
563
|
+
const xid = serder.ilk === "xip" ? said : serder.sad?.x;
|
|
564
|
+
if (!said || !sender || typeof xid !== "string" || !xid)
|
|
565
|
+
return null;
|
|
566
|
+
const cache = this.hby.db.tmsc.get([sender, xid, said]);
|
|
567
|
+
if (!cache?.rdt)
|
|
568
|
+
return null;
|
|
569
|
+
const opener = timestampMicros(cache.xdt);
|
|
570
|
+
if (timestampMicros(cache.rdt) === null || opener === null || !Number.isSafeInteger(cache.xl) || cache.xl < 0) {
|
|
571
|
+
throw new Error("Corrupt accepted exchange transaction lifetime.");
|
|
572
|
+
}
|
|
573
|
+
return this.deadlineDater(opener + BigInt(cache.xl) * 1000n).dts;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Rehydrate authenticated retained factors without route handling or writes.
|
|
577
|
+
* Pending-only access also enforces the original deadline with this owner's
|
|
578
|
+
* clock and refuses terminal responses. It does not require fresh RIP state:
|
|
579
|
+
* an approved issuance may need these exact factors after its BUP arrives.
|
|
580
|
+
*/
|
|
581
|
+
retainedInput(said, { pending = false } = {}) {
|
|
582
|
+
const db = this.hby.db;
|
|
583
|
+
const serder = pending ? db.epse.get([said]) : db.exns.get([said]) ?? db.epse.get([said]);
|
|
584
|
+
if (!serder || serder.said !== said || !serder.verify())
|
|
585
|
+
return null;
|
|
586
|
+
if (pending) {
|
|
587
|
+
const deadline = this.exchangeDeadline(serder);
|
|
588
|
+
if (!deadline || this.complete(said) || db.erpy.get([said]))
|
|
589
|
+
return null;
|
|
590
|
+
const expiry = timestampMicros(deadline);
|
|
591
|
+
if (expiry === null)
|
|
592
|
+
throw new Error("Corrupt accepted exchange deadline.");
|
|
593
|
+
if (this.nowMicros() >= expiry)
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
const args = this.escrowInput(serder);
|
|
597
|
+
const verified = verifyExchangeProofs(db, serder, args);
|
|
598
|
+
if (verified.invalid || verified.missing.length || !(verified.tsgs.some((group) => group.pre === serder.pre)
|
|
599
|
+
|| verified.cigars.some((cigar) => cigar.verfer?.qb64 === serder.pre)
|
|
600
|
+
|| verified.sourceSeals.some((seal) => seal.i.qb64 === serder.pre)))
|
|
601
|
+
return null;
|
|
602
|
+
return {
|
|
603
|
+
...args,
|
|
604
|
+
tsgs: verified.tsgs,
|
|
605
|
+
cigars: verified.cigars,
|
|
606
|
+
sourceSeals: verified.sourceSeals,
|
|
607
|
+
nests: loadNests(db, said),
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Reauthenticate one accepted body and its exact retained view through its
|
|
612
|
+
* registered route. No queries, writes, handling or notices occur. Historical
|
|
613
|
+
* mode proves retained issuer prefixes, not current standing, graph policy or
|
|
614
|
+
* consent; the default continues to require current issuer history.
|
|
615
|
+
*/
|
|
616
|
+
verifyAccepted(said, route, { historical = false } = {}) {
|
|
617
|
+
const serder = this.hby.db.exns.get([said]);
|
|
618
|
+
if (!serder || serder.route !== route || !serder.verify())
|
|
619
|
+
return false;
|
|
620
|
+
const handler = this.handlerFor(serder);
|
|
621
|
+
if (!handler?.verify)
|
|
622
|
+
return false;
|
|
623
|
+
const args = this.escrowInput(serder);
|
|
624
|
+
if (this.verifyEssr(serder, args.essrs))
|
|
625
|
+
return false;
|
|
626
|
+
const approved = this.authenticate(serder, this.resolveProofs(args), handler, new Deck());
|
|
627
|
+
if (approved.kind !== "verified")
|
|
628
|
+
return false;
|
|
629
|
+
const meta = this.hby.db.exchangeMeta.get([said]);
|
|
630
|
+
const verified = handler.verify({
|
|
631
|
+
serder,
|
|
632
|
+
attachments: normalizeAttachments(args.ptds ?? []),
|
|
633
|
+
essrs: args.essrs,
|
|
634
|
+
nests: loadNests(this.hby.db, said),
|
|
635
|
+
mailboxAid: meta?.mailboxAid,
|
|
636
|
+
receiverTime: storedReceiverTime(meta),
|
|
637
|
+
historical,
|
|
638
|
+
...(handler.acceptsSscs ? { sscs: approved.sscs } : {}),
|
|
639
|
+
...(handler.acceptsEvidence ? { evidence: approved.supplemental } : {}),
|
|
640
|
+
});
|
|
641
|
+
return verified === true || (typeof verified === "object" && verified.kind === "accept");
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Reverify replacement proofs for one live accepted Grant through its ordinary
|
|
645
|
+
* route. Bodies and order stay exact; this returns current observations without
|
|
646
|
+
* writes, handling or new consent. The Unblind owner publishes inside its own
|
|
647
|
+
* synchronous transaction after comparing the retained evidence snapshot.
|
|
648
|
+
*/
|
|
649
|
+
verifyGrantProofs(said, nests) {
|
|
650
|
+
const serder = this.hby.db.exns.get([said]);
|
|
651
|
+
if (!serder || !this.isV2Grant(serder))
|
|
652
|
+
return false;
|
|
653
|
+
const xid = serder.ilk === "xip" ? said : serder.sad.x, recipient = serder.sad.ri;
|
|
654
|
+
if (typeof xid !== "string" || typeof recipient !== "string" || !serder.pre)
|
|
655
|
+
return false;
|
|
656
|
+
const context = this.presentationContext(said, { xid, sender: serder.pre, recipient });
|
|
657
|
+
if (!context || nests.length !== context.nests.length
|
|
658
|
+
|| nests.some((nest, index) => !bytesEqual(nest.body.raw, context.nests[index].body.raw)))
|
|
659
|
+
return false;
|
|
660
|
+
const handler = this.handlerFor(serder);
|
|
661
|
+
if (!handler?.verify)
|
|
662
|
+
return false;
|
|
663
|
+
const args = this.escrowInput(serder);
|
|
664
|
+
const approved = this.authenticate(serder, this.resolveProofs(args), handler, new Deck());
|
|
665
|
+
if (approved.kind !== "verified")
|
|
666
|
+
return false;
|
|
667
|
+
const meta = this.hby.db.exchangeMeta.get([said]);
|
|
668
|
+
return handler.verify({
|
|
669
|
+
serder,
|
|
670
|
+
attachments: normalizeAttachments(args.ptds ?? []),
|
|
671
|
+
essrs: args.essrs,
|
|
672
|
+
nests,
|
|
673
|
+
mailboxAid: meta?.mailboxAid,
|
|
674
|
+
receiverTime: storedReceiverTime(meta),
|
|
675
|
+
...(handler.acceptsSscs ? { sscs: approved.sscs } : {}),
|
|
676
|
+
...(handler.acceptsEvidence ? { evidence: approved.supplemental } : {}),
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Read one selected live pending issuance Grant and its exact registry scope.
|
|
681
|
+
* Escrow presence grants no authority: reauthenticate retained sender factors,
|
|
682
|
+
* then reuse the v2 route's context checks. This changes no stores or cues
|
|
683
|
+
* and never accepts the Grant. Auxiliary authority expires at deadline equality.
|
|
684
|
+
*/
|
|
685
|
+
pendingGrant(said, { xid, sender, recipient }) {
|
|
686
|
+
const serder = this.hby.db.epse.get([said]);
|
|
687
|
+
const deadline = serder && this.exchangeDeadline(serder);
|
|
688
|
+
if (!serder || !deadline || serder.said !== said || !serder.verify() || !this.isV2Grant(serder)
|
|
689
|
+
|| serder.pre !== sender || serder.sad.ri !== recipient
|
|
690
|
+
|| (serder.ilk === "xip" ? said : serder.sad.x) !== xid
|
|
691
|
+
|| this.complete(said) || this.hby.db.erpy.get([said]))
|
|
692
|
+
return null;
|
|
693
|
+
const expiry = timestampMicros(deadline);
|
|
694
|
+
if (expiry === null)
|
|
695
|
+
throw new Error("Corrupt accepted exchange deadline.");
|
|
696
|
+
if (this.nowMicros() >= expiry)
|
|
697
|
+
return null;
|
|
698
|
+
const handler = this.handlerFor(serder);
|
|
699
|
+
if (handler?.protocolMajor !== 2 || !handler.pendingGrant)
|
|
700
|
+
return null;
|
|
701
|
+
const args = this.escrowInput(serder);
|
|
702
|
+
if (this.verifyEssr(serder, args.essrs))
|
|
703
|
+
return null;
|
|
704
|
+
const approved = this.authenticate(serder, this.resolveProofs(args), handler, new Deck());
|
|
705
|
+
if (approved.kind !== "verified")
|
|
706
|
+
return null;
|
|
707
|
+
const meta = this.hby.db.exchangeMeta.get([said]);
|
|
708
|
+
const registries = handler.pendingGrant({
|
|
709
|
+
serder,
|
|
710
|
+
attachments: normalizeAttachments(args.ptds ?? []),
|
|
711
|
+
essrs: args.essrs,
|
|
712
|
+
nests: loadNests(this.hby.db, said),
|
|
713
|
+
mailboxAid: meta?.mailboxAid,
|
|
714
|
+
receiverTime: storedReceiverTime(meta),
|
|
715
|
+
...(handler.acceptsSscs ? { sscs: approved.sscs } : {}),
|
|
716
|
+
...(handler.acceptsEvidence ? { evidence: approved.supplemental } : {}),
|
|
717
|
+
});
|
|
718
|
+
return registries?.length ? { serder, registries } : null;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Reauthenticate a live accepted or pending Grant and its exact retained disclosure.
|
|
722
|
+
* Scope is per registry, not permission to use every disclosed node or Admit.
|
|
723
|
+
* The original deadline and terminal response bound authority; inspection never
|
|
724
|
+
* writes, renews lifetime, emits cues or hydrates a fuller credential view.
|
|
725
|
+
*/
|
|
726
|
+
presentationContext(said, { xid, sender, recipient }) {
|
|
727
|
+
const serder = this.hby.db.exns.get([said]) ?? this.hby.db.epse.get([said]);
|
|
728
|
+
const deadline = serder && this.exchangeDeadline(serder);
|
|
729
|
+
if (!serder || !deadline || serder.said !== said || !serder.verify() || !this.isV2Grant(serder)
|
|
730
|
+
|| serder.pre !== sender || serder.sad.ri !== recipient
|
|
731
|
+
|| (serder.ilk === "xip" ? said : serder.sad.x) !== xid
|
|
732
|
+
|| this.hby.db.erpy.get([said]))
|
|
733
|
+
return null;
|
|
734
|
+
const expiry = timestampMicros(deadline);
|
|
735
|
+
if (expiry === null)
|
|
736
|
+
throw new Error("Corrupt accepted exchange deadline.");
|
|
737
|
+
if (this.nowMicros() >= expiry)
|
|
738
|
+
return null;
|
|
739
|
+
const handler = this.handlerFor(serder);
|
|
740
|
+
if (handler?.protocolMajor !== 2 || !handler.presentationContext)
|
|
741
|
+
return null;
|
|
742
|
+
const args = this.escrowInput(serder);
|
|
743
|
+
if (this.verifyEssr(serder, args.essrs))
|
|
744
|
+
return null;
|
|
745
|
+
const approved = this.authenticate(serder, this.resolveProofs(args), handler, new Deck());
|
|
746
|
+
if (approved.kind !== "verified")
|
|
747
|
+
return null;
|
|
748
|
+
const meta = this.hby.db.exchangeMeta.get([said]);
|
|
749
|
+
const nests = loadNests(this.hby.db, said);
|
|
750
|
+
const registries = handler.presentationContext({
|
|
751
|
+
serder,
|
|
752
|
+
attachments: normalizeAttachments(args.ptds ?? []),
|
|
753
|
+
essrs: args.essrs,
|
|
754
|
+
nests,
|
|
755
|
+
mailboxAid: meta?.mailboxAid,
|
|
756
|
+
receiverTime: storedReceiverTime(meta),
|
|
757
|
+
...(handler.acceptsSscs ? { sscs: approved.sscs } : {}),
|
|
758
|
+
...(handler.acceptsEvidence ? { evidence: approved.supplemental } : {}),
|
|
759
|
+
});
|
|
760
|
+
return registries?.size ? { serder, nests, registries } : null;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Elect the lowest verified index in the first authenticated sender proof group.
|
|
764
|
+
*
|
|
765
|
+
* Like KERIpy, choose one stored establishment group deterministically. Require
|
|
766
|
+
* an accepted exchange, or explicitly opt into a live pending presentation,
|
|
767
|
+
* before reverifying sender proofs against accepted historical establishment state.
|
|
768
|
+
* Resolve the winning key at that proof's accepted establishment, not the current
|
|
769
|
+
* group state. The local member's accepted KEL identifies its historical keys;
|
|
770
|
+
* rotating that member must not transfer or erase an existing approval's lead.
|
|
771
|
+
* Partial signatures elect no sender. Election alone does not authorize sending
|
|
772
|
+
* the selected disclosure; callers still approve its complete registry scope.
|
|
773
|
+
*/
|
|
774
|
+
lead(hab, said, { pendingPresentation = false } = {}) {
|
|
775
|
+
const record = this.hby.db.getHab(hab.pre);
|
|
776
|
+
if (!record?.mid)
|
|
777
|
+
return true;
|
|
778
|
+
const db = this.hby.db;
|
|
779
|
+
let serder = db.exns.get([said]);
|
|
780
|
+
if (!serder && pendingPresentation) {
|
|
781
|
+
const candidate = db.epse.get([said]);
|
|
782
|
+
if (candidate?.pre === hab.pre && typeof candidate.sad?.ri === "string") {
|
|
783
|
+
const xid = candidate.ilk === "xip" ? candidate.said : candidate.sad.x;
|
|
784
|
+
if (typeof xid === "string" && this.presentationContext(said, {
|
|
785
|
+
xid,
|
|
786
|
+
sender: candidate.pre,
|
|
787
|
+
recipient: candidate.sad.ri,
|
|
788
|
+
}))
|
|
789
|
+
serder = candidate;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (!serder || serder.pre !== hab.pre)
|
|
793
|
+
return false;
|
|
794
|
+
const verified = verifyExchangeProofs(db, serder, {
|
|
795
|
+
tsgs: this.rebuildEscrowedGroups(said).filter(group => group.pre === hab.pre),
|
|
796
|
+
});
|
|
797
|
+
const proof = verified.tsgs[0];
|
|
798
|
+
if (!proof)
|
|
799
|
+
return false;
|
|
800
|
+
let index = Infinity;
|
|
801
|
+
for (const siger of proof.sigers)
|
|
802
|
+
index = Math.min(index, siger.index);
|
|
803
|
+
const establishment = db.getEvtSerder(hab.pre, proof.said);
|
|
804
|
+
const leadKey = establishment?.verfers[index]?.qb64;
|
|
805
|
+
if (!leadKey)
|
|
806
|
+
return false;
|
|
807
|
+
return groupMemberHasKey(db, record.mid, leadKey);
|
|
808
|
+
}
|
|
809
|
+
/** Freeze last-establishment groups and expand sender-implied seals before durable admission. */
|
|
810
|
+
resolveProofs(args) {
|
|
811
|
+
const result = {
|
|
812
|
+
tsgs: [...(args.tsgs ?? [])],
|
|
813
|
+
cigars: [...(args.cigars ?? [])],
|
|
814
|
+
sourceSeals: [
|
|
815
|
+
...(args.sscs ?? []).map((seal) => ({ ...seal, i: new Prefixer({ qb64: args.serder.pre }) })),
|
|
816
|
+
...(args.sourceSeals ?? []),
|
|
817
|
+
],
|
|
818
|
+
missing: (args.unresolvedLast ?? []).map((prefix) => ({ pre: prefix.qb64, sn: null })),
|
|
819
|
+
};
|
|
820
|
+
for (const group of args.lsgs ?? []) {
|
|
821
|
+
const kever = this.hby.db.getKever(group.pre);
|
|
822
|
+
if (!kever) {
|
|
823
|
+
result.missing.push({ pre: group.pre, sn: null });
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
result.tsgs.push(new TransIdxSigGroup(group.prefixer, NumberPrimitive.fromNum(BigInt(kever.lastEst.s)), new Diger({ qb64: kever.lastEst.d }), group.sigers));
|
|
827
|
+
}
|
|
828
|
+
return result;
|
|
829
|
+
}
|
|
830
|
+
/** Match sender-factor precedence; the caller supplies live admission or isolated inspection cues. */
|
|
831
|
+
authenticate(serder, resolved, handler, queries) {
|
|
832
|
+
const said = serder.said;
|
|
833
|
+
const sender = serder.pre;
|
|
834
|
+
const senderTsgs = aggregateTransIdxSigGroups(resolved.tsgs.filter((group) => group.pre === sender));
|
|
835
|
+
const extraTsgs = aggregateTransIdxSigGroups(resolved.tsgs.filter((group) => group.pre !== sender));
|
|
836
|
+
const cigars = senderTsgs.length && !handler?.verifyEvidence ? [] : resolved.cigars;
|
|
837
|
+
const senderCigars = cigars.filter((cigar) => cigar.verfer?.qb64 === sender);
|
|
838
|
+
const extraCigars = cigars.filter((cigar) => cigar.verfer?.qb64 !== sender);
|
|
839
|
+
for (const cue of this.missingStateCues(resolved.missing))
|
|
840
|
+
queries.push(cue);
|
|
841
|
+
if (resolved.missing.length && (!handler?.acceptsMissingEvidence || resolved.missing.some((m) => m.pre === sender))) {
|
|
842
|
+
// An unresolved last-establishment reference has no historical coordinate to persist.
|
|
843
|
+
// Sender intake recovery belongs to the consolidated processMsg/KRAM boundary.
|
|
844
|
+
return {
|
|
845
|
+
kind: "reject",
|
|
846
|
+
said,
|
|
847
|
+
preserveEscrow: true,
|
|
848
|
+
reason: "Unresolved last-establishment evidence requires key state and retransmission.",
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
const sealed = verifyExchangeProofs(this.hby.db, serder, {
|
|
852
|
+
sourceSeals: resolved.sourceSeals.filter((seal) => seal.i.qb64 === sender),
|
|
853
|
+
});
|
|
854
|
+
if (sealed.missing.length) {
|
|
855
|
+
for (const cue of this.missingStateCues(sealed.missing))
|
|
856
|
+
queries.push(cue);
|
|
857
|
+
return {
|
|
858
|
+
kind: handler?.acceptsSscs ? "escrow" : "reject",
|
|
859
|
+
...(!handler?.acceptsSscs ? { preserveEscrow: true } : {}),
|
|
860
|
+
said,
|
|
861
|
+
reason: "Missing sender source-seal KEL evidence.",
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
let tsgs;
|
|
865
|
+
let validCigars;
|
|
866
|
+
if (sealed.sourceSeals.length) {
|
|
867
|
+
// A valid sender seal wins; invalid optional sender signatures cannot undo its authentication.
|
|
868
|
+
tsgs = verifyExchangeProofs(this.hby.db, serder, { tsgs: senderTsgs }).tsgs;
|
|
869
|
+
validCigars = [];
|
|
870
|
+
}
|
|
871
|
+
else {
|
|
872
|
+
if (!handler?.verifyEvidence && !senderTsgs.length && !senderCigars.length
|
|
873
|
+
&& (extraTsgs.length || extraCigars.length)) {
|
|
874
|
+
return {
|
|
875
|
+
kind: "reject",
|
|
876
|
+
said,
|
|
877
|
+
preserveEscrow: true,
|
|
878
|
+
reason: "Exchange has foreign proofs without sender authentication.",
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
const signatures = this.verifySignatures({ serder, sender, tsgs: senderTsgs, cigars: senderCigars });
|
|
882
|
+
if (signatures.kind !== "verified") {
|
|
883
|
+
return signatures;
|
|
884
|
+
}
|
|
885
|
+
tsgs = signatures.tsgs;
|
|
886
|
+
validCigars = signatures.cigars;
|
|
887
|
+
}
|
|
888
|
+
if (!handler?.verifyEvidence && (extraTsgs.length || extraCigars.length)) {
|
|
889
|
+
return {
|
|
890
|
+
kind: "reject",
|
|
891
|
+
said,
|
|
892
|
+
preserveEscrow: true,
|
|
893
|
+
reason: "Exchange route does not accept supplemental endorsements.",
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
let supplemental = { tsgs: [], cigars: [], sourceSeals: [] };
|
|
897
|
+
if (handler?.verifyEvidence) {
|
|
898
|
+
const { invalid, missing, ...factors } = verifyExchangeProofs(this.hby.db, serder, {
|
|
899
|
+
tsgs: extraTsgs,
|
|
900
|
+
cigars: extraCigars,
|
|
901
|
+
sourceSeals: resolved.sourceSeals.filter((seal) => seal.i.qb64 !== sender),
|
|
902
|
+
});
|
|
903
|
+
// Each reference helper invocation deduplicates its own coordinate list. Do not
|
|
904
|
+
// re-query unresolved last groups when passing them on to the selection hook.
|
|
905
|
+
for (const cue of this.missingStateCues(missing))
|
|
906
|
+
queries.push(cue);
|
|
907
|
+
if (missing.length && !handler.acceptsMissingEvidence) {
|
|
908
|
+
return { kind: "reject", said, preserveEscrow: true, reason: "Missing supplemental proof key state." };
|
|
909
|
+
}
|
|
910
|
+
const selection = handler.verifyEvidence({
|
|
911
|
+
serder,
|
|
912
|
+
factors,
|
|
913
|
+
invalid,
|
|
914
|
+
...(handler.acceptsMissingEvidence ? { missing: [...resolved.missing, ...missing] } : {}),
|
|
915
|
+
});
|
|
916
|
+
const selected = selection;
|
|
917
|
+
if (!selected)
|
|
918
|
+
return { kind: "reject", said, reason: "Route rejected supplemental exchange proofs." };
|
|
919
|
+
supplemental = {
|
|
920
|
+
tsgs: selected.tsgs ?? [],
|
|
921
|
+
cigars: selected.cigars ?? [],
|
|
922
|
+
sourceSeals: selected.sourceSeals ?? [],
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
return {
|
|
926
|
+
kind: "verified",
|
|
927
|
+
supplemental,
|
|
928
|
+
sscs: sealed.sourceSeals.map(({ s, d }) => ({ s, d })),
|
|
929
|
+
retained: {
|
|
930
|
+
tsgs: [...tsgs, ...supplemental.tsgs],
|
|
931
|
+
cigars: [...validCigars, ...supplemental.cigars],
|
|
932
|
+
sourceSeals: [...sealed.sourceSeals, ...supplemental.sourceSeals],
|
|
933
|
+
},
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
/** Match _cueMissingKeyState's coordinate deduplication within this invocation. */
|
|
937
|
+
missingStateCues(missing) {
|
|
938
|
+
const cues = [];
|
|
939
|
+
const seen = new Set();
|
|
940
|
+
for (const { pre, sn } of missing) {
|
|
941
|
+
const key = `${pre}:${sn ?? ""}`;
|
|
942
|
+
if (seen.has(key)) {
|
|
943
|
+
continue;
|
|
944
|
+
}
|
|
945
|
+
seen.add(key);
|
|
946
|
+
cues.push({
|
|
947
|
+
kin: "query",
|
|
948
|
+
pre,
|
|
949
|
+
route: "logs",
|
|
950
|
+
q: sn === null ? {} : { s: sn.toString(16) },
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
return cues;
|
|
954
|
+
}
|
|
955
|
+
/** Reattach the persisted verifier to each nontransferable signature before replay or retry. */
|
|
956
|
+
storedCigars(said) {
|
|
957
|
+
return this.hby.db.ecigs.get([said]).map(([verfer, cigar]) => new Cigar(cigar, verfer));
|
|
958
|
+
}
|
|
959
|
+
/** Restore source triples without losing the anchoring AID or its historical ordinal. */
|
|
960
|
+
storedSeals(said) {
|
|
961
|
+
const seals = [];
|
|
962
|
+
for (const [keys, [s, d]] of this.hby.db.ests.getTopItemIter([said, ""])) {
|
|
963
|
+
seals.push({ i: new Prefixer({ qb64: keys[1] }), s, d });
|
|
964
|
+
}
|
|
965
|
+
return seals;
|
|
966
|
+
}
|
|
967
|
+
/** Classify sender endorsements without publishing exchange evidence. */
|
|
968
|
+
verifySignatures(args) {
|
|
969
|
+
if (args.tsgs.length > 0) {
|
|
970
|
+
const verifiedGroups = [];
|
|
971
|
+
const grouped = args.tsgs;
|
|
972
|
+
for (const tsg of grouped) {
|
|
973
|
+
if (tsg.pre !== args.sender) {
|
|
974
|
+
return {
|
|
975
|
+
kind: "reject",
|
|
976
|
+
reason: `Exchange signer ${tsg.pre} does not match sender ${args.sender}.`,
|
|
977
|
+
said: args.serder.said ?? "<unknown>",
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
if (tsg.sn > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
981
|
+
return { kind: "reject", reason: "Sender ordinal exceeds runtime range.", said: args.serder.said };
|
|
982
|
+
}
|
|
983
|
+
const estSaid = this.hby.db.kels.getLast(tsg.pre, Number(tsg.sn));
|
|
984
|
+
const estEvent = estSaid ? this.hby.db.getEvtSerder(tsg.pre, estSaid) : null;
|
|
985
|
+
if (!estSaid || !estEvent) {
|
|
986
|
+
return {
|
|
987
|
+
kind: "escrow",
|
|
988
|
+
query: { pre: tsg.pre, sn: tsg.sn },
|
|
989
|
+
reason: `Missing accepted establishment state for ${tsg.pre}:${tsg.said}.`,
|
|
990
|
+
said: args.serder.said ?? "<unknown>",
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
if (estSaid !== tsg.said || !estEvent.estive || !tsg.prefixer.transferable) {
|
|
994
|
+
return { kind: "reject", reason: "Invalid sender establishment reference.", said: args.serder.said };
|
|
995
|
+
}
|
|
996
|
+
const tholder = estEvent.tholder;
|
|
997
|
+
if (!tholder || estEvent.verfers.length < tholder.size) {
|
|
998
|
+
return {
|
|
999
|
+
kind: "reject",
|
|
1000
|
+
reason: `Invalid threshold material for exchange signer ${tsg.pre}.`,
|
|
1001
|
+
said: args.serder.said ?? "<unknown>",
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
const verified = Kever.verifyIndexedSignatures(args.serder.raw, tsg.sigers, estEvent.verfers);
|
|
1005
|
+
if (!tholder.satisfy(verified.indices)) {
|
|
1006
|
+
return {
|
|
1007
|
+
kind: "escrow",
|
|
1008
|
+
query: { pre: tsg.pre, sn: tsg.sn },
|
|
1009
|
+
reason: `Exchange ${args.serder.said ?? "<unknown>"} does not yet satisfy sender threshold.`,
|
|
1010
|
+
said: args.serder.said ?? "<unknown>",
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
verifiedGroups.push(new TransIdxSigGroup(tsg.prefixer, tsg.seqner, tsg.diger, verified.sigers));
|
|
1014
|
+
}
|
|
1015
|
+
return { kind: "verified", tsgs: verifiedGroups, cigars: [] };
|
|
1016
|
+
}
|
|
1017
|
+
if (args.cigars.length > 0) {
|
|
1018
|
+
const verifiedCigars = [];
|
|
1019
|
+
for (const cigar of args.cigars) {
|
|
1020
|
+
if (!cigar.verfer) {
|
|
1021
|
+
return {
|
|
1022
|
+
kind: "reject",
|
|
1023
|
+
reason: "Exchange cigar is missing verifier context.",
|
|
1024
|
+
said: args.serder.said ?? "<unknown>",
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
if (cigar.verfer.qb64 !== args.sender) {
|
|
1028
|
+
return {
|
|
1029
|
+
kind: "reject",
|
|
1030
|
+
reason: `Exchange cigar signer ${cigar.verfer.qb64} does not match sender ${args.sender}.`,
|
|
1031
|
+
said: args.serder.said ?? "<unknown>",
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
if (cigar.verfer.transferable || !cigar.verfer.verify(cigar.raw, args.serder.raw)) {
|
|
1035
|
+
return {
|
|
1036
|
+
kind: "reject",
|
|
1037
|
+
preserveEscrow: true,
|
|
1038
|
+
reason: `Exchange cigar failed verification for ${args.sender}.`,
|
|
1039
|
+
said: args.serder.said ?? "<unknown>",
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
verifiedCigars.push(cigar);
|
|
1043
|
+
}
|
|
1044
|
+
return { kind: "verified", tsgs: [], cigars: verifiedCigars };
|
|
1045
|
+
}
|
|
1046
|
+
return {
|
|
1047
|
+
kind: "escrow",
|
|
1048
|
+
reason: "Exchange message has no signatures yet.",
|
|
1049
|
+
said: args.serder.said ?? "<unknown>",
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
/** Retain incomplete endorsements and the original expiration clock for retry. */
|
|
1053
|
+
escrowPartialSigned(serder, factors, ptds) {
|
|
1054
|
+
const said = serder.said;
|
|
1055
|
+
if (!said) {
|
|
1056
|
+
throw new ValidationError("Cannot escrow an exchange without a SAID.");
|
|
1057
|
+
}
|
|
1058
|
+
if (this.complete(said)) {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
this.storeEscrowEvidence(serder, factors, ptds);
|
|
1062
|
+
this.hby.db.emse?.trim([said]);
|
|
1063
|
+
this.retainPartialDeadline(serder);
|
|
1064
|
+
return this.hby.db.epse.put([said], serder);
|
|
1065
|
+
}
|
|
1066
|
+
/** Persist the same independently authenticated evidence for signature and schema dependencies. */
|
|
1067
|
+
storeEscrowEvidence(serder, factors, ptds) {
|
|
1068
|
+
const said = serder.said;
|
|
1069
|
+
for (const tsg of factors.tsgs) {
|
|
1070
|
+
const quadKey = [said, tsg.pre, tsg.sn.toString(16).padStart(32, "0"), tsg.said];
|
|
1071
|
+
for (const siger of tsg.sigers) {
|
|
1072
|
+
this.hby.db.esigs.add(quadKey, siger);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
for (const cigar of factors.cigars) {
|
|
1076
|
+
if (cigar.verfer) {
|
|
1077
|
+
this.hby.db.ecigs.add([said], [cigar.verfer, cigar]);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
for (const seal of factors.sourceSeals)
|
|
1081
|
+
this.hby.db.ests.add([said, seal.i.qb64], [seal.s, seal.d]);
|
|
1082
|
+
this.hby.db.epath.pin([said], ptds.map((group) => textDecoder.decode(group.raw)));
|
|
1083
|
+
}
|
|
1084
|
+
/** One absolute deadline spans sequential schema dependencies; receiver receipt is not the TMSC opener. */
|
|
1085
|
+
escrowMissingSchema(serder, schema, factors, ptds) {
|
|
1086
|
+
const { emse, emsd } = this.hby.db, said = serder.said;
|
|
1087
|
+
if (!emse || !emsd)
|
|
1088
|
+
throw new ValidationError("Missing-schema storage is unavailable on this readonly layout.");
|
|
1089
|
+
if (this.complete(said)) {
|
|
1090
|
+
return false;
|
|
1091
|
+
}
|
|
1092
|
+
const prior = emsd.get([said]);
|
|
1093
|
+
if (prior && timestampMicros(prior.dts) === null)
|
|
1094
|
+
throw new Error("Corrupt missing-schema deadline.");
|
|
1095
|
+
if (!prior) {
|
|
1096
|
+
const xid = serder.ilk === "xip" ? said : serder.sad.x;
|
|
1097
|
+
const cache = typeof xid === "string" && xid ? this.hby.db.tmsc.get([serder.pre, xid, said]) : null;
|
|
1098
|
+
const opener = cache && timestampMicros(cache.xdt);
|
|
1099
|
+
if (cache && (opener === null || opener === undefined || !Number.isSafeInteger(cache.pxl) || cache.pxl < 0)) {
|
|
1100
|
+
throw new Error("Corrupt missing-schema transaction lifetime.");
|
|
1101
|
+
}
|
|
1102
|
+
const expiry = cache ? opener + BigInt(cache.pxl) * 1000n : this.nowMicros() + 20000000n;
|
|
1103
|
+
emsd.put([said], this.deadlineDater(expiry));
|
|
1104
|
+
}
|
|
1105
|
+
this.storeEscrowEvidence(serder, factors, ptds);
|
|
1106
|
+
this.hby.db.epse.rem([said]);
|
|
1107
|
+
this.hby.db.epsd.rem([said]);
|
|
1108
|
+
const stored = emse.get([said, schema]) === null;
|
|
1109
|
+
emse.trim([said]);
|
|
1110
|
+
emse.put([said, schema], serder);
|
|
1111
|
+
return stored;
|
|
1112
|
+
}
|
|
1113
|
+
/** V2 Grant validity survives dependency changes and acceptance; it is not cache retention. */
|
|
1114
|
+
isV2Grant(serder) {
|
|
1115
|
+
return serder.pvrsn.major >= 2 && serder.route === "/ipex/grant";
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Bound PSE cleanup by the accepted v2 Grant lifetime (xdt + xl) once KRAM
|
|
1119
|
+
* records sender-threshold receipt; before that, freeze one local PSE timeout
|
|
1120
|
+
* that retransmission never extends. Mirrors KERIpy `_partialSignedDeadline`.
|
|
1121
|
+
*/
|
|
1122
|
+
retainPartialDeadline(serder) {
|
|
1123
|
+
const said = serder.said, prior = this.hby.db.epsd.get([said]);
|
|
1124
|
+
if (prior && timestampMicros(prior.dts) === null)
|
|
1125
|
+
throw new Error("Corrupt exchange partial deadline.");
|
|
1126
|
+
const accepted = this.isV2Grant(serder) ? this.exchangeDeadline(serder) : null;
|
|
1127
|
+
if (accepted) {
|
|
1128
|
+
if (prior?.dts !== accepted)
|
|
1129
|
+
this.hby.db.epsd.pin([said], this.deadlineDater(timestampMicros(accepted)));
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (prior)
|
|
1133
|
+
return;
|
|
1134
|
+
this.hby.db.epsd.put([said], this.deadlineDater(this.nowMicros() + BigInt(EXCHANGE_ESCROW_TIMEOUT_MS) * 1000n));
|
|
1135
|
+
}
|
|
1136
|
+
/** Preserve the original microsecond deadline without truncating its TMSC opener. */
|
|
1137
|
+
deadlineDater(expiry) {
|
|
1138
|
+
const remainder = (expiry % 1000n + 1000n) % 1000n;
|
|
1139
|
+
const text = makeNowIso8601(new Date(Number((expiry - remainder) / 1000n)))
|
|
1140
|
+
.replace(/\d{6}\+/, ((expiry % 1000000n + 1000000n) % 1000000n).toString().padStart(6, "0") + "+");
|
|
1141
|
+
if (timestampMicros(text) !== expiry)
|
|
1142
|
+
throw new Error("Exchange deadline exceeds supported date range.");
|
|
1143
|
+
return new Dater({ qb64: encodeDateTimeToDater(text) });
|
|
1144
|
+
}
|
|
1145
|
+
/** Trusted clock failures remain infrastructure errors rather than expiring remote work. */
|
|
1146
|
+
nowMicros() {
|
|
1147
|
+
const now = new Date(this.now()).getTime();
|
|
1148
|
+
if (!Number.isFinite(now))
|
|
1149
|
+
throw new Error("Invalid exchange receiver clock.");
|
|
1150
|
+
return BigInt(now) * 1000n;
|
|
1151
|
+
}
|
|
1152
|
+
/** Persist protocol evidence inside the admission transaction before route handling. */
|
|
1153
|
+
logAcceptedEvent(args) {
|
|
1154
|
+
const said = args.serder.said;
|
|
1155
|
+
if (!said) {
|
|
1156
|
+
throw new ValidationError("Cannot log an exchange without a SAID.");
|
|
1157
|
+
}
|
|
1158
|
+
for (const tsg of args.tsgs) {
|
|
1159
|
+
const quadKey = [said, tsg.pre, tsg.sn.toString(16).padStart(32, "0"), tsg.said];
|
|
1160
|
+
for (const siger of tsg.sigers) {
|
|
1161
|
+
this.hby.db.esigs.add(quadKey, siger);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
for (const cigar of args.cigars) {
|
|
1165
|
+
if (!cigar.verfer) {
|
|
1166
|
+
throw new ValidationError("Cannot log a cigar without verifier context.");
|
|
1167
|
+
}
|
|
1168
|
+
this.hby.db.ecigs.add([said], [cigar.verfer, cigar]);
|
|
1169
|
+
}
|
|
1170
|
+
const retainedIpex = args.serder.pvrsn.major === 2 && nestedIpexRoute(args.serder.route ?? "")
|
|
1171
|
+
&& this.complete(said);
|
|
1172
|
+
if (!retainedIpex) {
|
|
1173
|
+
this.hby.db.epath.pin([said], args.ptds.map((group) => textDecoder.decode(group.raw)));
|
|
1174
|
+
}
|
|
1175
|
+
for (const seal of args.sourceSeals)
|
|
1176
|
+
this.hby.db.ests.add([said, seal.i.qb64], [seal.s, seal.d]);
|
|
1177
|
+
const endorsers = new Set([
|
|
1178
|
+
...args.supplemental.tsgs.map((group) => group.pre),
|
|
1179
|
+
...args.supplemental.cigars.map((cigar) => cigar.verfer.qb64),
|
|
1180
|
+
...args.supplemental.sourceSeals.map((seal) => seal.i.qb64),
|
|
1181
|
+
]);
|
|
1182
|
+
for (const pre of endorsers)
|
|
1183
|
+
this.hby.db.eidx.add([pre], new Diger({ qb64: said }));
|
|
1184
|
+
const prior = args.serder.ked?.p;
|
|
1185
|
+
if (typeof prior === "string" && prior.length > 0) {
|
|
1186
|
+
this.hby.db.erpy.pin([prior], new Saider({ qb64: said }));
|
|
1187
|
+
}
|
|
1188
|
+
this.hby.db.exns.pin([said], args.serder);
|
|
1189
|
+
}
|
|
1190
|
+
rebuildEscrowedGroups(said) {
|
|
1191
|
+
const groups = [];
|
|
1192
|
+
let currentKey = null;
|
|
1193
|
+
let currentSigers = [];
|
|
1194
|
+
const flush = () => {
|
|
1195
|
+
if (!currentKey || currentSigers.length === 0) {
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
groups.push(new TransIdxSigGroup(new Prefixer({ qb64: currentKey[0] }), seqnerFromSnh(currentKey[1]), new Diger({ qb64: currentKey[2] }), currentSigers));
|
|
1199
|
+
currentSigers = [];
|
|
1200
|
+
};
|
|
1201
|
+
for (const [keys, siger] of this.hby.db.esigs.getTopItemIter([said, ""])) {
|
|
1202
|
+
const groupKey = keys.slice(1);
|
|
1203
|
+
if (!groupKey[0] || !groupKey[1] || !groupKey[2]) {
|
|
1204
|
+
continue;
|
|
1205
|
+
}
|
|
1206
|
+
if (currentKey
|
|
1207
|
+
&& (currentKey[0] !== groupKey[0]
|
|
1208
|
+
|| currentKey[1] !== groupKey[1]
|
|
1209
|
+
|| currentKey[2] !== groupKey[2])) {
|
|
1210
|
+
flush();
|
|
1211
|
+
}
|
|
1212
|
+
currentKey = [groupKey[0], groupKey[1], groupKey[2]];
|
|
1213
|
+
currentSigers.push(siger);
|
|
1214
|
+
}
|
|
1215
|
+
flush();
|
|
1216
|
+
return groups;
|
|
1217
|
+
}
|
|
1218
|
+
/** Clear pending metadata, preserving wire evidence during the acceptance transaction. */
|
|
1219
|
+
clearEscrow(serder, keepEvidence = false) {
|
|
1220
|
+
const said = serder.said;
|
|
1221
|
+
this.clearPending(serder);
|
|
1222
|
+
// First acceptance replaces provisional factors; accepted duplicates accumulate verified proofs.
|
|
1223
|
+
if (!keepEvidence || !this.complete(said)) {
|
|
1224
|
+
this.hby.db.esigs.trim([said, ""], { topive: false });
|
|
1225
|
+
this.hby.db.ecigs.rem([said]);
|
|
1226
|
+
this.hby.db.ests.trim([said, ""], { topive: false });
|
|
1227
|
+
}
|
|
1228
|
+
const accepted = keepEvidence ? this.hby.db.exns.get([said]) : null;
|
|
1229
|
+
const retainedIpex = accepted?.pvrsn.major === 2 && nestedIpexRoute(accepted.route ?? "");
|
|
1230
|
+
if (!retainedIpex)
|
|
1231
|
+
this.hby.db.epath.rem([said]);
|
|
1232
|
+
if (!keepEvidence) {
|
|
1233
|
+
this.hby.db.essrs.rem([said]);
|
|
1234
|
+
this.hby.db.enst.rem([said]);
|
|
1235
|
+
this.hby.db.exchangeMeta.rem([said]);
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
/** Snapshot current escrow proofs; retry re-reads this data again in its final writer. */
|
|
1239
|
+
escrowInput(serder) {
|
|
1240
|
+
const said = serder.said;
|
|
1241
|
+
return {
|
|
1242
|
+
serder,
|
|
1243
|
+
tsgs: this.rebuildEscrowedGroups(said),
|
|
1244
|
+
cigars: this.storedCigars(said),
|
|
1245
|
+
sourceSeals: this.storedSeals(said),
|
|
1246
|
+
ptds: this.hby.db.epath.get([said]).map((text) => PathedMaterialGroup.fromRaw(new TextEncoder().encode(text))),
|
|
1247
|
+
mailboxAid: this.hby.db.exchangeMeta.get([said])?.mailboxAid,
|
|
1248
|
+
essrs: this.hby.db.getEssrs(said) ?? undefined,
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
/** Decide eligibility from current accepted records and both protocol deadline stores. */
|
|
1252
|
+
escrowStatus(said) {
|
|
1253
|
+
if (this.complete(said))
|
|
1254
|
+
return { kind: "accepted" };
|
|
1255
|
+
const partial = this.hby.db.epse.get([said]) !== null;
|
|
1256
|
+
if (!partial && !this.hby.db.hasSchemaEscrow(said))
|
|
1257
|
+
return { kind: "absent" };
|
|
1258
|
+
const family = partial ? "epse" : "emse";
|
|
1259
|
+
const deadline = this.hby.db.emsd?.get([said]);
|
|
1260
|
+
const absolute = deadline && timestampMicros(deadline.dts);
|
|
1261
|
+
if (deadline && absolute === null)
|
|
1262
|
+
throw new Error("Corrupt missing-schema deadline.");
|
|
1263
|
+
const partialDeadline = this.hby.db.epsd.get([said]);
|
|
1264
|
+
const partialExpiry = partialDeadline && timestampMicros(partialDeadline.dts);
|
|
1265
|
+
if (!partial && partialDeadline && partialExpiry === null)
|
|
1266
|
+
throw new Error("Corrupt exchange partial deadline.");
|
|
1267
|
+
const date = partial ? partialExpiry : absolute;
|
|
1268
|
+
if (date === null || date === undefined) {
|
|
1269
|
+
if (!partial)
|
|
1270
|
+
throw new Error("Corrupt missing-schema deadline.");
|
|
1271
|
+
return { kind: "missingTimestamp", family };
|
|
1272
|
+
}
|
|
1273
|
+
const now = this.nowMicros();
|
|
1274
|
+
if (now > date || partialExpiry !== null && partialExpiry !== undefined && now > partialExpiry
|
|
1275
|
+
|| absolute !== null && absolute !== undefined && now > absolute)
|
|
1276
|
+
return { kind: "expired", family };
|
|
1277
|
+
return { kind: "pending", family };
|
|
1278
|
+
}
|
|
1279
|
+
/** Describe only the terminal decision that the owning writer actually commits. */
|
|
1280
|
+
expiryReport(status) {
|
|
1281
|
+
const detail = status.kind === "missingTimestamp"
|
|
1282
|
+
? "Pending exchange has no valid admission timestamp."
|
|
1283
|
+
: "Exchange dependency exceeded its pending lifetime or absolute schema deadline.";
|
|
1284
|
+
return { family: status.family, reason: status.kind, detail };
|
|
1285
|
+
}
|
|
1286
|
+
/** Remove pending LMDB evidence inside its owning writer and return the committed diagnostic. */
|
|
1287
|
+
retireCurrent(serder, ejection) {
|
|
1288
|
+
this.clearEscrow(serder);
|
|
1289
|
+
return ejection;
|
|
1290
|
+
}
|
|
1291
|
+
/** Decide expiry and remove pending rows in the same native transaction. */
|
|
1292
|
+
*expirePending(serder) {
|
|
1293
|
+
const said = serder.said;
|
|
1294
|
+
const result = this.hby.db.env.transactionSync(() => {
|
|
1295
|
+
const status = this.escrowStatus(said);
|
|
1296
|
+
if (status.kind === "accepted") {
|
|
1297
|
+
this.clearPending(serder);
|
|
1298
|
+
return undefined;
|
|
1299
|
+
}
|
|
1300
|
+
if (status.kind === "absent" || status.kind === "pending")
|
|
1301
|
+
return undefined;
|
|
1302
|
+
return this.retireCurrent(serder, this.expiryReport(status));
|
|
1303
|
+
});
|
|
1304
|
+
yield* abortable(async () => {
|
|
1305
|
+
await this.hby.db.env.flushed;
|
|
1306
|
+
});
|
|
1307
|
+
return result;
|
|
1308
|
+
}
|
|
1309
|
+
/** Clear only dependency markers, keeping all accepted evidence and metadata intact. */
|
|
1310
|
+
clearPending(serder) {
|
|
1311
|
+
const said = serder.said;
|
|
1312
|
+
this.hby.db.epse.rem([said]);
|
|
1313
|
+
this.hby.db.epsd.rem([said]);
|
|
1314
|
+
this.hby.db.emse?.trim([said]);
|
|
1315
|
+
this.hby.db.emsd?.rem([said]);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
function normalizeAttachments(ptds) {
|
|
1319
|
+
return ptds.map((group) => ({
|
|
1320
|
+
raw: group.raw.slice(),
|
|
1321
|
+
text: textDecoder.decode(group.raw),
|
|
1322
|
+
}));
|
|
1323
|
+
}
|
|
1324
|
+
function hexToFixedBytes(hex, size) {
|
|
1325
|
+
const normalized = hex.length % 2 === 0 ? hex : `0${hex}`;
|
|
1326
|
+
if (!/^[0-9a-f]+$/i.test(normalized)) {
|
|
1327
|
+
throw new Error(`Invalid hex ordinal ${hex}`);
|
|
1328
|
+
}
|
|
1329
|
+
if (normalized.length > size * 2) {
|
|
1330
|
+
throw new Error(`Hex ordinal ${hex} exceeds ${size} bytes.`);
|
|
1331
|
+
}
|
|
1332
|
+
const raw = new Uint8Array(size);
|
|
1333
|
+
const padded = normalized.padStart(size * 2, "0");
|
|
1334
|
+
for (let i = 0; i < size; i++) {
|
|
1335
|
+
raw[i] = Number.parseInt(padded.slice(i * 2, (i * 2) + 2), 16);
|
|
1336
|
+
}
|
|
1337
|
+
return raw;
|
|
1338
|
+
}
|
|
1339
|
+
function seqnerFromSnh(snh) {
|
|
1340
|
+
return new Seqner({ code: "0A", raw: hexToFixedBytes(snh, 16) });
|
|
1341
|
+
}
|
|
1342
|
+
function aggregateTransIdxSigGroups(groups) {
|
|
1343
|
+
const aggregated = new Map();
|
|
1344
|
+
for (const group of groups) {
|
|
1345
|
+
const key = `${group.pre}\0${group.sn}\0${group.said}`;
|
|
1346
|
+
const existing = aggregated.get(key);
|
|
1347
|
+
if (!existing) {
|
|
1348
|
+
aggregated.set(key, group);
|
|
1349
|
+
continue;
|
|
1350
|
+
}
|
|
1351
|
+
aggregated.set(key, new TransIdxSigGroup(existing.prefixer, existing.seqner, existing.diger, [...existing.sigers, ...group.sigers]));
|
|
1352
|
+
}
|
|
1353
|
+
return [...aggregated.values()];
|
|
1354
|
+
}
|