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
package/README.md
CHANGED
|
@@ -13,9 +13,20 @@ npm install keri-ts
|
|
|
13
13
|
|
|
14
14
|
- default import: browser-safe core/types surface
|
|
15
15
|
- `keri-ts/runtime`: explicit non-browser-safe runtime surface
|
|
16
|
-
- `keri-ts/db`:
|
|
16
|
+
- `keri-ts/db`: backend-neutral storage surface
|
|
17
|
+
- `keri-ts/db/lmdb`: native LMDB storage backend
|
|
18
|
+
- `keri-ts/db/indexeddb`: browser IndexedDB storage backend (`indexedDbOpener`).
|
|
19
|
+
The opener is single-writer by default: its first store takes a Web Locks lock per
|
|
20
|
+
store identity (`base`, `name`, `temp`), shared by every family it creates and
|
|
21
|
+
released when the last closes. A second opener or tab gets `StoreLockHeldError`,
|
|
22
|
+
and an engine without `navigator.locks` gets `StoreLockUnsupportedError`. Pass
|
|
23
|
+
`unsafeSkipStoreLock: true` only when another mechanism serializes writers (for
|
|
24
|
+
example a SharedWorker owner); `locks` injects a lock manager for tests
|
|
25
|
+
- `keri-ts/runtime/web`: browser host concerns (`barrierHttpClient` output barrier,
|
|
26
|
+
`acquireStoreLock` and `storeLockKey` for hosts that compose stores themselves,
|
|
27
|
+
`requestPersistentStorage`)
|
|
17
28
|
|
|
18
|
-
|
|
29
|
+
These entrypoints are the general library surfaces. `keri-ts/cli` is the
|
|
19
30
|
separate command-helper boundary used by Tufa. Runnable CLI/server ownership
|
|
20
31
|
lives in `@keri-ts/tufa`.
|
|
21
32
|
|
|
@@ -25,6 +36,23 @@ implementation-module exports do not automatically become package API. npm deep
|
|
|
25
36
|
imports such as `keri-ts/app/...` and `keri-ts/core/...` are not supported. Import
|
|
26
37
|
runtime operations from `keri-ts/runtime` and storage from `keri-ts/db`.
|
|
27
38
|
|
|
39
|
+
## Browser bundles
|
|
40
|
+
|
|
41
|
+
`keri-ts`, `keri-ts/runtime`, `keri-ts/runtime/web`, `keri-ts/db` and
|
|
42
|
+
`keri-ts/db/indexeddb` carry a
|
|
43
|
+
`browser` export condition that resolves to a build of the same entrypoint
|
|
44
|
+
without the Node polyfill import, so bundlers targeting the browser reach no
|
|
45
|
+
`node:` module. `keri-ts/cli`, `keri-ts/db/lmdb` and `keri-ts/runtime/node` are
|
|
46
|
+
Node-only and have no `browser` condition. The `import` and `types` targets are
|
|
47
|
+
unchanged.
|
|
48
|
+
|
|
49
|
+
The graph includes `cesr-ts`, which uses a top-level `await` to instantiate its
|
|
50
|
+
Argon2 WebAssembly, so bundle as ESM targeting ES2022 or later. See the
|
|
51
|
+
`cesr-ts` README for the Content Security Policy note.
|
|
52
|
+
|
|
53
|
+
esbuild also fails on `effection`'s `main()` runner, which lazily imports
|
|
54
|
+
`node:process`; mark `node:process` external. Vite and webpack need nothing.
|
|
55
|
+
|
|
28
56
|
## Maintainer Docs
|
|
29
57
|
|
|
30
58
|
- `docs/ARCHITECTURE_MAP.md`: package and module ownership map
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finite ACDC v2 registry authoring: stage, anchor and update protocol cores.
|
|
3
|
+
*
|
|
4
|
+
* Existing engines own acceptance and receipt authentication; this class only
|
|
5
|
+
* sequences them for one local individual issuer. It reads and writes no
|
|
6
|
+
* credential inventory: embedders that keep issued or held records wrap it
|
|
7
|
+
* (the wallet's `WalletAuthor` adds `issue` and `revoke`). Private derivation
|
|
8
|
+
* requires a `RegistryCustody`, whose coordinate store the embedder supplies.
|
|
9
|
+
*/
|
|
10
|
+
import { bytesEqual, makeBlindState } from "cesr-ts";
|
|
11
|
+
import { isLocalGroupHab } from "../app/multisig/group-members.js";
|
|
12
|
+
import { ValidationError } from "../core/errors.js";
|
|
13
|
+
import { acdcmap, blindate } from "./messaging.js";
|
|
14
|
+
import { matchesRegistrySeal } from "./regeventing.js";
|
|
15
|
+
import { validateSchema as validateAcdcSchema } from "./scheming.js";
|
|
16
|
+
/** Borrow the actual registry environment and receipt collector; acquire no handles or workers. */
|
|
17
|
+
export class RegistryAuthor {
|
|
18
|
+
constructor(rgy, receiptor, custody) {
|
|
19
|
+
Object.defineProperty(this, "rgy", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: rgy
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "receiptor", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: receiptor
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(this, "custody", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
writable: true,
|
|
35
|
+
value: custody
|
|
36
|
+
});
|
|
37
|
+
if (receiptor.hby !== rgy.hby) {
|
|
38
|
+
throw new ValidationError("Authoring requires the registry environment's actual receipt owner.");
|
|
39
|
+
}
|
|
40
|
+
if (custody && (custody.options.hby !== rgy.hby || custody.options.registry.baser !== rgy.baser)) {
|
|
41
|
+
throw new ValidationError("Authoring custody must use this registry environment's actual owners.");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Resolve the actual local registry; staging supports groups while signing methods enforce their owner. */
|
|
45
|
+
registry(name, controller) {
|
|
46
|
+
const registry = this.rgy.registryByName(name);
|
|
47
|
+
if (!registry || registry.hab.pre !== controller) {
|
|
48
|
+
throw new ValidationError("Unknown registry or different controller.");
|
|
49
|
+
}
|
|
50
|
+
return registry;
|
|
51
|
+
}
|
|
52
|
+
/** Signing belongs either to this individual owner or to explicit group approval, never a staging flag. */
|
|
53
|
+
individual(reg) {
|
|
54
|
+
if (isLocalGroupHab(this.rgy.hby, reg.hab)) {
|
|
55
|
+
throw new ValidationError("ACDC v2 group authoring requires member approval.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Idempotently stage an alias, then return only its exact accepted inception. */
|
|
59
|
+
*incept(name, controller, auths) {
|
|
60
|
+
const hab = this.rgy.hby.habs.get(controller);
|
|
61
|
+
if (!hab || isLocalGroupHab(this.rgy.hby, hab)) {
|
|
62
|
+
throw new ValidationError("ACDC v2 inception requires a local individual controller.");
|
|
63
|
+
}
|
|
64
|
+
const reg = this.rgy.registryByName(name) ?? this.rgy.makeRegistry(name, controller);
|
|
65
|
+
this.registry(name, controller);
|
|
66
|
+
const event = reg.store.event(reg.regk);
|
|
67
|
+
yield* this.anchor(reg, event, auths);
|
|
68
|
+
return event;
|
|
69
|
+
}
|
|
70
|
+
/** Construct the issuer's credential using the existing ACDC v2 finite builder. */
|
|
71
|
+
create(reg, options) {
|
|
72
|
+
this.registry(reg.name, reg.hab.pre);
|
|
73
|
+
return acdcmap(reg.hab.pre, { ...options, regid: reg.regk });
|
|
74
|
+
}
|
|
75
|
+
/** Stage one BUP state advance, preserving an exact pending retry and its opening. Never author historical upd. */
|
|
76
|
+
stage(reg, acdc, state, options = {}) {
|
|
77
|
+
return this.stageState(reg, acdc, state, options);
|
|
78
|
+
}
|
|
79
|
+
/** Share validation and exact pending-next reuse; only the concrete revocation ensure operation can reuse an accepted head. */
|
|
80
|
+
stageState(reg, acdc, state, options, ensureRevoked = false) {
|
|
81
|
+
this.registry(reg.name, acdc.issuer);
|
|
82
|
+
if (!acdc.verify() || acdc.regid !== reg.regk) {
|
|
83
|
+
throw new ValidationError("Credential does not match this registry.");
|
|
84
|
+
}
|
|
85
|
+
const schema = validateAcdcSchema(acdc, this.rgy.hby.db);
|
|
86
|
+
if (schema.kind !== "valid") {
|
|
87
|
+
throw new ValidationError(schema.kind === "missing" ? `Missing ACDC schema: ${schema.said}` : schema.reason);
|
|
88
|
+
}
|
|
89
|
+
const head = reg.store.headEvent(reg.regk);
|
|
90
|
+
if (!head || head.ilk === "upd")
|
|
91
|
+
throw new ValidationError("An accepted ACDC v2 registry head is required.");
|
|
92
|
+
if (options.public && options.boundEvent) {
|
|
93
|
+
throw new ValidationError("Public opening cannot use private bound coordinates.");
|
|
94
|
+
}
|
|
95
|
+
if (!options.public && !this.custody) {
|
|
96
|
+
throw new ValidationError("Derived authoring requires provisioned registry custody.");
|
|
97
|
+
}
|
|
98
|
+
if (!options.public && this.custody.options.hab !== reg.hab) {
|
|
99
|
+
throw new ValidationError("Derived authoring requires the registry habitat's custody.");
|
|
100
|
+
}
|
|
101
|
+
const sn = Number(BigInt(`0x${head.sad.n}`));
|
|
102
|
+
if (!Number.isSafeInteger(sn + 1))
|
|
103
|
+
throw new ValidationError("Registry ordinal is not representable.");
|
|
104
|
+
let bound;
|
|
105
|
+
if (options.boundEvent) {
|
|
106
|
+
const issuee = acdc.issuee, db = this.rgy.hby.db;
|
|
107
|
+
const event = issuee ? db.getEvtSerder(issuee, options.boundEvent) : null;
|
|
108
|
+
if (!event || event.sn === null || !Number.isSafeInteger(event.sn)
|
|
109
|
+
|| db.kels.getLast(issuee, event.sn) !== event.said || !db.fullyWitnessed(event)) {
|
|
110
|
+
throw new ValidationError("Bound update requires an exact accepted witnessed Issuee event.");
|
|
111
|
+
}
|
|
112
|
+
bound = { bsn: event.sn, bd: event.said };
|
|
113
|
+
}
|
|
114
|
+
const derive = (ordinal) => options.public
|
|
115
|
+
? makeBlindState({ sn: ordinal, acdc: acdc.said, state })
|
|
116
|
+
: this.custody.derive(reg.regk, ordinal, acdc.said, state, bound ? { bound: true, ...bound } : {});
|
|
117
|
+
const matches = (event, opening) => event.ilk === "bup" && event.sad.b === opening.d.nonce && opening.td.nonce === acdc.said
|
|
118
|
+
&& opening.ts.label === state;
|
|
119
|
+
const pending = [...reg.store.baser.evts.getTopItemIter()].map(([, event]) => event).filter((event) => event.regid === reg.regk && event.sad.n === (sn + 1).toString(16));
|
|
120
|
+
if (pending.length) {
|
|
121
|
+
const event = pending[0], opening = options.public ? reg.store.publicOpening(event.said) : derive(sn + 1);
|
|
122
|
+
if (pending.length !== 1 || !opening || !matches(event, opening) || event.sad.p !== head.said) {
|
|
123
|
+
throw new ValidationError("Registry has a different pending update.");
|
|
124
|
+
}
|
|
125
|
+
if (!options.public)
|
|
126
|
+
this.custody.retainDerivedUpdate(event, opening);
|
|
127
|
+
return { event, opening };
|
|
128
|
+
}
|
|
129
|
+
if (ensureRevoked && sn && head.ilk === "bup") {
|
|
130
|
+
const published = reg.store.publicOpening(head.said);
|
|
131
|
+
const opening = options.public ? published : derive(sn);
|
|
132
|
+
if (opening && matches(head, opening) && (!options.public || published)) {
|
|
133
|
+
if (!options.public)
|
|
134
|
+
this.custody.retainDerivedUpdate(head, opening);
|
|
135
|
+
return { event: head, opening };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (bound && this.rgy.hby.db.getKever(acdc.issuee)?.serder.said !== bound.bd) {
|
|
139
|
+
throw new ValidationError("New bound update must reference the known current Issuee event.");
|
|
140
|
+
}
|
|
141
|
+
const opening = derive(sn + 1), event = blindate(reg.regk, head.said, opening.d.nonce, { sn: sn + 1, stamp: options.stamp });
|
|
142
|
+
if (!options.public)
|
|
143
|
+
this.custody.retainDerivedUpdate(event, opening);
|
|
144
|
+
reg.store.baser.transaction(() => {
|
|
145
|
+
reg.store.putEvent(event);
|
|
146
|
+
if (options.public)
|
|
147
|
+
reg.store.retainOpening(event, opening);
|
|
148
|
+
const decision = reg.processEvent(event);
|
|
149
|
+
if (decision.kind === "reject")
|
|
150
|
+
throw new ValidationError(`Registry update rejected: ${decision.reason}`);
|
|
151
|
+
});
|
|
152
|
+
return { event, opening };
|
|
153
|
+
}
|
|
154
|
+
/** Advance one explicit state through real anchoring; staging is never reported as accepted. */
|
|
155
|
+
*update(reg, acdc, state, options = {}) {
|
|
156
|
+
this.individual(reg);
|
|
157
|
+
const { event } = this.stage(reg, acdc, state, options);
|
|
158
|
+
yield* this.anchor(reg, event, options.auths);
|
|
159
|
+
return event;
|
|
160
|
+
}
|
|
161
|
+
/** Reuse the current branch's already signed seal even before receipts; no extra anchor merely to poll. */
|
|
162
|
+
*anchor(reg, event, auths) {
|
|
163
|
+
this.registry(reg.name, reg.hab.pre);
|
|
164
|
+
this.individual(reg);
|
|
165
|
+
const ordinal = Number(BigInt(`0x${event.sad.n}`));
|
|
166
|
+
const accepted = reg.store.seqEvent(reg.regk, ordinal);
|
|
167
|
+
if (accepted && bytesEqual(accepted.raw, event.raw))
|
|
168
|
+
return;
|
|
169
|
+
const hab = reg.hab;
|
|
170
|
+
let current = hab.kever.serder, anchor = null;
|
|
171
|
+
while (current) {
|
|
172
|
+
if (current.seals.some((seal) => matchesRegistrySeal(seal, event)))
|
|
173
|
+
anchor = current;
|
|
174
|
+
const prior = current.prior ? hab.db.getEvtSerder(hab.pre, current.prior) : null;
|
|
175
|
+
if (!prior || prior.sn !== current.sn - 1)
|
|
176
|
+
break;
|
|
177
|
+
current = prior;
|
|
178
|
+
}
|
|
179
|
+
if (!anchor) {
|
|
180
|
+
const data = [{ i: reg.regk, s: event.sad.n, d: event.said }];
|
|
181
|
+
if (hab.kever.estOnly)
|
|
182
|
+
hab.rotate({ data });
|
|
183
|
+
else
|
|
184
|
+
hab.interact({ data });
|
|
185
|
+
anchor = hab.kever.serder;
|
|
186
|
+
}
|
|
187
|
+
yield* this.receiptor.receipt(hab.pre, { sn: anchor.sn, allowTcp: true, auths });
|
|
188
|
+
this.rgy.hby.kevery.processEscrows();
|
|
189
|
+
reg.processEscrows();
|
|
190
|
+
const exact = reg.store.seqEvent(reg.regk, ordinal);
|
|
191
|
+
if (!exact || !bytesEqual(exact.raw, event.raw)) {
|
|
192
|
+
throw new ValidationError("ACDC v2 registry event remains pending authenticated anchor receipts.");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Read-only ACDC chaining over caller-owned node verdicts; authentication and application state policy stay separate.
|
|
3
|
+
*
|
|
4
|
+
* KERIpy correspondence: the graph walk and Edge evaluation of upstream PR 1757's
|
|
5
|
+
* `acdc.evaluating.EdgeEvaluator`. keri-ts keeps a functional seam: protocols
|
|
6
|
+
* (IPEX) own node authentication and frame admission, then call `walkAcdcGraph`
|
|
7
|
+
* and `evaluateChain` without this module knowing any disclosure protocol.
|
|
8
|
+
*/
|
|
2
9
|
import { ParserError, Saider } from "cesr-ts";
|
|
3
10
|
import { ValidationError } from "../core/errors.js";
|
|
11
|
+
import { delegationAncestry } from "../core/kel/delegation-ancestry.js";
|
|
4
12
|
import { Schemer } from "../core/scheming.js";
|
|
5
|
-
import { delegationRelation } from "./relating.js";
|
|
6
13
|
import { validateSchema } from "./scheming.js";
|
|
7
|
-
/**
|
|
14
|
+
/** Every Grant-side caller defaults to `open`, matching KERIpy's Grant walk default. */
|
|
15
|
+
export const DEFAULT_GRANT_WALK = "open";
|
|
16
|
+
/** Reserved Edge-group labels include a pin at every level. The top-level Edge Section additionally forbids `w`. */
|
|
8
17
|
export const acdcGroupLabels = new Set(["d", "u", "s", "o", "w"]);
|
|
9
18
|
const leafLabels = new Set([...acdcGroupLabels, "n"]);
|
|
10
|
-
const unary = new Set(["I2I", "NI2I", "DI2I", "E1E", "NOT"]);
|
|
19
|
+
const unary = new Set(["I2I", "NI2I", "DI2I", "E1E", "I1I", "DI1I", "NOT"]);
|
|
20
|
+
/** Latest-wins issuer-to-issuee group. */
|
|
11
21
|
const delegative = new Set(["I2I", "NI2I", "DI2I"]);
|
|
12
|
-
|
|
22
|
+
/** Latest-wins issuer-to-issuer group, independent of the delegative group; E1E composes with both. */
|
|
23
|
+
const issuerIdentity = new Set(["I1I", "DI1I"]);
|
|
24
|
+
/** Any explicit relation suppresses the implicit I2I/NI2I default. */
|
|
25
|
+
const suppressDefault = new Set([...delegative, "E1E", ...issuerIdentity]);
|
|
13
26
|
/** SAD maps exclude scalar/array edge representations. */
|
|
14
27
|
function record(value) {
|
|
15
28
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
16
29
|
}
|
|
17
|
-
/**
|
|
18
|
-
export function acdcEdgeBlocks(value) {
|
|
19
|
-
if (!value || (Array.isArray(value) && !value.length) || (record(value) && !Object.keys(value).length))
|
|
20
|
-
return [];
|
|
21
|
-
if (record(value))
|
|
22
|
-
return [value];
|
|
23
|
-
return Array.isArray(value) && value.every(record) ? value : null;
|
|
24
|
-
}
|
|
25
|
-
/** Only canonical qualified digests identify expanded leaf targets and schema pins. */
|
|
30
|
+
/** Only canonical qualified digests identify expanded leaf targets, compact commitments and schema pins. */
|
|
26
31
|
function said(value) {
|
|
27
32
|
if (typeof value !== "string")
|
|
28
33
|
return false;
|
|
@@ -33,12 +38,116 @@ function said(value) {
|
|
|
33
38
|
return false;
|
|
34
39
|
}
|
|
35
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Classify a node's `e` field; null is malformed.
|
|
43
|
+
* Lists, falsy non-map values, non-SAID strings and a top-level `n` or `w` are
|
|
44
|
+
* malformed. A compact SAID is a valid opaque terminal that names no far nodes.
|
|
45
|
+
*/
|
|
46
|
+
export function acdcEdgeSection(sad) {
|
|
47
|
+
if (!Object.hasOwn(sad, "e"))
|
|
48
|
+
return { kind: "none" };
|
|
49
|
+
const value = sad.e;
|
|
50
|
+
if (record(value)) {
|
|
51
|
+
if (!Object.keys(value).length)
|
|
52
|
+
return { kind: "none" };
|
|
53
|
+
// The Edge Section is itself an Edge-group, never a leaf, and carries no weight.
|
|
54
|
+
if (Object.hasOwn(value, "n") || Object.hasOwn(value, "w"))
|
|
55
|
+
return null;
|
|
56
|
+
return { kind: "expanded", section: value };
|
|
57
|
+
}
|
|
58
|
+
return said(value) ? { kind: "compact", said: value } : null;
|
|
59
|
+
}
|
|
36
60
|
/** Compact Edge strings name blocks, never far ACDCs. Expanded leaves have exact labels. */
|
|
37
61
|
export function acdcEdgeTarget(value) {
|
|
38
62
|
if (!record(value) || !Object.hasOwn(value, "n"))
|
|
39
63
|
return null;
|
|
40
64
|
return Object.keys(value).every((label) => leafLabels.has(label)) && said(value.n) ? value.n : false;
|
|
41
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Walk a disclosed graph of credential views from `origin` in BFS order.
|
|
68
|
+
*
|
|
69
|
+
* Every view must verify (including its carried section SAIDs) under its own
|
|
70
|
+
* SAID key, every Edge Section must be well shaped, every disclosed node must be
|
|
71
|
+
* reachable and the reachable graph must be acyclic. Closed walks also require
|
|
72
|
+
* every expanded leaf target to be disclosed; open walks skip undisclosed ones
|
|
73
|
+
* (see `AcdcWalkPolicy`).
|
|
74
|
+
* Compact Edge Sections and compact Edge members are opaque terminals.
|
|
75
|
+
* Protocol frame admission (ilks, nests, duplicates) belongs to the caller.
|
|
76
|
+
*/
|
|
77
|
+
export function walkAcdcGraph(origin, nodes, walk) {
|
|
78
|
+
for (const [id, { body }] of nodes)
|
|
79
|
+
if (body.said !== id || !body.verify())
|
|
80
|
+
return null;
|
|
81
|
+
if (!nodes.has(origin))
|
|
82
|
+
return null;
|
|
83
|
+
const seen = new Set();
|
|
84
|
+
const order = [];
|
|
85
|
+
const dependencies = new Map();
|
|
86
|
+
const queue = [origin];
|
|
87
|
+
for (let index = 0; index < queue.length; index++) {
|
|
88
|
+
const id = queue[index];
|
|
89
|
+
if (seen.has(id))
|
|
90
|
+
continue;
|
|
91
|
+
seen.add(id);
|
|
92
|
+
order.push(id);
|
|
93
|
+
const farNodes = new Set();
|
|
94
|
+
dependencies.set(id, farNodes);
|
|
95
|
+
const section = acdcEdgeSection(nodes.get(id).body.sad);
|
|
96
|
+
if (!section)
|
|
97
|
+
return null;
|
|
98
|
+
if (section.kind !== "expanded")
|
|
99
|
+
continue;
|
|
100
|
+
const groups = [section.section];
|
|
101
|
+
for (let g = 0; g < groups.length; g++) {
|
|
102
|
+
for (const [label, member] of Object.entries(groups[g])) {
|
|
103
|
+
if (acdcGroupLabels.has(label))
|
|
104
|
+
continue;
|
|
105
|
+
if (typeof member === "string") {
|
|
106
|
+
if (!said(member))
|
|
107
|
+
return null;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const target = acdcEdgeTarget(member);
|
|
111
|
+
if (target === false)
|
|
112
|
+
return null;
|
|
113
|
+
if (target === null) {
|
|
114
|
+
if (!record(member))
|
|
115
|
+
return null;
|
|
116
|
+
groups.push(member);
|
|
117
|
+
}
|
|
118
|
+
else if (!nodes.has(target)) {
|
|
119
|
+
if (walk === "closed")
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
farNodes.add(target);
|
|
124
|
+
if (!seen.has(target))
|
|
125
|
+
queue.push(target);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (seen.size !== nodes.size)
|
|
131
|
+
return null;
|
|
132
|
+
const parents = new Map();
|
|
133
|
+
for (const [near, children] of dependencies) {
|
|
134
|
+
for (const far of children) {
|
|
135
|
+
if (!parents.has(far))
|
|
136
|
+
parents.set(far, new Set());
|
|
137
|
+
parents.get(far).add(near);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const dependencyOrder = order.filter((id) => dependencies.get(id).size === 0);
|
|
141
|
+
for (let i = 0; i < dependencyOrder.length; i++) {
|
|
142
|
+
for (const near of parents.get(dependencyOrder[i]) ?? []) {
|
|
143
|
+
const children = dependencies.get(near);
|
|
144
|
+
children.delete(dependencyOrder[i]);
|
|
145
|
+
if (!children.size)
|
|
146
|
+
dependencyOrder.push(near);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return dependencyOrder.length === nodes.size ? order : null;
|
|
150
|
+
}
|
|
42
151
|
/** Missing proof/pin dependencies retain their ordered schema causes for the existing escrow owner. */
|
|
43
152
|
function unknown(reason, retryable = false, schemas = []) {
|
|
44
153
|
return { kind: "unknown", reason, retryable, schemas };
|
|
@@ -54,11 +163,64 @@ function reduce(op, members) {
|
|
|
54
163
|
}
|
|
55
164
|
return { kind: op === "AND" ? "valid" : "invalid" };
|
|
56
165
|
}
|
|
166
|
+
/** Accepted delegation ancestry is the only evidence beyond the two ACDCs; missing KEL evidence can still arrive. */
|
|
167
|
+
function delegatedFrom(db, op, pre, ancestor) {
|
|
168
|
+
const ancestry = delegationAncestry(db, pre, ancestor);
|
|
169
|
+
if (ancestry.kind === "valid")
|
|
170
|
+
return { kind: "valid" };
|
|
171
|
+
if (ancestry.kind === "refused")
|
|
172
|
+
return { kind: "invalid" };
|
|
173
|
+
return unknown(`${op} delegation evidence: ${ancestry.reason}`, true);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Evaluate the unary relations of one leaf between its near and far ACDCs.
|
|
177
|
+
*
|
|
178
|
+
* Unrecognized tokens and the unimplemented NOT are non-retryable unknowns that
|
|
179
|
+
* are ANDed with, not substituted for, the recognized relations. Absent any
|
|
180
|
+
* explicit relation, I2I applies when the far node has an issuee, else NI2I.
|
|
181
|
+
* The delegative and issuer-identity groups are each latest-wins.
|
|
182
|
+
*/
|
|
183
|
+
function leafRelation(db, ops, near, far) {
|
|
184
|
+
const relations = [];
|
|
185
|
+
const unrecognized = ops.filter((token) => !unary.has(token));
|
|
186
|
+
if (unrecognized.length)
|
|
187
|
+
relations.push(unknown(`Unrecognized unary Edge operator ${unrecognized.join(", ")}.`));
|
|
188
|
+
if (ops.includes("NOT"))
|
|
189
|
+
relations.push(unknown("Unimplemented unary Edge operator NOT."));
|
|
190
|
+
const operators = [...ops];
|
|
191
|
+
if (!operators.some((token) => suppressDefault.has(token)))
|
|
192
|
+
operators.push(far.issuee !== null ? "I2I" : "NI2I");
|
|
193
|
+
const delegate = operators.findLast((token) => delegative.has(token));
|
|
194
|
+
const identity = operators.findLast((token) => issuerIdentity.has(token));
|
|
195
|
+
const truth = (value) => ({ kind: value ? "valid" : "invalid" });
|
|
196
|
+
if (operators.includes("E1E")) {
|
|
197
|
+
relations.push(truth(Boolean(near.issuee && far.issuee && near.issuee === far.issuee)));
|
|
198
|
+
}
|
|
199
|
+
if (delegate === "I2I")
|
|
200
|
+
relations.push(truth(Boolean(far.issuee && near.issuer === far.issuee)));
|
|
201
|
+
if (delegate === "DI2I") {
|
|
202
|
+
if (!near.issuer || !far.issuee)
|
|
203
|
+
relations.push({ kind: "invalid" });
|
|
204
|
+
else if (near.issuer !== far.issuee)
|
|
205
|
+
relations.push(delegatedFrom(db, "DI2I", near.issuer, far.issuee));
|
|
206
|
+
}
|
|
207
|
+
// Issuer identity never reads issuees.
|
|
208
|
+
if (identity) {
|
|
209
|
+
if (!near.issuer || !far.issuer)
|
|
210
|
+
relations.push({ kind: "invalid" });
|
|
211
|
+
else if (near.issuer !== far.issuer) {
|
|
212
|
+
relations.push(identity === "I1I" ? { kind: "invalid" } : delegatedFrom(db, "DI1I", near.issuer, far.issuer));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return reduce("AND", relations);
|
|
216
|
+
}
|
|
57
217
|
/**
|
|
58
218
|
* Validate every own schema, then conjoin each caller verdict with its complete edge expression.
|
|
59
219
|
* Every branch is inspected for malformed shape, even when its truth value is unused.
|
|
220
|
+
* Under an open walk an undisclosed far node is a non-retryable unknown for its leaf.
|
|
60
221
|
* Protocol callers supply issuer authentication; applications supply their state policy.
|
|
61
|
-
*
|
|
222
|
+
* The graph must come from `walkAcdcGraph` (directly or through a protocol walk).
|
|
223
|
+
* This helper reads schemas and KEL state but writes no records and publishes no cues.
|
|
62
224
|
*/
|
|
63
225
|
export function evaluateChain(graph, verdicts, db) {
|
|
64
226
|
// Own schemas are global obligations, unlike optional edge pins and node verdicts.
|
|
@@ -78,12 +240,15 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
78
240
|
if (!node || !auth)
|
|
79
241
|
return null;
|
|
80
242
|
memo.set(id, unknown(`Node ${id} is already being evaluated.`));
|
|
81
|
-
const
|
|
82
|
-
if (!
|
|
243
|
+
const section = acdcEdgeSection(node.sad);
|
|
244
|
+
if (!section)
|
|
83
245
|
return null;
|
|
84
246
|
const members = [auth];
|
|
85
|
-
|
|
86
|
-
|
|
247
|
+
if (section.kind === "compact") {
|
|
248
|
+
members.push(unknown(`Node ${id} carries compact Edge Section ${section.said}, which cannot be evaluated.`));
|
|
249
|
+
}
|
|
250
|
+
else if (section.kind === "expanded") {
|
|
251
|
+
const result = evaluateGroup(section.section, node, []);
|
|
87
252
|
if (!result)
|
|
88
253
|
return null;
|
|
89
254
|
members.push(result);
|
|
@@ -92,50 +257,41 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
92
257
|
memo.set(id, result);
|
|
93
258
|
return result;
|
|
94
259
|
};
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
return null;
|
|
99
|
-
const pins = Object.hasOwn(edge, "s") ? [...inherited, edge.s] : inherited;
|
|
100
|
-
if (target !== null)
|
|
101
|
-
return evaluateLeaf(edge, target, near, pins);
|
|
102
|
-
const op = Object.hasOwn(edge, "o") ? edge.o : "AND";
|
|
260
|
+
const evaluateGroup = (group, near, inherited) => {
|
|
261
|
+
const pins = Object.hasOwn(group, "s") ? [...inherited, group.s] : inherited;
|
|
262
|
+
const op = Object.hasOwn(group, "o") ? group.o : "AND";
|
|
103
263
|
if (typeof op !== "string")
|
|
104
264
|
return null;
|
|
105
265
|
const members = [];
|
|
106
|
-
for (const [label, member] of Object.entries(
|
|
266
|
+
for (const [label, member] of Object.entries(group)) {
|
|
107
267
|
if (acdcGroupLabels.has(label))
|
|
108
268
|
continue;
|
|
109
269
|
if (typeof member === "string") {
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
if (!record(member))
|
|
270
|
+
if (!said(member))
|
|
114
271
|
return null;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return null;
|
|
118
|
-
members.push(result);
|
|
272
|
+
members.push(unknown(`Compact Edge ${label} cannot be dereferenced.`));
|
|
273
|
+
continue;
|
|
119
274
|
}
|
|
275
|
+
const target = acdcEdgeTarget(member);
|
|
276
|
+
if (target === false || !record(member))
|
|
277
|
+
return null;
|
|
278
|
+
const result = target === null ? evaluateGroup(member, near, pins) : evaluateLeaf(member, target, near, pins);
|
|
279
|
+
if (!result)
|
|
280
|
+
return null;
|
|
281
|
+
members.push(result);
|
|
120
282
|
}
|
|
121
283
|
if (!members.length)
|
|
122
284
|
return null;
|
|
123
285
|
return op === "AND" || op === "OR" ? reduce(op, members) : unknown(`Unsupported Edge-group operator ${op}.`);
|
|
124
286
|
};
|
|
125
|
-
const evaluateLeaf = (edge, target, near,
|
|
126
|
-
const
|
|
127
|
-
if (!far)
|
|
128
|
-
return null;
|
|
287
|
+
const evaluateLeaf = (edge, target, near, inherited) => {
|
|
288
|
+
const pins = Object.hasOwn(edge, "s") ? [...inherited, edge.s] : inherited;
|
|
129
289
|
const op = edge.o;
|
|
130
290
|
const ops = op == null ? [] : typeof op === "string" ? [op] : Array.isArray(op) ? [...op] : null;
|
|
131
|
-
if (!ops)
|
|
291
|
+
if (!ops || !ops.every((token) => typeof token === "string"))
|
|
132
292
|
return null;
|
|
133
293
|
// Pin shape is morphological, so validate it before unsupported tokens or relations.
|
|
134
294
|
const resolved = [];
|
|
135
|
-
const ownSchema = far.schema;
|
|
136
|
-
const ownSchemaId = record(ownSchema) ? ownSchema.$id : ownSchema;
|
|
137
|
-
if (pins.length && typeof ownSchemaId !== "string")
|
|
138
|
-
return null;
|
|
139
295
|
for (const pin of pins) {
|
|
140
296
|
if (typeof pin === "string") {
|
|
141
297
|
if (!said(pin))
|
|
@@ -159,55 +315,33 @@ export function evaluateChain(graph, verdicts, db) {
|
|
|
159
315
|
else
|
|
160
316
|
return null;
|
|
161
317
|
}
|
|
162
|
-
|
|
163
|
-
if (
|
|
164
|
-
|
|
318
|
+
const far = graph.nodes.get(target)?.body;
|
|
319
|
+
if (!far) {
|
|
320
|
+
// A closed walk never yields a graph with an undisclosed target.
|
|
321
|
+
return graph.walk === "open" ? unknown(`Far node ${target} is not disclosed.`) : null;
|
|
165
322
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (relation.kind === "refused")
|
|
184
|
-
matched = false;
|
|
185
|
-
else if (relation.kind === "pending")
|
|
186
|
-
pending = unknown(relation.reason, true);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
own = { kind: matched ? "valid" : "invalid" };
|
|
190
|
-
if (matched) {
|
|
191
|
-
for (let pin of resolved) {
|
|
192
|
-
if (pin === ownSchemaId && record(ownSchema))
|
|
193
|
-
pin = ownSchema;
|
|
194
|
-
const result = validateSchema(far, db, pin);
|
|
195
|
-
if (result.kind === "valid")
|
|
196
|
-
continue;
|
|
197
|
-
own = result.kind === "missing"
|
|
198
|
-
? unknown(`Missing edge schema ${result.said}.`, true, [result.said])
|
|
199
|
-
: { kind: "invalid" };
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
// Pending delegation cannot replace a pin's decided refusal.
|
|
204
|
-
if (pending)
|
|
205
|
-
own = reduce("AND", [own, pending]);
|
|
323
|
+
const ownSchema = far.schema;
|
|
324
|
+
const ownSchemaId = record(ownSchema) ? ownSchema.$id : ownSchema;
|
|
325
|
+
if (pins.length && typeof ownSchemaId !== "string")
|
|
326
|
+
return null;
|
|
327
|
+
const relation = leafRelation(db, ops, near, far);
|
|
328
|
+
const own = [relation];
|
|
329
|
+
// A decided relation refusal needs no pin evidence; otherwise every pin is evaluated, not only the first failure.
|
|
330
|
+
if (relation.kind !== "invalid") {
|
|
331
|
+
for (let pin of resolved) {
|
|
332
|
+
if (pin === ownSchemaId && record(ownSchema))
|
|
333
|
+
pin = ownSchema;
|
|
334
|
+
const result = validateSchema(far, db, pin);
|
|
335
|
+
if (result.kind === "valid")
|
|
336
|
+
continue;
|
|
337
|
+
own.push(result.kind === "missing"
|
|
338
|
+
? unknown(`Missing edge schema ${result.said}.`, true, [result.said])
|
|
339
|
+
: { kind: "invalid" });
|
|
206
340
|
}
|
|
207
341
|
}
|
|
208
342
|
// Do not short-circuit a far subtree: its shape cannot be outvoted by this leaf.
|
|
209
343
|
const farVerdict = evaluateNode(target);
|
|
210
|
-
return farVerdict ? reduce("AND", [own, farVerdict]) : null;
|
|
344
|
+
return farVerdict ? reduce("AND", [reduce("AND", own), farVerdict]) : null;
|
|
211
345
|
};
|
|
212
346
|
return graph.order.length ? evaluateNode(graph.order[0]) : null;
|
|
213
347
|
}
|