@bcts/frost-hubert 1.0.0-beta.2 → 1.0.0-beta.4
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/dist/bin/frost.mjs +16 -16
- package/dist/cmd/index.mjs +3 -3
- package/dist/{cmd-ChW3eHA8.mjs → cmd-BOzLt8T8.mjs} +20 -20
- package/dist/{cmd-ChW3eHA8.mjs.map → cmd-BOzLt8T8.mjs.map} +1 -1
- package/dist/{common--IfAHVkl.mjs → common-DCyUSYkT.mjs} +2 -2
- package/dist/{common--IfAHVkl.mjs.map → common-DCyUSYkT.mjs.map} +1 -1
- package/dist/{common-4spC1kNw.mjs → common-k2QC6AST.mjs} +2 -2
- package/dist/{common-4spC1kNw.mjs.map → common-k2QC6AST.mjs.map} +1 -1
- package/dist/finalize-BUUNWqKC.cjs.map +1 -1
- package/dist/{finalize-BAwtGCQW.mjs → finalize-BVOveyol.mjs} +4 -4
- package/dist/{finalize-BAwtGCQW.mjs.map → finalize-BVOveyol.mjs.map} +1 -1
- package/dist/{finalize-Bm5RZIox.mjs → finalize-Bg0-BYxV.mjs} +3 -3
- package/dist/{finalize-Bm5RZIox.mjs.map → finalize-Bg0-BYxV.mjs.map} +1 -1
- package/dist/{finalize-CELJsR4C.mjs → finalize-f9hvnJ2R.mjs} +4 -4
- package/dist/{finalize-CELJsR4C.mjs.map → finalize-f9hvnJ2R.mjs.map} +1 -1
- package/dist/frost/index.mjs +1 -1
- package/dist/index-BErX9AZF.d.cts.map +1 -1
- package/dist/index-CD50Qtgw.d.cts.map +1 -1
- package/dist/index-CD50Qtgw.d.mts.map +1 -1
- package/dist/index-Drklne-Y.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/{invite-vRv9LMEE.mjs → invite-B4pfTK_5.mjs} +3 -3
- package/dist/{invite-vRv9LMEE.mjs.map → invite-B4pfTK_5.mjs.map} +1 -1
- package/dist/{invite-DNlTkwzM.mjs → invite-CPLnWY7c.mjs} +4 -4
- package/dist/{invite-DNlTkwzM.mjs.map → invite-CPLnWY7c.mjs.map} +1 -1
- package/dist/{receive-C2Dwb_FQ.mjs → receive-Bl_utFpz.mjs} +4 -4
- package/dist/{receive-C2Dwb_FQ.mjs.map → receive-Bl_utFpz.mjs.map} +1 -1
- package/dist/{receive-Bzn87ahI.mjs → receive-CYmQ_x3S.mjs} +4 -4
- package/dist/{receive-Bzn87ahI.mjs.map → receive-CYmQ_x3S.mjs.map} +1 -1
- package/dist/registry/index.cjs.map +1 -1
- package/dist/registry/index.mjs.map +1 -1
- package/dist/{registry-ycylEdoc.mjs → registry-DkhElxx1.mjs} +2 -2
- package/dist/{registry-ycylEdoc.mjs.map → registry-DkhElxx1.mjs.map} +1 -1
- package/dist/{rolldown-runtime-z9aeyW2b.mjs → rolldown-runtime-BhDjJH2R.mjs} +1 -1
- package/dist/{round1-BRgDPU4Y.mjs → round1-5RsoUTsC.mjs} +4 -4
- package/dist/{round1-BRgDPU4Y.mjs.map → round1-5RsoUTsC.mjs.map} +1 -1
- package/dist/{round1-_fHip4H1.mjs → round1-B0j_4sJq.mjs} +5 -5
- package/dist/{round1-_fHip4H1.mjs.map → round1-B0j_4sJq.mjs.map} +1 -1
- package/dist/{round1-DSaOFCar.mjs → round1-DC5LcN2C.mjs} +3 -3
- package/dist/{round1-DSaOFCar.mjs.map → round1-DC5LcN2C.mjs.map} +1 -1
- package/dist/{round1-DL4N2QJ5.mjs → round1-I9T20net.mjs} +5 -5
- package/dist/{round1-DL4N2QJ5.mjs.map → round1-I9T20net.mjs.map} +1 -1
- package/dist/{round2-DmQvJDVj.mjs → round2-BmpKBQwi.mjs} +4 -4
- package/dist/{round2-DmQvJDVj.mjs.map → round2-BmpKBQwi.mjs.map} +1 -1
- package/dist/{round2-Cq2SD6F8.mjs → round2-C0SsEt1J.mjs} +3 -3
- package/dist/{round2-Cq2SD6F8.mjs.map → round2-C0SsEt1J.mjs.map} +1 -1
- package/dist/{round2-CU-yTXHT.mjs → round2-CXkgjjyf.mjs} +4 -4
- package/dist/{round2-CU-yTXHT.mjs.map → round2-CXkgjjyf.mjs.map} +1 -1
- package/dist/{round2-BLOgZeAo.mjs → round2-DrZDN8Tt.mjs} +4 -4
- package/dist/{round2-BLOgZeAo.mjs.map → round2-DrZDN8Tt.mjs.map} +1 -1
- package/package.json +16 -16
- package/src/cmd/sign/participant/finalize.ts +1 -2
- package/src/registry/registry-impl.ts +1 -2
package/dist/bin/frost.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as createStorageClient, n as participantAdd, r as ownerSet } from "../registry-
|
|
2
|
+
import { i as createStorageClient, n as participantAdd, r as ownerSet } from "../registry-DkhElxx1.mjs";
|
|
3
3
|
import { program } from "commander";
|
|
4
4
|
//#region src/bin/frost.ts
|
|
5
5
|
/**
|
|
@@ -22,27 +22,27 @@ import { program } from "commander";
|
|
|
22
22
|
* @module
|
|
23
23
|
*/
|
|
24
24
|
const lazyDkgCoord = {
|
|
25
|
-
invite: () => import("../invite-
|
|
26
|
-
round1: () => import("../round1-
|
|
27
|
-
round2: () => import("../round2-
|
|
28
|
-
finalize: () => import("../finalize-
|
|
25
|
+
invite: () => import("../invite-B4pfTK_5.mjs").then((n) => n.n).then((m) => m.invite),
|
|
26
|
+
round1: () => import("../round1-DC5LcN2C.mjs").then((n) => n.n).then((m) => m.round1),
|
|
27
|
+
round2: () => import("../round2-C0SsEt1J.mjs").then((n) => n.o).then((m) => m.round2),
|
|
28
|
+
finalize: () => import("../finalize-Bg0-BYxV.mjs").then((n) => n.n).then((m) => m.finalize)
|
|
29
29
|
};
|
|
30
30
|
const lazyDkgPart = {
|
|
31
|
-
receive: () => import("../receive-
|
|
32
|
-
round1: () => import("../round1-
|
|
33
|
-
round2: () => import("../round2-
|
|
34
|
-
finalize: () => import("../finalize-
|
|
31
|
+
receive: () => import("../receive-Bl_utFpz.mjs").then((n) => n.r).then((m) => m.receive),
|
|
32
|
+
round1: () => import("../round1-B0j_4sJq.mjs").then((n) => n.n).then((m) => m.round1),
|
|
33
|
+
round2: () => import("../round2-CXkgjjyf.mjs").then((n) => n.n).then((m) => m.round2),
|
|
34
|
+
finalize: () => import("../finalize-f9hvnJ2R.mjs").then((n) => n.n).then((m) => m.finalize)
|
|
35
35
|
};
|
|
36
36
|
const lazySignCoord = {
|
|
37
|
-
invite: () => import("../invite-
|
|
38
|
-
round1: () => import("../round1-
|
|
39
|
-
round2: () => import("../round2-
|
|
37
|
+
invite: () => import("../invite-CPLnWY7c.mjs").then((n) => n.o).then((m) => m.invite),
|
|
38
|
+
round1: () => import("../round1-5RsoUTsC.mjs").then((n) => n.o).then((m) => m.round1),
|
|
39
|
+
round2: () => import("../round2-BmpKBQwi.mjs").then((n) => n.n).then((m) => m.round2)
|
|
40
40
|
};
|
|
41
41
|
const lazySignPart = {
|
|
42
|
-
receive: () => import("../receive-
|
|
43
|
-
round1: () => import("../round1-
|
|
44
|
-
round2: () => import("../round2-
|
|
45
|
-
finalize: () => import("../finalize-
|
|
42
|
+
receive: () => import("../receive-CYmQ_x3S.mjs").then((n) => n.n).then((m) => m.receive),
|
|
43
|
+
round1: () => import("../round1-I9T20net.mjs").then((n) => n.n).then((m) => m.round1),
|
|
44
|
+
round2: () => import("../round2-DrZDN8Tt.mjs").then((n) => n.n).then((m) => m.round2),
|
|
45
|
+
finalize: () => import("../finalize-BVOveyol.mjs").then((n) => n.n).then((m) => m.finalize)
|
|
46
46
|
};
|
|
47
47
|
/**
|
|
48
48
|
* Initialize the global CBOR tag registry. Mirrors the
|
package/dist/cmd/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose, r as setVerbose, t as groupStateDir } from "../common-
|
|
1
|
+
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose, r as setVerbose, t as groupStateDir } from "../common-k2QC6AST.mjs";
|
|
2
2
|
import { n as putWithIndicator, t as getWithIndicator } from "../busy-BlU8_pS2.mjs";
|
|
3
3
|
import { a as directionEmoji, c as fetchStatusPending, d as fetchStatusTimeout, f as parallelFetch, i as buildFetchRequests, l as fetchStatusRejected, m as parallelSend, n as DEFAULT_TIMEOUT_SECONDS, o as emptyCollectionResult, p as parallelFetchConfigWithTimeout, r as Direction, s as fetchStatusError, t as CollectionResult, u as fetchStatusSuccess } from "../parallel-PZiwHZT8.mjs";
|
|
4
|
-
import { i as createStorageClient, t as registry_exports } from "../registry-
|
|
5
|
-
import { n as dkg_exports, r as checkAridExists, t as sign_exports } from "../cmd-
|
|
4
|
+
import { i as createStorageClient, t as registry_exports } from "../registry-DkhElxx1.mjs";
|
|
5
|
+
import { n as dkg_exports, r as checkAridExists, t as sign_exports } from "../cmd-BOzLt8T8.mjs";
|
|
6
6
|
export { CollectionResult, DEFAULT_TIMEOUT_SECONDS, Direction, buildFetchRequests, checkAridExists, createStorageClient, directionEmoji, dkg_exports as dkg, emptyCollectionResult, fetchStatusError, fetchStatusPending, fetchStatusRejected, fetchStatusSuccess, fetchStatusTimeout, getWithIndicator, groupStateDir, isVerbose, parallelFetch, parallelFetchConfigWithTimeout, parallelSend, parseAridUr, putWithIndicator, registry_exports as registry, setVerbose, sign_exports as sign, signingKeyFromVerifying };
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
2
|
-
import { a as dkgStateDir, c as parseAridUr, d as resolveOwnerXidDocument, f as resolveParticipants, h as signingKeyFromVerifying, i as buildGroupParticipants, l as parseEnvelopeUr, m as resolveSenderName, o as formatNameWithOwnerMarker, p as resolveSender, s as groupParticipantFromRegistry, t as groupStateDir, u as participantNamesFromRegistry } from "./common-
|
|
3
|
-
import "./registry-
|
|
4
|
-
import { t as invite } from "./invite-
|
|
5
|
-
import { t as round1 } from "./round1-
|
|
6
|
-
import { a as round2, c as validateAndExtractRound2Response, i as persistRound2Packages, n as collectRound2Parallel, r as dispatchFinalizeRequestsParallel, s as updatePendingForFinalizeFromCollection, t as buildFinalizeRequestForParticipant } from "./round2-
|
|
7
|
-
import { t as finalize } from "./finalize-
|
|
8
|
-
import { i as resolveInviteEnvelope, n as receive, t as decodeInviteDetails } from "./receive-
|
|
9
|
-
import { t as round1$1 } from "./round1-
|
|
10
|
-
import { t as round2$1 } from "./round2-
|
|
11
|
-
import { t as finalize$1 } from "./finalize-
|
|
12
|
-
import { n as signingStateDir, r as signingStateDirForGroup, t as SignFinalizeContent } from "./common
|
|
13
|
-
import { a as invite$1, c as persistSessionState, i as gatherRecipientDocuments, l as validateCoordinator, n as buildSignInviteRequest, r as createSessionArids, s as loadEnvelopeFromPath, t as buildSessionStateJson } from "./invite-
|
|
14
|
-
import { a as round1$2, c as validateAndExtractCommitResponse, i as persistCommitments, n as collectCommitmentsParallel, r as dispatchShareRequestsParallel, s as updatePendingForShare, t as buildShareRequestForParticipant } from "./round1-
|
|
15
|
-
import { t as round2$2 } from "./round2-
|
|
16
|
-
import { t as receive$1 } from "./receive-
|
|
17
|
-
import { t as round1$3 } from "./round1-
|
|
18
|
-
import { t as round2$3 } from "./round2-
|
|
19
|
-
import { t as finalize$2 } from "./finalize-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
+
import { a as dkgStateDir, c as parseAridUr, d as resolveOwnerXidDocument, f as resolveParticipants, h as signingKeyFromVerifying, i as buildGroupParticipants, l as parseEnvelopeUr, m as resolveSenderName, o as formatNameWithOwnerMarker, p as resolveSender, s as groupParticipantFromRegistry, t as groupStateDir, u as participantNamesFromRegistry } from "./common-k2QC6AST.mjs";
|
|
3
|
+
import "./registry-DkhElxx1.mjs";
|
|
4
|
+
import { t as invite } from "./invite-B4pfTK_5.mjs";
|
|
5
|
+
import { t as round1 } from "./round1-DC5LcN2C.mjs";
|
|
6
|
+
import { a as round2, c as validateAndExtractRound2Response, i as persistRound2Packages, n as collectRound2Parallel, r as dispatchFinalizeRequestsParallel, s as updatePendingForFinalizeFromCollection, t as buildFinalizeRequestForParticipant } from "./round2-C0SsEt1J.mjs";
|
|
7
|
+
import { t as finalize } from "./finalize-Bg0-BYxV.mjs";
|
|
8
|
+
import { i as resolveInviteEnvelope, n as receive, t as decodeInviteDetails } from "./receive-Bl_utFpz.mjs";
|
|
9
|
+
import { t as round1$1 } from "./round1-B0j_4sJq.mjs";
|
|
10
|
+
import { t as round2$1 } from "./round2-CXkgjjyf.mjs";
|
|
11
|
+
import { t as finalize$1 } from "./finalize-f9hvnJ2R.mjs";
|
|
12
|
+
import { n as signingStateDir, r as signingStateDirForGroup, t as SignFinalizeContent } from "./common-DCyUSYkT.mjs";
|
|
13
|
+
import { a as invite$1, c as persistSessionState, i as gatherRecipientDocuments, l as validateCoordinator, n as buildSignInviteRequest, r as createSessionArids, s as loadEnvelopeFromPath, t as buildSessionStateJson } from "./invite-CPLnWY7c.mjs";
|
|
14
|
+
import { a as round1$2, c as validateAndExtractCommitResponse, i as persistCommitments, n as collectCommitmentsParallel, r as dispatchShareRequestsParallel, s as updatePendingForShare, t as buildShareRequestForParticipant } from "./round1-5RsoUTsC.mjs";
|
|
15
|
+
import { t as round2$2 } from "./round2-BmpKBQwi.mjs";
|
|
16
|
+
import { t as receive$1 } from "./receive-CYmQ_x3S.mjs";
|
|
17
|
+
import { t as round1$3 } from "./round1-I9T20net.mjs";
|
|
18
|
+
import { t as round2$3 } from "./round2-DrZDN8Tt.mjs";
|
|
19
|
+
import { t as finalize$2 } from "./finalize-BVOveyol.mjs";
|
|
20
20
|
//#region src/cmd/check.ts
|
|
21
21
|
/**
|
|
22
22
|
* Check if an ARID exists in storage.
|
|
@@ -109,4 +109,4 @@ var sign_exports = /* @__PURE__ */ __exportAll({
|
|
|
109
109
|
//#endregion
|
|
110
110
|
export { dkg_exports as n, checkAridExists as r, sign_exports as t };
|
|
111
111
|
|
|
112
|
-
//# sourceMappingURL=cmd-
|
|
112
|
+
//# sourceMappingURL=cmd-BOzLt8T8.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cmd-
|
|
1
|
+
{"version":3,"file":"cmd-BOzLt8T8.mjs","names":[],"sources":["../src/cmd/check.ts","../src/cmd/dkg/coordinator/index.ts","../src/cmd/dkg/participant/index.ts","../src/cmd/dkg/index.ts","../src/cmd/sign/coordinator/index.ts","../src/cmd/sign/participant/index.ts","../src/cmd/sign/index.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Check command utilities.\n *\n * Port of cmd/check.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { type ARID } from \"@bcts/components\";\n\nimport { type StorageClient } from \"./storage.js\";\n\n/**\n * Check if an ARID exists in storage.\n *\n * Port of check functionality from cmd/check.rs.\n */\nexport async function checkAridExists(client: StorageClient, arid: ARID): Promise<boolean> {\n return client.exists(arid);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG coordinator commands.\n *\n * Port of cmd/dkg/coordinator/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./invite.js\";\nexport * from \"./round1.js\";\nexport * from \"./round2.js\";\nexport * from \"./finalize.js\";\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant commands.\n *\n * Port of cmd/dkg/participant/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./receive.js\";\nexport * from \"./round1.js\";\nexport * from \"./round2.js\";\nexport * from \"./finalize.js\";\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG command module.\n *\n * Port of cmd/dkg/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./common.js\";\nexport * as coordinator from \"./coordinator/index.js\";\nexport * as participant from \"./participant/index.js\";\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign coordinator commands.\n *\n * Port of cmd/sign/coordinator/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./invite.js\";\nexport * from \"./round1.js\";\nexport * from \"./round2.js\";\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant commands.\n *\n * Port of cmd/sign/participant/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./receive.js\";\nexport * from \"./round1.js\";\nexport * from \"./round2.js\";\nexport * from \"./finalize.js\";\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign command module.\n *\n * Port of cmd/sign/mod.rs from frost-hubert-rust.\n *\n * @module\n */\n\nexport * from \"./common.js\";\nexport * as coordinator from \"./coordinator/index.js\";\nexport * as participant from \"./participant/index.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,eAAsB,gBAAgB,QAAuB,MAA8B;CACzF,OAAO,OAAO,OAAO,IAAI;AAC3B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as groupStateDir } from "./common-
|
|
1
|
+
import { t as groupStateDir } from "./common-k2QC6AST.mjs";
|
|
2
2
|
import { Envelope } from "@bcts/envelope";
|
|
3
3
|
//#region src/cmd/sign/common.ts
|
|
4
4
|
/**
|
|
@@ -93,4 +93,4 @@ var SignFinalizeContent = class SignFinalizeContent {
|
|
|
93
93
|
//#endregion
|
|
94
94
|
export { signingStateDir as n, signingStateDirForGroup as r, SignFinalizeContent as t };
|
|
95
95
|
|
|
96
|
-
//# sourceMappingURL=common
|
|
96
|
+
//# sourceMappingURL=common-DCyUSYkT.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common
|
|
1
|
+
{"version":3,"file":"common-DCyUSYkT.mjs","names":[],"sources":["../src/cmd/sign/common.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for sign commands.\n *\n * Port of cmd/sign/common.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { Envelope, type EnvelopeEncodableValue } from \"@bcts/envelope\";\n\nimport { groupStateDir } from \"../common\";\n\n/**\n * Get the signing state directory for a group (without session).\n *\n * Path: `{registry_dir}/group-state/{group_id.hex()}/signing`\n *\n * Port of `signing_state_dir_for_group()` from cmd/sign/common.rs.\n */\nexport function signingStateDirForGroup(registryPath: string, groupIdHex: string): string {\n return `${groupStateDir(registryPath, groupIdHex)}/signing`;\n}\n\n/**\n * Get the signing state directory for a given registry path, group ID, and session ID.\n *\n * Path: `{registry_dir}/group-state/{group_id.hex()}/signing/{session_id.hex()}`\n *\n * Port of `signing_state_dir()` from cmd/sign/common.rs.\n */\nexport function signingStateDir(\n registryPath: string,\n groupIdHex: string,\n sessionIdHex: string,\n): string {\n return `${signingStateDirForGroup(registryPath, groupIdHex)}/${sessionIdHex}`;\n}\n\n/**\n * Content wrapper for signFinalize events.\n *\n * This wraps an envelope with a unit subject and type assertion\n * \"signFinalize\", implementing the traits required by SealedEvent<T>.\n *\n * Port of `struct SignFinalizeContent` from cmd/sign/common.rs.\n */\nexport class SignFinalizeContent {\n private readonly _envelope: Envelope;\n\n private constructor(envelope: Envelope) {\n this._envelope = envelope;\n }\n\n /**\n * Creates a new SignFinalizeContent with a unit subject and type assertion.\n *\n * Port of `SignFinalizeContent::new()` from cmd/sign/common.rs.\n */\n static new(): SignFinalizeContent {\n const envelope = Envelope.unit().addType(\"signFinalize\");\n return new SignFinalizeContent(envelope);\n }\n\n /**\n * Adds an assertion to the content envelope.\n *\n * Port of `SignFinalizeContent::add_assertion()` from cmd/sign/common.rs.\n */\n addAssertion(\n predicate: EnvelopeEncodableValue,\n object: EnvelopeEncodableValue,\n ): SignFinalizeContent {\n const newEnvelope = this._envelope.addAssertion(predicate, object);\n return new SignFinalizeContent(newEnvelope);\n }\n\n /**\n * Returns the inner envelope.\n *\n * Port of `SignFinalizeContent::envelope()` from cmd/sign/common.rs.\n */\n envelope(): Envelope {\n return this._envelope;\n }\n\n /**\n * Creates a SignFinalizeContent from an envelope with validation.\n *\n * Validates that the envelope has a unit subject and type \"signFinalize\".\n *\n * Port of `TryFrom<Envelope> for SignFinalizeContent` from cmd/sign/common.rs.\n */\n static fromEnvelope(envelope: Envelope): SignFinalizeContent {\n // Validate it has a unit subject and type \"signFinalize\"\n envelope.checkSubjectUnit();\n envelope.checkType(\"signFinalize\");\n return new SignFinalizeContent(envelope);\n }\n\n /**\n * Converts this SignFinalizeContent to an Envelope.\n *\n * Port of `From<SignFinalizeContent> for Envelope` from cmd/sign/common.rs.\n */\n toEnvelope(): Envelope {\n return this._envelope;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,cAAsB,YAA4B;CACxF,OAAO,GAAG,cAAc,cAAc,UAAU,EAAE;AACpD;;;;;;;;AASA,SAAgB,gBACd,cACA,YACA,cACQ;CACR,OAAO,GAAG,wBAAwB,cAAc,UAAU,EAAE,GAAG;AACjE;;;;;;;;;AAUA,IAAa,sBAAb,MAAa,oBAAoB;CAC/B;CAEA,YAAoB,UAAoB;EACtC,KAAK,YAAY;CACnB;;;;;;CAOA,OAAO,MAA2B;EAEhC,OAAO,IAAI,oBADM,SAAS,KAAK,CAAC,CAAC,QAAQ,cACH,CAAC;CACzC;;;;;;CAOA,aACE,WACA,QACqB;EAErB,OAAO,IAAI,oBADS,KAAK,UAAU,aAAa,WAAW,MAClB,CAAC;CAC5C;;;;;;CAOA,WAAqB;EACnB,OAAO,KAAK;CACd;;;;;;;;CASA,OAAO,aAAa,UAAyC;EAE3D,SAAS,iBAAiB;EAC1B,SAAS,UAAU,cAAc;EACjC,OAAO,IAAI,oBAAoB,QAAQ;CACzC;;;;;;CAOA,aAAuB;EACrB,OAAO,KAAK;CACd;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as __require } from "./rolldown-runtime-
|
|
1
|
+
import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
2
|
import { n as compareXidBytes } from "./proposed-participant-Detb823_.mjs";
|
|
3
3
|
import { GroupParticipant } from "./registry/index.mjs";
|
|
4
4
|
import { UR } from "@bcts/uniform-resources";
|
|
@@ -279,4 +279,4 @@ function isVerbose() {
|
|
|
279
279
|
//#endregion
|
|
280
280
|
export { dkgStateDir as a, parseAridUr as c, resolveOwnerXidDocument as d, resolveParticipants as f, signingKeyFromVerifying as h, buildGroupParticipants as i, parseEnvelopeUr as l, resolveSenderName as m, isVerbose as n, formatNameWithOwnerMarker as o, resolveSender as p, setVerbose as r, groupParticipantFromRegistry as s, groupStateDir as t, participantNamesFromRegistry as u };
|
|
281
281
|
|
|
282
|
-
//# sourceMappingURL=common-
|
|
282
|
+
//# sourceMappingURL=common-k2QC6AST.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common-4spC1kNw.mjs","names":[],"sources":["../src/cmd/dkg/common.ts","../src/cmd/common.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for DKG commands.\n *\n * Port of cmd/dkg/common.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nimport { type ARID, type XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../dkg/proposed-participant.js\";\nimport { type Envelope } from \"@bcts/envelope\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport {\n GroupParticipant,\n type OwnerRecord,\n type ParticipantRecord,\n type Registry,\n} from \"../../registry/index.js\";\n\n// Re-export cross-cutting utilities for convenience\nexport { groupStateDir } from \"../common.js\";\n\n/**\n * Parse an ARID from a UR string.\n *\n * Mirrors Rust `parse_arid_ur` (`cmd/common.rs:27-43`):\n *\n * 1. Trim and reject empty input.\n * 2. Parse as a UR; require `ur_type` of `\"arid\"`.\n * 3. Try `ARID::try_from(cbor)` (the tagged-CBOR form).\n * 4. If that fails, fall back to interpreting the CBOR as a bare\n * byte string and constructing the ARID from those bytes via\n * `ARID::from_data_ref`.\n *\n * The earlier port only accepted the tagged form; this matches Rust\n * by accepting the byte-string fallback too.\n */\nexport function parseAridUr(urString: string): ARID {\n const trimmed = urString.trim();\n if (trimmed.length === 0) {\n throw new Error(\"ARID is required\");\n }\n const ur = UR.fromURString(trimmed);\n\n if (ur.urTypeStr() !== \"arid\") {\n throw new Error(`Expected a ur:arid, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { ARID: ARIDClass } = require(\"@bcts/components\");\n const cbor = ur.cbor();\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromTaggedCbor(cbor);\n } catch {\n // Fall back to a bare byte string payload, mirroring Rust's\n // `CBOR::try_into_byte_string(cbor) → ARID::from_data_ref(bytes)`.\n const bytes = (cbor as { asByteString(): Uint8Array | undefined }).asByteString?.();\n if (bytes === undefined) {\n throw new Error(\"Invalid ARID payload\");\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromData(bytes);\n }\n}\n\n/**\n * Parse an envelope from a UR string.\n *\n * Port of `parse_envelope_ur()` from cmd/dkg/common.rs.\n */\nexport function parseEnvelopeUr(urString: string): Envelope {\n const ur = UR.fromURString(urString.trim());\n\n if (ur.urTypeStr() !== \"envelope\") {\n throw new Error(`Expected ur:envelope, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { Envelope: EnvelopeClass } = require(\"@bcts/envelope\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return EnvelopeClass.fromCbor(ur.cbor());\n}\n\n/**\n * Resolve the registry owner's XID document.\n *\n * The earlier port called this `resolveSender(registry)`, but its\n * behaviour — \"give me the owner\" — has nothing in common with Rust's\n * `resolve_sender(registry, input)` (which resolves an arbitrary\n * named sender). This helper is renamed to its actual behaviour;\n * the Rust-equivalent `resolveSender(registry, input)` lives below.\n */\nexport function resolveOwnerXidDocument(registry: Registry): XIDDocument {\n const owner = registry.owner();\n\n if (!owner) {\n throw new Error(\"No owner set in registry. Run 'registry owner set' first.\");\n }\n\n return owner.xidDocument();\n}\n\n/**\n * Resolve a sender XID document from the registry by UR or pet name.\n *\n * Mirrors Rust `resolve_sender(registry, input)`\n * (`cmd/dkg/common.rs:76-94`):\n *\n * 1. Trim and reject empty input.\n * 2. Try parsing the input as a `ur:xid`. If that succeeds, look it\n * up via `registry.participant(xid)`; if no record is found,\n * error with `Sender with XID {ur} not found`.\n * 3. Otherwise look it up by pet name via\n * `registry.participantByPetName(name)`; if no record is found,\n * error with `Sender with pet name '{name}' not found`.\n *\n * Note Rust does NOT check the owner here — only the participants\n * map. The earlier inline duplicate in `participant/round1.ts` did\n * an extra owner-check fallback which is removed to match Rust.\n */\nexport function resolveSender(registry: Registry, input: string): XIDDocument {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Sender is required\");\n }\n\n // Try parsing as an XID UR string first. `XID.fromURString` throws\n // when the input isn't a `ur:xid`; that's the signal to fall back\n // to pet-name lookup.\n let xid: XID | undefined;\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n } catch {\n xid = undefined;\n }\n\n if (xid !== undefined) {\n const record = registry.participant(xid);\n if (record !== undefined) {\n return record.xidDocument();\n }\n throw new Error(`Sender with XID ${xid.urString()} not found`);\n }\n\n const result = registry.participantByPetName(trimmed);\n if (result !== undefined) {\n const [, record] = result;\n return record.xidDocument();\n }\n throw new Error(`Sender with pet name '${trimmed}' not found`);\n}\n\n// -----------------------------------------------------------------------------\n// Participant resolution\n// -----------------------------------------------------------------------------\n\n/**\n * Resolve participant identifiers (XID URs or pet names) to records.\n *\n * Port of `resolve_participants()` from cmd/dkg/common.rs lines 29-74.\n */\nexport function resolveParticipants(\n registry: Registry,\n inputs: string[],\n): [XID, ParticipantRecord][] {\n const seenArgs = new Set<string>();\n const seenXids = new Set<string>();\n const resolved: [XID, ParticipantRecord][] = [];\n\n for (const raw of inputs) {\n const trimmed = raw.trim();\n if (trimmed === \"\") {\n throw new Error(\"Participant identifier cannot be empty\");\n }\n if (seenArgs.has(trimmed)) {\n throw new Error(`Duplicate participant argument: ${trimmed}`);\n }\n seenArgs.add(trimmed);\n\n let xid: XID;\n let record: ParticipantRecord;\n\n // Try parsing as XID UR first\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n\n const foundRecord = registry.participant(xid);\n if (!foundRecord) {\n throw new Error(`Participant with XID ${xid.urString()} not found in registry`);\n }\n record = foundRecord;\n } catch {\n // Try looking up by pet name\n const result = registry.participantByPetName(trimmed);\n if (!result) {\n throw new Error(`Participant with pet name '${trimmed}' not found`);\n }\n [xid, record] = result;\n }\n\n const xidUr = xid.urString();\n if (seenXids.has(xidUr)) {\n throw new Error(`Duplicate participant specified; multiple inputs resolve to ${xidUr}`);\n }\n seenXids.add(xidUr);\n\n resolved.push([xid, record]);\n }\n\n return resolved;\n}\n\n/**\n * Get display name for sender from registry.\n *\n * Port of `resolve_sender_name()` from cmd/dkg/common.rs lines 96-116.\n */\nexport function resolveSenderName(registry: Registry, sender: XIDDocument): string | undefined {\n const owner = registry.owner();\n const senderXid = sender.xid();\n\n // Check if sender is the owner\n if (owner?.xidDocument().xid().urString() === senderXid.urString()) {\n const name = owner.petName() ?? senderXid.urString();\n return formatNameWithOwnerMarker(name, true);\n }\n\n // Look up in participants\n const record = registry.participant(senderXid);\n if (record) {\n const name = record.petName() ?? record.xid().urString();\n return formatNameWithOwnerMarker(name, false);\n }\n\n return undefined;\n}\n\n// -----------------------------------------------------------------------------\n// Group participant building\n// -----------------------------------------------------------------------------\n\n/**\n * Build GroupParticipant[] from XIDDocuments using registry lookups.\n *\n * Port of `build_group_participants()` from cmd/dkg/common.rs lines 122-131.\n */\nexport function buildGroupParticipants(\n registry: Registry,\n owner: OwnerRecord,\n participants: XIDDocument[],\n): GroupParticipant[] {\n return participants.map((doc) => groupParticipantFromRegistry(registry, owner, doc));\n}\n\n/**\n * Create a GroupParticipant from a XIDDocument, validating against the registry.\n *\n * Port of `group_participant_from_registry()` from cmd/dkg/common.rs lines 133-149.\n */\nexport function groupParticipantFromRegistry(\n registry: Registry,\n owner: OwnerRecord,\n document: XIDDocument,\n): GroupParticipant {\n const xid = document.xid();\n\n // If the document is the owner, allow it\n if (xid.urString() === owner.xid().urString()) {\n return new GroupParticipant(xid);\n }\n\n // Otherwise, verify the participant is in the registry\n if (!registry.participant(xid)) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n\n return new GroupParticipant(xid);\n}\n\n// -----------------------------------------------------------------------------\n// Name formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Format a participant name with owner marker if applicable.\n *\n * Port of `format_name_with_owner_marker()` from cmd/dkg/common.rs lines 155-157.\n */\nexport function formatNameWithOwnerMarker(name: string, isOwner: boolean): string {\n return isOwner ? `* ${name}` : name;\n}\n\n/**\n * Get display names for participants, sorted by XID, with owner marked.\n *\n * Port of `participant_names_from_registry()` from cmd/dkg/common.rs lines 159-191.\n */\nexport function participantNamesFromRegistry(\n registry: Registry,\n participants: XIDDocument[],\n ownerXid: XID,\n ownerPetName: string | undefined,\n): string[] {\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used\n // `urString().localeCompare(...)`, which diverges from byte order\n // for bytes ≥ 0x80 and is locale-aware.\n const sorted = [...participants].sort((a, b) =>\n compareXidBytes(a.xid().toData(), b.xid().toData()),\n );\n\n return sorted.map((document) => {\n const xid = document.xid();\n const isOwner = xid.urString() === ownerXid.urString();\n\n let name: string;\n if (isOwner) {\n name = ownerPetName ?? xid.urString();\n } else {\n const record = registry.participant(xid);\n if (!record) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n name = record.petName() ?? xid.urString();\n }\n\n return formatNameWithOwnerMarker(name, isOwner);\n });\n}\n\n/**\n * Get the DKG state directory for a given registry path and group ID.\n *\n * Port of `dkg_state_dir()` from cmd/dkg/common.rs.\n */\nexport function dkgStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex, \"dkg\");\n}\n\n/**\n * Convert a verifying key bytes to a SigningPublicKey.\n *\n * Port of `signing_key_from_verifying()` from cmd/dkg/common.rs.\n */\nexport function signingKeyFromVerifying(verifyingKeyBytes: Uint8Array): unknown {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { SigningPublicKey: SigningPublicKeyClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return SigningPublicKeyClass.fromBytes(verifyingKeyBytes);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for commands.\n *\n * Port of `cmd/common.rs` from `frost-hubert-rust`.\n *\n * Rust's `cmd::common` exports four cross-cutting helpers used by\n * both the DKG and signing subcommand trees:\n *\n * - `parse_arid_ur` / `signing_key_from_verifying` — re-exported\n * here so the TS module layout matches Rust. The implementations\n * live alongside their other DKG-specific siblings in\n * `cmd/dkg/common.ts` so callers in either tree can keep using\n * them; this file just surfaces them at the parallel-to-Rust\n * import path (`@bcts/frost-hubert/cmd/common`).\n * - `group_state_dir` and the verbose-flag helpers are TS-native here.\n *\n * `OptionalStorageSelector` is intentionally not ported: it's a\n * `clap`-specific argument struct and the TS port surfaces the same\n * effect via the `StorageSelection` string-literal union — see the\n * `parity audit` for context.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nexport { parseAridUr, signingKeyFromVerifying } from \"./dkg/common.js\";\n\n/**\n * Get the group state directory for a given registry path and group ID.\n *\n * Port of `group_state_dir()` from cmd/common.rs.\n */\nexport function groupStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex);\n}\n\n/**\n * Global verbose flag.\n */\nlet verboseFlag = false;\n\n/**\n * Set the verbose flag.\n */\nexport function setVerbose(value: boolean): void {\n verboseFlag = value;\n}\n\n/**\n * Check if verbose mode is enabled.\n *\n * Port of `is_verbose()` from cmd/common.rs.\n */\nexport function isVerbose(): boolean {\n return verboseFlag;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"common-k2QC6AST.mjs","names":[],"sources":["../src/cmd/dkg/common.ts","../src/cmd/common.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for DKG commands.\n *\n * Port of cmd/dkg/common.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nimport { type ARID, type XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../dkg/proposed-participant.js\";\nimport { type Envelope } from \"@bcts/envelope\";\nimport { UR } from \"@bcts/uniform-resources\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport {\n GroupParticipant,\n type OwnerRecord,\n type ParticipantRecord,\n type Registry,\n} from \"../../registry/index.js\";\n\n// Re-export cross-cutting utilities for convenience\nexport { groupStateDir } from \"../common.js\";\n\n/**\n * Parse an ARID from a UR string.\n *\n * Mirrors Rust `parse_arid_ur` (`cmd/common.rs:27-43`):\n *\n * 1. Trim and reject empty input.\n * 2. Parse as a UR; require `ur_type` of `\"arid\"`.\n * 3. Try `ARID::try_from(cbor)` (the tagged-CBOR form).\n * 4. If that fails, fall back to interpreting the CBOR as a bare\n * byte string and constructing the ARID from those bytes via\n * `ARID::from_data_ref`.\n *\n * The earlier port only accepted the tagged form; this matches Rust\n * by accepting the byte-string fallback too.\n */\nexport function parseAridUr(urString: string): ARID {\n const trimmed = urString.trim();\n if (trimmed.length === 0) {\n throw new Error(\"ARID is required\");\n }\n const ur = UR.fromURString(trimmed);\n\n if (ur.urTypeStr() !== \"arid\") {\n throw new Error(`Expected a ur:arid, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { ARID: ARIDClass } = require(\"@bcts/components\");\n const cbor = ur.cbor();\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromTaggedCbor(cbor);\n } catch {\n // Fall back to a bare byte string payload, mirroring Rust's\n // `CBOR::try_into_byte_string(cbor) → ARID::from_data_ref(bytes)`.\n const bytes = (cbor as { asByteString(): Uint8Array | undefined }).asByteString?.();\n if (bytes === undefined) {\n throw new Error(\"Invalid ARID payload\");\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return ARIDClass.fromData(bytes);\n }\n}\n\n/**\n * Parse an envelope from a UR string.\n *\n * Port of `parse_envelope_ur()` from cmd/dkg/common.rs.\n */\nexport function parseEnvelopeUr(urString: string): Envelope {\n const ur = UR.fromURString(urString.trim());\n\n if (ur.urTypeStr() !== \"envelope\") {\n throw new Error(`Expected ur:envelope, found ur:${ur.urTypeStr()}`);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { Envelope: EnvelopeClass } = require(\"@bcts/envelope\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return EnvelopeClass.fromCbor(ur.cbor());\n}\n\n/**\n * Resolve the registry owner's XID document.\n *\n * The earlier port called this `resolveSender(registry)`, but its\n * behaviour — \"give me the owner\" — has nothing in common with Rust's\n * `resolve_sender(registry, input)` (which resolves an arbitrary\n * named sender). This helper is renamed to its actual behaviour;\n * the Rust-equivalent `resolveSender(registry, input)` lives below.\n */\nexport function resolveOwnerXidDocument(registry: Registry): XIDDocument {\n const owner = registry.owner();\n\n if (!owner) {\n throw new Error(\"No owner set in registry. Run 'registry owner set' first.\");\n }\n\n return owner.xidDocument();\n}\n\n/**\n * Resolve a sender XID document from the registry by UR or pet name.\n *\n * Mirrors Rust `resolve_sender(registry, input)`\n * (`cmd/dkg/common.rs:76-94`):\n *\n * 1. Trim and reject empty input.\n * 2. Try parsing the input as a `ur:xid`. If that succeeds, look it\n * up via `registry.participant(xid)`; if no record is found,\n * error with `Sender with XID {ur} not found`.\n * 3. Otherwise look it up by pet name via\n * `registry.participantByPetName(name)`; if no record is found,\n * error with `Sender with pet name '{name}' not found`.\n *\n * Note Rust does NOT check the owner here — only the participants\n * map. The earlier inline duplicate in `participant/round1.ts` did\n * an extra owner-check fallback which is removed to match Rust.\n */\nexport function resolveSender(registry: Registry, input: string): XIDDocument {\n const trimmed = input.trim();\n if (trimmed.length === 0) {\n throw new Error(\"Sender is required\");\n }\n\n // Try parsing as an XID UR string first. `XID.fromURString` throws\n // when the input isn't a `ur:xid`; that's the signal to fall back\n // to pet-name lookup.\n let xid: XID | undefined;\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n } catch {\n xid = undefined;\n }\n\n if (xid !== undefined) {\n const record = registry.participant(xid);\n if (record !== undefined) {\n return record.xidDocument();\n }\n throw new Error(`Sender with XID ${xid.urString()} not found`);\n }\n\n const result = registry.participantByPetName(trimmed);\n if (result !== undefined) {\n const [, record] = result;\n return record.xidDocument();\n }\n throw new Error(`Sender with pet name '${trimmed}' not found`);\n}\n\n// -----------------------------------------------------------------------------\n// Participant resolution\n// -----------------------------------------------------------------------------\n\n/**\n * Resolve participant identifiers (XID URs or pet names) to records.\n *\n * Port of `resolve_participants()` from cmd/dkg/common.rs lines 29-74.\n */\nexport function resolveParticipants(\n registry: Registry,\n inputs: string[],\n): [XID, ParticipantRecord][] {\n const seenArgs = new Set<string>();\n const seenXids = new Set<string>();\n const resolved: [XID, ParticipantRecord][] = [];\n\n for (const raw of inputs) {\n const trimmed = raw.trim();\n if (trimmed === \"\") {\n throw new Error(\"Participant identifier cannot be empty\");\n }\n if (seenArgs.has(trimmed)) {\n throw new Error(`Duplicate participant argument: ${trimmed}`);\n }\n seenArgs.add(trimmed);\n\n let xid: XID;\n let record: ParticipantRecord;\n\n // Try parsing as XID UR first\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { XID: XIDClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n xid = XIDClass.fromURString(trimmed) as XID;\n\n const foundRecord = registry.participant(xid);\n if (!foundRecord) {\n throw new Error(`Participant with XID ${xid.urString()} not found in registry`);\n }\n record = foundRecord;\n } catch {\n // Try looking up by pet name\n const result = registry.participantByPetName(trimmed);\n if (!result) {\n throw new Error(`Participant with pet name '${trimmed}' not found`);\n }\n [xid, record] = result;\n }\n\n const xidUr = xid.urString();\n if (seenXids.has(xidUr)) {\n throw new Error(`Duplicate participant specified; multiple inputs resolve to ${xidUr}`);\n }\n seenXids.add(xidUr);\n\n resolved.push([xid, record]);\n }\n\n return resolved;\n}\n\n/**\n * Get display name for sender from registry.\n *\n * Port of `resolve_sender_name()` from cmd/dkg/common.rs lines 96-116.\n */\nexport function resolveSenderName(registry: Registry, sender: XIDDocument): string | undefined {\n const owner = registry.owner();\n const senderXid = sender.xid();\n\n // Check if sender is the owner\n if (owner?.xidDocument().xid().urString() === senderXid.urString()) {\n const name = owner.petName() ?? senderXid.urString();\n return formatNameWithOwnerMarker(name, true);\n }\n\n // Look up in participants\n const record = registry.participant(senderXid);\n if (record) {\n const name = record.petName() ?? record.xid().urString();\n return formatNameWithOwnerMarker(name, false);\n }\n\n return undefined;\n}\n\n// -----------------------------------------------------------------------------\n// Group participant building\n// -----------------------------------------------------------------------------\n\n/**\n * Build GroupParticipant[] from XIDDocuments using registry lookups.\n *\n * Port of `build_group_participants()` from cmd/dkg/common.rs lines 122-131.\n */\nexport function buildGroupParticipants(\n registry: Registry,\n owner: OwnerRecord,\n participants: XIDDocument[],\n): GroupParticipant[] {\n return participants.map((doc) => groupParticipantFromRegistry(registry, owner, doc));\n}\n\n/**\n * Create a GroupParticipant from a XIDDocument, validating against the registry.\n *\n * Port of `group_participant_from_registry()` from cmd/dkg/common.rs lines 133-149.\n */\nexport function groupParticipantFromRegistry(\n registry: Registry,\n owner: OwnerRecord,\n document: XIDDocument,\n): GroupParticipant {\n const xid = document.xid();\n\n // If the document is the owner, allow it\n if (xid.urString() === owner.xid().urString()) {\n return new GroupParticipant(xid);\n }\n\n // Otherwise, verify the participant is in the registry\n if (!registry.participant(xid)) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n\n return new GroupParticipant(xid);\n}\n\n// -----------------------------------------------------------------------------\n// Name formatting\n// -----------------------------------------------------------------------------\n\n/**\n * Format a participant name with owner marker if applicable.\n *\n * Port of `format_name_with_owner_marker()` from cmd/dkg/common.rs lines 155-157.\n */\nexport function formatNameWithOwnerMarker(name: string, isOwner: boolean): string {\n return isOwner ? `* ${name}` : name;\n}\n\n/**\n * Get display names for participants, sorted by XID, with owner marked.\n *\n * Port of `participant_names_from_registry()` from cmd/dkg/common.rs lines 159-191.\n */\nexport function participantNamesFromRegistry(\n registry: Registry,\n participants: XIDDocument[],\n ownerXid: XID,\n ownerPetName: string | undefined,\n): string[] {\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used\n // `urString().localeCompare(...)`, which diverges from byte order\n // for bytes ≥ 0x80 and is locale-aware.\n const sorted = [...participants].sort((a, b) =>\n compareXidBytes(a.xid().toData(), b.xid().toData()),\n );\n\n return sorted.map((document) => {\n const xid = document.xid();\n const isOwner = xid.urString() === ownerXid.urString();\n\n let name: string;\n if (isOwner) {\n name = ownerPetName ?? xid.urString();\n } else {\n const record = registry.participant(xid);\n if (!record) {\n throw new Error(`Invite participant not found in registry: ${xid.urString()}`);\n }\n name = record.petName() ?? xid.urString();\n }\n\n return formatNameWithOwnerMarker(name, isOwner);\n });\n}\n\n/**\n * Get the DKG state directory for a given registry path and group ID.\n *\n * Port of `dkg_state_dir()` from cmd/dkg/common.rs.\n */\nexport function dkgStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex, \"dkg\");\n}\n\n/**\n * Convert a verifying key bytes to a SigningPublicKey.\n *\n * Port of `signing_key_from_verifying()` from cmd/dkg/common.rs.\n */\nexport function signingKeyFromVerifying(verifyingKeyBytes: Uint8Array): unknown {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-require-imports, no-undef\n const { SigningPublicKey: SigningPublicKeyClass } = require(\"@bcts/components\");\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n return SigningPublicKeyClass.fromBytes(verifyingKeyBytes);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Common utilities for commands.\n *\n * Port of `cmd/common.rs` from `frost-hubert-rust`.\n *\n * Rust's `cmd::common` exports four cross-cutting helpers used by\n * both the DKG and signing subcommand trees:\n *\n * - `parse_arid_ur` / `signing_key_from_verifying` — re-exported\n * here so the TS module layout matches Rust. The implementations\n * live alongside their other DKG-specific siblings in\n * `cmd/dkg/common.ts` so callers in either tree can keep using\n * them; this file just surfaces them at the parallel-to-Rust\n * import path (`@bcts/frost-hubert/cmd/common`).\n * - `group_state_dir` and the verbose-flag helpers are TS-native here.\n *\n * `OptionalStorageSelector` is intentionally not ported: it's a\n * `clap`-specific argument struct and the TS port surfaces the same\n * effect via the `StorageSelection` string-literal union — see the\n * `parity audit` for context.\n *\n * @module\n */\n\nimport * as path from \"node:path\";\n\nexport { parseAridUr, signingKeyFromVerifying } from \"./dkg/common.js\";\n\n/**\n * Get the group state directory for a given registry path and group ID.\n *\n * Port of `group_state_dir()` from cmd/common.rs.\n */\nexport function groupStateDir(registryPath: string, groupIdHex: string): string {\n const base = path.dirname(registryPath);\n return path.join(base, \"group-state\", groupIdHex);\n}\n\n/**\n * Global verbose flag.\n */\nlet verboseFlag = false;\n\n/**\n * Set the verbose flag.\n */\nexport function setVerbose(value: boolean): void {\n verboseFlag = value;\n}\n\n/**\n * Check if verbose mode is enabled.\n *\n * Port of `is_verbose()` from cmd/common.rs.\n */\nexport function isVerbose(): boolean {\n return verboseFlag;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finalize-BUUNWqKC.cjs","names":["path","fs","ARID","parseAridUr","XID","compareXidBytes","signingStateDir","deserializeSignatureShare","deserializeSigningCommitments","serialized","isVerbose","getWithIndicator","SealedEvent","identifierFromU16","deserializePublicKeyPackage","createSigningPackage","signingKeyFromVerifying","hexToBytes","serializeSignature","aggregateSignatures","Signature","serializeSignatureShare","serializeSigningCommitments","resolveRegistryPath","Registry","Envelope"],"sources":["../src/cmd/sign/participant/finalize.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant finalize command.\n *\n * Port of cmd/sign/participant/finalize.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, type Digest, Signature, type SigningPublicKey, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedEvent } from \"@bcts/gstp\";\n\nimport {\n Registry,\n resolveRegistryPath,\n type GroupRecord,\n type OwnerRecord,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializePublicKeyPackage,\n deserializeSignatureShare,\n deserializeSigningCommitments,\n identifierFromU16,\n hexToBytes,\n serializeSignature,\n serializeSignatureShare,\n serializeSigningCommitments,\n type FrostIdentifier,\n type FrostPublicKeyPackage,\n type Ed25519SignatureShare,\n type Ed25519SigningCommitments,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n} from \"../../../frost/index.js\";\nimport { isVerbose } from \"../../common.js\";\n\n/**\n * Options for the sign finalize command.\n */\nexport interface SignFinalizeOptions {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign finalize command.\n */\nexport interface SignFinalizeResult {\n signature: string;\n signedEnvelope: string;\n}\n\n/**\n * State from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/finalize.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinator: XID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * State from share.json.\n *\n * Port of `struct ShareState` from cmd/sign/participant/finalize.rs.\n */\ninterface ShareState {\n finalizeArid: ARID;\n signatureShare: Ed25519SignatureShare;\n commitments: Map<string, Ed25519SigningCommitments>; // XID UR string -> commitments\n}\n\n/**\n * Load the receive state for a signing session.\n *\n * Searches for sign_receive.json in group-state directories.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Build list of group directories to search\n const groupDirs: [ARID, string][] = [];\n if (groupHint !== undefined) {\n groupDirs.push([groupHint, path.join(groupStateDir, groupHint.hex())]);\n } else {\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const name = entry.name;\n // Check if it's a valid 64-char hex string (ARID)\n if (name.length === 64 && /^[0-9a-f]+$/i.test(name)) {\n const groupId = ARID.fromHex(name);\n groupDirs.push([groupId, path.join(groupStateDir, name)]);\n }\n }\n }\n }\n }\n\n // Search for sign_receive.json\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, filePath] = candidates[0];\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.hex() !== groupId.hex()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n const coordinator = XID.fromURString(getStr(\"coordinator\"));\n\n const participantsVal = raw[\"participants\"];\n if (!Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XID.fromURString(entry));\n }\n\n const minSignersVal = raw[\"min_signers\"];\n if (typeof minSignersVal !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n const minSigners = minSignersVal;\n\n const targetUr = getStr(\"target\");\n\n // Sort participants by XID byte order — mirrors Rust `XID::cmp`.\n // The earlier port used `urString().localeCompare(...)`, which\n // diverges from byte order for bytes ≥ 0x80 and is locale-aware,\n // producing a different signing-package order than Rust.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n return {\n groupId,\n coordinator,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load the share state for a signing session.\n *\n * Port of `load_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadShareState(registryPath: string, groupId: ARID, sessionId: ARID): ShareState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const filePath = path.join(dir, \"share.json\");\n\n if (!fs.existsSync(filePath)) {\n throw new Error(\n `Signature share state not found at ${filePath}. Run \\`frost sign participant share\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in share.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in share.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const finalizeArid = parseAridUr(getStr(\"finalize_arid\"));\n\n const signatureShareHex = getStr(\"signature_share\");\n const signatureShare = deserializeSignatureShare(signatureShareHex);\n\n const commitmentsVal = raw[\"commitments\"];\n if (typeof commitmentsVal !== \"object\" || commitmentsVal === null) {\n throw new Error(\"Missing commitments map in share.json\");\n }\n\n const commitments = new Map<string, Ed25519SigningCommitments>();\n for (const [xidStr, value] of Object.entries(commitmentsVal as Record<string, unknown>)) {\n const serialized = value as SerializedSigningCommitments;\n const commits = deserializeSigningCommitments(serialized);\n commitments.set(xidStr, commits);\n }\n\n return { finalizeArid, signatureShare, commitments };\n}\n\n/**\n * Validate that session state is consistent with registry and owner.\n *\n * Port of `validate_session_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSessionState(\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n owner: OwnerRecord,\n): void {\n if (receiveState.coordinator.urString() !== groupRecord.coordinator().xid().urString()) {\n throw new Error(\"Coordinator in session state does not match registry\");\n }\n\n const ownerXidStr = owner.xid().urString();\n const isParticipant = receiveState.participants.some((p) => p.urString() === ownerXidStr);\n if (!isParticipant) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n}\n\n/**\n * Validate share state against receive state and registry.\n *\n * Port of `validate_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateShareState(\n shareState: ShareState,\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n): void {\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\n \"No listening ARID for signFinalize. Did you run `frost sign participant share`?\",\n );\n }\n\n if (shareState.finalizeArid.hex() !== listeningAtArid.hex()) {\n throw new Error(\n `Registry listening ARID (${listeningAtArid.urString()}) does not match persisted finalize ARID (${shareState.finalizeArid.urString()})`,\n );\n }\n\n // Check that commitments match session participants\n const commitParticipants = new Set(shareState.commitments.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (commitParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Commitments do not match session participants\");\n }\n for (const p of commitParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Commitments do not match session participants\");\n }\n }\n}\n\n/**\n * Validate the finalize event.\n *\n * Port of `validate_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateFinalizeEvent(\n sealedEvent: SealedEvent<Envelope>,\n sessionId: ARID,\n groupRecord: GroupRecord,\n): void {\n // Get the content envelope (which is the SignFinalizeContent envelope)\n const contentEnvelope = sealedEvent.content();\n\n // Validate the session predicate - extract ARID from the session assertion\n const sessionEnvelope = contentEnvelope.objectForPredicate(\"session\");\n if (sessionEnvelope === undefined) {\n throw new Error(\"Missing session in finalize event\");\n }\n const eventSession = ARID.fromTaggedCbor(sessionEnvelope.subject().tryLeaf());\n if (eventSession.hex() !== sessionId.hex()) {\n throw new Error(\n `Event session ${eventSession.urString()} does not match expected ${sessionId.urString()}`,\n );\n }\n\n const expectedCoordinator = groupRecord.coordinator().xid();\n if (sealedEvent.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected event sender: ${sealedEvent.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Validate signature shares from the finalize event.\n *\n * Port of `validate_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSignatureShares(\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n receiveState: ReceiveState,\n _shareState: ShareState,\n owner: OwnerRecord,\n): void {\n if (signatureSharesByXid.size < receiveState.minSigners) {\n throw new Error(\n `Finalize package contains ${signatureSharesByXid.size} signature shares but requires at least ${receiveState.minSigners}`,\n );\n }\n\n // Check that share participants match session participants\n const sharesParticipants = new Set(signatureSharesByXid.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (sharesParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n for (const p of sharesParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n }\n\n // Verify our own share matches\n const ownerXidStr = owner.xid().urString();\n const myShare = signatureSharesByXid.get(ownerXidStr);\n if (myShare === undefined) {\n throw new Error(\"Finalize package is missing this participant's signature share\");\n }\n\n // Compare shares (serialize both and compare hex strings)\n // Note: This assumes signature shares can be compared by their serialized form\n // The Rust code compares them directly via PartialEq\n}\n\n/**\n * Fetch and parse the finalize event from storage.\n *\n * Port of `fetch_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nasync function fetchFinalizeEvent(\n client: StorageClient,\n finalizeArid: ARID,\n timeout: number | undefined,\n owner: OwnerRecord,\n): Promise<SealedEvent<Envelope>> {\n if (isVerbose()) {\n console.error(\"Fetching finalize package from Hubert...\");\n }\n\n const finalizeEnvelope = await getWithIndicator(\n client,\n finalizeArid,\n \"Finalize package\",\n timeout,\n isVerbose(),\n );\n\n if (finalizeEnvelope === null || finalizeEnvelope === undefined) {\n throw new Error(\"Finalize package not found in Hubert storage\");\n }\n\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerKeys === undefined) {\n throw new Error(\"Owner XID document has no inception private keys\");\n }\n\n // Parse as SealedEvent<Envelope> - the content is the SignFinalizeContent envelope\n const sealedEvent = SealedEvent.tryFromEnvelope<Envelope>(\n finalizeEnvelope,\n undefined, // No expected ID for events\n undefined, // No date validation needed\n signerKeys,\n (env: Envelope) => {\n // Validate it's a SignFinalizeContent envelope (has unit subject and type \"signFinalize\")\n SignFinalizeContent.fromEnvelope(env);\n return env;\n },\n );\n\n return sealedEvent;\n}\n\n/**\n * Parse signature shares from the finalize event.\n *\n * Port of `parse_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction parseSignatureShares(event: SealedEvent<Envelope>): Map<string, Ed25519SignatureShare> {\n const contentEnvelope = event.content();\n\n const shares = new Map<string, Ed25519SignatureShare>();\n const entries = contentEnvelope.objectsForPredicate(\"signature_share\");\n\n for (const entry of entries) {\n // Extract XID from subject\n const xid = XID.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract share hex string from \"share\" predicate\n const shareEnvelope = entry.objectForPredicate(\"share\");\n if (shareEnvelope === undefined) {\n throw new Error(\"Missing share in signature_share entry\");\n }\n const shareJson = shareEnvelope.extractString();\n const share = deserializeSignatureShare(shareJson);\n\n const xidStr = xid.urString();\n if (shares.has(xidStr)) {\n throw new Error(`Duplicate signature share for participant ${xidStr}`);\n }\n shares.set(xidStr, share);\n }\n\n if (shares.size === 0) {\n throw new Error(\"Finalize package contains no signature shares\");\n }\n\n return shares;\n}\n\n/**\n * Build a mapping from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/finalize.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const xid = participants[i];\n const identifier = identifierFromU16(i + 1);\n map.set(xid.urString(), identifier);\n }\n return map;\n}\n\n/**\n * Convert commitments from XID-keyed to Identifier-keyed map.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidStr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Convert signature shares from XID-keyed to Identifier-keyed map.\n *\n * Port of `signature_shares_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction signatureSharesWithIdentifiers(\n shares: Map<string, Ed25519SignatureShare>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SignatureShare> {\n const mapped = new Map<FrostIdentifier, Ed25519SignatureShare>();\n for (const [xidStr, share] of shares) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, share);\n }\n return mapped;\n}\n\n/**\n * Result of loading a public key package.\n */\ninterface LoadedPublicKeyPackage {\n package: FrostPublicKeyPackage;\n verifyingKeyHex: string;\n}\n\n/**\n * Load the public key package for a group.\n *\n * Port of `load_public_key_package()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): LoadedPublicKeyPackage {\n const base = path.dirname(registryPath);\n\n // Try direct path first\n const directPath = path.join(base, \"group-state\", groupId.hex(), \"public_key_package.json\");\n if (fs.existsSync(directPath)) {\n const raw = JSON.parse(fs.readFileSync(directPath, \"utf-8\")) as SerializedPublicKeyPackage;\n return {\n package: deserializePublicKeyPackage(raw),\n verifyingKeyHex: raw.verifyingKey,\n };\n }\n\n // Fallback to collected_finalize.json (coordinator)\n const collectedPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n if (fs.existsSync(collectedPath)) {\n const raw = JSON.parse(fs.readFileSync(collectedPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n if (firstEntry === undefined) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n const publicKeyValue = firstEntry[\"public_key_package\"] as\n | SerializedPublicKeyPackage\n | undefined;\n if (publicKeyValue === undefined) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n return {\n package: deserializePublicKeyPackage(publicKeyValue),\n verifyingKeyHex: publicKeyValue.verifyingKey,\n };\n }\n\n throw new Error(\n `Public key package not found for group ${groupId.urString()}; run finalize respond/collect first`,\n );\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of `aggregate_and_verify_signature()` from cmd/sign/participant/finalize.rs.\n */\nfunction aggregateAndVerifySignature(\n registryPath: string,\n groupId: ARID,\n participants: XID[],\n commitments: Map<string, Ed25519SigningCommitments>,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n targetEnvelope: Envelope,\n targetDigest: Digest,\n): [Signature, Envelope, SigningPublicKey] {\n const xidToIdentifier = xidIdentifierMap(participants);\n const signingCommitments = commitmentsWithIdentifiers(commitments, xidToIdentifier);\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n const signatureSharesByIdentifier = signatureSharesWithIdentifiers(\n signatureSharesByXid,\n xidToIdentifier,\n );\n\n const { package: publicKeyPackage, verifyingKeyHex } = loadPublicKeyPackage(\n registryPath,\n groupId,\n );\n\n // Get verifying key from public key package\n const verifyingKeyBytes = hexToBytes(verifyingKeyHex);\n const verifyingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n\n // Aggregate the signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const sigBytes = serializeSignature(aggregatedSignature);\n if (sigBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n const finalSignature = Signature.ed25519FromData(sigBytes);\n\n // Verify signature against target digest\n if (!verifyingKey.verify(finalSignature, targetDigest.data())) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Create signed envelope\n const signedEnvelope = targetEnvelope.addAssertion(\"signed\", finalSignature);\n\n // Verify signature on envelope\n signedEnvelope.verifySignatureFrom(verifyingKey);\n\n return [finalSignature, signedEnvelope, verifyingKey];\n}\n\n/**\n * Update the registry verifying key if needed.\n *\n * Port of `update_registry_verifying_key()` from cmd/sign/participant/finalize.rs.\n */\nfunction updateRegistryVerifyingKey(\n registry: Registry,\n registryPath: string,\n groupId: ARID,\n verifyingKey: SigningPublicKey,\n groupRecord: GroupRecord,\n): void {\n const existing = groupRecord.verifyingKey();\n if (existing !== undefined) {\n if (existing.urString() !== verifyingKey.urString()) {\n throw new Error(\"Registry verifying key does not match finalize package\");\n }\n } else {\n const mutableGroup = registry.group(groupId);\n if (mutableGroup === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n mutableGroup.setVerifyingKey(verifyingKey);\n registry.save(registryPath);\n }\n}\n\n/**\n * Persist the final state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction persistFinalState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signedEnvelope: Envelope,\n signatureShares: Map<string, Ed25519SignatureShare>,\n shareState: ShareState,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const finalPath = path.join(dir, \"final.json\");\n\n // Load existing state if present\n let root: Record<string, unknown> = {};\n if (fs.existsSync(finalPath)) {\n root = JSON.parse(fs.readFileSync(finalPath, \"utf-8\")) as Record<string, unknown>;\n }\n\n // Build shares JSON\n const sharesJson: Record<string, string> = {};\n for (const [xidStr, share] of signatureShares) {\n sharesJson[xidStr] = serializeSignatureShare(share);\n }\n\n // Build commitments JSON\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidStr, commits] of shareState.commitments) {\n commitmentsJson[xidStr] = serializeSigningCommitments(commits);\n }\n\n root[\"group\"] = groupId.urString();\n root[\"session\"] = sessionId.urString();\n root[\"signature\"] = signature.urString();\n root[\"signature_shares\"] = sharesJson;\n root[\"commitments\"] = commitmentsJson;\n root[\"finalize_arid\"] = shareState.finalizeArid.urString();\n root[\"signed_target\"] = signedEnvelope.urString();\n\n fs.writeFileSync(finalPath, JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant finalize command.\n *\n * Receives the finalize event with aggregated signature.\n *\n * Port of `finalize()` from cmd/sign/participant/finalize.rs.\n */\nexport async function finalize(\n client: StorageClient,\n options: SignFinalizeOptions,\n cwd: string,\n): Promise<SignFinalizeResult> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint =\n options.groupId !== undefined && options.groupId !== \"\"\n ? parseAridUr(options.groupId)\n : undefined;\n\n // Load and validate session state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n const groupRecord = registry.group(groupId);\n\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n validateSessionState(receiveState, groupRecord, owner);\n\n const shareState = loadShareState(registryPath, groupId, sessionId);\n validateShareState(shareState, receiveState, groupRecord);\n\n // Fetch finalize event\n const sealedEvent = await fetchFinalizeEvent(\n client,\n shareState.finalizeArid,\n options.timeoutSeconds,\n owner,\n );\n\n // Validate event\n validateFinalizeEvent(sealedEvent, sessionId, groupRecord);\n\n // Extract and validate signature shares\n const signatureSharesByXid = parseSignatureShares(sealedEvent);\n validateSignatureShares(signatureSharesByXid, receiveState, shareState, owner);\n\n // Load target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest = targetEnvelope.subject().digest();\n\n // Aggregate signature\n const [finalSignature, signedEnvelope, verifyingKey] = aggregateAndVerifySignature(\n registryPath,\n groupId,\n receiveState.participants,\n shareState.commitments,\n signatureSharesByXid,\n targetEnvelope,\n targetDigest,\n );\n\n // Update registry verifying key if needed\n updateRegistryVerifyingKey(registry, registryPath, groupId, verifyingKey, groupRecord);\n\n // Persist final state\n persistFinalState(\n registryPath,\n groupId,\n sessionId,\n finalSignature,\n signedEnvelope,\n signatureSharesByXid,\n shareState,\n );\n\n // Clear listening ARID\n const mutableGroupRecord = registry.group(groupId);\n if (mutableGroupRecord !== undefined) {\n mutableGroupRecord.clearListeningAtArid();\n registry.save(registryPath);\n }\n\n const signatureStr = finalSignature.urString();\n const signedEnvelopeStr = signedEnvelope.urString();\n\n if (options.verbose === true) {\n console.log(signatureStr);\n console.log(signedEnvelopeStr);\n }\n\n return {\n signature: signatureStr,\n signedEnvelope: signedEnvelopeStr,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"finalize-BUUNWqKC.cjs","names":["path","fs","ARID","parseAridUr","XID","compareXidBytes","signingStateDir","deserializeSignatureShare","deserializeSigningCommitments","serialized","isVerbose","getWithIndicator","SealedEvent","identifierFromU16","deserializePublicKeyPackage","createSigningPackage","signingKeyFromVerifying","hexToBytes","serializeSignature","aggregateSignatures","Signature","serializeSignatureShare","serializeSigningCommitments","resolveRegistryPath","Registry","Envelope"],"sources":["../src/cmd/sign/participant/finalize.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant finalize command.\n *\n * Port of cmd/sign/participant/finalize.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, type Digest, Signature, type SigningPublicKey, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { SealedEvent } from \"@bcts/gstp\";\n\nimport {\n Registry,\n resolveRegistryPath,\n type GroupRecord,\n type OwnerRecord,\n} from \"../../../registry/index.js\";\nimport { getWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../../dkg/common.js\";\nimport { signingStateDir, SignFinalizeContent } from \"../common.js\";\nimport {\n aggregateSignatures,\n createSigningPackage,\n deserializePublicKeyPackage,\n deserializeSignatureShare,\n deserializeSigningCommitments,\n identifierFromU16,\n hexToBytes,\n serializeSignature,\n serializeSignatureShare,\n serializeSigningCommitments,\n type FrostIdentifier,\n type FrostPublicKeyPackage,\n type Ed25519SignatureShare,\n type Ed25519SigningCommitments,\n type SerializedPublicKeyPackage,\n type SerializedSigningCommitments,\n} from \"../../../frost/index.js\";\nimport { isVerbose } from \"../../common.js\";\n\n/**\n * Options for the sign finalize command.\n */\nexport interface SignFinalizeOptions {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign finalize command.\n */\nexport interface SignFinalizeResult {\n signature: string;\n signedEnvelope: string;\n}\n\n/**\n * State from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/finalize.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n coordinator: XID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * State from share.json.\n *\n * Port of `struct ShareState` from cmd/sign/participant/finalize.rs.\n */\ninterface ShareState {\n finalizeArid: ARID;\n signatureShare: Ed25519SignatureShare;\n commitments: Map<string, Ed25519SigningCommitments>; // XID UR string -> commitments\n}\n\n/**\n * Load the receive state for a signing session.\n *\n * Searches for sign_receive.json in group-state directories.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadReceiveState(\n registryPath: string,\n sessionId: ARID,\n groupHint: ARID | undefined,\n): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Build list of group directories to search\n const groupDirs: [ARID, string][] = [];\n if (groupHint !== undefined) {\n groupDirs.push([groupHint, path.join(groupStateDir, groupHint.hex())]);\n } else {\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n const name = entry.name;\n // Check if it's a valid 64-char hex string (ARID)\n if (name.length === 64 && /^[0-9a-f]+$/i.test(name)) {\n const groupId = ARID.fromHex(name);\n groupDirs.push([groupId, path.join(groupStateDir, name)]);\n }\n }\n }\n }\n }\n\n // Search for sign_receive.json\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, filePath] = candidates[0];\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.hex() !== groupId.hex()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n const coordinator = XID.fromURString(getStr(\"coordinator\"));\n\n const participantsVal = raw[\"participants\"];\n if (!Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XID.fromURString(entry));\n }\n\n const minSignersVal = raw[\"min_signers\"];\n if (typeof minSignersVal !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n const minSigners = minSignersVal;\n\n const targetUr = getStr(\"target\");\n\n // Sort participants by XID byte order — mirrors Rust `XID::cmp`.\n // The earlier port used `urString().localeCompare(...)`, which\n // diverges from byte order for bytes ≥ 0x80 and is locale-aware,\n // producing a different signing-package order than Rust.\n participants.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n return {\n groupId,\n coordinator,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load the share state for a signing session.\n *\n * Port of `load_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadShareState(registryPath: string, groupId: ARID, sessionId: ARID): ShareState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const filePath = path.join(dir, \"share.json\");\n\n if (!fs.existsSync(filePath)) {\n throw new Error(\n `Signature share state not found at ${filePath}. Run \\`frost sign participant share\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const val = raw[key];\n if (typeof val !== \"string\") {\n throw new Error(`Missing or invalid ${key} in share.json`);\n }\n return val;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.hex() !== sessionId.hex()) {\n throw new Error(\n `Session ${sessionInState.urString()} in share.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const finalizeArid = parseAridUr(getStr(\"finalize_arid\"));\n\n const signatureShareHex = getStr(\"signature_share\");\n const signatureShare = deserializeSignatureShare(signatureShareHex);\n\n const commitmentsVal = raw[\"commitments\"];\n if (typeof commitmentsVal !== \"object\" || commitmentsVal === null) {\n throw new Error(\"Missing commitments map in share.json\");\n }\n\n const commitments = new Map<string, Ed25519SigningCommitments>();\n for (const [xidStr, value] of Object.entries(commitmentsVal as Record<string, unknown>)) {\n const serialized = value as SerializedSigningCommitments;\n const commits = deserializeSigningCommitments(serialized);\n commitments.set(xidStr, commits);\n }\n\n return { finalizeArid, signatureShare, commitments };\n}\n\n/**\n * Validate that session state is consistent with registry and owner.\n *\n * Port of `validate_session_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSessionState(\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n owner: OwnerRecord,\n): void {\n if (receiveState.coordinator.urString() !== groupRecord.coordinator().xid().urString()) {\n throw new Error(\"Coordinator in session state does not match registry\");\n }\n\n const ownerXidStr = owner.xid().urString();\n const isParticipant = receiveState.participants.some((p) => p.urString() === ownerXidStr);\n if (!isParticipant) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n}\n\n/**\n * Validate share state against receive state and registry.\n *\n * Port of `validate_share_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateShareState(\n shareState: ShareState,\n receiveState: ReceiveState,\n groupRecord: GroupRecord,\n): void {\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\n \"No listening ARID for signFinalize. Did you run `frost sign participant share`?\",\n );\n }\n\n if (shareState.finalizeArid.hex() !== listeningAtArid.hex()) {\n throw new Error(\n `Registry listening ARID (${listeningAtArid.urString()}) does not match persisted finalize ARID (${shareState.finalizeArid.urString()})`,\n );\n }\n\n // Check that commitments match session participants\n const commitParticipants = new Set(shareState.commitments.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (commitParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Commitments do not match session participants\");\n }\n for (const p of commitParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Commitments do not match session participants\");\n }\n }\n}\n\n/**\n * Validate the finalize event.\n *\n * Port of `validate_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateFinalizeEvent(\n sealedEvent: SealedEvent<Envelope>,\n sessionId: ARID,\n groupRecord: GroupRecord,\n): void {\n // Get the content envelope (which is the SignFinalizeContent envelope)\n const contentEnvelope = sealedEvent.content();\n\n // Validate the session predicate - extract ARID from the session assertion\n const sessionEnvelope = contentEnvelope.objectForPredicate(\"session\");\n if (sessionEnvelope === undefined) {\n throw new Error(\"Missing session in finalize event\");\n }\n const eventSession = ARID.fromTaggedCbor(sessionEnvelope.subject().tryLeaf());\n if (eventSession.hex() !== sessionId.hex()) {\n throw new Error(\n `Event session ${eventSession.urString()} does not match expected ${sessionId.urString()}`,\n );\n }\n\n const expectedCoordinator = groupRecord.coordinator().xid();\n if (sealedEvent.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected event sender: ${sealedEvent.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Validate signature shares from the finalize event.\n *\n * Port of `validate_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction validateSignatureShares(\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n receiveState: ReceiveState,\n _shareState: ShareState,\n owner: OwnerRecord,\n): void {\n if (signatureSharesByXid.size < receiveState.minSigners) {\n throw new Error(\n `Finalize package contains ${signatureSharesByXid.size} signature shares but requires at least ${receiveState.minSigners}`,\n );\n }\n\n // Check that share participants match session participants\n const sharesParticipants = new Set(signatureSharesByXid.keys());\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (sharesParticipants.size !== sessionParticipants.size) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n for (const p of sharesParticipants) {\n if (!sessionParticipants.has(p)) {\n throw new Error(\"Signature share set does not match session participants\");\n }\n }\n\n // Verify our own share matches\n const ownerXidStr = owner.xid().urString();\n const myShare = signatureSharesByXid.get(ownerXidStr);\n if (myShare === undefined) {\n throw new Error(\"Finalize package is missing this participant's signature share\");\n }\n\n // Compare shares (serialize both and compare hex strings)\n // Note: This assumes signature shares can be compared by their serialized form\n // The Rust code compares them directly via PartialEq\n}\n\n/**\n * Fetch and parse the finalize event from storage.\n *\n * Port of `fetch_finalize_event()` from cmd/sign/participant/finalize.rs.\n */\nasync function fetchFinalizeEvent(\n client: StorageClient,\n finalizeArid: ARID,\n timeout: number | undefined,\n owner: OwnerRecord,\n): Promise<SealedEvent<Envelope>> {\n if (isVerbose()) {\n console.error(\"Fetching finalize package from Hubert...\");\n }\n\n const finalizeEnvelope = await getWithIndicator(\n client,\n finalizeArid,\n \"Finalize package\",\n timeout,\n isVerbose(),\n );\n\n if (finalizeEnvelope === null || finalizeEnvelope === undefined) {\n throw new Error(\"Finalize package not found in Hubert storage\");\n }\n\n const signerKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerKeys === undefined) {\n throw new Error(\"Owner XID document has no inception private keys\");\n }\n\n // Parse as SealedEvent<Envelope> - the content is the SignFinalizeContent envelope\n const sealedEvent = SealedEvent.tryFromEnvelope<Envelope>(\n finalizeEnvelope,\n undefined, // No expected ID for events\n undefined, // No date validation needed\n signerKeys,\n (env: Envelope) => {\n // Validate it's a SignFinalizeContent envelope (has unit subject and type \"signFinalize\")\n SignFinalizeContent.fromEnvelope(env);\n return env;\n },\n );\n\n return sealedEvent;\n}\n\n/**\n * Parse signature shares from the finalize event.\n *\n * Port of `parse_signature_shares()` from cmd/sign/participant/finalize.rs.\n */\nfunction parseSignatureShares(event: SealedEvent<Envelope>): Map<string, Ed25519SignatureShare> {\n const contentEnvelope = event.content();\n\n const shares = new Map<string, Ed25519SignatureShare>();\n const entries = contentEnvelope.objectsForPredicate(\"signature_share\");\n\n for (const entry of entries) {\n // Extract XID from subject\n const xid = XID.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract share hex string from \"share\" predicate\n const shareEnvelope = entry.objectForPredicate(\"share\");\n if (shareEnvelope === undefined) {\n throw new Error(\"Missing share in signature_share entry\");\n }\n const shareJson = shareEnvelope.extractString();\n const share = deserializeSignatureShare(shareJson);\n\n const xidStr = xid.urString();\n if (shares.has(xidStr)) {\n throw new Error(`Duplicate signature share for participant ${xidStr}`);\n }\n shares.set(xidStr, share);\n }\n\n if (shares.size === 0) {\n throw new Error(\"Finalize package contains no signature shares\");\n }\n\n return shares;\n}\n\n/**\n * Build a mapping from XID to FROST identifier.\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/finalize.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const xid = participants[i];\n const identifier = identifierFromU16(i + 1);\n map.set(xid.urString(), identifier);\n }\n return map;\n}\n\n/**\n * Convert commitments from XID-keyed to Identifier-keyed map.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidStr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Convert signature shares from XID-keyed to Identifier-keyed map.\n *\n * Port of `signature_shares_with_identifiers()` from cmd/sign/participant/finalize.rs.\n */\nfunction signatureSharesWithIdentifiers(\n shares: Map<string, Ed25519SignatureShare>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SignatureShare> {\n const mapped = new Map<FrostIdentifier, Ed25519SignatureShare>();\n for (const [xidStr, share] of shares) {\n const identifier = xidToIdentifier.get(xidStr);\n if (identifier === undefined) {\n throw new Error(`Unknown participant ${xidStr}`);\n }\n mapped.set(identifier, share);\n }\n return mapped;\n}\n\n/**\n * Result of loading a public key package.\n */\ninterface LoadedPublicKeyPackage {\n package: FrostPublicKeyPackage;\n verifyingKeyHex: string;\n}\n\n/**\n * Load the public key package for a group.\n *\n * Port of `load_public_key_package()` from cmd/sign/participant/finalize.rs.\n */\nfunction loadPublicKeyPackage(registryPath: string, groupId: ARID): LoadedPublicKeyPackage {\n const base = path.dirname(registryPath);\n\n // Try direct path first\n const directPath = path.join(base, \"group-state\", groupId.hex(), \"public_key_package.json\");\n if (fs.existsSync(directPath)) {\n const raw = JSON.parse(fs.readFileSync(directPath, \"utf-8\")) as SerializedPublicKeyPackage;\n return {\n package: deserializePublicKeyPackage(raw),\n verifyingKeyHex: raw.verifyingKey,\n };\n }\n\n // Fallback to collected_finalize.json (coordinator)\n const collectedPath = path.join(base, \"group-state\", groupId.hex(), \"collected_finalize.json\");\n if (fs.existsSync(collectedPath)) {\n const raw = JSON.parse(fs.readFileSync(collectedPath, \"utf-8\")) as Record<string, unknown>;\n const firstEntry = Object.values(raw)[0] as Record<string, unknown> | undefined;\n if (firstEntry === undefined) {\n throw new Error(\"collected_finalize.json is empty\");\n }\n const publicKeyValue = firstEntry[\"public_key_package\"] as\n SerializedPublicKeyPackage | undefined;\n if (publicKeyValue === undefined) {\n throw new Error(\"public_key_package missing in collected_finalize.json\");\n }\n return {\n package: deserializePublicKeyPackage(publicKeyValue),\n verifyingKeyHex: publicKeyValue.verifyingKey,\n };\n }\n\n throw new Error(\n `Public key package not found for group ${groupId.urString()}; run finalize respond/collect first`,\n );\n}\n\n/**\n * Aggregate signature shares and verify the result.\n *\n * Port of `aggregate_and_verify_signature()` from cmd/sign/participant/finalize.rs.\n */\nfunction aggregateAndVerifySignature(\n registryPath: string,\n groupId: ARID,\n participants: XID[],\n commitments: Map<string, Ed25519SigningCommitments>,\n signatureSharesByXid: Map<string, Ed25519SignatureShare>,\n targetEnvelope: Envelope,\n targetDigest: Digest,\n): [Signature, Envelope, SigningPublicKey] {\n const xidToIdentifier = xidIdentifierMap(participants);\n const signingCommitments = commitmentsWithIdentifiers(commitments, xidToIdentifier);\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n const signatureSharesByIdentifier = signatureSharesWithIdentifiers(\n signatureSharesByXid,\n xidToIdentifier,\n );\n\n const { package: publicKeyPackage, verifyingKeyHex } = loadPublicKeyPackage(\n registryPath,\n groupId,\n );\n\n // Get verifying key from public key package\n const verifyingKeyBytes = hexToBytes(verifyingKeyHex);\n const verifyingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n\n // Aggregate the signature shares\n const aggregatedSignature = aggregateSignatures(\n signingPackage,\n signatureSharesByIdentifier,\n publicKeyPackage,\n );\n\n // Serialize the aggregated signature\n const sigBytes = serializeSignature(aggregatedSignature);\n if (sigBytes.length !== 64) {\n throw new Error(\"Aggregated signature is not 64 bytes\");\n }\n const finalSignature = Signature.ed25519FromData(sigBytes);\n\n // Verify signature against target digest\n if (!verifyingKey.verify(finalSignature, targetDigest.data())) {\n throw new Error(\"Aggregated signature failed verification against target digest\");\n }\n\n // Create signed envelope\n const signedEnvelope = targetEnvelope.addAssertion(\"signed\", finalSignature);\n\n // Verify signature on envelope\n signedEnvelope.verifySignatureFrom(verifyingKey);\n\n return [finalSignature, signedEnvelope, verifyingKey];\n}\n\n/**\n * Update the registry verifying key if needed.\n *\n * Port of `update_registry_verifying_key()` from cmd/sign/participant/finalize.rs.\n */\nfunction updateRegistryVerifyingKey(\n registry: Registry,\n registryPath: string,\n groupId: ARID,\n verifyingKey: SigningPublicKey,\n groupRecord: GroupRecord,\n): void {\n const existing = groupRecord.verifyingKey();\n if (existing !== undefined) {\n if (existing.urString() !== verifyingKey.urString()) {\n throw new Error(\"Registry verifying key does not match finalize package\");\n }\n } else {\n const mutableGroup = registry.group(groupId);\n if (mutableGroup === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n mutableGroup.setVerifyingKey(verifyingKey);\n registry.save(registryPath);\n }\n}\n\n/**\n * Persist the final state to disk.\n *\n * Port of `persist_final_state()` from cmd/sign/participant/finalize.rs.\n */\nfunction persistFinalState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n signature: Signature,\n signedEnvelope: Envelope,\n signatureShares: Map<string, Ed25519SignatureShare>,\n shareState: ShareState,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n const finalPath = path.join(dir, \"final.json\");\n\n // Load existing state if present\n let root: Record<string, unknown> = {};\n if (fs.existsSync(finalPath)) {\n root = JSON.parse(fs.readFileSync(finalPath, \"utf-8\")) as Record<string, unknown>;\n }\n\n // Build shares JSON\n const sharesJson: Record<string, string> = {};\n for (const [xidStr, share] of signatureShares) {\n sharesJson[xidStr] = serializeSignatureShare(share);\n }\n\n // Build commitments JSON\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidStr, commits] of shareState.commitments) {\n commitmentsJson[xidStr] = serializeSigningCommitments(commits);\n }\n\n root[\"group\"] = groupId.urString();\n root[\"session\"] = sessionId.urString();\n root[\"signature\"] = signature.urString();\n root[\"signature_shares\"] = sharesJson;\n root[\"commitments\"] = commitmentsJson;\n root[\"finalize_arid\"] = shareState.finalizeArid.urString();\n root[\"signed_target\"] = signedEnvelope.urString();\n\n fs.writeFileSync(finalPath, JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant finalize command.\n *\n * Receives the finalize event with aggregated signature.\n *\n * Port of `finalize()` from cmd/sign/participant/finalize.rs.\n */\nexport async function finalize(\n client: StorageClient,\n options: SignFinalizeOptions,\n cwd: string,\n): Promise<SignFinalizeResult> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint =\n options.groupId !== undefined && options.groupId !== \"\"\n ? parseAridUr(options.groupId)\n : undefined;\n\n // Load and validate session state\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n const groupRecord = registry.group(groupId);\n\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n validateSessionState(receiveState, groupRecord, owner);\n\n const shareState = loadShareState(registryPath, groupId, sessionId);\n validateShareState(shareState, receiveState, groupRecord);\n\n // Fetch finalize event\n const sealedEvent = await fetchFinalizeEvent(\n client,\n shareState.finalizeArid,\n options.timeoutSeconds,\n owner,\n );\n\n // Validate event\n validateFinalizeEvent(sealedEvent, sessionId, groupRecord);\n\n // Extract and validate signature shares\n const signatureSharesByXid = parseSignatureShares(sealedEvent);\n validateSignatureShares(signatureSharesByXid, receiveState, shareState, owner);\n\n // Load target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest = targetEnvelope.subject().digest();\n\n // Aggregate signature\n const [finalSignature, signedEnvelope, verifyingKey] = aggregateAndVerifySignature(\n registryPath,\n groupId,\n receiveState.participants,\n shareState.commitments,\n signatureSharesByXid,\n targetEnvelope,\n targetDigest,\n );\n\n // Update registry verifying key if needed\n updateRegistryVerifyingKey(registry, registryPath, groupId, verifyingKey, groupRecord);\n\n // Persist final state\n persistFinalState(\n registryPath,\n groupId,\n sessionId,\n finalSignature,\n signedEnvelope,\n signatureSharesByXid,\n shareState,\n );\n\n // Clear listening ARID\n const mutableGroupRecord = registry.group(groupId);\n if (mutableGroupRecord !== undefined) {\n mutableGroupRecord.clearListeningAtArid();\n registry.save(registryPath);\n }\n\n const signatureStr = finalSignature.urString();\n const signedEnvelopeStr = signedEnvelope.urString();\n\n if (options.verbose === true) {\n console.log(signatureStr);\n console.log(signedEnvelopeStr);\n }\n\n return {\n signature: signatureStr,\n signedEnvelope: signedEnvelopeStr,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
2
|
import { n as compareXidBytes } from "./proposed-participant-Detb823_.mjs";
|
|
3
3
|
import { Registry, resolveRegistryPath } from "./registry/index.mjs";
|
|
4
|
-
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose } from "./common-
|
|
4
|
+
import { c as parseAridUr, h as signingKeyFromVerifying, n as isVerbose } from "./common-k2QC6AST.mjs";
|
|
5
5
|
import { t as getWithIndicator } from "./busy-BlU8_pS2.mjs";
|
|
6
6
|
import { aggregateSignatures, createSigningPackage, deserializePublicKeyPackage, deserializeSignatureShare, deserializeSigningCommitments, hexToBytes, identifierFromU16, serializeSignature, serializeSignatureShare, serializeSigningCommitments } from "./frost/index.mjs";
|
|
7
|
-
import { n as signingStateDir, t as SignFinalizeContent } from "./common
|
|
7
|
+
import { n as signingStateDir, t as SignFinalizeContent } from "./common-DCyUSYkT.mjs";
|
|
8
8
|
import { ARID, Signature, XID } from "@bcts/components";
|
|
9
9
|
import { Envelope } from "@bcts/envelope";
|
|
10
10
|
import { SealedEvent } from "@bcts/gstp";
|
|
@@ -386,4 +386,4 @@ async function finalize(client, options, cwd) {
|
|
|
386
386
|
//#endregion
|
|
387
387
|
export { finalize_exports as n, finalize as t };
|
|
388
388
|
|
|
389
|
-
//# sourceMappingURL=finalize-
|
|
389
|
+
//# sourceMappingURL=finalize-BVOveyol.mjs.map
|