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
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group proposal reads, owned by the library so that a CLI, a browser wallet and
|
|
3
|
+
* a service all see and dismiss the same proposals. Operations follow the
|
|
4
|
+
* workflow contract (`app/runtime/workflow-contract.ts`):
|
|
5
|
+
* - `listGroupProposals` and `findGroupProposal` are pure reads of stored
|
|
6
|
+
* exchange messages, the multisig embed index (`meids.`) and the notifier.
|
|
7
|
+
* - `dismissGroupProposal` removes local notices only.
|
|
8
|
+
*
|
|
9
|
+
* A proposal is identified by the SAID of the outer exchange wrapper that
|
|
10
|
+
* announced it. Approval, which is the only step that signs, names that SAID
|
|
11
|
+
* explicitly; nothing here or in the notice store selects a proposal to approve.
|
|
12
|
+
*
|
|
13
|
+
* Boundaries:
|
|
14
|
+
* - Dependencies are declared collaborators, not an AgentRuntime (ADR-0013).
|
|
15
|
+
* - Notices discover candidates only. Their attributes never authorize a route
|
|
16
|
+
* or a group; every field below is read from the stored, indexed wrapper.
|
|
17
|
+
*/
|
|
18
|
+
import { Vrsn_2_0 } from "cesr-ts";
|
|
19
|
+
import { ValidationError } from "../../core/errors.js";
|
|
20
|
+
import { isV2RegistryRoute } from "../../core/exchange/protocol-exchanging.js";
|
|
21
|
+
import { loadNests } from "../../db/exchange/exchange-nests.js";
|
|
22
|
+
import { abortable } from "../runtime/abortable.js";
|
|
23
|
+
import { collectBytes } from "../transport/byte-source.js";
|
|
24
|
+
import { findLocalGroupMember, groupSigningMembers, uniqueMembers } from "./group-members.js";
|
|
25
|
+
import { acdcV2RegistryProposal, MULTISIG_RPY_ROUTE, multisigChild } from "./grouping.js";
|
|
26
|
+
import { multisigEmbeddedSection, multisigPayloadSaid, storedGroupMessage } from "./multisig-messaging.js";
|
|
27
|
+
import { approveKelProposal, approveRegistryV2Proposal, approveRpyProposal, approveVdrProposal, eventAccepted, isKelRoute, isVdrRoute, kelApproval, payloadSection, } from "./multisig-workflows.js";
|
|
28
|
+
/** Page size when reading the notice store; no proposal is hidden behind the first page. */
|
|
29
|
+
const NOTICE_PAGE = 100;
|
|
30
|
+
/** Wrapper route to proposal kind, or null for routes this API does not cover. */
|
|
31
|
+
function proposalKind(route) {
|
|
32
|
+
if (!isKelRoute(route) && !isVdrRoute(route) && route !== MULTISIG_RPY_ROUTE && !isV2RegistryRoute(route)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return route.slice("/multisig/".length);
|
|
36
|
+
}
|
|
37
|
+
/** Page through every notice; `fn` sees each in durable order. */
|
|
38
|
+
function eachNotice(notifier, fn) {
|
|
39
|
+
for (let start = 0;; start += NOTICE_PAGE) {
|
|
40
|
+
const page = notifier.list(start, NOTICE_PAGE);
|
|
41
|
+
for (const note of page)
|
|
42
|
+
fn({ rid: note.pad.i, attrs: note.pad.a });
|
|
43
|
+
if (page.length < NOTICE_PAGE)
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Wrapper SAIDs the notice store holds for multisig proposals, oldest first and without repeats. */
|
|
48
|
+
function noticedWrappers(notifier) {
|
|
49
|
+
const saids = new Set();
|
|
50
|
+
eachNotice(notifier, ({ attrs }) => {
|
|
51
|
+
if (typeof attrs.d === "string")
|
|
52
|
+
saids.add(attrs.d);
|
|
53
|
+
});
|
|
54
|
+
return [...saids];
|
|
55
|
+
}
|
|
56
|
+
/** The local member that would approve, without throwing for a group not yet joined. */
|
|
57
|
+
function approvingMember(hby, group, members) {
|
|
58
|
+
const mid = hby.db.getHab(group)?.mid;
|
|
59
|
+
return (mid ? hby.habs.get(mid) : null) ?? findLocalGroupMember(hby, members);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Event body of a wrapper's named child. v1 reads the pathed embed; v2 reads the
|
|
63
|
+
* first nest of a wrapper that authenticates through its own route. Proofs are
|
|
64
|
+
* not read: a listing never signs, so only the body is needed.
|
|
65
|
+
*/
|
|
66
|
+
function childBody(deps, wrapper, route, label) {
|
|
67
|
+
if (wrapper.pvrsn.major === 1)
|
|
68
|
+
return multisigChild(deps.hby, wrapper, label);
|
|
69
|
+
if (!wrapper.said || !deps.exc.verifyAccepted(wrapper.said, route))
|
|
70
|
+
return null;
|
|
71
|
+
const body = loadNests(deps.hby.db, wrapper.said)[0]?.body;
|
|
72
|
+
const event = body;
|
|
73
|
+
if (!event || typeof event.pre !== "string")
|
|
74
|
+
return null;
|
|
75
|
+
return { event, attachment: new Uint8Array(), genus: event.gvrsn ?? event.pvrsn ?? Vrsn_2_0 };
|
|
76
|
+
}
|
|
77
|
+
function eventRef(event, pre) {
|
|
78
|
+
return event.said && event.sn !== null ? { pre, sn: event.sn, said: event.said } : undefined;
|
|
79
|
+
}
|
|
80
|
+
function decode(deps, exn, route, kind) {
|
|
81
|
+
const { hby } = deps;
|
|
82
|
+
const payload = payloadSection(exn.ked ?? {});
|
|
83
|
+
if (isKelRoute(route)) {
|
|
84
|
+
const child = childBody(deps, exn, route, kind);
|
|
85
|
+
const approval = child && kelApproval(exn, route, child);
|
|
86
|
+
if (!approval)
|
|
87
|
+
return null;
|
|
88
|
+
const { smids, rmids } = approval.proposal.attrs;
|
|
89
|
+
return {
|
|
90
|
+
kind,
|
|
91
|
+
group: approval.group,
|
|
92
|
+
embedded: approval.event.said ?? "",
|
|
93
|
+
smids,
|
|
94
|
+
rmids: rmids ?? [],
|
|
95
|
+
event: eventRef(approval.event, approval.group),
|
|
96
|
+
inapplicable: eventAccepted(hby, approval.event) && !smids.some(mid => hby.habs.has(mid)),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (isV2RegistryRoute(route)) {
|
|
100
|
+
const nests = loadNests(hby.db, exn.said);
|
|
101
|
+
const registry = acdcV2RegistryProposal(exn, nests, deps.registryStore);
|
|
102
|
+
if (!registry?.anchor.pre)
|
|
103
|
+
return null;
|
|
104
|
+
const group = registry.anchor.pre;
|
|
105
|
+
return {
|
|
106
|
+
kind,
|
|
107
|
+
group,
|
|
108
|
+
embedded: registry.tel.said ?? "",
|
|
109
|
+
smids: groupSigningMembers(hby, group),
|
|
110
|
+
rmids: [],
|
|
111
|
+
event: eventRef(registry.anchor, group),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const group = typeof payload.gid === "string" ? payload.gid : "";
|
|
115
|
+
if (!group)
|
|
116
|
+
return null;
|
|
117
|
+
const smids = groupSigningMembers(hby, group);
|
|
118
|
+
if (route === MULTISIG_RPY_ROUTE) {
|
|
119
|
+
const child = childBody(deps, exn, route, "rpy");
|
|
120
|
+
return child?.event.said ? { kind, group, embedded: child.event.said, smids, rmids: [] } : null;
|
|
121
|
+
}
|
|
122
|
+
// vcp, iss and rev: the named TEL event, sealed by the group event in `anc`.
|
|
123
|
+
const anchor = multisigChild(hby, exn, "anc");
|
|
124
|
+
const tel = multisigEmbeddedSection(exn.ked ?? {})?.[kind];
|
|
125
|
+
const embedded = tel && typeof tel === "object" ? tel.d : undefined;
|
|
126
|
+
if (!anchor || anchor.event.pre !== group || typeof embedded !== "string")
|
|
127
|
+
return null;
|
|
128
|
+
return { kind, group, embedded, smids, rmids: [], event: eventRef(anchor.event, group) };
|
|
129
|
+
}
|
|
130
|
+
/** Read one stored wrapper; null when it is not a well-formed proposal of a supported kind. */
|
|
131
|
+
function readProposal(deps, said) {
|
|
132
|
+
const { hby } = deps;
|
|
133
|
+
const exn = hby.db.exns.get([said]);
|
|
134
|
+
if (!exn?.ked || !exn.said || !exn.pre)
|
|
135
|
+
return null;
|
|
136
|
+
const route = exn.route ?? "";
|
|
137
|
+
const kind = proposalKind(route);
|
|
138
|
+
if (!kind || !multisigPayloadSaid(exn))
|
|
139
|
+
return null;
|
|
140
|
+
let decoded;
|
|
141
|
+
try {
|
|
142
|
+
decoded = decode(deps, exn, route, kind);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
if (error instanceof ValidationError)
|
|
146
|
+
return null; // one malformed row never hides the others
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
if (!decoded)
|
|
150
|
+
return null;
|
|
151
|
+
const member = approvingMember(hby, decoded.group, uniqueMembers([...decoded.smids, ...decoded.rmids]));
|
|
152
|
+
const approved = !!member && storedGroupMessage(hby.db, member.pre, exn) !== null;
|
|
153
|
+
const inapplicable = !approved && decoded.inapplicable === true;
|
|
154
|
+
return {
|
|
155
|
+
said: exn.said,
|
|
156
|
+
kind,
|
|
157
|
+
group: decoded.group,
|
|
158
|
+
embedded: decoded.embedded,
|
|
159
|
+
proposer: exn.pre,
|
|
160
|
+
smids: decoded.smids,
|
|
161
|
+
rmids: decoded.rmids,
|
|
162
|
+
local: approved ? "approved" : inapplicable ? "inapplicable" : "unapproved",
|
|
163
|
+
needs: {
|
|
164
|
+
groupAlias: !approved && !inapplicable && (kind === "icp" || (kind === "rot" && !hby.habs.has(decoded.group))),
|
|
165
|
+
registryName: !approved && !inapplicable && kind === "vcp",
|
|
166
|
+
},
|
|
167
|
+
...(decoded.event ? { event: decoded.event } : {}),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/** Group prefix for a prefix or local alias. */
|
|
171
|
+
function resolveGroup(hby, group) {
|
|
172
|
+
return hby.habByName(group)?.pre ?? group;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* List the proposals the notice store announces, oldest notice first. Pure. Only
|
|
176
|
+
* wrappers that are stored, indexed in `meids.` and well formed are listed, one
|
|
177
|
+
* entry per wrapper; every notice page is read, so nothing hides behind the
|
|
178
|
+
* first 100. A dismissed proposal has no notice and is not listed; it remains
|
|
179
|
+
* available through {@link findGroupProposal}.
|
|
180
|
+
*/
|
|
181
|
+
export function listGroupProposals(deps, { group } = {}) {
|
|
182
|
+
if (!deps.notifier)
|
|
183
|
+
return [];
|
|
184
|
+
const wanted = group === undefined ? undefined : resolveGroup(deps.hby, group);
|
|
185
|
+
const proposals = [];
|
|
186
|
+
const seen = new Set();
|
|
187
|
+
for (const said of noticedWrappers(deps.notifier)) {
|
|
188
|
+
const exn = deps.hby.db.exns.get([said]);
|
|
189
|
+
const payloadSaid = exn && multisigPayloadSaid(exn);
|
|
190
|
+
if (!payloadSaid || !deps.hby.db.meids.get([payloadSaid]).some(index => index.qb64 === said))
|
|
191
|
+
continue;
|
|
192
|
+
const proposal = readProposal(deps, said);
|
|
193
|
+
if (!proposal || (wanted !== undefined && proposal.group !== wanted) || seen.has(said))
|
|
194
|
+
continue;
|
|
195
|
+
seen.add(said);
|
|
196
|
+
proposals.push(proposal);
|
|
197
|
+
}
|
|
198
|
+
return proposals;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Read one stored proposal by its wrapper SAID, whether or not a notice remains.
|
|
202
|
+
* Pure. Null when no such well-formed proposal is stored.
|
|
203
|
+
*/
|
|
204
|
+
export function findGroupProposal(deps, said) {
|
|
205
|
+
return readProposal(deps, said);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Dismiss a proposal locally: remove the notices that announce it, including
|
|
209
|
+
* those other members' wrappers of the same payload raised. The stored wrapper
|
|
210
|
+
* and the multisig index stay, so the proposal can still be found and approved
|
|
211
|
+
* by SAID. KERI has no reject message: nothing is sent, and the proposer and the
|
|
212
|
+
* other members learn nothing from a dismissal.
|
|
213
|
+
*
|
|
214
|
+
* @returns Number of notices removed.
|
|
215
|
+
*/
|
|
216
|
+
export function dismissGroupProposal(deps, said) {
|
|
217
|
+
if (!deps.notifier)
|
|
218
|
+
return 0;
|
|
219
|
+
const exn = deps.hby.db.exns.get([said]);
|
|
220
|
+
const payloadSaid = exn && multisigPayloadSaid(exn);
|
|
221
|
+
const wrappers = new Set([said]);
|
|
222
|
+
if (payloadSaid)
|
|
223
|
+
for (const index of deps.hby.db.meids.get([payloadSaid]))
|
|
224
|
+
wrappers.add(index.qb64);
|
|
225
|
+
const stale = [];
|
|
226
|
+
eachNotice(deps.notifier, ({ rid, attrs }) => {
|
|
227
|
+
if (typeof attrs.d === "string" && wrappers.has(attrs.d))
|
|
228
|
+
stale.push(rid);
|
|
229
|
+
});
|
|
230
|
+
return stale.filter(rid => deps.notifier.remove(rid)).length;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Approve one proposal, named by its wrapper SAID: sign this member's
|
|
234
|
+
* contribution to the embedded event, send it to the other members and hand the
|
|
235
|
+
* group event to the Counselor. Returns without waiting for other members; read
|
|
236
|
+
* progress with `counselor.status(result.event)`. This is the only call that
|
|
237
|
+
* signs, and it acts on exactly the SAID given: nothing is selected from the
|
|
238
|
+
* notice store, so a proposal the caller did not name cannot be approved.
|
|
239
|
+
*
|
|
240
|
+
* Calling it is the user's consent, so it never prompts. Repeating it after a
|
|
241
|
+
* crash resumes: this member's recorded signatures and stored wrapper are
|
|
242
|
+
* replayed, never replaced, and the group is not joined twice.
|
|
243
|
+
*
|
|
244
|
+
* Supports every proposal kind: KEL (`icp`, `rot`, `ixn`), reply (`rpy`), legacy registry and credential (`vcp`, `iss`, `rev`) and
|
|
245
|
+
* ACDC v2 registry (`rip`, `bup`). For the registry kinds `event` is the group anchor that seals the TEL event.
|
|
246
|
+
*
|
|
247
|
+
* @throws ValidationError for a SAID that is not a stored supported proposal, a missing `groupAlias` when the proposal {@link GroupProposal.needs} one, or a proposal that cannot be approved.
|
|
248
|
+
*/
|
|
249
|
+
export function* approveGroupProposal(deps, said, choices = {}) {
|
|
250
|
+
const { hby } = deps;
|
|
251
|
+
const proposal = findGroupProposal(deps, said);
|
|
252
|
+
const exn = hby.db.exns.get([said]);
|
|
253
|
+
if (!proposal || !exn)
|
|
254
|
+
throw new ValidationError(`No group proposal ${said} is stored.`);
|
|
255
|
+
const route = exn.route ?? "";
|
|
256
|
+
const payloadSaid = multisigPayloadSaid(exn);
|
|
257
|
+
if (!hby.db.meids.get([payloadSaid]).some(index => index.qb64 === said)) {
|
|
258
|
+
// Acceptance commits before the asynchronous handler; resume that ordinary intake.
|
|
259
|
+
const message = yield* abortable(signal => collectBytes(deps.exc.replay(said, signal)));
|
|
260
|
+
yield* deps.reactor.processBytes(message, { local: true });
|
|
261
|
+
if (!hby.db.meids.get([payloadSaid]).some(index => index.qb64 === said)) {
|
|
262
|
+
throw new ValidationError(`Group proposal ${said} is not indexed after replay.`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const options = { resume: true, groupAlias: choices.groupAlias, registryName: choices.registryName };
|
|
266
|
+
const result = isKelRoute(route)
|
|
267
|
+
? yield* approveKelProposal(hby, deps, exn, route, options)
|
|
268
|
+
: isVdrRoute(route)
|
|
269
|
+
? yield* approveVdrProposal(hby, deps.vdr, deps, exn, route, options)
|
|
270
|
+
: isV2RegistryRoute(route)
|
|
271
|
+
? yield* approveRegistryV2Proposal(hby, deps, exn, route, options)
|
|
272
|
+
: yield* approveRpyProposal(hby, deps, exn, route, options);
|
|
273
|
+
if (!result)
|
|
274
|
+
throw new ValidationError(`Group proposal ${said} cannot be approved.`);
|
|
275
|
+
const { event } = proposal;
|
|
276
|
+
if (event) {
|
|
277
|
+
const { auths, fallbackAfterMs, proxy } = choices;
|
|
278
|
+
deps.counselor.start(event, { auths, fallbackAfterMs, proxy });
|
|
279
|
+
}
|
|
280
|
+
return { ...result, ...(event ? { event } : {}) };
|
|
281
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ValidationError } from "../../core/errors.js";
|
|
2
|
+
import { revokeCredential, } from "../credentials/credential-revoking.js";
|
|
3
|
+
import { createCredential, inceptCredentialRegistry, } from "../credentials/credential-workflows.js";
|
|
4
|
+
import { groupSigningMembers, localGroupMember, uniqueMembers } from "./group-members.js";
|
|
5
|
+
import { MULTISIG_ICP_ROUTE, MULTISIG_IXN_ROUTE, MULTISIG_ROT_ROUTE } from "./grouping.js";
|
|
6
|
+
import { remoteGroupMembers } from "./multisig-messaging.js";
|
|
7
|
+
import { approveAcdcV2Registry, commitAcceptedGroupMembers, publishAcdcV2Registry, publishProposal, } from "./multisig-workflows.js";
|
|
8
|
+
/** Propose a new group: create this member's inception and publish it. */
|
|
9
|
+
export function* proposeGroupInception(deps, member, alias, { smids, rmids = smids, ...args }, inputs) {
|
|
10
|
+
// Publishing needs a route to every other member. Refuse before the group habitat exists, so a call that could
|
|
11
|
+
// not be sent leaves nothing behind and the same alias can be used again.
|
|
12
|
+
for (const other of remoteGroupMembers(deps.hby, member, uniqueMembers([...smids, ...rmids]))) {
|
|
13
|
+
if (!deps.postman.canReach(member.pre, other)) {
|
|
14
|
+
throw new ValidationError(`Group member ${other} cannot be reached: no end role is known for it. Resolve its OOBI first.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const created = deps.hby.makeGroupHab(alias, member, [...smids], [...rmids], undefined, args);
|
|
18
|
+
const event = { pre: created.hab.pre, sn: created.serder.sn ?? 0, said: created.serder.said };
|
|
19
|
+
deps.counselor.start(event, inputs);
|
|
20
|
+
const sent = yield* publishProposal(deps.hby, deps.protocol, deps.postman, member, uniqueMembers([...smids, ...rmids]), {
|
|
21
|
+
route: MULTISIG_ICP_ROUTE,
|
|
22
|
+
attrs: { smids: [...smids], rmids: [...rmids], ...(args.delpre ? { delegator: args.delpre } : {}) },
|
|
23
|
+
}, created.message);
|
|
24
|
+
return { ...sent, route: MULTISIG_ICP_ROUTE, group: created.hab.pre, event, smids, rmids };
|
|
25
|
+
}
|
|
26
|
+
/** Propose a group rotation, including member add or remove through new `smids` / `rmids`. */
|
|
27
|
+
export function* proposeGroupRotation(deps, group, { smids: newSmids, rmids: newRmids, ...args } = {}, inputs) {
|
|
28
|
+
const { hby } = deps;
|
|
29
|
+
const rotated = hby.rotateGroupHab(group.name, newSmids && [...newSmids], newRmids && [...newRmids], args);
|
|
30
|
+
const smids = newSmids?.length ? newSmids : groupSigningMembers(hby, rotated.hab.pre);
|
|
31
|
+
const rmids = newRmids?.length ? newRmids : smids;
|
|
32
|
+
const event = { pre: rotated.hab.pre, sn: rotated.serder.sn, said: rotated.serder.said };
|
|
33
|
+
deps.counselor.start(event, inputs);
|
|
34
|
+
const sent = yield* publishProposal(hby, deps.protocol, deps.postman, localGroupMember(hby, rotated.hab.pre), uniqueMembers([...smids, ...rmids]), { route: MULTISIG_ROT_ROUTE, attrs: { gid: rotated.hab.pre, smids: [...smids], rmids: [...rmids] } }, rotated.message);
|
|
35
|
+
return { ...sent, route: MULTISIG_ROT_ROUTE, group: rotated.hab.pre, event, smids, rmids };
|
|
36
|
+
}
|
|
37
|
+
/** Propose a group interaction event carrying `data`. */
|
|
38
|
+
export function* proposeGroupInteraction(deps, group, data, inputs, version) {
|
|
39
|
+
const { hby } = deps;
|
|
40
|
+
const created = hby.interactGroupHab(group.name, undefined, { data, version });
|
|
41
|
+
const smids = groupSigningMembers(hby, created.hab.pre);
|
|
42
|
+
const event = { pre: created.hab.pre, sn: created.serder.sn, said: created.serder.said };
|
|
43
|
+
deps.counselor.start(event, inputs);
|
|
44
|
+
const sent = yield* publishProposal(hby, deps.protocol, deps.postman, localGroupMember(hby, created.hab.pre), smids, { route: MULTISIG_IXN_ROUTE, attrs: { gid: created.hab.pre, smids } }, created.message);
|
|
45
|
+
return { ...sent, route: MULTISIG_IXN_ROUTE, group: created.hab.pre, event, smids, rmids: [] };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Commit the members a proposed rotation named, once the rotation is accepted and
|
|
49
|
+
* is the group's latest establishment event. Idempotent; false until then, so a
|
|
50
|
+
* proposed newcomer is never adopted early. Other event kinds commit nothing.
|
|
51
|
+
*
|
|
52
|
+
* @throws ValidationError when the event is not an accepted event body held locally.
|
|
53
|
+
*/
|
|
54
|
+
export function settleProposedRotation(deps, result) {
|
|
55
|
+
if (result.route !== MULTISIG_ROT_ROUTE)
|
|
56
|
+
return false;
|
|
57
|
+
const serder = deps.hby.db.getEvtSerder(result.event.pre, result.event.said);
|
|
58
|
+
if (!serder)
|
|
59
|
+
throw new ValidationError(`No rotation ${result.event.said} is held for ${result.event.pre}.`);
|
|
60
|
+
return commitAcceptedGroupMembers(deps.hby, serder, result.smids, result.rmids);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Propose an ACDC v2 registry event (`rip` or `bup`): author the group anchor
|
|
64
|
+
* that seals it, process this member's own contribution, hand the anchor to the
|
|
65
|
+
* Counselor and publish the proposal. The proposer's contribution is also its
|
|
66
|
+
* approval. Returns without waiting; the anchor's progress is
|
|
67
|
+
* `counselor.status(result.event)`. A `bup` needs its `opening`.
|
|
68
|
+
*
|
|
69
|
+
* @throws ValidationError for a group that is not joined and accepted, or a TEL event the group cannot propose.
|
|
70
|
+
*/
|
|
71
|
+
export function* proposeRegistryEvent(deps, group, event, opening, inputs) {
|
|
72
|
+
const { hby } = deps;
|
|
73
|
+
const approval = yield* approveAcdcV2Registry(hby, deps.protocol, group, event, { opening, resume: true });
|
|
74
|
+
const anchorSaid = approval[0].sad?.a?.anc;
|
|
75
|
+
const anchor = anchorSaid ? hby.db.getEvtSerder(group.pre, anchorSaid) : null;
|
|
76
|
+
if (!anchor || anchor.sn === null)
|
|
77
|
+
throw new ValidationError("Registry proposal lost its group anchor.");
|
|
78
|
+
const anchorRef = { pre: group.pre, sn: anchor.sn, said: anchor.said };
|
|
79
|
+
deps.counselor.start(anchorRef, inputs);
|
|
80
|
+
const sent = yield* publishAcdcV2Registry(hby, deps.postman, group, approval);
|
|
81
|
+
const regid = event.ilk === "rip" ? event.said : event.regid;
|
|
82
|
+
const accepted = deps.registryStore?.seqEvent(regid, Number(BigInt(`0x${event.sad.n}`)))?.said === event.said;
|
|
83
|
+
return {
|
|
84
|
+
route: approval[0].route,
|
|
85
|
+
said: approval[0].said,
|
|
86
|
+
embedded: event.said,
|
|
87
|
+
group: group.pre,
|
|
88
|
+
accepted,
|
|
89
|
+
...sent,
|
|
90
|
+
event: anchorRef,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function proposedGroup(result, what) {
|
|
94
|
+
if (!result.group)
|
|
95
|
+
throw new ValidationError(`${what} must be proposed by a local group.`);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Propose a group's legacy credential registry (`vcp`): author the anchoring group event,
|
|
100
|
+
* process this member's contribution, hand the anchor to the Counselor and publish the
|
|
101
|
+
* proposal. Returns without waiting; the anchor's progress is `counselor.status(result.group.event)`
|
|
102
|
+
* and the registry's is `waitForTelEvent`.
|
|
103
|
+
*
|
|
104
|
+
* @throws ValidationError when `group` is not a local group or the registry name is taken.
|
|
105
|
+
*/
|
|
106
|
+
export function* proposeCredentialRegistry(deps, group, options, inputs) {
|
|
107
|
+
const result = proposedGroup(yield* inceptCredentialRegistry(deps.rgy, deps.input, deps.postman, group, options), "A group registry");
|
|
108
|
+
deps.counselor.start(result.group.event, inputs);
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/** Propose a group credential issuance (`iss`) the way {@link proposeCredentialRegistry} proposes a registry. */
|
|
112
|
+
export function* proposeCredentialIssue(deps, options, inputs) {
|
|
113
|
+
const result = proposedGroup(yield* createCredential(deps.rgy, deps.input, deps.postman, options), "A group credential");
|
|
114
|
+
deps.counselor.start(result.group.event, inputs);
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
/** Propose a group credential revocation (`rev`) the way {@link proposeCredentialRegistry} proposes a registry. */
|
|
118
|
+
export function* proposeCredentialRevocation(deps, options, inputs) {
|
|
119
|
+
const result = proposedGroup(yield* revokeCredential(deps.rgy, deps.input, deps.postman, options), "A group revocation");
|
|
120
|
+
deps.counselor.start(result.group.event, inputs);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ValidationError } from "../../core/errors.js";
|
|
2
|
-
import {
|
|
2
|
+
import { openOwner } from "../../db/core/store-owner.js";
|
|
3
|
+
import { Noter, Notice } from "../../db/noting.js";
|
|
3
4
|
import { Signaler } from "./signaling.js";
|
|
4
5
|
export function notice(attrs, options = {}) {
|
|
5
6
|
const dt = typeof options.dt === "string"
|
|
@@ -17,19 +18,14 @@ export function notice(attrs, options = {}) {
|
|
|
17
18
|
/** Derive sidecar-open options from the owning `Habery` path/layout settings. */
|
|
18
19
|
export function noterOptionsForHabery(hby, options = {}) {
|
|
19
20
|
return {
|
|
20
|
-
|
|
21
|
-
base: hby.base,
|
|
22
|
-
temp: hby.temp,
|
|
23
|
-
headDirPath: hby.headDirPath,
|
|
24
|
-
compat: hby.compat,
|
|
25
|
-
readonly: hby.readonly,
|
|
26
|
-
reopen: true,
|
|
21
|
+
...hby.storeIdentity(),
|
|
27
22
|
...options,
|
|
28
23
|
};
|
|
29
24
|
}
|
|
30
25
|
/** Open the notification sidecar that belongs to one `Habery`. */
|
|
31
26
|
export function* openNoterForHabery(hby, options = {}) {
|
|
32
|
-
|
|
27
|
+
const identity = noterOptionsForHabery(hby, options);
|
|
28
|
+
return yield* openOwner(new Noter(hby.opener.create(Noter.Family, identity)), "Noter", identity);
|
|
33
29
|
}
|
|
34
30
|
/**
|
|
35
31
|
* Signed durable controller notifications with transient `/notification` pings.
|
|
@@ -11,7 +11,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _Signal_raw, _Signal_pad, _Signal_ckey;
|
|
13
13
|
import { MtrDex, Salter } from "cesr-ts";
|
|
14
|
-
import {
|
|
14
|
+
import { doEvery, PROTOCOL_PACING } from "../runtime/doing.js";
|
|
15
|
+
import { systemClock } from "../runtime/runtime-clock.js";
|
|
15
16
|
const textEncoder = new TextEncoder();
|
|
16
17
|
const textDecoder = new TextDecoder();
|
|
17
18
|
function randomNonce() {
|
|
@@ -162,11 +163,10 @@ export class Signaler {
|
|
|
162
163
|
this.closed = true;
|
|
163
164
|
this.clear();
|
|
164
165
|
}
|
|
165
|
-
*signalDo() {
|
|
166
|
-
|
|
166
|
+
*signalDo(clock = systemClock, pacing = PROTOCOL_PACING) {
|
|
167
|
+
return yield* doEvery(clock, pacing.tockMs, function* () {
|
|
167
168
|
this.processOnce();
|
|
168
|
-
|
|
169
|
-
}
|
|
169
|
+
}.bind(this));
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
Object.defineProperty(Signaler, "SignalTimeoutMs", {
|
|
@@ -144,7 +144,7 @@ function* dispatchMessage(envelope, revery, kevery, exchanger, tevery, mailboxAi
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
if (serder.ilk === "qry" && !["logs", "ksn", "mbx", "tels", "tsn"].includes(serder.route ?? "")
|
|
147
|
-
&& qvy?.resource
|
|
147
|
+
&& !(qvy?.claims ? qvy.claims(serder) : qvy?.resource === serder.route)) {
|
|
148
148
|
return { envelope, decision: { kind: "drop", reason: "missingProcessor" } };
|
|
149
149
|
}
|
|
150
150
|
const result = kevery.kramer?.intake(envelope);
|
|
@@ -487,6 +487,31 @@ export function copyAuxiliaryQuery(envelope) {
|
|
|
487
487
|
copied.tsgs.splice(0, copied.tsgs.length, ...normalized.tsgs);
|
|
488
488
|
return copied;
|
|
489
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Serialize an auxiliary query without nested evidence so a later process can rebuild it: its own frame with
|
|
492
|
+
* every attachment group (plus `children`, nested evidence already encoded as counted frames), then the
|
|
493
|
+
* normalized proof KRAM may have completed from earlier inputs.
|
|
494
|
+
*/
|
|
495
|
+
export function auxiliaryQueryWire(envelope, children = []) {
|
|
496
|
+
const version = envelope.gvrsn ?? envelope.serder.gvrsn ?? envelope.serder.pvrsn;
|
|
497
|
+
const frame = concatBytes(Counter.makeGVC(version), envelope.serder.raw, Counter.enclose({
|
|
498
|
+
code: "AttachmentGroup",
|
|
499
|
+
version,
|
|
500
|
+
qb64: concatBytes(...envelope.attachmentGroups.map(group => group.raw), ...children),
|
|
501
|
+
}));
|
|
502
|
+
const proof = serializeMessage(envelope.serder, { tsgs: envelope.tsgs, gvrsn: version, genusify: true });
|
|
503
|
+
const size = new Uint8Array(4);
|
|
504
|
+
new DataView(size.buffer).setUint32(0, frame.length);
|
|
505
|
+
return concatBytes(size, frame, proof);
|
|
506
|
+
}
|
|
507
|
+
/** Rebuild the envelope {@link auxiliaryQueryWire} serialized. */
|
|
508
|
+
export function restoreAuxiliaryQuery(wire, local = false) {
|
|
509
|
+
const length = new DataView(wire.buffer, wire.byteOffset, 4).getUint32(0);
|
|
510
|
+
const restored = envelopeFromFrame(parseBytes(wire.slice(4, 4 + length))[0], local);
|
|
511
|
+
const normalized = envelopeFromFrame(parseBytes(wire.slice(4 + length))[0]);
|
|
512
|
+
restored.tsgs.splice(0, restored.tsgs.length, ...normalized.tsgs);
|
|
513
|
+
return restored;
|
|
514
|
+
}
|
|
490
515
|
/** Normalize the actual query endorsements for ingress and per-request authorization. */
|
|
491
516
|
export function queryEnvelopeFromDispatch(envelope) {
|
|
492
517
|
const lastSsg = envelope.ssgs.at(-1);
|
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { call } from "effection";
|
|
2
2
|
import { Deck } from "../../core/deck.js";
|
|
3
|
+
import { ValidationError } from "../../core/errors.js";
|
|
3
4
|
import { Kevery } from "../../core/kel/eventing.js";
|
|
5
|
+
import { consoleLogger } from "../../core/logger.js";
|
|
4
6
|
import { BasicReplyRouteHandler, Revery } from "../../core/routing.js";
|
|
5
7
|
import { Exchanger } from "../exchanges/exchanging.js";
|
|
6
8
|
import { QueryReplies } from "../queries/query-replies.js";
|
|
7
|
-
import {
|
|
9
|
+
import { systemClock } from "../runtime/runtime-clock.js";
|
|
10
|
+
import { waitOnClock } from "../runtime/workflow-contract.js";
|
|
8
11
|
import { dispatchEnvelope, envelopeFromFrame, queryEnvelopeFromDispatch, } from "./parsering.js";
|
|
12
|
+
/**
|
|
13
|
+
* Wait after every escrow pass, as KERIpy's Doist cycle (`tock` 0.03125 s, app/directing.py) paces its `escrowDo`,
|
|
14
|
+
* which runs one full pass per cycle. A pass is never skipped or shortened; this is the time others get between passes.
|
|
15
|
+
*/
|
|
16
|
+
export const ESCROW_TOCK_MS = 31.25;
|
|
17
|
+
/**
|
|
18
|
+
* Identify a refusal of one already-extracted message, which must not end its stream.
|
|
19
|
+
*
|
|
20
|
+
* KERIpy's parser resumes after any non-extraction exception. This is deliberately narrower:
|
|
21
|
+
* infrastructure failures, programmer errors and cancellation must still reach the input owner.
|
|
22
|
+
* A dispatch-side ParserError also propagates, because it indicates corrupt local state and
|
|
23
|
+
* skipping would advance a mailbox cursor past a message that was never processed.
|
|
24
|
+
*/
|
|
25
|
+
function isInvalidMessageError(error) {
|
|
26
|
+
return error instanceof ValidationError;
|
|
27
|
+
}
|
|
9
28
|
/**
|
|
10
29
|
* Dispatch to synchronous semantic owners and publish their committed output.
|
|
11
30
|
*
|
|
@@ -140,6 +159,8 @@ export class ProtocolProcessor {
|
|
|
140
159
|
* @param options Local intake policy, hosted mailbox provenance and whether to advance escrows.
|
|
141
160
|
* @param kvy Input-specific Kevery in this domain; defaults to the shared owner.
|
|
142
161
|
* @returns Exact dispatch result and current mailbox authorization at its synchronous query decision.
|
|
162
|
+
* A message refused by validation after extraction is an `invalidMessage` drop, so the caller
|
|
163
|
+
* continues with the next frame as KERIpy's parser does.
|
|
143
164
|
* @throws Domain mismatch, infrastructure/handler or cleanup errors propagate; publication still runs in the dispatch finalizer.
|
|
144
165
|
*/
|
|
145
166
|
dispatch(frame, { local = this.kvy.local, mailboxAid, escrows = false } = {}, kvy = this.kvy) {
|
|
@@ -151,9 +172,26 @@ export class ProtocolProcessor {
|
|
|
151
172
|
const self = this;
|
|
152
173
|
return call(function* () {
|
|
153
174
|
try {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
175
|
+
const envelope = envelopeFromFrame(frame, local);
|
|
176
|
+
let result;
|
|
177
|
+
let invalid = false;
|
|
178
|
+
try {
|
|
179
|
+
result = yield* dispatchEnvelope(envelope, self.rvy, kvy, self.exc, self.tvy ?? undefined, self.vry ?? undefined, mailboxAid, self.kvy, // One authoritative v2 sender policy and KRAM intake across all inputs.
|
|
180
|
+
self.registry ?? undefined, self.qvy);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (!isInvalidMessageError(error))
|
|
184
|
+
throw error;
|
|
185
|
+
invalid = true;
|
|
186
|
+
consoleLogger.warn("Skipping invalid message", {
|
|
187
|
+
said: envelope.serder.said,
|
|
188
|
+
ilk: envelope.serder.ilk,
|
|
189
|
+
route: envelope.serder.route,
|
|
190
|
+
detail: error.message,
|
|
191
|
+
});
|
|
192
|
+
result = { envelope, decision: { kind: "drop", reason: "invalidMessage", detail: error.message } };
|
|
193
|
+
}
|
|
194
|
+
const mailboxQueryAuthorized = !invalid && result.envelope.serder.route === "mbx"
|
|
157
195
|
&& kvy.isMailboxQueryAuthorized(queryEnvelopeFromDispatch(result.envelope));
|
|
158
196
|
// Capture this request's facts before optional escrows can suspend or change key state.
|
|
159
197
|
self.publishCues();
|
|
@@ -223,10 +261,10 @@ export class ProtocolProcessor {
|
|
|
223
261
|
* - mirrors the dedicated `escrowDo` loop rather than folding escrow
|
|
224
262
|
* processing into parser ingress
|
|
225
263
|
*/
|
|
226
|
-
*escrowDo() {
|
|
264
|
+
*escrowDo(clock = systemClock) {
|
|
227
265
|
while (true) {
|
|
228
266
|
yield* this.processEscrowsOnce();
|
|
229
|
-
yield*
|
|
267
|
+
yield* waitOnClock(clock, ESCROW_TOCK_MS);
|
|
230
268
|
}
|
|
231
269
|
}
|
|
232
270
|
}
|