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,30 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
/**
|
|
2
|
+
* `tufa multisig ...` command implementation.
|
|
3
|
+
*
|
|
4
|
+
* The command surface follows KLI's group lifecycle model and calls the library's
|
|
5
|
+
* proposal API; a command only parses, resolves the user's choices, waits on the
|
|
6
|
+
* Counselor under runtime workers and returns what to print:
|
|
7
|
+
* - `incept`, `rotate`, and `interact` propose a group KEL event (`proposeGroup*`)
|
|
8
|
+
* and publish a `/multisig/*` EXN to the other members
|
|
9
|
+
* - `join` approves one stored proposal the user consents to
|
|
10
|
+
* (`approveGroupProposal`) and signs nothing else; see `group-join.ts`
|
|
11
|
+
*/
|
|
12
|
+
import { Ilks } from "cesr-ts";
|
|
13
|
+
import { action } from "effection";
|
|
14
|
+
import { registryEventRef, registryEventStatus, settleRegistryEvent } from "../../app/credentials/registry-settling.js";
|
|
15
|
+
import { telEventStatus, waitForIssuedCredential, waitForTelEvent, } from "../../app/credentials/tel-completion.js";
|
|
16
|
+
import { endpointRoleAccepted, isLocalGroupHab, localGroupMember, proposeGroupEndpointRole, } from "../../app/identity/endpoint-roleing.js";
|
|
17
|
+
import { MULTISIG_REV_ROUTE, MULTISIG_ROT_ROUTE, MULTISIG_VCP_ROUTE } from "../../app/multisig/grouping.js";
|
|
18
|
+
import { routeForKelEvent } from "../../app/multisig/multisig-workflows.js";
|
|
19
|
+
import { proposeGroupInception, proposeGroupInteraction, proposeGroupRotation, settleProposedRotation, } from "../../app/multisig/proposing.js";
|
|
20
|
+
import { observeUntil } from "../../app/runtime/workflow-contract.js";
|
|
10
21
|
import { ValidationError } from "../../core/errors.js";
|
|
11
22
|
import { isV2RegistryRoute } from "../../core/exchange/protocol-exchanging.js";
|
|
12
23
|
import { Roles } from "../../core/roles.js";
|
|
13
24
|
import { withAgentRuntime } from "../common/context.js";
|
|
14
25
|
import { loadOptionObject, loadRotateFileOptions, parseBooleanOption, parseCountOption, parseDataItems, parseFileData, parseKeriVersionOption, parseNumberOption, parseStringListOption, parseStringOption, parseThresholdOption, } from "../common/parsing.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
|
|
26
|
+
import { withRuntimeWorkers } from "../common/runtime-workers.js";
|
|
27
|
+
import { joinProposal } from "./group-join.js";
|
|
28
|
+
import { counselInputs, finishAcceptedEvent, supplyDelegationProxy, supplyWitnessAuths, waitForAcceptance, } from "./group-wait.js";
|
|
29
|
+
import { rootCopyLine } from "./root-copy-lines.js";
|
|
18
30
|
/**
|
|
19
31
|
* Re-seal held registry roots to members an accepted group rotation added or
|
|
20
32
|
* rekeyed, as KERIpy `kli multisig rotate|join`. Runs while the command's
|
|
21
33
|
* runtime worker delivers; every outcome is returned, none fails the rotation.
|
|
22
34
|
*/
|
|
23
|
-
function* resealAfterRotation(hby, runtime, group, rotation) {
|
|
24
|
-
const
|
|
25
|
-
if (!
|
|
35
|
+
function* resealAfterRotation(hby, runtime, group, rotation, since) {
|
|
36
|
+
const replicating = runtime.rootReplicator, root = runtime.registryRoot;
|
|
37
|
+
if (!hby.habs.get(group) || !replicating || !root)
|
|
26
38
|
return [];
|
|
27
|
-
|
|
39
|
+
replicating.prompt(group);
|
|
40
|
+
const results = yield* replicating.processOnce();
|
|
41
|
+
const lines = results.map(rootCopyLine);
|
|
42
|
+
// The runtime's loop may have sent a copy since the rotation cue prompted it, before this pass: such a copy reads
|
|
43
|
+
// from the sent marker as transmitted, so the report does not depend on which of the two sent first.
|
|
44
|
+
const attempted = new Set(results.filter(result => result.group === group).map(result => `${result.registry}/${result.recipient}`));
|
|
45
|
+
const sender = localGroupMember(hby, group).pre, from = new Date(since).toISOString();
|
|
46
|
+
for (const [[, registry, recipient], marker] of [...hby.db.rrsn.getTopItemIter([group])]) {
|
|
47
|
+
if (attempted.has(`${registry}/${recipient}`) || marker.dt < from)
|
|
48
|
+
continue;
|
|
49
|
+
if (marker.key !== root.contributor(group, recipient))
|
|
50
|
+
continue;
|
|
51
|
+
lines.push({
|
|
52
|
+
phase: "root_copy",
|
|
53
|
+
gid: group,
|
|
54
|
+
registry: registry,
|
|
55
|
+
sender,
|
|
56
|
+
recipient: recipient,
|
|
57
|
+
transmitted: true,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return lines;
|
|
28
61
|
}
|
|
29
62
|
function requireText(value, label) {
|
|
30
63
|
if (!value) {
|
|
@@ -76,8 +109,9 @@ export function* multisigInceptCommand(args) {
|
|
|
76
109
|
throw new ValidationError("Multisig inception config must include non-empty aids.");
|
|
77
110
|
}
|
|
78
111
|
return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
|
|
79
|
-
const
|
|
80
|
-
|
|
112
|
+
const sent = yield* proposeGroupInception(proposeDeps(hby, runtime), requireHabByAlias(hby, alias), group, {
|
|
113
|
+
smids,
|
|
114
|
+
rmids,
|
|
81
115
|
isith: options.isith,
|
|
82
116
|
nsith: options.nsith,
|
|
83
117
|
toad: options.toad,
|
|
@@ -85,33 +119,13 @@ export function* multisigInceptCommand(args) {
|
|
|
85
119
|
delpre: options.delpre,
|
|
86
120
|
data: options.data ?? [],
|
|
87
121
|
version: commandArgs.version,
|
|
88
|
-
});
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}, created.message);
|
|
93
|
-
const accepted = yield* waitForGroupAcceptance(hby, runtime, created.serder, multisigApprovalOptions(hby, {
|
|
94
|
-
...commandArgs,
|
|
95
|
-
group,
|
|
96
|
-
auto: true,
|
|
97
|
-
}));
|
|
98
|
-
let delegationPhase = null;
|
|
99
|
-
if (accepted) {
|
|
100
|
-
yield* receiptAcceptedEvent(hby, created.hab.pre, commandArgs, runtime);
|
|
101
|
-
delegationPhase = yield* completeDelegationIfNeeded(hby, runtime, created.hab.pre, commandArgs.proxy);
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
route: MULTISIG_ICP_ROUTE,
|
|
105
|
-
group: created.hab.pre,
|
|
106
|
-
accepted,
|
|
107
|
-
messages,
|
|
108
|
-
deliveries,
|
|
109
|
-
state: hby.db.getState(created.hab.pre),
|
|
110
|
-
delegationPhase: delegationPhase,
|
|
111
|
-
};
|
|
122
|
+
}, counselInputs(hby, commandArgs.proxy, options.delpre !== undefined, group));
|
|
123
|
+
const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
|
|
124
|
+
const delegationPhase = accepted ? yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs) : null;
|
|
125
|
+
return { ...groupEventResult(hby, sent, accepted), delegationPhase };
|
|
112
126
|
});
|
|
113
127
|
}
|
|
114
|
-
/**
|
|
128
|
+
/** Approve one stored group multisig proposal the user consents to. */
|
|
115
129
|
export function* multisigJoinCommand(args) {
|
|
116
130
|
const commandArgs = {
|
|
117
131
|
name: parseStringOption(args.name, "name"),
|
|
@@ -128,58 +142,56 @@ export function* multisigJoinCommand(args) {
|
|
|
128
142
|
auto: parseBooleanOption(args.auto, "auto"),
|
|
129
143
|
registryName: parseStringOption(args.registryName, "registryName"),
|
|
130
144
|
said: parseStringOption(args.said, "said"),
|
|
145
|
+
kind: parseStringOption(args.kind, "kind"),
|
|
131
146
|
approvalTimeoutSeconds: nonNegativeNumber(args.approvalTimeoutSeconds, 60, "approval timeout seconds"),
|
|
132
147
|
proxy: parseStringOption(args.proxy, "proxy"),
|
|
133
148
|
};
|
|
134
149
|
const name = requireText(commandArgs.name, "Name");
|
|
135
150
|
return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
151
|
+
const since = runtime.clock.now();
|
|
152
|
+
const deadline = approvalDeadline(commandArgs);
|
|
153
|
+
const joined = yield* joinProposal(approvalDeps(hby, runtime), {
|
|
154
|
+
group: commandArgs.group,
|
|
155
|
+
said: commandArgs.said,
|
|
156
|
+
kind: commandArgs.kind,
|
|
157
|
+
deadline,
|
|
158
|
+
confirm: proposal => approvePrompt(commandArgs, proposal),
|
|
159
|
+
groupAlias: proposal => chooseGroupAlias(hby, commandArgs, proposal.group),
|
|
160
|
+
registryName: proposal => chooseRegistryName(commandArgs, proposal.embedded),
|
|
161
|
+
inputs: () => ({ fallbackAfterMs: 0 }),
|
|
162
|
+
});
|
|
163
|
+
if (!joined) {
|
|
164
|
+
const local = yield* completeLocalGroupEvent(hby, runtime, commandArgs, deadline, since);
|
|
140
165
|
if (!local) {
|
|
141
166
|
throw new ValidationError("No matching stored multisig proposal was available to join.");
|
|
142
167
|
}
|
|
143
|
-
if (local.accepted) {
|
|
144
|
-
yield* receiptAcceptedEvent(hby, local.group, commandArgs, runtime);
|
|
145
|
-
if (local.route === MULTISIG_ICP_ROUTE || local.route === MULTISIG_ROT_ROUTE) {
|
|
146
|
-
yield* completeDelegationIfNeeded(hby, runtime, local.group, commandArgs.proxy);
|
|
147
|
-
}
|
|
148
|
-
if (local.route === MULTISIG_ROT_ROUTE) {
|
|
149
|
-
return { ...local, rootCopies: yield* resealAfterRotation(hby, runtime, local.group, local.embedded) };
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
168
|
return local;
|
|
153
169
|
}
|
|
170
|
+
const { event, ...result } = joined.result;
|
|
154
171
|
if (result.tel) {
|
|
155
172
|
const { publication, reger } = runtime.vdr;
|
|
156
173
|
const tel = result.tel;
|
|
157
174
|
if (result.route === MULTISIG_VCP_ROUTE || result.route === MULTISIG_REV_ROUTE) {
|
|
158
|
-
yield*
|
|
175
|
+
yield* waitForTelEvent({ publication }, tel.pre, tel.sn, { deadline });
|
|
159
176
|
result.accepted = reger.tels.getOn(tel.pre, tel.sn)?.qb64 === result.embedded;
|
|
160
177
|
}
|
|
161
178
|
else {
|
|
162
|
-
yield* waitForIssuedCredential(publication, tel.pre,
|
|
179
|
+
yield* waitForIssuedCredential({ publication }, tel.pre, { deadline });
|
|
163
180
|
result.accepted = reger.saved.get(tel.pre) !== null;
|
|
164
181
|
}
|
|
165
|
-
tel.publicationComplete = publication
|
|
182
|
+
tel.publicationComplete = telEventStatus({ publication }, tel.pre, tel.sn).state === "complete";
|
|
166
183
|
return result;
|
|
167
184
|
}
|
|
168
185
|
if (isV2RegistryRoute(result.route)) {
|
|
169
|
-
|
|
186
|
+
supplyWitnessAuths(hby, runtime, event, commandArgs);
|
|
187
|
+
result.accepted = yield* settleRegistryApproval(hby, runtime, result, deadline);
|
|
170
188
|
return result;
|
|
171
189
|
}
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
if (result.route === MULTISIG_ROT_ROUTE) {
|
|
179
|
-
return { ...result, rootCopies: yield* resealAfterRotation(hby, runtime, result.group, result.embedded) };
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return result;
|
|
190
|
+
if (!event)
|
|
191
|
+
return result;
|
|
192
|
+
// No scheduling point separates the approval from here, so the Counselor has not yet used its defaults.
|
|
193
|
+
supplyDelegationProxy(hby, runtime, event, commandArgs.proxy);
|
|
194
|
+
return yield* finishJoinedEvent(hby, runtime, result, event, commandArgs, since);
|
|
183
195
|
});
|
|
184
196
|
}
|
|
185
197
|
/** Create or begin one group interaction event. */
|
|
@@ -204,26 +216,11 @@ export function* multisigInteractCommand(args) {
|
|
|
204
216
|
const group = requireText(commandArgs.group ?? commandArgs.alias, "Group");
|
|
205
217
|
const data = parseDataItems(commandArgs.data);
|
|
206
218
|
return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
group,
|
|
213
|
-
auto: true,
|
|
214
|
-
}));
|
|
215
|
-
if (accepted) {
|
|
216
|
-
yield* receiptAcceptedEvent(hby, created.hab.pre, commandArgs, runtime);
|
|
217
|
-
}
|
|
218
|
-
return {
|
|
219
|
-
route: MULTISIG_IXN_ROUTE,
|
|
220
|
-
group: created.hab.pre,
|
|
221
|
-
accepted,
|
|
222
|
-
messages,
|
|
223
|
-
deliveries,
|
|
224
|
-
state: hby.db.getState(created.hab.pre),
|
|
225
|
-
delegationPhase: null,
|
|
226
|
-
};
|
|
219
|
+
const sent = yield* proposeGroupInteraction(proposeDeps(hby, runtime), requireGroupHab(hby, group), data, { fallbackAfterMs: 0 }, commandArgs.version);
|
|
220
|
+
const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
|
|
221
|
+
if (accepted)
|
|
222
|
+
yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs);
|
|
223
|
+
return groupEventResult(hby, sent, accepted);
|
|
227
224
|
});
|
|
228
225
|
}
|
|
229
226
|
/** Rotate or begin rotation of one group identifier. */
|
|
@@ -258,7 +255,11 @@ export function* multisigRotateCommand(args) {
|
|
|
258
255
|
const group = requireText(commandArgs.group ?? commandArgs.alias, "Group");
|
|
259
256
|
const options = mergeRotateOptions(commandArgs);
|
|
260
257
|
return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
|
|
261
|
-
const
|
|
258
|
+
const since = runtime.clock.now();
|
|
259
|
+
const groupHab = requireGroupHab(hby, group);
|
|
260
|
+
const sent = yield* proposeGroupRotation(proposeDeps(hby, runtime), groupHab, {
|
|
261
|
+
smids: commandArgs.smids,
|
|
262
|
+
rmids: commandArgs.rmids,
|
|
262
263
|
isith: options.isith,
|
|
263
264
|
nsith: options.nsith,
|
|
264
265
|
toad: options.toad,
|
|
@@ -266,34 +267,17 @@ export function* multisigRotateCommand(args) {
|
|
|
266
267
|
adds: options.witsAdd,
|
|
267
268
|
data: options.data ?? [],
|
|
268
269
|
version: commandArgs.version,
|
|
269
|
-
});
|
|
270
|
-
const
|
|
271
|
-
const rmids = commandArgs.rmids?.length ? commandArgs.rmids : smids;
|
|
272
|
-
const { deliveries, messages } = yield* publishProposal(hby, runtime.protocol, runtime.postman, localGroupMember(hby, rotated.hab.pre), uniqueMembers([...smids, ...rmids]), { route: MULTISIG_ROT_ROUTE, attrs: { gid: rotated.hab.pre, smids, rmids } }, rotated.message);
|
|
273
|
-
const accepted = yield* waitForGroupAcceptance(hby, runtime, rotated.serder, multisigApprovalOptions(hby, {
|
|
274
|
-
...commandArgs,
|
|
275
|
-
group,
|
|
276
|
-
auto: true,
|
|
277
|
-
}));
|
|
270
|
+
}, counselInputs(hby, commandArgs.proxy, !!hby.db.getKever(groupHab.pre)?.delpre, group));
|
|
271
|
+
const accepted = yield* waitForAcceptance(hby, runtime, sent.event, approvalDeadline(commandArgs));
|
|
278
272
|
let delegationPhase = null;
|
|
279
273
|
let rootCopies = [];
|
|
280
274
|
if (accepted) {
|
|
281
275
|
// The proposer's own acceptance must commit the rotated membership as a joiner's does.
|
|
282
|
-
|
|
283
|
-
yield*
|
|
284
|
-
|
|
285
|
-
rootCopies = yield* resealAfterRotation(hby, runtime, rotated.hab.pre, rotated.serder.said);
|
|
276
|
+
settleProposedRotation({ hby }, sent);
|
|
277
|
+
delegationPhase = yield* finishAcceptedEvent(hby, runtime, sent.event, commandArgs);
|
|
278
|
+
rootCopies = yield* resealAfterRotation(hby, runtime, sent.group, sent.event.said, since);
|
|
286
279
|
}
|
|
287
|
-
return {
|
|
288
|
-
route: MULTISIG_ROT_ROUTE,
|
|
289
|
-
group: rotated.hab.pre,
|
|
290
|
-
accepted,
|
|
291
|
-
messages,
|
|
292
|
-
deliveries,
|
|
293
|
-
state: hby.db.getState(rotated.hab.pre),
|
|
294
|
-
delegationPhase: delegationPhase,
|
|
295
|
-
rootCopies,
|
|
296
|
-
};
|
|
280
|
+
return { ...groupEventResult(hby, sent, accepted), delegationPhase, rootCopies };
|
|
297
281
|
});
|
|
298
282
|
}
|
|
299
283
|
/** Propose one group multisig reply such as `/end/role/add`. */
|
|
@@ -318,12 +302,12 @@ export function* multisigRpyCommand(args) {
|
|
|
318
302
|
return yield* withMultisigRuntime(commandArgs, name, function* ({ hby, runtime }) {
|
|
319
303
|
const groupHab = requireHabByAlias(hby, group);
|
|
320
304
|
const result = yield* proposeGroupEndpointRole(hby, runtime.protocol, runtime.postman, groupHab, { eid, role, allow: commandArgs.allow });
|
|
305
|
+
// The reply is accepted when the other members' contributions reach this runtime.
|
|
321
306
|
const accepted = commandArgs.approvalTimeoutSeconds > 0
|
|
322
|
-
? yield*
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}))
|
|
307
|
+
? yield* observeUntil(() => endpointRoleAccepted(hby, groupHab.pre, role, eid), {
|
|
308
|
+
timeoutMs: Math.max(0, approvalDeadline(commandArgs) - Date.now()),
|
|
309
|
+
pollMs: 250,
|
|
310
|
+
})
|
|
327
311
|
: result.accepted;
|
|
328
312
|
return { ...result, accepted };
|
|
329
313
|
});
|
|
@@ -340,13 +324,7 @@ function* withMultisigRuntime(args, name, use) {
|
|
|
340
324
|
const signer = selected && isLocalGroupHab(context.hby, selected)
|
|
341
325
|
? localGroupMember(context.hby, selected.pre)
|
|
342
326
|
: selected;
|
|
343
|
-
|
|
344
|
-
try {
|
|
345
|
-
return yield* use(context);
|
|
346
|
-
}
|
|
347
|
-
finally {
|
|
348
|
-
yield* worker.halt();
|
|
349
|
-
}
|
|
327
|
+
return yield* withRuntimeWorkers(context.runtime, { hab: signer }, () => use(context));
|
|
350
328
|
});
|
|
351
329
|
}
|
|
352
330
|
function requireHabByAlias(hby, alias) {
|
|
@@ -356,6 +334,12 @@ function requireHabByAlias(hby, alias) {
|
|
|
356
334
|
}
|
|
357
335
|
return hab;
|
|
358
336
|
}
|
|
337
|
+
function requireGroupHab(hby, group) {
|
|
338
|
+
const hab = hby.habByName(group);
|
|
339
|
+
if (!hab)
|
|
340
|
+
throw new ValidationError(`Group alias ${group} is invalid.`);
|
|
341
|
+
return hab;
|
|
342
|
+
}
|
|
359
343
|
function mergeRotateOptions(args) {
|
|
360
344
|
const options = args.file && args.file !== "" ? loadRotateFileOptions(args.file) : {};
|
|
361
345
|
if (args.isith !== undefined) {
|
|
@@ -384,23 +368,78 @@ function mergeRotateOptions(args) {
|
|
|
384
368
|
}
|
|
385
369
|
return options;
|
|
386
370
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
371
|
+
/** Deadline of this command's approval wait, measured from when the wait starts. */
|
|
372
|
+
function approvalDeadline(args) {
|
|
373
|
+
return Date.now() + args.approvalTimeoutSeconds * 1000;
|
|
374
|
+
}
|
|
375
|
+
function proposeDeps(hby, runtime) {
|
|
376
|
+
return { hby, protocol: runtime.protocol, postman: runtime.postman, counselor: runtime.counselor };
|
|
377
|
+
}
|
|
378
|
+
function approvalDeps(hby, runtime) {
|
|
390
379
|
return {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
380
|
+
hby,
|
|
381
|
+
exc: runtime.exc,
|
|
382
|
+
reactor: runtime.reactor,
|
|
383
|
+
protocol: runtime.protocol,
|
|
384
|
+
postman: runtime.postman,
|
|
385
|
+
notifier: runtime.notifier,
|
|
386
|
+
registryStore: runtime.acdc?.store ?? null,
|
|
387
|
+
vdr: runtime.vdr,
|
|
388
|
+
counselor: runtime.counselor,
|
|
395
389
|
};
|
|
396
390
|
}
|
|
397
|
-
function
|
|
391
|
+
function groupEventResult(hby, sent, accepted) {
|
|
398
392
|
return {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
393
|
+
route: sent.route,
|
|
394
|
+
group: sent.group,
|
|
395
|
+
accepted,
|
|
396
|
+
messages: sent.messages,
|
|
397
|
+
deliveries: sent.deliveries,
|
|
398
|
+
members: sent.members,
|
|
399
|
+
state: hby.db.getState(sent.group),
|
|
400
|
+
delegationPhase: null,
|
|
402
401
|
};
|
|
403
402
|
}
|
|
403
|
+
/**
|
|
404
|
+
* A joined event that this approval completed has nothing left to wait for from other
|
|
405
|
+
* members; finish its receipts and delegation. One that still needs other members
|
|
406
|
+
* returns at once and stays counseled in the store.
|
|
407
|
+
*/
|
|
408
|
+
function* finishJoinedEvent(hby, runtime, result, event, args, since) {
|
|
409
|
+
if (!result.accepted)
|
|
410
|
+
return result;
|
|
411
|
+
yield* finishAcceptedEvent(hby, runtime, event, args);
|
|
412
|
+
if (result.route !== MULTISIG_ROT_ROUTE)
|
|
413
|
+
return result;
|
|
414
|
+
return { ...result, rootCopies: yield* resealAfterRotation(hby, runtime, result.group, result.embedded, since) };
|
|
415
|
+
}
|
|
416
|
+
/** Resume a locally authored group event named by `--group` when no proposal was left to join. */
|
|
417
|
+
function* completeLocalGroupEvent(hby, runtime, args, deadline, since) {
|
|
418
|
+
if (!args.group || args.said)
|
|
419
|
+
return null;
|
|
420
|
+
const groupHab = hby.habByName(args.group) ?? hby.habs.get(args.group);
|
|
421
|
+
if (!groupHab?.pre || !isLocalGroupHab(hby, groupHab))
|
|
422
|
+
return null;
|
|
423
|
+
const serder = hby.db.getKever(groupHab.pre)?.serder ?? hby.db.getEvtSerder(groupHab.pre, groupHab.pre);
|
|
424
|
+
const route = serder && routeForKelEvent(serder);
|
|
425
|
+
if (!serder?.said || serder.sn === null || !route)
|
|
426
|
+
return null;
|
|
427
|
+
const event = { pre: groupHab.pre, sn: serder.sn, said: serder.said };
|
|
428
|
+
const delegated = serder.ilk === Ilks.dip || serder.ilk === Ilks.drt;
|
|
429
|
+
runtime.counselor.start(event, counselInputs(hby, args.proxy, delegated, groupHab.pre));
|
|
430
|
+
const accepted = yield* waitForAcceptance(hby, runtime, event, deadline);
|
|
431
|
+
const result = {
|
|
432
|
+
route,
|
|
433
|
+
said: "",
|
|
434
|
+
embedded: serder.said,
|
|
435
|
+
group: groupHab.pre,
|
|
436
|
+
accepted,
|
|
437
|
+
deliveries: [],
|
|
438
|
+
messages: [],
|
|
439
|
+
members: [],
|
|
440
|
+
};
|
|
441
|
+
return yield* finishJoinedEvent(hby, runtime, result, event, args, since);
|
|
442
|
+
}
|
|
404
443
|
function chooseRegistryName(args, regk) {
|
|
405
444
|
if (args.registryName) {
|
|
406
445
|
return args.registryName;
|
|
@@ -439,70 +478,38 @@ function chooseGroupAlias(hby, args, groupPre) {
|
|
|
439
478
|
return group;
|
|
440
479
|
}
|
|
441
480
|
}
|
|
442
|
-
|
|
481
|
+
/** Ask whether to join a proposal; `--auto` answers yes without asking, only for the join command that set it. */
|
|
482
|
+
export function approvePrompt(args, proposal) {
|
|
443
483
|
if (args.auto) {
|
|
444
484
|
return true;
|
|
445
485
|
}
|
|
446
486
|
console.log(JSON.stringify({
|
|
447
|
-
route:
|
|
448
|
-
group:
|
|
449
|
-
embedded:
|
|
487
|
+
route: `/multisig/${proposal.kind}`,
|
|
488
|
+
group: proposal.group,
|
|
489
|
+
embedded: proposal.embedded,
|
|
450
490
|
}, null, 2));
|
|
451
491
|
const yn = prompt("\nJoin [Y|n]? ");
|
|
452
492
|
return yn === null || yn === "" || yn === "y" || yn === "Y";
|
|
453
493
|
}
|
|
454
|
-
/**
|
|
455
|
-
* Collect witness receipts for the current accepted multisig event using explicit runtime collaborators.
|
|
456
|
-
*
|
|
457
|
-
* @param hby Borrowed local identities and accepted-state stores.
|
|
458
|
-
* @param pre Accepted group event subject.
|
|
459
|
-
* @param args Witness authentication and HTTP endpoint mode choices.
|
|
460
|
-
* @param runtime Borrowed composed runtime; caller owns its worker and store lifetime.
|
|
461
|
-
* @param sn Accepted event ordinal to receipt; defaults to the current event.
|
|
462
|
-
*/
|
|
463
|
-
function* receiptAcceptedEvent(hby, pre, args, runtime, sn) {
|
|
464
|
-
const kever = hby.db.getKever(pre);
|
|
465
|
-
if (!kever || kever.wits.length === 0) {
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
const auths = resolveWitnessAuths(kever.wits, args.code ?? [], {
|
|
469
|
-
codeTime: args.codeTime,
|
|
470
|
-
promptMissing: args.authenticate ?? false,
|
|
471
|
-
});
|
|
472
|
-
if (args.endpoint) {
|
|
473
|
-
const receiptor = new Receiptor(hby, runtime.protocol, runtime.http, runtime.clock);
|
|
474
|
-
yield* receiptor.receipt(pre, { sn: sn ?? kever.sn, auths });
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
const witDoer = new WitnessReceiptor(hby, runtime.protocol, runtime.http, runtime.clock);
|
|
478
|
-
yield* witDoer.submit(pre, { sn: sn ?? kever.sn, auths });
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
494
|
/**
|
|
482
495
|
* Settle one approved v2 RIP/BUP as KERIpy's join Counselor does: wait for the group's KEL acceptance of
|
|
483
|
-
* the exact anchor
|
|
484
|
-
*
|
|
496
|
+
* the exact anchor and let the anchor escrow accept the TEL event. The Counselor, started by the approval,
|
|
497
|
+
* converges the anchor's witness receipts, which the TEL event needs.
|
|
485
498
|
*
|
|
486
499
|
* @returns Whether the approved TEL event is accepted before the approval deadline.
|
|
487
500
|
*/
|
|
488
|
-
function* settleRegistryApproval(hby, runtime, result,
|
|
501
|
+
function* settleRegistryApproval(hby, runtime, result, deadline) {
|
|
489
502
|
const store = runtime.acdc?.store, tel = store?.event(result.embedded);
|
|
490
503
|
const anc = hby.db.exns.get([result.said])?.sad?.a?.anc;
|
|
491
504
|
if (!store || !tel || typeof tel.sad?.n !== "string" || typeof anc !== "string")
|
|
492
505
|
return result.accepted;
|
|
493
|
-
const
|
|
494
|
-
|
|
506
|
+
const anchor = hby.db.getEvtSerder(result.group, anc);
|
|
507
|
+
const ref = registryEventRef(tel, { pre: result.group, sn: anchor?.sn ?? 0, said: anc });
|
|
508
|
+
const deps = { db: hby.db, store, protocol: runtime.protocol };
|
|
495
509
|
while (true) {
|
|
496
|
-
if (
|
|
510
|
+
if (registryEventStatus(deps, ref).state === "accepted")
|
|
497
511
|
return true;
|
|
498
|
-
|
|
499
|
-
if (!receipted && anchor && hby.db.kels.getLast(result.group, anchor.sn) === anc) {
|
|
500
|
-
if (!hby.db.fullyWitnessed(anchor))
|
|
501
|
-
yield* receiptAcceptedEvent(hby, result.group, args, runtime, anchor.sn);
|
|
502
|
-
receipted = true;
|
|
503
|
-
}
|
|
504
|
-
yield* runtime.protocol.processEscrowsOnce();
|
|
505
|
-
if (store.seqEvent(regid, sn)?.said === tel.said)
|
|
512
|
+
if ((yield* settleRegistryEvent(deps, ref)).state === "accepted")
|
|
506
513
|
return true;
|
|
507
514
|
if (Date.now() >= deadline)
|
|
508
515
|
return false;
|
|
@@ -517,108 +524,6 @@ function nonNegativeNumber(value, fallback, label) {
|
|
|
517
524
|
}
|
|
518
525
|
return parsed;
|
|
519
526
|
}
|
|
520
|
-
/** Approve stored proposals until the target event is accepted or the deadline expires. */
|
|
521
|
-
function* waitForGroupAcceptance(hby, runtime, serder, options) {
|
|
522
|
-
if (eventAccepted(hby, serder)) {
|
|
523
|
-
return true;
|
|
524
|
-
}
|
|
525
|
-
while (true) {
|
|
526
|
-
yield* approvePendingMultisigProposal(hby, runtime, options);
|
|
527
|
-
if (eventAccepted(hby, serder)) {
|
|
528
|
-
return true;
|
|
529
|
-
}
|
|
530
|
-
if (Date.now() >= options.deadline)
|
|
531
|
-
break;
|
|
532
|
-
yield* sleep(Math.min(250, options.deadline - Date.now()));
|
|
533
|
-
}
|
|
534
|
-
return eventAccepted(hby, serder);
|
|
535
|
-
}
|
|
536
|
-
/** Wait for one stored proposal while the command host owns background progress. */
|
|
537
|
-
function* waitForOneApproval(hby, runtime, options) {
|
|
538
|
-
while (true) {
|
|
539
|
-
const result = yield* approvePendingMultisigProposal(hby, runtime, options);
|
|
540
|
-
if (result) {
|
|
541
|
-
return result;
|
|
542
|
-
}
|
|
543
|
-
if (Date.now() >= options.deadline)
|
|
544
|
-
break;
|
|
545
|
-
yield* sleep(Math.min(250, options.deadline - Date.now()));
|
|
546
|
-
}
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
/** Wait for a locally authored group event to complete through stored approvals. */
|
|
550
|
-
function* waitForLocalGroupCompletion(hby, runtime, options) {
|
|
551
|
-
if (!options.group || options.said) {
|
|
552
|
-
return null;
|
|
553
|
-
}
|
|
554
|
-
const groupHab = groupHabByAliasOrPrefix(hby, options.group);
|
|
555
|
-
if (!groupHab?.pre) {
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
const serder = localGroupJoinSerder(hby, groupHab.pre);
|
|
559
|
-
if (!serder) {
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
const route = routeForKelEvent(serder);
|
|
563
|
-
if (!route) {
|
|
564
|
-
return null;
|
|
565
|
-
}
|
|
566
|
-
const accepted = yield* waitForGroupAcceptance(hby, runtime, serder, options);
|
|
567
|
-
return {
|
|
568
|
-
route,
|
|
569
|
-
said: "",
|
|
570
|
-
embedded: serder.said ?? "",
|
|
571
|
-
group: groupHab.pre,
|
|
572
|
-
accepted,
|
|
573
|
-
deliveries: [],
|
|
574
|
-
messages: [],
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
/** Approve stored proposals until the endpoint reply is accepted or the deadline expires. */
|
|
578
|
-
function* waitForReplyAcceptance(hby, runtime, groupPre, role, eid, options) {
|
|
579
|
-
if (endpointRoleAccepted(hby, groupPre, role, eid)) {
|
|
580
|
-
return true;
|
|
581
|
-
}
|
|
582
|
-
while (true) {
|
|
583
|
-
yield* approvePendingMultisigProposal(hby, runtime, options);
|
|
584
|
-
if (endpointRoleAccepted(hby, groupPre, role, eid)) {
|
|
585
|
-
return true;
|
|
586
|
-
}
|
|
587
|
-
if (Date.now() >= options.deadline)
|
|
588
|
-
break;
|
|
589
|
-
yield* sleep(Math.min(250, options.deadline - Date.now()));
|
|
590
|
-
}
|
|
591
|
-
return endpointRoleAccepted(hby, groupPre, role, eid);
|
|
592
|
-
}
|
|
593
|
-
/** Complete the delegation workflow for an accepted delegated group event. */
|
|
594
|
-
function* completeDelegationIfNeeded(hby, runtime, pre, proxy) {
|
|
595
|
-
const kever = hby.db.getKever(pre);
|
|
596
|
-
if (!kever?.delpre) {
|
|
597
|
-
return null;
|
|
598
|
-
}
|
|
599
|
-
const communicationHab = resolveDelegationCommunicationHab(hby, proxy);
|
|
600
|
-
if (!communicationHab) {
|
|
601
|
-
throw new ValidationError(`Delegated group event for ${pre} requires --proxy <alias>.`);
|
|
602
|
-
}
|
|
603
|
-
runtime.delegating.beginLatest(pre, kever.sn, { communicationHab });
|
|
604
|
-
const deadline = Date.now() + 120_000;
|
|
605
|
-
while (!runtime.delegating.complete(pre, kever.sn)) {
|
|
606
|
-
if (Date.now() >= deadline)
|
|
607
|
-
throw new Error("Runtime did not converge within 120000ms.");
|
|
608
|
-
yield* sleep(Math.min(250, deadline - Date.now()));
|
|
609
|
-
}
|
|
610
|
-
return runtime.delegating.workflowStatus(pre, kever.sner.numh).phase;
|
|
611
|
-
}
|
|
612
|
-
function groupHabByAliasOrPrefix(hby, group) {
|
|
613
|
-
return hby.habByName(group) ?? hby.habs.get(group) ?? null;
|
|
614
|
-
}
|
|
615
|
-
function localGroupJoinSerder(hby, groupPre) {
|
|
616
|
-
const kever = hby.db.getKever(groupPre);
|
|
617
|
-
if (kever?.serder) {
|
|
618
|
-
return kever.serder;
|
|
619
|
-
}
|
|
620
|
-
return hby.db.getEvtSerder(groupPre, groupPre);
|
|
621
|
-
}
|
|
622
527
|
function* sleep(ms) {
|
|
623
528
|
yield* action((resolve) => {
|
|
624
529
|
const id = setTimeout(resolve, ms);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** The operator command that resends a copy automatic replication did not send. */
|
|
2
|
+
export const RootCopyRecoveryCommand = "tufa vc registry root send";
|
|
3
|
+
function errorText(error) {
|
|
4
|
+
return error instanceof Error ? error.message : String(error);
|
|
5
|
+
}
|
|
6
|
+
/** Map one typed copy result to its `root_copy` line. */
|
|
7
|
+
export function rootCopyLine(result) {
|
|
8
|
+
const line = {
|
|
9
|
+
phase: "root_copy",
|
|
10
|
+
gid: result.group,
|
|
11
|
+
registry: result.registry,
|
|
12
|
+
sender: result.sender,
|
|
13
|
+
recipient: result.recipient,
|
|
14
|
+
transmitted: false,
|
|
15
|
+
};
|
|
16
|
+
if (result.exchange !== undefined)
|
|
17
|
+
line.exchange = result.exchange;
|
|
18
|
+
if (result.kin === "sent")
|
|
19
|
+
return { ...line, transmitted: true };
|
|
20
|
+
return { ...line, error: errorText(result.error), recovery: RootCopyRecoveryCommand };
|
|
21
|
+
}
|
|
22
|
+
/** Map an unexaminable rotation to its `root_copy` line. */
|
|
23
|
+
export function rootResealLine(examination) {
|
|
24
|
+
return {
|
|
25
|
+
phase: "root_copy",
|
|
26
|
+
gid: examination.group,
|
|
27
|
+
rotation: examination.rotation,
|
|
28
|
+
transmitted: false,
|
|
29
|
+
error: examination.error.message,
|
|
30
|
+
};
|
|
31
|
+
}
|