From 58a554b1684fd78775b449b8f2b5d9635d30b69b Mon Sep 17 00:00:00 2001 From: Lazaridis Date: Sun, 11 Feb 2018 05:09:27 +0200 Subject: use the providers initial _blocktracker. fixes #2393 --- app/scripts/metamask-controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 63815ab65..428c78e2c 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -444,7 +444,7 @@ module.exports = class MetamaskController extends EventEmitter { // create filter polyfill middleware const filterMiddleware = createFilterMiddleware({ provider: this.provider, - blockTracker: this.blockTracker, + blockTracker: this.provider._blockTracker, }) engine.push(createOriginMiddleware({ origin })) -- cgit From 92453f8715b78c0e6e2cdb9b2e1cfe48c0b013ad Mon Sep 17 00:00:00 2001 From: Csaba Solya Date: Sat, 3 Mar 2018 00:32:57 +0100 Subject: seed phrase verifier --- app/scripts/metamask-controller.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index ad4e71792..89bcbd51b 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 { @@ -592,8 +593,23 @@ module.exports = class MetamaskController extends EventEmitter { primaryKeyring.serialize() .then((serialized) => { const seedWords = serialized.mnemonic - this.configManager.setSeedWords(seedWords) - cb(null, seedWords) + + primaryKeyring.getAccounts() + .then((accounts) => { + if (accounts.length < 1) { + return cb(new Error('MetamaskController - No accounts found')) + } + + seedPhraseVerifier.verifyAccounts(accounts, seedWords) + .then(() => { + this.configManager.setSeedWords(seedWords) + cb(null, seedWords) + }) + .catch((err) => { + log.error(err) + cb(err) + }) + }) }) } -- cgit From 4bd7f1a37abcd09dc8816fc5b28ad41bc86b1aea Mon Sep 17 00:00:00 2001 From: Csaba Solya Date: Sat, 3 Mar 2018 00:40:40 +0100 Subject: fix lint issues --- app/scripts/metamask-controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 89bcbd51b..b9231aa3d 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -599,9 +599,9 @@ module.exports = class MetamaskController extends EventEmitter { if (accounts.length < 1) { return cb(new Error('MetamaskController - No accounts found')) } - + seedPhraseVerifier.verifyAccounts(accounts, seedWords) - .then(() => { + .then(() => { this.configManager.setSeedWords(seedWords) cb(null, seedWords) }) -- cgit From 2b86d65d0c3266e8ddfe814abe1d1755fbf23fda Mon Sep 17 00:00:00 2001 From: Csaba Solya Date: Sat, 3 Mar 2018 22:08:10 +0100 Subject: verify seedwords on log in --- app/scripts/metamask-controller.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index b9231aa3d..df9adc248 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -345,6 +345,7 @@ module.exports = class MetamaskController extends EventEmitter { // primary HD keyring management addNewAccount: nodeify(this.addNewAccount, this), placeSeedWords: this.placeSeedWords.bind(this), + verifySeedPhrase: this.verifySeedPhrase.bind(this), clearSeedWordCache: this.clearSeedWordCache.bind(this), resetAccount: this.resetAccount.bind(this), importAccountWithStrategy: this.importAccountWithStrategy.bind(this), @@ -588,6 +589,19 @@ 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((err, seedWords) => { + + if (err) { + return cb(err) + } + this.configManager.setSeedWords(seedWords) + return cb(null, seedWords) + }) + } + + verifySeedPhrase (cb) { + const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found')) primaryKeyring.serialize() @@ -602,12 +616,11 @@ module.exports = class MetamaskController extends EventEmitter { seedPhraseVerifier.verifyAccounts(accounts, seedWords) .then(() => { - this.configManager.setSeedWords(seedWords) - cb(null, seedWords) + return cb(null, seedWords) }) .catch((err) => { log.error(err) - cb(err) + return cb(err) }) }) }) -- cgit From f7d4a1080df6d1c8ea5f68f88b01caea065b5e92 Mon Sep 17 00:00:00 2001 From: Csaba Solya Date: Sun, 4 Mar 2018 08:47:46 +0100 Subject: add documentation --- app/scripts/metamask-controller.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index df9adc248..f523e3919 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -600,6 +600,10 @@ module.exports = class MetamaskController extends EventEmitter { }) } + // 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. verifySeedPhrase (cb) { const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] -- cgit From 59007a6c36055f9197ad83ccb1741fa186b85f53 Mon Sep 17 00:00:00 2001 From: Csaba Solya Date: Tue, 6 Mar 2018 15:56:27 +0100 Subject: modify verifySeedPhrase to async and call it from addNewAccount also --- app/scripts/metamask-controller.js | 66 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f523e3919..0a5c1d36f 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -345,7 +345,7 @@ module.exports = class MetamaskController extends EventEmitter { // primary HD keyring management addNewAccount: nodeify(this.addNewAccount, this), placeSeedWords: this.placeSeedWords.bind(this), - verifySeedPhrase: this.verifySeedPhrase.bind(this), + verifySeedPhrase: nodeify(this.verifySeedPhrase, this), clearSeedWordCache: this.clearSeedWordCache.bind(this), resetAccount: this.resetAccount.bind(this), importAccountWithStrategy: this.importAccountWithStrategy.bind(this), @@ -567,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) @@ -590,44 +594,42 @@ module.exports = class MetamaskController extends EventEmitter { // Also used when revealing the seed words in the confirmation view. placeSeedWords (cb) { - this.verifySeedPhrase((err, seedWords) => { - - if (err) { + this.verifySeedPhrase() + .then((seedWords) => { + this.configManager.setSeedWords(seedWords) + return cb(null, seedWords) + }) + .catch((err) => { return cb(err) - } - this.configManager.setSeedWords(seedWords) - return cb(null, seedWords) - }) + }) } // 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. - verifySeedPhrase (cb) { + 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 - - primaryKeyring.getAccounts() - .then((accounts) => { - if (accounts.length < 1) { - return cb(new Error('MetamaskController - No accounts found')) - } - - seedPhraseVerifier.verifyAccounts(accounts, seedWords) - .then(() => { - return cb(null, seedWords) - }) - .catch((err) => { - log.error(err) - return cb(err) - }) - }) - }) + 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 -- cgit From d8f5150aa5bf4b04310f887504428f1caa13cbf4 Mon Sep 17 00:00:00 2001 From: Lazaridis Date: Fri, 16 Mar 2018 00:27:10 +0200 Subject: adds initial documentation, re #3568 --- app/scripts/metamask-controller.js | 178 ++++++++++++++++++++++++++++--------- 1 file changed, 138 insertions(+), 40 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 0a5c1d36f..31c0bed58 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1,3 +1,9 @@ +/** + * @file The central metamask controller. Aggregates other controllers and exports an api. + * @copyright Copyright (c) 2018 MetaMask + * @license MIT + */ + const EventEmitter = require('events') const extend = require('xtend') const pump = require('pump') @@ -41,7 +47,11 @@ const seedPhraseVerifier = require('./lib/seed-phrase-verifier') module.exports = class MetamaskController extends EventEmitter { - constructor (opts) { + /** + * @constructor + * @param {Object} opts + */ + constructor (opts) { super() this.defaultMaxListeners = 20 @@ -223,10 +233,9 @@ module.exports = class MetamaskController extends EventEmitter { this.infuraController.store.subscribe(sendUpdate) } - // - // Constructor helpers - // - + /** + * Constructor helper: initialize a provider. + */ initializeProvider () { const providerOpts = { static: { @@ -257,6 +266,9 @@ module.exports = class MetamaskController extends EventEmitter { return providerProxy } + /** + * Constructor helper: initialize a public confi store. + */ initPublicConfigStore () { // get init state const publicConfigStore = new ObservableStore() @@ -282,6 +294,9 @@ module.exports = class MetamaskController extends EventEmitter { // State Management // + /** + * ? + */ getState () { const wallet = this.configManager.getWallet() const vault = this.keyringController.store.getState().vault @@ -319,7 +334,10 @@ module.exports = class MetamaskController extends EventEmitter { // // Remote Features // - + + /** + * ? + */ getApi () { const keyringController = this.keyringController const preferencesController = this.preferencesController @@ -517,10 +535,22 @@ module.exports = class MetamaskController extends EventEmitter { return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) } - // - // Vault Management - // - +//============================================================================= +// VAULT / KEYRING RELATED METHODS +//============================================================================= + + /** + * Creates a new Vault(?) and create a new keychain(?) + * + * A vault is ... + * + * A keychain is ... + * + * + * @param {} password + * + * @returns {} vault + */ async createNewVaultAndKeychain (password) { const release = await this.createVaultMutex.acquire() let vault @@ -544,6 +574,11 @@ module.exports = class MetamaskController extends EventEmitter { return vault } + /** + * Create a new Vault and restore an existent keychain + * @param {} password + * @param {} seed + */ async createNewVaultAndRestore (password, seed) { const release = await this.createVaultMutex.acquire() try { @@ -557,16 +592,28 @@ module.exports = class MetamaskController extends EventEmitter { } } + /** + * Retrieves the first Identiy from the passed Vault and selects the related address + * + * An Identity is ... + * + * @param {} vault + */ selectFirstIdentity (vault) { const { identities } = vault const address = Object.keys(identities)[0] this.preferencesController.setSelectedAddress(address) } - // + // ? // Opinionated Keyring Management // + /** + * Adds a new account to ... + * + * @returns {} keyState + */ async addNewAccount () { const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0] if (!primaryKeyring) { @@ -588,10 +635,12 @@ module.exports = class MetamaskController extends EventEmitter { return keyState } - // Adds the current vault's seed words to the UI's state tree. - // - // Used when creating a first vault, to allow confirmation. - // Also used when revealing the seed words in the confirmation view. + /** + * Adds the current vault's seed words to the UI's state tree. + * + * Used when creating a first vault, to allow confirmation. + * Also used when revealing the seed words in the confirmation view. + */ placeSeedWords (cb) { this.verifySeedPhrase() @@ -604,10 +653,13 @@ module.exports = class MetamaskController extends EventEmitter { }) } - // 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. + /** + * Verifies the validity of the current vault's seed phrase. + * + * Validity: seed phrase 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] @@ -632,22 +684,33 @@ module.exports = class MetamaskController extends EventEmitter { } } - // ClearSeedWordCache - // - // Removes the primary account's seed words from the UI's state tree, - // ensuring they are only ever available in the background process. + /** + * Remove the primary account seed phrase from the UI's state tree. + * + * The seed phrase remains available in the background process. + * + */ clearSeedWordCache (cb) { this.configManager.setSeedWords(null) cb(null, this.preferencesController.getSelectedAddress()) } - + + /** + * ? + */ resetAccount (cb) { const selectedAddress = this.preferencesController.getSelectedAddress() this.txController.wipeTransactions(selectedAddress) cb(null, selectedAddress) } - + /** + * Imports an account ... ? + * + * @param {} strategy + * @param {} args + * @param {} cb + */ importAccountWithStrategy (strategy, args, cb) { accountImporter.importAccount(strategy, args) .then((privateKey) => { @@ -659,11 +722,15 @@ module.exports = class MetamaskController extends EventEmitter { .catch((reason) => { cb(reason) }) } +//============================================================================= +// END (VAULT / KEYRING RELATED METHODS) +//============================================================================= - // - // Identity Management - // - // + + +//============================================================================= +// Identity Management +//============================================================================= async retryTransaction (txId, cb) { await this.txController.retryTransaction(txId) @@ -729,7 +796,11 @@ module.exports = class MetamaskController extends EventEmitter { } }) } - + + /** + * @param {} msgParams + * @param {} cb + */ signMessage (msgParams, cb) { log.info('MetaMaskController - signMessage') const msgId = msgParams.metamaskId @@ -758,6 +829,12 @@ module.exports = class MetamaskController extends EventEmitter { } // Prefixed Style Message Signing Methods: + + /** + * + * @param {} msgParams + * @param {} cb + */ approvePersonalMessage (msgParams, cb) { const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams) this.sendUpdate() @@ -773,7 +850,10 @@ module.exports = class MetamaskController extends EventEmitter { } }) } - + + /** + * @param {} msgParams + */ signPersonalMessage (msgParams) { log.info('MetaMaskController - signPersonalMessage') const msgId = msgParams.metamaskId @@ -791,7 +871,10 @@ module.exports = class MetamaskController extends EventEmitter { return this.getState() }) } - + + /** + * @param {} msgParams + */ signTypedMessage (msgParams) { log.info('MetaMaskController - signTypedMessage') const msgId = msgParams.metamaskId @@ -843,13 +926,23 @@ module.exports = class MetamaskController extends EventEmitter { this.sendUpdate() cb() } - + + /** + * ? + * + * @param {} migratorOutput + */ restoreOldVaultAccounts (migratorOutput) { const { serialized } = migratorOutput return this.keyringController.restoreKeyring(serialized) .then(() => migratorOutput) } + /** + * ? + * + * @param {} migratorOutput + */ restoreOldLostAccounts (migratorOutput) { const { lostAccounts } = migratorOutput if (lostAccounts) { @@ -859,10 +952,15 @@ module.exports = class MetamaskController extends EventEmitter { return Promise.resolve(migratorOutput) } - // IMPORT LOST ACCOUNTS - // @Object with key lostAccounts: @Array accounts <{ address, privateKey }> - // Uses the array's private keys to create a new Simple Key Pair keychain - // and add it to the keyring controller. + + /** + * Import (lost) Accounts + * + * @param {Object} {lostAccounts} @Array accounts <{ address, privateKey }> + * + * Uses the array's private keys to create a new Simple Key Pair keychain + * and add it to the keyring controller. + */ importLostAccounts ({ lostAccounts }) { const privKeys = lostAccounts.map(acct => acct.privateKey) return this.keyringController.restoreKeyring({ @@ -871,9 +969,9 @@ module.exports = class MetamaskController extends EventEmitter { }) } - // - // config - // +//============================================================================= +// CONFIG +//============================================================================= // Log blocks -- cgit From 904f00e8acf40a72d233d1776c8aa760026e1bd3 Mon Sep 17 00:00:00 2001 From: Lazaridis Date: Fri, 16 Mar 2018 02:29:53 +0200 Subject: group all vault/keyring related methods together, re #3568 --- app/scripts/metamask-controller.js | 258 +++++++++++++++++++------------------ 1 file changed, 130 insertions(+), 128 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 31c0bed58..cbdf757c6 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -267,7 +267,7 @@ module.exports = class MetamaskController extends EventEmitter { } /** - * Constructor helper: initialize a public confi store. + * Constructor helper: initialize a public config store. */ initPublicConfigStore () { // get init state @@ -290,12 +290,11 @@ module.exports = class MetamaskController extends EventEmitter { return publicConfigStore } - // - // State Management - // /** - * ? + * The metamask-state of the various controllers, made available to the UI + * + * @returns {Object} status */ getState () { const wallet = this.configManager.getWallet() @@ -331,12 +330,10 @@ module.exports = class MetamaskController extends EventEmitter { ) } - // - // Remote Features - // - /** - * ? + * Returns an api-object which is consumed by the UI + * + * @returns {Object} */ getApi () { const keyringController = this.keyringController @@ -656,7 +653,7 @@ module.exports = class MetamaskController extends EventEmitter { /** * Verifies the validity of the current vault's seed phrase. * - * Validity: seed phrase can restore the accounts belonging to the current vault. + * Validity: seed phrase restores the accounts belonging to the current vault. * * Called when the first account is created and on unlocking the vault. */ @@ -722,81 +719,9 @@ module.exports = class MetamaskController extends EventEmitter { .catch((reason) => { cb(reason) }) } -//============================================================================= -// END (VAULT / KEYRING RELATED METHODS) -//============================================================================= - - - -//============================================================================= -// Identity Management -//============================================================================= - - async retryTransaction (txId, cb) { - await this.txController.retryTransaction(txId) - const state = await this.getState() - return state - } - - - newUnsignedMessage (msgParams, cb) { - const msgId = this.messageManager.addUnapprovedMessage(msgParams) - this.sendUpdate() - this.opts.showUnconfirmedMessage() - this.messageManager.once(`${msgId}:finished`, (data) => { - switch (data.status) { - case 'signed': - return cb(null, data.rawSig) - case 'rejected': - return cb(new Error('MetaMask Message Signature: User denied message signature.')) - default: - return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) - } - }) - } - - newUnsignedPersonalMessage (msgParams, cb) { - if (!msgParams.from) { - return cb(new Error('MetaMask Message Signature: from field is required.')) - } - - const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams) - this.sendUpdate() - this.opts.showUnconfirmedMessage() - this.personalMessageManager.once(`${msgId}:finished`, (data) => { - switch (data.status) { - case 'signed': - return cb(null, data.rawSig) - case 'rejected': - return cb(new Error('MetaMask Message Signature: User denied message signature.')) - default: - return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) - } - }) - } - - newUnsignedTypedMessage (msgParams, cb) { - let msgId - try { - msgId = this.typedMessageManager.addUnapprovedMessage(msgParams) - this.sendUpdate() - this.opts.showUnconfirmedMessage() - } catch (e) { - return cb(e) - } + // --------------------------------------------------------------------------- + // Identity Management (sign) - this.typedMessageManager.once(`${msgId}:finished`, (data) => { - switch (data.status) { - case 'signed': - return cb(null, data.rawSig) - case 'rejected': - return cb(new Error('MetaMask Message Signature: User denied message signature.')) - default: - return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) - } - }) - } - /** * @param {} msgParams * @param {} cb @@ -820,14 +745,6 @@ module.exports = class MetamaskController extends EventEmitter { }) } - cancelMessage (msgId, cb) { - const messageManager = this.messageManager - messageManager.rejectMsg(msgId) - if (cb && typeof cb === 'function') { - cb(null, this.getState()) - } - } - // Prefixed Style Message Signing Methods: /** @@ -892,41 +809,10 @@ module.exports = class MetamaskController extends EventEmitter { return this.getState() }) } - - cancelPersonalMessage (msgId, cb) { - const messageManager = this.personalMessageManager - messageManager.rejectMsg(msgId) - if (cb && typeof cb === 'function') { - cb(null, this.getState()) - } - } - - cancelTypedMessage (msgId, cb) { - const messageManager = this.typedMessageManager - messageManager.rejectMsg(msgId) - if (cb && typeof cb === 'function') { - cb(null, this.getState()) - } - } - - markAccountsFound (cb) { - this.configManager.setLostAccounts([]) - this.sendUpdate() - cb(null, this.getState()) - } - - markPasswordForgotten(cb) { - this.configManager.setPasswordForgotten(true) - this.sendUpdate() - cb() - } - - unMarkPasswordForgotten(cb) { - this.configManager.setPasswordForgotten(false) - this.sendUpdate() - cb() - } + // --------------------------------------------------------------------------- + // Account Restauration + /** * ? * @@ -952,7 +838,6 @@ module.exports = class MetamaskController extends EventEmitter { return Promise.resolve(migratorOutput) } - /** * Import (lost) Accounts * @@ -969,6 +854,123 @@ module.exports = class MetamaskController extends EventEmitter { }) } +//============================================================================= +// END (VAULT / KEYRING RELATED METHODS) +//============================================================================= + + + +//============================================================================= +// MESSAGES +//============================================================================= + + async retryTransaction (txId, cb) { + await this.txController.retryTransaction(txId) + const state = await this.getState() + return state + } + + + newUnsignedMessage (msgParams, cb) { + const msgId = this.messageManager.addUnapprovedMessage(msgParams) + this.sendUpdate() + this.opts.showUnconfirmedMessage() + this.messageManager.once(`${msgId}:finished`, (data) => { + switch (data.status) { + case 'signed': + return cb(null, data.rawSig) + case 'rejected': + return cb(new Error('MetaMask Message Signature: User denied message signature.')) + default: + return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) + } + }) + } + + newUnsignedPersonalMessage (msgParams, cb) { + if (!msgParams.from) { + return cb(new Error('MetaMask Message Signature: from field is required.')) + } + + const msgId = this.personalMessageManager.addUnapprovedMessage(msgParams) + this.sendUpdate() + this.opts.showUnconfirmedMessage() + this.personalMessageManager.once(`${msgId}:finished`, (data) => { + switch (data.status) { + case 'signed': + return cb(null, data.rawSig) + case 'rejected': + return cb(new Error('MetaMask Message Signature: User denied message signature.')) + default: + return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) + } + }) + } + + newUnsignedTypedMessage (msgParams, cb) { + let msgId + try { + msgId = this.typedMessageManager.addUnapprovedMessage(msgParams) + this.sendUpdate() + this.opts.showUnconfirmedMessage() + } catch (e) { + return cb(e) + } + + this.typedMessageManager.once(`${msgId}:finished`, (data) => { + switch (data.status) { + case 'signed': + return cb(null, data.rawSig) + case 'rejected': + return cb(new Error('MetaMask Message Signature: User denied message signature.')) + default: + return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`)) + } + }) + } + + cancelMessage (msgId, cb) { + const messageManager = this.messageManager + messageManager.rejectMsg(msgId) + if (cb && typeof cb === 'function') { + cb(null, this.getState()) + } + } + + cancelPersonalMessage (msgId, cb) { + const messageManager = this.personalMessageManager + messageManager.rejectMsg(msgId) + if (cb && typeof cb === 'function') { + cb(null, this.getState()) + } + } + + cancelTypedMessage (msgId, cb) { + const messageManager = this.typedMessageManager + messageManager.rejectMsg(msgId) + if (cb && typeof cb === 'function') { + cb(null, this.getState()) + } + } + + markAccountsFound (cb) { + this.configManager.setLostAccounts([]) + this.sendUpdate() + cb(null, this.getState()) + } + + markPasswordForgotten(cb) { + this.configManager.setPasswordForgotten(true) + this.sendUpdate() + cb() + } + + unMarkPasswordForgotten(cb) { + this.configManager.setPasswordForgotten(false) + this.sendUpdate() + cb() + } + //============================================================================= // CONFIG //============================================================================= -- cgit From bb6af25e20f723942a2b5770a8763bff3b6d6032 Mon Sep 17 00:00:00 2001 From: Lazaridis Date: Fri, 16 Mar 2018 03:22:10 +0200 Subject: add ESLint exceptions for //= and //-, re #3568 --- app/scripts/metamask-controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index cbdf757c6..953e22fc7 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -858,11 +858,11 @@ module.exports = class MetamaskController extends EventEmitter { // END (VAULT / KEYRING RELATED METHODS) //============================================================================= +// - -//============================================================================= +//============================================================================= // MESSAGES -//============================================================================= +//============================================================================= async retryTransaction (txId, cb) { await this.txController.retryTransaction(txId) -- cgit From e1d6398b0fed39e579c0383e34236b30d3154295 Mon Sep 17 00:00:00 2001 From: Lazaridis Date: Fri, 16 Mar 2018 18:37:56 +0200 Subject: moves setup-related code towads end of file, re #3568 --- app/scripts/metamask-controller.js | 239 +++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 115 deletions(-) (limited to 'app/scripts/metamask-controller.js') diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 953e22fc7..18d71874a 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -290,6 +290,9 @@ module.exports = class MetamaskController extends EventEmitter { return publicConfigStore } +//============================================================================= +// EXPOSED TO THE UI SUBSYSTEM +//============================================================================= /** * The metamask-state of the various controllers, made available to the UI @@ -415,122 +418,7 @@ module.exports = class MetamaskController extends EventEmitter { } } - setupUntrustedCommunication (connectionStream, originDomain) { - // Check if new connection is blacklisted - if (this.blacklistController.checkForPhishing(originDomain)) { - log.debug('MetaMask - sending phishing warning for', originDomain) - this.sendPhishingWarning(connectionStream, originDomain) - return - } - - // setup multiplexing - const mux = setupMultiplex(connectionStream) - // connect features - this.setupProviderConnection(mux.createStream('provider'), originDomain) - this.setupPublicConfig(mux.createStream('publicConfig')) - } - - setupTrustedCommunication (connectionStream, originDomain) { - // setup multiplexing - const mux = setupMultiplex(connectionStream) - // connect features - this.setupControllerConnection(mux.createStream('controller')) - this.setupProviderConnection(mux.createStream('provider'), originDomain) - } - - sendPhishingWarning (connectionStream, hostname) { - const mux = setupMultiplex(connectionStream) - const phishingStream = mux.createStream('phishing') - phishingStream.write({ hostname }) - } - - setupControllerConnection (outStream) { - const api = this.getApi() - const dnode = Dnode(api) - pump( - outStream, - dnode, - outStream, - (err) => { - if (err) log.error(err) - } - ) - dnode.on('remote', (remote) => { - // push updates to popup - const sendUpdate = remote.sendUpdate.bind(remote) - this.on('update', sendUpdate) - }) - } - - setupProviderConnection (outStream, origin) { - // setup json rpc engine stack - const engine = new RpcEngine() - // create filter polyfill middleware - const filterMiddleware = createFilterMiddleware({ - provider: this.provider, - blockTracker: this.provider._blockTracker, - }) - - engine.push(createOriginMiddleware({ origin })) - engine.push(createLoggerMiddleware({ origin })) - engine.push(filterMiddleware) - engine.push(createProviderMiddleware({ provider: this.provider })) - - // setup connection - const providerStream = createEngineStream({ engine }) - pump( - outStream, - providerStream, - outStream, - (err) => { - // cleanup filter polyfill middleware - filterMiddleware.destroy() - if (err) log.error(err) - } - ) - } - - setupPublicConfig (outStream) { - pump( - asStream(this.publicConfigStore), - outStream, - (err) => { - if (err) log.error(err) - } - ) - } - - privateSendUpdate () { - this.emit('update', this.getState()) - } - - getGasPrice () { - const { recentBlocksController } = this - const { recentBlocks } = recentBlocksController.store.getState() - - // Return 1 gwei if no blocks have been observed: - if (recentBlocks.length === 0) { - return '0x' + GWEI_BN.toString(16) - } - - const lowestPrices = recentBlocks.map((block) => { - if (!block.gasPrices || block.gasPrices.length < 1) { - return GWEI_BN - } - return block.gasPrices - .map(hexPrefix => hexPrefix.substr(2)) - .map(hex => new BN(hex, 16)) - .sort((a, b) => { - return a.gt(b) ? 1 : -1 - })[0] - }) - .map(number => number.div(GWEI_BN).toNumber()) - - const percentileNum = percentile(50, lowestPrices) - const percentileNumBn = new BN(percentileNum) - return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) - } //============================================================================= // VAULT / KEYRING RELATED METHODS @@ -971,6 +859,127 @@ module.exports = class MetamaskController extends EventEmitter { cb() } +//============================================================================= +// SETUP +//============================================================================= + + setupUntrustedCommunication (connectionStream, originDomain) { + // Check if new connection is blacklisted + if (this.blacklistController.checkForPhishing(originDomain)) { + log.debug('MetaMask - sending phishing warning for', originDomain) + this.sendPhishingWarning(connectionStream, originDomain) + return + } + + // setup multiplexing + const mux = setupMultiplex(connectionStream) + // connect features + this.setupProviderConnection(mux.createStream('provider'), originDomain) + this.setupPublicConfig(mux.createStream('publicConfig')) + } + + setupTrustedCommunication (connectionStream, originDomain) { + // setup multiplexing + const mux = setupMultiplex(connectionStream) + // connect features + this.setupControllerConnection(mux.createStream('controller')) + this.setupProviderConnection(mux.createStream('provider'), originDomain) + } + + sendPhishingWarning (connectionStream, hostname) { + const mux = setupMultiplex(connectionStream) + const phishingStream = mux.createStream('phishing') + phishingStream.write({ hostname }) + } + + setupControllerConnection (outStream) { + const api = this.getApi() + const dnode = Dnode(api) + pump( + outStream, + dnode, + outStream, + (err) => { + if (err) log.error(err) + } + ) + dnode.on('remote', (remote) => { + // push updates to popup + const sendUpdate = remote.sendUpdate.bind(remote) + this.on('update', sendUpdate) + }) + } + + setupProviderConnection (outStream, origin) { + // setup json rpc engine stack + const engine = new RpcEngine() + + // create filter polyfill middleware + const filterMiddleware = createFilterMiddleware({ + provider: this.provider, + blockTracker: this.provider._blockTracker, + }) + + engine.push(createOriginMiddleware({ origin })) + engine.push(createLoggerMiddleware({ origin })) + engine.push(filterMiddleware) + engine.push(createProviderMiddleware({ provider: this.provider })) + + // setup connection + const providerStream = createEngineStream({ engine }) + pump( + outStream, + providerStream, + outStream, + (err) => { + // cleanup filter polyfill middleware + filterMiddleware.destroy() + if (err) log.error(err) + } + ) + } + + setupPublicConfig (outStream) { + pump( + asStream(this.publicConfigStore), + outStream, + (err) => { + if (err) log.error(err) + } + ) + } + + privateSendUpdate () { + this.emit('update', this.getState()) + } + + getGasPrice () { + const { recentBlocksController } = this + const { recentBlocks } = recentBlocksController.store.getState() + + // Return 1 gwei if no blocks have been observed: + if (recentBlocks.length === 0) { + return '0x' + GWEI_BN.toString(16) + } + + const lowestPrices = recentBlocks.map((block) => { + if (!block.gasPrices || block.gasPrices.length < 1) { + return GWEI_BN + } + return block.gasPrices + .map(hexPrefix => hexPrefix.substr(2)) + .map(hex => new BN(hex, 16)) + .sort((a, b) => { + return a.gt(b) ? 1 : -1 + })[0] + }) + .map(number => number.div(GWEI_BN).toNumber()) + + const percentileNum = percentile(50, lowestPrices) + const percentileNumBn = new BN(percentileNum) + return '0x' + percentileNumBn.mul(GWEI_BN).toString(16) + } + //============================================================================= // CONFIG //============================================================================= -- cgit