@ -34,111 +34,6 @@ const monero_config = require("./monero_config");
//
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - Exposing available names
//
const wordsetNamesByWordsetName = { } ;
const allWordsetNames = Object . keys ( mnemonic . mn _words ) ;
for ( let wordsetName of allWordsetNames ) {
wordsetNamesByWordsetName [ wordsetName ] = wordsetName ;
}
exports . WordsetNamesByWordsetName = wordsetNamesByWordsetName ;
exports . AllWordsetNames = allWordsetNames ;
//
//
// Mnemonic wordset utilities - Comparison
// TODO: perhaps move this to mnemonic.js
function AreEqualMnemonics ( a , b , a _ _wordsetName , b _ _wordsetName ) {
if ( a _ _wordsetName !== b _ _wordsetName ) {
return false ;
}
const wordsetName = a _ _wordsetName ;
const wordset = mnemonic . mn _words [ wordsetName ] ;
const prefix _len = wordset . prefix _len ;
// since mnemonics can be entered with only the first N letters, we must check equality of mnemonics by prefix
let a _ _mnemonicString _words = a . split ( " " ) ;
let b _ _mnemonicString _words = b . split ( " " ) ;
if ( a _ _mnemonicString _words . length != b _ _mnemonicString _words . length ) {
return false ;
}
let numberOf _mnemonicString _words = a _ _mnemonicString _words . length ;
for ( var i = 0 ; i < numberOf _mnemonicString _words ; i ++ ) {
let a _ _word = a _ _mnemonicString _words [ i ] ;
let b _ _word = b _ _mnemonicString _words [ i ] ;
// ... We're assuming that a and b are already valid mneminics
const a _prefix = a _ _word . slice ( 0 , prefix _len ) ;
const b _prefix = b _ _word . slice ( 0 , prefix _len ) ;
if ( a _prefix !== b _prefix ) {
return false ;
}
}
return true ;
}
exports . AreEqualMnemonics = AreEqualMnemonics ;
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - Wordset name detection by mnemonic contents
// TODO: perhaps move this to mnemonic.js
function WordsetNameAccordingToMnemonicString (
mnemonicString , // throws
) {
const mnemonicString _words = mnemonicString . split ( " " ) ;
if ( mnemonicString _words . length == 0 ) {
throw "Invalid mnemonic" ;
}
var wholeMnemonicSuspectedAsWordsetNamed = null ; // to derive
for ( let mnemonicString _word of mnemonicString _words ) {
var thisWordIsInWordsetNamed = null ; // to derive
for ( let wordsetName of allWordsetNames ) {
if ( wordsetName === "electrum" ) {
continue ; // skip because it conflicts with 'english'
}
const wordset = mnemonic . mn _words [ wordsetName ] ;
const prefix _len = wordset . prefix _len ;
if ( mnemonicString _word . length < prefix _len ) {
throw "Please enter more than " +
( prefix _len - 1 ) +
" letters per word" ;
}
const wordsetWords = wordset . words ;
for ( let wordsetWord of wordsetWords ) {
if ( wordsetWord . indexOf ( mnemonicString _word ) == 0 ) {
// we can safely check prefix b/c we've checked mnemonicString_word is of at least min length
thisWordIsInWordsetNamed = wordsetName ;
break ; // done looking; exit interior then exterior loops
}
}
if ( thisWordIsInWordsetNamed != null ) {
// just found
break ; // also exit
}
// haven't found it yet; keep looking
}
if ( thisWordIsInWordsetNamed === null ) {
// didn't find this word in any of the mnemonic wordsets
throw "Unrecognized mnemonic language" ;
}
if ( wholeMnemonicSuspectedAsWordsetNamed === null ) {
// haven't found it yet
wholeMnemonicSuspectedAsWordsetNamed = thisWordIsInWordsetNamed ;
} else if (
thisWordIsInWordsetNamed !== wholeMnemonicSuspectedAsWordsetNamed
) {
throw "Ambiguous mnemonic language" ; // multiple wordset names detected
} else {
// nothing to do but keep verifying the rest of the words that it's the same suspsected wordset
}
}
if ( wholeMnemonicSuspectedAsWordsetNamed === null ) {
// this might be redundant, but for logical rigor……
throw "Unrecognized mnemonic language" ;
}
//
return wholeMnemonicSuspectedAsWordsetNamed ;
}
exports . WordsetNameAccordingToMnemonicString = WordsetNameAccordingToMnemonicString ;
//
//
////////////////////////////////////////////////////////////////////////////////
// Mnemonic wordset utilities - By locale
//
const mnemonicWordsetNamesByAppLocaleNames = {
@ -193,7 +88,6 @@ exports.MnemonicStringFromSeed = MnemonicStringFromSeed;
//
function SeedAndKeysFromMnemonic _sync (
mnemonicString ,
mnemonic _wordsetName ,
nettype ,
) {
// -> {err_str?, seed?, keys?}
@ -201,10 +95,11 @@ function SeedAndKeysFromMnemonic_sync(
try {
const ret = monero _utils . seed _and _keys _from _mnemonic (
mnemonicString ,
mnemonic_wordsetNam e
nettyp e
) ;
return {
err _str : null ,
mnemonic _language : ret . mnemonic _language ,
seed : ret . sec _seed _string ,
keys : {
public _addr : ret . address _string ,
@ -222,6 +117,7 @@ function SeedAndKeysFromMnemonic_sync(
console . error ( "Invalid mnemonic!" ) ;
return {
err _str : typeof e === "string" ? e : "" + e ,
mnemonic _language : null ,
seed : null ,
keys : null ,
} ;
@ -231,20 +127,20 @@ exports.SeedAndKeysFromMnemonic_sync = SeedAndKeysFromMnemonic_sync;
function SeedAndKeysFromMnemonic (
mnemonicString ,
mnemonic _wordsetName ,
nettype ,
fn , // made available via callback not because it's async but for convenience
) {
// fn: (err?, seed?, keys?)
const payload = SeedAndKeysFromMnemonic _sync (
mnemonicString ,
mnemonic _wordsetName ,
nettype ,
) ;
const err = payload . err _str ? new Error ( payload . err _str ) : null ;
const seed = payload . seed ;
const keys = payload . keys ;
fn ( err , seed , keys ) ;
fn (
payload . err _str ? new Error ( payload . err _str ) : null ,
payload . mnemonic _language ,
payload . seed ,
payload . keys
) ;
}
exports . SeedAndKeysFromMnemonic = SeedAndKeysFromMnemonic ;
//