mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-10 13:47:12 +00:00
Re-implement bip39
This commit is contained in:
parent
fab55d3807
commit
64d60c7083
41
.pnp.cjs
generated
41
.pnp.cjs
generated
@ -573,6 +573,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
"@types/pako",
|
"@types/pako",
|
||||||
"npm:1.0.1"
|
"npm:1.0.1"
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"@types/pbkdf2",
|
||||||
|
"npm:3.1.0"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"@types/qs",
|
"@types/qs",
|
||||||
"npm:6.9.6"
|
"npm:6.9.6"
|
||||||
@ -841,10 +845,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
"bindings",
|
"bindings",
|
||||||
"npm:1.5.0"
|
"npm:1.5.0"
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"bip39",
|
|
||||||
"npm:3.0.4"
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"bl",
|
"bl",
|
||||||
"npm:4.1.0"
|
"npm:4.1.0"
|
||||||
@ -3357,9 +3357,9 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
["@types/karma-jasmine-html-reporter", "npm:1.5.1"],
|
["@types/karma-jasmine-html-reporter", "npm:1.5.1"],
|
||||||
["@types/libsodium-wrappers", "npm:0.7.9"],
|
["@types/libsodium-wrappers", "npm:0.7.9"],
|
||||||
["@types/node", "npm:15.3.1"],
|
["@types/node", "npm:15.3.1"],
|
||||||
|
["@types/pbkdf2", "npm:3.1.0"],
|
||||||
["@typescript-eslint/eslint-plugin", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
["@typescript-eslint/eslint-plugin", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
||||||
["@typescript-eslint/parser", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
["@typescript-eslint/parser", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
||||||
["bip39", "npm:3.0.4"],
|
|
||||||
["bn.js", "npm:5.2.0"],
|
["bn.js", "npm:5.2.0"],
|
||||||
["buffer", "npm:6.0.3"],
|
["buffer", "npm:6.0.3"],
|
||||||
["elliptic", "npm:6.5.4"],
|
["elliptic", "npm:6.5.4"],
|
||||||
@ -3381,6 +3381,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
["karma-jasmine-html-reporter", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:1.6.0"],
|
["karma-jasmine-html-reporter", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:1.6.0"],
|
||||||
["libsodium-wrappers", "npm:0.7.9"],
|
["libsodium-wrappers", "npm:0.7.9"],
|
||||||
["nyc", "npm:15.1.0"],
|
["nyc", "npm:15.1.0"],
|
||||||
|
["pbkdf2", "npm:3.1.2"],
|
||||||
["prettier", "npm:2.4.1"],
|
["prettier", "npm:2.4.1"],
|
||||||
["ses", "npm:0.11.1"],
|
["ses", "npm:0.11.1"],
|
||||||
["source-map-support", "npm:0.5.19"],
|
["source-map-support", "npm:0.5.19"],
|
||||||
@ -4716,13 +4717,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
}]
|
}]
|
||||||
]],
|
]],
|
||||||
["@types/node", [
|
["@types/node", [
|
||||||
["npm:11.11.6", {
|
|
||||||
"packageLocation": "./.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip/node_modules/@types/node/",
|
|
||||||
"packageDependencies": [
|
|
||||||
["@types/node", "npm:11.11.6"]
|
|
||||||
],
|
|
||||||
"linkType": "HARD",
|
|
||||||
}],
|
|
||||||
["npm:13.13.52", {
|
["npm:13.13.52", {
|
||||||
"packageLocation": "./.yarn/cache/@types-node-npm-13.13.52-95159539bb-8f1afff497.zip/node_modules/@types/node/",
|
"packageLocation": "./.yarn/cache/@types-node-npm-13.13.52-95159539bb-8f1afff497.zip/node_modules/@types/node/",
|
||||||
"packageDependencies": [
|
"packageDependencies": [
|
||||||
@ -4764,6 +4758,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
"linkType": "HARD",
|
"linkType": "HARD",
|
||||||
}]
|
}]
|
||||||
]],
|
]],
|
||||||
|
["@types/pbkdf2", [
|
||||||
|
["npm:3.1.0", {
|
||||||
|
"packageLocation": "./.yarn/cache/@types-pbkdf2-npm-3.1.0-9fa74ff7fb-d15024b195.zip/node_modules/@types/pbkdf2/",
|
||||||
|
"packageDependencies": [
|
||||||
|
["@types/pbkdf2", "npm:3.1.0"],
|
||||||
|
["@types/node", "npm:15.3.1"]
|
||||||
|
],
|
||||||
|
"linkType": "HARD",
|
||||||
|
}]
|
||||||
|
]],
|
||||||
["@types/qs", [
|
["@types/qs", [
|
||||||
["npm:6.9.6", {
|
["npm:6.9.6", {
|
||||||
"packageLocation": "./.yarn/cache/@types-qs-npm-6.9.6-2fc5ce36d4-01871b1cf7.zip/node_modules/@types/qs/",
|
"packageLocation": "./.yarn/cache/@types-qs-npm-6.9.6-2fc5ce36d4-01871b1cf7.zip/node_modules/@types/qs/",
|
||||||
@ -6287,19 +6291,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
|||||||
"linkType": "HARD",
|
"linkType": "HARD",
|
||||||
}]
|
}]
|
||||||
]],
|
]],
|
||||||
["bip39", [
|
|
||||||
["npm:3.0.4", {
|
|
||||||
"packageLocation": "./.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip/node_modules/bip39/",
|
|
||||||
"packageDependencies": [
|
|
||||||
["bip39", "npm:3.0.4"],
|
|
||||||
["@types/node", "npm:11.11.6"],
|
|
||||||
["create-hash", "npm:1.2.0"],
|
|
||||||
["pbkdf2", "npm:3.1.2"],
|
|
||||||
["randombytes", "npm:2.1.0"]
|
|
||||||
],
|
|
||||||
"linkType": "HARD",
|
|
||||||
}]
|
|
||||||
]],
|
|
||||||
["bl", [
|
["bl", [
|
||||||
["npm:4.1.0", {
|
["npm:4.1.0", {
|
||||||
"packageLocation": "./.yarn/cache/bl-npm-4.1.0-7f94cdcf3f-9e8521fa7e.zip/node_modules/bl/",
|
"packageLocation": "./.yarn/cache/bl-npm-4.1.0-7f94cdcf3f-9e8521fa7e.zip/node_modules/bl/",
|
||||||
|
BIN
.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/@types-pbkdf2-npm-3.1.0-9fa74ff7fb-d15024b195.zip
(Stored with Git LFS)
vendored
Normal file
BIN
.yarn/cache/@types-pbkdf2-npm-3.1.0-9fa74ff7fb-d15024b195.zip
(Stored with Git LFS)
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip
(Stored with Git LFS)
vendored
Binary file not shown.
3
NOTICE
3
NOTICE
@ -23,6 +23,9 @@ The code in packages/json-rpc was forked from https://github.com/iov-one/iov-cor
|
|||||||
|
|
||||||
The code in packages/socket and scripts/socketserver was forked from the folders packages/iov-socket and scripts/socketserver respectively of https://github.com/iov-one/iov-core at tag v2.5.0 on 2020-06-24.
|
The code in packages/socket and scripts/socketserver was forked from the folders packages/iov-socket and scripts/socketserver respectively of https://github.com/iov-one/iov-core at tag v2.5.0 on 2020-06-24.
|
||||||
|
|
||||||
|
The code in packages/crypto/src/bip39.ts contains code forked from bitcoinjs/bip39 (https://github.com/bitcoinjs/bip39/blob/v3.0.4/LICENSE)
|
||||||
|
on 2021-12-16. Copyright (c) 2014, Wei Lu and Daniel Cousens.
|
||||||
|
|
||||||
Copyright 2018-2020 IOV SAS
|
Copyright 2018-2020 IOV SAS
|
||||||
Copyright 2020-2021 Confio OÜ
|
Copyright 2020-2021 Confio OÜ
|
||||||
Copyright 2020 Simon Warta
|
Copyright 2020 Simon Warta
|
||||||
|
@ -45,10 +45,10 @@
|
|||||||
"@cosmjs/math": "workspace:packages/math",
|
"@cosmjs/math": "workspace:packages/math",
|
||||||
"@cosmjs/utils": "workspace:packages/utils",
|
"@cosmjs/utils": "workspace:packages/utils",
|
||||||
"@noble/hashes": "^1",
|
"@noble/hashes": "^1",
|
||||||
"bip39": "^3.0.2",
|
|
||||||
"bn.js": "^5.2.0",
|
"bn.js": "^5.2.0",
|
||||||
"elliptic": "^6.5.3",
|
"elliptic": "^6.5.3",
|
||||||
"libsodium-wrappers": "^0.7.6"
|
"libsodium-wrappers": "^0.7.6",
|
||||||
|
"pbkdf2": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
||||||
@ -61,6 +61,7 @@
|
|||||||
"@types/karma-jasmine-html-reporter": "^1",
|
"@types/karma-jasmine-html-reporter": "^1",
|
||||||
"@types/libsodium-wrappers": "^0.7.7",
|
"@types/libsodium-wrappers": "^0.7.7",
|
||||||
"@types/node": "^15.0.1",
|
"@types/node": "^15.0.1",
|
||||||
|
"@types/pbkdf2": "^3.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.28",
|
"@typescript-eslint/eslint-plugin": "^4.28",
|
||||||
"@typescript-eslint/parser": "^4.28",
|
"@typescript-eslint/parser": "^4.28",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
|
@ -1,8 +1,49 @@
|
|||||||
import { fromHex } from "@cosmjs/encoding";
|
import { fromAscii, fromBase64, fromHex } from "@cosmjs/encoding";
|
||||||
|
|
||||||
import { Bip39 } from "./bip39";
|
import { Bip39, EnglishMnemonic, entropyToMnemonic, mnemonicToEntropy } from "./bip39";
|
||||||
import { EnglishMnemonic } from "./englishmnemonic";
|
import { sha256 } from "./sha";
|
||||||
import bip39Vectors from "./testdata/bip39.json";
|
import bip39Vectors from "./testdata/bip39.json";
|
||||||
|
import wordlists from "./testdata/bip39_wordlists.json";
|
||||||
|
|
||||||
|
describe("entropyToMnemonic", () => {
|
||||||
|
it("works", () => {
|
||||||
|
// From https://iancoleman.io/bip39/
|
||||||
|
expect(entropyToMnemonic(fromHex("a323224e6b13d31942509dc4e2e579be3d5bb7f2"))).toEqual(
|
||||||
|
"permit boil near stomach diamond million announce beauty shaft blame fury ladder stick swim slab",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("works for all the test vectors", () => {
|
||||||
|
// Test vectors from https://github.com/trezor/python-mnemonic/blob/b502451a33a440783926e04428115e0bed87d01f/vectors.json
|
||||||
|
// plus similar vectors generated for the missing lengths 15 and 21 words
|
||||||
|
const { "12": vec12, "15": vec15, "18": vec18, "21": vec21, "24": vec24 } = bip39Vectors.encoding;
|
||||||
|
for (const vectors of [vec12, vec15, vec18, vec21, vec24]) {
|
||||||
|
for (const { entropy, mnemonic } of vectors) {
|
||||||
|
expect(entropyToMnemonic(fromHex(entropy)).toString()).toEqual(mnemonic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("mnemonicToEntropy", () => {
|
||||||
|
it("works", () => {
|
||||||
|
// From https://iancoleman.io/bip39/
|
||||||
|
expect(
|
||||||
|
mnemonicToEntropy(
|
||||||
|
"permit boil near stomach diamond million announce beauty shaft blame fury ladder stick swim slab",
|
||||||
|
),
|
||||||
|
).toEqual(fromHex("a323224e6b13d31942509dc4e2e579be3d5bb7f2"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("works for all the test vectors", () => {
|
||||||
|
const { "12": vec12, "15": vec15, "18": vec18, "21": vec21, "24": vec24 } = bip39Vectors.encoding;
|
||||||
|
for (const vectors of [vec12, vec15, vec18, vec21, vec24]) {
|
||||||
|
for (const { entropy, mnemonic } of vectors) {
|
||||||
|
expect(mnemonicToEntropy(mnemonic)).toEqual(fromHex(entropy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("Bip39", () => {
|
describe("Bip39", () => {
|
||||||
describe("encode", () => {
|
describe("encode", () => {
|
||||||
@ -414,3 +455,240 @@ describe("Bip39", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("EnglishMnemonic", () => {
|
||||||
|
describe("wordlist", () => {
|
||||||
|
it("matches the words from the bitcoin/bips/bip-0039 spec", () => {
|
||||||
|
const lineFeed = 0x0a;
|
||||||
|
const bip39EnglishTxt = fromBase64(wordlists.english);
|
||||||
|
|
||||||
|
// Ensure we loaded the correct english.txt from https://github.com/bitcoin/bips/tree/master/bip-0039
|
||||||
|
const checksum = sha256(bip39EnglishTxt);
|
||||||
|
expect(checksum).toEqual(fromHex("2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda"));
|
||||||
|
|
||||||
|
const wordsFromSpec: string[] = [];
|
||||||
|
|
||||||
|
let start = 0; // the start cursor marks the first byte of the word
|
||||||
|
let end = 0; // the end cursor marks the line feed byte
|
||||||
|
while (end < bip39EnglishTxt.length - 1) {
|
||||||
|
end = start;
|
||||||
|
while (bip39EnglishTxt[end] !== lineFeed) end++;
|
||||||
|
const slice = bip39EnglishTxt.slice(start, end);
|
||||||
|
wordsFromSpec.push(fromAscii(slice));
|
||||||
|
start = end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(EnglishMnemonic.wordlist).toEqual(wordsFromSpec);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("works for valid inputs", () => {
|
||||||
|
expect(() => {
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
);
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon address",
|
||||||
|
);
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||||
|
);
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon admit",
|
||||||
|
);
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||||
|
);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects invalid whitespacing", () => {
|
||||||
|
// extra space (leading, middle, trailing)
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
" abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about ",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
|
||||||
|
// newline, tab
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon\nabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon\tabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects disallowed letters", () => {
|
||||||
|
// Disallowed letters in words (capital, number, special char)
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"Abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon Abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"route66 abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon route66 abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"lötkolben abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon lötkolben abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic format/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("word counts other than 12, 15, 18, 21, 24", () => {
|
||||||
|
// too few and too many words (11, 13, 17, 19, 23, 25)
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 11/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 13/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 17/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 19/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 23/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid word count(.*)got: 25/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects invalid checksums", () => {
|
||||||
|
// 12x, 15x, 18x, 21x, 24x "zoo"
|
||||||
|
expect(() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo")).toThrowError(
|
||||||
|
/invalid mnemonic checksum/i,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||||
|
).toThrowError(/invalid mnemonic checksum/i);
|
||||||
|
expect(
|
||||||
|
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||||
|
).toThrowError(/invalid mnemonic checksum/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic checksum/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||||
|
),
|
||||||
|
).toThrowError(/invalid mnemonic checksum/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects valid mnemonics of other languages", () => {
|
||||||
|
// valid Spanish and Italian bip39 mnemonics
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"humo odio oriente colina taco fingir salto geranio glaciar academia suave vigor",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"yema folleto tos llave obtener natural fruta deseo laico sopa novato lazo imponer afinar vena hoja zarza cama",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"burla plaza arroz ronda pregunta vacuna veloz boina retiro exento prensa tortuga cabeza pilar anual molino molde fiesta masivo jefe leve fatiga clase plomo",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"braccio trincea armonia emiro svedese lepre stridulo metallo baldo rasente potassio rilassato",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"riparato arrosto globulo singolo bozzolo roba pirolisi ultimato padrone munto leggero avanzato monetario guanto lorenzo latino inoltrare modulo",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
expect(
|
||||||
|
() =>
|
||||||
|
new EnglishMnemonic(
|
||||||
|
"promessa mercurio spessore snodo trave risata mecenate vichingo ceto orecchino vissuto risultato canino scarso futile fune epilogo uovo inedito apatico folata egoismo rifugio coma",
|
||||||
|
),
|
||||||
|
).toThrowError(/contains invalid word/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("toString", () => {
|
||||||
|
it("works", () => {
|
||||||
|
const original =
|
||||||
|
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
const mnemonic = new EnglishMnemonic(original);
|
||||||
|
expect(mnemonic.toString()).toEqual(original);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,242 +0,0 @@
|
|||||||
import { fromAscii, fromBase64, fromHex } from "@cosmjs/encoding";
|
|
||||||
|
|
||||||
import { EnglishMnemonic } from "./englishmnemonic";
|
|
||||||
import { sha256 } from "./sha";
|
|
||||||
import wordlists from "./testdata/bip39_wordlists.json";
|
|
||||||
|
|
||||||
describe("EnglishMnemonic", () => {
|
|
||||||
describe("wordlist", () => {
|
|
||||||
it("matches the words from the bitcoin/bips/bip-0039 spec", () => {
|
|
||||||
const lineFeed = 0x0a;
|
|
||||||
const bip39EnglishTxt = fromBase64(wordlists.english);
|
|
||||||
|
|
||||||
// Ensure we loaded the correct english.txt from https://github.com/bitcoin/bips/tree/master/bip-0039
|
|
||||||
const checksum = sha256(bip39EnglishTxt);
|
|
||||||
expect(checksum).toEqual(fromHex("2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda"));
|
|
||||||
|
|
||||||
const wordsFromSpec: string[] = [];
|
|
||||||
|
|
||||||
let start = 0; // the start cursor marks the first byte of the word
|
|
||||||
let end = 0; // the end cursor marks the line feed byte
|
|
||||||
while (end < bip39EnglishTxt.length - 1) {
|
|
||||||
end = start;
|
|
||||||
while (bip39EnglishTxt[end] !== lineFeed) end++;
|
|
||||||
const slice = bip39EnglishTxt.slice(start, end);
|
|
||||||
wordsFromSpec.push(fromAscii(slice));
|
|
||||||
start = end + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(EnglishMnemonic.wordlist).toEqual(wordsFromSpec);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("works for valid inputs", () => {
|
|
||||||
expect(() => {
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
);
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon address",
|
|
||||||
);
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
|
||||||
);
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon admit",
|
|
||||||
);
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
|
||||||
);
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects invalid whitespacing", () => {
|
|
||||||
// extra space (leading, middle, trailing)
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
" abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about ",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
|
|
||||||
// newline, tab
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon\nabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon\tabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects disallowed letters", () => {
|
|
||||||
// Disallowed letters in words (capital, number, special char)
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"Abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon Abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"route66 abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon route66 abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"lötkolben abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon lötkolben abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic format/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("word counts other than 12, 15, 18, 21, 24", () => {
|
|
||||||
// too few and too many words (11, 13, 17, 19, 23, 25)
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 11/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 13/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 17/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 19/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 23/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid word count(.*)got: 25/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects invalid checksums", () => {
|
|
||||||
// 12x, 15x, 18x, 21x, 24x "zoo"
|
|
||||||
expect(() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo")).toThrowError(
|
|
||||||
/invalid mnemonic checksum/i,
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
|
||||||
).toThrowError(/invalid mnemonic checksum/i);
|
|
||||||
expect(
|
|
||||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
|
||||||
).toThrowError(/invalid mnemonic checksum/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic checksum/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
|
||||||
),
|
|
||||||
).toThrowError(/invalid mnemonic checksum/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("rejects valid mnemonics of other languages", () => {
|
|
||||||
// valid Spanish and Italian bip39 mnemonics
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"humo odio oriente colina taco fingir salto geranio glaciar academia suave vigor",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"yema folleto tos llave obtener natural fruta deseo laico sopa novato lazo imponer afinar vena hoja zarza cama",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"burla plaza arroz ronda pregunta vacuna veloz boina retiro exento prensa tortuga cabeza pilar anual molino molde fiesta masivo jefe leve fatiga clase plomo",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"braccio trincea armonia emiro svedese lepre stridulo metallo baldo rasente potassio rilassato",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"riparato arrosto globulo singolo bozzolo roba pirolisi ultimato padrone munto leggero avanzato monetario guanto lorenzo latino inoltrare modulo",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
expect(
|
|
||||||
() =>
|
|
||||||
new EnglishMnemonic(
|
|
||||||
"promessa mercurio spessore snodo trave risata mecenate vichingo ceto orecchino vissuto risultato canino scarso futile fune epilogo uovo inedito apatico folata egoismo rifugio coma",
|
|
||||||
),
|
|
||||||
).toThrowError(/contains invalid word/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("toString", () => {
|
|
||||||
it("works", () => {
|
|
||||||
const original =
|
|
||||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
|
||||||
const mnemonic = new EnglishMnemonic(original);
|
|
||||||
expect(mnemonic.toString()).toEqual(original);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,39 +0,0 @@
|
|||||||
import * as bip39 from "bip39";
|
|
||||||
|
|
||||||
export class EnglishMnemonic {
|
|
||||||
public static readonly wordlist: readonly string[] = bip39.wordlists.english;
|
|
||||||
|
|
||||||
// list of space separated lower case words (1 or more)
|
|
||||||
private static readonly mnemonicMatcher = /^[a-z]+( [a-z]+)*$/;
|
|
||||||
|
|
||||||
private readonly data: string;
|
|
||||||
|
|
||||||
public constructor(mnemonic: string) {
|
|
||||||
if (!EnglishMnemonic.mnemonicMatcher.test(mnemonic)) {
|
|
||||||
throw new Error("Invalid mnemonic format");
|
|
||||||
}
|
|
||||||
|
|
||||||
const words = mnemonic.split(" ");
|
|
||||||
const allowedWordsLengths: readonly number[] = [12, 15, 18, 21, 24];
|
|
||||||
if (allowedWordsLengths.indexOf(words.length) === -1) {
|
|
||||||
throw new Error(
|
|
||||||
`Invalid word count in mnemonic (allowed: ${allowedWordsLengths} got: ${words.length})`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const word of words) {
|
|
||||||
if (EnglishMnemonic.wordlist.indexOf(word) === -1) {
|
|
||||||
throw new Error("Mnemonic contains invalid word");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Throws with informative error message if mnemonic is not valid
|
|
||||||
bip39.mnemonicToEntropy(mnemonic);
|
|
||||||
|
|
||||||
this.data = mnemonic;
|
|
||||||
}
|
|
||||||
|
|
||||||
public toString(): string {
|
|
||||||
return this.data;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
export { Bip39 } from "./bip39";
|
export { Bip39, EnglishMnemonic } from "./bip39";
|
||||||
export { EnglishMnemonic } from "./englishmnemonic";
|
|
||||||
export { HashFunction } from "./hash";
|
export { HashFunction } from "./hash";
|
||||||
export { Hmac } from "./hmac";
|
export { Hmac } from "./hmac";
|
||||||
export { Keccak256, keccak256 } from "./keccak";
|
export { Keccak256, keccak256 } from "./keccak";
|
||||||
|
35
yarn.lock
35
yarn.lock
@ -462,9 +462,9 @@ __metadata:
|
|||||||
"@types/karma-jasmine-html-reporter": ^1
|
"@types/karma-jasmine-html-reporter": ^1
|
||||||
"@types/libsodium-wrappers": ^0.7.7
|
"@types/libsodium-wrappers": ^0.7.7
|
||||||
"@types/node": ^15.0.1
|
"@types/node": ^15.0.1
|
||||||
|
"@types/pbkdf2": ^3.1.0
|
||||||
"@typescript-eslint/eslint-plugin": ^4.28
|
"@typescript-eslint/eslint-plugin": ^4.28
|
||||||
"@typescript-eslint/parser": ^4.28
|
"@typescript-eslint/parser": ^4.28
|
||||||
bip39: ^3.0.2
|
|
||||||
bn.js: ^5.2.0
|
bn.js: ^5.2.0
|
||||||
buffer: ^6.0.3
|
buffer: ^6.0.3
|
||||||
elliptic: ^6.5.3
|
elliptic: ^6.5.3
|
||||||
@ -486,6 +486,7 @@ __metadata:
|
|||||||
karma-jasmine-html-reporter: ^1.5.4
|
karma-jasmine-html-reporter: ^1.5.4
|
||||||
libsodium-wrappers: ^0.7.6
|
libsodium-wrappers: ^0.7.6
|
||||||
nyc: ^15.1.0
|
nyc: ^15.1.0
|
||||||
|
pbkdf2: ^3.1.2
|
||||||
prettier: ^2.4.1
|
prettier: ^2.4.1
|
||||||
ses: ^0.11.0
|
ses: ^0.11.0
|
||||||
source-map-support: ^0.5.19
|
source-map-support: ^0.5.19
|
||||||
@ -1692,13 +1693,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:11.11.6":
|
|
||||||
version: 11.11.6
|
|
||||||
resolution: "@types/node@npm:11.11.6"
|
|
||||||
checksum: 075f1c011cf568e49701419acbcb55c24906b3bb5a34d9412a3b88f228a7a78401a5ad4d3e1cd6855c99aaea5ef96e37fc86ca097e50f06da92cf822befc1fff
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@types/node@npm:>=13.7.0":
|
"@types/node@npm:>=13.7.0":
|
||||||
version: 15.9.0
|
version: 15.9.0
|
||||||
resolution: "@types/node@npm:15.9.0"
|
resolution: "@types/node@npm:15.9.0"
|
||||||
@ -1720,6 +1714,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/pbkdf2@npm:^3.1.0":
|
||||||
|
version: 3.1.0
|
||||||
|
resolution: "@types/pbkdf2@npm:3.1.0"
|
||||||
|
dependencies:
|
||||||
|
"@types/node": "*"
|
||||||
|
checksum: d15024b1957c21cf3b8887329d9bd8dfde754cf13a09d76ae25f1391cfc62bb8b8d7b760773c5dbaa748172fba8b3e0c3dbe962af6ccbd69b76df12a48dfba40
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/qs@npm:*":
|
"@types/qs@npm:*":
|
||||||
version: 6.9.6
|
version: 6.9.6
|
||||||
resolution: "@types/qs@npm:6.9.6"
|
resolution: "@types/qs@npm:6.9.6"
|
||||||
@ -2401,18 +2404,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"bip39@npm:^3.0.2":
|
|
||||||
version: 3.0.4
|
|
||||||
resolution: "bip39@npm:3.0.4"
|
|
||||||
dependencies:
|
|
||||||
"@types/node": 11.11.6
|
|
||||||
create-hash: ^1.1.0
|
|
||||||
pbkdf2: ^3.0.9
|
|
||||||
randombytes: ^2.0.1
|
|
||||||
checksum: 79ce1600a03d1ba5053bdd4e6323f9463ec340764c7e52918b6c6b9dca81221940f2d9a65656447f108f9bc2c8d9ae8df319cca83bbd1dad63f53ef2768d9bae
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"bl@npm:^4.0.3":
|
"bl@npm:^4.0.3":
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
resolution: "bl@npm:4.1.0"
|
resolution: "bl@npm:4.1.0"
|
||||||
@ -5947,7 +5938,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"pbkdf2@npm:^3.0.9":
|
"pbkdf2@npm:^3.1.2":
|
||||||
version: 3.1.2
|
version: 3.1.2
|
||||||
resolution: "pbkdf2@npm:3.1.2"
|
resolution: "pbkdf2@npm:3.1.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -6210,7 +6201,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"randombytes@npm:^2.0.1, randombytes@npm:^2.1.0":
|
"randombytes@npm:^2.1.0":
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
resolution: "randombytes@npm:2.1.0"
|
resolution: "randombytes@npm:2.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user