aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts
diff options
context:
space:
mode:
authorBruno Barbieri <bruno.barbieri@consensys.net>2018-07-20 03:00:59 +0800
committerGitHub <noreply@github.com>2018-07-20 03:00:59 +0800
commit9be2248d7accfc51fd21f31b16d08c18a468c0f7 (patch)
treed52384c0b0803e68188fe310a665cec2890b5680 /app/scripts
parent3784a7e2c852974315cfe17a68673938cf24a7fa (diff)
parentdf19163bf9611d75aaf8ea6da52651dbba9a5e00 (diff)
downloadtangerine-wallet-browser-9be2248d7accfc51fd21f31b16d08c18a468c0f7.tar.gz
tangerine-wallet-browser-9be2248d7accfc51fd21f31b16d08c18a468c0f7.tar.zst
tangerine-wallet-browser-9be2248d7accfc51fd21f31b16d08c18a468c0f7.zip
Merge pull request #4625 from MetaMask/initial-trezor-support
Initial trezor support
Diffstat (limited to 'app/scripts')
-rw-r--r--app/scripts/controllers/preferences.js24
-rw-r--r--app/scripts/lib/util.js2
-rw-r--r--app/scripts/metamask-controller.js150
-rw-r--r--app/scripts/platforms/extension.js7
4 files changed, 180 insertions, 3 deletions
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index b314745f5..f6250dc16 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -86,6 +86,30 @@ class PreferencesController {
}
/**
+ * Removes an address from state
+ *
+ * @param {string} address A hex address
+ * @returns {string} the address that was removed
+ */
+ removeAddress (address) {
+ const identities = this.store.getState().identities
+ if (!identities[address]) {
+ throw new Error(`${address} can't be deleted cause it was not found`)
+ }
+ delete identities[address]
+ this.store.updateState({ identities })
+
+ // If the selected account is no longer valid,
+ // select an arbitrary other account:
+ if (address === this.getSelectedAddress()) {
+ const selected = Object.keys(identities)[0]
+ this.setSelectedAddress(selected)
+ }
+ return address
+ }
+
+
+ /**
* Adds addresses to the identities object without removing identities
*
* @param {string[]} addresses An array of hex addresses
diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js
index 431d1e59c..51e9036cc 100644
--- a/app/scripts/lib/util.js
+++ b/app/scripts/lib/util.js
@@ -28,7 +28,7 @@ function getStack () {
*
*/
const getEnvironmentType = (url = window.location.href) => {
- if (url.match(/popup.html(?:\?.+)*$/)) {
+ if (url.match(/popup.html(?:#.*)*$/)) {
return ENVIRONMENT_TYPE_POPUP
} else if (url.match(/home.html(?:\?.+)*$/) || url.match(/home.html(?:#.*)*$/)) {
return ENVIRONMENT_TYPE_FULLSCREEN
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 450113acf..dc5c24b1b 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -47,6 +47,7 @@ const percentile = require('percentile')
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
const cleanErrorStack = require('./lib/cleanErrorStack')
const log = require('loglevel')
+const TrezorKeyring = require('eth-trezor-keyring')
module.exports = class MetamaskController extends EventEmitter {
@@ -124,7 +125,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,
@@ -351,8 +354,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),
@@ -509,6 +521,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
//
@@ -621,6 +754,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.
diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js
index f5cc255d1..f8dd767dc 100644
--- a/app/scripts/platforms/extension.js
+++ b/app/scripts/platforms/extension.js
@@ -17,8 +17,11 @@ class ExtensionPlatform {
return extension.runtime.getManifest().version
}
- openExtensionInBrowser () {
- const extensionURL = extension.runtime.getURL('home.html')
+ openExtensionInBrowser (route = null) {
+ let extensionURL = extension.runtime.getURL('home.html')
+ if (route) {
+ extensionURL += `#${route}`
+ }
this.openWindow({ url: extensionURL })
}