Merge pull request #14289 from MetaMask/master-sync
Sync `develop` with `master`feature/default_network_editable
commit
e9a815e477
@ -0,0 +1,99 @@ |
|||||||
|
diff --git a/node_modules/bip39/index.js b/node_modules/bip39/index.js
|
||||||
|
index aa0f29f..bee8008 100644
|
||||||
|
--- a/node_modules/bip39/index.js
|
||||||
|
+++ b/node_modules/bip39/index.js
|
||||||
|
@@ -48,7 +48,9 @@ function salt (password) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function mnemonicToSeed (mnemonic, password) {
|
||||||
|
- var mnemonicBuffer = Buffer.from(unorm.nfkd(mnemonic), 'utf8')
|
||||||
|
+ var mnemonicBuffer = typeof mnemonic === 'string'
|
||||||
|
+ ? Buffer.from(unorm.nfkd(mnemonic), 'utf8')
|
||||||
|
+ : mnemonic
|
||||||
|
var saltBuffer = Buffer.from(salt(unorm.nfkd(password)), 'utf8')
|
||||||
|
|
||||||
|
return pbkdf2(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512')
|
||||||
|
@@ -61,12 +63,28 @@ function mnemonicToSeedHex (mnemonic, password) {
|
||||||
|
function mnemonicToEntropy (mnemonic, wordlist) {
|
||||||
|
wordlist = wordlist || DEFAULT_WORDLIST
|
||||||
|
|
||||||
|
- var words = unorm.nfkd(mnemonic).split(' ')
|
||||||
|
+ var mnemonicAsBuffer = typeof mnemonic === 'string'
|
||||||
|
+ ? Buffer.from(unorm.nfkd(mnemonic), 'utf8')
|
||||||
|
+ : mnemonic
|
||||||
|
+
|
||||||
|
+ var words = [];
|
||||||
|
+ var currentWord = [];
|
||||||
|
+ for (const byte of mnemonicAsBuffer.values()) {
|
||||||
|
+ // split at space or \u3000 (ideographic space, for Japanese wordlists)
|
||||||
|
+ if (byte === 0x20 || byte === 0x3000) {
|
||||||
|
+ words.push(Buffer.from(currentWord));
|
||||||
|
+ currentWord = [];
|
||||||
|
+ } else {
|
||||||
|
+ currentWord.push(byte);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ words.push(Buffer.from(currentWord));
|
||||||
|
+
|
||||||
|
if (words.length % 3 !== 0) throw new Error(INVALID_MNEMONIC)
|
||||||
|
|
||||||
|
// convert word indices to 11 bit binary strings
|
||||||
|
var bits = words.map(function (word) {
|
||||||
|
- var index = wordlist.indexOf(word)
|
||||||
|
+ var index = wordlist.indexOf(word.toString('utf8'))
|
||||||
|
if (index === -1) throw new Error(INVALID_MNEMONIC)
|
||||||
|
|
||||||
|
return lpad(index.toString(2), '0', 11)
|
||||||
|
@@ -104,12 +122,41 @@ function entropyToMnemonic (entropy, wordlist) {
|
||||||
|
|
||||||
|
var bits = entropyBits + checksumBits
|
||||||
|
var chunks = bits.match(/(.{1,11})/g)
|
||||||
|
- var words = chunks.map(function (binary) {
|
||||||
|
+ var wordsAsBuffers = chunks.map(function (binary) {
|
||||||
|
var index = binaryToByte(binary)
|
||||||
|
- return wordlist[index]
|
||||||
|
+ return Buffer.from(wordlist[index], 'utf8')
|
||||||
|
})
|
||||||
|
|
||||||
|
- return wordlist === JAPANESE_WORDLIST ? words.join('\u3000') : words.join(' ')
|
||||||
|
+ var bufferSize = wordsAsBuffers.reduce(function (bufferSize, wordAsBuffer, i) {
|
||||||
|
+ var shouldAddSeparator = i < wordsAsBuffers.length - 1
|
||||||
|
+ return (
|
||||||
|
+ bufferSize +
|
||||||
|
+ wordAsBuffer.length +
|
||||||
|
+ (shouldAddSeparator ? 1 : 0)
|
||||||
|
+ )
|
||||||
|
+ }, 0)
|
||||||
|
+ var separator = wordlist === JAPANESE_WORDLIST ? '\u3000' : ' '
|
||||||
|
+ var result = wordsAsBuffers.reduce(function (result, wordAsBuffer, i) {
|
||||||
|
+ var shouldAddSeparator = i < wordsAsBuffers.length - 1
|
||||||
|
+ result.workingBuffer.set(wordAsBuffer, result.offset)
|
||||||
|
+ if (shouldAddSeparator) {
|
||||||
|
+ result.workingBuffer.write(
|
||||||
|
+ separator,
|
||||||
|
+ result.offset + wordAsBuffer.length,
|
||||||
|
+ separator.length,
|
||||||
|
+ 'utf8'
|
||||||
|
+ )
|
||||||
|
+ }
|
||||||
|
+ return {
|
||||||
|
+ workingBuffer: result.workingBuffer,
|
||||||
|
+ offset: (
|
||||||
|
+ result.offset +
|
||||||
|
+ wordAsBuffer.length +
|
||||||
|
+ (shouldAddSeparator ? 1 : 0)
|
||||||
|
+ )
|
||||||
|
+ }
|
||||||
|
+ }, { workingBuffer: Buffer.alloc(bufferSize), offset: 0 })
|
||||||
|
+ return result.workingBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateMnemonic (strength, rng, wordlist) {
|
||||||
|
@@ -124,6 +171,7 @@ function validateMnemonic (mnemonic, wordlist) {
|
||||||
|
try {
|
||||||
|
mnemonicToEntropy(mnemonic, wordlist)
|
||||||
|
} catch (e) {
|
||||||
|
+ console.log('could not validate mnemonic', e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
diff --git a/node_modules/eth-hd-keyring/index.js b/node_modules/eth-hd-keyring/index.js
|
||||||
|
index 19d1d7f..350d6b8 100644
|
||||||
|
--- a/node_modules/eth-hd-keyring/index.js
|
||||||
|
+++ b/node_modules/eth-hd-keyring/index.js
|
||||||
|
@@ -17,8 +17,11 @@ class HdKeyring extends SimpleKeyring {
|
||||||
|
}
|
||||||
|
|
||||||
|
serialize () {
|
||||||
|
+ const mnemonicAsBuffer = typeof this.mnemonic === 'string'
|
||||||
|
+ ? Buffer.from(this.mnemonic, 'utf8')
|
||||||
|
+ : this.mnemonic
|
||||||
|
return Promise.resolve({
|
||||||
|
- mnemonic: this.mnemonic,
|
||||||
|
+ mnemonic: Array.from(mnemonicAsBuffer.values()),
|
||||||
|
numberOfAccounts: this.wallets.length,
|
||||||
|
hdPath: this.hdPath,
|
||||||
|
})
|
||||||
|
@@ -69,9 +72,22 @@ class HdKeyring extends SimpleKeyring {
|
||||||
|
|
||||||
|
/* PRIVATE METHODS */
|
||||||
|
|
||||||
|
- _initFromMnemonic (mnemonic) {
|
||||||
|
- this.mnemonic = mnemonic
|
||||||
|
- const seed = bip39.mnemonicToSeed(mnemonic)
|
||||||
|
+ /**
|
||||||
|
+ * Sets appropriate properties for the keyring based on the given
|
||||||
|
+ * BIP39-compliant mnemonic.
|
||||||
|
+ *
|
||||||
|
+ * @param {string|Array<number>|Buffer} mnemonic - A seed phrase represented
|
||||||
|
+ * as a string, an array of UTF-8 bytes, or a Buffer.
|
||||||
|
+ */
|
||||||
|
+ _initFromMnemonic(mnemonic) {
|
||||||
|
+ if (typeof mnemonic === 'string') {
|
||||||
|
+ this.mnemonic = Buffer.from(mnemonic, 'utf8')
|
||||||
|
+ } else if (Array.isArray(mnemonic)) {
|
||||||
|
+ this.mnemonic = Buffer.from(mnemonic)
|
||||||
|
+ } else {
|
||||||
|
+ this.mnemonic = mnemonic
|
||||||
|
+ }
|
||||||
|
+ const seed = bip39.mnemonicToSeed(this.mnemonic)
|
||||||
|
this.hdWallet = hdkey.fromMasterSeed(seed)
|
||||||
|
this.root = this.hdWallet.derivePath(this.hdPath)
|
||||||
|
}
|
@ -0,0 +1,37 @@ |
|||||||
|
diff --git a/node_modules/eth-keyring-controller/index.js b/node_modules/eth-keyring-controller/index.js
|
||||||
|
index 250ab98..38615aa 100644
|
||||||
|
--- a/node_modules/eth-keyring-controller/index.js
|
||||||
|
+++ b/node_modules/eth-keyring-controller/index.js
|
||||||
|
@@ -84,15 +84,20 @@ class KeyringController extends EventEmitter {
|
||||||
|
*
|
||||||
|
* @emits KeyringController#unlock
|
||||||
|
* @param {string} password - The password to encrypt the vault with
|
||||||
|
- * @param {string} seed - The BIP44-compliant seed phrase.
|
||||||
|
+ * @param {string|Array<number>} seedPhrase - The BIP39-compliant seed phrase,
|
||||||
|
+ * either as a string or an array of UTF-8 bytes that represent the string.
|
||||||
|
* @returns {Promise<Object>} A Promise that resolves to the state.
|
||||||
|
*/
|
||||||
|
- createNewVaultAndRestore (password, seed) {
|
||||||
|
+ createNewVaultAndRestore(password, seedPhrase) {
|
||||||
|
+ const seedPhraseAsBuffer = typeof seedPhrase === 'string'
|
||||||
|
+ ? Buffer.from(seedPhrase, 'utf8')
|
||||||
|
+ : Buffer.from(seedPhrase)
|
||||||
|
+
|
||||||
|
if (typeof password !== 'string') {
|
||||||
|
return Promise.reject(new Error('Password must be text.'))
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!bip39.validateMnemonic(seed)) {
|
||||||
|
+ if (!bip39.validateMnemonic(seedPhraseAsBuffer)) {
|
||||||
|
return Promise.reject(new Error('Seed phrase is invalid.'))
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -101,7 +106,7 @@ class KeyringController extends EventEmitter {
|
||||||
|
return this.persistAllKeyrings(password)
|
||||||
|
.then(() => {
|
||||||
|
return this.addNewKeyring('HD Key Tree', {
|
||||||
|
- mnemonic: seed,
|
||||||
|
+ mnemonic: seedPhraseAsBuffer,
|
||||||
|
numberOfAccounts: 1,
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in new issue