Merge branch 'dev' of github.com:MetaMask/metamask-plugin into obs-store2

feature/default_network_editable
kumavis 8 years ago
commit bb1ee8e649
  1. 6
      CHANGELOG.md
  2. 2
      app/manifest.json
  3. 42
      app/scripts/keyring-controller.js
  4. 22
      app/scripts/metamask-controller.js
  5. 1
      package.json
  6. 3
      test/unit/keyring-controller-test.js
  7. 20
      ui/app/actions.js
  8. 2
      ui/app/conf-tx.js

@ -2,7 +2,13 @@
## Current Master ## Current Master
- Fix rendering bug where the Confirm transaction view would lets you approve transactions when the account has insufficient balance.
- Add ability to import accounts in JSON file format (used by Mist, Geth, MyEtherWallet, and more!) - Add ability to import accounts in JSON file format (used by Mist, Geth, MyEtherWallet, and more!)
## 3.1.2 2017-1-24
- Fix "New Account" default keychain
## 3.1.1 2017-1-20 ## 3.1.1 2017-1-20
- Fix HD wallet seed export - Fix HD wallet seed export

@ -1,7 +1,7 @@
{ {
"name": "MetaMask", "name": "MetaMask",
"short_name": "Metamask", "short_name": "Metamask",
"version": "3.1.1", "version": "3.1.2",
"manifest_version": 2, "manifest_version": 2,
"author": "https://metamask.io", "author": "https://metamask.io",
"description": "Ethereum Browser Extension", "description": "Ethereum Browser Extension",

@ -150,12 +150,13 @@ module.exports = class KeyringController extends EventEmitter {
mnemonic: seed, mnemonic: seed,
numberOfAccounts: 1, numberOfAccounts: 1,
}) })
}).then(() => { })
const firstKeyring = this.keyrings[0] .then((firstKeyring) => {
return firstKeyring.getAccounts() return firstKeyring.getAccounts()
}) })
.then((accounts) => { .then((accounts) => {
const firstAccount = accounts[0] const firstAccount = accounts[0]
if (!firstAccount) throw new Error('KeyringController - First Account not found.')
const hexAccount = normalize(firstAccount) const hexAccount = normalize(firstAccount)
this.configManager.setSelectedAccount(hexAccount) this.configManager.setSelectedAccount(hexAccount)
return this.setupAccounts(accounts) return this.setupAccounts(accounts)
@ -164,25 +165,6 @@ module.exports = class KeyringController extends EventEmitter {
.then(this.fullUpdate.bind(this)) .then(this.fullUpdate.bind(this))
} }
// PlaceSeedWords
// returns Promise( @object state )
//
// 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 () {
const hdKeyrings = this.keyrings.filter((keyring) => keyring.type === 'HD Key Tree')
const firstKeyring = hdKeyrings[0]
if (!firstKeyring) throw new Error('KeyringController - No HD Key Tree found')
return firstKeyring.serialize()
.then((serialized) => {
const seedWords = serialized.mnemonic
this.configManager.setSeedWords(seedWords)
return this.fullUpdate()
})
}
// ClearSeedWordCache // ClearSeedWordCache
// //
// returns Promise( @string currentSelectedAccount ) // returns Promise( @string currentSelectedAccount )
@ -259,9 +241,8 @@ module.exports = class KeyringController extends EventEmitter {
// Calls the `addAccounts` method on the Keyring // Calls the `addAccounts` method on the Keyring
// in the kryings array at index `keyringNum`, // in the kryings array at index `keyringNum`,
// and then saves those changes. // and then saves those changes.
addNewAccount (keyRingNum = 0) { addNewAccount (selectedKeyring) {
const ring = this.keyrings[keyRingNum] return selectedKeyring.addAccounts(1)
return ring.addAccounts(1)
.then(this.setupAccounts.bind(this)) .then(this.setupAccounts.bind(this))
.then(this.persistAllKeyrings.bind(this)) .then(this.persistAllKeyrings.bind(this))
.then(this.fullUpdate.bind(this)) .then(this.fullUpdate.bind(this))
@ -426,18 +407,17 @@ module.exports = class KeyringController extends EventEmitter {
// puts the current seed words into the state tree. // puts the current seed words into the state tree.
createFirstKeyTree () { createFirstKeyTree () {
this.clearKeyrings() this.clearKeyrings()
return this.addNewKeyring('HD Key Tree', {numberOfAccounts: 1}) return this.addNewKeyring('HD Key Tree', { numberOfAccounts: 1 })
.then(() => { .then((keyring) => {
return this.keyrings[0].getAccounts() return keyring.getAccounts()
}) })
.then((accounts) => { .then((accounts) => {
const firstAccount = accounts[0] const firstAccount = accounts[0]
if (!firstAccount) throw new Error('KeyringController - No account found on keychain.')
const hexAccount = normalize(firstAccount) const hexAccount = normalize(firstAccount)
this.configManager.setSelectedAccount(hexAccount) this.configManager.setSelectedAccount(hexAccount)
this.emit('newAccount', hexAccount) this.emit('newAccount', hexAccount)
return this.setupAccounts(accounts) return this.setupAccounts(accounts)
}).then(() => {
return this.placeSeedWords()
}) })
.then(this.persistAllKeyrings.bind(this)) .then(this.persistAllKeyrings.bind(this))
} }
@ -587,6 +567,10 @@ module.exports = class KeyringController extends EventEmitter {
return this.keyringTypes.find(kr => kr.type === type) return this.keyringTypes.find(kr => kr.type === type)
} }
getKeyringsByType (type) {
return this.keyrings.filter((keyring) => keyring.type === type)
}
// Get Accounts // Get Accounts
// returns Promise( @Array[ @string accounts ] ) // returns Promise( @Array[ @string accounts ] )
// //

@ -1,5 +1,6 @@
const EventEmitter = require('events') const EventEmitter = require('events')
const extend = require('xtend') const extend = require('xtend')
const promiseToCallback = require('promise-to-callback')
const EthStore = require('./lib/eth-store') const EthStore = require('./lib/eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js') const MetaMaskProvider = require('web3-provider-engine/zero.js')
const KeyringController = require('./keyring-controller') const KeyringController = require('./keyring-controller')
@ -120,7 +121,20 @@ module.exports = class MetamaskController extends EventEmitter {
// forward directly to keyringController // forward directly to keyringController
createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController), createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController),
createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore).bind(keyringController), createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore).bind(keyringController),
placeSeedWords: nodeify(keyringController.placeSeedWords).bind(keyringController), // 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) => {
const primaryKeyring = 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)
promiseToCallback(this.keyringController.fullUpdate())(cb)
})
},
clearSeedWordCache: nodeify(keyringController.clearSeedWordCache).bind(keyringController), clearSeedWordCache: nodeify(keyringController.clearSeedWordCache).bind(keyringController),
setLocked: nodeify(keyringController.setLocked).bind(keyringController), setLocked: nodeify(keyringController.setLocked).bind(keyringController),
submitPassword: (password, cb) => { submitPassword: (password, cb) => {
@ -135,6 +149,11 @@ module.exports = class MetamaskController extends EventEmitter {
.then((newState) => { cb(null, newState) }) .then((newState) => { cb(null, newState) })
.catch((reason) => { cb(reason) }) .catch((reason) => { cb(reason) })
}, },
addNewAccount: (cb) => {
const primaryKeyring = keyringController.getKeyringsByType('HD Key Tree')[0]
if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
promiseToCallback(keyringController.addNewAccount(primaryKeyring))(cb)
},
importAccountWithStrategy: (strategy, args, cb) => { importAccountWithStrategy: (strategy, args, cb) => {
accountImporter.importAccount(strategy, args) accountImporter.importAccount(strategy, args)
.then((privateKey) => { .then((privateKey) => {
@ -145,7 +164,6 @@ module.exports = class MetamaskController extends EventEmitter {
.then(() => { cb(null, keyringController.fullUpdate()) }) .then(() => { cb(null, keyringController.fullUpdate()) })
.catch((reason) => { cb(reason) }) .catch((reason) => { cb(reason) })
}, },
addNewAccount: nodeify(keyringController.addNewAccount).bind(keyringController),
setSelectedAccount: nodeify(keyringController.setSelectedAccount).bind(keyringController), setSelectedAccount: nodeify(keyringController.setSelectedAccount).bind(keyringController),
saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController), saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController),
exportAccount: nodeify(keyringController.exportAccount).bind(keyringController), exportAccount: nodeify(keyringController.exportAccount).bind(keyringController),

@ -76,6 +76,7 @@
"polyfill-crypto.getrandomvalues": "^1.0.0", "polyfill-crypto.getrandomvalues": "^1.0.0",
"post-message-stream": "^1.0.0", "post-message-stream": "^1.0.0",
"promise-filter": "^1.1.0", "promise-filter": "^1.1.0",
"promise-to-callback": "^1.0.0",
"pumpify": "^1.3.4", "pumpify": "^1.3.4",
"qrcode-npm": "0.0.3", "qrcode-npm": "0.0.3",
"react": "^15.0.2", "react": "^15.0.2",

@ -41,6 +41,9 @@ describe('KeyringController', function() {
state = newState state = newState
done() done()
}) })
.catch((err) => {
done(err)
})
}) })
afterEach(function() { afterEach(function() {

@ -231,7 +231,21 @@ function createNewVaultAndRestore (password, seed) {
} }
function createNewVaultAndKeychain (password) { function createNewVaultAndKeychain (password) {
return callBackgroundThenUpdate(background.createNewVaultAndKeychain, password) return (dispatch) => {
dispatch(actions.showLoadingIndication())
background.createNewVaultAndKeychain(password, (err, newState) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
background.placeSeedWords((err, newState) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
dispatch(actions.hideLoadingIndication())
dispatch(actions.updateMetamaskState(newState))
})
})
}
} }
function revealSeedConfirmation () { function revealSeedConfirmation () {
@ -286,8 +300,8 @@ function navigateToNewAccountScreen() {
} }
} }
function addNewAccount (ringNumber = 0) { function addNewAccount () {
return callBackgroundThenUpdate(background.addNewAccount, ringNumber) return callBackgroundThenUpdate(background.addNewAccount)
} }
function showInfoPage () { function showInfoPage () {

@ -134,7 +134,7 @@ ConfirmTxScreen.prototype.checkBalanceAgainstTx = function (txData) {
var address = txData.txParams.from || state.selectedAccount var address = txData.txParams.from || state.selectedAccount
var account = state.accounts[address] var account = state.accounts[address]
var balance = account ? account.balance : '0x0' var balance = account ? account.balance : '0x0'
var maxCost = new BN(txData.maxCost) var maxCost = new BN(txData.maxCost, 16)
var balanceBn = new BN(ethUtil.stripHexPrefix(balance), 16) var balanceBn = new BN(ethUtil.stripHexPrefix(balance), 16)
return maxCost.gt(balanceBn) return maxCost.gt(balanceBn)

Loading…
Cancel
Save