aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorfrankiebee <frankie.diamond@gmail.com>2018-03-14 06:27:26 +0800
committerfrankiebee <frankie.diamond@gmail.com>2018-03-14 06:27:26 +0800
commita2c14ad02b6f080efe18535d64efe4acdaa5f310 (patch)
treea4f10bab758b35c5344557907c7c95a396e4fbb9 /app
parentc465d510b100fdf9926413751df04cbd59de68eb (diff)
parentc83a9ceb04a485149fe65fbb2b44f0adeda696b1 (diff)
downloadtangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar.gz
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar.bz2
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar.lz
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar.xz
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.tar.zst
tangerine-wallet-browser-a2c14ad02b6f080efe18535d64efe4acdaa5f310.zip
Merge remote-tracking branch 'origin/i#3509' into i#3509
Diffstat (limited to 'app')
-rw-r--r--app/_locales/en/messages.json605
-rw-r--r--app/manifest.json12
-rw-r--r--app/scripts/controllers/transactions.js4
-rw-r--r--app/scripts/lib/seed-phrase-verifier.js48
-rw-r--r--app/scripts/lib/tx-state-manager.js2
-rw-r--r--app/scripts/metamask-controller.js53
6 files changed, 703 insertions, 21 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 8c28f1c43..1ca31427d 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1,10 +1,609 @@
{
+ "accept": {
+ "message": "Accept"
+ },
+ "account": {
+ "message": "Account"
+ },
+ "accountDetails": {
+ "message": "Account Details"
+ },
+ "accountName": {
+ "message": "Account Name"
+ },
+ "address": {
+ "message": "Address"
+ },
+ "addToken": {
+ "message": "Add Token"
+ },
+ "amount": {
+ "message": "Amount"
+ },
+ "amountPlusGas": {
+ "message": "Amount + Gas"
+ },
+ "appDescription": {
+ "message": "Ethereum Browser Extension",
+ "description": "The description of the application"
+ },
"appName": {
"message": "MetaMask",
"description": "The name of the application"
},
- "appDescription": {
- "message": "Ethereum Identity Management",
- "description": "The description of the application"
+ "attemptingConnect": {
+ "message": "Attempting to connect to blockchain."
+ },
+ "available": {
+ "message": "Available"
+ },
+ "back": {
+ "message": "Back"
+ },
+ "balance": {
+ "message": "Balance:"
+ },
+ "balanceIsInsufficientGas": {
+ "message": "Insufficient balance for current gas total"
+ },
+ "beta": {
+ "message": "BETA"
+ },
+ "betweenMinAndMax": {
+ "message": "must be greater than or equal to $1 and less than or equal to $2.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "borrowDharma": {
+ "message": "Borrow With Dharma (Beta)"
+ },
+ "buy": {
+ "message": "Buy"
+ },
+ "buyCoinbase": {
+ "message": "Buy on Coinbase"
+ },
+ "buyCoinbaseExplainer": {
+ "message": "Coinbase is the world’s most popular way to buy and sell bitcoin, ethereum, and litecoin."
+ },
+ "cancel": {
+ "message": "Cancel"
+ },
+ "clickCopy": {
+ "message": "Click to Copy"
+ },
+ "confirm": {
+ "message": "Confirm"
+ },
+ "confirmContract": {
+ "message": "Confirm Contract"
+ },
+ "confirmPassword": {
+ "message": "Confirm Password"
+ },
+ "confirmTransaction": {
+ "message": "Confirm Transaction"
+ },
+ "continueToCoinbase": {
+ "message": "Continue to Coinbase"
+ },
+ "contractDeployment": {
+ "message": "Contract Deployment"
+ },
+ "conversionProgress": {
+ "message": "Conversion in progress"
+ },
+ "copiedButton": {
+ "message": "Copied"
+ },
+ "copiedClipboard": {
+ "message": "Copied to Clipboard"
+ },
+ "copiedExclamation": {
+ "message": "Copied!"
+ },
+ "copy": {
+ "message": "Copy"
+ },
+ "copyToClipboard": {
+ "message": "Copy to clipboard"
+ },
+ "copyButton": {
+ "message": " Copy "
+ },
+ "copyPrivateKey": {
+ "message": "This is your private key (click to copy)"
+ },
+ "create": {
+ "message": "Create"
+ },
+ "createAccount": {
+ "message": "Create Account"
+ },
+ "createDen": {
+ "message": "Create"
+ },
+ "crypto": {
+ "message": "Crypto",
+ "description": "Exchange type (cryptocurrencies)"
+ },
+ "customGas": {
+ "message": "Customize Gas"
+ },
+ "customize": {
+ "message": "Customize"
+ },
+ "customRPC": {
+ "message": "Custom RPC"
+ },
+ "defaultNetwork": {
+ "message": "The default network for Ether transactions is Main Net."
+ },
+ "denExplainer": {
+ "message": "Your DEN is your password-encrypted storage within MetaMask."
+ },
+ "deposit": {
+ "message": "Deposit"
+ },
+ "depositBTC": {
+ "message": "Deposit your BTC to the address below:"
+ },
+ "depositCoin": {
+ "message": "Deposit your $1 to the address below",
+ "description": "Tells the user what coin they have selected to deposit with shapeshift"
+ },
+ "depositEth": {
+ "message": "Deposit Eth"
+ },
+ "depositEther": {
+ "message": "Deposit Ether"
+ },
+ "depositFiat": {
+ "message": "Deposit with Fiat"
+ },
+ "depositFromAccount": {
+ "message": "Deposit from another account"
+ },
+ "depositShapeShift": {
+ "message": "Deposit with ShapeShift"
+ },
+ "depositShapeShiftExplainer": {
+ "message": "If you own other cryptocurrencies, you can trade and deposit Ether directly into your MetaMask wallet. No Account Needed."
+ },
+ "details": {
+ "message": "Details"
+ },
+ "directDeposit": {
+ "message": "Direct Deposit"
+ },
+ "directDepositEther": {
+ "message": "Directly Deposit Ether"
+ },
+ "directDepositEtherExplainer": {
+ "message": "If you already have some Ether, the quickest way to get Ether in your new wallet by direct deposit."
+ },
+ "done": {
+ "message": "Done"
+ },
+ "edit": {
+ "message": "Edit"
+ },
+ "editAccountName": {
+ "message": "Edit Account Name"
+ },
+ "encryptNewDen": {
+ "message": "Encrypt your new DEN"
+ },
+ "enterPassword": {
+ "message": "Enter password"
+ },
+ "etherscanView": {
+ "message": "View account on Etherscan"
+ },
+ "exchangeRate": {
+ "message": "Exchange Rate"
+ },
+ "exportPrivateKey": {
+ "message": "Export Private Key"
+ },
+ "exportPrivateKeyWarning": {
+ "message": "Export private keys at your own risk."
+ },
+ "failed": {
+ "message": "Failed"
+ },
+ "fiat": {
+ "message": "FIAT",
+ "description": "Exchange type"
+ },
+ "fileImportFail": {
+ "message": "File import not working? Click here!",
+ "description": "Helps user import their account from a JSON file"
+ },
+ "from": {
+ "message": "From"
+ },
+ "fromShapeShift": {
+ "message": "From ShapeShift"
+ },
+ "gas": {
+ "message": "Gas",
+ "description": "Short indication of gas cost"
+ },
+ "gasFee": {
+ "message": "Gas Fee"
+ },
+ "gasLimit": {
+ "message": "Gas Limit"
+ },
+ "gasLimitCalculation": {
+ "message": "We calculate the suggested gas limit based on network success rates."
+ },
+ "gasLimitRequired": {
+ "message": "Gas Limit Required"
+ },
+ "gasLimitTooLow": {
+ "message": "Gas limit must be at least 21000"
+ },
+ "gasPrice": {
+ "message": "Gas Price (GWEI)"
+ },
+ "gasPriceCalculation": {
+ "message": "We calculate the suggested gas prices based on network success rates."
+ },
+ "gasPriceRequired": {
+ "message": "Gas Price Required"
+ },
+ "getEther": {
+ "message": "Get Ether"
+ },
+ "getEtherFromFaucet": {
+ "message": "Get Ether from a faucet for the $1",
+ "description": "Displays network name for Ether faucet"
+ },
+ "greaterThanMin": {
+ "message": "must be greater than or equal to $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "here": {
+ "message": "here",
+ "description": "as in -click here- for more information (goes with troubleTokenBalances)"
+ },
+ "hide": {
+ "message": "Hide"
+ },
+ "hideToken": {
+ "message": "Hide Token"
+ },
+ "hideTokenPrompt": {
+ "message": "Hide Token?"
+ },
+ "howToDeposit": {
+ "message": "How would you like to deposit Ether?"
+ },
+ "import": {
+ "message": "Import",
+ "description": "Button to import an account from a selected file"
+ },
+ "importAccount": {
+ "message": "Import Account"
+ },
+ "importAnAccount": {
+ "message": "Import an account"
+ },
+ "importDen": {
+ "message": "Import Existing DEN"
+ },
+ "imported": {
+ "message": "Imported",
+ "description": "status showing that an account has been fully loaded into the keyring"
+ },
+ "infoHelp": {
+ "message": "Info & Help"
+ },
+ "invalidAddress": {
+ "message": "Invalid address"
+ },
+ "invalidGasParams": {
+ "message": "Invalid Gas Parameters"
+ },
+ "invalidInput": {
+ "message": "Invalid input."
+ },
+ "invalidRequest": {
+ "message": "Invalid Request"
+ },
+ "jsonFile": {
+ "message": "JSON File",
+ "description": "format for importing an account"
+ },
+ "kovan": {
+ "message": "Kovan Test Network"
+ },
+ "lessThanMax": {
+ "message": "must be less than or equal to $1.",
+ "description": "helper for inputting hex as decimal input"
+ },
+ "limit": {
+ "message": "Limit"
+ },
+ "loading": {
+ "message": "Loading..."
+ },
+ "loadingTokens": {
+ "message": "Loading Tokens..."
+ },
+ "localhost": {
+ "message": "Localhost 8545"
+ },
+ "logout": {
+ "message": "Log out"
+ },
+ "loose": {
+ "message": "Loose"
+ },
+ "mainnet": {
+ "message": "Main Ethereum Network"
+ },
+ "message": {
+ "message": "Message"
+ },
+ "min": {
+ "message": "Minimum"
+ },
+ "myAccounts": {
+ "message": "My Accounts"
+ },
+ "needEtherInWallet": {
+ "message": "To interact with decentralized applications using MetaMask, you’ll need Ether in your wallet."
+ },
+ "needImportFile": {
+ "message": "You must select a file to import.",
+ "description": "User is important an account and needs to add a file to continue"
+ },
+ "needImportPassword": {
+ "message": "You must enter a password for the selected file.",
+ "description": "Password and file needed to import an account"
+ },
+ "networks": {
+ "message": "Networks"
+ },
+ "newAccount": {
+ "message": "New Account"
+ },
+ "newAccountNumberName": {
+ "message": "Account $1",
+ "description": "Default name of next account to be created on create account screen"
+ },
+ "newContract": {
+ "message": "New Contract"
+ },
+ "newPassword": {
+ "message": "New Password (min 8 chars)"
+ },
+ "newRecipient": {
+ "message": "New Recipient"
+ },
+ "next": {
+ "message": "Next"
+ },
+ "noAddressForName": {
+ "message": "No address has been set for this name."
+ },
+ "noDeposits": {
+ "message": "No deposits received"
+ },
+ "noTransactionHistory": {
+ "message": "No transaction history."
+ },
+ "noTransactions": {
+ "message": "No Transactions"
+ },
+ "notStarted": {
+ "message": "Not Started"
+ },
+ "oldUI": {
+ "message": "Old UI"
+ },
+ "oldUIMessage": {
+ "message": "You have returned to the old UI. You can switch back to the New UI through the option in the top right dropdown menu."
+ },
+ "or": {
+ "message": "or",
+ "description": "choice between creating or importing a new account"
+ },
+ "passwordMismatch": {
+ "message": "passwords don't match",
+ "description": "in password creation process, the two new password fields did not match"
+ },
+ "passwordShort": {
+ "message": "password not long enough",
+ "description": "in password creation process, the password is not long enough to be secure"
+ },
+ "pastePrivateKey": {
+ "message": "Paste your private key string here:",
+ "description": "For importing an account from a private key"
+ },
+ "pasteSeed": {
+ "message": "Paste your seed phrase here!"
+ },
+ "pleaseReviewTransaction": {
+ "message": "Please review your transaction."
+ },
+ "privateKey": {
+ "message": "Private Key",
+ "description": "select this type of file to use to import an account"
+ },
+ "privateKeyWarning": {
+ "message": "Warning: Never disclose this key. Anyone with your private keys can take steal any assets held in your account."
+ },
+ "privateNetwork": {
+ "message": "Private Network"
+ },
+ "qrCode": {
+ "message": "Show QR Code"
+ },
+ "readdToken": {
+ "message": "You can add this token back in the future by going go to “Add token” in your accounts options menu."
+ },
+ "readMore": {
+ "message": "Read more here."
+ },
+ "receive": {
+ "message": "Receive"
+ },
+ "recipientAddress": {
+ "message": "Recipient Address"
+ },
+ "refundAddress": {
+ "message": "Your Refund Address"
+ },
+ "rejected": {
+ "message": "Rejected"
+ },
+ "required": {
+ "message": "Required"
+ },
+ "retryWithMoreGas": {
+ "message": "Retry with a higher gas price here"
+ },
+ "revert": {
+ "message": "Revert"
+ },
+ "rinkeby": {
+ "message": "Rinkeby Test Network"
+ },
+ "ropsten": {
+ "message": "Ropsten Test Network"
+ },
+ "sampleAccountName": {
+ "message": "E.g. My new account",
+ "description": "Help user understand concept of adding a human-readable name to their account"
+ },
+ "save": {
+ "message": "Save"
+ },
+ "saveAsFile": {
+ "message": "Save as File",
+ "description": "Account export process"
+ },
+ "selectService": {
+ "message": "Select Service"
+ },
+ "send": {
+ "message": "Send"
+ },
+ "sendTokens": {
+ "message": "Send Tokens"
+ },
+ "sendTokensAnywhere": {
+ "message": "Send Tokens to anyone with an Ethereum account"
+ },
+ "settings": {
+ "message": "Settings"
+ },
+ "shapeshiftBuy": {
+ "message": "Buy with Shapeshift"
+ },
+ "showPrivateKeys": {
+ "message": "Show Private Keys"
+ },
+ "showQRCode": {
+ "message": "Show QR Code"
+ },
+ "sign": {
+ "message": "Sign"
+ },
+ "signMessage": {
+ "message": "Sign Message"
+ },
+ "signNotice": {
+ "message": "Signing this message can have \ndangerous side effects. Only sign messages from \nsites you fully trust with your entire account.\n This dangerous method will be removed in a future version. "
+ },
+ "sigRequest": {
+ "message": "Signature Request"
+ },
+ "sigRequested": {
+ "message": "Signature Requested"
+ },
+ "status": {
+ "message": "Status"
+ },
+ "submit": {
+ "message": "Submit"
+ },
+ "takesTooLong": {
+ "message": "Taking too long?"
+ },
+ "testFaucet": {
+ "message": "Test Faucet"
+ },
+ "to": {
+ "message": "To"
+ },
+ "toETHviaShapeShift": {
+ "message": "$1 to ETH via ShapeShift",
+ "description": "system will fill in deposit type in start of message"
+ },
+ "tokenBalance": {
+ "message": "Your Token Balance is:"
+ },
+ "total": {
+ "message": "Total"
+ },
+ "transactionMemo": {
+ "message": "Transaction memo (optional)"
+ },
+ "transactionNumber": {
+ "message": "Transaction Number"
+ },
+ "transfers": {
+ "message": "Transfers"
+ },
+ "troubleTokenBalances": {
+ "message": "We had trouble loading your token balances. You can view them ",
+ "description": "Followed by a link (here) to view token balances"
+ },
+ "typePassword": {
+ "message": "Type Your Password"
+ },
+ "uiWelcome": {
+ "message": "Welcome to the New UI (Beta)"
+ },
+ "uiWelcomeMessage": {
+ "message": "You are now using the new Metamask UI. Take a look around, try out new features like sending tokens, and let us know if you have any issues."
+ },
+ "unavailable": {
+ "message": "Unavailable"
+ },
+ "unknown": {
+ "message": "Unknown"
+ },
+ "unknownNetwork": {
+ "message": "Unknown Private Network"
+ },
+ "unknownNetworkId": {
+ "message": "Unknown network ID"
+ },
+ "usaOnly": {
+ "message": "USA only",
+ "description": "Using this exchange is limited to people inside the USA"
+ },
+ "usedByClients": {
+ "message": "Used by a variety of different clients"
+ },
+ "viewAccount": {
+ "message": "View Account"
+ },
+ "warning": {
+ "message": "Warning"
+ },
+ "whatsThis": {
+ "message": "What's this?"
+ },
+ "yourSigRequested": {
+ "message": "Your signature is being requested"
+ },
+ "youSign": {
+ "message": "You are signing"
}
}
diff --git a/app/manifest.json b/app/manifest.json
index 2b3acf1b5..6c5ed686b 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,10 +1,10 @@
{
- "name": "MetaMask",
- "short_name": "Metamask",
- "version": "4.1.3",
+ "name": "__MSG_appName__",
+ "short_name": "__MSG_appName__",
+ "version": "4.2.0",
"manifest_version": 2,
"author": "https://metamask.io",
- "description": "Ethereum Browser Extension",
+ "description": "__MSG_appDescription__",
"commands": {
"_execute_browser_action": {
"suggested_key": {
@@ -59,7 +59,7 @@
"clipboardWrite",
"http://localhost:8545/",
"https://*.infura.io/"
- ],
+ ],
"web_accessible_resources": [
"scripts/inpage.js"
],
@@ -68,4 +68,4 @@
"https://metamask.io/*"
]
}
-}
+} \ No newline at end of file
diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js
index ef5578d5a..9c2ca0dc8 100644
--- a/app/scripts/controllers/transactions.js
+++ b/app/scripts/controllers/transactions.js
@@ -3,7 +3,7 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const Transaction = require('ethereumjs-tx')
const EthQuery = require('ethjs-query')
-const TransactionStateManger = require('../lib/tx-state-manager')
+const TransactionStateManager = require('../lib/tx-state-manager')
const TxGasUtil = require('../lib/tx-gas-utils')
const PendingTransactionTracker = require('../lib/pending-tx-tracker')
const createId = require('../lib/random-id')
@@ -38,7 +38,7 @@ module.exports = class TransactionController extends EventEmitter {
this.query = new EthQuery(this.provider)
this.txGasUtil = new TxGasUtil(this.provider)
- this.txStateManager = new TransactionStateManger({
+ this.txStateManager = new TransactionStateManager({
initState: opts.initState,
txHistoryLimit: opts.txHistoryLimit,
getNetwork: this.getNetwork.bind(this),
diff --git a/app/scripts/lib/seed-phrase-verifier.js b/app/scripts/lib/seed-phrase-verifier.js
new file mode 100644
index 000000000..9cea22029
--- /dev/null
+++ b/app/scripts/lib/seed-phrase-verifier.js
@@ -0,0 +1,48 @@
+const KeyringController = require('eth-keyring-controller')
+
+const seedPhraseVerifier = {
+
+ // Verifies if the seed words can restore the accounts.
+ //
+ // The seed words can recreate the primary keyring and the accounts belonging to it.
+ // The created accounts in the primary keyring are always the same.
+ // The keyring always creates the accounts in the same sequence.
+ verifyAccounts (createdAccounts, seedWords) {
+
+ return new Promise((resolve, reject) => {
+
+ if (!createdAccounts || createdAccounts.length < 1) {
+ return reject(new Error('No created accounts defined.'))
+ }
+
+ const keyringController = new KeyringController({})
+ const Keyring = keyringController.getKeyringClassForType('HD Key Tree')
+ const opts = {
+ mnemonic: seedWords,
+ numberOfAccounts: createdAccounts.length,
+ }
+
+ const keyring = new Keyring(opts)
+ keyring.getAccounts()
+ .then((restoredAccounts) => {
+
+ log.debug('Created accounts: ' + JSON.stringify(createdAccounts))
+ log.debug('Restored accounts: ' + JSON.stringify(restoredAccounts))
+
+ if (restoredAccounts.length !== createdAccounts.length) {
+ // this should not happen...
+ return reject(new Error('Wrong number of accounts'))
+ }
+
+ for (let i = 0; i < restoredAccounts.length; i++) {
+ if (restoredAccounts[i].toLowerCase() !== createdAccounts[i].toLowerCase()) {
+ return reject(new Error('Not identical accounts! Original: ' + createdAccounts[i] + ', Restored: ' + restoredAccounts[i]))
+ }
+ }
+ return resolve()
+ })
+ })
+ },
+}
+
+module.exports = seedPhraseVerifier
diff --git a/app/scripts/lib/tx-state-manager.js b/app/scripts/lib/tx-state-manager.js
index 051efd247..2eb006380 100644
--- a/app/scripts/lib/tx-state-manager.js
+++ b/app/scripts/lib/tx-state-manager.js
@@ -4,7 +4,7 @@ const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const txStateHistoryHelper = require('./tx-state-history-helper')
-module.exports = class TransactionStateManger extends EventEmitter {
+module.exports = class TransactionStateManager extends EventEmitter {
constructor ({ initState, txHistoryLimit, getNetwork }) {
super()
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index ad4e71792..0a5c1d36f 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -37,6 +37,7 @@ const version = require('../manifest.json').version
const BN = require('ethereumjs-util').BN
const GWEI_BN = new BN('1000000000')
const percentile = require('percentile')
+const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
module.exports = class MetamaskController extends EventEmitter {
@@ -344,6 +345,7 @@ module.exports = class MetamaskController extends EventEmitter {
// primary HD keyring management
addNewAccount: nodeify(this.addNewAccount, this),
placeSeedWords: this.placeSeedWords.bind(this),
+ verifySeedPhrase: nodeify(this.verifySeedPhrase, this),
clearSeedWordCache: this.clearSeedWordCache.bind(this),
resetAccount: this.resetAccount.bind(this),
importAccountWithStrategy: this.importAccountWithStrategy.bind(this),
@@ -565,14 +567,18 @@ module.exports = class MetamaskController extends EventEmitter {
// Opinionated Keyring Management
//
- async addNewAccount (cb) {
+ async addNewAccount () {
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
- if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
+ if (!primaryKeyring) {
+ throw new Error('MetamaskController - No HD Key Tree found')
+ }
const keyringController = this.keyringController
const oldAccounts = await keyringController.getAccounts()
const keyState = await keyringController.addNewAccount(primaryKeyring)
const newAccounts = await keyringController.getAccounts()
+ await this.verifySeedPhrase()
+
newAccounts.forEach((address) => {
if (!oldAccounts.includes(address)) {
this.preferencesController.setSelectedAddress(address)
@@ -587,14 +593,43 @@ module.exports = class MetamaskController extends EventEmitter {
// Used when creating a first vault, to allow confirmation.
// Also used when revealing the seed words in the confirmation view.
placeSeedWords (cb) {
+
+ this.verifySeedPhrase()
+ .then((seedWords) => {
+ this.configManager.setSeedWords(seedWords)
+ return cb(null, seedWords)
+ })
+ .catch((err) => {
+ return cb(err)
+ })
+ }
+
+ // Verifies the current vault's seed words if they can restore the
+ // accounts belonging to the current vault.
+ //
+ // Called when the first account is created and on unlocking the vault.
+ async verifySeedPhrase () {
+
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
- if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
- primaryKeyring.serialize()
- .then((serialized) => {
- const seedWords = serialized.mnemonic
- this.configManager.setSeedWords(seedWords)
- cb(null, seedWords)
- })
+ if (!primaryKeyring) {
+ throw new Error('MetamaskController - No HD Key Tree found')
+ }
+
+ const serialized = await primaryKeyring.serialize()
+ const seedWords = serialized.mnemonic
+
+ const accounts = await primaryKeyring.getAccounts()
+ if (accounts.length < 1) {
+ throw new Error('MetamaskController - No accounts found')
+ }
+
+ try {
+ await seedPhraseVerifier.verifyAccounts(accounts, seedWords)
+ return seedWords
+ } catch (err) {
+ log.error(err.message)
+ throw err
+ }
}
// ClearSeedWordCache