keri-ts 2.1.0 → 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/custody.js +164 -0
- package/esm/keri/npm/src/acdc/dhking.js +244 -32
- package/esm/keri/npm/src/acdc/regbasing.js +10 -0
- package/esm/keri/npm/src/acdc/salting.js +16 -1
- package/esm/keri/npm/src/acdc/scheming.js +93 -54
- package/esm/keri/npm/src/acdc/unblinding.js +118 -95
- 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 +4 -6
- 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 +68 -60
- 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/delivery/forwarding.js +16 -3
- package/esm/keri/npm/src/app/exchanges/exchanging.js +14 -4
- package/esm/keri/npm/src/app/identity/challenging.js +50 -0
- 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 +129 -6
- package/esm/keri/npm/src/app/identity/keeping.js +77 -4
- 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-grouping.js +34 -11
- 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 +10 -5
- package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +18 -0
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +94 -139
- 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/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 +9 -3
- package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +106 -55
- 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/http-client.js +25 -6
- package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
- package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
- package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
- package/esm/keri/npm/src/cli/credentials/ipex.js +157 -190
- 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.js +10 -13
- package/esm/keri/npm/src/cli/identity/challenge.js +8 -34
- package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
- package/esm/keri/npm/src/cli/identity/incept.js +15 -32
- package/esm/keri/npm/src/cli/identity/interact.js +5 -17
- package/esm/keri/npm/src/cli/identity/rotate.js +8 -36
- package/esm/keri/npm/src/cli/index.js +3 -1
- 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 +163 -284
- package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
- package/esm/keri/npm/src/core/kel/eventing.js +66 -10
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +39 -6
- 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 +13 -0
- package/esm/keri/npm/src/db/basing.js +34 -2
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
- package/esm/keri/npm/src/db/indexeddb.js +98 -0
- package/esm/keri/npm/src/db/keeping.js +11 -2
- package/esm/keri/npm/src/db/store-lock.js +150 -0
- 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.browser.js +2 -0
- package/esm/keri/npm/src/npm/index.browser.js +9 -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 +51 -4
- 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/tel-publication.js +16 -0
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +15 -2
- package/types/acdc/authoring.d.ts +54 -0
- package/types/acdc/authoring.d.ts.map +1 -0
- 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 +4 -0
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +6 -1
- 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 +56 -44
- package/types/app/credentials/root-replicating.d.ts.map +1 -1
- 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/delivery/forwarding.d.ts +6 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- 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/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 +67 -2
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +49 -3
- package/types/app/identity/keeping.d.ts.map +1 -1
- 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-grouping.d.ts +18 -0
- package/types/app/ipex/ipex-grouping.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 +3 -0
- 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 +11 -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 +91 -22
- 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/signaling.d.ts +3 -1
- package/types/app/notifications/signaling.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +13 -0
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +7 -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 +72 -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/http-client.d.ts.map +1 -1
- 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/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.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/interact.d.ts.map +1 -1
- package/types/cli/identity/rotate.d.ts.map +1 -1
- package/types/cli/index.d.ts +3 -1
- 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 +28 -5
- 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/core/cues.d.ts +11 -0
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/kel/eventing.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/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 +8 -2
- package/types/db/basing.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/indexeddb.d.ts +37 -0
- package/types/db/indexeddb.d.ts.map +1 -0
- package/types/db/keeping.d.ts +5 -2
- package/types/db/keeping.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/npm/db-indexeddb.d.ts +4 -0
- package/types/npm/db-indexeddb.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 +41 -6
- package/types/runtime/index.d.ts.map +1 -1
- 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/cli/common/tel-completion.js +0 -24
- package/types/cli/common/tel-completion.d.ts +0 -8
- package/types/cli/common/tel-completion.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
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry blind derivation over the Keeper's registry root.
|
|
3
|
+
*
|
|
4
|
+
* Issuing a blinded (BUP) registry update needs a deterministic opening. The
|
|
5
|
+
* root salt stays in the Keeper; this core derives openings from it and keeps
|
|
6
|
+
* only the public, event-specific coordinates in a `DerivedUpdateStore`. A
|
|
7
|
+
* runtime defaults to {@link BaserDerivedUpdateStore}; a wallet backs the port
|
|
8
|
+
* with its own table. The core opens no database of its own.
|
|
9
|
+
*/
|
|
10
|
+
import { bytesEqual, makeBlindState, makeBoundState, MtrDex, Salter } from "cesr-ts";
|
|
11
|
+
import { ValidationError } from "../core/errors.js";
|
|
12
|
+
import { DerivedUpdateRecord } from "../core/records.js";
|
|
13
|
+
import { vetBlind } from "./regeventing.js";
|
|
14
|
+
/** Process-local store for a CLI or tests; a wallet backs the port with its own durable table. */
|
|
15
|
+
export class MemoryDerivedUpdateStore {
|
|
16
|
+
constructor() {
|
|
17
|
+
Object.defineProperty(this, "rows", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: new Map()
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
get(event) {
|
|
25
|
+
return this.rows.get(event) ?? null;
|
|
26
|
+
}
|
|
27
|
+
pin(event, value) {
|
|
28
|
+
this.rows.set(event, structuredClone(value));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Derivation coordinates kept in a registry environment's own database (`RegBaser.dvus`). The default of a
|
|
33
|
+
* runtime that supplies no store, so a server agent keeps them durably beside the registry events they
|
|
34
|
+
* describe. A wallet with its own table still passes that instead.
|
|
35
|
+
*/
|
|
36
|
+
export class BaserDerivedUpdateStore {
|
|
37
|
+
constructor(baser) {
|
|
38
|
+
Object.defineProperty(this, "baser", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: baser
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
get(event) {
|
|
46
|
+
const row = this.baser.dvus.get([event]);
|
|
47
|
+
return row ? { credential: row.credential, state: row.state, bound: row.bound } : null;
|
|
48
|
+
}
|
|
49
|
+
pin(event, value) {
|
|
50
|
+
this.baser.dvus.pin([event], new DerivedUpdateRecord(structuredClone(value)));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Explicit capability over a local habitat's Keeper root and accepted public registry evidence. */
|
|
54
|
+
export class RegistryCustody {
|
|
55
|
+
/** Borrow owners only; construction loads no encrypted row. */
|
|
56
|
+
constructor(options) {
|
|
57
|
+
Object.defineProperty(this, "options", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: options
|
|
62
|
+
});
|
|
63
|
+
this.owner();
|
|
64
|
+
}
|
|
65
|
+
/** Bind the actual local habitat and its key owners, never an AID label alone. */
|
|
66
|
+
owner() {
|
|
67
|
+
const { hby, hab } = this.options;
|
|
68
|
+
if (hby.habs.get(hab.pre) !== hab || hab.ks !== hby.ks || hab.mgr !== hby.mgr || hab.db !== hby.db) {
|
|
69
|
+
throw new ValidationError("Custody requires the actual local habitat and Keeper owners");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Load only this habitat's Keeper root; possession confers no protocol authority. */
|
|
73
|
+
load(registry) {
|
|
74
|
+
this.owner();
|
|
75
|
+
const root = this.options.hby.mgr.getRegistryRoot(this.options.hab.pre, registry);
|
|
76
|
+
if (!root)
|
|
77
|
+
throw new ValidationError("Registry custody is not provisioned");
|
|
78
|
+
return root;
|
|
79
|
+
}
|
|
80
|
+
/** Provision an issuer-selected root once, refusing replacement behind opaque accepted history. */
|
|
81
|
+
createCustody(registry) {
|
|
82
|
+
this.owner();
|
|
83
|
+
const { hby, hab } = this.options;
|
|
84
|
+
if (!hby.mgr.aeid || !hby.mgr.seed) {
|
|
85
|
+
throw new ValidationError("Private credential custody requires an authenticated encrypted Keeper");
|
|
86
|
+
}
|
|
87
|
+
if (hby.mgr.getRegistryRoot(hab.pre, registry))
|
|
88
|
+
return { registry };
|
|
89
|
+
const rip = this.options.registry.seqEvent(registry, 0);
|
|
90
|
+
if (!rip || rip.issuer !== hab.pre) {
|
|
91
|
+
throw new ValidationError("New custody requires the accepted registry issuer's actual local habitat");
|
|
92
|
+
}
|
|
93
|
+
// Existing clone validation authenticates public openings without another parser or proof algorithm.
|
|
94
|
+
for (const _ of this.options.registry.cloneTelIter(registry)) { /* consume the accepted public prefix */ }
|
|
95
|
+
const head = this.options.registry.headEvent(registry);
|
|
96
|
+
const last = head ? Number(BigInt(`0x${head.sad.n}`)) : 0;
|
|
97
|
+
if (!Number.isSafeInteger(last))
|
|
98
|
+
throw new ValidationError("Accepted registry ordinal is not representable");
|
|
99
|
+
for (let ordinal = 1; ordinal <= last; ordinal++) {
|
|
100
|
+
const event = this.options.registry.seqEvent(registry, ordinal);
|
|
101
|
+
if (!event)
|
|
102
|
+
throw new ValidationError("Accepted registry history is incomplete");
|
|
103
|
+
if (event.ilk === "bup" && !this.options.registry.opening(event.said)) {
|
|
104
|
+
throw new ValidationError("Local custody is missing for blinded registry history; salt cannot be recreated");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
hby.mgr.putRegistryRoot(hab.pre, registry, new Salter({ code: MtrDex.Salt_128, raw: crypto.getRandomValues(new Uint8Array(16)) }));
|
|
108
|
+
return { registry };
|
|
109
|
+
}
|
|
110
|
+
/** Derive a candidate only; consumers still authenticate its exact accepted event and bound KEL reference. */
|
|
111
|
+
derive(registry, ordinal, credential, state, options = {}) {
|
|
112
|
+
if ((typeof ordinal !== "bigint" && (typeof ordinal !== "number" || !Number.isSafeInteger(ordinal))) || ordinal < 1) {
|
|
113
|
+
throw new ValidationError("Update ordinal must be a positive integer");
|
|
114
|
+
}
|
|
115
|
+
const root = this.load(registry);
|
|
116
|
+
const values = { salt: root.qb64, sn: ordinal, tier: "low", acdc: credential, state };
|
|
117
|
+
return options.bound
|
|
118
|
+
? makeBoundState({ ...values, bsn: options.bsn ?? 0, bd: options.bd ?? "" })
|
|
119
|
+
: makeBlindState(values);
|
|
120
|
+
}
|
|
121
|
+
/** Persist exact nonsecret coordinates before processing/anchoring a newly derived BUP. */
|
|
122
|
+
retainDerivedUpdate(event, opening) {
|
|
123
|
+
if (event.ilk !== "bup" || !event.verify() || !vetBlind(opening, event.sad.b)) {
|
|
124
|
+
throw new ValidationError("Derived update requires its exact authenticated BUP opening");
|
|
125
|
+
}
|
|
126
|
+
const value = {
|
|
127
|
+
credential: opening.td.nonce,
|
|
128
|
+
state: opening.ts.label,
|
|
129
|
+
bound: "bn" in opening ? { bn: opening.bn.num.toString(16), bd: opening.bd.nonce } : null,
|
|
130
|
+
};
|
|
131
|
+
const old = this.options.store.get(event.said);
|
|
132
|
+
if (old && JSON.stringify(canonical(old)) !== JSON.stringify(value)) {
|
|
133
|
+
throw new ValidationError("Different derivation coordinates are already retained for this event");
|
|
134
|
+
}
|
|
135
|
+
this.options.store.pin(event.said, value);
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
/** Reproduce only the exact accepted event, never today's head or a later credential's coordinates. */
|
|
139
|
+
derivedOpening(event) {
|
|
140
|
+
if (event.ilk !== "bup" || !event.verify())
|
|
141
|
+
throw new ValidationError("Exact accepted blinded update is required");
|
|
142
|
+
const ordinal = BigInt(`0x${event.sad.n}`);
|
|
143
|
+
if (!Number.isSafeInteger(Number(ordinal))) {
|
|
144
|
+
throw new ValidationError("Accepted registry ordinal is not representable");
|
|
145
|
+
}
|
|
146
|
+
const stored = event.regid ? this.options.registry.seqEvent(event.regid, Number(ordinal)) : null;
|
|
147
|
+
if (!stored || !bytesEqual(stored.raw, event.raw)) {
|
|
148
|
+
throw new ValidationError("Exact accepted registry event is required");
|
|
149
|
+
}
|
|
150
|
+
const value = this.options.store.get(event.said);
|
|
151
|
+
if (!value)
|
|
152
|
+
throw new ValidationError("Exact derived update coordinates are unavailable");
|
|
153
|
+
const opening = this.derive(event.regid, ordinal, value.credential, value.state, value.bound ? { bound: true, bsn: BigInt(`0x${value.bound.bn}`), bd: value.bound.bd } : {});
|
|
154
|
+
if (!vetBlind(opening, event.sad.b)) {
|
|
155
|
+
throw new ValidationError("Derived opening does not match the exact accepted event");
|
|
156
|
+
}
|
|
157
|
+
return opening;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** Fix field order so equality does not depend on how a store hydrated the record. */
|
|
161
|
+
function canonical(value) {
|
|
162
|
+
const { credential, state, bound } = value;
|
|
163
|
+
return { credential, state, bound: bound ? { bn: bound.bn, bd: bound.bd } : null };
|
|
164
|
+
}
|