aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/metamask-controller.js
diff options
context:
space:
mode:
authorThomas <thomas.b.huang@gmail.com>2018-07-26 13:38:44 +0800
committerThomas <thomas.b.huang@gmail.com>2018-07-26 13:38:44 +0800
commit138858647ed28a8aaba4b7e18e387ea0b6af0889 (patch)
tree0bc936ee7316112d01e617a246a645e3914da949 /app/scripts/metamask-controller.js
parentfa02a6c7c65f6866998171881fd657570fe3fe7b (diff)
parenta5d344a58223e029dc86bf33a8ca9357492765f3 (diff)
downloadtangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar.gz
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar.bz2
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar.lz
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar.xz
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.tar.zst
tangerine-wallet-browser-138858647ed28a8aaba4b7e18e387ea0b6af0889.zip
Merge branch 'develop' into network-remove-provider-engine
Diffstat (limited to 'app/scripts/metamask-controller.js')
-rw-r--r--app/scripts/metamask-controller.js170
1 files changed, 169 insertions, 1 deletions
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 3d7268395..12daf1603 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -35,6 +35,7 @@ const TypedMessageManager = require('./lib/typed-message-manager')
const TransactionController = require('./controllers/transactions')
const BalancesController = require('./controllers/computed-balances')
const TokenRatesController = require('./controllers/token-rates')
+const DetectTokensController = require('./controllers/detect-tokens')
const ConfigManager = require('./lib/config-manager')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
@@ -46,6 +47,7 @@ const GWEI_BN = new BN('1000000000')
const percentile = require('percentile')
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
const log = require('loglevel')
+const TrezorKeyring = require('eth-trezor-keyring')
module.exports = class MetamaskController extends EventEmitter {
@@ -124,7 +126,9 @@ module.exports = class MetamaskController extends EventEmitter {
})
// key mgmt
+ const additionalKeyrings = [TrezorKeyring]
this.keyringController = new KeyringController({
+ keyringTypes: additionalKeyrings,
initState: initState.KeyringController,
getNetwork: this.networkController.getNetworkState.bind(this.networkController),
encryptor: opts.encryptor || undefined,
@@ -144,6 +148,13 @@ module.exports = class MetamaskController extends EventEmitter {
this.accountTracker.syncWithAddresses(addresses)
})
+ // detect tokens controller
+ this.detectTokensController = new DetectTokensController({
+ preferences: this.preferencesController,
+ network: this.networkController,
+ keyringMemStore: this.keyringController.memStore,
+ })
+
// address book controller
this.addressBookController = new AddressBookController({
initState: initState.AddressBookController,
@@ -164,6 +175,13 @@ module.exports = class MetamaskController extends EventEmitter {
})
this.txController.on('newUnapprovedTx', opts.showUnapprovedTx.bind(opts))
+ this.txController.on(`tx:status-update`, (txId, status) => {
+ if (status === 'confirmed' || status === 'failed') {
+ const txMeta = this.txController.txStateManager.getTx(txId)
+ this.platform.showTransactionNotification(txMeta)
+ }
+ })
+
// computed balances (accounting for pending transactions)
this.balancesController = new BalancesController({
accountTracker: this.accountTracker,
@@ -332,6 +350,7 @@ module.exports = class MetamaskController extends EventEmitter {
markAccountsFound: this.markAccountsFound.bind(this),
markPasswordForgotten: this.markPasswordForgotten.bind(this),
unMarkPasswordForgotten: this.unMarkPasswordForgotten.bind(this),
+ getGasPrice: (cb) => cb(null, this.getGasPrice()),
// coinbase
buyEth: this.buyEth.bind(this),
@@ -344,8 +363,17 @@ module.exports = class MetamaskController extends EventEmitter {
verifySeedPhrase: nodeify(this.verifySeedPhrase, this),
clearSeedWordCache: this.clearSeedWordCache.bind(this),
resetAccount: nodeify(this.resetAccount, this),
+ removeAccount: nodeify(this.removeAccount, this),
importAccountWithStrategy: nodeify(this.importAccountWithStrategy, this),
+ // hardware wallets
+ connectHardware: nodeify(this.connectHardware, this),
+ forgetDevice: nodeify(this.forgetDevice, this),
+ checkHardwareStatus: nodeify(this.checkHardwareStatus, this),
+
+ // TREZOR
+ unlockTrezorAccount: nodeify(this.unlockTrezorAccount, this),
+
// vault management
submitPassword: nodeify(this.submitPassword, this),
@@ -502,6 +530,127 @@ module.exports = class MetamaskController extends EventEmitter {
}
//
+ // Hardware
+ //
+
+ /**
+ * Fetch account list from a trezor device.
+ *
+ * @returns [] accounts
+ */
+ async connectHardware (deviceName, page) {
+
+ switch (deviceName) {
+ case 'trezor':
+ const keyringController = this.keyringController
+ const oldAccounts = await keyringController.getAccounts()
+ let keyring = await keyringController.getKeyringsByType(
+ 'Trezor Hardware'
+ )[0]
+ if (!keyring) {
+ keyring = await this.keyringController.addNewKeyring('Trezor Hardware')
+ }
+ let accounts = []
+
+ switch (page) {
+ case -1:
+ accounts = await keyring.getPreviousPage()
+ break
+ case 1:
+ accounts = await keyring.getNextPage()
+ break
+ default:
+ accounts = await keyring.getFirstPage()
+ }
+
+ // Merge with existing accounts
+ // and make sure addresses are not repeated
+ const accountsToTrack = [...new Set(oldAccounts.concat(accounts.map(a => a.address.toLowerCase())))]
+ this.accountTracker.syncWithAddresses(accountsToTrack)
+ return accounts
+
+ default:
+ throw new Error('MetamaskController:connectHardware - Unknown device')
+ }
+ }
+
+ /**
+ * Check if the device is unlocked
+ *
+ * @returns {Promise<boolean>}
+ */
+ async checkHardwareStatus (deviceName) {
+
+ switch (deviceName) {
+ case 'trezor':
+ const keyringController = this.keyringController
+ const keyring = await keyringController.getKeyringsByType(
+ 'Trezor Hardware'
+ )[0]
+ if (!keyring) {
+ return false
+ }
+ return keyring.isUnlocked()
+ default:
+ throw new Error('MetamaskController:checkHardwareStatus - Unknown device')
+ }
+ }
+
+ /**
+ * Clear
+ *
+ * @returns {Promise<boolean>}
+ */
+ async forgetDevice (deviceName) {
+
+ switch (deviceName) {
+ case 'trezor':
+ const keyringController = this.keyringController
+ const keyring = await keyringController.getKeyringsByType(
+ 'Trezor Hardware'
+ )[0]
+ if (!keyring) {
+ throw new Error('MetamaskController:forgetDevice - Trezor Hardware keyring not found')
+ }
+ keyring.forgetDevice()
+ return true
+ default:
+ throw new Error('MetamaskController:forgetDevice - Unknown device')
+ }
+ }
+
+ /**
+ * Imports an account from a trezor device.
+ *
+ * @returns {} keyState
+ */
+ async unlockTrezorAccount (index) {
+ const keyringController = this.keyringController
+ const keyring = await keyringController.getKeyringsByType(
+ 'Trezor Hardware'
+ )[0]
+ if (!keyring) {
+ throw new Error('MetamaskController - No Trezor Hardware Keyring found')
+ }
+
+ keyring.setAccountToUnlock(index)
+ const oldAccounts = await keyringController.getAccounts()
+ const keyState = await keyringController.addNewAccount(keyring)
+ const newAccounts = await keyringController.getAccounts()
+ this.preferencesController.setAddresses(newAccounts)
+ newAccounts.forEach(address => {
+ if (!oldAccounts.includes(address)) {
+ this.preferencesController.setAccountLabel(address, `TREZOR #${parseInt(index, 10) + 1}`)
+ this.preferencesController.setSelectedAddress(address)
+ }
+ })
+
+ const { identities } = this.preferencesController.store.getState()
+ return { ...keyState, identities }
+ }
+
+
+ //
// Account Management
//
@@ -614,6 +763,23 @@ module.exports = class MetamaskController extends EventEmitter {
}
/**
+ * Removes an account from state / storage.
+ *
+ * @param {string[]} address A hex address
+ *
+ */
+ async removeAccount (address) {
+ // Remove account from the preferences controller
+ this.preferencesController.removeAddress(address)
+ // Remove account from the account tracker controller
+ this.accountTracker.removeAccount(address)
+ // Remove account from the keyring
+ await this.keyringController.removeAccount(address)
+ return address
+ }
+
+
+ /**
* Imports an account with the specified import strategy.
* These are defined in app/scripts/account-import-strategies
* Each strategy represents a different way of serializing an Ethereum key pair.
@@ -1235,10 +1401,12 @@ module.exports = class MetamaskController extends EventEmitter {
set isClientOpen (open) {
this._isClientOpen = open
this.isClientOpenAndUnlocked = this.getState().isUnlocked && open
+ this.detectTokensController.isOpen = open
}
/**
- * A method for activating the retrieval of price data, which should only be fetched when the UI is visible.
+ * A method for activating the retrieval of price data and auto detect tokens,
+ * which should only be fetched when the UI is visible.
* @private
* @param {boolean} active - True if price data should be getting fetched.
*/