import { describe, it, expect } from 'vitest'; import { Bytes } from '../src/bytes'; import { Mnemonic, MnemonicRaw } from '../src/mnemonic'; describe('Success cases', () => { // Simple array of cases const testCases: Array<{ fromPhrase: string; fromWords: Array; passphrase?: string; raw: MnemonicRaw; toEntropy: Uint8Array; toSeed: Uint8Array; toPhrase: string; toPhraseWithoutPassphrase: string; toWords: Array; toWordsWithoutPassphrase: Array; }> = [ // No pass-phrase { fromPhrase: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', fromWords: [ 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'about', ], raw: { words: [ 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'about', ], }, toEntropy: Bytes.fromHex( '00000000000000000000000000000000', ).toUint8Array(), toSeed: Bytes.fromHex( '5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4', ).toUint8Array(), toPhrase: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', toPhraseWithoutPassphrase: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about', toWords: [ 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'about', ], toWordsWithoutPassphrase: [ 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'about', ], }, // Passphrase { fromPhrase: 'legal winner thank year wave sausage worth useful legal winner thank yellow Libauth', fromWords: [ 'legal', 'winner', 'thank', 'year', 'wave', 'sausage', 'worth', 'useful', 'legal', 'winner', 'thank', 'yellow', 'Libauth', ], passphrase: 'Libauth', raw: { words: [ 'legal', 'winner', 'thank', 'year', 'wave', 'sausage', 'worth', 'useful', 'legal', 'winner', 'thank', 'yellow', ], passphrase: 'Libauth', }, toEntropy: Bytes.fromHex( '7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f', ).toUint8Array(), toSeed: Bytes.fromHex( '0199495e71f9e7f40b52febf82dcb1a6c342e9178a5e8cfea4204cf6b2071e89345ab83e8a5f0ea3ae59025e5e2e8dd2c965752541912f28ead8a33ff7dd11dd', ).toUint8Array(), toPhrase: 'legal winner thank year wave sausage worth useful legal winner thank yellow Libauth', toPhraseWithoutPassphrase: 'legal winner thank year wave sausage worth useful legal winner thank yellow', toWords: [ 'legal', 'winner', 'thank', 'year', 'wave', 'sausage', 'worth', 'useful', 'legal', 'winner', 'thank', 'yellow', 'Libauth', ], toWordsWithoutPassphrase: [ 'legal', 'winner', 'thank', 'year', 'wave', 'sausage', 'worth', 'useful', 'legal', 'winner', 'thank', 'yellow', ], }, ]; it.each(testCases)('from(string)', ({ fromPhrase: phrase, raw }) => { const mnemonic = Mnemonic.from(phrase); expect(mnemonic.toRaw()).toStrictEqual(raw); }); it.each(testCases)('from(words)', ({ fromWords, raw }) => { const mnemonic = Mnemonic.from(fromWords); expect(mnemonic.toRaw()).toStrictEqual(raw); }); it.each(testCases)('fromPhrase', ({ fromPhrase, raw }) => { const mnemonic = Mnemonic.fromPhrase(fromPhrase); expect(mnemonic.toRaw()).toStrictEqual(raw); }); it.each(testCases)('fromWords', ({ fromWords, raw }) => { const mnemonic = Mnemonic.fromWords(fromWords); expect(mnemonic.toRaw()).toStrictEqual(raw); }); it.each(testCases)('fromWords', ({ fromWords, raw }) => { const mnemonic = Mnemonic.fromWords(fromWords); expect(mnemonic.toRaw()).toStrictEqual(raw); }); it.each(testCases)('toSeed', ({ toSeed, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.toSeed()).toStrictEqual(toSeed); }); it.each(testCases)('toPhrase', ({ toPhrase, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.toPhrase()).toStrictEqual(toPhrase); }); it.each(testCases)( 'toPhrase(withoutPassphrase)', ({ toPhraseWithoutPassphrase, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.toPhrase(false)).toStrictEqual(toPhraseWithoutPassphrase); }, ); it.each(testCases)('toWords', ({ toWords, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.toWords()).toStrictEqual(toWords); }); it.each(testCases)( 'toWords(withoutPassphrase)', ({ toWordsWithoutPassphrase, _passphrase, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.toWords(false)).toStrictEqual(toWordsWithoutPassphrase); }, ); it.each(testCases)('getPassphrase', ({ passphrase, raw }) => { const mnemonic = Mnemonic.fromRaw(raw); expect(mnemonic.getPassphrase()).toStrictEqual(passphrase); }); }); describe('Generate Cases', () => { it('generateRandom should return instance of Mnemonic', () => { const mnemonic = Mnemonic.generateRandom(); expect(mnemonic).toBeInstanceOf(Mnemonic); }); it('generateRandom should return instance of Mnemonic with passphrase', () => { const mnemonic = Mnemonic.generateRandom('GeneralProtocols!'); expect(mnemonic).toBeInstanceOf(Mnemonic); expect(mnemonic.getPassphrase()).toBe('GeneralProtocols!'); }); }); describe('Validations', () => { it('isValid should succeed if valid mnemonic', () => { const isValid = Mnemonic.isValid( 'goose just fan kidney barrel album wave crowd movie flame cousin exhaust', ); expect(isValid).toBe(true); }); it('isValid should fail if invalid mnemonic', () => { // 11 words. const isValid = Mnemonic.isValid( 'goose just fan kidney barrel album wave crowd movie flame cousin', ); expect(isValid).toBe(false); }); it('isValidWord should succeed if word is in word list', () => { const isValid = Mnemonic.isValidWord('goose'); expect(isValid).toBe(true); }); it('isValidWord should fail if word is not in word list', () => { const isValid = Mnemonic.isValidWord('fnord'); expect(isValid).toBe(false); }); }); describe('Fail cases', () => { it('fromPhrase should fail if invalid number of words', () => { expect(() => { // 11 words. Mnemonic.fromPhrase( 'goose just fan kidney barrel album wave crowd movie flame cousin', ); }).toThrow(); }); it('generateRandom should fail if invalid wordList contains invalid number of words', () => { expect(() => { // 11 words. Mnemonic.generateRandom('GeneralProtocols!', ['one', 'two', 'three']); }).toThrow(); }); it('fromWords should fail if invalid number of words', () => { expect(() => { // 11 words. Mnemonic.fromWords([ 'goose', 'just', 'fan', 'kidney', 'barrel', 'album', 'wave', 'crowd', 'movie', 'flame', 'cousin', ]); }).toThrow(); }); it('fromPhrase should fail if word not in dictionary', () => { expect(() => { // Invalid word "fnord". Mnemonic.fromPhrase( 'fnord just fan kidney barrel album wave crowd movie flame cousin exhaust', ); }).toThrow(); }); it('fromWord should fail if word not in dictionary', () => { expect(() => { // Invalid word "fnord". Mnemonic.fromWords([ 'fnord', 'just', 'fan', 'kidney', 'barrel', 'album', 'wave', 'crowd', 'movie', 'flame', 'cousin', 'exhaust', ]); }).toThrow(); }); it('fromWord should fail if checksum is invalid', () => { expect(() => { // Invalid word "fnord". Mnemonic.fromWords([ 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'abandon', 'banana', ]); }).toThrow(); }); });