keri-ts 2.1.0 → 2.2.1
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 +187 -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 +341 -0
- package/esm/keri/npm/src/app/ipex/group-issuance.js +905 -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 +50 -19
- package/esm/keri/npm/src/app/ipex/ipex-node-authentication.js +42 -18
- package/esm/keri/npm/src/app/ipex/issuance.js +896 -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 +408 -0
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +667 -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 +488 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +18 -0
- package/esm/keri/npm/src/app/multisig/multisig-messaging.js +33 -6
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +98 -147
- 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 +164 -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.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 +83 -0
- package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
- package/esm/keri/npm/src/cli/messaging/multisig.js +190 -285
- 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 +84 -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 +254 -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/ipex-node-authentication.d.ts +9 -1
- package/types/app/ipex/ipex-node-authentication.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +445 -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 +300 -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 +257 -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-messaging.d.ts +23 -6
- package/types/app/multisig/multisig-messaging.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 +56 -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 +29 -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 +42 -7
- 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
|
@@ -1,158 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delegator-side CLI approval for pending delegated events.
|
|
3
|
-
*
|
|
4
|
-
* KERIpy correspondence:
|
|
5
|
-
* - this is the bounded command analogue of KLI's delegation approval flow
|
|
6
|
-
* - pending work is discovered from durable `delegables.` escrow, not from
|
|
7
|
-
* controller notifications
|
|
8
|
-
*
|
|
9
|
-
* Maintainer rule:
|
|
10
|
-
* - `/delegate/request` notifications are UI hints only
|
|
11
|
-
* - approval ordering and event selection come from the delegated-event escrows
|
|
12
|
-
* and the delegator's own KEL state
|
|
13
|
-
*/
|
|
14
|
-
import { Diger } from "cesr-ts";
|
|
15
|
-
import { call, race, sleep, spawn } from "effection";
|
|
16
|
-
import { runAgentRuntime } from "../../app/runtime/agent-runtime.js";
|
|
17
1
|
import { ValidationError } from "../../core/errors.js";
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import { groupSigningMembers, isLocalGroupHab, localGroupMember } from "../../app/identity/endpoint-roleing.js";
|
|
2
|
+
import { parseBooleanOption, parseNumberOption, parseStringListOption, parseStringOption, } from "../common/parsing.js";
|
|
3
|
+
import { approveDelegation, DELEGATION_APPROVAL_TIMEOUT_MS, proposeGroupDelegationApproval, requestDelegatedEvent, settleDelegationApproval, waitForDelegationAnchor, waitForDelegationApproval, waitForPendingDelegation, } from "../../app/identity/delegation-approval.js";
|
|
4
|
+
import { isLocalGroupHab, localGroupMember } from "../../app/identity/endpoint-roleing.js";
|
|
22
5
|
import { MULTISIG_IXN_ROUTE } from "../../app/multisig/grouping.js";
|
|
23
|
-
import { SeqNoQuerier } from "../../app/queries/querying.js";
|
|
24
|
-
import { runtimeTurn } from "../../app/runtime/runtime-turn.js";
|
|
25
|
-
import { WitnessReceiptor } from "../../app/witness/receipting.js";
|
|
26
6
|
import { withHabAndAgentRuntime } from "../common/context.js";
|
|
7
|
+
import { withRuntimeWorkers } from "../common/runtime-workers.js";
|
|
27
8
|
import { resolveWitnessAuths } from "../common/witness-auth.js";
|
|
28
|
-
/**
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!pre) {
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
const serder = hby.db.getEvtSerder(pre, said);
|
|
37
|
-
if (!serder) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
const sourcePrefix = delegationSourcePrefix(hby, serder, pre);
|
|
41
|
-
if (sourcePrefix !== delegatorPre) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
pending.push(serder);
|
|
45
|
-
}
|
|
46
|
-
return pending.sort((left, right) => (left.sn ?? 0) - (right.sn ?? 0));
|
|
47
|
-
}
|
|
48
|
-
/** Determine the delegator prefix for `dip` or `drt` escrow material. */
|
|
49
|
-
function delegationSourcePrefix(hby, serder, pre) {
|
|
50
|
-
if (serder.delpre) {
|
|
51
|
-
return serder.delpre;
|
|
52
|
-
}
|
|
53
|
-
if (serder.ilk !== "drt") {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
const delegatedPre = serder.pre ?? pre;
|
|
57
|
-
return hby.db.getKever(delegatedPre)?.delpre
|
|
58
|
-
?? hby.db.getState(delegatedPre)?.di;
|
|
59
|
-
}
|
|
60
|
-
/** Project a delegated event into the seal embedded by the approving event. */
|
|
61
|
-
function anchorData(serder) {
|
|
62
|
-
if (!serder.pre || !serder.snh || !serder.said) {
|
|
63
|
-
throw new ValidationError("Delegated event is missing pre, sn, or said.");
|
|
64
|
-
}
|
|
65
|
-
return { i: serder.pre, s: serder.snh, d: serder.said };
|
|
66
|
-
}
|
|
67
|
-
function approvingEvent(hby, serder, delegator) {
|
|
68
|
-
return hby.db.fetchLastSealingEventByEventSeal(delegator.pre, anchorData(serder));
|
|
69
|
-
}
|
|
70
|
-
/** Resolve delegate witnesses for either delegated inception or rotation. */
|
|
71
|
-
function delegateWitnesses(hby, serder) {
|
|
72
|
-
if ((serder.sn ?? 0) === 0) {
|
|
73
|
-
return [...serder.backs];
|
|
74
|
-
}
|
|
75
|
-
if (!serder.pre) {
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
return [...(hby.db.getKever(serder.pre)?.wits ?? [])];
|
|
79
|
-
}
|
|
80
|
-
/** Return true once the delegated event has left escrow and reached local state. */
|
|
81
|
-
function delegateCommitted(hby, serder) {
|
|
82
|
-
if (!serder.pre) {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
const kever = hby.db.getKever(serder.pre);
|
|
86
|
-
return kever !== undefined && kever !== null && kever.sn >= (serder.sn ?? 0);
|
|
87
|
-
}
|
|
88
|
-
/** Build a witness log query used to pull delegate-side completion material. */
|
|
89
|
-
function delegateWitnessLogsQuery(hab, serder, witness) {
|
|
90
|
-
if (!serder.pre || !serder.snh) {
|
|
91
|
-
throw new ValidationError("Delegated event is missing pre or sn for query.");
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
pre: serder.pre,
|
|
95
|
-
signer: hab.pre,
|
|
96
|
-
src: witness,
|
|
97
|
-
route: "logs",
|
|
98
|
-
q: { fn: "0", s: serder.snh },
|
|
99
|
-
wits: [witness],
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Publish group delegation approval to remote signing members before advancing the workflow.
|
|
104
|
-
*
|
|
105
|
-
* @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
|
|
106
|
-
* @param hby Borrowed local identities and accepted-state stores.
|
|
107
|
-
* @param groupHab Group approving habitat.
|
|
108
|
-
* @param message Signed approving interaction to embed for remote members.
|
|
109
|
-
* @returns Successful delivery URLs after each concrete Poster outcome.
|
|
110
|
-
*/
|
|
111
|
-
function* publishGroupDelegationApproval(runtime, hby, groupHab, message) {
|
|
112
|
-
const member = localGroupMember(hby, groupHab.pre);
|
|
113
|
-
const smids = groupSigningMembers(hby, groupHab.pre);
|
|
114
|
-
const deliveries = [];
|
|
115
|
-
for (const recipient of smids) {
|
|
116
|
-
if (recipient === member.pre || hby.habs.has(recipient)) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
const { msg } = createExchangeMessage(member, {
|
|
120
|
-
dest: recipient,
|
|
121
|
-
route: MULTISIG_IXN_ROUTE,
|
|
122
|
-
payload: { gid: groupHab.pre, smids },
|
|
123
|
-
embeds: { ixn: message },
|
|
124
|
-
});
|
|
125
|
-
const postman = runtime.postman;
|
|
126
|
-
const evt = postman.send({ src: member.pre, dest: recipient, topic: "multisig", msg }, { notify: true });
|
|
127
|
-
const result = yield* postman.wait(evt);
|
|
128
|
-
if (result.kin === "failed")
|
|
129
|
-
throw result.error;
|
|
130
|
-
deliveries.push(...result.deliveries);
|
|
131
|
-
}
|
|
132
|
-
return deliveries;
|
|
133
|
-
}
|
|
134
|
-
function eventAccepted(hby, serder) {
|
|
135
|
-
return !!serder.pre && serder.said !== undefined
|
|
136
|
-
&& hby.db.kels.getLast(serder.pre, serder.sn ?? 0) === serder.said;
|
|
137
|
-
}
|
|
138
|
-
function pinApprovalSeal(hby, hab, delegated, approving) {
|
|
139
|
-
if (!approving.sner || !approving.said || !delegated.pre || !delegated.said) {
|
|
140
|
-
throw new ValidationError("Approving event material is incomplete.");
|
|
141
|
-
}
|
|
142
|
-
hby.db.aess.pin(dgKey(delegated.pre, delegated.said), [
|
|
143
|
-
approving.sner,
|
|
144
|
-
new Diger({ qb64: approving.said }),
|
|
145
|
-
]);
|
|
146
|
-
hab.kvy.processEscrowDelegables();
|
|
147
|
-
}
|
|
148
|
-
/** Observe approval state while the command's host workers own background progress. */
|
|
149
|
-
function* waitForDelegation(done, timeoutMs) {
|
|
150
|
-
const deadline = Date.now() + timeoutMs;
|
|
151
|
-
while (!done()) {
|
|
152
|
-
if (Date.now() >= deadline)
|
|
153
|
-
throw new Error(`Runtime did not converge within ${timeoutMs}ms.`);
|
|
154
|
-
yield* runtimeTurn();
|
|
155
|
-
}
|
|
9
|
+
/** Wall-clock budget for the request and anchor waits; `--timeout` seconds, else the library default. */
|
|
10
|
+
function waitBudgetMs(confirmArgs) {
|
|
11
|
+
return confirmArgs.timeoutSeconds === undefined
|
|
12
|
+
? DELEGATION_APPROVAL_TIMEOUT_MS
|
|
13
|
+
: confirmArgs.timeoutSeconds * 1000;
|
|
156
14
|
}
|
|
157
15
|
/**
|
|
158
16
|
* Approve pending events without starting or serially driving background workers.
|
|
@@ -164,11 +22,12 @@ function* waitForDelegation(done, timeoutMs) {
|
|
|
164
22
|
*/
|
|
165
23
|
function* performDelegationApproval(hby, hab, runtime, confirmArgs) {
|
|
166
24
|
const interactionApproval = confirmArgs.interact ?? false;
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
170
|
-
throw new ValidationError(`No delegated events are awaiting approval for ${hab.pre}.`);
|
|
25
|
+
const timeoutMs = waitBudgetMs(confirmArgs);
|
|
26
|
+
const waited = yield* waitForPendingDelegation(hby, { delegator: hab.pre }, { timeoutMs });
|
|
27
|
+
if (waited.outcome === "timed-out") {
|
|
28
|
+
throw new ValidationError(`No delegated events are awaiting approval for ${hab.pre} after ${timeoutMs}ms.`);
|
|
171
29
|
}
|
|
30
|
+
const pending = waited.status;
|
|
172
31
|
if (pending.length > 1 && !confirmArgs.auto) {
|
|
173
32
|
throw new ValidationError(`Multiple delegated events are awaiting approval for ${hab.pre}. Re-run with --auto to approve them in order.`);
|
|
174
33
|
}
|
|
@@ -177,109 +36,75 @@ function* performDelegationApproval(hby, hab, runtime, confirmArgs) {
|
|
|
177
36
|
promptMissing: confirmArgs.authenticate ?? false,
|
|
178
37
|
});
|
|
179
38
|
const selected = confirmArgs.auto ? pending : [pending[0]];
|
|
180
|
-
|
|
181
|
-
|
|
39
|
+
const deps = {
|
|
40
|
+
hby,
|
|
41
|
+
protocol: runtime.protocol,
|
|
42
|
+
http: runtime.http,
|
|
43
|
+
clock: runtime.clock,
|
|
44
|
+
querying: runtime.querying,
|
|
45
|
+
};
|
|
46
|
+
for (const request of selected) {
|
|
182
47
|
if (isLocalGroupHab(hby, hab)) {
|
|
183
|
-
|
|
184
|
-
throw new ValidationError("Multisig delegated approval currently requires --interact.");
|
|
185
|
-
}
|
|
186
|
-
const approving = approvingEvent(hby, serder, hab);
|
|
187
|
-
if (!approving) {
|
|
188
|
-
const created = hby.interactGroupHab(confirmArgs.alias, undefined, { data: [anchor] });
|
|
189
|
-
const deliveries = yield* publishGroupDelegationApproval(runtime, hby, created.hab, created.message);
|
|
190
|
-
console.log(JSON.stringify({
|
|
191
|
-
status: eventAccepted(hby, created.serder) ? "accepted" : "multisig-pending",
|
|
192
|
-
route: MULTISIG_IXN_ROUTE,
|
|
193
|
-
group: created.hab.pre,
|
|
194
|
-
delegated: serder.pre,
|
|
195
|
-
said: serder.said,
|
|
196
|
-
anchor: created.serder.said,
|
|
197
|
-
deliveries,
|
|
198
|
-
}));
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
const witnesses = delegateWitnesses(hby, serder).sort();
|
|
202
|
-
const selectedWitness = witnesses[0];
|
|
203
|
-
const member = localGroupMember(hby, hab.pre);
|
|
204
|
-
pinApprovalSeal(hby, hab, serder, approving);
|
|
205
|
-
if (!delegateCommitted(hby, serder) && selectedWitness) {
|
|
206
|
-
runtime.querying.enqueue(delegateWitnessLogsQuery(member, serder, selectedWitness));
|
|
207
|
-
yield* waitForDelegation(() => delegateCommitted(hby, serder), 30_000);
|
|
208
|
-
}
|
|
209
|
-
pinApprovalSeal(hby, hab, serder, approving);
|
|
210
|
-
if (serder.pre && serder.said) {
|
|
211
|
-
const stillPending = hby.db.delegables.get([serder.pre]).includes(serder.said);
|
|
212
|
-
if (stillPending) {
|
|
213
|
-
throw new ValidationError(`Delegated event ${serder.said} remained in delegables escrow after approval.`);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
console.log(`Approved delegated ${serder.ilk} ${serder.said ?? ""} for ${serder.pre ?? ""} using multisig ixn.`);
|
|
48
|
+
yield* approveGroupDelegation(hby, hab, runtime, confirmArgs, request, auths);
|
|
217
49
|
continue;
|
|
218
50
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
hab.rotate({ data: [anchor] });
|
|
227
|
-
}
|
|
228
|
-
if (hab.kever?.wits.length) {
|
|
229
|
-
const witDoer = new WitnessReceiptor(hby, runtime.protocol, runtime.http, runtime.clock);
|
|
230
|
-
yield* witDoer.submit(hab.pre, {
|
|
231
|
-
sn: hab.kever.sn,
|
|
232
|
-
auths,
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
const approving = hby.db.getEvtSerder(hab.pre, hab.kever.said);
|
|
236
|
-
if (!approving) {
|
|
237
|
-
throw new ValidationError("Approving event material is incomplete.");
|
|
238
|
-
}
|
|
239
|
-
const witnesses = delegateWitnesses(hby, serder).sort();
|
|
240
|
-
const selectedWitness = witnesses[0];
|
|
241
|
-
if (selectedWitness) {
|
|
242
|
-
// Witnessed delegates must prove the delegated event is committed
|
|
243
|
-
// locally before we pin `aess.` and retry delegated unescrow. Doing
|
|
244
|
-
// it earlier can make local state look approved but incomplete.
|
|
245
|
-
runtime.querying.enqueue(delegateWitnessLogsQuery(hab, serder, selectedWitness));
|
|
246
|
-
yield* waitForDelegation(() => delegateCommitted(hby, serder), 30_000);
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
// No delegate witness exists to query. Process the local delegable
|
|
250
|
-
// after the delegator has anchored approval; the delegate still
|
|
251
|
-
// discovers approval through its own delegator-KEL query path.
|
|
252
|
-
pinApprovalSeal(hby, hab, serder, approving);
|
|
253
|
-
const observed = yield* race([
|
|
254
|
-
call(function* () {
|
|
255
|
-
yield* new SeqNoQuerier(hby.db, runtime.querying, serder.pre, serder.sn ?? 0, {
|
|
256
|
-
signer: hab.pre,
|
|
257
|
-
}).queryDo();
|
|
258
|
-
return true;
|
|
259
|
-
}),
|
|
260
|
-
call(function* () {
|
|
261
|
-
yield* sleep(30_000);
|
|
262
|
-
return false;
|
|
263
|
-
}),
|
|
264
|
-
]);
|
|
265
|
-
if (!observed)
|
|
266
|
-
throw new Error("Runtime did not converge within 30000ms.");
|
|
267
|
-
}
|
|
268
|
-
// Match KERIpy sequencing: only record the approving seal and retry
|
|
269
|
-
// delegated unescrow after the delegate event has been observed as
|
|
270
|
-
// locally committed through the witness-backed query/replay path.
|
|
271
|
-
if (selectedWitness) {
|
|
272
|
-
pinApprovalSeal(hby, hab, serder, approving);
|
|
51
|
+
yield* approveDelegation(deps, request, {
|
|
52
|
+
event: interactionApproval ? "ixn" : "rot",
|
|
53
|
+
auths,
|
|
54
|
+
});
|
|
55
|
+
const result = yield* waitForDelegationApproval({ db: hby.db, settle: () => settleDelegationApproval(deps, request) }, request, { timeoutMs: 30_000 });
|
|
56
|
+
if (result.outcome === "timed-out") {
|
|
57
|
+
throw new Error(`Runtime did not converge within ${result.timeoutMs}ms.`);
|
|
273
58
|
}
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
if (stillPending) {
|
|
277
|
-
throw new ValidationError(`Delegated event ${serder.said} remained in delegables escrow after approval.`);
|
|
278
|
-
}
|
|
59
|
+
if (hby.db.delegables.get([request.delegate]).includes(request.said)) {
|
|
60
|
+
throw new ValidationError(`Delegated event ${request.said} remained in delegables escrow after approval.`);
|
|
279
61
|
}
|
|
280
|
-
console.log(`Approved delegated ${
|
|
62
|
+
console.log(`Approved delegated ${request.ilk} ${request.said} for ${request.delegate} using ${interactionApproval ? "ixn" : "rot"}.`);
|
|
281
63
|
}
|
|
282
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Group delegator approval: propose the anchoring interaction the first time; once the
|
|
67
|
+
* group's KEL holds the anchor (the other members approved it), ask for the delegate's event.
|
|
68
|
+
*/
|
|
69
|
+
function* approveGroupDelegation(hby, hab, runtime, confirmArgs, request, auths) {
|
|
70
|
+
if (!confirmArgs.interact) {
|
|
71
|
+
throw new ValidationError("Multisig delegated approval currently requires --interact.");
|
|
72
|
+
}
|
|
73
|
+
const deps = {
|
|
74
|
+
hby,
|
|
75
|
+
protocol: runtime.protocol,
|
|
76
|
+
http: runtime.http,
|
|
77
|
+
clock: runtime.clock,
|
|
78
|
+
querying: runtime.querying,
|
|
79
|
+
};
|
|
80
|
+
const timeoutMs = waitBudgetMs(confirmArgs);
|
|
81
|
+
const sent = yield* proposeGroupDelegationApproval({ hby, protocol: runtime.protocol, postman: runtime.postman, counselor: runtime.counselor }, request, { auths, fallbackAfterMs: 0 });
|
|
82
|
+
if (sent) {
|
|
83
|
+
console.log(JSON.stringify({
|
|
84
|
+
status: hby.db.kels.getLast(sent.group, sent.event.sn) === sent.event.said ? "accepted" : "multisig-pending",
|
|
85
|
+
route: MULTISIG_IXN_ROUTE,
|
|
86
|
+
group: sent.group,
|
|
87
|
+
delegated: request.delegate,
|
|
88
|
+
said: request.said,
|
|
89
|
+
anchor: sent.event.said,
|
|
90
|
+
deliveries: sent.deliveries,
|
|
91
|
+
}));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const anchored = yield* waitForDelegationAnchor({ db: hby.db }, request, { timeoutMs });
|
|
95
|
+
if (anchored.outcome === "timed-out") {
|
|
96
|
+
throw new ValidationError(`The anchor for delegated ${request.ilk} ${request.said} was not accepted and receipted by ${hab.pre} within ${timeoutMs}ms. `
|
|
97
|
+
+ "The other members must approve the proposal first.");
|
|
98
|
+
}
|
|
99
|
+
requestDelegatedEvent(deps, request, localGroupMember(hby, hab.pre).pre);
|
|
100
|
+
const result = yield* waitForDelegationApproval({ db: hby.db, settle: () => settleDelegationApproval(deps, request) }, request, { timeoutMs: 30_000 });
|
|
101
|
+
if (result.outcome === "timed-out")
|
|
102
|
+
throw new Error(`Runtime did not converge within ${result.timeoutMs}ms.`);
|
|
103
|
+
if (hby.db.delegables.get([request.delegate]).includes(request.said)) {
|
|
104
|
+
throw new ValidationError(`Delegated event ${request.said} remained in delegables escrow after approval.`);
|
|
105
|
+
}
|
|
106
|
+
console.log(`Approved delegated ${request.ilk} ${request.said} for ${request.delegate} using multisig ixn.`);
|
|
107
|
+
}
|
|
283
108
|
/** Approve pending delegated events for the selected local delegator habitat. */
|
|
284
109
|
export function* delegateConfirmCommand(args) {
|
|
285
110
|
const confirmArgs = {
|
|
@@ -294,7 +119,11 @@ export function* delegateConfirmCommand(args) {
|
|
|
294
119
|
authenticate: parseBooleanOption(args.authenticate, "authenticate"),
|
|
295
120
|
code: parseStringListOption(args.code, "code"),
|
|
296
121
|
codeTime: parseStringOption(args.codeTime, "codeTime"),
|
|
122
|
+
timeoutSeconds: parseNumberOption(args.timeout, "timeout"),
|
|
297
123
|
};
|
|
124
|
+
if (confirmArgs.timeoutSeconds !== undefined && !(confirmArgs.timeoutSeconds >= 0)) {
|
|
125
|
+
throw new ValidationError("timeout must not be negative");
|
|
126
|
+
}
|
|
298
127
|
if (!confirmArgs.name) {
|
|
299
128
|
throw new ValidationError("Name is required and cannot be empty");
|
|
300
129
|
}
|
|
@@ -311,12 +140,6 @@ export function* delegateConfirmCommand(args) {
|
|
|
311
140
|
throw new ValidationError(`Missing accepted key state for ${hab.pre}.`);
|
|
312
141
|
}
|
|
313
142
|
const signer = isLocalGroupHab(hby, hab) ? localGroupMember(hby, hab.pre) : hab;
|
|
314
|
-
|
|
315
|
-
try {
|
|
316
|
-
yield* performDelegationApproval(hby, hab, runtime, confirmArgs);
|
|
317
|
-
}
|
|
318
|
-
finally {
|
|
319
|
-
yield* worker.halt();
|
|
320
|
-
}
|
|
143
|
+
yield* withRuntimeWorkers(runtime, { hab: signer }, () => performDelegationApproval(hby, hab, runtime, confirmArgs));
|
|
321
144
|
});
|
|
322
145
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { call } from "effection";
|
|
2
2
|
import { resolveBootstrap } from "../../app/bootstrap/bootstrapping.js";
|
|
3
|
-
import { createProtocolProcessor } from "../../app/protocol/protocol-processing.js";
|
|
4
|
-
import { createAgentRuntime, runAgentRuntimeUntil, } from "../../app/runtime/agent-runtime.js";
|
|
5
|
-
import { systemClock } from "../../app/runtime/runtime-clock.js";
|
|
6
3
|
import { NodeHttpClient } from "../../app/transport/node-http-client.js";
|
|
7
4
|
import { ValidationError } from "../../core/errors.js";
|
|
8
5
|
import { assertBootstrapComplete } from "../common/bootstrap.js";
|
|
9
6
|
import { createConfiger } from "../../app/identity/configing.js";
|
|
10
7
|
import { resolveDelegationCommunicationHab } from "../../app/identity/delegating.js";
|
|
11
|
-
import {
|
|
8
|
+
import { cliEventCompletionDeps, completeEventOrThrow } from "../common/event-completion.js";
|
|
12
9
|
import { setupHby } from "../common/existing.js";
|
|
13
10
|
import { loadInceptFileOptions, parseBooleanOption, parseCountOption, parseDataItems, parseKeriVersionOption, parseStringListOption, parseStringOption, parseThresholdOption, } from "../common/parsing.js";
|
|
14
11
|
/**
|
|
@@ -121,34 +118,20 @@ export function* inceptCommand(args) {
|
|
|
121
118
|
delpre: opts.delpre,
|
|
122
119
|
version: inceptArgs.version,
|
|
123
120
|
});
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
throw new ValidationError(`Delegated inception for ${hab.pre} requires --proxy <alias>.`);
|
|
139
|
-
}
|
|
140
|
-
const runtime = yield* createAgentRuntime(hby, http, systemClock);
|
|
141
|
-
try {
|
|
142
|
-
runtime.delegating.beginLatest(hab.pre, 0, {
|
|
143
|
-
communicationHab,
|
|
144
|
-
});
|
|
145
|
-
yield* runAgentRuntimeUntil(runtime, () => runtime.delegating.complete(hab.pre, 0), { hab, timeoutMs: 120_000, pollMailbox: true });
|
|
146
|
-
delegationPhase = runtime.delegating.workflowStatus(hab.pre, "0").phase;
|
|
147
|
-
}
|
|
148
|
-
finally {
|
|
149
|
-
yield* runtime.close();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
121
|
+
const { delegationPhase } = yield* completeEventOrThrow(cliEventCompletionDeps(hby, http), hab, 0, {
|
|
122
|
+
endpoint: inceptArgs.endpoint,
|
|
123
|
+
delegation: opts.delpre
|
|
124
|
+
? {
|
|
125
|
+
communicationHab: () => {
|
|
126
|
+
const communicationHab = resolveDelegationCommunicationHab(hby, inceptArgs.proxy);
|
|
127
|
+
if (!communicationHab) {
|
|
128
|
+
throw new ValidationError(`Delegated inception for ${hab.pre} requires --proxy <alias>.`);
|
|
129
|
+
}
|
|
130
|
+
return communicationHab;
|
|
131
|
+
},
|
|
132
|
+
}
|
|
133
|
+
: undefined,
|
|
134
|
+
});
|
|
152
135
|
const state = hby.db.getState(hab.pre);
|
|
153
136
|
return { prefix: hab.pre, keys: state?.k ?? [], delegationPhase };
|
|
154
137
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { createProtocolProcessor } from "../../app/protocol/protocol-processing.js";
|
|
2
|
-
import { systemClock } from "../../app/runtime/runtime-clock.js";
|
|
3
1
|
import { NodeHttpClient } from "../../app/transport/node-http-client.js";
|
|
4
2
|
import { isLocalGroupHab } from "../../app/multisig/group-members.js";
|
|
5
|
-
import { Receiptor, WitnessReceiptor } from "../../app/witness/receipting.js";
|
|
6
3
|
import { ValidationError } from "../../core/errors.js";
|
|
7
4
|
import { withExistingHab } from "../common/context.js";
|
|
5
|
+
import { cliEventCompletionDeps, completeEventOrThrow } from "../common/event-completion.js";
|
|
8
6
|
import { parseBooleanOption, parseDataItems, parseKeriVersionOption, parseStringListOption, parseStringOption, } from "../common/parsing.js";
|
|
9
7
|
import { resolveWitnessAuths } from "../common/witness-auth.js";
|
|
10
8
|
/**
|
|
@@ -59,20 +57,10 @@ export function* interactCommand(args) {
|
|
|
59
57
|
codeTime: interactArgs.codeTime,
|
|
60
58
|
promptMissing: interactArgs.authenticate ?? false,
|
|
61
59
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
auths,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
const witDoer = new WitnessReceiptor(hby, createProtocolProcessor(hby), http, systemClock);
|
|
71
|
-
yield* witDoer.submit(hab.pre, {
|
|
72
|
-
sn: hab.kever.sn,
|
|
73
|
-
auths,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
60
|
+
yield* completeEventOrThrow(cliEventCompletionDeps(hby, http), hab, hab.kever.sn, {
|
|
61
|
+
auths,
|
|
62
|
+
endpoint: interactArgs.endpoint,
|
|
63
|
+
});
|
|
76
64
|
}
|
|
77
65
|
const state = hby.db.getState(hab.pre);
|
|
78
66
|
console.log(`Prefix ${hab.pre}`);
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { createProtocolProcessor } from "../../app/protocol/protocol-processing.js";
|
|
2
|
-
import { systemClock } from "../../app/runtime/runtime-clock.js";
|
|
3
1
|
import { NodeHttpClient } from "../../app/transport/node-http-client.js";
|
|
4
|
-
import { createAgentRuntime, runAgentRuntimeUntil, } from "../../app/runtime/agent-runtime.js";
|
|
5
2
|
import { ValidationError } from "../../core/errors.js";
|
|
6
3
|
import { resolveDelegationCommunicationHab } from "../../app/identity/delegating.js";
|
|
7
4
|
import { isLocalGroupHab } from "../../app/multisig/group-members.js";
|
|
8
|
-
import { Receiptor, WitnessReceiptor } from "../../app/witness/receipting.js";
|
|
9
5
|
import { withExistingHab } from "../common/context.js";
|
|
6
|
+
import { cliEventCompletionDeps, completeEventOrThrow } from "../common/event-completion.js";
|
|
10
7
|
import { loadRotateFileOptions, parseBooleanOption, parseCountOption, parseDataItems, parseKeriVersionOption, parseStringListOption, parseStringOption, parseThresholdOption, } from "../common/parsing.js";
|
|
11
8
|
import { resolveWitnessAuths } from "../common/witness-auth.js";
|
|
12
9
|
/** Empty baseline used before CLI/file precedence is applied. */
|
|
@@ -127,38 +124,13 @@ export function* rotateCommand(args, { witnessAuths } = {}) {
|
|
|
127
124
|
data: options.data ?? [],
|
|
128
125
|
version: rotateArgs.version,
|
|
129
126
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
const witDoer = new WitnessReceiptor(hby, createProtocolProcessor(hby), http, systemClock);
|
|
140
|
-
yield* witDoer.submit(hab.pre, {
|
|
141
|
-
sn: hab.kever.sn,
|
|
142
|
-
auths,
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
let delegationPhase = null;
|
|
147
|
-
if (kever.delpre !== null && hab.kever) {
|
|
148
|
-
const communicationHab = resolveDelegationCommunicationHab(hby, rotateArgs.proxy);
|
|
149
|
-
const runtime = yield* createAgentRuntime(hby, http, systemClock);
|
|
150
|
-
try {
|
|
151
|
-
runtime.delegating.beginLatest(hab.pre, hab.kever.sn, {
|
|
152
|
-
communicationHab,
|
|
153
|
-
});
|
|
154
|
-
const snh = hab.kever.sn.toString(16);
|
|
155
|
-
yield* runAgentRuntimeUntil(runtime, () => runtime.delegating.complete(hab.pre, hab.kever.sn), { hab, timeoutMs: 120_000, pollMailbox: true });
|
|
156
|
-
delegationPhase = runtime.delegating.workflowStatus(hab.pre, snh).phase;
|
|
157
|
-
}
|
|
158
|
-
finally {
|
|
159
|
-
yield* runtime.close();
|
|
160
|
-
}
|
|
161
|
-
}
|
|
127
|
+
const { delegationPhase } = yield* completeEventOrThrow(cliEventCompletionDeps(hby, http), hab, hab.kever.sn, {
|
|
128
|
+
auths,
|
|
129
|
+
endpoint: rotateArgs.endpoint,
|
|
130
|
+
delegation: kever.delpre !== null && hab.kever
|
|
131
|
+
? { communicationHab: () => resolveDelegationCommunicationHab(hby, rotateArgs.proxy) }
|
|
132
|
+
: undefined,
|
|
133
|
+
});
|
|
162
134
|
const state = hby.db.getState(hab.pre);
|
|
163
135
|
console.log(`Prefix ${hab.pre}`);
|
|
164
136
|
console.log(`New Sequence No. ${hab.kever?.sn ?? state?.s ?? ""}`);
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
export { parseGvrsn } from "../core/attachment-countering.js";
|
|
9
9
|
export { withAgentRuntime, withExistingHab, withExistingHabery, withHabAndAgentRuntime, } from "./common/context.js";
|
|
10
10
|
export { ensureHby, setupHby } from "./common/existing.js";
|
|
11
|
-
export { parseBooleanOption, parseCountOption, parseIntegerOption, parseNumberOption, parseStringListOption, parseStringOption, } from "./common/parsing.js";
|
|
11
|
+
export { parseBooleanOption, parseCountOption, parseIntegerOption, parseKeriVersionOption, parseNumberOption, parseStringListOption, parseStringOption, } from "./common/parsing.js";
|
|
12
12
|
export { writeJsonLine, writeTextLines } from "./common/rendering.js";
|
|
13
|
+
export { withRuntimeWorkers } from "./common/runtime-workers.js";
|
|
13
14
|
export { resolveWitnessAuths } from "./common/witness-auth.js";
|
|
14
15
|
export { ipexAdmitCommand, ipexAgreeCommand, ipexApplyCommand, ipexGrantCommand, ipexJoinCommand, ipexListCommand, ipexOfferCommand, ipexPollCommand, ipexSpurnCommand, joinIpexProposal, } from "./credentials/ipex.js";
|
|
15
16
|
export { vcCreateCommand, vcExportCommand, vcImportCommand, vcListCommand, vcRegistryInceptCommand, vcRegistryListCommand, vcRegistryStatusCommand, vcRevokeCommand, vcSchemaImportCommand, } from "./credentials/vc.js";
|
|
@@ -30,6 +31,7 @@ export { rotateCommand } from "./identity/rotate.js";
|
|
|
30
31
|
export { exchangeSendCommand } from "./messaging/exchange.js";
|
|
31
32
|
export { multisigInceptCommand, multisigInteractCommand, multisigJoinCommand, multisigRotateCommand, multisigRpyCommand, } from "./messaging/multisig.js";
|
|
32
33
|
export { notificationsListCommand, notificationsMarkReadCommand, notificationsRemoveCommand, } from "./messaging/notifications.js";
|
|
34
|
+
export { rootCopyLine, RootCopyRecoveryCommand, rootResealLine, } from "./messaging/root-copy-lines.js";
|
|
33
35
|
export { annotateCommand } from "./tools/annotate.js";
|
|
34
36
|
export { benchmarkCommand } from "./tools/benchmark.js";
|
|
35
37
|
export { dumpEvts } from "./tools/db-dump.js";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `tufa multisig join` proposal selection, as KERIpy `kli multisig join`.
|
|
3
|
+
*
|
|
4
|
+
* Join approves exactly one stored proposal, the first the user consents to:
|
|
5
|
+
* - an explicit `--said` names the proposal, otherwise the unapproved proposals
|
|
6
|
+
* the notice store announces are offered in notice order; `--kind` restricts the
|
|
7
|
+
* offer (and a `--said`) to one proposal kind, so a join never signs another kind;
|
|
8
|
+
* - without `--auto` every offered proposal is shown and approved only on a yes;
|
|
9
|
+
* - with `--auto` the first offered proposal is approved without a prompt. This is
|
|
10
|
+
* the whole of auto consent: it exists only inside the `join` the user ran for
|
|
11
|
+
* that purpose, and no other command signs a proposal it was not asked to sign.
|
|
12
|
+
*
|
|
13
|
+
* Signing, publication and the Counselor hand-off belong to `approveGroupProposal`.
|
|
14
|
+
*/
|
|
15
|
+
import { sleep } from "effection";
|
|
16
|
+
import { approveGroupProposal, dismissGroupProposal, findGroupProposal, listGroupProposals, } from "../../app/multisig/proposals.js";
|
|
17
|
+
import { ValidationError } from "../../core/errors.js";
|
|
18
|
+
/** Group prefix for a joined group's prefix or alias; undefined for a name not yet used. */
|
|
19
|
+
function joinedGroup(hby, group) {
|
|
20
|
+
return group === undefined ? undefined : (hby.habByName(group) ?? hby.habs.get(group))?.pre ?? undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Candidates for one pass, oldest first. */
|
|
23
|
+
function candidates(deps, { said, group, kind }) {
|
|
24
|
+
const wanted = joinedGroup(deps.hby, group);
|
|
25
|
+
if (said !== undefined) {
|
|
26
|
+
const proposal = findGroupProposal(deps, said);
|
|
27
|
+
if (proposal && kind !== undefined && proposal.kind !== kind) {
|
|
28
|
+
throw new ValidationError(`Multisig exchange ${said} is a ${proposal.kind} proposal, not ${kind}.`);
|
|
29
|
+
}
|
|
30
|
+
if (proposal && wanted !== undefined && proposal.group !== wanted) {
|
|
31
|
+
throw new ValidationError(`Multisig exchange ${said} belongs to group ${proposal.group}, not ${wanted}.`);
|
|
32
|
+
}
|
|
33
|
+
return proposal ? [proposal] : [];
|
|
34
|
+
}
|
|
35
|
+
return listGroupProposals(deps, wanted === undefined ? {} : { group: wanted })
|
|
36
|
+
.filter(proposal => proposal.local === "unapproved" && (kind === undefined || proposal.kind === kind));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Approve the first proposal the user consents to, polling stored proposals until
|
|
40
|
+
* the deadline. A declined proposal is not offered again by this call. Returns
|
|
41
|
+
* null when nothing was approved; the host owns the runtime that delivers new
|
|
42
|
+
* proposals while this waits.
|
|
43
|
+
*/
|
|
44
|
+
export function* joinProposal(deps, options) {
|
|
45
|
+
if (!deps.notifier && options.said === undefined) {
|
|
46
|
+
throw new ValidationError("Multisig join requires notification storage or an explicit exchange SAID.");
|
|
47
|
+
}
|
|
48
|
+
const skipped = new Set();
|
|
49
|
+
while (true) {
|
|
50
|
+
for (const proposal of candidates(deps, options)) {
|
|
51
|
+
if (skipped.has(proposal.said))
|
|
52
|
+
continue;
|
|
53
|
+
// An explicit proposal already approved here is replayed without asking again.
|
|
54
|
+
if (proposal.local !== "approved" && !options.confirm(proposal)) {
|
|
55
|
+
skipped.add(proposal.said);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const choices = { ...options.inputs(proposal) };
|
|
59
|
+
if (proposal.needs.groupAlias)
|
|
60
|
+
choices.groupAlias = options.groupAlias(proposal);
|
|
61
|
+
if (proposal.needs.registryName)
|
|
62
|
+
choices.registryName = options.registryName(proposal);
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = yield* approveGroupProposal(deps, proposal.said, choices);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// A proposal that cannot be approved never hides a later one; an explicit SAID reports why.
|
|
69
|
+
if (options.said === undefined && error instanceof ValidationError) {
|
|
70
|
+
skipped.add(proposal.said);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
dismissGroupProposal(deps, proposal.said);
|
|
76
|
+
return { proposal, result };
|
|
77
|
+
}
|
|
78
|
+
const remaining = options.deadline - Date.now();
|
|
79
|
+
if (remaining <= 0)
|
|
80
|
+
return null;
|
|
81
|
+
yield* sleep(Math.min(250, remaining));
|
|
82
|
+
}
|
|
83
|
+
}
|