@bcts/seedtool-cli 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.
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region \0rolldown/runtime.js
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -7,16 +7,12 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
9
  var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
- key = keys[i];
13
- if (!__hasOwnProp.call(to, key) && key !== except) {
14
- __defProp(to, key, {
15
- get: ((k) => from[k]).bind(null, key),
16
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
- });
18
- }
19
- }
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
20
16
  }
21
17
  return to;
22
18
  };
@@ -24,10 +20,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
20
  value: mod,
25
21
  enumerable: true
26
22
  }) : target, mod));
27
-
28
23
  //#endregion
29
24
  let node_readline = require("node:readline");
30
- node_readline = __toESM(node_readline);
25
+ node_readline = __toESM(node_readline, 1);
26
+ let node_fs = require("node:fs");
27
+ node_fs = __toESM(node_fs, 1);
31
28
  let _bcts_components = require("@bcts/components");
32
29
  let _bcts_envelope = require("@bcts/envelope");
33
30
  let _bcts_known_values = require("@bcts/known-values");
@@ -38,7 +35,6 @@ let _scure_bip39 = require("@scure/bip39");
38
35
  let _scure_bip39_wordlists_english_js = require("@scure/bip39/wordlists/english.js");
39
36
  let _bcts_uniform_resources = require("@bcts/uniform-resources");
40
37
  let _bcts_tags = require("@bcts/tags");
41
-
42
38
  //#region src/cli.ts
43
39
  /**
44
40
  * Copyright © 2023-2026 Blockchain Commons, LLC
@@ -164,9 +160,9 @@ var Cli = class Cli {
164
160
  /** The number of output units (hex bytes, base-10 digits, etc.) */
165
161
  count = 16;
166
162
  /** The input format. Default: Random */
167
- in = InputFormatKey.Random;
163
+ in = "random";
168
164
  /** The output format. Default: Hex */
169
- out = OutputFormatKey.Hex;
165
+ out = "hex";
170
166
  /** The lowest int returned (0-254). Default: 0 */
171
167
  low = 0;
172
168
  /** The highest int returned (1-255), low < high. Default: 9 */
@@ -186,7 +182,7 @@ var Cli = class Cli {
186
182
  /** The number of groups that must meet their threshold. Default: 1 */
187
183
  groupThreshold = 1;
188
184
  /** SSKR output format. Default: Envelope */
189
- sskrFormat = SSKRFormatKey.Envelope;
185
+ sskrFormat = "envelope";
190
186
  /** Deterministic RNG seed string. */
191
187
  deterministic;
192
188
  /** The seed being processed (internal state). */
@@ -194,12 +190,21 @@ var Cli = class Cli {
194
190
  /** The RNG source (internal state). */
195
191
  rng;
196
192
  /**
197
- * Get input from argument or read from stdin.
198
- * Matches Rust expect_input method.
193
+ * Get input from argument or lazily read it from stdin.
194
+ *
195
+ * Mirrors Rust's `Cli::expect_input` (seedtool-cli-rust/src/cli.rs:191-200):
196
+ * stdin is touched only when an input-consuming code path actually needs it.
197
+ * Modes like `--in random` or `-d <SEED>` (deterministic) never call this,
198
+ * so they exit cleanly even when stdin is a non-TTY but no input is piped.
199
+ *
200
+ * Reads the stdin file descriptor synchronously via `fs.readFileSync(0, ...)`
201
+ * and caches the trimmed result on `this.input` so subsequent calls don't
202
+ * re-read.
199
203
  */
200
204
  expectInput() {
201
205
  if (this.input !== void 0) return this.input;
202
- throw new Error("Input required but not provided. Use stdin or pass as argument.");
206
+ this.input = node_fs.readFileSync(0, "utf-8").trim();
207
+ return this.input;
203
208
  }
204
209
  /**
205
210
  * Get input from argument or read from stdin asynchronously.
@@ -292,7 +297,6 @@ var Cli = class Cli {
292
297
  return cli;
293
298
  }
294
299
  };
295
-
296
300
  //#endregion
297
301
  //#region src/seed.ts
298
302
  /**
@@ -500,7 +504,6 @@ var Seed = class Seed {
500
504
  return true;
501
505
  }
502
506
  };
503
-
504
507
  //#endregion
505
508
  //#region src/random.ts
506
509
  /**
@@ -608,7 +611,6 @@ function sha256DeterministicRandomString(str, n) {
608
611
  function deterministicRandom(entropy, n) {
609
612
  return hkdfHmacSha256((0, _noble_hashes_sha2_js.sha256)(entropy), new Uint8Array(0), n);
610
613
  }
611
-
612
614
  //#endregion
613
615
  //#region src/util.ts
614
616
  /**
@@ -628,18 +630,34 @@ function dataToHex(bytes) {
628
630
  }
629
631
  /**
630
632
  * Convert hex string to bytes.
631
- * Matches Rust hex_to_data function.
633
+ *
634
+ * Mirrors the error wording produced by Rust's `hex` crate
635
+ * (`FromHexError::OddLength` and `FromHexError::InvalidHexCharacter`),
636
+ * which seedtool-cli-rust surfaces unchanged through anyhow:
637
+ *
638
+ * "Odd number of digits"
639
+ * "Invalid character '{c}' at position {n}"
640
+ *
641
+ * The outer CLI layer adds the `Error: ` prefix to match Rust's anyhow
642
+ * output.
632
643
  */
633
644
  function hexToData(hex) {
634
- if (hex.length % 2 !== 0) throw new Error("Hex string must have even length");
645
+ if (hex.length % 2 !== 0) throw new Error("Odd number of digits");
635
646
  const bytes = new Uint8Array(hex.length / 2);
636
647
  for (let i = 0; i < hex.length; i += 2) {
637
- const byte = parseInt(hex.substring(i, i + 2), 16);
638
- if (isNaN(byte)) throw new Error(`Invalid hex character at position ${i}`);
639
- bytes[i / 2] = byte;
648
+ const hi = hexCharToNibble(hex, i);
649
+ const lo = hexCharToNibble(hex, i + 1);
650
+ bytes[i / 2] = hi << 4 | lo;
640
651
  }
641
652
  return bytes;
642
653
  }
654
+ function hexCharToNibble(hex, index) {
655
+ const c = hex.charCodeAt(index);
656
+ if (c >= 48 && c <= 57) return c - 48;
657
+ if (c >= 97 && c <= 102) return c - 97 + 10;
658
+ if (c >= 65 && c <= 70) return c - 65 + 10;
659
+ throw new Error(`Invalid character '${hex[index]}' at position ${index}`);
660
+ }
643
661
  /**
644
662
  * Convert byte values to a different base range [0, base-1].
645
663
  * Each byte (0-255) is scaled proportionally to the target base.
@@ -717,12 +735,11 @@ function digitsToData(inStr, low, high) {
717
735
  const result = [];
718
736
  for (const c of inStr) {
719
737
  const n = c.charCodeAt(0) - "0".charCodeAt(0);
720
- if (n < low || n > high) throw new Error(`Invalid digit: ${c}. Expected range [${low}-${high}].`);
738
+ if (n < low || n > high) throw new Error("Invalid digit.");
721
739
  result.push(n);
722
740
  }
723
741
  return new Uint8Array(result);
724
742
  }
725
-
726
743
  //#endregion
727
744
  //#region src/formats/hex.ts
728
745
  /**
@@ -745,7 +762,6 @@ var HexFormat = class {
745
762
  return dataToHex(state.expectSeed().data());
746
763
  }
747
764
  };
748
-
749
765
  //#endregion
750
766
  //#region src/formats/bip39.ts
751
767
  /**
@@ -770,18 +786,9 @@ var Bip39Format = class {
770
786
  return (0, _scure_bip39.entropyToMnemonic)(state.expectSeed().data(), _scure_bip39_wordlists_english_js.wordlist);
771
787
  }
772
788
  };
773
-
774
789
  //#endregion
775
790
  //#region src/formats/sskr.ts
776
791
  /**
777
- * Copyright © 2023-2026 Blockchain Commons, LLC
778
- * Copyright © 2025-2026 Parity Technologies
779
- *
780
- *
781
- * SSKR format
782
- * Ported from seedtool-cli-rust/src/formats/sskr.rs
783
- */
784
- /**
785
792
  * SSKR format handler.
786
793
  * Round-trippable: sskr shares → seed → sskr shares.
787
794
  * Supports multiple sub-formats: envelope, btw, btwm, btwu, ur.
@@ -806,15 +813,15 @@ var SSKRFormat = class {
806
813
  };
807
814
  function outputSskrSeed(seed, spec, format) {
808
815
  switch (format) {
809
- case SSKRFormatKey.Envelope: {
816
+ case "envelope": {
810
817
  const seedEnvelope = seed.toEnvelope();
811
818
  const contentKey = _bcts_envelope.SymmetricKey.new();
812
819
  return seedEnvelope.wrap().encryptSubject(contentKey).sskrSplitFlattened(spec, contentKey).map((env) => env.urString()).join("\n");
813
820
  }
814
- case SSKRFormatKey.Btw: return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Standard);
815
- case SSKRFormatKey.Btwm: return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Minimal);
816
- case SSKRFormatKey.Btwu: return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Uri);
817
- case SSKRFormatKey.Ur: return makeShares(spec, seed).map((share) => {
821
+ case "btw": return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Standard);
822
+ case "btwm": return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Minimal);
823
+ case "btwu": return makeBytewordsShares(spec, seed, _bcts_uniform_resources.BytewordsStyle.Uri);
824
+ case "ur": return makeShares(spec, seed).map((share) => {
818
825
  return _bcts_uniform_resources.UR.new("sskr", (0, _bcts_dcbor.toByteString)(share.asBytes())).toString();
819
826
  }).join("\n");
820
827
  }
@@ -924,7 +931,6 @@ function parseSskrSeed(input) {
924
931
  if (urLegacyResult !== null) return urLegacyResult;
925
932
  throw new Error("Insufficient or invalid SSKR shares.");
926
933
  }
927
-
928
934
  //#endregion
929
935
  //#region src/formats/envelope.ts
930
936
  /**
@@ -948,7 +954,6 @@ var EnvelopeFormat = class {
948
954
  return state.toEnvelope().urString();
949
955
  }
950
956
  };
951
-
952
957
  //#endregion
953
958
  //#region src/formats/seed-format.ts
954
959
  /**
@@ -973,7 +978,6 @@ var SeedFormat = class {
973
978
  return state.seedWithOverrides().toComponentsSeed().urString();
974
979
  }
975
980
  };
976
-
977
981
  //#endregion
978
982
  //#region src/formats/multipart.ts
979
983
  /**
@@ -995,7 +999,7 @@ var MultipartFormat = class {
995
999
  decoder.receive(share);
996
1000
  if (decoder.isComplete()) break;
997
1001
  }
998
- if (!decoder.isComplete()) throw new Error("Insufficient multipart shares");
1002
+ if (!decoder.isComplete()) throw new Error("Insufficient SSKR shares");
999
1003
  const ur = decoder.message();
1000
1004
  if (ur === void 0 || ur === null) throw new Error("Failed to decode multipart message");
1001
1005
  const envelope = _bcts_envelope.Envelope.fromUR(ur);
@@ -1010,7 +1014,6 @@ var MultipartFormat = class {
1010
1014
  return parts.join("\n");
1011
1015
  }
1012
1016
  };
1013
-
1014
1017
  //#endregion
1015
1018
  //#region src/formats/random.ts
1016
1019
  /**
@@ -1030,7 +1033,6 @@ var RandomFormat = class {
1030
1033
  return state;
1031
1034
  }
1032
1035
  };
1033
-
1034
1036
  //#endregion
1035
1037
  //#region src/formats/base6.ts
1036
1038
  /**
@@ -1056,7 +1058,6 @@ var Base6Format = class {
1056
1058
  return dataToInts(state.expectSeed().data(), 0, 5, "");
1057
1059
  }
1058
1060
  };
1059
-
1060
1061
  //#endregion
1061
1062
  //#region src/formats/base10.ts
1062
1063
  /**
@@ -1082,7 +1083,6 @@ var Base10Format = class {
1082
1083
  return dataToInts(state.expectSeed().data(), 0, 9, "");
1083
1084
  }
1084
1085
  };
1085
-
1086
1086
  //#endregion
1087
1087
  //#region src/formats/bits.ts
1088
1088
  /**
@@ -1108,7 +1108,6 @@ var BitsFormat = class {
1108
1108
  return dataToInts(state.expectSeed().data(), 0, 1, "");
1109
1109
  }
1110
1110
  };
1111
-
1112
1111
  //#endregion
1113
1112
  //#region src/formats/dice.ts
1114
1113
  /**
@@ -1134,7 +1133,6 @@ var DiceFormat = class {
1134
1133
  return dataToInts(state.expectSeed().data(), 1, 6, "");
1135
1134
  }
1136
1135
  };
1137
-
1138
1136
  //#endregion
1139
1137
  //#region src/formats/cards.ts
1140
1138
  const CARD_SUITS = "cdhs";
@@ -1146,7 +1144,7 @@ const CARD_RANKS = "a23456789tjqk";
1146
1144
  function parseRank(c) {
1147
1145
  const lower = c.toLowerCase();
1148
1146
  const index = CARD_RANKS.indexOf(lower);
1149
- if (index === -1) throw new Error(`Invalid card rank: ${c}. Allowed: [A,2-9,T,J,Q,K]`);
1147
+ if (index === -1) throw new Error("Invalid card rank. Allowed: [A,2-9,T,J,Q,K]");
1150
1148
  return index;
1151
1149
  }
1152
1150
  /**
@@ -1156,7 +1154,7 @@ function parseRank(c) {
1156
1154
  function parseSuit(c) {
1157
1155
  const lower = c.toLowerCase();
1158
1156
  const index = CARD_SUITS.indexOf(lower);
1159
- if (index === -1) throw new Error(`Invalid card suit: ${c}. Allowed: [C,D,H,S]`);
1157
+ if (index === -1) throw new Error("Invalid card rank. Allowed: [D,C,H,S]");
1160
1158
  return index;
1161
1159
  }
1162
1160
  /**
@@ -1204,7 +1202,6 @@ var CardsFormat = class {
1204
1202
  return dataToAlphabet(state.expectSeed().data(), 52, toCard);
1205
1203
  }
1206
1204
  };
1207
-
1208
1205
  //#endregion
1209
1206
  //#region src/formats/ints.ts
1210
1207
  /**
@@ -1228,7 +1225,6 @@ var IntsFormat = class {
1228
1225
  return dataToInts(state.expectSeed().data(), state.low, state.high, " ");
1229
1226
  }
1230
1227
  };
1231
-
1232
1228
  //#endregion
1233
1229
  //#region src/formats/bytewords-standard.ts
1234
1230
  /**
@@ -1252,7 +1248,6 @@ var BytewordsStandardFormat = class {
1252
1248
  return (0, _bcts_uniform_resources.encodeBytewords)(state.expectSeed().data(), _bcts_uniform_resources.BytewordsStyle.Standard);
1253
1249
  }
1254
1250
  };
1255
-
1256
1251
  //#endregion
1257
1252
  //#region src/formats/bytewords-minimal.ts
1258
1253
  /**
@@ -1276,7 +1271,6 @@ var BytewordsMinimalFormat = class {
1276
1271
  return (0, _bcts_uniform_resources.encodeBytewords)(state.expectSeed().data(), _bcts_uniform_resources.BytewordsStyle.Minimal);
1277
1272
  }
1278
1273
  };
1279
-
1280
1274
  //#endregion
1281
1275
  //#region src/formats/bytewords-uri.ts
1282
1276
  /**
@@ -1300,39 +1294,30 @@ var BytewordsUriFormat = class {
1300
1294
  return (0, _bcts_uniform_resources.encodeBytewords)(state.expectSeed().data(), _bcts_uniform_resources.BytewordsStyle.Uri);
1301
1295
  }
1302
1296
  };
1303
-
1304
1297
  //#endregion
1305
1298
  //#region src/formats/format.ts
1306
1299
  /**
1307
- * Copyright © 2023-2026 Blockchain Commons, LLC
1308
- * Copyright © 2025-2026 Parity Technologies
1309
- *
1310
- *
1311
- * Format traits and factory functions
1312
- * Ported from seedtool-cli-rust/src/formats/format.rs
1313
- */
1314
- /**
1315
1300
  * Select input format by key.
1316
1301
  * Matches Rust select_input_format function.
1317
1302
  */
1318
1303
  function selectInputFormat(key) {
1319
1304
  switch (key) {
1320
- case InputFormatKey.Random: return new RandomFormat();
1321
- case InputFormatKey.Hex: return new HexFormat();
1322
- case InputFormatKey.Btw: return new BytewordsStandardFormat();
1323
- case InputFormatKey.Btwu: return new BytewordsUriFormat();
1324
- case InputFormatKey.Btwm: return new BytewordsMinimalFormat();
1325
- case InputFormatKey.Bits: return new BitsFormat();
1326
- case InputFormatKey.Cards: return new CardsFormat();
1327
- case InputFormatKey.Dice: return new DiceFormat();
1328
- case InputFormatKey.Base6: return new Base6Format();
1329
- case InputFormatKey.Base10: return new Base10Format();
1330
- case InputFormatKey.Ints: return new IntsFormat();
1331
- case InputFormatKey.Bip39: return new Bip39Format();
1332
- case InputFormatKey.Sskr: return new SSKRFormat();
1333
- case InputFormatKey.Envelope: return new EnvelopeFormat();
1334
- case InputFormatKey.Multipart: return new MultipartFormat();
1335
- case InputFormatKey.Seed: return new SeedFormat();
1305
+ case "random": return new RandomFormat();
1306
+ case "hex": return new HexFormat();
1307
+ case "btw": return new BytewordsStandardFormat();
1308
+ case "btwu": return new BytewordsUriFormat();
1309
+ case "btwm": return new BytewordsMinimalFormat();
1310
+ case "bits": return new BitsFormat();
1311
+ case "cards": return new CardsFormat();
1312
+ case "dice": return new DiceFormat();
1313
+ case "base6": return new Base6Format();
1314
+ case "base10": return new Base10Format();
1315
+ case "ints": return new IntsFormat();
1316
+ case "bip39": return new Bip39Format();
1317
+ case "sskr": return new SSKRFormat();
1318
+ case "envelope": return new EnvelopeFormat();
1319
+ case "multipart": return new MultipartFormat();
1320
+ case "seed": return new SeedFormat();
1336
1321
  }
1337
1322
  }
1338
1323
  /**
@@ -1341,24 +1326,23 @@ function selectInputFormat(key) {
1341
1326
  */
1342
1327
  function selectOutputFormat(key) {
1343
1328
  switch (key) {
1344
- case OutputFormatKey.Hex: return new HexFormat();
1345
- case OutputFormatKey.Btw: return new BytewordsStandardFormat();
1346
- case OutputFormatKey.Btwu: return new BytewordsUriFormat();
1347
- case OutputFormatKey.Btwm: return new BytewordsMinimalFormat();
1348
- case OutputFormatKey.Bits: return new BitsFormat();
1349
- case OutputFormatKey.Cards: return new CardsFormat();
1350
- case OutputFormatKey.Dice: return new DiceFormat();
1351
- case OutputFormatKey.Base6: return new Base6Format();
1352
- case OutputFormatKey.Base10: return new Base10Format();
1353
- case OutputFormatKey.Ints: return new IntsFormat();
1354
- case OutputFormatKey.Bip39: return new Bip39Format();
1355
- case OutputFormatKey.Sskr: return new SSKRFormat();
1356
- case OutputFormatKey.Envelope: return new EnvelopeFormat();
1357
- case OutputFormatKey.Multipart: return new MultipartFormat();
1358
- case OutputFormatKey.Seed: return new SeedFormat();
1329
+ case "hex": return new HexFormat();
1330
+ case "btw": return new BytewordsStandardFormat();
1331
+ case "btwu": return new BytewordsUriFormat();
1332
+ case "btwm": return new BytewordsMinimalFormat();
1333
+ case "bits": return new BitsFormat();
1334
+ case "cards": return new CardsFormat();
1335
+ case "dice": return new DiceFormat();
1336
+ case "base6": return new Base6Format();
1337
+ case "base10": return new Base10Format();
1338
+ case "ints": return new IntsFormat();
1339
+ case "bip39": return new Bip39Format();
1340
+ case "sskr": return new SSKRFormat();
1341
+ case "envelope": return new EnvelopeFormat();
1342
+ case "multipart": return new MultipartFormat();
1343
+ case "seed": return new SeedFormat();
1359
1344
  }
1360
1345
  }
1361
-
1362
1346
  //#endregion
1363
1347
  exports.Base10Format = Base10Format;
1364
1348
  exports.Base6Format = Base6Format;
@@ -1399,4 +1383,5 @@ exports.parseLowInt = parseLowInt;
1399
1383
  exports.selectInputFormat = selectInputFormat;
1400
1384
  exports.selectOutputFormat = selectOutputFormat;
1401
1385
  exports.sha256DeterministicRandom = sha256DeterministicRandom;
1386
+
1402
1387
  //# sourceMappingURL=index.cjs.map