@bcts/frost-hubert 1.0.0-alpha.23 → 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 (154) hide show
  1. package/dist/bin/frost.cjs +345 -71
  2. package/dist/bin/frost.cjs.map +1 -1
  3. package/dist/bin/frost.mjs +345 -71
  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/cmd/index.cjs +28 -22
  10. package/dist/cmd/index.d.cts +2 -2
  11. package/dist/cmd/index.d.mts +2 -2
  12. package/dist/cmd/index.mjs +7 -3
  13. package/dist/cmd-Bw9_i2_f.cjs +130 -0
  14. package/dist/cmd-Bw9_i2_f.cjs.map +1 -0
  15. package/dist/cmd-CS1uJtuD.mjs +113 -0
  16. package/dist/cmd-CS1uJtuD.mjs.map +1 -0
  17. package/dist/common-CvH6dFvQ.mjs +282 -0
  18. package/dist/common-CvH6dFvQ.mjs.map +1 -0
  19. package/dist/common-DUWvtc08.mjs +96 -0
  20. package/dist/common-DUWvtc08.mjs.map +1 -0
  21. package/dist/common-lKP5EzHy.cjs +372 -0
  22. package/dist/common-lKP5EzHy.cjs.map +1 -0
  23. package/dist/common-lThIvJmZ.cjs +114 -0
  24. package/dist/common-lThIvJmZ.cjs.map +1 -0
  25. package/dist/dkg/index.cjs +6 -102
  26. package/dist/dkg/index.cjs.map +1 -1
  27. package/dist/dkg/index.d.cts +2 -2
  28. package/dist/dkg/index.d.mts +2 -2
  29. package/dist/dkg/index.mjs +4 -101
  30. package/dist/dkg/index.mjs.map +1 -1
  31. package/dist/finalize-BRgJK-Xv.cjs +402 -0
  32. package/dist/finalize-BRgJK-Xv.cjs.map +1 -0
  33. package/dist/finalize-BfLgzn8f.cjs +303 -0
  34. package/dist/finalize-BfLgzn8f.cjs.map +1 -0
  35. package/dist/finalize-CNTDj6aS.mjs +389 -0
  36. package/dist/finalize-CNTDj6aS.mjs.map +1 -0
  37. package/dist/finalize-EC3ikHQq.mjs +252 -0
  38. package/dist/finalize-EC3ikHQq.mjs.map +1 -0
  39. package/dist/finalize-IA01t_Qq.mjs +290 -0
  40. package/dist/finalize-IA01t_Qq.mjs.map +1 -0
  41. package/dist/finalize-UPyI1yb1.cjs +265 -0
  42. package/dist/finalize-UPyI1yb1.cjs.map +1 -0
  43. package/dist/{index-BkqLimZT.d.mts → index-B3c-80VS.d.cts} +26 -3
  44. package/dist/index-B3c-80VS.d.cts.map +1 -0
  45. package/dist/{index-BJlwbPYu.d.cts → index-BgbSGpxn.d.mts} +102 -80
  46. package/dist/index-BgbSGpxn.d.mts.map +1 -0
  47. package/dist/{index-BMbPgH0W.d.cts → index-C8QeHNwa.d.cts} +46 -2
  48. package/dist/{index-BMbPgH0W.d.cts.map → index-C8QeHNwa.d.cts.map} +1 -1
  49. package/dist/{index-DmxfT59Y.d.cts → index-D3QTWkEm.d.mts} +26 -3
  50. package/dist/index-D3QTWkEm.d.mts.map +1 -0
  51. package/dist/{index-DoV5HFvV.d.mts → index-DVbWyOs7.d.mts} +46 -2
  52. package/dist/{index-DoV5HFvV.d.mts.map → index-DVbWyOs7.d.mts.map} +1 -1
  53. package/dist/{index-Dzm1v4_4.d.mts → index-F1iNEAJR.d.cts} +102 -80
  54. package/dist/index-F1iNEAJR.d.cts.map +1 -0
  55. package/dist/index.cjs +31 -23
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +4 -4
  58. package/dist/index.d.mts +4 -4
  59. package/dist/index.mjs +9 -4
  60. package/dist/index.mjs.map +1 -1
  61. package/dist/invite-5277FQVT.cjs +274 -0
  62. package/dist/invite-5277FQVT.cjs.map +1 -0
  63. package/dist/invite-DUTcfTgX.cjs +109 -0
  64. package/dist/invite-DUTcfTgX.cjs.map +1 -0
  65. package/dist/invite-IU4n0dq2.mjs +96 -0
  66. package/dist/invite-IU4n0dq2.mjs.map +1 -0
  67. package/dist/invite-RU-OXTNS.mjs +219 -0
  68. package/dist/invite-RU-OXTNS.mjs.map +1 -0
  69. package/dist/parallel-D1R6ZGlY.cjs +318 -0
  70. package/dist/parallel-D1R6ZGlY.cjs.map +1 -0
  71. package/dist/parallel-D6zc6VW4.mjs +235 -0
  72. package/dist/parallel-D6zc6VW4.mjs.map +1 -0
  73. package/dist/proposed-participant-Dm1Eq6mX.cjs +141 -0
  74. package/dist/proposed-participant-Dm1Eq6mX.cjs.map +1 -0
  75. package/dist/proposed-participant-cWM7iUrO.mjs +129 -0
  76. package/dist/proposed-participant-cWM7iUrO.mjs.map +1 -0
  77. package/dist/receive-CAI-x4II.cjs +213 -0
  78. package/dist/receive-CAI-x4II.cjs.map +1 -0
  79. package/dist/receive-D2Nn68L7.mjs +188 -0
  80. package/dist/receive-D2Nn68L7.mjs.map +1 -0
  81. package/dist/receive-DA_KQEgk.mjs +177 -0
  82. package/dist/receive-DA_KQEgk.mjs.map +1 -0
  83. package/dist/receive-kZMsXhbK.cjs +190 -0
  84. package/dist/receive-kZMsXhbK.cjs.map +1 -0
  85. package/dist/registry/index.cjs +85 -10
  86. package/dist/registry/index.cjs.map +1 -1
  87. package/dist/registry/index.d.cts +1 -1
  88. package/dist/registry/index.d.mts +1 -1
  89. package/dist/registry/index.mjs +85 -10
  90. package/dist/registry/index.mjs.map +1 -1
  91. package/dist/{registry-loI1_Mh1.cjs → registry-9puTaRrD.cjs} +1 -1
  92. package/dist/{registry-loI1_Mh1.cjs.map → registry-9puTaRrD.cjs.map} +1 -1
  93. package/dist/{registry-CgrCZ4En.mjs → registry-BpCwtrRt.mjs} +1 -1
  94. package/dist/{registry-CgrCZ4En.mjs.map → registry-BpCwtrRt.mjs.map} +1 -1
  95. package/dist/round1-4Hyx8w0x.cjs +422 -0
  96. package/dist/round1-4Hyx8w0x.cjs.map +1 -0
  97. package/dist/round1-7v9LlE11.mjs +373 -0
  98. package/dist/round1-7v9LlE11.mjs.map +1 -0
  99. package/dist/round1-BHBjru1m.cjs +465 -0
  100. package/dist/round1-BHBjru1m.cjs.map +1 -0
  101. package/dist/round1-CMLKN2RR.mjs +195 -0
  102. package/dist/round1-CMLKN2RR.mjs.map +1 -0
  103. package/dist/round1-CWSXZx5R.cjs +208 -0
  104. package/dist/round1-CWSXZx5R.cjs.map +1 -0
  105. package/dist/round1-CcQCGlIT.mjs +208 -0
  106. package/dist/round1-CcQCGlIT.mjs.map +1 -0
  107. package/dist/round1-Cgm7j1kI.mjs +452 -0
  108. package/dist/round1-Cgm7j1kI.mjs.map +1 -0
  109. package/dist/round1-DQ0fnc1H.cjs +221 -0
  110. package/dist/round1-DQ0fnc1H.cjs.map +1 -0
  111. package/dist/round2-BWz9SQIi.cjs +305 -0
  112. package/dist/round2-BWz9SQIi.cjs.map +1 -0
  113. package/dist/round2-BkNRCXgS.mjs +292 -0
  114. package/dist/round2-BkNRCXgS.mjs.map +1 -0
  115. package/dist/round2-Bl2uK93U.mjs +450 -0
  116. package/dist/round2-Bl2uK93U.mjs.map +1 -0
  117. package/dist/round2-CdUT-AhH.cjs +499 -0
  118. package/dist/round2-CdUT-AhH.cjs.map +1 -0
  119. package/dist/round2-DOA3rnV-.mjs +280 -0
  120. package/dist/round2-DOA3rnV-.mjs.map +1 -0
  121. package/dist/round2-Dg24w-TU.mjs +397 -0
  122. package/dist/round2-Dg24w-TU.mjs.map +1 -0
  123. package/dist/round2-LylCa84n.cjs +293 -0
  124. package/dist/round2-LylCa84n.cjs.map +1 -0
  125. package/dist/round2-o2Q-GMbX.cjs +410 -0
  126. package/dist/round2-o2Q-GMbX.cjs.map +1 -0
  127. package/dist/storage-B-Gu68-O.cjs +79 -0
  128. package/dist/storage-B-Gu68-O.cjs.map +1 -0
  129. package/dist/storage-Bkkliz0K.mjs +74 -0
  130. package/dist/storage-Bkkliz0K.mjs.map +1 -0
  131. package/package.json +10 -10
  132. package/src/bin/frost.ts +849 -128
  133. package/src/cmd/common.ts +19 -1
  134. package/src/cmd/dkg/common.ts +97 -10
  135. package/src/cmd/dkg/coordinator/invite.ts +5 -2
  136. package/src/cmd/dkg/participant/finalize.ts +51 -17
  137. package/src/cmd/dkg/participant/round1.ts +39 -38
  138. package/src/cmd/dkg/participant/round2.ts +60 -26
  139. package/src/cmd/sign/coordinator/round2.ts +5 -1
  140. package/src/cmd/sign/participant/finalize.ts +6 -2
  141. package/src/cmd/sign/participant/receive.ts +5 -2
  142. package/src/dkg/group-invite.ts +12 -2
  143. package/src/dkg/proposed-participant.ts +32 -3
  144. package/src/registry/owner-record.ts +12 -0
  145. package/src/registry/participant-record.ts +35 -2
  146. package/src/registry/registry-impl.ts +74 -18
  147. package/dist/cmd-5yLeC_QL.mjs +0 -4708
  148. package/dist/cmd-5yLeC_QL.mjs.map +0 -1
  149. package/dist/cmd-BfZjC3Uh.cjs +0 -4847
  150. package/dist/cmd-BfZjC3Uh.cjs.map +0 -1
  151. package/dist/index-BJlwbPYu.d.cts.map +0 -1
  152. package/dist/index-BkqLimZT.d.mts.map +0 -1
  153. package/dist/index-DmxfT59Y.d.cts.map +0 -1
  154. package/dist/index-Dzm1v4_4.d.mts.map +0 -1
@@ -1,19 +1,55 @@
1
1
  #!/usr/bin/env node
2
- import { n as participantAdd, r as ownerSet } from "../registry-CgrCZ4En.mjs";
2
+ import { t as createStorageClient } from "../storage-Bkkliz0K.mjs";
3
+ import { n as participantAdd, r as ownerSet } from "../registry-BpCwtrRt.mjs";
3
4
  import { program } from "commander";
4
5
  //#region src/bin/frost.ts
5
6
  /**
6
7
  * Copyright © 2023-2026 Blockchain Commons, LLC
7
8
  * Copyright © 2025-2026 Parity Technologies
8
9
  *
9
- */
10
- /**
10
+ *
11
11
  * FROST CLI binary entry point.
12
12
  *
13
- * Port of main.rs and lib.rs CLI from frost-hubert-rust.
13
+ * Port of `frost-hubert-rust/src/main.rs` and the per-subcommand
14
+ * `clap::Parser` definitions in
15
+ * `frost-hubert-rust/src/cmd/{registry,dkg,sign}/...`.
16
+ *
17
+ * Each subcommand is a thin wrapper that:
18
+ * 1. parses CLI args into the matching `*Options` interface,
19
+ * 2. constructs a `StorageClient` if a backend is requested,
20
+ * 3. delegates to the library function in `src/cmd/...`,
21
+ * 4. prints the same single-line output Rust prints.
14
22
  *
15
23
  * @module
16
24
  */
25
+ const lazyDkgCoord = {
26
+ invite: () => import("../invite-IU4n0dq2.mjs").then((n) => n.n).then((m) => m.invite),
27
+ round1: () => import("../round1-Cgm7j1kI.mjs").then((n) => n.n).then((m) => m.round1),
28
+ round2: () => import("../round2-Bl2uK93U.mjs").then((n) => n.o).then((m) => m.round2),
29
+ finalize: () => import("../finalize-IA01t_Qq.mjs").then((n) => n.n).then((m) => m.finalize)
30
+ };
31
+ const lazyDkgPart = {
32
+ receive: () => import("../receive-D2Nn68L7.mjs").then((n) => n.r).then((m) => m.receive),
33
+ round1: () => import("../round1-CMLKN2RR.mjs").then((n) => n.n).then((m) => m.round1),
34
+ round2: () => import("../round2-DOA3rnV-.mjs").then((n) => n.n).then((m) => m.round2),
35
+ finalize: () => import("../finalize-EC3ikHQq.mjs").then((n) => n.n).then((m) => m.finalize)
36
+ };
37
+ const lazySignCoord = {
38
+ invite: () => import("../invite-RU-OXTNS.mjs").then((n) => n.o).then((m) => m.invite),
39
+ round1: () => import("../round1-7v9LlE11.mjs").then((n) => n.o).then((m) => m.round1),
40
+ round2: () => import("../round2-Dg24w-TU.mjs").then((n) => n.n).then((m) => m.round2)
41
+ };
42
+ const lazySignPart = {
43
+ receive: () => import("../receive-DA_KQEgk.mjs").then((n) => n.n).then((m) => m.receive),
44
+ round1: () => import("../round1-CcQCGlIT.mjs").then((n) => n.n).then((m) => m.round1),
45
+ round2: () => import("../round2-BkNRCXgS.mjs").then((n) => n.n).then((m) => m.round2),
46
+ finalize: () => import("../finalize-CNTDj6aS.mjs").then((n) => n.n).then((m) => m.finalize)
47
+ };
48
+ /**
49
+ * Initialize the global CBOR tag registry. Mirrors the
50
+ * Rust `lib.rs::run` initialization step (`bc_components::register_tags();`
51
+ * `bc_envelope::register_tags();` `provenance_mark::register_tags();`).
52
+ */
17
53
  async function registerTags() {
18
54
  try {
19
55
  const components = await import("@bcts/components");
@@ -24,86 +60,324 @@ async function registerTags() {
24
60
  if (typeof provenanceMark.registerTags === "function") provenanceMark.registerTags();
25
61
  } catch {}
26
62
  }
27
- async function main() {
28
- await registerTags();
29
- program.name("frost").description("FROST threshold signing CLI").version("1.0.0");
30
- const registryCmd = program.command("registry").description("Manage the registry");
31
- registryCmd.command("owner").description("Manage the registry owner").command("set <xid-document> [pet-name]").description("Set the registry owner using an ur:xid document that includes private keys").option("-r, --registry <path>", "Registry path or filename override").action((xidDocument, petName, options) => {
32
- try {
33
- ownerSet({
34
- xidDocument,
35
- petName,
36
- registryPath: options.registry
37
- }, process.cwd());
38
- } catch (error) {
39
- console.error(error.message);
63
+ function isStorageSelection(value) {
64
+ return value === "server" || value === "mainline" || value === "ipfs" || value === "hybrid";
65
+ }
66
+ function parseStorageSelection(opts) {
67
+ const value = opts.storage;
68
+ if (value === void 0) return void 0;
69
+ if (!isStorageSelection(value)) throw new Error(`Unknown --storage value: ${String(value)}`);
70
+ return value;
71
+ }
72
+ async function buildClient(opts) {
73
+ const selection = parseStorageSelection(opts);
74
+ if (selection === void 0) return void 0;
75
+ return createStorageClient(selection, opts.host !== void 0 && opts.port !== void 0 ? `http://${opts.host}:${opts.port}` : opts.host);
76
+ }
77
+ /** Convert a comma-separated, repeated-flag, or positional list. */
78
+ function asStringArray(value) {
79
+ if (Array.isArray(value)) return value;
80
+ if (typeof value === "string") return [value];
81
+ return [];
82
+ }
83
+ function asNumber(value) {
84
+ if (value === void 0 || value === null) return void 0;
85
+ if (typeof value !== "string" && typeof value !== "number") throw new Error(`Expected a number, got: ${typeof value}`);
86
+ const n = Number(value);
87
+ if (Number.isNaN(n)) throw new Error(`Expected a number, got: ${value}`);
88
+ return n;
89
+ }
90
+ function defined(obj) {
91
+ const out = {};
92
+ for (const [key, value] of Object.entries(obj)) if (value !== void 0) out[key] = value;
93
+ return out;
94
+ }
95
+ /**
96
+ * Wrap a CLI action handler so any thrown error prints to stderr and
97
+ * exits with code 1. Mirrors Rust's `anyhow::Result<()>` propagation.
98
+ */
99
+ function runAsync(handler) {
100
+ return (...args) => {
101
+ handler(...args).catch((err) => {
102
+ console.error(err instanceof Error ? err.message : String(err));
40
103
  process.exit(1);
41
- }
42
- });
43
- registryCmd.command("participant").description("Manage registry participants").command("add <xid-document> [pet-name]").description("Add a participant using an ur:xid document").option("-r, --registry <path>", "Registry path or filename override").action((xidDocument, petName, options) => {
104
+ });
105
+ };
106
+ }
107
+ function runSync(handler) {
108
+ return (...args) => {
44
109
  try {
45
- participantAdd({
46
- xidDocument,
47
- petName,
48
- registryPath: options.registry
49
- }, process.cwd());
50
- } catch (error) {
51
- console.error(error.message);
110
+ handler(...args);
111
+ } catch (err) {
112
+ console.error(err instanceof Error ? err.message : String(err));
52
113
  process.exit(1);
53
114
  }
54
- });
115
+ };
116
+ }
117
+ const addStorageOpts = (cmd) => cmd.option("--storage <selection>", "Storage backend (server|mainline|ipfs|hybrid)").option("--host <host>", "Server host (server backend only)").option("--port <port>", "Server port (server backend only)");
118
+ const addRegistryOpt = (cmd) => cmd.option("-r, --registry <path>", "Registry path or filename override");
119
+ const addTimeoutOpt = (cmd) => cmd.option("--timeout <seconds>", "Wait up to this many seconds");
120
+ async function main() {
121
+ await registerTags();
122
+ program.name("frost").description("FROST threshold signing CLI").version("1.0.0");
123
+ const registryCmd = program.command("registry").description("Manage the registry");
124
+ registryCmd.command("owner").description("Manage the registry owner").command("set <xid-document> [pet-name]").description("Set the registry owner using an ur:xid document that includes private keys").option("-r, --registry <path>", "Registry path or filename override").action(runSync((xidDocument, petName, options) => {
125
+ ownerSet({
126
+ xidDocument,
127
+ petName,
128
+ registryPath: options.registry
129
+ }, process.cwd());
130
+ }));
131
+ registryCmd.command("participant").description("Manage registry participants").command("add <xid-document> [pet-name]").description("Add a participant using an ur:xid document").option("-r, --registry <path>", "Registry path or filename override").action(runSync((xidDocument, petName, options) => {
132
+ participantAdd({
133
+ xidDocument,
134
+ petName,
135
+ registryPath: options.registry
136
+ }, process.cwd());
137
+ }));
55
138
  const dkgCmd = program.command("dkg").description("Distributed Key Generation commands");
56
139
  const dkgCoordinatorCmd = dkgCmd.command("coordinator").description("DKG coordinator commands");
57
- dkgCoordinatorCmd.command("invite").description("Send DKG invite to participants").action(() => {
58
- console.log("DKG coordinator invite command not yet implemented");
59
- });
60
- dkgCoordinatorCmd.command("round1").description("Collect round 1 responses").action(() => {
61
- console.log("DKG coordinator round1 command not yet implemented");
62
- });
63
- dkgCoordinatorCmd.command("round2").description("Collect round 2 responses").action(() => {
64
- console.log("DKG coordinator round2 command not yet implemented");
65
- });
140
+ addStorageOpts(addRegistryOpt(dkgCoordinatorCmd.command("invite <participants...>").description("Compose or send a DKG invite").option("--min-signers <n>", "Minimum signers required; defaults to participant count").option("--charter <string>", "Charter statement for the DKG group", "").option("--valid-days <days>", "Days the invite is valid for", "30").option("--preview", "Print the preview invite envelope UR instead of the sealed envelope"))).action(runAsync(async (participants, opts) => {
141
+ if (parseStorageSelection(opts) !== void 0 && opts.preview === true) throw new Error("--preview cannot be used with Hubert storage options");
142
+ const client = await buildClient(opts);
143
+ const result = await (await lazyDkgCoord.invite())(client ?? noOpClient(), {
144
+ charter: opts.charter ?? "",
145
+ validDays: asNumber(opts.validDays) ?? 30,
146
+ participantNames: asStringArray(participants),
147
+ ...defined({
148
+ registryPath: opts.registry,
149
+ minSigners: asNumber(opts.minSigners)
150
+ })
151
+ }, process.cwd());
152
+ console.log(result.envelopeUr);
153
+ }));
154
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgCoordinatorCmd.command("round1 <group-id>").description("Collect round 1 responses").option("--preview", "Preview one of the round 2 requests while sending").option("--parallel", "Use parallel fetch/send")))).action(runAsync(async (groupId, opts) => {
155
+ const client = await buildClient(opts);
156
+ if (client === void 0) throw new Error("dkg coordinator round1 requires --storage");
157
+ const result = await (await lazyDkgCoord.round1())(client, {
158
+ groupId,
159
+ ...defined({
160
+ registryPath: opts.registry,
161
+ timeoutSeconds: asNumber(opts.timeout),
162
+ preview: opts.preview,
163
+ parallel: opts.parallel
164
+ })
165
+ }, process.cwd());
166
+ console.log(JSON.stringify(result));
167
+ }));
168
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgCoordinatorCmd.command("round2 <group-id>").description("Collect round 2 responses").option("--preview", "Preview one of the finalize requests while sending").option("--parallel", "Use parallel fetch/send")))).action(runAsync(async (groupId, opts) => {
169
+ const client = await buildClient(opts);
170
+ if (client === void 0) throw new Error("dkg coordinator round2 requires --storage");
171
+ const result = await (await lazyDkgCoord.round2())(client, {
172
+ groupId,
173
+ ...defined({
174
+ registryPath: opts.registry,
175
+ timeoutSeconds: asNumber(opts.timeout),
176
+ preview: opts.preview,
177
+ parallel: opts.parallel
178
+ })
179
+ }, process.cwd());
180
+ console.log(JSON.stringify(result));
181
+ }));
182
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgCoordinatorCmd.command("finalize <group-id>").description("Collect finalize responses").option("--parallel", "Use parallel fetch")))).action(runAsync(async (groupId, opts) => {
183
+ const client = await buildClient(opts);
184
+ if (client === void 0) throw new Error("dkg coordinator finalize requires --storage");
185
+ const result = await (await lazyDkgCoord.finalize())(client, {
186
+ groupId,
187
+ ...defined({
188
+ registryPath: opts.registry,
189
+ timeoutSeconds: asNumber(opts.timeout),
190
+ parallel: opts.parallel
191
+ })
192
+ }, process.cwd());
193
+ console.log(result.verifyingKey);
194
+ }));
66
195
  const dkgParticipantCmd = dkgCmd.command("participant").description("DKG participant commands");
67
- dkgParticipantCmd.command("receive").description("Receive DKG invite").action(() => {
68
- console.log("DKG participant receive command not yet implemented");
69
- });
70
- dkgParticipantCmd.command("round1").description("Send round 1 response").action(() => {
71
- console.log("DKG participant round1 command not yet implemented");
72
- });
73
- dkgParticipantCmd.command("round2").description("Send round 2 response").action(() => {
74
- console.log("DKG participant round2 command not yet implemented");
75
- });
76
- dkgParticipantCmd.command("finalize").description("Receive finalize package").action(() => {
77
- console.log("DKG participant finalize command not yet implemented");
78
- });
196
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgParticipantCmd.command("receive <invite>").description("Receive a DKG invite (ur:arid or ur:envelope)").option("--no-envelope", "Suppress printing the invite envelope UR").option("--info", "Show invite details").option("--sender <sender>", "Require the invite to come from this sender")))).action(runAsync(async (invite, opts) => {
197
+ const selection = parseStorageSelection(opts);
198
+ const client = await buildClient(opts);
199
+ const result = await (await lazyDkgPart.receive())(client, {
200
+ invite,
201
+ noEnvelope: opts.envelope === false,
202
+ ...defined({
203
+ registryPath: opts.registry,
204
+ timeoutSeconds: asNumber(opts.timeout),
205
+ info: opts.info,
206
+ sender: opts.sender,
207
+ storageSelection: selection
208
+ })
209
+ }, process.cwd());
210
+ if (result.envelopeUr !== void 0) console.log(result.envelopeUr);
211
+ }));
212
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgParticipantCmd.command("round1 <invite>").description("Send round 1 response").option("--response-arid <ur>", "Optional ARID for the next response").option("--preview", "Print the preview response envelope UR instead").option("--reject <reason>", "Reject the invite with the provided reason").option("--sender <sender>", "Require the invite to come from this sender")))).action(runAsync(async (invite, opts) => {
213
+ const selection = parseStorageSelection(opts);
214
+ const client = await buildClient(opts);
215
+ const result = await (await lazyDkgPart.round1())(client, {
216
+ invite,
217
+ ...defined({
218
+ registryPath: opts.registry,
219
+ timeoutSeconds: asNumber(opts.timeout),
220
+ responseArid: opts.responseArid,
221
+ preview: opts.preview,
222
+ rejectReason: opts.reject,
223
+ sender: opts.sender,
224
+ storageSelection: selection
225
+ })
226
+ }, process.cwd());
227
+ if (result.envelopeUr !== void 0) console.log(result.envelopeUr);
228
+ else if (result.listeningArid !== void 0) console.log(result.listeningArid);
229
+ }));
230
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgParticipantCmd.command("round2 <group-id>").description("Send round 2 response").option("--preview", "Also print the preview response envelope")))).action(runAsync(async (groupId, opts) => {
231
+ const selection = parseStorageSelection(opts);
232
+ const client = await buildClient(opts);
233
+ const result = await (await lazyDkgPart.round2())(client, {
234
+ groupId,
235
+ ...defined({
236
+ registryPath: opts.registry,
237
+ timeoutSeconds: asNumber(opts.timeout),
238
+ preview: opts.preview,
239
+ storageSelection: selection
240
+ })
241
+ }, process.cwd());
242
+ if (result.envelopeUr !== void 0) console.log(result.envelopeUr);
243
+ else console.log(result.listeningArid);
244
+ }));
245
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(dkgParticipantCmd.command("finalize <group-id>").description("Receive finalize package").option("--preview", "Also print the preview response envelope")))).action(runAsync(async (groupId, opts) => {
246
+ const selection = parseStorageSelection(opts);
247
+ const client = await buildClient(opts);
248
+ const result = await (await lazyDkgPart.finalize())(client, {
249
+ groupId,
250
+ ...defined({
251
+ registryPath: opts.registry,
252
+ timeoutSeconds: asNumber(opts.timeout),
253
+ preview: opts.preview,
254
+ storageSelection: selection
255
+ })
256
+ }, process.cwd());
257
+ console.log(result.verifyingKey);
258
+ }));
79
259
  const signCmd = program.command("sign").description("Threshold signing commands");
80
260
  const signCoordinatorCmd = signCmd.command("coordinator").description("Sign coordinator commands");
81
- signCoordinatorCmd.command("invite").description("Send sign invite to participants").action(() => {
82
- console.log("Sign coordinator invite command not yet implemented");
83
- });
84
- signCoordinatorCmd.command("round1").description("Collect round 1 responses").action(() => {
85
- console.log("Sign coordinator round1 command not yet implemented");
86
- });
87
- signCoordinatorCmd.command("round2").description("Collect round 2 responses and finalize signature").action(() => {
88
- console.log("Sign coordinator round2 command not yet implemented");
89
- });
261
+ addStorageOpts(addRegistryOpt(signCoordinatorCmd.command("invite <group-id>").description("Send sign invite to participants").requiredOption("--target <path>", "Path to a file containing the target envelope UR").option("--preview", "Print the preview request envelope UR instead of sending"))).action(runAsync(async (groupId, opts) => {
262
+ const client = await buildClient(opts);
263
+ const result = await (await lazySignCoord.invite())(client, {
264
+ groupId,
265
+ targetFile: opts.target,
266
+ ...defined({
267
+ registryPath: opts.registry,
268
+ preview: opts.preview
269
+ })
270
+ }, process.cwd());
271
+ console.log(result.startArid);
272
+ }));
273
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(signCoordinatorCmd.command("round1 <session-id>").description("Collect round 1 (commitment) responses").option("--group <ur:arid>", "Optional group ID hint").option("--preview-share", "Print a sample unsealed signRound2 request").option("--parallel", "Use parallel fetch/send")))).action(runAsync(async (sessionId, opts) => {
274
+ const client = await buildClient(opts);
275
+ if (client === void 0) throw new Error("sign coordinator round1 requires --storage");
276
+ const result = await (await lazySignCoord.round1())(client, {
277
+ sessionId,
278
+ ...defined({
279
+ registryPath: opts.registry,
280
+ groupId: opts.group,
281
+ timeoutSeconds: asNumber(opts.timeout),
282
+ previewShare: opts.previewShare,
283
+ parallel: opts.parallel
284
+ })
285
+ }, process.cwd());
286
+ console.log(JSON.stringify(result));
287
+ }));
288
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(signCoordinatorCmd.command("round2 <session-id>").description("Collect round 2 responses and finalize signature").option("--group <ur:arid>", "Optional group ID hint").option("--preview-finalize", "Print a sample unsealed finalize package").option("--parallel", "Use parallel fetch/send")))).action(runAsync(async (sessionId, opts) => {
289
+ const client = await buildClient(opts);
290
+ if (client === void 0) throw new Error("sign coordinator round2 requires --storage");
291
+ const result = await (await lazySignCoord.round2())(client, {
292
+ sessionId,
293
+ ...defined({
294
+ registryPath: opts.registry,
295
+ groupId: opts.group,
296
+ timeoutSeconds: asNumber(opts.timeout),
297
+ previewFinalize: opts.previewFinalize,
298
+ parallel: opts.parallel
299
+ })
300
+ }, process.cwd());
301
+ console.log(result.signedEnvelope);
302
+ }));
90
303
  const signParticipantCmd = signCmd.command("participant").description("Sign participant commands");
91
- signParticipantCmd.command("receive").description("Receive sign invite").action(() => {
92
- console.log("Sign participant receive command not yet implemented");
93
- });
94
- signParticipantCmd.command("round1").description("Send commitment").action(() => {
95
- console.log("Sign participant round1 command not yet implemented");
96
- });
97
- signParticipantCmd.command("round2").description("Send signature share").action(() => {
98
- console.log("Sign participant round2 command not yet implemented");
99
- });
100
- signParticipantCmd.command("finalize").description("Receive finalize event").action(() => {
101
- console.log("Sign participant finalize command not yet implemented");
102
- });
304
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(signParticipantCmd.command("receive <request>").description("Receive a signInvite request (ur:arid or ur:envelope)").option("--info", "Show request details").option("--sender <sender>", "Require the request to come from this sender")))).action(runAsync(async (request, opts) => {
305
+ const selection = parseStorageSelection(opts);
306
+ const client = await buildClient(opts);
307
+ const result = await (await lazySignPart.receive())(client, selection, {
308
+ request,
309
+ ...defined({
310
+ registryPath: opts.registry,
311
+ timeoutSeconds: asNumber(opts.timeout),
312
+ info: opts.info,
313
+ sender: opts.sender
314
+ })
315
+ }, process.cwd());
316
+ console.log(JSON.stringify(result));
317
+ }));
318
+ addStorageOpts(addRegistryOpt(signParticipantCmd.command("round1 <session-id>").description("Send commitment").option("--preview", "Print the preview response envelope UR instead of sending").option("--reject <reason>", "Reject the signInvite request with the provided reason").option("--group <ur:arid>", "Optional group ID hint"))).action(runAsync(async (sessionId, opts) => {
319
+ const selection = parseStorageSelection(opts);
320
+ const client = await buildClient(opts);
321
+ const result = await (await lazySignPart.round1())(client, {
322
+ sessionId,
323
+ ...defined({
324
+ registryPath: opts.registry,
325
+ groupId: opts.group,
326
+ preview: opts.preview,
327
+ rejectReason: opts.reject,
328
+ storageSelection: selection
329
+ })
330
+ }, process.cwd());
331
+ if (result.envelopeUr !== void 0) console.log(result.envelopeUr);
332
+ else if (result.listeningArid !== void 0) console.log(result.listeningArid);
333
+ }));
334
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(signParticipantCmd.command("round2 <session-id>").description("Send signature share").option("--preview", "Print the unsealed response envelope UR instead of sending").option("--group <ur:arid>", "Optional group ID hint")))).action(runAsync(async (sessionId, opts) => {
335
+ const client = await buildClient(opts);
336
+ if (client === void 0) throw new Error("sign participant round2 requires --storage");
337
+ const result = await (await lazySignPart.round2())(client, {
338
+ sessionId,
339
+ ...defined({
340
+ registryPath: opts.registry,
341
+ groupId: opts.group,
342
+ timeoutSeconds: asNumber(opts.timeout),
343
+ preview: opts.preview
344
+ })
345
+ }, process.cwd());
346
+ console.log(result.listeningArid);
347
+ }));
348
+ addStorageOpts(addTimeoutOpt(addRegistryOpt(signParticipantCmd.command("finalize <session-id>").description("Receive finalize event").option("--group <ur:arid>", "Optional group ID hint")))).action(runAsync(async (sessionId, opts) => {
349
+ const client = await buildClient(opts);
350
+ if (client === void 0) throw new Error("sign participant finalize requires --storage");
351
+ const result = await (await lazySignPart.finalize())(client, {
352
+ sessionId,
353
+ ...defined({
354
+ registryPath: opts.registry,
355
+ groupId: opts.group,
356
+ timeoutSeconds: asNumber(opts.timeout)
357
+ })
358
+ }, process.cwd());
359
+ console.log(result.signature);
360
+ }));
103
361
  program.parse();
104
362
  }
363
+ /**
364
+ * Build a no-op StorageClient for preview-only paths (the
365
+ * coordinator-invite library expects a defined client even when no
366
+ * envelope is sent, because it threads through some helpers).
367
+ *
368
+ * Mirrors Rust's behaviour: `--preview` skips the
369
+ * `StorageClient::from_selection` call entirely, but the underlying
370
+ * library still walks through the same code path with a stub.
371
+ */
372
+ function noOpClient() {
373
+ return {
374
+ put: () => Promise.reject(/* @__PURE__ */ new Error("no-op storage client used in preview mode")),
375
+ get: () => Promise.reject(/* @__PURE__ */ new Error("no-op storage client used in preview mode")),
376
+ exists: () => Promise.resolve(false)
377
+ };
378
+ }
105
379
  main().catch((error) => {
106
- console.error(error.message);
380
+ console.error(error instanceof Error ? error.message : String(error));
107
381
  process.exit(1);
108
382
  });
109
383
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"frost.mjs","names":[],"sources":["../../src/bin/frost.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n/**\n * FROST CLI binary entry point.\n *\n * Port of main.rs and lib.rs CLI from frost-hubert-rust.\n *\n * @module\n */\n\nimport { program } from \"commander\";\n\nimport { ownerSet } from \"../cmd/registry/owner/set.js\";\nimport { participantAdd } from \"../cmd/registry/participant/add.js\";\n\n// Type for modules that may have registerTags\ninterface TagModule {\n registerTags?: () => void;\n}\n\n// Register CBOR tags using dynamic import\nasync function registerTags(): Promise<void> {\n try {\n const components = (await import(\"@bcts/components\")) as TagModule;\n const envelope = (await import(\"@bcts/envelope\")) as TagModule;\n const provenanceMark = (await import(\"@bcts/provenance-mark\")) as TagModule;\n\n if (typeof components.registerTags === \"function\") {\n components.registerTags();\n }\n if (typeof envelope.registerTags === \"function\") {\n envelope.registerTags();\n }\n if (typeof provenanceMark.registerTags === \"function\") {\n provenanceMark.registerTags();\n }\n } catch {\n // Tags may not need registration in this context\n }\n}\n\n// Main CLI function\nasync function main(): Promise<void> {\n // Initialize tags before CLI runs\n await registerTags();\n\n program.name(\"frost\").description(\"FROST threshold signing CLI\").version(\"1.0.0\");\n\n // Registry commands\n const registryCmd = program.command(\"registry\").description(\"Manage the registry\");\n\n // Registry owner commands\n const ownerCmd = registryCmd.command(\"owner\").description(\"Manage the registry owner\");\n\n ownerCmd\n .command(\"set <xid-document> [pet-name]\")\n .description(\"Set the registry owner using an ur:xid document that includes private keys\")\n .option(\"-r, --registry <path>\", \"Registry path or filename override\")\n .action((xidDocument: string, petName: string | undefined, options: { registry?: string }) => {\n try {\n ownerSet(\n {\n xidDocument,\n petName,\n registryPath: options.registry,\n },\n process.cwd(),\n );\n } catch (error) {\n console.error((error as Error).message);\n process.exit(1);\n }\n });\n\n // Registry participant commands\n const participantCmd = registryCmd\n .command(\"participant\")\n .description(\"Manage registry participants\");\n\n participantCmd\n .command(\"add <xid-document> [pet-name]\")\n .description(\"Add a participant using an ur:xid document\")\n .option(\"-r, --registry <path>\", \"Registry path or filename override\")\n .action((xidDocument: string, petName: string | undefined, options: { registry?: string }) => {\n try {\n participantAdd(\n {\n xidDocument,\n petName,\n registryPath: options.registry,\n },\n process.cwd(),\n );\n } catch (error) {\n console.error((error as Error).message);\n process.exit(1);\n }\n });\n\n // DKG commands (placeholder)\n const dkgCmd = program.command(\"dkg\").description(\"Distributed Key Generation commands\");\n\n const dkgCoordinatorCmd = dkgCmd.command(\"coordinator\").description(\"DKG coordinator commands\");\n dkgCoordinatorCmd\n .command(\"invite\")\n .description(\"Send DKG invite to participants\")\n .action(() => {\n console.log(\"DKG coordinator invite command not yet implemented\");\n });\n\n dkgCoordinatorCmd\n .command(\"round1\")\n .description(\"Collect round 1 responses\")\n .action(() => {\n console.log(\"DKG coordinator round1 command not yet implemented\");\n });\n\n dkgCoordinatorCmd\n .command(\"round2\")\n .description(\"Collect round 2 responses\")\n .action(() => {\n console.log(\"DKG coordinator round2 command not yet implemented\");\n });\n\n const dkgParticipantCmd = dkgCmd.command(\"participant\").description(\"DKG participant commands\");\n dkgParticipantCmd\n .command(\"receive\")\n .description(\"Receive DKG invite\")\n .action(() => {\n console.log(\"DKG participant receive command not yet implemented\");\n });\n\n dkgParticipantCmd\n .command(\"round1\")\n .description(\"Send round 1 response\")\n .action(() => {\n console.log(\"DKG participant round1 command not yet implemented\");\n });\n\n dkgParticipantCmd\n .command(\"round2\")\n .description(\"Send round 2 response\")\n .action(() => {\n console.log(\"DKG participant round2 command not yet implemented\");\n });\n\n dkgParticipantCmd\n .command(\"finalize\")\n .description(\"Receive finalize package\")\n .action(() => {\n console.log(\"DKG participant finalize command not yet implemented\");\n });\n\n // Sign commands (placeholder)\n const signCmd = program.command(\"sign\").description(\"Threshold signing commands\");\n\n const signCoordinatorCmd = signCmd\n .command(\"coordinator\")\n .description(\"Sign coordinator commands\");\n signCoordinatorCmd\n .command(\"invite\")\n .description(\"Send sign invite to participants\")\n .action(() => {\n console.log(\"Sign coordinator invite command not yet implemented\");\n });\n\n signCoordinatorCmd\n .command(\"round1\")\n .description(\"Collect round 1 responses\")\n .action(() => {\n console.log(\"Sign coordinator round1 command not yet implemented\");\n });\n\n signCoordinatorCmd\n .command(\"round2\")\n .description(\"Collect round 2 responses and finalize signature\")\n .action(() => {\n console.log(\"Sign coordinator round2 command not yet implemented\");\n });\n\n const signParticipantCmd = signCmd\n .command(\"participant\")\n .description(\"Sign participant commands\");\n signParticipantCmd\n .command(\"receive\")\n .description(\"Receive sign invite\")\n .action(() => {\n console.log(\"Sign participant receive command not yet implemented\");\n });\n\n signParticipantCmd\n .command(\"round1\")\n .description(\"Send commitment\")\n .action(() => {\n console.log(\"Sign participant round1 command not yet implemented\");\n });\n\n signParticipantCmd\n .command(\"round2\")\n .description(\"Send signature share\")\n .action(() => {\n console.log(\"Sign participant round2 command not yet implemented\");\n });\n\n signParticipantCmd\n .command(\"finalize\")\n .description(\"Receive finalize event\")\n .action(() => {\n console.log(\"Sign participant finalize command not yet implemented\");\n });\n\n program.parse();\n}\n\nmain().catch((error: unknown) => {\n console.error((error as Error).message);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"frost.mjs","names":[],"sources":["../../src/bin/frost.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * FROST CLI binary entry point.\n *\n * Port of `frost-hubert-rust/src/main.rs` and the per-subcommand\n * `clap::Parser` definitions in\n * `frost-hubert-rust/src/cmd/{registry,dkg,sign}/...`.\n *\n * Each subcommand is a thin wrapper that:\n * 1. parses CLI args into the matching `*Options` interface,\n * 2. constructs a `StorageClient` if a backend is requested,\n * 3. delegates to the library function in `src/cmd/...`,\n * 4. prints the same single-line output Rust prints.\n *\n * @module\n */\n\nimport { program } from \"commander\";\n\nimport { ownerSet } from \"../cmd/registry/owner/set.js\";\nimport { participantAdd } from \"../cmd/registry/participant/add.js\";\nimport { type StorageClient, type StorageSelection, createStorageClient } from \"../cmd/storage.js\";\n\n// DKG / sign command modules transitively load `@frosts/core`, whose\n// published dist auto-imports `vitest` as a side-effect (a known\n// upstream packaging bug). Importing them at module-load time would\n// crash the registry-only CLI, so we lazy-import them inside the\n// command handlers below. Once `@frosts/core` ships a clean dist this\n// can be flipped back to static imports.\nconst lazyDkgCoord = {\n invite: () => import(\"../cmd/dkg/coordinator/invite.js\").then((m) => m.invite),\n round1: () => import(\"../cmd/dkg/coordinator/round1.js\").then((m) => m.round1),\n round2: () => import(\"../cmd/dkg/coordinator/round2.js\").then((m) => m.round2),\n finalize: () => import(\"../cmd/dkg/coordinator/finalize.js\").then((m) => m.finalize),\n};\nconst lazyDkgPart = {\n receive: () => import(\"../cmd/dkg/participant/receive.js\").then((m) => m.receive),\n round1: () => import(\"../cmd/dkg/participant/round1.js\").then((m) => m.round1),\n round2: () => import(\"../cmd/dkg/participant/round2.js\").then((m) => m.round2),\n finalize: () => import(\"../cmd/dkg/participant/finalize.js\").then((m) => m.finalize),\n};\nconst lazySignCoord = {\n invite: () => import(\"../cmd/sign/coordinator/invite.js\").then((m) => m.invite),\n round1: () => import(\"../cmd/sign/coordinator/round1.js\").then((m) => m.round1),\n round2: () => import(\"../cmd/sign/coordinator/round2.js\").then((m) => m.round2),\n};\nconst lazySignPart = {\n receive: () => import(\"../cmd/sign/participant/receive.js\").then((m) => m.receive),\n round1: () => import(\"../cmd/sign/participant/round1.js\").then((m) => m.round1),\n round2: () => import(\"../cmd/sign/participant/round2.js\").then((m) => m.round2),\n finalize: () => import(\"../cmd/sign/participant/finalize.js\").then((m) => m.finalize),\n};\n\n// Type for modules that may have registerTags\ninterface TagModule {\n registerTags?: () => void;\n}\n\n/**\n * Initialize the global CBOR tag registry. Mirrors the\n * Rust `lib.rs::run` initialization step (`bc_components::register_tags();`\n * `bc_envelope::register_tags();` `provenance_mark::register_tags();`).\n */\nasync function registerTags(): Promise<void> {\n try {\n const components = (await import(\"@bcts/components\")) as TagModule;\n const envelope = (await import(\"@bcts/envelope\")) as TagModule;\n const provenanceMark = (await import(\"@bcts/provenance-mark\")) as TagModule;\n\n if (typeof components.registerTags === \"function\") {\n components.registerTags();\n }\n if (typeof envelope.registerTags === \"function\") {\n envelope.registerTags();\n }\n if (typeof provenanceMark.registerTags === \"function\") {\n provenanceMark.registerTags();\n }\n } catch {\n // Tags may not need registration in this context\n }\n}\n\n/**\n * Storage-related CLI options shared across most subcommands.\n *\n * Mirrors Rust `OptionalStorageSelector` (clap-flatten) — the user can\n * pass exactly one of `--storage server|mainline|ipfs|hybrid` to enable\n * a Hubert backend. When omitted, the subcommand runs in local-only\n * preview/state mode.\n */\ninterface StorageOpts {\n storage?: StorageSelection;\n host?: string;\n port?: string;\n}\n\nfunction isStorageSelection(value: string): value is StorageSelection {\n return value === \"server\" || value === \"mainline\" || value === \"ipfs\" || value === \"hybrid\";\n}\n\nfunction parseStorageSelection(opts: StorageOpts): StorageSelection | undefined {\n const value = opts.storage;\n if (value === undefined) return undefined;\n if (!isStorageSelection(value)) {\n throw new Error(`Unknown --storage value: ${String(value)}`);\n }\n return value;\n}\n\nasync function buildClient(opts: StorageOpts): Promise<StorageClient | undefined> {\n const selection = parseStorageSelection(opts);\n if (selection === undefined) return undefined;\n const serverUrl =\n opts.host !== undefined && opts.port !== undefined\n ? `http://${opts.host}:${opts.port}`\n : opts.host;\n return createStorageClient(selection, serverUrl);\n}\n\n/** Convert a comma-separated, repeated-flag, or positional list. */\nfunction asStringArray(value: unknown): string[] {\n if (Array.isArray(value)) return value as string[];\n if (typeof value === \"string\") return [value];\n return [];\n}\n\nfunction asNumber(value: unknown): number | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new Error(`Expected a number, got: ${typeof value}`);\n }\n const n = Number(value);\n if (Number.isNaN(n)) throw new Error(`Expected a number, got: ${value as string}`);\n return n;\n}\n\n/**\n * Build an object containing only the keys whose values are defined.\n *\n * The frost-hubert library types use `exactOptionalPropertyTypes: true`,\n * which means `{ foo?: string }` rejects `{ foo: undefined }` — only\n * `{ foo: \"x\" }` or `{}` is allowed. Spreading this helper's return\n * value into an options object preserves that contract: at runtime we\n * filter out the `undefined` keys, and we strip `undefined` from the\n * value type so the spread satisfies `exactOptionalPropertyTypes`.\n */\ntype DefinedValues<T> = { [K in keyof T]?: Exclude<T[K], undefined> };\nfunction defined<T extends Record<string, unknown>>(obj: T): DefinedValues<T> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== undefined) out[key] = value;\n }\n return out as DefinedValues<T>;\n}\n\n/**\n * Wrap a CLI action handler so any thrown error prints to stderr and\n * exits with code 1. Mirrors Rust's `anyhow::Result<()>` propagation.\n */\nfunction runAsync<TArgs extends unknown[]>(\n handler: (...args: TArgs) => Promise<void>,\n): (...args: TArgs) => void {\n return (...args: TArgs): void => {\n handler(...args).catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n };\n}\n\nfunction runSync<TArgs extends unknown[]>(\n handler: (...args: TArgs) => void,\n): (...args: TArgs) => void {\n return (...args: TArgs): void => {\n try {\n handler(...args);\n } catch (err) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n };\n}\n\n// Common option attachers — keep the per-subcommand definitions short.\nconst addStorageOpts = (cmd: ReturnType<typeof program.command>): typeof cmd =>\n cmd\n .option(\"--storage <selection>\", \"Storage backend (server|mainline|ipfs|hybrid)\")\n .option(\"--host <host>\", \"Server host (server backend only)\")\n .option(\"--port <port>\", \"Server port (server backend only)\");\n\nconst addRegistryOpt = (cmd: ReturnType<typeof program.command>): typeof cmd =>\n cmd.option(\"-r, --registry <path>\", \"Registry path or filename override\");\n\nconst addTimeoutOpt = (cmd: ReturnType<typeof program.command>): typeof cmd =>\n cmd.option(\"--timeout <seconds>\", \"Wait up to this many seconds\");\n\n// ---------------------------------------------------------------------------\n// CLI definition\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n await registerTags();\n\n program.name(\"frost\").description(\"FROST threshold signing CLI\").version(\"1.0.0\");\n\n // ─── Registry ──────────────────────────────────────────────────────────\n const registryCmd = program.command(\"registry\").description(\"Manage the registry\");\n const ownerCmd = registryCmd.command(\"owner\").description(\"Manage the registry owner\");\n\n ownerCmd\n .command(\"set <xid-document> [pet-name]\")\n .description(\"Set the registry owner using an ur:xid document that includes private keys\")\n .option(\"-r, --registry <path>\", \"Registry path or filename override\")\n .action(\n runSync(\n (xidDocument: string, petName: string | undefined, options: { registry?: string }) => {\n ownerSet({ xidDocument, petName, registryPath: options.registry }, process.cwd());\n },\n ),\n );\n\n const participantCmd = registryCmd\n .command(\"participant\")\n .description(\"Manage registry participants\");\n\n participantCmd\n .command(\"add <xid-document> [pet-name]\")\n .description(\"Add a participant using an ur:xid document\")\n .option(\"-r, --registry <path>\", \"Registry path or filename override\")\n .action(\n runSync(\n (xidDocument: string, petName: string | undefined, options: { registry?: string }) => {\n participantAdd({ xidDocument, petName, registryPath: options.registry }, process.cwd());\n },\n ),\n );\n\n // ─── DKG ──────────────────────────────────────────────────────────────\n const dkgCmd = program.command(\"dkg\").description(\"Distributed Key Generation commands\");\n const dkgCoordinatorCmd = dkgCmd.command(\"coordinator\").description(\"DKG coordinator commands\");\n\n // dkg coordinator invite\n addStorageOpts(\n addRegistryOpt(\n dkgCoordinatorCmd\n .command(\"invite <participants...>\")\n .description(\"Compose or send a DKG invite\")\n .option(\"--min-signers <n>\", \"Minimum signers required; defaults to participant count\")\n .option(\"--charter <string>\", \"Charter statement for the DKG group\", \"\")\n .option(\"--valid-days <days>\", \"Days the invite is valid for\", \"30\")\n .option(\"--preview\", \"Print the preview invite envelope UR instead of the sealed envelope\"),\n ),\n ).action(\n runAsync(\n async (\n participants: string[],\n opts: StorageOpts & {\n registry?: string;\n minSigners?: string;\n charter?: string;\n validDays?: string;\n preview?: boolean;\n },\n ) => {\n const selection = parseStorageSelection(opts);\n if (selection !== undefined && opts.preview === true) {\n throw new Error(\"--preview cannot be used with Hubert storage options\");\n }\n const client = await buildClient(opts);\n const fn = await lazyDkgCoord.invite();\n const result = await fn(\n // dkgCoordInvite requires a defined client; for preview the\n // invite is built but not posted, so we pass a no-op client.\n client ?? noOpClient(),\n {\n charter: opts.charter ?? \"\",\n validDays: asNumber(opts.validDays) ?? 30,\n participantNames: asStringArray(participants),\n ...defined({\n registryPath: opts.registry,\n minSigners: asNumber(opts.minSigners),\n }),\n },\n process.cwd(),\n );\n console.log(result.envelopeUr);\n },\n ),\n );\n\n // dkg coordinator round1\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgCoordinatorCmd\n .command(\"round1 <group-id>\")\n .description(\"Collect round 1 responses\")\n .option(\"--preview\", \"Preview one of the round 2 requests while sending\")\n .option(\"--parallel\", \"Use parallel fetch/send\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n preview?: boolean;\n parallel?: boolean;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"dkg coordinator round1 requires --storage\");\n }\n const fn = await lazyDkgCoord.round1();\n const result = await fn(\n client,\n {\n groupId,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n preview: opts.preview,\n parallel: opts.parallel,\n }),\n },\n process.cwd(),\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n\n // dkg coordinator round2\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgCoordinatorCmd\n .command(\"round2 <group-id>\")\n .description(\"Collect round 2 responses\")\n .option(\"--preview\", \"Preview one of the finalize requests while sending\")\n .option(\"--parallel\", \"Use parallel fetch/send\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n preview?: boolean;\n parallel?: boolean;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"dkg coordinator round2 requires --storage\");\n }\n const fn = await lazyDkgCoord.round2();\n const result = await fn(\n client,\n {\n groupId,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n preview: opts.preview,\n parallel: opts.parallel,\n }),\n },\n process.cwd(),\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n\n // dkg coordinator finalize\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgCoordinatorCmd\n .command(\"finalize <group-id>\")\n .description(\"Collect finalize responses\")\n .option(\"--parallel\", \"Use parallel fetch\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n parallel?: boolean;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"dkg coordinator finalize requires --storage\");\n }\n const fn = await lazyDkgCoord.finalize();\n const result = await fn(\n client,\n {\n groupId,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n parallel: opts.parallel,\n }),\n },\n process.cwd(),\n );\n console.log(result.verifyingKey);\n },\n ),\n );\n\n // ─── DKG participant ───────────────────────────────────────────────────\n const dkgParticipantCmd = dkgCmd.command(\"participant\").description(\"DKG participant commands\");\n\n // dkg participant receive\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgParticipantCmd\n .command(\"receive <invite>\")\n .description(\"Receive a DKG invite (ur:arid or ur:envelope)\")\n .option(\"--no-envelope\", \"Suppress printing the invite envelope UR\")\n .option(\"--info\", \"Show invite details\")\n .option(\"--sender <sender>\", \"Require the invite to come from this sender\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n invite: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n envelope?: boolean;\n info?: boolean;\n sender?: string;\n },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazyDkgPart.receive();\n const result = await fn(\n client,\n {\n invite,\n // commander auto-negates `--no-envelope` into `envelope: false`.\n noEnvelope: opts.envelope === false,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n info: opts.info,\n sender: opts.sender,\n storageSelection: selection,\n }),\n },\n process.cwd(),\n );\n if (result.envelopeUr !== undefined) console.log(result.envelopeUr);\n },\n ),\n );\n\n // dkg participant round1\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgParticipantCmd\n .command(\"round1 <invite>\")\n .description(\"Send round 1 response\")\n .option(\"--response-arid <ur>\", \"Optional ARID for the next response\")\n .option(\"--preview\", \"Print the preview response envelope UR instead\")\n .option(\"--reject <reason>\", \"Reject the invite with the provided reason\")\n .option(\"--sender <sender>\", \"Require the invite to come from this sender\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n invite: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n responseArid?: string;\n preview?: boolean;\n reject?: string;\n sender?: string;\n },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazyDkgPart.round1();\n const result = await fn(\n client,\n {\n invite,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n responseArid: opts.responseArid,\n preview: opts.preview,\n rejectReason: opts.reject,\n sender: opts.sender,\n storageSelection: selection,\n }),\n },\n process.cwd(),\n );\n if (result.envelopeUr !== undefined) console.log(result.envelopeUr);\n else if (result.listeningArid !== undefined) console.log(result.listeningArid);\n },\n ),\n );\n\n // dkg participant round2\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgParticipantCmd\n .command(\"round2 <group-id>\")\n .description(\"Send round 2 response\")\n .option(\"--preview\", \"Also print the preview response envelope\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & { registry?: string; timeout?: string; preview?: boolean },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazyDkgPart.round2();\n const result = await fn(\n client,\n {\n groupId,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n preview: opts.preview,\n storageSelection: selection,\n }),\n },\n process.cwd(),\n );\n if (result.envelopeUr !== undefined) console.log(result.envelopeUr);\n else console.log(result.listeningArid);\n },\n ),\n );\n\n // dkg participant finalize\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n dkgParticipantCmd\n .command(\"finalize <group-id>\")\n .description(\"Receive finalize package\")\n .option(\"--preview\", \"Also print the preview response envelope\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & { registry?: string; timeout?: string; preview?: boolean },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazyDkgPart.finalize();\n const result = await fn(\n client,\n {\n groupId,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n preview: opts.preview,\n storageSelection: selection,\n }),\n },\n process.cwd(),\n );\n console.log(result.verifyingKey);\n },\n ),\n );\n\n // ─── Sign ──────────────────────────────────────────────────────────────\n const signCmd = program.command(\"sign\").description(\"Threshold signing commands\");\n const signCoordinatorCmd = signCmd\n .command(\"coordinator\")\n .description(\"Sign coordinator commands\");\n\n // sign coordinator invite\n addStorageOpts(\n addRegistryOpt(\n signCoordinatorCmd\n .command(\"invite <group-id>\")\n .description(\"Send sign invite to participants\")\n .requiredOption(\"--target <path>\", \"Path to a file containing the target envelope UR\")\n .option(\"--preview\", \"Print the preview request envelope UR instead of sending\"),\n ),\n ).action(\n runAsync(\n async (\n groupId: string,\n opts: StorageOpts & { registry?: string; target: string; preview?: boolean },\n ) => {\n const client = await buildClient(opts);\n const fn = await lazySignCoord.invite();\n const result = await fn(\n client,\n {\n groupId,\n targetFile: opts.target,\n ...defined({\n registryPath: opts.registry,\n preview: opts.preview,\n }),\n },\n process.cwd(),\n );\n console.log(result.startArid);\n },\n ),\n );\n\n // sign coordinator round1\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n signCoordinatorCmd\n .command(\"round1 <session-id>\")\n .description(\"Collect round 1 (commitment) responses\")\n .option(\"--group <ur:arid>\", \"Optional group ID hint\")\n .option(\"--preview-share\", \"Print a sample unsealed signRound2 request\")\n .option(\"--parallel\", \"Use parallel fetch/send\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n sessionId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n group?: string;\n previewShare?: boolean;\n parallel?: boolean;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"sign coordinator round1 requires --storage\");\n }\n const fn = await lazySignCoord.round1();\n const result = await fn(\n client,\n {\n sessionId,\n ...defined({\n registryPath: opts.registry,\n groupId: opts.group,\n timeoutSeconds: asNumber(opts.timeout),\n previewShare: opts.previewShare,\n parallel: opts.parallel,\n }),\n },\n process.cwd(),\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n\n // sign coordinator round2\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n signCoordinatorCmd\n .command(\"round2 <session-id>\")\n .description(\"Collect round 2 responses and finalize signature\")\n .option(\"--group <ur:arid>\", \"Optional group ID hint\")\n .option(\"--preview-finalize\", \"Print a sample unsealed finalize package\")\n .option(\"--parallel\", \"Use parallel fetch/send\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n sessionId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n group?: string;\n previewFinalize?: boolean;\n parallel?: boolean;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"sign coordinator round2 requires --storage\");\n }\n const fn = await lazySignCoord.round2();\n const result = await fn(\n client,\n {\n sessionId,\n ...defined({\n registryPath: opts.registry,\n groupId: opts.group,\n timeoutSeconds: asNumber(opts.timeout),\n previewFinalize: opts.previewFinalize,\n parallel: opts.parallel,\n }),\n },\n process.cwd(),\n );\n console.log(result.signedEnvelope);\n },\n ),\n );\n\n // ─── Sign participant ──────────────────────────────────────────────────\n const signParticipantCmd = signCmd\n .command(\"participant\")\n .description(\"Sign participant commands\");\n\n // sign participant receive\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n signParticipantCmd\n .command(\"receive <request>\")\n .description(\"Receive a signInvite request (ur:arid or ur:envelope)\")\n .option(\"--info\", \"Show request details\")\n .option(\"--sender <sender>\", \"Require the request to come from this sender\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n request: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n info?: boolean;\n sender?: string;\n },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazySignPart.receive();\n const result = await fn(\n client,\n selection,\n {\n request,\n ...defined({\n registryPath: opts.registry,\n timeoutSeconds: asNumber(opts.timeout),\n info: opts.info,\n sender: opts.sender,\n }),\n },\n process.cwd(),\n );\n console.log(JSON.stringify(result));\n },\n ),\n );\n\n // sign participant round1\n addStorageOpts(\n addRegistryOpt(\n signParticipantCmd\n .command(\"round1 <session-id>\")\n .description(\"Send commitment\")\n .option(\"--preview\", \"Print the preview response envelope UR instead of sending\")\n .option(\"--reject <reason>\", \"Reject the signInvite request with the provided reason\")\n .option(\"--group <ur:arid>\", \"Optional group ID hint\"),\n ),\n ).action(\n runAsync(\n async (\n sessionId: string,\n opts: StorageOpts & {\n registry?: string;\n preview?: boolean;\n reject?: string;\n group?: string;\n },\n ) => {\n const selection = parseStorageSelection(opts);\n const client = await buildClient(opts);\n const fn = await lazySignPart.round1();\n const result = await fn(\n client,\n {\n sessionId,\n ...defined({\n registryPath: opts.registry,\n groupId: opts.group,\n preview: opts.preview,\n rejectReason: opts.reject,\n storageSelection: selection,\n }),\n },\n process.cwd(),\n );\n if (result.envelopeUr !== undefined) console.log(result.envelopeUr);\n else if (result.listeningArid !== undefined) console.log(result.listeningArid);\n },\n ),\n );\n\n // sign participant round2\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n signParticipantCmd\n .command(\"round2 <session-id>\")\n .description(\"Send signature share\")\n .option(\"--preview\", \"Print the unsealed response envelope UR instead of sending\")\n .option(\"--group <ur:arid>\", \"Optional group ID hint\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n sessionId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n preview?: boolean;\n group?: string;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"sign participant round2 requires --storage\");\n }\n const fn = await lazySignPart.round2();\n const result = await fn(\n client,\n {\n sessionId,\n ...defined({\n registryPath: opts.registry,\n groupId: opts.group,\n timeoutSeconds: asNumber(opts.timeout),\n preview: opts.preview,\n }),\n },\n process.cwd(),\n );\n console.log(result.listeningArid);\n },\n ),\n );\n\n // sign participant finalize\n addStorageOpts(\n addTimeoutOpt(\n addRegistryOpt(\n signParticipantCmd\n .command(\"finalize <session-id>\")\n .description(\"Receive finalize event\")\n .option(\"--group <ur:arid>\", \"Optional group ID hint\"),\n ),\n ),\n ).action(\n runAsync(\n async (\n sessionId: string,\n opts: StorageOpts & {\n registry?: string;\n timeout?: string;\n group?: string;\n },\n ) => {\n const client = await buildClient(opts);\n if (client === undefined) {\n throw new Error(\"sign participant finalize requires --storage\");\n }\n const fn = await lazySignPart.finalize();\n const result = await fn(\n client,\n {\n sessionId,\n ...defined({\n registryPath: opts.registry,\n groupId: opts.group,\n timeoutSeconds: asNumber(opts.timeout),\n }),\n },\n process.cwd(),\n );\n console.log(result.signature);\n },\n ),\n );\n\n program.parse();\n}\n\n/**\n * Build a no-op StorageClient for preview-only paths (the\n * coordinator-invite library expects a defined client even when no\n * envelope is sent, because it threads through some helpers).\n *\n * Mirrors Rust's behaviour: `--preview` skips the\n * `StorageClient::from_selection` call entirely, but the underlying\n * library still walks through the same code path with a stub.\n */\nfunction noOpClient(): StorageClient {\n return {\n put: () => Promise.reject(new Error(\"no-op storage client used in preview mode\")),\n get: () => Promise.reject(new Error(\"no-op storage client used in preview mode\")),\n exists: () => Promise.resolve(false),\n };\n}\n\nmain().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ //#region src/cmd/busy.ts
2
+ /**
3
+ * Put an envelope to storage with a progress indicator.
4
+ *
5
+ * Port of `put_with_indicator()` from cmd/busy.rs.
6
+ */
7
+ async function putWithIndicator(client, arid, envelope, message, verbose) {
8
+ if (verbose) console.log(`${message}...`);
9
+ await client.put(arid, envelope);
10
+ if (verbose) console.log(`${message}... done`);
11
+ }
12
+ /**
13
+ * Get an envelope from storage with a progress indicator.
14
+ *
15
+ * Port of `get_with_indicator()` from cmd/busy.rs.
16
+ */
17
+ async function getWithIndicator(client, arid, message, timeoutSeconds, verbose) {
18
+ if (verbose) console.log(`${message}...`);
19
+ const envelope = await client.get(arid, timeoutSeconds);
20
+ if (verbose) if (envelope) console.log(`${message}... found`);
21
+ else console.log(`${message}... not found`);
22
+ return envelope;
23
+ }
24
+ //#endregion
25
+ export { putWithIndicator as n, getWithIndicator as t };
26
+
27
+ //# sourceMappingURL=busy-DkM2jAIZ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"busy-DkM2jAIZ.mjs","names":[],"sources":["../src/cmd/busy.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Progress indicator utilities.\n *\n * Port of cmd/busy.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport { type ARID } from \"@bcts/components\";\nimport { type Envelope } from \"@bcts/envelope\";\n\nimport { type StorageClient } from \"./storage.js\";\n\n/**\n * Put an envelope to storage with a progress indicator.\n *\n * Port of `put_with_indicator()` from cmd/busy.rs.\n */\nexport async function putWithIndicator(\n client: StorageClient,\n arid: ARID,\n envelope: Envelope,\n message: string,\n verbose: boolean,\n): Promise<void> {\n if (verbose) {\n console.log(`${message}...`);\n }\n\n await client.put(arid, envelope);\n\n if (verbose) {\n console.log(`${message}... done`);\n }\n}\n\n/**\n * Get an envelope from storage with a progress indicator.\n *\n * Port of `get_with_indicator()` from cmd/busy.rs.\n */\nexport async function getWithIndicator(\n client: StorageClient,\n arid: ARID,\n message: string,\n timeoutSeconds: number | undefined,\n verbose: boolean,\n): Promise<Envelope | undefined> {\n if (verbose) {\n console.log(`${message}...`);\n }\n\n const envelope = await client.get(arid, timeoutSeconds);\n\n if (verbose) {\n if (envelope) {\n console.log(`${message}... found`);\n } else {\n console.log(`${message}... not found`);\n }\n }\n\n return envelope;\n}\n"],"mappings":";;;;;;AAsBA,eAAsB,iBACpB,QACA,MACA,UACA,SACA,SACe;AACf,KAAI,QACF,SAAQ,IAAI,GAAG,QAAQ,KAAK;AAG9B,OAAM,OAAO,IAAI,MAAM,SAAS;AAEhC,KAAI,QACF,SAAQ,IAAI,GAAG,QAAQ,UAAU;;;;;;;AASrC,eAAsB,iBACpB,QACA,MACA,SACA,gBACA,SAC+B;AAC/B,KAAI,QACF,SAAQ,IAAI,GAAG,QAAQ,KAAK;CAG9B,MAAM,WAAW,MAAM,OAAO,IAAI,MAAM,eAAe;AAEvD,KAAI,QACF,KAAI,SACF,SAAQ,IAAI,GAAG,QAAQ,WAAW;KAElC,SAAQ,IAAI,GAAG,QAAQ,eAAe;AAI1C,QAAO"}