keri-ts 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/esm/keri/npm/src/acdc/authoring.js +195 -0
- package/esm/keri/npm/src/acdc/chaining.js +223 -89
- package/esm/keri/npm/src/acdc/custody.js +164 -0
- package/esm/keri/npm/src/acdc/dhking.js +244 -32
- package/esm/keri/npm/src/acdc/observing.js +2 -2
- package/esm/keri/npm/src/acdc/regbasing.js +30 -29
- package/esm/keri/npm/src/acdc/regengine.js +4 -6
- package/esm/keri/npm/src/acdc/registering.js +13 -10
- package/esm/keri/npm/src/acdc/registraring.js +4 -9
- package/esm/keri/npm/src/acdc/salting.js +143 -26
- package/esm/keri/npm/src/acdc/scheming.js +93 -54
- package/esm/keri/npm/src/acdc/unblinding.js +120 -99
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
- package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +5 -7
- package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
- package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
- package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
- package/esm/keri/npm/src/app/credentials/root-replicating.js +131 -0
- package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
- package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
- package/esm/keri/npm/src/app/credentials/verifying.js +12 -3
- package/esm/keri/npm/src/app/delivery/forwarding.js +64 -9
- package/esm/keri/npm/src/app/exchanges/exchanging.js +24 -15
- package/esm/keri/npm/src/app/identity/challenging.js +50 -0
- package/esm/keri/npm/src/app/identity/configing.js +17 -43
- package/esm/keri/npm/src/app/identity/delegating.js +77 -77
- package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
- package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
- package/esm/keri/npm/src/app/identity/habbing.js +183 -41
- package/esm/keri/npm/src/app/identity/keeping.js +78 -5
- package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
- package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
- package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
- package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
- package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
- package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
- package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +42 -16
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
- package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
- package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
- package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
- package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
- package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
- package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
- package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +15 -14
- package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +32 -0
- package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +101 -141
- package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
- package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
- package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
- package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
- package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +44 -6
- package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +113 -65
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
- package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
- package/esm/keri/npm/src/app/runtime/doing.js +17 -0
- package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
- package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
- package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
- package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
- package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
- package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
- package/esm/keri/npm/src/app/transport/http-client.js +25 -6
- package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
- package/esm/keri/npm/src/app/transport/message-source.js +1 -1
- package/esm/keri/npm/src/app/transport/messengering.js +3 -4
- package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
- package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
- package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
- package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
- package/esm/keri/npm/src/cli/common/context.js +2 -2
- package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
- package/esm/keri/npm/src/cli/common/existing.js +3 -5
- package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
- package/esm/keri/npm/src/cli/credentials/ipex.js +159 -191
- package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
- package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
- package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
- package/esm/keri/npm/src/cli/endpoints/oobi.js +12 -15
- package/esm/keri/npm/src/cli/identity/challenge.js +9 -35
- package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
- package/esm/keri/npm/src/cli/identity/incept.js +17 -34
- package/esm/keri/npm/src/cli/identity/init.js +4 -3
- package/esm/keri/npm/src/cli/identity/interact.js +7 -19
- package/esm/keri/npm/src/cli/identity/rotate.js +10 -38
- package/esm/keri/npm/src/cli/index.js +3 -1
- package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
- package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
- package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
- package/esm/keri/npm/src/cli/messaging/multisig.js +187 -250
- package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
- package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
- package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
- package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
- package/esm/keri/npm/src/core/bytes.js +9 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
- package/esm/keri/npm/src/core/kel/eventing.js +67 -12
- package/esm/keri/npm/src/core/kel/kever.js +11 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +41 -9
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
- package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
- package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
- package/esm/keri/npm/src/core/records.js +23 -0
- package/esm/keri/npm/src/core/routing.js +15 -2
- package/esm/keri/npm/src/db/basing.js +183 -205
- package/esm/keri/npm/src/db/core/dber.js +1062 -0
- package/esm/keri/npm/src/db/core/index.js +4 -2
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
- package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
- package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
- package/esm/keri/npm/src/db/core/memstore.js +532 -0
- package/esm/keri/npm/src/db/core/path-manager.js +109 -223
- package/esm/keri/npm/src/db/core/store-owner.js +104 -0
- package/esm/keri/npm/src/db/core/webdber.js +252 -0
- package/esm/keri/npm/src/db/escrowing.js +2 -2
- package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
- package/esm/keri/npm/src/db/indexeddb.js +98 -0
- package/esm/keri/npm/src/db/keeping.js +38 -123
- package/esm/keri/npm/src/db/koming.js +1 -1
- package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
- package/esm/keri/npm/src/db/lmdb.js +6 -0
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
- package/esm/keri/npm/src/db/noting.js +11 -55
- package/esm/keri/npm/src/db/reger.js +43 -105
- package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
- package/esm/keri/npm/src/db/store-lock.js +150 -0
- package/esm/keri/npm/src/db/subing.js +1 -1
- package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
- package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
- package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
- package/esm/keri/npm/src/npm/db.browser.js +2 -0
- package/esm/keri/npm/src/npm/index.browser.js +9 -0
- package/esm/keri/npm/src/npm/runtime-node.js +3 -0
- package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
- package/esm/keri/npm/src/npm/runtime-web.js +3 -0
- package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
- package/esm/keri/npm/src/runtime/index.js +58 -12
- package/esm/keri/npm/src/runtime/node.js +14 -0
- package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
- package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
- package/esm/keri/npm/src/runtime/web.js +10 -0
- package/esm/keri/npm/src/vdr/eventing.js +1 -1
- package/esm/keri/npm/src/vdr/tel-publication.js +19 -3
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +24 -4
- package/types/acdc/authoring.d.ts +54 -0
- package/types/acdc/authoring.d.ts.map +1 -0
- package/types/acdc/chaining.d.ts +56 -6
- package/types/acdc/chaining.d.ts.map +1 -1
- package/types/acdc/custody.d.ts +77 -0
- package/types/acdc/custody.d.ts.map +1 -0
- package/types/acdc/dhking.d.ts +94 -3
- package/types/acdc/dhking.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +11 -6
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/regengine.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +8 -4
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/registraring.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +59 -7
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/acdc/scheming.d.ts +2 -0
- package/types/acdc/scheming.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts +58 -19
- package/types/acdc/unblinding.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +3 -1
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
- package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
- package/types/app/bootstrap/oobiery.d.ts +3 -1
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-revoking.d.ts +3 -0
- package/types/app/credentials/credential-revoking.d.ts.map +1 -1
- package/types/app/credentials/credential-workflows.d.ts +5 -0
- package/types/app/credentials/credential-workflows.d.ts.map +1 -1
- package/types/app/credentials/registry-settling.d.ts +85 -0
- package/types/app/credentials/registry-settling.d.ts.map +1 -0
- package/types/app/credentials/root-replicating.d.ts +97 -0
- package/types/app/credentials/root-replicating.d.ts.map +1 -0
- package/types/app/credentials/root-replicator.d.ts +105 -0
- package/types/app/credentials/root-replicator.d.ts.map +1 -0
- package/types/app/credentials/tel-completion.d.ts +55 -0
- package/types/app/credentials/tel-completion.d.ts.map +1 -0
- package/types/app/credentials/verifying.d.ts +2 -1
- package/types/app/credentials/verifying.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +16 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +2 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/challenging.d.ts +54 -0
- package/types/app/identity/challenging.d.ts.map +1 -1
- package/types/app/identity/configing.d.ts +7 -5
- package/types/app/identity/configing.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +21 -4
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/delegation-approval.d.ts +228 -0
- package/types/app/identity/delegation-approval.d.ts.map +1 -0
- package/types/app/identity/event-completion.d.ts +151 -0
- package/types/app/identity/event-completion.d.ts.map +1 -0
- package/types/app/identity/habbing.d.ts +90 -7
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +50 -4
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/identity/lmdb-habery.d.ts +6 -0
- package/types/app/identity/lmdb-habery.d.ts.map +1 -0
- package/types/app/ipex/group-ipex.d.ts +247 -0
- package/types/app/ipex/group-ipex.d.ts.map +1 -0
- package/types/app/ipex/group-issuance.d.ts +281 -0
- package/types/app/ipex/group-issuance.d.ts.map +1 -0
- package/types/app/ipex/ipex-admitting.d.ts +47 -0
- package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
- package/types/app/ipex/ipex-conversation.d.ts +195 -0
- package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
- package/types/app/ipex/ipex-discloser.d.ts +156 -0
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
- package/types/app/ipex/ipex-granting.d.ts +145 -0
- package/types/app/ipex/ipex-granting.d.ts.map +1 -0
- package/types/app/ipex/ipex-graph.d.ts +4 -4
- package/types/app/ipex/ipex-graph.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts +18 -0
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +11 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/ipexing.d.ts +3 -0
- package/types/app/ipex/ipexing.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +443 -0
- package/types/app/ipex/issuance.d.ts.map +1 -0
- package/types/app/ipex/pending-presentations.d.ts +25 -0
- package/types/app/ipex/pending-presentations.d.ts.map +1 -0
- package/types/app/ipex/presentation-files.d.ts +47 -0
- package/types/app/ipex/presentation-files.d.ts.map +1 -0
- package/types/app/ipex/presenting.d.ts +298 -0
- package/types/app/ipex/presenting.d.ts.map +1 -0
- package/types/app/ipex/receive-issuance.d.ts +99 -0
- package/types/app/ipex/receive-issuance.d.ts.map +1 -0
- package/types/app/ipex/unblinding-workflow.d.ts +255 -0
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
- package/types/app/mailbox/ipex-arrival.d.ts +104 -0
- package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
- package/types/app/mailbox/kel-publisher.d.ts +141 -0
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
- package/types/app/mailbox/kel-publishing.d.ts +70 -0
- package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
- package/types/app/mailbox/kel-submission.d.ts +18 -0
- package/types/app/mailbox/kel-submission.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-admin.d.ts +113 -0
- package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-poller.d.ts +92 -3
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +4 -1
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +196 -0
- package/types/app/multisig/counseling.d.ts.map +1 -0
- package/types/app/multisig/group-members.d.ts +20 -0
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +39 -20
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +93 -23
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposals.d.ts +129 -0
- package/types/app/multisig/proposals.d.ts.map +1 -0
- package/types/app/multisig/proposing.d.ts +125 -0
- package/types/app/multisig/proposing.d.ts.map +1 -0
- package/types/app/notifications/notifying.d.ts +1 -1
- package/types/app/notifications/notifying.d.ts.map +1 -1
- package/types/app/notifications/signaling.d.ts +3 -1
- package/types/app/notifications/signaling.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +16 -1
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +9 -1
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-workflows.d.ts +98 -0
- package/types/app/queries/query-workflows.d.ts.map +1 -0
- package/types/app/runtime/agent-runtime.d.ts +79 -25
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +2 -1
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/delivery-outbox.d.ts +68 -0
- package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
- package/types/app/runtime/doing.d.ts +27 -0
- package/types/app/runtime/doing.d.ts.map +1 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
- package/types/app/runtime/operation-owners.d.ts +137 -0
- package/types/app/runtime/operation-owners.d.ts.map +1 -0
- package/types/app/runtime/retry-backoff.d.ts +49 -0
- package/types/app/runtime/retry-backoff.d.ts.map +1 -0
- package/types/app/runtime/workflow-contract.d.ts +79 -0
- package/types/app/runtime/workflow-contract.d.ts.map +1 -0
- package/types/app/transport/byte-source.d.ts +13 -10
- package/types/app/transport/byte-source.d.ts.map +1 -1
- package/types/app/transport/cesr-egress.d.ts +21 -7
- package/types/app/transport/cesr-egress.d.ts.map +1 -1
- package/types/app/transport/file-bytes.d.ts +11 -0
- package/types/app/transport/file-bytes.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts +3 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/http-messenger.d.ts +15 -10
- package/types/app/transport/http-messenger.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +1 -1
- package/types/app/transport/messengering.d.ts +2 -2
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/transport/node-http-client.d.ts +10 -0
- package/types/app/transport/node-http-client.d.ts.map +1 -0
- package/types/app/transport/tcp-dialer.d.ts +21 -0
- package/types/app/transport/tcp-dialer.d.ts.map +1 -0
- package/types/cli/common/event-completion.d.ts +26 -0
- package/types/cli/common/event-completion.d.ts.map +1 -0
- package/types/cli/common/existing.d.ts.map +1 -1
- package/types/cli/common/runtime-workers.d.ts +23 -0
- package/types/cli/common/runtime-workers.d.ts.map +1 -0
- package/types/cli/credentials/ipex.d.ts.map +1 -1
- package/types/cli/credentials/vc.d.ts +1 -1
- package/types/cli/credentials/vc.d.ts.map +1 -1
- package/types/cli/endpoints/did.d.ts.map +1 -1
- package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
- package/types/cli/endpoints/oobi.d.ts +3 -1
- package/types/cli/endpoints/oobi.d.ts.map +1 -1
- package/types/cli/identity/challenge.d.ts +1 -1
- package/types/cli/identity/challenge.d.ts.map +1 -1
- package/types/cli/identity/delegate.d.ts +14 -1
- package/types/cli/identity/delegate.d.ts.map +1 -1
- package/types/cli/identity/incept.d.ts.map +1 -1
- package/types/cli/identity/init.d.ts.map +1 -1
- package/types/cli/identity/interact.d.ts.map +1 -1
- package/types/cli/identity/rotate.d.ts.map +1 -1
- package/types/cli/index.d.ts +4 -2
- package/types/cli/index.d.ts.map +1 -1
- package/types/cli/messaging/group-join.d.ts +53 -0
- package/types/cli/messaging/group-join.d.ts.map +1 -0
- package/types/cli/messaging/group-wait.d.ts +34 -0
- package/types/cli/messaging/group-wait.d.ts.map +1 -0
- package/types/cli/messaging/multisig.d.ts +36 -4
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/cli/messaging/root-copy-lines.d.ts +39 -0
- package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
- package/types/cli/tools/annotate.d.ts.map +1 -1
- package/types/cli/tools/benchmark.d.ts.map +1 -1
- package/types/cli/tools/db-dump.d.ts.map +1 -1
- package/types/core/bytes.d.ts +2 -0
- package/types/core/bytes.d.ts.map +1 -1
- package/types/core/cues.d.ts +11 -0
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts +41 -0
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +5 -4
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +14 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +1 -3
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +1 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/records.d.ts +61 -0
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +6 -0
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/basing.d.ts +22 -25
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/dber.d.ts +505 -0
- package/types/db/core/dber.d.ts.map +1 -0
- package/types/db/core/index.d.ts +4 -2
- package/types/db/core/index.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +59 -0
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
- package/types/db/core/lmdb-opener.d.ts +17 -0
- package/types/db/core/lmdb-opener.d.ts.map +1 -0
- package/types/db/core/lmdber.d.ts +60 -383
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/memstore.d.ts +129 -0
- package/types/db/core/memstore.d.ts.map +1 -0
- package/types/db/core/path-manager.d.ts +22 -45
- package/types/db/core/path-manager.d.ts.map +1 -1
- package/types/db/core/store-owner.d.ts +59 -0
- package/types/db/core/store-owner.d.ts.map +1 -0
- package/types/db/core/webdber.d.ts +127 -0
- package/types/db/core/webdber.d.ts.map +1 -0
- package/types/db/escrowing.d.ts +3 -3
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange/exchange-nests.d.ts.map +1 -1
- package/types/db/indexeddb.d.ts +37 -0
- package/types/db/indexeddb.d.ts.map +1 -0
- package/types/db/keeping.d.ts +14 -25
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/koming.d.ts +7 -8
- package/types/db/koming.d.ts.map +1 -1
- package/types/db/lmdb-stores.d.ts +45 -0
- package/types/db/lmdb-stores.d.ts.map +1 -0
- package/types/db/lmdb.d.ts +7 -0
- package/types/db/lmdb.d.ts.map +1 -0
- package/types/db/mailbox/mailboxing.d.ts +7 -21
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/noting.d.ts +7 -12
- package/types/db/noting.d.ts.map +1 -1
- package/types/db/reger.d.ts +7 -11
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/replay/witness-replay.d.ts +0 -2
- package/types/db/replay/witness-replay.d.ts.map +1 -1
- package/types/db/store-lock.d.ts +72 -0
- package/types/db/store-lock.d.ts.map +1 -0
- package/types/db/subing.d.ts +24 -25
- package/types/db/subing.d.ts.map +1 -1
- package/types/npm/db-indexeddb.d.ts +4 -0
- package/types/npm/db-indexeddb.d.ts.map +1 -0
- package/types/npm/db-lmdb.d.ts +4 -0
- package/types/npm/db-lmdb.d.ts.map +1 -0
- package/types/npm/runtime-node.d.ts +4 -0
- package/types/npm/runtime-node.d.ts.map +1 -0
- package/types/npm/runtime-web.d.ts +4 -0
- package/types/npm/runtime-web.d.ts.map +1 -0
- package/types/runtime/index.d.ts +48 -14
- package/types/runtime/index.d.ts.map +1 -1
- package/types/runtime/node.d.ts +15 -0
- package/types/runtime/node.d.ts.map +1 -0
- package/types/runtime/web/output-barrier.d.ts +30 -0
- package/types/runtime/web/output-barrier.d.ts.map +1 -0
- package/types/runtime/web/persistent-storage.d.ts +36 -0
- package/types/runtime/web/persistent-storage.d.ts.map +1 -0
- package/types/runtime/web.d.ts +11 -0
- package/types/runtime/web.d.ts.map +1 -0
- package/types/vdr/tel-publication.d.ts +6 -0
- package/types/vdr/tel-publication.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/acdc/relating.js +0 -59
- package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
- package/esm/keri/npm/src/db/baser-defaults.js +0 -11
- package/types/acdc/relating.d.ts +0 -21
- package/types/acdc/relating.d.ts.map +0 -1
- package/types/cli/common/tel-completion.d.ts +0 -8
- package/types/cli/common/tel-completion.d.ts.map +0 -1
- package/types/db/baser-defaults.d.ts +0 -5
- package/types/db/baser-defaults.d.ts.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TopicsRecord } from "../../core/records.js";
|
|
2
2
|
import { Roles } from "../../core/roles.js";
|
|
3
|
-
import {
|
|
3
|
+
import { openOwner } from "../../db/core/store-owner.js";
|
|
4
|
+
import { Mailboxer } from "../../db/mailbox/mailboxing.js";
|
|
4
5
|
/**
|
|
5
6
|
* Derive mailbox open options from one existing habery.
|
|
6
7
|
*
|
|
@@ -13,13 +14,7 @@ import { createMailboxer } from "../../db/mailbox/mailboxing.js";
|
|
|
13
14
|
*/
|
|
14
15
|
export function mailboxerOptionsForHabery(hby, options = {}) {
|
|
15
16
|
return {
|
|
16
|
-
|
|
17
|
-
base: hby.base,
|
|
18
|
-
temp: hby.temp,
|
|
19
|
-
headDirPath: hby.headDirPath,
|
|
20
|
-
compat: hby.compat,
|
|
21
|
-
readonly: hby.readonly,
|
|
22
|
-
reopen: true,
|
|
17
|
+
...hby.storeIdentity(),
|
|
23
18
|
...options,
|
|
24
19
|
};
|
|
25
20
|
}
|
|
@@ -35,7 +30,8 @@ export function mailboxerOptionsForHabery(hby, options = {}) {
|
|
|
35
30
|
* @returns Provider sidecar whose acquisition/lifetime belongs to the caller scope.
|
|
36
31
|
*/
|
|
37
32
|
export function* openMailboxerForHabery(hby, options = {}) {
|
|
38
|
-
|
|
33
|
+
const identity = mailboxerOptionsForHabery(hby, options);
|
|
34
|
+
return yield* openOwner(new Mailboxer(hby.opener.create(Mailboxer.Family, identity)), "Mailboxer", identity);
|
|
39
35
|
}
|
|
40
36
|
/**
|
|
41
37
|
* Build the stored mailbox topic key used by KERIpy-style mailbox storage.
|
|
@@ -92,6 +88,15 @@ export function updateMailboxRemoteCursor(hby, pre, witness, topic, idx) {
|
|
|
92
88
|
record.topics[topic] = idx;
|
|
93
89
|
hby.db.tops.pin([pre, witness], record);
|
|
94
90
|
}
|
|
91
|
+
/** AIDs `pre` currently has an authorized mailbox role with, in stored order. */
|
|
92
|
+
export function authorizedMailboxes(db, pre) {
|
|
93
|
+
const eids = [];
|
|
94
|
+
for (const [keys, end] of db.ends.getTopItemIter([pre, Roles.mailbox], { topive: true })) {
|
|
95
|
+
if (end.allowed && keys[2])
|
|
96
|
+
eids.push(keys[2]);
|
|
97
|
+
}
|
|
98
|
+
return eids;
|
|
99
|
+
}
|
|
95
100
|
/**
|
|
96
101
|
* Enumerate authorized mailbox providers and the subject's current KEL witnesses.
|
|
97
102
|
*
|
|
@@ -104,11 +109,7 @@ export function updateMailboxRemoteCursor(hby, pre, witness, topic, idx) {
|
|
|
104
109
|
* @returns One HTTPS-preferred HTTP target per provider AID, with stable worker keys.
|
|
105
110
|
*/
|
|
106
111
|
export function mailboxPollEndpoints(hab) {
|
|
107
|
-
const eids = new Set();
|
|
108
|
-
for (const [keys, end] of hab.db.ends.getTopItemIter([hab.pre, Roles.mailbox], { topive: true })) {
|
|
109
|
-
if (end.allowed && keys[2])
|
|
110
|
-
eids.add(keys[2]);
|
|
111
|
-
}
|
|
112
|
+
const eids = new Set(authorizedMailboxes(hab.db, hab.pre));
|
|
112
113
|
for (const eid of hab.kever?.wits ?? [])
|
|
113
114
|
eids.add(eid);
|
|
114
115
|
const endpoints = [];
|
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group-event Counselor: drives an accepted-or-pending group KEL event through
|
|
3
|
+
* member signatures and witness receipts, as KERIpy `app.grouping.Counselor`.
|
|
4
|
+
*
|
|
5
|
+
* Durable state is KERIpy's, row for row: `gpse` and `gpwe` hold `(pre) ->
|
|
6
|
+
* IoSet[(Number, Diger)]`, `gdee` holds delegated events awaiting the delegator
|
|
7
|
+
* and `cgms` holds `(pre, number.qb64) -> Diger` for completed events. The
|
|
8
|
+
* Counselor never signs; it only observes accepted state and, for witness
|
|
9
|
+
* receipts, asks the injected receipting collaborator to submit or fetch.
|
|
10
|
+
*
|
|
11
|
+
* Divergences from KERIpy, each deliberate:
|
|
12
|
+
* - An escrow row is removed by exact `(Number, Diger)` tuple. KERIpy removes
|
|
13
|
+
* every row of the prefix and never compares digests; here a different SAID
|
|
14
|
+
* accepted at the same sn drops only the stale tuple and reads `superseded`.
|
|
15
|
+
* - Receipts are judged against the event's own governing establishment, not
|
|
16
|
+
* the prefix's current key state.
|
|
17
|
+
* - "Must submit" derives from stored receipts and the election, not from an
|
|
18
|
+
* in-memory cue, so a restarted process resumes. Non-elected members fetch
|
|
19
|
+
* receipts and, after `fallbackAfterMs`, submit as the elected one would;
|
|
20
|
+
* KERIpy stalls when the elected member is offline.
|
|
21
|
+
* - A newer completion at the same `(pre, sn)` replaces the `cgms` digest.
|
|
22
|
+
* - A delegated `dip`/`drt` is accepted by its own delegate before the delegator's
|
|
23
|
+
* anchor and before witnesses receipt it (KERIpy `validateDelegation`: the
|
|
24
|
+
* delegatee accepts its own event to trigger receipting and approval). It
|
|
25
|
+
* waits in `gdee`. The publishing member (elected, or any member once the
|
|
26
|
+
* fallback grace passes) hands it to the Anchorer, which requests approval,
|
|
27
|
+
* awaits the anchor and publishes; the Counselor gates and observes, and
|
|
28
|
+
* writes `cgms` when the Anchorer completes. Any other member queries the
|
|
29
|
+
* delegator's witness for the anchor, pins `aess`, and continues in `gpwe`.
|
|
30
|
+
* Without an Anchorer such events stay in `gdee`, reported `notSupported`.
|
|
31
|
+
*
|
|
32
|
+
* Witness authorization codes, the delegation proxy and retry timers are process
|
|
33
|
+
* memory only, as in KERIpy and the Anchorer. Without a proxy the local group
|
|
34
|
+
* member sends delegation traffic, as KERIpy does for every group event, so a
|
|
35
|
+
* restart never leaves a delegated event waiting for one. Collaborators are
|
|
36
|
+
* narrow (ADR-0013); nothing here reaches a runtime.
|
|
37
|
+
*/
|
|
38
|
+
import { Diger, Ilks, NumberPrimitive, NumDex, Verfer } from "cesr-ts";
|
|
39
|
+
import { ValidationError } from "../../core/errors.js";
|
|
40
|
+
import { Kever } from "../../core/kel/kever.js";
|
|
41
|
+
import { dgKey } from "../../db/core/keys.js";
|
|
42
|
+
import { pinAuthorizingSeal, retryDelegatorWitnessQuery, } from "../identity/delegating.js";
|
|
43
|
+
import { observeUntil } from "../runtime/workflow-contract.js";
|
|
44
|
+
import { groupWitnesser, isLocalGroupHab, localGroupMember } from "./group-members.js";
|
|
45
|
+
/** Grace before a non-elected member submits receipts itself. */
|
|
46
|
+
export const DEFAULT_FALLBACK_AFTER_MS = 60_000;
|
|
47
|
+
/** First and longest wait between receipt attempts for one event. */
|
|
48
|
+
export const RECEIPT_BACKOFF_MS = { first: 1_000, max: 30_000 };
|
|
49
|
+
/** The production receipt retry delays as a policy; only `baseMs` and `maxMs` apply, the Counselor never gives up. */
|
|
50
|
+
export const DEFAULT_RECEIPT_RETRY = Object.freeze({
|
|
51
|
+
baseMs: RECEIPT_BACKOFF_MS.first,
|
|
52
|
+
maxMs: RECEIPT_BACKOFF_MS.max,
|
|
53
|
+
boundMs: 0,
|
|
54
|
+
});
|
|
55
|
+
/** Escrow tables in stage order. */
|
|
56
|
+
const STAGES = [["signatures", "gpse"], ["delegation", "gdee"], ["witnesses", "gpwe"]];
|
|
57
|
+
/** Receipt progress of one event against its own governing establishment. */
|
|
58
|
+
function receiptProgress(db, serder) {
|
|
59
|
+
let est = serder;
|
|
60
|
+
while (est && !est.estive)
|
|
61
|
+
est = est.prior ? db.getEvtSerder(est.pre, est.prior) : null;
|
|
62
|
+
if (!est)
|
|
63
|
+
return { have: 0, need: 0, missing: [] };
|
|
64
|
+
const witnesses = db.wits.get(dgKey(est.pre, est.said)).map(wit => wit.qb64);
|
|
65
|
+
const { indices } = Kever.verifyIndexedSignatures(serder.raw, db.wigs.get(dgKey(serder.pre, serder.said)), witnesses.map(qb64 => new Verfer({ qb64 })));
|
|
66
|
+
return {
|
|
67
|
+
have: indices.length,
|
|
68
|
+
need: Number(est.bner.num),
|
|
69
|
+
missing: witnesses.filter((_, index) => !indices.includes(index)),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** Counsels group events through signature and witness stages. */
|
|
73
|
+
export class Counselor {
|
|
74
|
+
/**
|
|
75
|
+
* @param hby Borrowed identities and stores; the Counselor opens nothing.
|
|
76
|
+
* @param receipting Submits or fetches witness receipts for accepted events.
|
|
77
|
+
* @param clock Time source for fallback and retry; only `now` is used.
|
|
78
|
+
* @param changes Optional sink told `{kind:"group", id:"<pre>:<sn>"}` after commits.
|
|
79
|
+
* @param delegation Anchorer and query port for delegated events; omit for non-delegated hosts.
|
|
80
|
+
* @param mailboxes Told when one of the group's rotations completes; the member runtime's publisher then tells
|
|
81
|
+
* the group's mailboxes the new key state, and several members doing so is harmless.
|
|
82
|
+
*/
|
|
83
|
+
constructor(hby, receipting, clock, changes, delegation, mailboxes, receiptRetry = DEFAULT_RECEIPT_RETRY) {
|
|
84
|
+
Object.defineProperty(this, "hby", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
configurable: true,
|
|
87
|
+
writable: true,
|
|
88
|
+
value: hby
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(this, "receipting", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
configurable: true,
|
|
93
|
+
writable: true,
|
|
94
|
+
value: receipting
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(this, "clock", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
configurable: true,
|
|
99
|
+
writable: true,
|
|
100
|
+
value: clock
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(this, "changes", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: true,
|
|
105
|
+
writable: true,
|
|
106
|
+
value: changes
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(this, "delegation", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true,
|
|
111
|
+
writable: true,
|
|
112
|
+
value: delegation
|
|
113
|
+
});
|
|
114
|
+
Object.defineProperty(this, "mailboxes", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: mailboxes
|
|
119
|
+
});
|
|
120
|
+
Object.defineProperty(this, "receiptRetry", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
value: receiptRetry
|
|
125
|
+
});
|
|
126
|
+
Object.defineProperty(this, "runs", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: true,
|
|
130
|
+
value: new Map()
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(this, "anchorQuery", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
configurable: true,
|
|
135
|
+
writable: true,
|
|
136
|
+
value: void 0
|
|
137
|
+
});
|
|
138
|
+
this.anchorQuery = delegation && { hby, querying: delegation.querying, retryPasses: new Map() };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Begin counseling an event. Idempotent and safe before local acceptance.
|
|
142
|
+
*
|
|
143
|
+
* @returns True when a new `gpse` row was added; false when the event is
|
|
144
|
+
* already counseled or complete, or another SAID holds that sn.
|
|
145
|
+
* @throws ValidationError when `pre` is not a local group or the ref is malformed.
|
|
146
|
+
*/
|
|
147
|
+
start(event, inputs = {}) {
|
|
148
|
+
const { pre, sn, said } = event;
|
|
149
|
+
if (!Number.isSafeInteger(sn) || sn < 0 || !said)
|
|
150
|
+
throw new ValidationError("Invalid group event reference.");
|
|
151
|
+
const hab = this.hby.habs.get(pre);
|
|
152
|
+
if (!hab || !isLocalGroupHab(this.hby, hab))
|
|
153
|
+
throw new ValidationError(`${pre} is not a local group.`);
|
|
154
|
+
const db = this.hby.db;
|
|
155
|
+
if (this.settled(event))
|
|
156
|
+
return false; // nothing to counsel, so nothing to retain
|
|
157
|
+
this.retain(event, inputs);
|
|
158
|
+
if (this.stageOf(event))
|
|
159
|
+
return false;
|
|
160
|
+
return db.gpse.add([pre], [NumberPrimitive.fromNum(BigInt(sn)), new Diger({ qb64: said })]);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Replace in-memory inputs of a counseled event, for example witness auths or
|
|
164
|
+
* a proxy after a restart, and re-arm any attempt waiting out its backoff.
|
|
165
|
+
* Ignored for an event that is already complete or superseded.
|
|
166
|
+
*/
|
|
167
|
+
supply(event, inputs) {
|
|
168
|
+
if (!this.settled(event))
|
|
169
|
+
this.retain(event, inputs);
|
|
170
|
+
}
|
|
171
|
+
/** Pure read of one event's state. */
|
|
172
|
+
status(event) {
|
|
173
|
+
const { pre, sn, said } = event;
|
|
174
|
+
const done = this.completed(pre, sn);
|
|
175
|
+
if (done !== null)
|
|
176
|
+
return done === said ? { state: "complete" } : { state: "superseded", accepted: done };
|
|
177
|
+
const accepted = this.hby.db.kels.getLast(pre, sn);
|
|
178
|
+
if (accepted && accepted !== said)
|
|
179
|
+
return { state: "superseded", accepted };
|
|
180
|
+
const stage = this.stageOf(event);
|
|
181
|
+
if (!stage)
|
|
182
|
+
return { state: "unknown" };
|
|
183
|
+
// A counseled event may not be stored locally yet; it is still pending, not unknown.
|
|
184
|
+
const serder = this.hby.db.getEvtSerder(pre, said);
|
|
185
|
+
if (!serder)
|
|
186
|
+
return { state: "pending", stage, elected: null, receipts: { have: 0, need: 0 } };
|
|
187
|
+
const { have, need, missing } = receiptProgress(this.hby.db, serder);
|
|
188
|
+
const elected = accepted ? groupWitnesser(this.hby, pre, { sn, said }) : null;
|
|
189
|
+
const status = { state: "pending", stage, elected, receipts: { have, need } };
|
|
190
|
+
const run = this.runs.get(this.runKey(event));
|
|
191
|
+
const failure = run?.failure ? this.receiptBlock(run, missing) : undefined;
|
|
192
|
+
if (stage === "delegation")
|
|
193
|
+
status.blocked = this.delegationBlock(event) ?? failure;
|
|
194
|
+
else if (stage === "witnesses")
|
|
195
|
+
status.blocked = failure;
|
|
196
|
+
if (!status.blocked)
|
|
197
|
+
delete status.blocked;
|
|
198
|
+
return status;
|
|
199
|
+
}
|
|
200
|
+
/** Why a receipt attempt failed: missing auths for unreceipted witnesses, else the witness's own reason. */
|
|
201
|
+
receiptBlock(run, missing) {
|
|
202
|
+
const unauthorized = missing.filter(witness => !(witness in run.auths));
|
|
203
|
+
return unauthorized.length
|
|
204
|
+
? { kind: "witnessAuth", witnesses: unauthorized }
|
|
205
|
+
: { kind: "witness", reason: run.failure };
|
|
206
|
+
}
|
|
207
|
+
/** What keeps a delegated event in `gdee`, if anything the caller can fix. */
|
|
208
|
+
delegationBlock(event) {
|
|
209
|
+
if (!this.delegation)
|
|
210
|
+
return { kind: "notSupported", feature: "delegation" };
|
|
211
|
+
const delpre = this.hby.db.getKever(event.pre)?.delpre;
|
|
212
|
+
if (delpre && !this.hby.db.getKever(delpre))
|
|
213
|
+
return { kind: "delegatorUnknown", delpre };
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
fallbackElapsed(run) {
|
|
217
|
+
return !!run && run.since !== null && this.clock.now() - run.since >= run.fallbackAfterMs;
|
|
218
|
+
}
|
|
219
|
+
/** True when the event is complete, or another SAID holds its sn. */
|
|
220
|
+
settled({ pre, sn, said }) {
|
|
221
|
+
const accepted = this.hby.db.kels.getLast(pre, sn);
|
|
222
|
+
return (!!accepted && accepted !== said) || this.completed(pre, sn) !== null;
|
|
223
|
+
}
|
|
224
|
+
/** Events still counseled for `pre`, or for every prefix, in stage order. */
|
|
225
|
+
pending(pre) {
|
|
226
|
+
const found = [];
|
|
227
|
+
for (const [stage, table] of STAGES) {
|
|
228
|
+
for (const [[key], [number, diger]] of this.hby.db[table].getTopItemIter(pre ?? "", { topive: !!pre })) {
|
|
229
|
+
found.push({ pre: key, sn: Number(number.num), said: diger.qb64, stage });
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return found;
|
|
233
|
+
}
|
|
234
|
+
/** True once the exact event completed; drops its in-memory inputs. */
|
|
235
|
+
complete(event) {
|
|
236
|
+
const done = this.completed(event.pre, event.sn) === event.said;
|
|
237
|
+
if (done)
|
|
238
|
+
this.runs.delete(this.runKey(event));
|
|
239
|
+
return done;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Stop counseling `pre`: remove its escrow rows, completion markers and
|
|
243
|
+
* in-memory inputs. Accepted KEL state is untouched.
|
|
244
|
+
*/
|
|
245
|
+
abandon(pre) {
|
|
246
|
+
const db = this.hby.db;
|
|
247
|
+
const removed = new Set(this.pending(pre).map(event => event.sn));
|
|
248
|
+
for (const [[, number]] of db.cgms.getTopItemIter([pre], { topive: true })) {
|
|
249
|
+
removed.add(Number(new NumberPrimitive({ qb64: number }).num));
|
|
250
|
+
}
|
|
251
|
+
db.transaction(() => {
|
|
252
|
+
for (const [, table] of STAGES)
|
|
253
|
+
db[table].rem([pre]);
|
|
254
|
+
for (const [keys] of [...db.cgms.getTopItemIter([pre], { topive: true })])
|
|
255
|
+
db.cgms.rem(keys);
|
|
256
|
+
});
|
|
257
|
+
for (const key of [...this.runs.keys()])
|
|
258
|
+
if (key.startsWith(`${pre}:`))
|
|
259
|
+
this.runs.delete(key);
|
|
260
|
+
for (const sn of removed)
|
|
261
|
+
this.changes?.push({ kind: "group", id: `${pre}:${sn}` });
|
|
262
|
+
}
|
|
263
|
+
/** One pass over all stages, as KERIpy `processEscrows`. */
|
|
264
|
+
*processOnce() {
|
|
265
|
+
// A runtime calls this every turn; with nothing counseled, three row counts are the whole cost.
|
|
266
|
+
const db = this.hby.db;
|
|
267
|
+
if (db.gpse.cnt() === 0 && db.gdee.cnt() === 0 && db.gpwe.cnt() === 0)
|
|
268
|
+
return;
|
|
269
|
+
this.processSignatures();
|
|
270
|
+
yield* this.processDelegation();
|
|
271
|
+
yield* this.processWitnesses();
|
|
272
|
+
}
|
|
273
|
+
/** Move events accepted with their escrowed SAID on to delegation or witnesses. */
|
|
274
|
+
processSignatures() {
|
|
275
|
+
for (const [[pre], [number, diger]] of [...this.hby.db.gpse.getTopItemIter()]) {
|
|
276
|
+
const event = this.refOf(pre, number, diger);
|
|
277
|
+
if (this.dropIfSuperseded(this.hby.db.gpse, event, number, diger))
|
|
278
|
+
continue;
|
|
279
|
+
if (this.hby.db.kels.getLast(pre, event.sn) !== event.said)
|
|
280
|
+
continue;
|
|
281
|
+
const ilk = this.hby.db.getEvtSerder(pre, event.said)?.ilk;
|
|
282
|
+
const next = ilk === Ilks.dip || ilk === Ilks.drt ? this.hby.db.gdee : this.hby.db.gpwe;
|
|
283
|
+
this.hby.db.transaction(() => {
|
|
284
|
+
this.hby.db.gpse.rem([pre], [number, diger]);
|
|
285
|
+
next.add([pre], [number, diger]);
|
|
286
|
+
});
|
|
287
|
+
this.changes?.push({ kind: "group", id: `${pre}:${event.sn}` });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Delegated events: the publishing member drives the Anchorer, any other member
|
|
292
|
+
* watches for the delegator's anchor. Both wait for the delegator's KEL.
|
|
293
|
+
*/
|
|
294
|
+
*processDelegation() {
|
|
295
|
+
const db = this.hby.db;
|
|
296
|
+
for (const [[pre], [number, diger]] of [...db.gdee.getTopItemIter()]) {
|
|
297
|
+
const event = this.refOf(pre, number, diger);
|
|
298
|
+
if (this.dropIfSuperseded(db.gdee, event, number, diger))
|
|
299
|
+
continue;
|
|
300
|
+
const serder = db.getEvtSerder(pre, event.said);
|
|
301
|
+
const delpre = db.getKever(pre)?.delpre;
|
|
302
|
+
if (!this.delegation || !serder || !delpre || !db.getKever(delpre))
|
|
303
|
+
continue;
|
|
304
|
+
const run = this.retain(event, {});
|
|
305
|
+
run.since ??= this.clock.now();
|
|
306
|
+
const member = localGroupMember(this.hby, pre);
|
|
307
|
+
if (groupWitnesser(this.hby, pre, event) || this.fallbackElapsed(run)) {
|
|
308
|
+
yield* this.publishDelegation(event, serder, run, member, [number, diger]);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
this.watchAnchor(event, serder, run, member, delpre, [number, diger]);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/** Publishing duty: begin the Anchorer, keep receipts coming, and record completion. */
|
|
316
|
+
*publishDelegation(event, serder, run, member, row) {
|
|
317
|
+
const { anchorer } = this.delegation;
|
|
318
|
+
if (anchorer.complete(event.pre, event.sn)) {
|
|
319
|
+
this.finish(this.hby.db.gdee, event, row);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
// The Anchorer asks the delegator only once the event's witnesses have receipted it.
|
|
323
|
+
if (!this.hby.db.fullyWitnessed(serder))
|
|
324
|
+
yield* this.pursueReceipts(event, serder, true);
|
|
325
|
+
if (!run.begun) {
|
|
326
|
+
anchorer.begin(serder, { communicationHab: run.proxy ?? member });
|
|
327
|
+
run.begun = true;
|
|
328
|
+
this.changes?.push({ kind: "group", id: `${event.pre}:${event.sn}` });
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/** Non-publishing duty: find the delegator's sealing event, pin it, and move on to receipts. */
|
|
332
|
+
watchAnchor(event, serder, run, member, delpre, row) {
|
|
333
|
+
const db = this.hby.db;
|
|
334
|
+
retryDelegatorWitnessQuery(this.anchorQuery, serder, run.proxy ?? member);
|
|
335
|
+
const delegating = db.fetchLastSealingEventByEventSeal(delpre, { i: event.pre, s: serder.snh, d: event.said });
|
|
336
|
+
if (!delegating)
|
|
337
|
+
return;
|
|
338
|
+
pinAuthorizingSeal(this.hby, serder, delegating);
|
|
339
|
+
db.transaction(() => {
|
|
340
|
+
db.gdee.rem([event.pre], row);
|
|
341
|
+
db.gpwe.add([event.pre], row);
|
|
342
|
+
});
|
|
343
|
+
this.changes?.push({ kind: "group", id: `${event.pre}:${event.sn}` });
|
|
344
|
+
}
|
|
345
|
+
/** Record completion of a counseled event and drop its row from `table`. */
|
|
346
|
+
finish(table, event, row) {
|
|
347
|
+
const db = this.hby.db;
|
|
348
|
+
db.transaction(() => {
|
|
349
|
+
table.rem([event.pre], row);
|
|
350
|
+
db.cgms.pin([event.pre, row[0].qb64], row[1]);
|
|
351
|
+
});
|
|
352
|
+
this.runs.delete(this.runKey(event));
|
|
353
|
+
this.changes?.push({ kind: "group", id: `${event.pre}:${event.sn}` });
|
|
354
|
+
const ilk = db.getEvtSerder(event.pre, event.said)?.ilk;
|
|
355
|
+
if (ilk === Ilks.rot || ilk === Ilks.drt) {
|
|
356
|
+
this.mailboxes?.rotated({ kin: "rotated", pre: event.pre, sn: event.sn, said: event.said });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/** Complete events whose own witness threshold is met; otherwise submit or fetch receipts. */
|
|
360
|
+
*processWitnesses() {
|
|
361
|
+
const db = this.hby.db;
|
|
362
|
+
for (const [[pre], [number, diger]] of [...db.gpwe.getTopItemIter()]) {
|
|
363
|
+
const event = this.refOf(pre, number, diger);
|
|
364
|
+
if (this.dropIfSuperseded(db.gpwe, event, number, diger))
|
|
365
|
+
continue;
|
|
366
|
+
const serder = db.getEvtSerder(pre, event.said);
|
|
367
|
+
if (!serder)
|
|
368
|
+
continue;
|
|
369
|
+
if (!db.fullyWitnessed(serder)) {
|
|
370
|
+
yield* this.pursueReceipts(event, serder);
|
|
371
|
+
if (!db.fullyWitnessed(serder))
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
this.finish(db.gpwe, event, [number, diger]);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/** One backed-off receipt attempt: submit when forced, elected or past the grace, else fetch. */
|
|
378
|
+
*pursueReceipts(event, serder, forceSubmit = false) {
|
|
379
|
+
const run = this.retain(event, {});
|
|
380
|
+
const now = this.clock.now();
|
|
381
|
+
run.since ??= now;
|
|
382
|
+
if (now < run.nextAt)
|
|
383
|
+
return;
|
|
384
|
+
const submit = forceSubmit || groupWitnesser(this.hby, event.pre, event) || now - run.since >= run.fallbackAfterMs;
|
|
385
|
+
try {
|
|
386
|
+
if (submit)
|
|
387
|
+
yield* this.receipting.receipt(event.pre, { sn: event.sn, auths: run.auths });
|
|
388
|
+
else
|
|
389
|
+
yield* this.receipting.get(event.pre, { sn: event.sn, said: event.said });
|
|
390
|
+
run.failure = null;
|
|
391
|
+
run.delay = this.receiptRetry.baseMs;
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
// A witness refusing or being unreachable is a remote outcome: report it in status and retry later.
|
|
395
|
+
run.failure = error instanceof Error ? error.message : String(error);
|
|
396
|
+
run.delay = Math.min(run.delay * 2, this.receiptRetry.maxMs);
|
|
397
|
+
}
|
|
398
|
+
run.nextAt = now + run.delay;
|
|
399
|
+
if (!this.hby.db.fullyWitnessed(serder))
|
|
400
|
+
this.changes?.push({ kind: "group", id: `${event.pre}:${event.sn}` });
|
|
401
|
+
}
|
|
402
|
+
/** Remove a stale tuple when another SAID holds its sn; true when removed. */
|
|
403
|
+
dropIfSuperseded(table, event, number, diger) {
|
|
404
|
+
const accepted = this.hby.db.kels.getLast(event.pre, event.sn);
|
|
405
|
+
if (!accepted || accepted === event.said)
|
|
406
|
+
return false;
|
|
407
|
+
table.rem([event.pre], [number, diger]);
|
|
408
|
+
this.runs.delete(this.runKey(event));
|
|
409
|
+
this.changes?.push({ kind: "group", id: `${event.pre}:${event.sn}` });
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
/** Digest of the completed event at `(pre, sn)`, under either number width KERIpy writes. */
|
|
413
|
+
completed(pre, sn) {
|
|
414
|
+
const cgms = this.hby.db.cgms;
|
|
415
|
+
const auto = NumberPrimitive.fromNum(BigInt(sn));
|
|
416
|
+
const huge = new NumberPrimitive({ code: NumDex.Huge, raw: hugeRaw(sn) });
|
|
417
|
+
return (cgms.get([pre, auto.qb64]) ?? cgms.get([pre, huge.qb64]))?.qb64 ?? null;
|
|
418
|
+
}
|
|
419
|
+
/** Stage whose escrow holds exactly this event, if any. */
|
|
420
|
+
stageOf({ pre, sn, said }) {
|
|
421
|
+
for (const [stage, table] of STAGES) {
|
|
422
|
+
for (const [number, diger] of this.hby.db[table].get([pre])) {
|
|
423
|
+
if (Number(number.num) === sn && diger.qb64 === said)
|
|
424
|
+
return stage;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
refOf(pre, number, diger) {
|
|
430
|
+
return { pre, sn: Number(number.num), said: diger.qb64 };
|
|
431
|
+
}
|
|
432
|
+
runKey({ pre, sn, said }) {
|
|
433
|
+
return `${pre}:${sn}:${said}`;
|
|
434
|
+
}
|
|
435
|
+
/** Get or create the in-memory run for an event, applying supplied inputs. */
|
|
436
|
+
retain(event, { auths, fallbackAfterMs, proxy }) {
|
|
437
|
+
if (fallbackAfterMs !== undefined && !(fallbackAfterMs >= 0 && Number.isFinite(fallbackAfterMs))) {
|
|
438
|
+
throw new ValidationError("fallbackAfterMs must be a finite nonnegative duration.");
|
|
439
|
+
}
|
|
440
|
+
const key = this.runKey(event);
|
|
441
|
+
const run = this.runs.get(key)
|
|
442
|
+
?? {
|
|
443
|
+
auths: {},
|
|
444
|
+
fallbackAfterMs: DEFAULT_FALLBACK_AFTER_MS,
|
|
445
|
+
since: null,
|
|
446
|
+
nextAt: 0,
|
|
447
|
+
delay: this.receiptRetry.baseMs,
|
|
448
|
+
failure: null,
|
|
449
|
+
proxy: null,
|
|
450
|
+
begun: false,
|
|
451
|
+
};
|
|
452
|
+
if (proxy) {
|
|
453
|
+
run.proxy = proxy;
|
|
454
|
+
run.begun = false; // the Anchorer pins its sender per begin, so re-pin
|
|
455
|
+
}
|
|
456
|
+
if (auths) {
|
|
457
|
+
run.auths = { ...auths };
|
|
458
|
+
run.nextAt = 0; // New credentials re-arm an attempt that was waiting out its backoff.
|
|
459
|
+
}
|
|
460
|
+
if (fallbackAfterMs !== undefined)
|
|
461
|
+
run.fallbackAfterMs = fallbackAfterMs;
|
|
462
|
+
this.runs.set(key, run);
|
|
463
|
+
return run;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/** Big-endian 16-byte raw for the `0A` (Huge) number code. */
|
|
467
|
+
function hugeRaw(sn) {
|
|
468
|
+
const raw = new Uint8Array(16);
|
|
469
|
+
for (let at = 15, value = BigInt(sn); at >= 0; at--, value >>= 8n)
|
|
470
|
+
raw[at] = Number(value & 0xffn);
|
|
471
|
+
return raw;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Observe `event` until it is no longer pending or the deadline passes. Starts
|
|
475
|
+
* no worker and makes no receipt call; progress comes from `processOnce`
|
|
476
|
+
* running elsewhere.
|
|
477
|
+
*/
|
|
478
|
+
export function* waitForGroupEvent(counselor, event, { timeoutMs, clock }) {
|
|
479
|
+
const done = yield* observeUntil(() => counselor.status(event).state !== "pending", { timeoutMs, clock });
|
|
480
|
+
const status = counselor.status(event);
|
|
481
|
+
return done ? { outcome: "settled", status } : { outcome: "timed-out", status, timeoutMs };
|
|
482
|
+
}
|
|
@@ -64,6 +64,38 @@ export function groupWitnesserSelection(db, group, { sn, said }) {
|
|
|
64
64
|
}
|
|
65
65
|
return null;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Return the current signing member elected by `coordinator`, as KERIpy
|
|
69
|
+
* `GroupHab.elected`: the member whose latest contribution to the coordinator's
|
|
70
|
+
* establishment keys holds the lowest verified signing index. Null when the
|
|
71
|
+
* event has no election or that contributor is no longer a current signing
|
|
72
|
+
* member. The result depends on locally stored signatures, so it suits
|
|
73
|
+
* idempotent duties only; frozen operations recheck their earlier choice instead.
|
|
74
|
+
*/
|
|
75
|
+
export function groupElectedMember(hby, group, coordinator) {
|
|
76
|
+
const selection = groupWitnesserSelection(hby.db, group, coordinator);
|
|
77
|
+
if (!selection)
|
|
78
|
+
return null;
|
|
79
|
+
return groupSigningMembers(hby, group).find(member => latestGroupContribution(hby.db, member, selection.establishment.verfers)?.index === selection.index) ?? null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* True when the local member is the witnesser for the exact accepted group event
|
|
83
|
+
* `coordinator`, as KERIpy `_groupWitnesser`: the member's latest contribution to
|
|
84
|
+
* the governing establishment's keys holds the lowest verified signing index.
|
|
85
|
+
*
|
|
86
|
+
* Unlike `groupElectedMember` this does not require that member to be a current
|
|
87
|
+
* signing member, so a historical event keeps its witnesser after a later
|
|
88
|
+
* rotation. Like it, the answer depends on locally stored signatures and suits
|
|
89
|
+
* idempotent duties only.
|
|
90
|
+
*/
|
|
91
|
+
export function groupWitnesser(hby, group, coordinator) {
|
|
92
|
+
const selection = groupWitnesserSelection(hby.db, group, coordinator);
|
|
93
|
+
if (!selection)
|
|
94
|
+
return false;
|
|
95
|
+
const member = localGroupMember(hby, group).pre;
|
|
96
|
+
const contribution = member ? latestGroupContribution(hby.db, member, selection.establishment.verfers) : null;
|
|
97
|
+
return contribution?.index === selection.index;
|
|
98
|
+
}
|
|
67
99
|
/** Return current group signing member AIDs in signing-index order. */
|
|
68
100
|
export function groupSigningMembers(hby, groupPre) {
|
|
69
101
|
const stored = hby.ks.getSmids(groupPre).map((tuple) => tuple[0].qb64);
|
|
@@ -304,8 +304,9 @@ export function* prepareMultisigEventExn(sender, proposal, wire, options = {}) {
|
|
|
304
304
|
// Keep the route selection stable through parser suspension; attribute values remain immutable borrows.
|
|
305
305
|
const captured = { ...proposal };
|
|
306
306
|
const { route, attrs } = captured;
|
|
307
|
-
// KERIpy `kli multisig incept|interact
|
|
308
|
-
//
|
|
307
|
+
// KERIpy `kli multisig incept|interact` and `ends add` send these routes as v1 `e`-embed
|
|
308
|
+
// wrappers whatever the group KEL version. `kli multisig rotate --version 2.0` sends a v2
|
|
309
|
+
// nested wrapper, and `kli multisig join` replies in its proposal's form, as approvals here do.
|
|
309
310
|
const keripyEmbedRoute = KERIPY_EMBED_PROPOSAL_ROUTES.includes(route);
|
|
310
311
|
const version = options.pvrsn ?? options.version ?? (keripyEmbedRoute ? Vrsn_1_0 : Vrsn_2_0);
|
|
311
312
|
const field = route.slice(route.lastIndexOf("/") + 1);
|
|
@@ -547,7 +548,7 @@ export class Multiplexor {
|
|
|
547
548
|
if (this.isLocalHab(sender))
|
|
548
549
|
yield* this.processApproved(nests);
|
|
549
550
|
}
|
|
550
|
-
const { existing, submitters } = this.hby.db.
|
|
551
|
+
const { existing, submitters } = this.hby.db.transaction(() => {
|
|
551
552
|
const indexed = this.hby.db.meids.get([embeddedSaid]);
|
|
552
553
|
const existing = isV2RegistryRoute(route) || v2Ipex
|
|
553
554
|
? indexed.filter(diger => {
|