aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/metamask-controller.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/scripts/metamask-controller.js')
-rw-r--r--app/scripts/metamask-controller.js116
1 files changed, 95 insertions, 21 deletions
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 1a468b6c7..ad42a39fb 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -1,6 +1,5 @@
const EventEmitter = require('events')
const extend = require('xtend')
-const promiseToCallback = require('promise-to-callback')
const pump = require('pump')
const Dnode = require('dnode')
const ObservableStore = require('obs-store')
@@ -25,6 +24,7 @@ const InfuraController = require('./controllers/infura')
const BlacklistController = require('./controllers/blacklist')
const MessageManager = require('./lib/message-manager')
const PersonalMessageManager = require('./lib/personal-message-manager')
+const TypedMessageManager = require('./lib/typed-message-manager')
const TransactionController = require('./controllers/transactions')
const BalancesController = require('./controllers/computed-balances')
const ConfigManager = require('./lib/config-manager')
@@ -95,25 +95,20 @@ module.exports = class MetamaskController extends EventEmitter {
// key mgmt
this.keyringController = new KeyringController({
initState: initState.KeyringController,
- accountTracker: this.accountTracker,
getNetwork: this.networkController.getNetworkState.bind(this.networkController),
encryptor: opts.encryptor || undefined,
})
// If only one account exists, make sure it is selected.
- this.keyringController.store.subscribe((state) => {
- const addresses = Object.keys(state.walletNicknames || {})
+ this.keyringController.memStore.subscribe((state) => {
+ const addresses = state.keyrings.reduce((res, keyring) => {
+ return res.concat(keyring.accounts)
+ }, [])
if (addresses.length === 1) {
const address = addresses[0]
this.preferencesController.setSelectedAddress(address)
}
- })
- this.keyringController.on('newAccount', (address) => {
- this.preferencesController.setSelectedAddress(address)
- this.accountTracker.addAccount(address)
- })
- this.keyringController.on('removedAccount', (address) => {
- this.accountTracker.removeAccount(address)
+ this.accountTracker.syncWithAddresses(addresses)
})
// address book controller
@@ -161,6 +156,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.networkController.lookupNetwork()
this.messageManager = new MessageManager()
this.personalMessageManager = new PersonalMessageManager()
+ this.typedMessageManager = new TypedMessageManager()
this.publicConfigStore = this.initPublicConfigStore()
// manual disk state subscriptions
@@ -202,6 +198,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.balancesController.store.subscribe(this.sendUpdate.bind(this))
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
this.personalMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
+ this.typedMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
this.preferencesController.store.subscribe(this.sendUpdate.bind(this))
this.addressBookController.store.subscribe(this.sendUpdate.bind(this))
@@ -239,6 +236,7 @@ module.exports = class MetamaskController extends EventEmitter {
processMessage: this.newUnsignedMessage.bind(this),
// personal_sign msg signing
processPersonalMessage: this.newUnsignedPersonalMessage.bind(this),
+ processTypedMessage: this.newUnsignedTypedMessage.bind(this),
}
const providerProxy = this.networkController.initializeProvider(providerOpts)
return providerProxy
@@ -283,6 +281,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.txController.memStore.getState(),
this.messageManager.memStore.getState(),
this.personalMessageManager.memStore.getState(),
+ this.typedMessageManager.memStore.getState(),
this.keyringController.memStore.getState(),
this.balancesController.store.getState(),
this.preferencesController.store.getState(),
@@ -324,13 +323,13 @@ module.exports = class MetamaskController extends EventEmitter {
createShapeShiftTx: this.createShapeShiftTx.bind(this),
// primary HD keyring management
- addNewAccount: this.addNewAccount.bind(this),
+ addNewAccount: nodeify(this.addNewAccount, this),
placeSeedWords: this.placeSeedWords.bind(this),
clearSeedWordCache: this.clearSeedWordCache.bind(this),
importAccountWithStrategy: this.importAccountWithStrategy.bind(this),
// vault management
- submitPassword: this.submitPassword.bind(this),
+ submitPassword: nodeify(keyringController.submitPassword, keyringController),
// network management
setProviderType: nodeify(networkController.setProviderType, networkController),
@@ -346,8 +345,8 @@ module.exports = class MetamaskController extends EventEmitter {
// KeyringController
setLocked: nodeify(keyringController.setLocked, keyringController),
- createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain, keyringController),
- createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore, keyringController),
+ createNewVaultAndKeychain: nodeify(this.createNewVaultAndKeychain, this),
+ createNewVaultAndRestore: nodeify(this.createNewVaultAndRestore, this),
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController),
exportAccount: nodeify(keyringController.exportAccount, keyringController),
@@ -364,6 +363,10 @@ module.exports = class MetamaskController extends EventEmitter {
signPersonalMessage: nodeify(this.signPersonalMessage, this),
cancelPersonalMessage: this.cancelPersonalMessage.bind(this),
+ // personalMessageManager
+ signTypedMessage: nodeify(this.signTypedMessage, this),
+ cancelTypedMessage: this.cancelTypedMessage.bind(this),
+
// notices
checkNotices: noticeController.updateNoticesList.bind(noticeController),
markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
@@ -464,20 +467,43 @@ module.exports = class MetamaskController extends EventEmitter {
// Vault Management
//
- submitPassword (password, cb) {
- return this.keyringController.submitPassword(password)
- .then((newState) => { cb(null, newState) })
- .catch((reason) => { cb(reason) })
+ async createNewVaultAndKeychain (password, cb) {
+ const vault = await this.keyringController.createNewVaultAndKeychain(password)
+ this.selectFirstIdentity(vault)
+ return vault
+ }
+
+ async createNewVaultAndRestore (password, seed, cb) {
+ const vault = await this.keyringController.createNewVaultAndRestore(password, seed)
+ this.selectFirstIdentity(vault)
+ return vault
+ }
+
+ selectFirstIdentity (vault) {
+ const { identities } = vault
+ const address = Object.keys(identities)[0]
+ this.preferencesController.setSelectedAddress(address)
}
//
// Opinionated Keyring Management
//
- addNewAccount (cb) {
+ async addNewAccount (cb) {
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
- promiseToCallback(this.keyringController.addNewAccount(primaryKeyring))(cb)
+ const keyringController = this.keyringController
+ const oldAccounts = await keyringController.getAccounts()
+ const keyState = await keyringController.addNewAccount(primaryKeyring)
+ const newAccounts = await keyringController.getAccounts()
+
+ newAccounts.forEach((address) => {
+ if (!oldAccounts.includes(address)) {
+ this.preferencesController.setSelectedAddress(address)
+ }
+ })
+
+ return keyState
}
// Adds the current vault's seed words to the UI's state tree.
@@ -556,6 +582,28 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
+ 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)}`))
+ }
+ })
+ }
+
signMessage (msgParams, cb) {
log.info('MetaMaskController - signMessage')
const msgId = msgParams.metamaskId
@@ -618,6 +666,24 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
+ signTypedMessage (msgParams) {
+ log.info('MetaMaskController - signTypedMessage')
+ const msgId = msgParams.metamaskId
+ // sets the status op the message to 'approved'
+ // and removes the metamaskId for signing
+ return this.typedMessageManager.approveMessage(msgParams)
+ .then((cleanMsgParams) => {
+ // signs the message
+ return this.keyringController.signTypedMessage(cleanMsgParams)
+ })
+ .then((rawSig) => {
+ // tells the listener that the message has been signed
+ // and can be returned to the dapp
+ this.typedMessageManager.setMsgStatusSigned(msgId, rawSig)
+ return this.getState()
+ })
+ }
+
cancelPersonalMessage (msgId, cb) {
const messageManager = this.personalMessageManager
messageManager.rejectMsg(msgId)
@@ -626,6 +692,14 @@ module.exports = class MetamaskController extends EventEmitter {
}
}
+ 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()