keri-ts 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/esm/keri/npm/src/acdc/authoring.js +195 -0
- package/esm/keri/npm/src/acdc/custody.js +164 -0
- package/esm/keri/npm/src/acdc/dhking.js +244 -32
- package/esm/keri/npm/src/acdc/regbasing.js +10 -0
- package/esm/keri/npm/src/acdc/salting.js +16 -1
- package/esm/keri/npm/src/acdc/scheming.js +93 -54
- package/esm/keri/npm/src/acdc/unblinding.js +118 -95
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
- package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +4 -6
- package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
- package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
- package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
- package/esm/keri/npm/src/app/credentials/root-replicating.js +68 -60
- package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
- package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
- package/esm/keri/npm/src/app/delivery/forwarding.js +16 -3
- package/esm/keri/npm/src/app/exchanges/exchanging.js +14 -4
- package/esm/keri/npm/src/app/identity/challenging.js +50 -0
- package/esm/keri/npm/src/app/identity/delegating.js +77 -77
- package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
- package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
- package/esm/keri/npm/src/app/identity/habbing.js +129 -6
- package/esm/keri/npm/src/app/identity/keeping.js +77 -4
- package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
- package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
- package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
- package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
- package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +34 -11
- package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
- package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
- package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
- package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
- package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
- package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +10 -5
- package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +18 -0
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +94 -139
- package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
- package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
- package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
- package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +9 -3
- package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +106 -55
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
- package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
- package/esm/keri/npm/src/app/runtime/doing.js +17 -0
- package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
- package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
- package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
- package/esm/keri/npm/src/app/transport/http-client.js +25 -6
- package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
- package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
- package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
- package/esm/keri/npm/src/cli/credentials/ipex.js +157 -190
- package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
- package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
- package/esm/keri/npm/src/cli/endpoints/oobi.js +10 -13
- package/esm/keri/npm/src/cli/identity/challenge.js +8 -34
- package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
- package/esm/keri/npm/src/cli/identity/incept.js +15 -32
- package/esm/keri/npm/src/cli/identity/interact.js +5 -17
- package/esm/keri/npm/src/cli/identity/rotate.js +8 -36
- package/esm/keri/npm/src/cli/index.js +3 -1
- package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
- package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
- package/esm/keri/npm/src/cli/messaging/multisig.js +163 -284
- package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
- package/esm/keri/npm/src/core/kel/eventing.js +66 -10
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +39 -6
- package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
- package/esm/keri/npm/src/core/records.js +23 -0
- package/esm/keri/npm/src/core/routing.js +13 -0
- package/esm/keri/npm/src/db/basing.js +34 -2
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
- package/esm/keri/npm/src/db/indexeddb.js +98 -0
- package/esm/keri/npm/src/db/keeping.js +11 -2
- package/esm/keri/npm/src/db/store-lock.js +150 -0
- package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
- package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
- package/esm/keri/npm/src/npm/db.browser.js +2 -0
- package/esm/keri/npm/src/npm/index.browser.js +9 -0
- package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
- package/esm/keri/npm/src/npm/runtime-web.js +3 -0
- package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
- package/esm/keri/npm/src/runtime/index.js +51 -4
- package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
- package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
- package/esm/keri/npm/src/runtime/web.js +10 -0
- package/esm/keri/npm/src/vdr/tel-publication.js +16 -0
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +15 -2
- package/types/acdc/authoring.d.ts +54 -0
- package/types/acdc/authoring.d.ts.map +1 -0
- package/types/acdc/custody.d.ts +77 -0
- package/types/acdc/custody.d.ts.map +1 -0
- package/types/acdc/dhking.d.ts +94 -3
- package/types/acdc/dhking.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +4 -0
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +6 -1
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/acdc/scheming.d.ts +2 -0
- package/types/acdc/scheming.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts +58 -19
- package/types/acdc/unblinding.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +3 -1
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
- package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
- package/types/app/bootstrap/oobiery.d.ts +3 -1
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-revoking.d.ts +3 -0
- package/types/app/credentials/credential-revoking.d.ts.map +1 -1
- package/types/app/credentials/credential-workflows.d.ts +5 -0
- package/types/app/credentials/credential-workflows.d.ts.map +1 -1
- package/types/app/credentials/registry-settling.d.ts +85 -0
- package/types/app/credentials/registry-settling.d.ts.map +1 -0
- package/types/app/credentials/root-replicating.d.ts +56 -44
- package/types/app/credentials/root-replicating.d.ts.map +1 -1
- package/types/app/credentials/root-replicator.d.ts +105 -0
- package/types/app/credentials/root-replicator.d.ts.map +1 -0
- package/types/app/credentials/tel-completion.d.ts +55 -0
- package/types/app/credentials/tel-completion.d.ts.map +1 -0
- package/types/app/delivery/forwarding.d.ts +6 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/challenging.d.ts +54 -0
- package/types/app/identity/challenging.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +21 -4
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/delegation-approval.d.ts +228 -0
- package/types/app/identity/delegation-approval.d.ts.map +1 -0
- package/types/app/identity/event-completion.d.ts +151 -0
- package/types/app/identity/event-completion.d.ts.map +1 -0
- package/types/app/identity/habbing.d.ts +67 -2
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +49 -3
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/ipex/group-ipex.d.ts +247 -0
- package/types/app/ipex/group-ipex.d.ts.map +1 -0
- package/types/app/ipex/group-issuance.d.ts +281 -0
- package/types/app/ipex/group-issuance.d.ts.map +1 -0
- package/types/app/ipex/ipex-admitting.d.ts +47 -0
- package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
- package/types/app/ipex/ipex-conversation.d.ts +195 -0
- package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
- package/types/app/ipex/ipex-discloser.d.ts +156 -0
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
- package/types/app/ipex/ipex-granting.d.ts +145 -0
- package/types/app/ipex/ipex-granting.d.ts.map +1 -0
- package/types/app/ipex/ipex-grouping.d.ts +18 -0
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +443 -0
- package/types/app/ipex/issuance.d.ts.map +1 -0
- package/types/app/ipex/pending-presentations.d.ts +25 -0
- package/types/app/ipex/pending-presentations.d.ts.map +1 -0
- package/types/app/ipex/presentation-files.d.ts +47 -0
- package/types/app/ipex/presentation-files.d.ts.map +1 -0
- package/types/app/ipex/presenting.d.ts +298 -0
- package/types/app/ipex/presenting.d.ts.map +1 -0
- package/types/app/ipex/receive-issuance.d.ts +99 -0
- package/types/app/ipex/receive-issuance.d.ts.map +1 -0
- package/types/app/ipex/unblinding-workflow.d.ts +255 -0
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
- package/types/app/mailbox/ipex-arrival.d.ts +104 -0
- package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
- package/types/app/mailbox/kel-publisher.d.ts +141 -0
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
- package/types/app/mailbox/kel-publishing.d.ts +70 -0
- package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
- package/types/app/mailbox/kel-submission.d.ts +18 -0
- package/types/app/mailbox/kel-submission.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-admin.d.ts +113 -0
- package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-poller.d.ts +92 -3
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +3 -0
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +196 -0
- package/types/app/multisig/counseling.d.ts.map +1 -0
- package/types/app/multisig/group-members.d.ts +11 -0
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +39 -20
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +91 -22
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposals.d.ts +129 -0
- package/types/app/multisig/proposals.d.ts.map +1 -0
- package/types/app/multisig/proposing.d.ts +125 -0
- package/types/app/multisig/proposing.d.ts.map +1 -0
- package/types/app/notifications/signaling.d.ts +3 -1
- package/types/app/notifications/signaling.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +13 -0
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +7 -1
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-workflows.d.ts +98 -0
- package/types/app/queries/query-workflows.d.ts.map +1 -0
- package/types/app/runtime/agent-runtime.d.ts +72 -25
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +2 -1
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/delivery-outbox.d.ts +68 -0
- package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
- package/types/app/runtime/doing.d.ts +27 -0
- package/types/app/runtime/doing.d.ts.map +1 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
- package/types/app/runtime/operation-owners.d.ts +137 -0
- package/types/app/runtime/operation-owners.d.ts.map +1 -0
- package/types/app/runtime/retry-backoff.d.ts +49 -0
- package/types/app/runtime/retry-backoff.d.ts.map +1 -0
- package/types/app/runtime/workflow-contract.d.ts +79 -0
- package/types/app/runtime/workflow-contract.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/cli/common/event-completion.d.ts +26 -0
- package/types/cli/common/event-completion.d.ts.map +1 -0
- package/types/cli/common/runtime-workers.d.ts +23 -0
- package/types/cli/common/runtime-workers.d.ts.map +1 -0
- package/types/cli/credentials/ipex.d.ts.map +1 -1
- package/types/cli/credentials/vc.d.ts +1 -1
- package/types/cli/credentials/vc.d.ts.map +1 -1
- package/types/cli/endpoints/did.d.ts.map +1 -1
- package/types/cli/endpoints/oobi.d.ts +3 -1
- package/types/cli/endpoints/oobi.d.ts.map +1 -1
- package/types/cli/identity/challenge.d.ts +1 -1
- package/types/cli/identity/challenge.d.ts.map +1 -1
- package/types/cli/identity/delegate.d.ts +14 -1
- package/types/cli/identity/delegate.d.ts.map +1 -1
- package/types/cli/identity/incept.d.ts.map +1 -1
- package/types/cli/identity/interact.d.ts.map +1 -1
- package/types/cli/identity/rotate.d.ts.map +1 -1
- package/types/cli/index.d.ts +3 -1
- package/types/cli/index.d.ts.map +1 -1
- package/types/cli/messaging/group-join.d.ts +53 -0
- package/types/cli/messaging/group-join.d.ts.map +1 -0
- package/types/cli/messaging/group-wait.d.ts +34 -0
- package/types/cli/messaging/group-wait.d.ts.map +1 -0
- package/types/cli/messaging/multisig.d.ts +28 -5
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/cli/messaging/root-copy-lines.d.ts +39 -0
- package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
- package/types/core/cues.d.ts +11 -0
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +14 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +1 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/records.d.ts +61 -0
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +6 -0
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/basing.d.ts +8 -2
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +59 -0
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
- package/types/db/indexeddb.d.ts +37 -0
- package/types/db/indexeddb.d.ts.map +1 -0
- package/types/db/keeping.d.ts +5 -2
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/store-lock.d.ts +72 -0
- package/types/db/store-lock.d.ts.map +1 -0
- package/types/npm/db-indexeddb.d.ts +4 -0
- package/types/npm/db-indexeddb.d.ts.map +1 -0
- package/types/npm/runtime-web.d.ts +4 -0
- package/types/npm/runtime-web.d.ts.map +1 -0
- package/types/runtime/index.d.ts +41 -6
- package/types/runtime/index.d.ts.map +1 -1
- package/types/runtime/web/output-barrier.d.ts +30 -0
- package/types/runtime/web/output-barrier.d.ts.map +1 -0
- package/types/runtime/web/persistent-storage.d.ts +36 -0
- package/types/runtime/web/persistent-storage.d.ts.map +1 -0
- package/types/runtime/web.d.ts +11 -0
- package/types/runtime/web.d.ts.map +1 -0
- package/types/vdr/tel-publication.d.ts +6 -0
- package/types/vdr/tel-publication.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
- package/types/cli/common/tel-completion.d.ts +0 -8
- package/types/cli/common/tel-completion.d.ts.map +0 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ValidationError } from "../../core/errors.js";
|
|
2
|
+
import { revokeCredential, } from "../credentials/credential-revoking.js";
|
|
3
|
+
import { createCredential, inceptCredentialRegistry, } from "../credentials/credential-workflows.js";
|
|
4
|
+
import { groupSigningMembers, localGroupMember, uniqueMembers } from "./group-members.js";
|
|
5
|
+
import { MULTISIG_ICP_ROUTE, MULTISIG_IXN_ROUTE, MULTISIG_ROT_ROUTE } from "./grouping.js";
|
|
6
|
+
import { remoteGroupMembers } from "./multisig-messaging.js";
|
|
7
|
+
import { approveAcdcV2Registry, commitAcceptedGroupMembers, publishAcdcV2Registry, publishProposal, } from "./multisig-workflows.js";
|
|
8
|
+
/** Propose a new group: create this member's inception and publish it. */
|
|
9
|
+
export function* proposeGroupInception(deps, member, alias, { smids, rmids = smids, ...args }, inputs) {
|
|
10
|
+
// Publishing needs a route to every other member. Refuse before the group habitat exists, so a call that could
|
|
11
|
+
// not be sent leaves nothing behind and the same alias can be used again.
|
|
12
|
+
for (const other of remoteGroupMembers(deps.hby, member, uniqueMembers([...smids, ...rmids]))) {
|
|
13
|
+
if (!deps.postman.canReach(member.pre, other)) {
|
|
14
|
+
throw new ValidationError(`Group member ${other} cannot be reached: no end role is known for it. Resolve its OOBI first.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const created = deps.hby.makeGroupHab(alias, member, [...smids], [...rmids], undefined, args);
|
|
18
|
+
const event = { pre: created.hab.pre, sn: created.serder.sn ?? 0, said: created.serder.said };
|
|
19
|
+
deps.counselor.start(event, inputs);
|
|
20
|
+
const sent = yield* publishProposal(deps.hby, deps.protocol, deps.postman, member, uniqueMembers([...smids, ...rmids]), {
|
|
21
|
+
route: MULTISIG_ICP_ROUTE,
|
|
22
|
+
attrs: { smids: [...smids], rmids: [...rmids], ...(args.delpre ? { delegator: args.delpre } : {}) },
|
|
23
|
+
}, created.message);
|
|
24
|
+
return { ...sent, route: MULTISIG_ICP_ROUTE, group: created.hab.pre, event, smids, rmids };
|
|
25
|
+
}
|
|
26
|
+
/** Propose a group rotation, including member add or remove through new `smids` / `rmids`. */
|
|
27
|
+
export function* proposeGroupRotation(deps, group, { smids: newSmids, rmids: newRmids, ...args } = {}, inputs) {
|
|
28
|
+
const { hby } = deps;
|
|
29
|
+
const rotated = hby.rotateGroupHab(group.name, newSmids && [...newSmids], newRmids && [...newRmids], args);
|
|
30
|
+
const smids = newSmids?.length ? newSmids : groupSigningMembers(hby, rotated.hab.pre);
|
|
31
|
+
const rmids = newRmids?.length ? newRmids : smids;
|
|
32
|
+
const event = { pre: rotated.hab.pre, sn: rotated.serder.sn, said: rotated.serder.said };
|
|
33
|
+
deps.counselor.start(event, inputs);
|
|
34
|
+
const sent = yield* publishProposal(hby, deps.protocol, deps.postman, localGroupMember(hby, rotated.hab.pre), uniqueMembers([...smids, ...rmids]), { route: MULTISIG_ROT_ROUTE, attrs: { gid: rotated.hab.pre, smids: [...smids], rmids: [...rmids] } }, rotated.message);
|
|
35
|
+
return { ...sent, route: MULTISIG_ROT_ROUTE, group: rotated.hab.pre, event, smids, rmids };
|
|
36
|
+
}
|
|
37
|
+
/** Propose a group interaction event carrying `data`. */
|
|
38
|
+
export function* proposeGroupInteraction(deps, group, data, inputs, version) {
|
|
39
|
+
const { hby } = deps;
|
|
40
|
+
const created = hby.interactGroupHab(group.name, undefined, { data, version });
|
|
41
|
+
const smids = groupSigningMembers(hby, created.hab.pre);
|
|
42
|
+
const event = { pre: created.hab.pre, sn: created.serder.sn, said: created.serder.said };
|
|
43
|
+
deps.counselor.start(event, inputs);
|
|
44
|
+
const sent = yield* publishProposal(hby, deps.protocol, deps.postman, localGroupMember(hby, created.hab.pre), smids, { route: MULTISIG_IXN_ROUTE, attrs: { gid: created.hab.pre, smids } }, created.message);
|
|
45
|
+
return { ...sent, route: MULTISIG_IXN_ROUTE, group: created.hab.pre, event, smids, rmids: [] };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Commit the members a proposed rotation named, once the rotation is accepted and
|
|
49
|
+
* is the group's latest establishment event. Idempotent; false until then, so a
|
|
50
|
+
* proposed newcomer is never adopted early. Other event kinds commit nothing.
|
|
51
|
+
*
|
|
52
|
+
* @throws ValidationError when the event is not an accepted event body held locally.
|
|
53
|
+
*/
|
|
54
|
+
export function settleProposedRotation(deps, result) {
|
|
55
|
+
if (result.route !== MULTISIG_ROT_ROUTE)
|
|
56
|
+
return false;
|
|
57
|
+
const serder = deps.hby.db.getEvtSerder(result.event.pre, result.event.said);
|
|
58
|
+
if (!serder)
|
|
59
|
+
throw new ValidationError(`No rotation ${result.event.said} is held for ${result.event.pre}.`);
|
|
60
|
+
return commitAcceptedGroupMembers(deps.hby, serder, result.smids, result.rmids);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Propose an ACDC v2 registry event (`rip` or `bup`): author the group anchor
|
|
64
|
+
* that seals it, process this member's own contribution, hand the anchor to the
|
|
65
|
+
* Counselor and publish the proposal. The proposer's contribution is also its
|
|
66
|
+
* approval. Returns without waiting; the anchor's progress is
|
|
67
|
+
* `counselor.status(result.event)`. A `bup` needs its `opening`.
|
|
68
|
+
*
|
|
69
|
+
* @throws ValidationError for a group that is not joined and accepted, or a TEL event the group cannot propose.
|
|
70
|
+
*/
|
|
71
|
+
export function* proposeRegistryEvent(deps, group, event, opening, inputs) {
|
|
72
|
+
const { hby } = deps;
|
|
73
|
+
const approval = yield* approveAcdcV2Registry(hby, deps.protocol, group, event, { opening, resume: true });
|
|
74
|
+
const anchorSaid = approval[0].sad?.a?.anc;
|
|
75
|
+
const anchor = anchorSaid ? hby.db.getEvtSerder(group.pre, anchorSaid) : null;
|
|
76
|
+
if (!anchor || anchor.sn === null)
|
|
77
|
+
throw new ValidationError("Registry proposal lost its group anchor.");
|
|
78
|
+
const anchorRef = { pre: group.pre, sn: anchor.sn, said: anchor.said };
|
|
79
|
+
deps.counselor.start(anchorRef, inputs);
|
|
80
|
+
const sent = yield* publishAcdcV2Registry(hby, deps.postman, group, approval);
|
|
81
|
+
const regid = event.ilk === "rip" ? event.said : event.regid;
|
|
82
|
+
const accepted = deps.registryStore?.seqEvent(regid, Number(BigInt(`0x${event.sad.n}`)))?.said === event.said;
|
|
83
|
+
return {
|
|
84
|
+
route: approval[0].route,
|
|
85
|
+
said: approval[0].said,
|
|
86
|
+
embedded: event.said,
|
|
87
|
+
group: group.pre,
|
|
88
|
+
accepted,
|
|
89
|
+
...sent,
|
|
90
|
+
event: anchorRef,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function proposedGroup(result, what) {
|
|
94
|
+
if (!result.group)
|
|
95
|
+
throw new ValidationError(`${what} must be proposed by a local group.`);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Propose a group's legacy credential registry (`vcp`): author the anchoring group event,
|
|
100
|
+
* process this member's contribution, hand the anchor to the Counselor and publish the
|
|
101
|
+
* proposal. Returns without waiting; the anchor's progress is `counselor.status(result.group.event)`
|
|
102
|
+
* and the registry's is `waitForTelEvent`.
|
|
103
|
+
*
|
|
104
|
+
* @throws ValidationError when `group` is not a local group or the registry name is taken.
|
|
105
|
+
*/
|
|
106
|
+
export function* proposeCredentialRegistry(deps, group, options, inputs) {
|
|
107
|
+
const result = proposedGroup(yield* inceptCredentialRegistry(deps.rgy, deps.input, deps.postman, group, options), "A group registry");
|
|
108
|
+
deps.counselor.start(result.group.event, inputs);
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
/** Propose a group credential issuance (`iss`) the way {@link proposeCredentialRegistry} proposes a registry. */
|
|
112
|
+
export function* proposeCredentialIssue(deps, options, inputs) {
|
|
113
|
+
const result = proposedGroup(yield* createCredential(deps.rgy, deps.input, deps.postman, options), "A group credential");
|
|
114
|
+
deps.counselor.start(result.group.event, inputs);
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
/** Propose a group credential revocation (`rev`) the way {@link proposeCredentialRegistry} proposes a registry. */
|
|
118
|
+
export function* proposeCredentialRevocation(deps, options, inputs) {
|
|
119
|
+
const result = proposedGroup(yield* revokeCredential(deps.rgy, deps.input, deps.postman, options), "A group revocation");
|
|
120
|
+
deps.counselor.start(result.group.event, inputs);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
@@ -11,7 +11,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
11
11
|
};
|
|
12
12
|
var _Signal_raw, _Signal_pad, _Signal_ckey;
|
|
13
13
|
import { MtrDex, Salter } from "cesr-ts";
|
|
14
|
-
import {
|
|
14
|
+
import { doEvery, PROTOCOL_PACING } from "../runtime/doing.js";
|
|
15
|
+
import { systemClock } from "../runtime/runtime-clock.js";
|
|
15
16
|
const textEncoder = new TextEncoder();
|
|
16
17
|
const textDecoder = new TextDecoder();
|
|
17
18
|
function randomNonce() {
|
|
@@ -162,11 +163,10 @@ export class Signaler {
|
|
|
162
163
|
this.closed = true;
|
|
163
164
|
this.clear();
|
|
164
165
|
}
|
|
165
|
-
*signalDo() {
|
|
166
|
-
|
|
166
|
+
*signalDo(clock = systemClock, pacing = PROTOCOL_PACING) {
|
|
167
|
+
return yield* doEvery(clock, pacing.tockMs, function* () {
|
|
167
168
|
this.processOnce();
|
|
168
|
-
|
|
169
|
-
}
|
|
169
|
+
}.bind(this));
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
Object.defineProperty(Signaler, "SignalTimeoutMs", {
|
|
@@ -144,7 +144,7 @@ function* dispatchMessage(envelope, revery, kevery, exchanger, tevery, mailboxAi
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
if (serder.ilk === "qry" && !["logs", "ksn", "mbx", "tels", "tsn"].includes(serder.route ?? "")
|
|
147
|
-
&& qvy?.resource
|
|
147
|
+
&& !(qvy?.claims ? qvy.claims(serder) : qvy?.resource === serder.route)) {
|
|
148
148
|
return { envelope, decision: { kind: "drop", reason: "missingProcessor" } };
|
|
149
149
|
}
|
|
150
150
|
const result = kevery.kramer?.intake(envelope);
|
|
@@ -487,6 +487,31 @@ export function copyAuxiliaryQuery(envelope) {
|
|
|
487
487
|
copied.tsgs.splice(0, copied.tsgs.length, ...normalized.tsgs);
|
|
488
488
|
return copied;
|
|
489
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Serialize an auxiliary query without nested evidence so a later process can rebuild it: its own frame with
|
|
492
|
+
* every attachment group (plus `children`, nested evidence already encoded as counted frames), then the
|
|
493
|
+
* normalized proof KRAM may have completed from earlier inputs.
|
|
494
|
+
*/
|
|
495
|
+
export function auxiliaryQueryWire(envelope, children = []) {
|
|
496
|
+
const version = envelope.gvrsn ?? envelope.serder.gvrsn ?? envelope.serder.pvrsn;
|
|
497
|
+
const frame = concatBytes(Counter.makeGVC(version), envelope.serder.raw, Counter.enclose({
|
|
498
|
+
code: "AttachmentGroup",
|
|
499
|
+
version,
|
|
500
|
+
qb64: concatBytes(...envelope.attachmentGroups.map(group => group.raw), ...children),
|
|
501
|
+
}));
|
|
502
|
+
const proof = serializeMessage(envelope.serder, { tsgs: envelope.tsgs, gvrsn: version, genusify: true });
|
|
503
|
+
const size = new Uint8Array(4);
|
|
504
|
+
new DataView(size.buffer).setUint32(0, frame.length);
|
|
505
|
+
return concatBytes(size, frame, proof);
|
|
506
|
+
}
|
|
507
|
+
/** Rebuild the envelope {@link auxiliaryQueryWire} serialized. */
|
|
508
|
+
export function restoreAuxiliaryQuery(wire, local = false) {
|
|
509
|
+
const length = new DataView(wire.buffer, wire.byteOffset, 4).getUint32(0);
|
|
510
|
+
const restored = envelopeFromFrame(parseBytes(wire.slice(4, 4 + length))[0], local);
|
|
511
|
+
const normalized = envelopeFromFrame(parseBytes(wire.slice(4 + length))[0]);
|
|
512
|
+
restored.tsgs.splice(0, restored.tsgs.length, ...normalized.tsgs);
|
|
513
|
+
return restored;
|
|
514
|
+
}
|
|
490
515
|
/** Normalize the actual query endorsements for ingress and per-request authorization. */
|
|
491
516
|
export function queryEnvelopeFromDispatch(envelope) {
|
|
492
517
|
const lastSsg = envelope.ssgs.at(-1);
|
|
@@ -6,8 +6,14 @@ import { consoleLogger } from "../../core/logger.js";
|
|
|
6
6
|
import { BasicReplyRouteHandler, Revery } from "../../core/routing.js";
|
|
7
7
|
import { Exchanger } from "../exchanges/exchanging.js";
|
|
8
8
|
import { QueryReplies } from "../queries/query-replies.js";
|
|
9
|
-
import {
|
|
9
|
+
import { systemClock } from "../runtime/runtime-clock.js";
|
|
10
|
+
import { waitOnClock } from "../runtime/workflow-contract.js";
|
|
10
11
|
import { dispatchEnvelope, envelopeFromFrame, queryEnvelopeFromDispatch, } from "./parsering.js";
|
|
12
|
+
/**
|
|
13
|
+
* Wait after every escrow pass, as KERIpy's Doist cycle (`tock` 0.03125 s, app/directing.py) paces its `escrowDo`,
|
|
14
|
+
* which runs one full pass per cycle. A pass is never skipped or shortened; this is the time others get between passes.
|
|
15
|
+
*/
|
|
16
|
+
export const ESCROW_TOCK_MS = 31.25;
|
|
11
17
|
/**
|
|
12
18
|
* Identify a refusal of one already-extracted message, which must not end its stream.
|
|
13
19
|
*
|
|
@@ -255,10 +261,10 @@ export class ProtocolProcessor {
|
|
|
255
261
|
* - mirrors the dedicated `escrowDo` loop rather than folding escrow
|
|
256
262
|
* processing into parser ingress
|
|
257
263
|
*/
|
|
258
|
-
*escrowDo() {
|
|
264
|
+
*escrowDo(clock = systemClock) {
|
|
259
265
|
while (true) {
|
|
260
266
|
yield* this.processEscrowsOnce();
|
|
261
|
-
yield*
|
|
267
|
+
yield* waitOnClock(clock, ESCROW_TOCK_MS);
|
|
262
268
|
}
|
|
263
269
|
}
|
|
264
270
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { call, race, sleep, spawn } from "effection";
|
|
2
|
+
import { ValidationError } from "../../core/errors.js";
|
|
3
|
+
import { isLocalGroupHab } from "../multisig/group-members.js";
|
|
4
|
+
import { AnchorQuerier, KeyStateNoticer } from "./querying.js";
|
|
5
|
+
/** One elapsed deadline covers query sending and independently received evidence. */
|
|
6
|
+
export const QUERY_TIMEOUT_MS = 10_000;
|
|
7
|
+
/** Reject group habs: a query must be signed by one member, not by a group needing more signatures. */
|
|
8
|
+
export function requireQueryRequester(hby, hab) {
|
|
9
|
+
if (isLocalGroupHab(hby, hab)) {
|
|
10
|
+
throw new ValidationError("Query --alias must select a member requester, not a group requiring additional signatures.");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Durable anchor status (`scope: "durable"`): the accepted KEL of `prefix` already holds the exact seal. */
|
|
14
|
+
export function anchorQueryStatus(deps, prefix, anchor) {
|
|
15
|
+
return deps.hby.db.fetchLastSealingEventByEventSeal(prefix, anchor)
|
|
16
|
+
? { state: "completed", scope: "durable" }
|
|
17
|
+
: { state: "active", phase: "awaitingEvidence", scope: "durable" };
|
|
18
|
+
}
|
|
19
|
+
/** Start a key-state query in the caller's scope. */
|
|
20
|
+
export function* beginKeyStateQuery(deps, target) {
|
|
21
|
+
requireQueryRequester(deps.hby, target.hab);
|
|
22
|
+
const workflow = new KeyStateNoticer(deps.hby.db, deps.querying, target.prefix, deps.cues, {
|
|
23
|
+
signer: target.hab.pre,
|
|
24
|
+
});
|
|
25
|
+
return yield* startQuery(deps, target.prefix, workflow);
|
|
26
|
+
}
|
|
27
|
+
/** Start an anchor query in the caller's scope. */
|
|
28
|
+
export function* beginAnchorQuery(deps, target) {
|
|
29
|
+
requireQueryRequester(deps.hby, target.hab);
|
|
30
|
+
const workflow = new AnchorQuerier(deps.hby.db, deps.querying, target.prefix, target.anchor, {
|
|
31
|
+
signer: target.hab.pre,
|
|
32
|
+
});
|
|
33
|
+
return yield* startQuery(deps, target.prefix, workflow);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Query current key state for `prefix` and wait for accepted evidence.
|
|
37
|
+
*
|
|
38
|
+
* @returns `settled` (status `completed`), or `timed-out`; a timeout is not permission to treat
|
|
39
|
+
* stale local state as success. Workflow failures propagate.
|
|
40
|
+
*/
|
|
41
|
+
export function* queryKeyState(deps, target, options = {}) {
|
|
42
|
+
return yield* beginThenWait(beginKeyStateQuery(deps, target), options);
|
|
43
|
+
}
|
|
44
|
+
/** Query for an accepted KEL event holding the exact seal `target.anchor`; see {@link queryKeyState}. */
|
|
45
|
+
export function* queryAnchor(deps, target, options = {}) {
|
|
46
|
+
return yield* beginThenWait(beginAnchorQuery(deps, target), options);
|
|
47
|
+
}
|
|
48
|
+
/** Spawn the workflow in the caller's scope. */
|
|
49
|
+
function* startQuery(deps, prefix, workflow) {
|
|
50
|
+
let completed = false;
|
|
51
|
+
const status = () => completed
|
|
52
|
+
? { state: "completed", scope: "process" }
|
|
53
|
+
: { state: "active", phase: "awaitingEvidence", scope: "process" };
|
|
54
|
+
const observing = yield* spawn(function* () {
|
|
55
|
+
yield* workflow.queryDo();
|
|
56
|
+
completed = true;
|
|
57
|
+
});
|
|
58
|
+
deps.changes?.push({ kind: "query", id: prefix });
|
|
59
|
+
return {
|
|
60
|
+
prefix,
|
|
61
|
+
status,
|
|
62
|
+
*wait(options = {}) {
|
|
63
|
+
const outcome = yield* waitForQuery(observing, status, options.timeoutMs ?? QUERY_TIMEOUT_MS);
|
|
64
|
+
if (outcome.outcome === "settled")
|
|
65
|
+
deps.changes?.push({ kind: "query", id: prefix });
|
|
66
|
+
return outcome;
|
|
67
|
+
},
|
|
68
|
+
halt: () => observing.halt(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Observe completion within the window without transferring task ownership.
|
|
73
|
+
* The race cancels only its observation when the timer wins; the run's `halt`
|
|
74
|
+
* joins the original task.
|
|
75
|
+
*/
|
|
76
|
+
function* waitForQuery(observing, status, timeoutMs) {
|
|
77
|
+
const done = yield* race([
|
|
78
|
+
call(function* () {
|
|
79
|
+
yield* observing;
|
|
80
|
+
return true;
|
|
81
|
+
}),
|
|
82
|
+
call(function* () {
|
|
83
|
+
yield* sleep(timeoutMs);
|
|
84
|
+
return false;
|
|
85
|
+
}),
|
|
86
|
+
]);
|
|
87
|
+
return done ? { outcome: "settled", status: status() } : { outcome: "timed-out", status: status(), timeoutMs };
|
|
88
|
+
}
|
|
89
|
+
/** begin + wait, halting the run on every exit path. */
|
|
90
|
+
function* beginThenWait(begin, options) {
|
|
91
|
+
const run = yield* begin;
|
|
92
|
+
try {
|
|
93
|
+
return yield* run.wait(options);
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
yield* run.halt();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { WireParseError } from "cesr-ts";
|
|
2
2
|
import { call, resource, spawn, suspend } from "effection";
|
|
3
|
-
import { Dhke } from "../../acdc/dhking.js";
|
|
4
3
|
import { RegistryObserver } from "../../acdc/observing.js";
|
|
5
4
|
import { createRegery as createAcdcRegery } from "../../acdc/registraring.js";
|
|
6
5
|
import { RegistryRoot } from "../../acdc/salting.js";
|
|
7
|
-
import { Unblind } from "../../acdc/unblinding.js";
|
|
8
6
|
import { Deck } from "../../core/deck.js";
|
|
9
|
-
import { DatabaseNotOpenError
|
|
7
|
+
import { DatabaseNotOpenError } from "../../core/errors.js";
|
|
10
8
|
import { Kevery } from "../../core/kel/eventing.js";
|
|
11
9
|
import { Kramer } from "../../core/mailbox/kraming.js";
|
|
12
10
|
import { CREDENTIAL_MAILBOX_TOPIC, DELEGATE_MAILBOX_TOPIC, RECEIPT_MAILBOX_TOPIC, REPLAY_MAILBOX_TOPIC, REPLY_MAILBOX_TOPIC, } from "../../core/mailbox/mailbox-topics.js";
|
|
11
|
+
import { Roles } from "../../core/roles.js";
|
|
13
12
|
import { Revery } from "../../core/routing.js";
|
|
14
13
|
import { openOwner } from "../../db/core/store-owner.js";
|
|
15
14
|
import { Mailboxer } from "../../db/mailbox/mailboxing.js";
|
|
@@ -28,10 +27,12 @@ import { loadChallengeHandlers } from "../identity/challenging.js";
|
|
|
28
27
|
import { Anchorer, loadDelegationHandlers } from "../identity/delegating.js";
|
|
29
28
|
import { loadIpexHandlers } from "../ipex/ipexing.js";
|
|
30
29
|
import { ForwardHandler } from "../mailbox/forward-handler.js";
|
|
30
|
+
import { KEL_PUBLISHER_PACING, KelPublisher, kelPublisherDo } from "../mailbox/kel-publisher.js";
|
|
31
31
|
import { MailboxDirector } from "../mailbox/mailbox-director.js";
|
|
32
|
-
import { MailboxPoller } from "../mailbox/mailbox-poller.js";
|
|
32
|
+
import { MAILBOX_POLLER_PACING, MailboxPoller, } from "../mailbox/mailbox-poller.js";
|
|
33
33
|
import { mailboxerOptionsForHabery } from "../mailbox/mailboxing.js";
|
|
34
34
|
import { mailboxTopicForRoute } from "../mailbox/topic-routing.js";
|
|
35
|
+
import { Counselor } from "../multisig/counseling.js";
|
|
35
36
|
import { loadMultisigHandlers } from "../multisig/grouping.js";
|
|
36
37
|
import { noterOptionsForHabery, Notifier } from "../notifications/notifying.js";
|
|
37
38
|
import { Signaler } from "../notifications/signaling.js";
|
|
@@ -41,7 +42,11 @@ import { QueryReplies } from "../queries/query-replies.js";
|
|
|
41
42
|
import { WitnessInquisitor } from "../queries/witness-inquisitor.js";
|
|
42
43
|
import { Receiptor } from "../witness/receipting.js";
|
|
43
44
|
import { cueDo } from "./cue-runtime.js";
|
|
44
|
-
import {
|
|
45
|
+
import { doEvery, PROTOCOL_PACING } from "./doing.js";
|
|
46
|
+
import { IpexAuxiliaries } from "./ipex-auxiliaries.js";
|
|
47
|
+
import { composeOwners, operationOwnersDo, OWNER_PACING, } from "./operation-owners.js";
|
|
48
|
+
import { signalerChangeSink } from "./workflow-contract.js";
|
|
49
|
+
import { observeUntil } from "./workflow-contract.js";
|
|
45
50
|
/**
|
|
46
51
|
* Create the shared runtime composition root used by CLI commands and
|
|
47
52
|
* `tufa agent`.
|
|
@@ -59,15 +64,6 @@ import { runtimeTurn } from "./runtime-turn.js";
|
|
|
59
64
|
* @throws Dependency mismatch/acquisition errors propagate after owned resource cleanup.
|
|
60
65
|
*/
|
|
61
66
|
export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
62
|
-
const selected = options.ipexAuxiliary;
|
|
63
|
-
if (selected) {
|
|
64
|
-
if (options.kram?.enabled !== true) {
|
|
65
|
-
throw new ValidationError("IPEX auxiliary runtime requires explicitly enabled KRAM");
|
|
66
|
-
}
|
|
67
|
-
if (!selected.hab.pre || hby.habs.get(selected.hab.pre) !== selected.hab) {
|
|
68
|
-
throw new ValidationError("IPEX auxiliary runtime requires its actual local habitat");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
67
|
const injectedSignaler = options.signaler ?? options.notifier?.signaler;
|
|
72
68
|
if ((options.notifier && options.notifier.signator !== hby.signator)
|
|
73
69
|
|| (options.noter && options.notifier && options.noter !== options.notifier.noter)
|
|
@@ -102,8 +98,6 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
102
98
|
const acdc = options.acdc ?? (!hby.readonly ? (yield* openAcdcRegeryForHabery(hby)) : null);
|
|
103
99
|
const ownsAcdcRegery = options.acdc === undefined && acdc !== null;
|
|
104
100
|
const acdcRegery = acdc;
|
|
105
|
-
if (selected && !acdc)
|
|
106
|
-
throw new ValidationError("IPEX auxiliary runtime requires a v2 registry");
|
|
107
101
|
// Acquire after stores, before processors/consumers: reverse teardown joins consumers, clears cues, closes stores.
|
|
108
102
|
const cues = yield* resource(function* (provide) {
|
|
109
103
|
const owned = new Deck();
|
|
@@ -135,25 +129,21 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
135
129
|
const kvy = new Kevery(hby.db, { cues: protocolCues, rvy: revery, messagePolicy: options.messagePolicy, kramer });
|
|
136
130
|
const exc = new Exchanger(hby, { cues: protocolCues, now });
|
|
137
131
|
const registry = acdc ? new RegistryObserver(hby.db, acdc.store) : null;
|
|
138
|
-
|
|
132
|
+
// Every runtime with a v2 registry store owns the per-identifier DH and Unblind owners: one dispatch path.
|
|
133
|
+
const ipex = registry
|
|
139
134
|
? yield* resource(function* (provide) {
|
|
140
|
-
const
|
|
141
|
-
? { kind: "dhke", owner: new Dhke({ hab: selected.hab, exc, registryStore: registry.store, rvy: revery, now }) }
|
|
142
|
-
: {
|
|
143
|
-
kind: "unblind",
|
|
144
|
-
owner: new Unblind({ hab: selected.hab, exc, registry, states: selected.states, rvy: revery, now }),
|
|
145
|
-
};
|
|
135
|
+
const owners = new IpexAuxiliaries(exc, registry, revery, now, options.kram?.enabled === true);
|
|
146
136
|
try {
|
|
147
|
-
revery.rtr
|
|
148
|
-
yield* provide(
|
|
137
|
+
owners.registerReplyRoutes(revery.rtr);
|
|
138
|
+
yield* provide(owners);
|
|
149
139
|
}
|
|
150
140
|
finally {
|
|
151
|
-
|
|
141
|
+
owners.close();
|
|
152
142
|
}
|
|
153
143
|
})
|
|
154
144
|
: null;
|
|
155
145
|
const replies = new QueryReplies(cues);
|
|
156
|
-
const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies,
|
|
146
|
+
const protocol = new ProtocolProcessor(kvy, revery, exc, vdr?.tvy ?? null, vdr?.vry ?? null, registry, protocolCues, cues, replies, ipex ?? undefined);
|
|
157
147
|
const reactor = new Reactor(protocol);
|
|
158
148
|
loadChallengeHandlers(hby.db, exc);
|
|
159
149
|
loadDelegationHandlers(hby, exc, notifier);
|
|
@@ -165,7 +155,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
165
155
|
grantWalk: options.grantWalk,
|
|
166
156
|
});
|
|
167
157
|
// Construction adopts stored copies an earlier handler-less Exchanger left unescrowed.
|
|
168
|
-
const registryRoot = options.registryRoots !== "refuse" && acdc
|
|
158
|
+
const registryRoot = options.registryRoots !== "refuse" && acdc
|
|
159
|
+
? new RegistryRoot(hby, acdc, notifier, options.operationStores?.changes ?? (signaler ? signalerChangeSink(signaler) : undefined))
|
|
160
|
+
: null;
|
|
169
161
|
if (registryRoot)
|
|
170
162
|
exc.addHandler(registryRoot);
|
|
171
163
|
const mailboxDirector = yield* resource(function* (provide) {
|
|
@@ -204,7 +196,25 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
204
196
|
// Copies ride the credential topic; the refuser adds no mailbox topic of its own.
|
|
205
197
|
if (options.registryRoots === "refuse")
|
|
206
198
|
exc.addHandler(new RouteRefuser(RegistryRoot.Route));
|
|
207
|
-
const
|
|
199
|
+
const kelPublisher = new KelPublisher({
|
|
200
|
+
hby,
|
|
201
|
+
http,
|
|
202
|
+
clock,
|
|
203
|
+
changes: signaler ? signalerChangeSink(signaler) : undefined,
|
|
204
|
+
retry: options.kelPublishRetry,
|
|
205
|
+
});
|
|
206
|
+
const mailboxPoller = new MailboxPoller(hby, mailboxDirector, http, clock, {
|
|
207
|
+
onPolled: (pre, mailbox) => kelPublisher.prompt(pre, mailbox),
|
|
208
|
+
onUnauthorized: (pre, mailbox) => kelPublisher.repair(pre, mailbox),
|
|
209
|
+
timeouts: options.mailboxPolling,
|
|
210
|
+
});
|
|
211
|
+
// A mailbox role accepted from a reply (a group member's approved add, an OOBI) is acted on at the next tock.
|
|
212
|
+
revery.onEndRole = (cid, role) => {
|
|
213
|
+
if (role !== Roles.mailbox)
|
|
214
|
+
return;
|
|
215
|
+
kelPublisher.prompt(cid);
|
|
216
|
+
mailboxPoller.prompt(cid);
|
|
217
|
+
};
|
|
208
218
|
for (const topic of [
|
|
209
219
|
DELEGATE_MAILBOX_TOPIC,
|
|
210
220
|
CREDENTIAL_MAILBOX_TOPIC,
|
|
@@ -224,6 +234,36 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
224
234
|
}
|
|
225
235
|
});
|
|
226
236
|
const delegating = new Anchorer(hby, postman, querying, protocol, http, clock);
|
|
237
|
+
// Group receipting reaches TCP-only witnesses as `WitnessReceiptor` does, as KERIpy's Counselor does.
|
|
238
|
+
const groupReceiptor = new Receiptor(hby, protocol, http, clock);
|
|
239
|
+
const counselor = new Counselor(hby, {
|
|
240
|
+
receipt: (pre, options) => groupReceiptor.receipt(pre, { ...options, allowTcp: true }),
|
|
241
|
+
get: (pre, options) => groupReceiptor.get(pre, options),
|
|
242
|
+
}, clock, signaler ? signalerChangeSink(signaler) : undefined, { anchorer: delegating, querying }, {
|
|
243
|
+
rotated: (cue) => {
|
|
244
|
+
kelPublisher.rotated.push(cue);
|
|
245
|
+
owned?.rootReplicator?.prompt(cue.pre);
|
|
246
|
+
},
|
|
247
|
+
}, options.counselorReceiptRetry);
|
|
248
|
+
const owned = acdc && ipex
|
|
249
|
+
? composeOwners({
|
|
250
|
+
hby,
|
|
251
|
+
acdc,
|
|
252
|
+
exc,
|
|
253
|
+
protocol,
|
|
254
|
+
reactor,
|
|
255
|
+
postman,
|
|
256
|
+
receiptor: new Receiptor(hby, protocol, http, clock),
|
|
257
|
+
ipex,
|
|
258
|
+
clock,
|
|
259
|
+
registryRoot,
|
|
260
|
+
mux,
|
|
261
|
+
counselor,
|
|
262
|
+
retry: options.operationRetry,
|
|
263
|
+
queryResendMs: options.issuanceQueryResendMs,
|
|
264
|
+
changes: signaler ? signalerChangeSink(signaler) : undefined,
|
|
265
|
+
}, options.operationStores)
|
|
266
|
+
: null;
|
|
227
267
|
const oobiery = new Oobiery(hby, protocol, revery, http, cues);
|
|
228
268
|
oobiery.registerReplyRoutes(revery.rtr);
|
|
229
269
|
const authenticator = new Authenticator(hby, http);
|
|
@@ -239,7 +279,9 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
239
279
|
replies,
|
|
240
280
|
exc,
|
|
241
281
|
mux,
|
|
242
|
-
|
|
282
|
+
ipex,
|
|
283
|
+
operations: owned?.operations ?? null,
|
|
284
|
+
rootReplicator: owned?.rootReplicator ?? null,
|
|
243
285
|
oobiery,
|
|
244
286
|
authenticator,
|
|
245
287
|
mailboxDirector,
|
|
@@ -247,6 +289,12 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
247
289
|
mailboxPoller,
|
|
248
290
|
postman,
|
|
249
291
|
delegating,
|
|
292
|
+
counselor,
|
|
293
|
+
kelPublisher,
|
|
294
|
+
ownerPacing: options.ownerPacing ?? OWNER_PACING,
|
|
295
|
+
publisherPacing: options.publisherPacing ?? KEL_PUBLISHER_PACING,
|
|
296
|
+
protocolPacing: options.protocolPacing ?? PROTOCOL_PACING,
|
|
297
|
+
pollerPacing: options.pollerPacing ?? MAILBOX_POLLER_PACING,
|
|
250
298
|
querying,
|
|
251
299
|
replyStreams,
|
|
252
300
|
vdr,
|
|
@@ -264,7 +312,7 @@ export function* createAgentRuntime(hby, http, clock, options = {}) {
|
|
|
264
312
|
const failures = [];
|
|
265
313
|
const cleanup = [
|
|
266
314
|
function* () {
|
|
267
|
-
|
|
315
|
+
ipex?.close();
|
|
268
316
|
},
|
|
269
317
|
function* () {
|
|
270
318
|
yield* querying.close();
|
|
@@ -485,6 +533,7 @@ export function runtimePendingState(runtime) {
|
|
|
485
533
|
delegationPending: runtime.hby.db.dpwe.cnt() > 0
|
|
486
534
|
|| runtime.hby.db.dune.cnt() > 0
|
|
487
535
|
|| runtime.hby.db.dpub.cnt() > 0,
|
|
536
|
+
groupPending: runtime.hby.db.gpse.cnt() > 0 || runtime.hby.db.gdee.cnt() > 0 || runtime.hby.db.gpwe.cnt() > 0,
|
|
488
537
|
queriesPending: runtime.querying.hasPendingWork(),
|
|
489
538
|
deliveriesPending: runtime.querying.hasPendingDelivery || runtime.postman.hasPending,
|
|
490
539
|
};
|
|
@@ -506,6 +555,9 @@ export function runtimeHasPendingWork(runtime) {
|
|
|
506
555
|
}
|
|
507
556
|
/**
|
|
508
557
|
* Return true once OOBI acceptance and its ingress/query dependencies settle.
|
|
558
|
+
* This is a whole-runtime drain predicate: any unrelated pending cue, query,
|
|
559
|
+
* delegation or OOBI keeps it false. A command or request that asked for one
|
|
560
|
+
* OOBI must wait with `waitForOobi` (`app/bootstrap/oobi-resolving.ts`) instead.
|
|
509
561
|
* Background receipt delivery is not remote acknowledgement of OOBI acceptance;
|
|
510
562
|
* static OOBI servers may refuse unsolicited posts. Runtime close still joins I/O.
|
|
511
563
|
*
|
|
@@ -536,14 +588,10 @@ export function* runAgentRuntimeUntil(runtime, done, options) {
|
|
|
536
588
|
if (done())
|
|
537
589
|
return;
|
|
538
590
|
const { timeoutMs, ...workerOptions } = options;
|
|
539
|
-
const deadline = Date.now() + timeoutMs;
|
|
540
591
|
const worker = yield* spawn(() => runAgentRuntime(runtime, workerOptions));
|
|
541
592
|
try {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
throw new Error(`Runtime did not converge within ${timeoutMs}ms.`);
|
|
545
|
-
yield* runtimeTurn();
|
|
546
|
-
}
|
|
593
|
+
if (!(yield* observeUntil(done, { timeoutMs })))
|
|
594
|
+
throw new Error(`Runtime did not converge within ${timeoutMs}ms.`);
|
|
547
595
|
}
|
|
548
596
|
finally {
|
|
549
597
|
yield* worker.halt();
|
|
@@ -572,52 +620,55 @@ export { runtimeTurn } from "./runtime-turn.js";
|
|
|
572
620
|
*/
|
|
573
621
|
export function* runAgentRuntime(runtime, options = {}) {
|
|
574
622
|
runtime.querying.configure({ hab: options.hab });
|
|
623
|
+
const pacing = runtime.protocolPacing;
|
|
575
624
|
const telReceiptor = runtime.vdr ? new Receiptor(runtime.hby, runtime.protocol, runtime.http, runtime.clock) : null;
|
|
576
625
|
const tasks = [
|
|
577
626
|
yield* spawn(() => runtime.querying.deliverDo()),
|
|
578
627
|
yield* spawn(() => runtime.postman.deliverDo()),
|
|
579
628
|
...(runtime.vdr && telReceiptor
|
|
580
629
|
? [
|
|
581
|
-
yield* spawn(
|
|
582
|
-
while (true) {
|
|
583
|
-
yield* publishPendingTel(runtime.hby, runtime.vdr.publication, telReceiptor, runtime.http, runtime.clock);
|
|
584
|
-
yield* runtimeTurn();
|
|
585
|
-
}
|
|
586
|
-
}),
|
|
630
|
+
yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => publishPendingTel(runtime.hby, runtime.vdr.publication, telReceiptor, runtime.http, runtime.clock))),
|
|
587
631
|
]
|
|
588
632
|
: []),
|
|
589
633
|
yield* spawn(function* () {
|
|
590
|
-
yield* cueDo(runtime, options);
|
|
634
|
+
yield* cueDo(runtime, options, pacing);
|
|
591
635
|
}),
|
|
592
636
|
yield* spawn(function* () {
|
|
593
|
-
yield* runtime.protocol.escrowDo();
|
|
637
|
+
yield* runtime.protocol.escrowDo(runtime.clock);
|
|
594
638
|
}),
|
|
595
639
|
yield* spawn(function* () {
|
|
596
|
-
yield* runtime.oobiery.oobiDo();
|
|
640
|
+
yield* runtime.oobiery.oobiDo(runtime.clock, pacing);
|
|
597
641
|
}),
|
|
598
642
|
yield* spawn(function* () {
|
|
599
|
-
yield* runtime.authenticator.authDo();
|
|
643
|
+
yield* runtime.authenticator.authDo(runtime.clock, pacing);
|
|
600
644
|
}),
|
|
601
645
|
...(runtime.signaler
|
|
602
646
|
? [
|
|
603
647
|
yield* spawn(function* () {
|
|
604
|
-
yield* runtime.signaler.signalDo();
|
|
648
|
+
yield* runtime.signaler.signalDo(runtime.clock, pacing);
|
|
605
649
|
}),
|
|
606
650
|
]
|
|
607
651
|
: []),
|
|
608
652
|
...(options.pollMailbox ?? true
|
|
609
653
|
? [
|
|
610
654
|
yield* spawn(function* () {
|
|
611
|
-
yield* runtime.mailboxPoller.pollDo((batch) => settleMailboxPollBatch(runtime, batch));
|
|
655
|
+
yield* runtime.mailboxPoller.pollDo((batch) => settleMailboxPollBatch(runtime, batch), runtime.pollerPacing);
|
|
612
656
|
}),
|
|
613
657
|
]
|
|
614
658
|
: []),
|
|
615
|
-
yield* spawn(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
659
|
+
yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => runtime.delegating.processAllOnce())),
|
|
660
|
+
yield* spawn(() => doEvery(runtime.clock, pacing.tockMs, () => runtime.counselor.processOnce())),
|
|
661
|
+
yield* spawn(() => kelPublisherDo(runtime.kelPublisher, runtime.clock, runtime.publisherPacing)),
|
|
662
|
+
...(runtime.operations && runtime.ipex
|
|
663
|
+
? [
|
|
664
|
+
yield* spawn(() => operationOwnersDo({
|
|
665
|
+
operations: runtime.operations,
|
|
666
|
+
rootReplicator: runtime.rootReplicator,
|
|
667
|
+
ipex: runtime.ipex,
|
|
668
|
+
clock: runtime.clock,
|
|
669
|
+
}, runtime.ownerPacing)),
|
|
670
|
+
]
|
|
671
|
+
: []),
|
|
621
672
|
];
|
|
622
673
|
try {
|
|
623
674
|
return yield* suspend();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { doEvery, PROTOCOL_PACING } from "./doing.js";
|
|
2
2
|
/**
|
|
3
3
|
* Use an explicitly selected or sole local habitat; never guess among hosted identities.
|
|
4
4
|
*
|
|
@@ -53,9 +53,6 @@ export function* processCuesOnce(runtime, { hab, queryCues } = {}) {
|
|
|
53
53
|
* @param runtime Borrowed composed runtime containing the actual cue consumers.
|
|
54
54
|
* @param options Explicit signer and optional command-owned query cue destination.
|
|
55
55
|
*/
|
|
56
|
-
export function* cueDo(runtime, options = {}) {
|
|
57
|
-
|
|
58
|
-
yield* processCuesOnce(runtime, options);
|
|
59
|
-
yield* runtimeTurn();
|
|
60
|
-
}
|
|
56
|
+
export function* cueDo(runtime, options = {}, pacing = PROTOCOL_PACING) {
|
|
57
|
+
return yield* doEvery(runtime.clock, pacing.tockMs, () => processCuesOnce(runtime, options));
|
|
61
58
|
}
|