@bcts/frost-hubert 1.0.0-alpha.22 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/bin/frost.cjs +347 -75
  2. package/dist/bin/frost.cjs.map +1 -1
  3. package/dist/bin/frost.mjs +347 -75
  4. package/dist/bin/frost.mjs.map +1 -1
  5. package/dist/busy-DkM2jAIZ.mjs +27 -0
  6. package/dist/busy-DkM2jAIZ.mjs.map +1 -0
  7. package/dist/busy-EZU7EKr6.cjs +38 -0
  8. package/dist/busy-EZU7EKr6.cjs.map +1 -0
  9. package/dist/{chunk-uaV2rQ02.cjs → chunk-CZWwpsFl.cjs} +22 -32
  10. package/dist/{chunk-ClPoSABd.mjs → chunk-CjcI7cDX.mjs} +6 -12
  11. package/dist/cmd/index.cjs +46 -43
  12. package/dist/cmd/index.d.cts +2 -4
  13. package/dist/cmd/index.d.mts +2 -4
  14. package/dist/cmd/index.mjs +7 -6
  15. package/dist/cmd-Bw9_i2_f.cjs +130 -0
  16. package/dist/cmd-Bw9_i2_f.cjs.map +1 -0
  17. package/dist/cmd-CS1uJtuD.mjs +113 -0
  18. package/dist/cmd-CS1uJtuD.mjs.map +1 -0
  19. package/dist/common-CvH6dFvQ.mjs +282 -0
  20. package/dist/common-CvH6dFvQ.mjs.map +1 -0
  21. package/dist/common-DUWvtc08.mjs +96 -0
  22. package/dist/common-DUWvtc08.mjs.map +1 -0
  23. package/dist/common-lKP5EzHy.cjs +372 -0
  24. package/dist/common-lKP5EzHy.cjs.map +1 -0
  25. package/dist/common-lThIvJmZ.cjs +114 -0
  26. package/dist/common-lThIvJmZ.cjs.map +1 -0
  27. package/dist/dkg/index.cjs +245 -7
  28. package/dist/dkg/index.cjs.map +1 -0
  29. package/dist/dkg/index.d.cts +2 -2
  30. package/dist/dkg/index.d.mts +2 -2
  31. package/dist/dkg/index.mjs +238 -2
  32. package/dist/dkg/index.mjs.map +1 -0
  33. package/dist/finalize-BRgJK-Xv.cjs +402 -0
  34. package/dist/finalize-BRgJK-Xv.cjs.map +1 -0
  35. package/dist/finalize-BfLgzn8f.cjs +303 -0
  36. package/dist/finalize-BfLgzn8f.cjs.map +1 -0
  37. package/dist/finalize-CNTDj6aS.mjs +389 -0
  38. package/dist/finalize-CNTDj6aS.mjs.map +1 -0
  39. package/dist/finalize-EC3ikHQq.mjs +252 -0
  40. package/dist/finalize-EC3ikHQq.mjs.map +1 -0
  41. package/dist/finalize-IA01t_Qq.mjs +290 -0
  42. package/dist/finalize-IA01t_Qq.mjs.map +1 -0
  43. package/dist/finalize-UPyI1yb1.cjs +265 -0
  44. package/dist/finalize-UPyI1yb1.cjs.map +1 -0
  45. package/dist/frost/index.cjs +8 -9
  46. package/dist/frost/index.cjs.map +1 -1
  47. package/dist/frost/index.mjs +2 -3
  48. package/dist/frost/index.mjs.map +1 -1
  49. package/dist/{group-invite-Dz1Jmiky.d.cts → index-B3c-80VS.d.cts} +25 -2
  50. package/dist/index-B3c-80VS.d.cts.map +1 -0
  51. package/dist/{index-CcvTi5EA.d.cts → index-BgbSGpxn.d.mts} +102 -80
  52. package/dist/index-BgbSGpxn.d.mts.map +1 -0
  53. package/dist/{registry-impl-CE76sTXQ.d.cts → index-C8QeHNwa.d.cts} +46 -2
  54. package/dist/index-C8QeHNwa.d.cts.map +1 -0
  55. package/dist/{group-invite-Wk9CIbHL.d.mts → index-D3QTWkEm.d.mts} +25 -2
  56. package/dist/index-D3QTWkEm.d.mts.map +1 -0
  57. package/dist/{registry-impl-BETn_lEO.d.mts → index-DVbWyOs7.d.mts} +46 -2
  58. package/dist/index-DVbWyOs7.d.mts.map +1 -0
  59. package/dist/{index-DNCPeLNM.d.mts → index-F1iNEAJR.d.cts} +102 -80
  60. package/dist/index-F1iNEAJR.d.cts.map +1 -0
  61. package/dist/index.cjs +72 -68
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +4 -7
  64. package/dist/index.d.cts.map +1 -1
  65. package/dist/index.d.mts +4 -7
  66. package/dist/index.d.mts.map +1 -1
  67. package/dist/index.mjs +11 -10
  68. package/dist/index.mjs.map +1 -1
  69. package/dist/invite-5277FQVT.cjs +274 -0
  70. package/dist/invite-5277FQVT.cjs.map +1 -0
  71. package/dist/invite-DUTcfTgX.cjs +109 -0
  72. package/dist/invite-DUTcfTgX.cjs.map +1 -0
  73. package/dist/invite-IU4n0dq2.mjs +96 -0
  74. package/dist/invite-IU4n0dq2.mjs.map +1 -0
  75. package/dist/invite-RU-OXTNS.mjs +219 -0
  76. package/dist/invite-RU-OXTNS.mjs.map +1 -0
  77. package/dist/parallel-D1R6ZGlY.cjs +318 -0
  78. package/dist/parallel-D1R6ZGlY.cjs.map +1 -0
  79. package/dist/parallel-D6zc6VW4.mjs +235 -0
  80. package/dist/parallel-D6zc6VW4.mjs.map +1 -0
  81. package/dist/proposed-participant-Dm1Eq6mX.cjs +141 -0
  82. package/dist/proposed-participant-Dm1Eq6mX.cjs.map +1 -0
  83. package/dist/proposed-participant-cWM7iUrO.mjs +129 -0
  84. package/dist/proposed-participant-cWM7iUrO.mjs.map +1 -0
  85. package/dist/receive-CAI-x4II.cjs +213 -0
  86. package/dist/receive-CAI-x4II.cjs.map +1 -0
  87. package/dist/receive-D2Nn68L7.mjs +188 -0
  88. package/dist/receive-D2Nn68L7.mjs.map +1 -0
  89. package/dist/receive-DA_KQEgk.mjs +177 -0
  90. package/dist/receive-DA_KQEgk.mjs.map +1 -0
  91. package/dist/receive-kZMsXhbK.cjs +190 -0
  92. package/dist/receive-kZMsXhbK.cjs.map +1 -0
  93. package/dist/registry/index.cjs +881 -13
  94. package/dist/registry/index.cjs.map +1 -0
  95. package/dist/registry/index.d.cts +1 -1
  96. package/dist/registry/index.d.mts +1 -1
  97. package/dist/registry/index.mjs +867 -2
  98. package/dist/registry/index.mjs.map +1 -0
  99. package/dist/{registry-FMU-ec5K.cjs → registry-9puTaRrD.cjs} +28 -31
  100. package/dist/registry-9puTaRrD.cjs.map +1 -0
  101. package/dist/{registry-BDnNV1Rk.mjs → registry-BpCwtrRt.mjs} +7 -10
  102. package/dist/{registry-BDnNV1Rk.mjs.map → registry-BpCwtrRt.mjs.map} +1 -1
  103. package/dist/round1-4Hyx8w0x.cjs +422 -0
  104. package/dist/round1-4Hyx8w0x.cjs.map +1 -0
  105. package/dist/round1-7v9LlE11.mjs +373 -0
  106. package/dist/round1-7v9LlE11.mjs.map +1 -0
  107. package/dist/round1-BHBjru1m.cjs +465 -0
  108. package/dist/round1-BHBjru1m.cjs.map +1 -0
  109. package/dist/round1-CMLKN2RR.mjs +195 -0
  110. package/dist/round1-CMLKN2RR.mjs.map +1 -0
  111. package/dist/round1-CWSXZx5R.cjs +208 -0
  112. package/dist/round1-CWSXZx5R.cjs.map +1 -0
  113. package/dist/round1-CcQCGlIT.mjs +208 -0
  114. package/dist/round1-CcQCGlIT.mjs.map +1 -0
  115. package/dist/round1-Cgm7j1kI.mjs +452 -0
  116. package/dist/round1-Cgm7j1kI.mjs.map +1 -0
  117. package/dist/round1-DQ0fnc1H.cjs +221 -0
  118. package/dist/round1-DQ0fnc1H.cjs.map +1 -0
  119. package/dist/round2-BWz9SQIi.cjs +305 -0
  120. package/dist/round2-BWz9SQIi.cjs.map +1 -0
  121. package/dist/round2-BkNRCXgS.mjs +292 -0
  122. package/dist/round2-BkNRCXgS.mjs.map +1 -0
  123. package/dist/round2-Bl2uK93U.mjs +450 -0
  124. package/dist/round2-Bl2uK93U.mjs.map +1 -0
  125. package/dist/round2-CdUT-AhH.cjs +499 -0
  126. package/dist/round2-CdUT-AhH.cjs.map +1 -0
  127. package/dist/round2-DOA3rnV-.mjs +280 -0
  128. package/dist/round2-DOA3rnV-.mjs.map +1 -0
  129. package/dist/round2-Dg24w-TU.mjs +397 -0
  130. package/dist/round2-Dg24w-TU.mjs.map +1 -0
  131. package/dist/round2-LylCa84n.cjs +293 -0
  132. package/dist/round2-LylCa84n.cjs.map +1 -0
  133. package/dist/round2-o2Q-GMbX.cjs +410 -0
  134. package/dist/round2-o2Q-GMbX.cjs.map +1 -0
  135. package/dist/storage-B-Gu68-O.cjs +79 -0
  136. package/dist/storage-B-Gu68-O.cjs.map +1 -0
  137. package/dist/storage-Bkkliz0K.mjs +74 -0
  138. package/dist/storage-Bkkliz0K.mjs.map +1 -0
  139. package/package.json +17 -17
  140. package/src/bin/frost.ts +849 -128
  141. package/src/cmd/common.ts +19 -1
  142. package/src/cmd/dkg/common.ts +97 -10
  143. package/src/cmd/dkg/coordinator/invite.ts +5 -2
  144. package/src/cmd/dkg/participant/finalize.ts +52 -18
  145. package/src/cmd/dkg/participant/round1.ts +39 -38
  146. package/src/cmd/dkg/participant/round2.ts +60 -26
  147. package/src/cmd/sign/coordinator/round2.ts +5 -1
  148. package/src/cmd/sign/participant/finalize.ts +6 -2
  149. package/src/cmd/sign/participant/receive.ts +5 -2
  150. package/src/dkg/group-invite.ts +12 -2
  151. package/src/dkg/proposed-participant.ts +33 -5
  152. package/src/frost/index.ts +1 -1
  153. package/src/registry/owner-record.ts +13 -2
  154. package/src/registry/participant-record.ts +36 -4
  155. package/src/registry/registry-impl.ts +74 -18
  156. package/dist/group-invite-CrbOabFL.cjs +0 -368
  157. package/dist/group-invite-CrbOabFL.cjs.map +0 -1
  158. package/dist/group-invite-Dz1Jmiky.d.cts.map +0 -1
  159. package/dist/group-invite-RPElq-fm.mjs +0 -338
  160. package/dist/group-invite-RPElq-fm.mjs.map +0 -1
  161. package/dist/group-invite-Wk9CIbHL.d.mts.map +0 -1
  162. package/dist/index-CcvTi5EA.d.cts.map +0 -1
  163. package/dist/index-DNCPeLNM.d.mts.map +0 -1
  164. package/dist/registry-FMU-ec5K.cjs.map +0 -1
  165. package/dist/registry-impl-BETn_lEO.d.mts.map +0 -1
  166. package/dist/registry-impl-C7w4awTv.cjs +0 -865
  167. package/dist/registry-impl-C7w4awTv.cjs.map +0 -1
  168. package/dist/registry-impl-CE76sTXQ.d.cts.map +0 -1
  169. package/dist/registry-impl-eYXVSPwM.mjs +0 -797
  170. package/dist/registry-impl-eYXVSPwM.mjs.map +0 -1
  171. package/dist/sign-2bOp18Fs.cjs +0 -4875
  172. package/dist/sign-2bOp18Fs.cjs.map +0 -1
  173. package/dist/sign-D8C3HJ4B.mjs +0 -4736
  174. package/dist/sign-D8C3HJ4B.mjs.map +0 -1
@@ -0,0 +1,303 @@
1
+ const require_chunk = require("./chunk-CZWwpsFl.cjs");
2
+ const require_registry_index = require("./registry/index.cjs");
3
+ const require_common = require("./common-lKP5EzHy.cjs");
4
+ const require_busy = require("./busy-EZU7EKr6.cjs");
5
+ const require_parallel = require("./parallel-D1R6ZGlY.cjs");
6
+ let _bcts_gstp = require("@bcts/gstp");
7
+ let node_fs = require("node:fs");
8
+ node_fs = require_chunk.__toESM(node_fs, 1);
9
+ let node_path = require("node:path");
10
+ node_path = require_chunk.__toESM(node_path, 1);
11
+ //#region src/cmd/dkg/coordinator/finalize.ts
12
+ /**
13
+ * Copyright © 2023-2026 Blockchain Commons, LLC
14
+ * Copyright © 2025-2026 Parity Technologies
15
+ *
16
+ *
17
+ * DKG coordinator finalize command.
18
+ *
19
+ * Port of cmd/dkg/coordinator/finalize.rs from frost-hubert-rust.
20
+ *
21
+ * @module
22
+ */
23
+ var finalize_exports = /* @__PURE__ */ require_chunk.__exportAll({ finalize: () => finalize });
24
+ /**
25
+ * Validate that the owner is the coordinator of the group.
26
+ *
27
+ * Port of coordinator check from finalize.rs lines 76-82.
28
+ */
29
+ function validateCoordinator(groupRecord, ownerXid) {
30
+ if (groupRecord.coordinator().xid().urString() !== ownerXid.urString()) throw new Error(`Only the coordinator can collect finalize responses. Coordinator: ${groupRecord.coordinator().xid().urString()}, Owner: ${ownerXid.urString()}`);
31
+ }
32
+ /**
33
+ * Validate envelope and extract finalize data (for parallel fetch).
34
+ *
35
+ * Port of `validate_and_extract_finalize_response()` from finalize.rs lines 407-466.
36
+ */
37
+ function validateAndExtractFinalizeResponse(envelope, coordinatorKeys, expectedGroupId, expectedParticipant) {
38
+ const now = /* @__PURE__ */ new Date();
39
+ let sealed;
40
+ try {
41
+ sealed = _bcts_gstp.SealedResponse.tryFromEncryptedEnvelope(envelope, void 0, now, coordinatorKeys);
42
+ } catch (err) {
43
+ return { rejected: `Failed to decrypt/parse response: ${err instanceof Error ? err.message : String(err)}` };
44
+ }
45
+ if (!sealed.isOk()) try {
46
+ return { rejected: `Participant reported error: ${sealed.error().optionalObjectForPredicate("reason")?.extractString() ?? "unknown reason"}` };
47
+ } catch {
48
+ return { rejected: "Participant reported error: unknown reason" };
49
+ }
50
+ let result;
51
+ try {
52
+ result = sealed.result();
53
+ } catch {
54
+ return { rejected: "Finalize response has no result" };
55
+ }
56
+ try {
57
+ result.checkSubjectUnit();
58
+ result.checkType("dkgFinalizeResponse");
59
+ } catch (err) {
60
+ return { rejected: `Invalid response type: ${err instanceof Error ? err.message : String(err)}` };
61
+ }
62
+ try {
63
+ const groupId = require_common.parseAridUr(result.objectForPredicate("group").extractString());
64
+ if (groupId.urString() !== expectedGroupId.urString()) return { rejected: `Group ${groupId.urString()} does not match expected ${expectedGroupId.urString()}` };
65
+ } catch (err) {
66
+ return { rejected: `Failed to extract group: ${err instanceof Error ? err.message : String(err)}` };
67
+ }
68
+ try {
69
+ const participantStr = result.objectForPredicate("participant").extractString();
70
+ const { XID: XIDClass } = require("@bcts/components");
71
+ const participantXid = XIDClass.fromURString(participantStr);
72
+ if (participantXid.urString() !== expectedParticipant.urString()) return { rejected: `Participant ${participantXid.urString()} does not match expected ${expectedParticipant.urString()}` };
73
+ } catch (err) {
74
+ return { rejected: `Failed to extract participant: ${err instanceof Error ? err.message : String(err)}` };
75
+ }
76
+ let keyPackage;
77
+ let publicKeyPackage;
78
+ try {
79
+ const keyJsonStr = result.objectForPredicate("key_package").extractString();
80
+ keyPackage = JSON.parse(keyJsonStr);
81
+ } catch (err) {
82
+ return { rejected: `Failed to parse key_package: ${err instanceof Error ? err.message : String(err)}` };
83
+ }
84
+ try {
85
+ const pubJsonStr = result.objectForPredicate("public_key_package").extractString();
86
+ publicKeyPackage = JSON.parse(pubJsonStr);
87
+ } catch (err) {
88
+ return { rejected: `Failed to parse public_key_package: ${err instanceof Error ? err.message : String(err)}` };
89
+ }
90
+ return {
91
+ keyPackage,
92
+ publicKeyPackage
93
+ };
94
+ }
95
+ /**
96
+ * Fetch a finalize response sequentially.
97
+ *
98
+ * Port of `fetch_finalize_response()` from finalize.rs lines 282-358.
99
+ */
100
+ async function fetchFinalizeResponse(client, responseArid, timeout, coordinatorKeys, expectedGroup, expectedParticipant, participantName) {
101
+ const envelope = await require_busy.getWithIndicator(client, responseArid, participantName, timeout, require_common.isVerbose());
102
+ if (envelope === null || envelope === void 0) throw new Error("Finalize response not found in Hubert storage");
103
+ const result = validateAndExtractFinalizeResponse(envelope, coordinatorKeys, expectedGroup, expectedParticipant);
104
+ if ("rejected" in result) throw new Error(result.rejected);
105
+ return {
106
+ participant: expectedParticipant,
107
+ keyPackage: result.keyPackage,
108
+ publicKeyPackage: result.publicKeyPackage
109
+ };
110
+ }
111
+ /**
112
+ * Collect finalize responses in parallel with progress display.
113
+ *
114
+ * Port of `collect_finalize_parallel()` from finalize.rs lines 371-404.
115
+ */
116
+ async function collectFinalizeParallel(client, registry, pendingRequests, coordinatorKeys, expectedGroupId, timeout) {
117
+ const requests = [];
118
+ for (const [xid, arid] of pendingRequests.iterCollect()) {
119
+ const name = registry.participant(xid)?.petName() ?? xid.urString();
120
+ requests.push([
121
+ xid,
122
+ arid,
123
+ name
124
+ ]);
125
+ }
126
+ return require_parallel.parallelFetch(client, requests, (envelope, xid) => validateAndExtractFinalizeResponse(envelope, coordinatorKeys, expectedGroupId, xid), require_parallel.parallelFetchConfigWithTimeout(timeout));
127
+ }
128
+ /**
129
+ * Finalize collection results: persist, update registry, print summary.
130
+ *
131
+ * Port of `finalize_collection_results()` from finalize.rs lines 469-590.
132
+ */
133
+ function finalizeFinalizeCollectionResults(collection, registryPath, registry, groupId) {
134
+ if (collection.rejections.length > 0) {
135
+ console.error();
136
+ console.error("Rejections:");
137
+ for (const [xid, reason] of collection.rejections) console.error(` ${xid.urString()}: ${reason}`);
138
+ }
139
+ if (collection.errors.length > 0) {
140
+ console.error();
141
+ console.error("Errors:");
142
+ for (const [xid, error] of collection.errors) console.error(` ${xid.urString()}: ${error}`);
143
+ }
144
+ if (collection.timeouts.length > 0) {
145
+ console.error();
146
+ console.error("Timeouts:");
147
+ for (const xid of collection.timeouts) console.error(` ${xid.urString()}`);
148
+ }
149
+ if (!collection.allSucceeded()) throw new Error(`Finalize collection incomplete: ${collection.successes.length} succeeded, ${collection.rejections.length} rejected, ${collection.errors.length} errors, ${collection.timeouts.length} timeouts`);
150
+ let groupVerifyingKey;
151
+ for (const [xid, data] of collection.successes) {
152
+ const pubKeyPkg = data.publicKeyPackage;
153
+ if (!pubKeyPkg.verifying_key) throw new Error(`Failed to extract verifying key for ${xid.urString()}: missing verifying_key field`);
154
+ let signingKey;
155
+ try {
156
+ signingKey = require_common.signingKeyFromVerifying(hexToBytes(pubKeyPkg.verifying_key));
157
+ } catch (err) {
158
+ throw new Error(`Failed to extract verifying key for ${xid.urString()}: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
159
+ }
160
+ if (groupVerifyingKey !== void 0) {
161
+ if (groupVerifyingKey.urString() !== signingKey.urString()) throw new Error(`Group verifying key mismatch for participant ${xid.urString()}`);
162
+ } else groupVerifyingKey = signingKey;
163
+ }
164
+ const stateDir = require_common.groupStateDir(registryPath, groupId.hex());
165
+ node_fs.mkdirSync(stateDir, { recursive: true });
166
+ const collectedPath = node_path.join(stateDir, "collected_finalize.json");
167
+ const root = {};
168
+ for (const [xid, data] of collection.successes) root[xid.urString()] = {
169
+ key_package: data.keyPackage,
170
+ public_key_package: data.publicKeyPackage
171
+ };
172
+ node_fs.writeFileSync(collectedPath, JSON.stringify(root, null, 2));
173
+ const groupRecord = registry.group(groupId);
174
+ if (groupRecord === void 0) throw new Error("Group not found in registry");
175
+ if (groupVerifyingKey !== void 0) groupRecord.setVerifyingKey(groupVerifyingKey);
176
+ groupRecord.clearPendingRequests();
177
+ registry.save(registryPath);
178
+ if (require_common.isVerbose()) {
179
+ console.error();
180
+ console.error(`Collected ${collection.successes.length} finalize responses. Saved to ${collectedPath}`);
181
+ if (groupVerifyingKey !== void 0) console.error(groupVerifyingKey.urString());
182
+ } else if (groupVerifyingKey !== void 0) console.log(groupVerifyingKey.urString());
183
+ return groupVerifyingKey;
184
+ }
185
+ /**
186
+ * Helper to convert hex string to bytes.
187
+ */
188
+ function hexToBytes(hex) {
189
+ const bytes = new Uint8Array(hex.length / 2);
190
+ for (let i = 0; i < bytes.length; i++) bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
191
+ return bytes;
192
+ }
193
+ /**
194
+ * Execute the DKG coordinator finalize command.
195
+ *
196
+ * Collects finalize responses (key/public key packages) from all participants.
197
+ *
198
+ * Port of `finalize()` from cmd/dkg/coordinator/finalize.rs.
199
+ */
200
+ async function finalize(client, options, cwd) {
201
+ const registryPath = require_registry_index.resolveRegistryPath(options.registryPath, cwd);
202
+ const registry = require_registry_index.Registry.load(registryPath);
203
+ const owner = registry.owner();
204
+ if (owner === void 0) throw new Error("Registry owner is required");
205
+ const groupId = require_common.parseAridUr(options.groupId);
206
+ const groupRecord = registry.group(groupId);
207
+ if (groupRecord === void 0) throw new Error(`Group ${options.groupId} not found in registry`);
208
+ validateCoordinator(groupRecord, owner.xid());
209
+ const pendingRequests = groupRecord.pendingRequests();
210
+ if (pendingRequests.isEmpty()) throw new Error("No pending requests for this group. Did you run 'frost dkg coordinator finalize send'?");
211
+ const coordinatorKeys = owner.xidDocument().inceptionPrivateKeys();
212
+ if (coordinatorKeys === void 0) throw new Error("Coordinator XID document has no private keys");
213
+ let verifyingKey;
214
+ let collected;
215
+ let rejected = 0;
216
+ let errors;
217
+ let timeouts = 0;
218
+ if (options.parallel === true) {
219
+ const collection = await collectFinalizeParallel(client, registry, pendingRequests, coordinatorKeys, groupId, options.timeoutSeconds);
220
+ verifyingKey = finalizeFinalizeCollectionResults(collection, registryPath, registry, groupId);
221
+ collected = collection.successes.length;
222
+ rejected = collection.rejections.length;
223
+ errors = collection.errors.length;
224
+ timeouts = collection.timeouts.length;
225
+ } else {
226
+ const collectedEntries = [];
227
+ const errorEntries = [];
228
+ let groupVerifyingKey;
229
+ if (require_common.isVerbose()) console.error(`Collecting finalize responses from ${pendingRequests.len()} participants...`);
230
+ for (const [participantXid, collectFromArid] of pendingRequests.iterCollect()) {
231
+ const name = registry.participant(participantXid)?.petName() ?? participantXid.urString();
232
+ try {
233
+ const entry = await fetchFinalizeResponse(client, collectFromArid, options.timeoutSeconds, coordinatorKeys, groupId, participantXid, name);
234
+ const pubKeyPkg = entry.publicKeyPackage;
235
+ if (!pubKeyPkg.verifying_key) throw new Error("missing verifying_key field");
236
+ const signingKey = require_common.signingKeyFromVerifying(hexToBytes(pubKeyPkg.verifying_key));
237
+ if (groupVerifyingKey !== void 0) {
238
+ if (groupVerifyingKey.urString() !== signingKey.urString()) {
239
+ if (require_common.isVerbose()) console.error("error: group verifying key mismatch");
240
+ errorEntries.push([participantXid, "Group verifying key mismatch across responses"]);
241
+ continue;
242
+ }
243
+ } else groupVerifyingKey = signingKey;
244
+ collectedEntries.push(entry);
245
+ } catch (err) {
246
+ if (require_common.isVerbose()) console.error(`error: ${err instanceof Error ? err.message : String(err)}`);
247
+ errorEntries.push([participantXid, err instanceof Error ? err.message : String(err)]);
248
+ }
249
+ }
250
+ if (errorEntries.length > 0) {
251
+ if (require_common.isVerbose()) {
252
+ console.error();
253
+ console.error(`Failed to collect from ${errorEntries.length} participants:`);
254
+ for (const [xid, error] of errorEntries) console.error(` ${xid.urString()}: ${error}`);
255
+ }
256
+ throw new Error(`Finalize collection incomplete: ${errorEntries.length} of ${pendingRequests.len()} responses failed`);
257
+ }
258
+ const stateDir = require_common.groupStateDir(registryPath, groupId.hex());
259
+ node_fs.mkdirSync(stateDir, { recursive: true });
260
+ const collectedPath = node_path.join(stateDir, "collected_finalize.json");
261
+ const root = {};
262
+ for (const entry of collectedEntries) root[entry.participant.urString()] = {
263
+ key_package: entry.keyPackage,
264
+ public_key_package: entry.publicKeyPackage
265
+ };
266
+ node_fs.writeFileSync(collectedPath, JSON.stringify(root, null, 2));
267
+ const groupRecordMut = registry.group(groupId);
268
+ if (groupRecordMut === void 0) throw new Error("Group not found in registry");
269
+ if (groupVerifyingKey !== void 0) groupRecordMut.setVerifyingKey(groupVerifyingKey);
270
+ groupRecordMut.clearPendingRequests();
271
+ registry.save(registryPath);
272
+ if (require_common.isVerbose()) {
273
+ console.error();
274
+ console.error(`Collected ${collectedEntries.length} finalize responses. Saved to ${collectedPath}`);
275
+ if (groupVerifyingKey !== void 0) console.error(groupVerifyingKey.urString());
276
+ } else if (groupVerifyingKey !== void 0) console.log(groupVerifyingKey.urString());
277
+ verifyingKey = groupVerifyingKey;
278
+ collected = collectedEntries.length;
279
+ errors = errorEntries.length;
280
+ }
281
+ return {
282
+ verifyingKey: verifyingKey?.urString() ?? "",
283
+ collected,
284
+ rejected,
285
+ errors,
286
+ timeouts
287
+ };
288
+ }
289
+ //#endregion
290
+ Object.defineProperty(exports, "finalize", {
291
+ enumerable: true,
292
+ get: function() {
293
+ return finalize;
294
+ }
295
+ });
296
+ Object.defineProperty(exports, "finalize_exports", {
297
+ enumerable: true,
298
+ get: function() {
299
+ return finalize_exports;
300
+ }
301
+ });
302
+
303
+ //# sourceMappingURL=finalize-BfLgzn8f.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-BfLgzn8f.cjs","names":["SealedResponse","parseAridUr","getWithIndicator","isVerbose","parallelFetch","parallelFetchConfigWithTimeout","signingKeyFromVerifying","groupStateDir","path","resolveRegistryPath","Registry"],"sources":["../src/cmd/dkg/coordinator/finalize.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG coordinator finalize command.\n *\n * Port of cmd/dkg/coordinator/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 { type ARID, type PrivateKeys, type SigningPublicKey, type XID } from \"@bcts/components\";\nimport { type Envelope } from \"@bcts/envelope\";\nimport { SealedResponse } from \"@bcts/gstp\";\n\nimport {\n type GroupRecord,\n type PendingRequests,\n Registry,\n resolveRegistryPath,\n} from \"../../../registry/index.js\";\nimport { groupStateDir, isVerbose } from \"../../common.js\";\nimport {\n type CollectionResult,\n parallelFetch,\n type ParallelFetchConfig,\n parallelFetchConfigWithTimeout,\n} from \"../../parallel.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { getWithIndicator } from \"../../busy.js\";\nimport { parseAridUr, signingKeyFromVerifying } from \"../common.js\";\n\n/**\n * Options for the DKG finalize command.\n */\nexport interface DkgFinalizeOptions {\n registryPath?: string;\n groupId: string;\n parallel?: boolean;\n timeoutSeconds?: number;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG finalize command.\n */\nexport interface DkgFinalizeResult {\n verifyingKey: string;\n collected: number;\n rejected: number;\n errors: number;\n timeouts: number;\n}\n\n/**\n * Data extracted from a successful finalize response.\n *\n * Port of `struct FinalizeResponseData` from finalize.rs.\n */\ninterface FinalizeResponseData {\n keyPackage: unknown;\n publicKeyPackage: unknown;\n}\n\n/**\n * Entry for a collected finalize response.\n *\n * Port of `struct FinalizeEntry` from finalize.rs.\n */\ninterface FinalizeEntry {\n participant: XID;\n keyPackage: unknown;\n publicKeyPackage: unknown;\n}\n\n/**\n * Validate that the owner is the coordinator of the group.\n *\n * Port of coordinator check from finalize.rs lines 76-82.\n */\nfunction validateCoordinator(groupRecord: GroupRecord, ownerXid: XID): void {\n if (groupRecord.coordinator().xid().urString() !== ownerXid.urString()) {\n throw new Error(\n `Only the coordinator can collect finalize responses. Coordinator: ${groupRecord.coordinator().xid().urString()}, Owner: ${ownerXid.urString()}`,\n );\n }\n}\n\n/**\n * Validate envelope and extract finalize data (for parallel fetch).\n *\n * Port of `validate_and_extract_finalize_response()` from finalize.rs lines 407-466.\n */\nfunction validateAndExtractFinalizeResponse(\n envelope: Envelope,\n coordinatorKeys: PrivateKeys,\n expectedGroupId: ARID,\n expectedParticipant: XID,\n): FinalizeResponseData | { rejected: string } {\n const now = new Date();\n\n let sealed: SealedResponse;\n try {\n sealed = SealedResponse.tryFromEncryptedEnvelope(envelope, undefined, now, coordinatorKeys);\n } catch (err) {\n return {\n rejected: `Failed to decrypt/parse response: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Check for error response\n if (!sealed.isOk()) {\n try {\n const error = sealed.error();\n const reasonEnv = error.optionalObjectForPredicate(\"reason\");\n const reason = reasonEnv?.extractString() ?? \"unknown reason\";\n return { rejected: `Participant reported error: ${reason}` };\n } catch {\n return { rejected: \"Participant reported error: unknown reason\" };\n }\n }\n\n // Get and validate result\n let result: Envelope;\n try {\n result = sealed.result();\n } catch {\n return { rejected: \"Finalize response has no result\" };\n }\n\n // Validate response type\n try {\n result.checkSubjectUnit();\n result.checkType(\"dkgFinalizeResponse\");\n } catch (err) {\n return {\n rejected: `Invalid response type: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Validate group ID\n try {\n const groupEnv = result.objectForPredicate(\"group\");\n const groupIdStr = groupEnv.extractString();\n const groupId = parseAridUr(groupIdStr);\n if (groupId.urString() !== expectedGroupId.urString()) {\n return {\n rejected: `Group ${groupId.urString()} does not match expected ${expectedGroupId.urString()}`,\n };\n }\n } catch (err) {\n return {\n rejected: `Failed to extract group: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Validate participant\n try {\n const participantEnv = result.objectForPredicate(\"participant\");\n const participantStr = participantEnv.extractString();\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 const participantXid = XIDClass.fromURString(participantStr) as XID;\n if (participantXid.urString() !== expectedParticipant.urString()) {\n return {\n rejected: `Participant ${participantXid.urString()} does not match expected ${expectedParticipant.urString()}`,\n };\n }\n } catch (err) {\n return {\n rejected: `Failed to extract participant: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // Extract key packages\n let keyPackage: unknown;\n let publicKeyPackage: unknown;\n\n try {\n const keyJsonEnv = result.objectForPredicate(\"key_package\");\n const keyJsonStr = keyJsonEnv.extractString();\n keyPackage = JSON.parse(keyJsonStr);\n } catch (err) {\n return {\n rejected: `Failed to parse key_package: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n try {\n const pubJsonEnv = result.objectForPredicate(\"public_key_package\");\n const pubJsonStr = pubJsonEnv.extractString();\n publicKeyPackage = JSON.parse(pubJsonStr);\n } catch (err) {\n return {\n rejected: `Failed to parse public_key_package: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n return { keyPackage, publicKeyPackage };\n}\n\n/**\n * Fetch a finalize response sequentially.\n *\n * Port of `fetch_finalize_response()` from finalize.rs lines 282-358.\n */\nasync function fetchFinalizeResponse(\n client: StorageClient,\n responseArid: ARID,\n timeout: number | undefined,\n coordinatorKeys: PrivateKeys,\n expectedGroup: ARID,\n expectedParticipant: XID,\n participantName: string,\n): Promise<FinalizeEntry> {\n const envelope = await getWithIndicator(\n client,\n responseArid,\n participantName,\n timeout,\n isVerbose(),\n );\n\n if (envelope === null || envelope === undefined) {\n throw new Error(\"Finalize response not found in Hubert storage\");\n }\n\n const result = validateAndExtractFinalizeResponse(\n envelope,\n coordinatorKeys,\n expectedGroup,\n expectedParticipant,\n );\n\n if (\"rejected\" in result) {\n throw new Error(result.rejected);\n }\n\n return {\n participant: expectedParticipant,\n keyPackage: result.keyPackage,\n publicKeyPackage: result.publicKeyPackage,\n };\n}\n\n/**\n * Collect finalize responses in parallel with progress display.\n *\n * Port of `collect_finalize_parallel()` from finalize.rs lines 371-404.\n */\nasync function collectFinalizeParallel(\n client: StorageClient,\n registry: Registry,\n pendingRequests: PendingRequests,\n coordinatorKeys: PrivateKeys,\n expectedGroupId: ARID,\n timeout: number | undefined,\n): Promise<CollectionResult<FinalizeResponseData>> {\n const requests: [XID, ARID, string][] = [];\n\n for (const [xid, arid] of pendingRequests.iterCollect()) {\n const record = registry.participant(xid);\n const name = record?.petName() ?? xid.urString();\n requests.push([xid, arid, name]);\n }\n\n const config: ParallelFetchConfig = parallelFetchConfigWithTimeout(timeout);\n\n return parallelFetch(\n client,\n requests,\n (envelope: Envelope, xid: XID) =>\n validateAndExtractFinalizeResponse(envelope, coordinatorKeys, expectedGroupId, xid),\n config,\n );\n}\n\n/**\n * Finalize collection results: persist, update registry, print summary.\n *\n * Port of `finalize_collection_results()` from finalize.rs lines 469-590.\n */\nfunction finalizeFinalizeCollectionResults(\n collection: CollectionResult<FinalizeResponseData>,\n registryPath: string,\n registry: Registry,\n groupId: ARID,\n): SigningPublicKey | undefined {\n // Report any failures\n if (collection.rejections.length > 0) {\n console.error();\n console.error(\"Rejections:\");\n for (const [xid, reason] of collection.rejections) {\n console.error(` ${xid.urString()}: ${reason}`);\n }\n }\n if (collection.errors.length > 0) {\n console.error();\n console.error(\"Errors:\");\n for (const [xid, error] of collection.errors) {\n console.error(` ${xid.urString()}: ${error}`);\n }\n }\n if (collection.timeouts.length > 0) {\n console.error();\n console.error(\"Timeouts:\");\n for (const xid of collection.timeouts) {\n console.error(` ${xid.urString()}`);\n }\n }\n\n if (!collection.allSucceeded()) {\n throw new Error(\n `Finalize collection incomplete: ${collection.successes.length} succeeded, ` +\n `${collection.rejections.length} rejected, ${collection.errors.length} errors, ` +\n `${collection.timeouts.length} timeouts`,\n );\n }\n\n // Validate group verifying key consistency\n let groupVerifyingKey: SigningPublicKey | undefined;\n\n for (const [xid, data] of collection.successes) {\n // Extract verifying_key from public_key_package\n const pubKeyPkg = data.publicKeyPackage as { verifying_key?: string };\n if (!pubKeyPkg.verifying_key) {\n throw new Error(\n `Failed to extract verifying key for ${xid.urString()}: missing verifying_key field`,\n );\n }\n\n // The verifying key is typically hex-encoded\n let signingKey: SigningPublicKey;\n try {\n const verifyingKeyBytes = hexToBytes(pubKeyPkg.verifying_key);\n signingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n } catch (err) {\n throw new Error(\n `Failed to extract verifying key for ${xid.urString()}: ${err instanceof Error ? err.message : String(err)}`,\n { cause: err },\n );\n }\n\n if (groupVerifyingKey !== undefined) {\n if (groupVerifyingKey.urString() !== signingKey.urString()) {\n throw new Error(`Group verifying key mismatch for participant ${xid.urString()}`);\n }\n } else {\n groupVerifyingKey = signingKey;\n }\n }\n\n // Persist collected finalize data\n const stateDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(stateDir, { recursive: true });\n\n const collectedPath = path.join(stateDir, \"collected_finalize.json\");\n const root: Record<string, { key_package: unknown; public_key_package: unknown }> = {};\n\n for (const [xid, data] of collection.successes) {\n root[xid.urString()] = {\n key_package: data.keyPackage,\n public_key_package: data.publicKeyPackage,\n };\n }\n\n fs.writeFileSync(collectedPath, JSON.stringify(root, null, 2));\n\n // Update registry\n const groupRecord = registry.group(groupId);\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n if (groupVerifyingKey !== undefined) {\n groupRecord.setVerifyingKey(groupVerifyingKey);\n }\n groupRecord.clearPendingRequests();\n registry.save(registryPath);\n\n if (isVerbose()) {\n console.error();\n console.error(\n `Collected ${collection.successes.length} finalize responses. Saved to ${collectedPath}`,\n );\n if (groupVerifyingKey !== undefined) {\n console.error(groupVerifyingKey.urString());\n }\n } else if (groupVerifyingKey !== undefined) {\n console.log(groupVerifyingKey.urString());\n }\n\n return groupVerifyingKey;\n}\n\n/**\n * Helper to convert hex string to bytes.\n */\nfunction hexToBytes(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n\n/**\n * Execute the DKG coordinator finalize command.\n *\n * Collects finalize responses (key/public key packages) from all participants.\n *\n * Port of `finalize()` from cmd/dkg/coordinator/finalize.rs.\n */\nexport async function finalize(\n client: StorageClient,\n options: DkgFinalizeOptions,\n cwd: string,\n): Promise<DkgFinalizeResult> {\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 groupId = parseAridUr(options.groupId);\n const groupRecord = registry.group(groupId);\n\n if (groupRecord === undefined) {\n throw new Error(`Group ${options.groupId} not found in registry`);\n }\n\n // Validate that owner is the coordinator\n validateCoordinator(groupRecord, owner.xid());\n\n const pendingRequests = groupRecord.pendingRequests();\n if (pendingRequests.isEmpty()) {\n throw new Error(\n \"No pending requests for this group. Did you run 'frost dkg coordinator finalize send'?\",\n );\n }\n\n const coordinatorKeys = owner.xidDocument().inceptionPrivateKeys();\n if (coordinatorKeys === undefined) {\n throw new Error(\"Coordinator XID document has no private keys\");\n }\n\n let verifyingKey: SigningPublicKey | undefined;\n let collected: number;\n let rejected = 0;\n let errors: number;\n let timeouts = 0;\n\n if (options.parallel === true) {\n // Parallel path with progress display\n const collection = await collectFinalizeParallel(\n client,\n registry,\n pendingRequests,\n coordinatorKeys,\n groupId,\n options.timeoutSeconds,\n );\n\n verifyingKey = finalizeFinalizeCollectionResults(collection, registryPath, registry, groupId);\n\n collected = collection.successes.length;\n rejected = collection.rejections.length;\n errors = collection.errors.length;\n timeouts = collection.timeouts.length;\n } else {\n // Sequential path (original behavior)\n const collectedEntries: FinalizeEntry[] = [];\n const errorEntries: [XID, string][] = [];\n let groupVerifyingKey: SigningPublicKey | undefined;\n\n if (isVerbose()) {\n console.error(`Collecting finalize responses from ${pendingRequests.len()} participants...`);\n }\n\n for (const [participantXid, collectFromArid] of pendingRequests.iterCollect()) {\n const record = registry.participant(participantXid);\n const name = record?.petName() ?? participantXid.urString();\n\n try {\n const entry = await fetchFinalizeResponse(\n client,\n collectFromArid,\n options.timeoutSeconds,\n coordinatorKeys,\n groupId,\n participantXid,\n name,\n );\n\n // Extract verifying key from public_key_package\n const pubKeyPkg = entry.publicKeyPackage as { verifying_key?: string };\n if (!pubKeyPkg.verifying_key) {\n throw new Error(\"missing verifying_key field\");\n }\n\n const verifyingKeyBytes = hexToBytes(pubKeyPkg.verifying_key);\n const signingKey = signingKeyFromVerifying(verifyingKeyBytes) as SigningPublicKey;\n\n if (groupVerifyingKey !== undefined) {\n if (groupVerifyingKey.urString() !== signingKey.urString()) {\n if (isVerbose()) {\n console.error(\"error: group verifying key mismatch\");\n }\n errorEntries.push([participantXid, \"Group verifying key mismatch across responses\"]);\n continue;\n }\n } else {\n groupVerifyingKey = signingKey;\n }\n\n collectedEntries.push(entry);\n } catch (err) {\n if (isVerbose()) {\n console.error(`error: ${err instanceof Error ? err.message : String(err)}`);\n }\n errorEntries.push([participantXid, err instanceof Error ? err.message : String(err)]);\n }\n }\n\n if (errorEntries.length > 0) {\n if (isVerbose()) {\n console.error();\n console.error(`Failed to collect from ${errorEntries.length} participants:`);\n for (const [xid, error] of errorEntries) {\n console.error(` ${xid.urString()}: ${error}`);\n }\n }\n throw new Error(\n `Finalize collection incomplete: ${errorEntries.length} of ${pendingRequests.len()} responses failed`,\n );\n }\n\n // Persist collected finalize data\n const stateDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(stateDir, { recursive: true });\n\n const collectedPath = path.join(stateDir, \"collected_finalize.json\");\n const root: Record<string, { key_package: unknown; public_key_package: unknown }> = {};\n\n for (const entry of collectedEntries) {\n root[entry.participant.urString()] = {\n key_package: entry.keyPackage,\n public_key_package: entry.publicKeyPackage,\n };\n }\n\n fs.writeFileSync(collectedPath, JSON.stringify(root, null, 2));\n\n // Update registry pending requests cleared\n const groupRecordMut = registry.group(groupId);\n if (groupRecordMut === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n if (groupVerifyingKey !== undefined) {\n groupRecordMut.setVerifyingKey(groupVerifyingKey);\n }\n groupRecordMut.clearPendingRequests();\n registry.save(registryPath);\n\n if (isVerbose()) {\n console.error();\n console.error(\n `Collected ${collectedEntries.length} finalize responses. Saved to ${collectedPath}`,\n );\n if (groupVerifyingKey !== undefined) {\n console.error(groupVerifyingKey.urString());\n }\n } else if (groupVerifyingKey !== undefined) {\n console.log(groupVerifyingKey.urString());\n }\n\n verifyingKey = groupVerifyingKey;\n collected = collectedEntries.length;\n errors = errorEntries.length;\n }\n\n return {\n verifyingKey: verifyingKey?.urString() ?? \"\",\n collected,\n rejected,\n errors,\n timeouts,\n };\n}\n"],"mappings":"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"}