@bcts/seedtool-cli 1.0.0-alpha.14 → 1.0.0-alpha.16
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/LICENSE +1 -1
- package/README.md +72 -3
- package/dist/index.cjs +78 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +69 -62
- package/dist/index.mjs.map +1 -1
- package/dist/main.mjs +81 -71
- package/dist/main.mjs.map +1 -1
- package/package.json +21 -17
- package/src/cli.ts +25 -24
- package/src/formats/bip39.ts +1 -1
- package/src/formats/format.ts +32 -36
- package/src/formats/multipart.ts +1 -1
- package/src/formats/sskr.ts +41 -32
- package/src/main.ts +39 -16
- package/src/random.ts +3 -3
- package/src/seed.ts +4 -4
- package/src/styles.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as readline from "readline";
|
|
1
|
+
import * as readline from "node:readline";
|
|
2
2
|
import { SSKRGroupSpec, SSKRSecret, SSKRShare, SSKRSpec, Seed as Seed$1, sskrCombine, sskrGenerate } from "@bcts/components";
|
|
3
3
|
import { Envelope, SymmetricKey } from "@bcts/envelope";
|
|
4
4
|
import { DATE, NAME, NOTE, SEED_TYPE } from "@bcts/known-values";
|
|
5
5
|
import { CborDate, decodeCbor, expectBytes, toByteString, toTaggedValue } from "@bcts/dcbor";
|
|
6
|
-
import { sha256 } from "@noble/hashes/
|
|
7
|
-
import { hkdf } from "@noble/hashes/hkdf";
|
|
6
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
7
|
+
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
8
8
|
import { entropyToMnemonic, mnemonicToEntropy, validateMnemonic } from "@scure/bip39";
|
|
9
|
-
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
9
|
+
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
10
10
|
import { BytewordsStyle, MultipartDecoder, MultipartEncoder, UR, decodeBytewords, encodeBytewords } from "@bcts/uniform-resources";
|
|
11
11
|
import { SSKR_SHARE, SSKR_SHARE_V1 } from "@bcts/tags";
|
|
12
12
|
|
|
@@ -115,8 +115,8 @@ function parseDate(s) {
|
|
|
115
115
|
* Returns SSKRGroupSpec instance.
|
|
116
116
|
*/
|
|
117
117
|
function parseGroupSpec(s) {
|
|
118
|
-
const match =
|
|
119
|
-
if (
|
|
118
|
+
const match = /^(\d+)-of-(\d+)$/i.exec(s);
|
|
119
|
+
if (match === null) throw new Error(`Invalid group specification: ${s}. Use format 'M-of-N' (e.g., '2-of-3').`);
|
|
120
120
|
const threshold = parseInt(match[1], 10);
|
|
121
121
|
const count = parseInt(match[2], 10);
|
|
122
122
|
return SSKRGroupSpec.new(threshold, count);
|
|
@@ -182,7 +182,7 @@ var Cli = class Cli {
|
|
|
182
182
|
terminal: false
|
|
183
183
|
});
|
|
184
184
|
rl.on("line", (line) => {
|
|
185
|
-
data += line
|
|
185
|
+
data += `${line}\n`;
|
|
186
186
|
});
|
|
187
187
|
rl.on("close", () => {
|
|
188
188
|
resolve(data.trim());
|
|
@@ -239,23 +239,23 @@ var Cli = class Cli {
|
|
|
239
239
|
*/
|
|
240
240
|
clone() {
|
|
241
241
|
const cli = new Cli();
|
|
242
|
-
cli.input = this.input;
|
|
242
|
+
if (this.input !== void 0) cli.input = this.input;
|
|
243
243
|
cli.count = this.count;
|
|
244
244
|
cli.in = this.in;
|
|
245
245
|
cli.out = this.out;
|
|
246
246
|
cli.low = this.low;
|
|
247
247
|
cli.high = this.high;
|
|
248
|
-
cli.name = this.name;
|
|
249
|
-
cli.note = this.note;
|
|
250
|
-
cli.date = this.date;
|
|
248
|
+
if (this.name !== void 0) cli.name = this.name;
|
|
249
|
+
if (this.note !== void 0) cli.note = this.note;
|
|
250
|
+
if (this.date !== void 0) cli.date = this.date;
|
|
251
251
|
cli.maxFragmentLen = this.maxFragmentLen;
|
|
252
252
|
cli.additionalParts = this.additionalParts;
|
|
253
253
|
cli.groups = [...this.groups];
|
|
254
254
|
cli.groupThreshold = this.groupThreshold;
|
|
255
255
|
cli.sskrFormat = this.sskrFormat;
|
|
256
|
-
cli.deterministic = this.deterministic;
|
|
257
|
-
cli.seed = this.seed
|
|
258
|
-
cli.rng = this.rng;
|
|
256
|
+
if (this.deterministic !== void 0) cli.deterministic = this.deterministic;
|
|
257
|
+
if (this.seed !== void 0) cli.seed = this.seed.clone();
|
|
258
|
+
if (this.rng !== void 0) cli.rng = this.rng;
|
|
259
259
|
return cli;
|
|
260
260
|
}
|
|
261
261
|
};
|
|
@@ -377,7 +377,7 @@ var Seed = class Seed {
|
|
|
377
377
|
* - Optional note assertion (if not empty)
|
|
378
378
|
*/
|
|
379
379
|
toEnvelope() {
|
|
380
|
-
let envelope = Envelope.new(
|
|
380
|
+
let envelope = Envelope.new(this._data);
|
|
381
381
|
envelope = envelope.addType(SEED_TYPE);
|
|
382
382
|
if (this._creationDate !== void 0) {
|
|
383
383
|
const cborDate = CborDate.fromDatetime(this._creationDate);
|
|
@@ -729,6 +729,10 @@ var Bip39Format = class {
|
|
|
729
729
|
//#endregion
|
|
730
730
|
//#region src/formats/sskr.ts
|
|
731
731
|
/**
|
|
732
|
+
* SSKR format
|
|
733
|
+
* Ported from seedtool-cli-rust/src/formats/sskr.rs
|
|
734
|
+
*/
|
|
735
|
+
/**
|
|
732
736
|
* SSKR format handler.
|
|
733
737
|
* Round-trippable: sskr shares → seed → sskr shares.
|
|
734
738
|
* Supports multiple sub-formats: envelope, btw, btwm, btwu, ur.
|
|
@@ -753,16 +757,16 @@ var SSKRFormat = class {
|
|
|
753
757
|
};
|
|
754
758
|
function outputSskrSeed(seed, spec, format) {
|
|
755
759
|
switch (format) {
|
|
756
|
-
case
|
|
757
|
-
const
|
|
760
|
+
case SSKRFormatKey.Envelope: {
|
|
761
|
+
const seedEnvelope = seed.toEnvelope();
|
|
758
762
|
const contentKey = SymmetricKey.new();
|
|
759
|
-
return
|
|
763
|
+
return seedEnvelope.wrap().encryptSubject(contentKey).sskrSplitFlattened(spec, contentKey).map((env) => env.urString()).join("\n");
|
|
760
764
|
}
|
|
761
|
-
case
|
|
762
|
-
case
|
|
763
|
-
case
|
|
764
|
-
case
|
|
765
|
-
return UR.
|
|
765
|
+
case SSKRFormatKey.Btw: return makeBytewordsShares(spec, seed, BytewordsStyle.Standard);
|
|
766
|
+
case SSKRFormatKey.Btwm: return makeBytewordsShares(spec, seed, BytewordsStyle.Minimal);
|
|
767
|
+
case SSKRFormatKey.Btwu: return makeBytewordsShares(spec, seed, BytewordsStyle.Uri);
|
|
768
|
+
case SSKRFormatKey.Ur: return makeShares(spec, seed).map((share) => {
|
|
769
|
+
return UR.new("sskr", toByteString(share.asBytes())).toString();
|
|
766
770
|
}).join("\n");
|
|
767
771
|
}
|
|
768
772
|
}
|
|
@@ -784,7 +788,8 @@ function parseEnvelopes(input) {
|
|
|
784
788
|
shareEnvelopes.push(envelope);
|
|
785
789
|
} catch {}
|
|
786
790
|
if (shareEnvelopes.length === 0) return null;
|
|
787
|
-
const
|
|
791
|
+
const sskrJoin = Envelope.sskrJoin;
|
|
792
|
+
const recoveredEnvelope = sskrJoin(shareEnvelopes).unwrap();
|
|
788
793
|
return Seed.fromEnvelope(recoveredEnvelope);
|
|
789
794
|
} catch {
|
|
790
795
|
return null;
|
|
@@ -805,7 +810,7 @@ function fromTaggedCborShares(taggedCborDataShares) {
|
|
|
805
810
|
const cbor = decodeCbor(data);
|
|
806
811
|
const tagged = cbor;
|
|
807
812
|
if (tagged.tag !== SSKR_SHARE.value && tagged.tag !== SSKR_SHARE_V1.value) return null;
|
|
808
|
-
const bytes = expectBytes(tagged.value
|
|
813
|
+
const bytes = expectBytes(tagged.value !== void 0 ? tagged.value : cbor);
|
|
809
814
|
untaggedShares.push(bytes);
|
|
810
815
|
}
|
|
811
816
|
return fromUntaggedCborShares(untaggedShares);
|
|
@@ -839,7 +844,7 @@ function parseUr(input, expectedTagValue, allowTaggedCbor) {
|
|
|
839
844
|
urs.push(ur);
|
|
840
845
|
} catch {}
|
|
841
846
|
if (urs.length === 0) return null;
|
|
842
|
-
for (const ur of urs) if (ur.
|
|
847
|
+
for (const ur of urs) if (ur.urTypeStr() !== expectedType) return null;
|
|
843
848
|
const untaggedCborShares = [];
|
|
844
849
|
for (const ur of urs) {
|
|
845
850
|
let cbor = ur.cbor();
|
|
@@ -864,9 +869,9 @@ function parseSskrSeed(input) {
|
|
|
864
869
|
if (btwmResult !== null) return btwmResult;
|
|
865
870
|
const btwuResult = parseBytewords(input, BytewordsStyle.Uri);
|
|
866
871
|
if (btwuResult !== null) return btwuResult;
|
|
867
|
-
const urResult = parseUr(input, SSKR_SHARE.value, false);
|
|
872
|
+
const urResult = parseUr(input, Number(SSKR_SHARE.value), false);
|
|
868
873
|
if (urResult !== null) return urResult;
|
|
869
|
-
const urLegacyResult = parseUr(input, SSKR_SHARE_V1.value, true);
|
|
874
|
+
const urLegacyResult = parseUr(input, Number(SSKR_SHARE_V1.value), true);
|
|
870
875
|
if (urLegacyResult !== null) return urLegacyResult;
|
|
871
876
|
throw new Error("Insufficient or invalid SSKR shares.");
|
|
872
877
|
}
|
|
@@ -943,7 +948,7 @@ var MultipartFormat = class {
|
|
|
943
948
|
}
|
|
944
949
|
if (!decoder.isComplete()) throw new Error("Insufficient multipart shares");
|
|
945
950
|
const ur = decoder.message();
|
|
946
|
-
if (ur === void 0) throw new Error("Failed to decode multipart message");
|
|
951
|
+
if (ur === void 0 || ur === null) throw new Error("Failed to decode multipart message");
|
|
947
952
|
const envelope = Envelope.fromUR(ur);
|
|
948
953
|
state.seed = Seed.fromEnvelope(envelope);
|
|
949
954
|
return state;
|
|
@@ -1250,28 +1255,31 @@ var BytewordsUriFormat = class {
|
|
|
1250
1255
|
//#endregion
|
|
1251
1256
|
//#region src/formats/format.ts
|
|
1252
1257
|
/**
|
|
1258
|
+
* Format traits and factory functions
|
|
1259
|
+
* Ported from seedtool-cli-rust/src/formats/format.rs
|
|
1260
|
+
*/
|
|
1261
|
+
/**
|
|
1253
1262
|
* Select input format by key.
|
|
1254
1263
|
* Matches Rust select_input_format function.
|
|
1255
1264
|
*/
|
|
1256
1265
|
function selectInputFormat(key) {
|
|
1257
1266
|
switch (key) {
|
|
1258
|
-
case
|
|
1259
|
-
case
|
|
1260
|
-
case
|
|
1261
|
-
case
|
|
1262
|
-
case
|
|
1263
|
-
case
|
|
1264
|
-
case
|
|
1265
|
-
case
|
|
1266
|
-
case
|
|
1267
|
-
case
|
|
1268
|
-
case
|
|
1269
|
-
case
|
|
1270
|
-
case
|
|
1271
|
-
case
|
|
1272
|
-
case
|
|
1273
|
-
case
|
|
1274
|
-
default: throw new Error(`Unknown input format: ${key}`);
|
|
1267
|
+
case InputFormatKey.Random: return new RandomFormat();
|
|
1268
|
+
case InputFormatKey.Hex: return new HexFormat();
|
|
1269
|
+
case InputFormatKey.Btw: return new BytewordsStandardFormat();
|
|
1270
|
+
case InputFormatKey.Btwu: return new BytewordsUriFormat();
|
|
1271
|
+
case InputFormatKey.Btwm: return new BytewordsMinimalFormat();
|
|
1272
|
+
case InputFormatKey.Bits: return new BitsFormat();
|
|
1273
|
+
case InputFormatKey.Cards: return new CardsFormat();
|
|
1274
|
+
case InputFormatKey.Dice: return new DiceFormat();
|
|
1275
|
+
case InputFormatKey.Base6: return new Base6Format();
|
|
1276
|
+
case InputFormatKey.Base10: return new Base10Format();
|
|
1277
|
+
case InputFormatKey.Ints: return new IntsFormat();
|
|
1278
|
+
case InputFormatKey.Bip39: return new Bip39Format();
|
|
1279
|
+
case InputFormatKey.Sskr: return new SSKRFormat();
|
|
1280
|
+
case InputFormatKey.Envelope: return new EnvelopeFormat();
|
|
1281
|
+
case InputFormatKey.Multipart: return new MultipartFormat();
|
|
1282
|
+
case InputFormatKey.Seed: return new SeedFormat();
|
|
1275
1283
|
}
|
|
1276
1284
|
}
|
|
1277
1285
|
/**
|
|
@@ -1280,22 +1288,21 @@ function selectInputFormat(key) {
|
|
|
1280
1288
|
*/
|
|
1281
1289
|
function selectOutputFormat(key) {
|
|
1282
1290
|
switch (key) {
|
|
1283
|
-
case
|
|
1284
|
-
case
|
|
1285
|
-
case
|
|
1286
|
-
case
|
|
1287
|
-
case
|
|
1288
|
-
case
|
|
1289
|
-
case
|
|
1290
|
-
case
|
|
1291
|
-
case
|
|
1292
|
-
case
|
|
1293
|
-
case
|
|
1294
|
-
case
|
|
1295
|
-
case
|
|
1296
|
-
case
|
|
1297
|
-
case
|
|
1298
|
-
default: throw new Error(`Unknown output format: ${key}`);
|
|
1291
|
+
case OutputFormatKey.Hex: return new HexFormat();
|
|
1292
|
+
case OutputFormatKey.Btw: return new BytewordsStandardFormat();
|
|
1293
|
+
case OutputFormatKey.Btwu: return new BytewordsUriFormat();
|
|
1294
|
+
case OutputFormatKey.Btwm: return new BytewordsMinimalFormat();
|
|
1295
|
+
case OutputFormatKey.Bits: return new BitsFormat();
|
|
1296
|
+
case OutputFormatKey.Cards: return new CardsFormat();
|
|
1297
|
+
case OutputFormatKey.Dice: return new DiceFormat();
|
|
1298
|
+
case OutputFormatKey.Base6: return new Base6Format();
|
|
1299
|
+
case OutputFormatKey.Base10: return new Base10Format();
|
|
1300
|
+
case OutputFormatKey.Ints: return new IntsFormat();
|
|
1301
|
+
case OutputFormatKey.Bip39: return new Bip39Format();
|
|
1302
|
+
case OutputFormatKey.Sskr: return new SSKRFormat();
|
|
1303
|
+
case OutputFormatKey.Envelope: return new EnvelopeFormat();
|
|
1304
|
+
case OutputFormatKey.Multipart: return new MultipartFormat();
|
|
1305
|
+
case OutputFormatKey.Seed: return new SeedFormat();
|
|
1299
1306
|
}
|
|
1300
1307
|
}
|
|
1301
1308
|
|