1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Merge branch 'dev' into i843-MoveSaltIntoEncryptor

This commit is contained in:
Dan Finlay 2016-11-22 15:36:50 -08:00
commit 2966d46fa2
48 changed files with 239 additions and 143 deletions

View File

@ -5,6 +5,8 @@
- Add support for the new, default Ropsten Test Network. - Add support for the new, default Ropsten Test Network.
- Fix bug that would cause MetaMask to occasionally lose its StreamProvider connection and drop requests. - Fix bug that would cause MetaMask to occasionally lose its StreamProvider connection and drop requests.
- Fix bug that would cause the Custom RPC menu item to not appear when Localhost 8545 was selected. - Fix bug that would cause the Custom RPC menu item to not appear when Localhost 8545 was selected.
- Point ropsten faucet button to actual faucet.
- Phase out ethereumjs-util from our encryptor module.
## 2.13.8 2016-11-16 ## 2.13.8 2016-11-16

View File

@ -18,6 +18,12 @@ If you're a web dapp developer, we've got two types of guides for you:
Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built. Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built.
## Installing Local Builds on Chrome
To install your locally built extension on Chrome, [follow this guide](http://stackoverflow.com/a/24577660/272576).
The built extension is stored in `./dist/chrome/`.
## Architecture ## Architecture
[![Architecture Diagram](./docs/architecture.png)][1] [![Architecture Diagram](./docs/architecture.png)][1]

View File

@ -50,7 +50,7 @@ endOfStream(pingStream, triggerReload)
// set web3 defaultAcount // set web3 defaultAcount
inpageProvider.publicConfigStore.subscribe(function (state) { inpageProvider.publicConfigStore.subscribe(function (state) {
web3.eth.defaultAccount = state.selectedAddress web3.eth.defaultAccount = state.selectedAccount
}) })
// //

View File

@ -1,4 +1,5 @@
const async = require('async') const async = require('async')
const bind = require('ap').partial
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const ethBinToOps = require('eth-bin-to-ops') const ethBinToOps = require('eth-bin-to-ops')
const EthQuery = require('eth-query') const EthQuery = require('eth-query')
@ -9,7 +10,6 @@ const EventEmitter = require('events').EventEmitter
const normalize = require('./lib/sig-util').normalize const normalize = require('./lib/sig-util').normalize
const encryptor = require('./lib/encryptor') const encryptor = require('./lib/encryptor')
const messageManager = require('./lib/message-manager') const messageManager = require('./lib/message-manager')
const autoFaucet = require('./lib/auto-faucet')
const IdStoreMigrator = require('./lib/idStore-migrator') const IdStoreMigrator = require('./lib/idStore-migrator')
const BN = ethUtil.BN const BN = ethUtil.BN
@ -61,13 +61,12 @@ module.exports = class KeyringController extends EventEmitter {
transactions: this.configManager.getTxList(), transactions: this.configManager.getTxList(),
unconfMsgs: messageManager.unconfirmedMsgs(), unconfMsgs: messageManager.unconfirmedMsgs(),
messages: messageManager.getMsgList(), messages: messageManager.getMsgList(),
selectedAddress: address,
selectedAccount: address, selectedAccount: address,
shapeShiftTxList: this.configManager.getShapeShiftTxList(), shapeShiftTxList: this.configManager.getShapeShiftTxList(),
currentFiat: this.configManager.getCurrentFiat(), currentFiat: this.configManager.getCurrentFiat(),
conversionRate: this.configManager.getConversionRate(), conversionRate: this.configManager.getConversionRate(),
conversionDate: this.configManager.getConversionDate(), conversionDate: this.configManager.getConversionDate(),
keyringTypes: this.keyringTypes.map((krt) => krt.type()), keyringTypes: this.keyringTypes.map(krt => krt.type),
identities: this.identities, identities: this.identities,
} }
} }
@ -76,8 +75,8 @@ module.exports = class KeyringController extends EventEmitter {
this.ethStore = ethStore this.ethStore = ethStore
} }
createNewVaultAndKeychain (password, entropy, cb) { createNewVaultAndKeychain (password, cb) {
this.createNewVault(password, entropy, (err) => { this.createNewVault(password, (err) => {
if (err) return cb(err) if (err) return cb(err)
this.createFirstKeyTree(password, cb) this.createFirstKeyTree(password, cb)
}) })
@ -94,7 +93,7 @@ module.exports = class KeyringController extends EventEmitter {
this.clearKeyrings() this.clearKeyrings()
this.createNewVault(password, '', (err) => { this.createNewVault(password, (err) => {
if (err) return cb(err) if (err) return cb(err)
this.addNewKeyring('HD Key Tree', { this.addNewKeyring('HD Key Tree', {
mnemonic: seed, mnemonic: seed,
@ -121,7 +120,7 @@ module.exports = class KeyringController extends EventEmitter {
.then((derivedKey) => { .then((derivedKey) => {
key = derivedKey key = derivedKey
this.key = key this.key = key
return this.idStoreMigrator.oldSeedForPassword(password) return this.idStoreMigrator.migratedVaultForPassword(password)
}) })
.then((serialized) => { .then((serialized) => {
if (serialized && shouldMigrate) { if (serialized && shouldMigrate) {
@ -135,7 +134,7 @@ module.exports = class KeyringController extends EventEmitter {
}) })
} }
createNewVault (password, entropy, cb) { createNewVault (password, cb) {
const configManager = this.configManager const configManager = this.configManager
const salt = this.getSalt() const salt = this.getSalt()
configManager.setSalt(salt) configManager.setSalt(salt)
@ -161,7 +160,7 @@ module.exports = class KeyringController extends EventEmitter {
this.configManager.setSelectedAccount(firstAccount) this.configManager.setSelectedAccount(firstAccount)
this.placeSeedWords() this.placeSeedWords()
autoFaucet(hexAccount) this.emit('newAccount', hexAccount)
this.setupAccounts(accounts) this.setupAccounts(accounts)
this.persistAllKeyrings() this.persistAllKeyrings()
.then(() => { .then(() => {
@ -173,10 +172,15 @@ module.exports = class KeyringController extends EventEmitter {
}) })
} }
placeSeedWords () { placeSeedWords (cb) {
const firstKeyring = this.keyrings[0] const firstKeyring = this.keyrings[0]
const seedWords = firstKeyring.serialize().mnemonic const seedWords = firstKeyring.serialize().mnemonic
this.configManager.setSeedWords(seedWords) this.configManager.setSeedWords(seedWords)
if (cb) {
cb()
}
this.emit('update')
} }
submitPassword (password, cb) { submitPassword (password, cb) {
@ -317,7 +321,7 @@ module.exports = class KeyringController extends EventEmitter {
getKeyringClassForType (type) { getKeyringClassForType (type) {
const Keyring = this.keyringTypes.reduce((res, kr) => { const Keyring = this.keyringTypes.reduce((res, kr) => {
if (kr.type() === type) { if (kr.type === type) {
return kr return kr
} else { } else {
return res return res
@ -334,7 +338,7 @@ module.exports = class KeyringController extends EventEmitter {
}, []) }, [])
} }
setSelectedAddress (address, cb) { setSelectedAccount (address, cb) {
var addr = normalize(address) var addr = normalize(address)
this.configManager.setSelectedAccount(addr) this.configManager.setSelectedAccount(addr)
cb(null, addr) cb(null, addr)
@ -369,7 +373,7 @@ module.exports = class KeyringController extends EventEmitter {
// calculate metadata for tx // calculate metadata for tx
async.parallel([ async.parallel([
analyzeForDelegateCall, analyzeForDelegateCall,
estimateGas, analyzeGasUsage,
], didComplete) ], didComplete)
// perform static analyis on the target contract code // perform static analyis on the target contract code
@ -392,14 +396,69 @@ module.exports = class KeyringController extends EventEmitter {
} }
} }
function estimateGas (cb) { function analyzeGasUsage (cb) {
query.estimateGas(txParams, function (err, result) { query.getBlockByNumber('latest', true, function (err, block) {
if (err) return cb(err) if (err) return cb(err)
txData.estimatedGas = self.addGasBuffer(result) async.waterfall([
cb() bind(estimateGas, txData, block.gasLimit),
bind(checkForGasError, txData),
bind(setTxGas, txData, block.gasLimit),
], cb)
}) })
} }
function estimateGas(txData, blockGasLimitHex, cb) {
const txParams = txData.txParams
// check if gasLimit is already specified
txData.gasLimitSpecified = Boolean(txParams.gas)
// if not, fallback to block gasLimit
if (!txData.gasLimitSpecified) {
txParams.gas = blockGasLimitHex
}
// run tx, see if it will OOG
query.estimateGas(txParams, cb)
}
function checkForGasError(txData, estimatedGasHex) {
txData.estimatedGas = estimatedGasHex
// all gas used - must be an error
if (estimatedGasHex === txData.txParams.gas) {
txData.simulationFails = true
}
cb()
}
function setTxGas(txData, blockGasLimitHex) {
const txParams = txData.txParams
// if OOG, nothing more to do
if (txData.simulationFails) {
cb()
return
}
// if gasLimit was specified and doesnt OOG,
// use original specified amount
if (txData.gasLimitSpecified) {
txData.estimatedGas = txParams.gas
cb()
return
}
// if gasLimit not originally specified,
// try adding an additional gas buffer to our estimation for safety
const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16)
const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16)
const estimationWithBuffer = self.addGasBuffer(estimatedGasBn)
// added gas buffer is too high
if (estimationWithBuffer.gt(blockGasLimitBn)) {
txParams.gas = txData.estimatedGas
// added gas buffer is safe
} else {
const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer)
txParams.gas = gasWithBufferHex
}
cb()
return
}
function didComplete (err) { function didComplete (err) {
if (err) return cb(err) if (err) return cb(err)
configManager.addTx(txData) configManager.addTx(txData)

View File

@ -2,17 +2,17 @@ const EventEmitter = require('events').EventEmitter
const hdkey = require('ethereumjs-wallet/hdkey') const hdkey = require('ethereumjs-wallet/hdkey')
const bip39 = require('bip39') const bip39 = require('bip39')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
// *Internal Deps
const sigUtil = require('../lib/sig-util') const sigUtil = require('../lib/sig-util')
// Options:
const hdPathString = `m/44'/60'/0'/0`
const type = 'HD Key Tree' const type = 'HD Key Tree'
const hdPathString = `m/44'/60'/0'/0` class HdKeyring extends EventEmitter {
module.exports = class HdKeyring extends EventEmitter { /* PUBLIC METHODS */
static type () {
return type
}
constructor (opts = {}) { constructor (opts = {}) {
super() super()
@ -20,28 +20,6 @@ module.exports = class HdKeyring extends EventEmitter {
this.deserialize(opts) this.deserialize(opts)
} }
deserialize (opts = {}) {
this.opts = opts || {}
this.wallets = []
this.mnemonic = null
this.root = null
if ('mnemonic' in opts) {
this.initFromMnemonic(opts.mnemonic)
}
if ('numberOfAccounts' in opts) {
this.addAccounts(opts.numberOfAccounts)
}
}
initFromMnemonic (mnemonic) {
this.mnemonic = mnemonic
const seed = bip39.mnemonicToSeed(mnemonic)
this.hdWallet = hdkey.fromMasterSeed(seed)
this.root = this.hdWallet.derivePath(hdPathString)
}
serialize () { serialize () {
return { return {
mnemonic: this.mnemonic, mnemonic: this.mnemonic,
@ -49,14 +27,24 @@ module.exports = class HdKeyring extends EventEmitter {
} }
} }
exportAccount (address) { deserialize (opts = {}) {
const wallet = this.getWalletForAccount(address) this.opts = opts || {}
return wallet.getPrivateKey().toString('hex') this.wallets = []
this.mnemonic = null
this.root = null
if ('mnemonic' in opts) {
this._initFromMnemonic(opts.mnemonic)
}
if ('numberOfAccounts' in opts) {
this.addAccounts(opts.numberOfAccounts)
}
} }
addAccounts (numberOfAccounts = 1) { addAccounts (numberOfAccounts = 1) {
if (!this.root) { if (!this.root) {
this.initFromMnemonic(bip39.generateMnemonic()) this._initFromMnemonic(bip39.generateMnemonic())
} }
const oldLen = this.wallets.length const oldLen = this.wallets.length
@ -76,7 +64,7 @@ module.exports = class HdKeyring extends EventEmitter {
// tx is an instance of the ethereumjs-transaction class. // tx is an instance of the ethereumjs-transaction class.
signTransaction (address, tx) { signTransaction (address, tx) {
const wallet = this.getWalletForAccount(address) const wallet = this._getWalletForAccount(address)
var privKey = wallet.getPrivateKey() var privKey = wallet.getPrivateKey()
tx.sign(privKey) tx.sign(privKey)
return tx return tx
@ -84,7 +72,7 @@ module.exports = class HdKeyring extends EventEmitter {
// For eth_sign, we need to sign transactions: // For eth_sign, we need to sign transactions:
signMessage (withAccount, data) { signMessage (withAccount, data) {
const wallet = this.getWalletForAccount(withAccount) const wallet = this._getWalletForAccount(withAccount)
const message = ethUtil.removeHexPrefix(data) const message = ethUtil.removeHexPrefix(data)
var privKey = wallet.getPrivateKey() var privKey = wallet.getPrivateKey()
var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey) var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey)
@ -92,10 +80,29 @@ module.exports = class HdKeyring extends EventEmitter {
return rawMsgSig return rawMsgSig
} }
getWalletForAccount (account) { exportAccount (address) {
const wallet = this._getWalletForAccount(address)
return wallet.getPrivateKey().toString('hex')
}
/* PRIVATE METHODS */
_initFromMnemonic (mnemonic) {
this.mnemonic = mnemonic
const seed = bip39.mnemonicToSeed(mnemonic)
this.hdWallet = hdkey.fromMasterSeed(seed)
this.root = this.hdWallet.derivePath(hdPathString)
}
_getWalletForAccount (account) {
return this.wallets.find((w) => { return this.wallets.find((w) => {
const address = w.getAddress().toString('hex') const address = w.getAddress().toString('hex')
return ((address === account) || (sigUtil.normalize(address) === account)) return ((address === account) || (sigUtil.normalize(address) === account))
}) })
} }
} }
HdKeyring.type = type
module.exports = HdKeyring

View File

@ -4,7 +4,9 @@ const ethUtil = require('ethereumjs-util')
const type = 'Simple Key Pair' const type = 'Simple Key Pair'
const sigUtil = require('../lib/sig-util') const sigUtil = require('../lib/sig-util')
module.exports = class SimpleKeyring extends EventEmitter { class SimpleKeyring extends EventEmitter {
/* PUBLIC METHODS */
static type () { static type () {
return type return type
@ -44,7 +46,7 @@ module.exports = class SimpleKeyring extends EventEmitter {
// tx is an instance of the ethereumjs-transaction class. // tx is an instance of the ethereumjs-transaction class.
signTransaction (address, tx) { signTransaction (address, tx) {
const wallet = this.getWalletForAccount(address) const wallet = this._getWalletForAccount(address)
var privKey = wallet.getPrivateKey() var privKey = wallet.getPrivateKey()
tx.sign(privKey) tx.sign(privKey)
return tx return tx
@ -52,7 +54,7 @@ module.exports = class SimpleKeyring extends EventEmitter {
// For eth_sign, we need to sign transactions: // For eth_sign, we need to sign transactions:
signMessage (withAccount, data) { signMessage (withAccount, data) {
const wallet = this.getWalletForAccount(withAccount) const wallet = this._getWalletForAccount(withAccount)
const message = ethUtil.removeHexPrefix(data) const message = ethUtil.removeHexPrefix(data)
var privKey = wallet.getPrivateKey() var privKey = wallet.getPrivateKey()
var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey) var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey)
@ -60,8 +62,19 @@ module.exports = class SimpleKeyring extends EventEmitter {
return rawMsgSig return rawMsgSig
} }
getWalletForAccount (account) { exportAccount (address) {
const wallet = this._getWalletForAccount(address)
return wallet.getPrivateKey().toString('hex')
}
/* PRIVATE METHODS */
_getWalletForAccount (account) {
return this.wallets.find(w => w.getAddress().toString('hex') === account) return this.wallets.find(w => w.getAddress().toString('hex') === account)
} }
} }
SimpleKeyring.type = type
module.exports = SimpleKeyring

View File

@ -1,5 +1,3 @@
var ethUtil = require('ethereumjs-util')
module.exports = { module.exports = {
// Simple encryption methods: // Simple encryption methods:
@ -101,10 +99,10 @@ function keyFromPassword (password) {
} }
function serializeBufferFromStorage (str) { function serializeBufferFromStorage (str) {
str = ethUtil.stripHexPrefix(str) var stripStr = (str.slice(0, 2) === '0x') ? str.slice(2) : str
var buf = new Uint8Array(str.length / 2) var buf = new Uint8Array(stripStr.length / 2)
for (var i = 0; i < str.length; i += 2) { for (var i = 0; i < stripStr.length; i += 2) {
var seg = str.substr(i, 2) var seg = stripStr.substr(i, 2)
buf[i / 2] = parseInt(seg, 16) buf[i / 2] = parseInt(seg, 16)
} }
return buf return buf

View File

@ -11,7 +11,7 @@ module.exports = class IdentityStoreMigrator {
} }
} }
oldSeedForPassword (password) { migratedVaultForPassword (password) {
const hasOldVault = this.hasOldVault() const hasOldVault = this.hasOldVault()
const configManager = this.configManager const configManager = this.configManager

View File

@ -44,7 +44,7 @@ function IdentityStore (opts = {}) {
// public // public
// //
IdentityStore.prototype.createNewVault = function (password, entropy, cb) { IdentityStore.prototype.createNewVault = function (password, cb) {
delete this._keyStore delete this._keyStore
var serializedKeystore = this.configManager.getWallet() var serializedKeystore = this.configManager.getWallet()
@ -53,7 +53,7 @@ IdentityStore.prototype.createNewVault = function (password, entropy, cb) {
} }
this.purgeCache() this.purgeCache()
this._createVault(password, null, entropy, (err) => { this._createVault(password, null, (err) => {
if (err) return cb(err) if (err) return cb(err)
this._autoFaucet() this._autoFaucet()
@ -77,7 +77,7 @@ IdentityStore.prototype.recoverSeed = function (cb) {
IdentityStore.prototype.recoverFromSeed = function (password, seed, cb) { IdentityStore.prototype.recoverFromSeed = function (password, seed, cb) {
this.purgeCache() this.purgeCache()
this._createVault(password, seed, null, (err) => { this._createVault(password, seed, (err) => {
if (err) return cb(err) if (err) return cb(err)
this._loadIdentities() this._loadIdentities()
@ -497,7 +497,7 @@ IdentityStore.prototype.tryPassword = function (password, cb) {
}) })
} }
IdentityStore.prototype._createVault = function (password, seedPhrase, entropy, cb) { IdentityStore.prototype._createVault = function (password, seedPhrase, cb) {
const opts = { const opts = {
password, password,
hdPathString: this.hdPathString, hdPathString: this.hdPathString,

View File

@ -66,20 +66,20 @@ function MetamaskInpageProvider (connectionStream) {
MetamaskInpageProvider.prototype.send = function (payload) { MetamaskInpageProvider.prototype.send = function (payload) {
const self = this const self = this
let selectedAddress let selectedAccount
let result = null let result = null
switch (payload.method) { switch (payload.method) {
case 'eth_accounts': case 'eth_accounts':
// read from localStorage // read from localStorage
selectedAddress = self.publicConfigStore.get('selectedAddress') selectedAccount = self.publicConfigStore.get('selectedAddress')
result = selectedAddress ? [selectedAddress] : [] result = selectedAccount ? [selectedAccount] : []
break break
case 'eth_coinbase': case 'eth_coinbase':
// read from localStorage // read from localStorage
selectedAddress = self.publicConfigStore.get('selectedAddress') selectedAccount = self.publicConfigStore.get('selectedAddress')
result = selectedAddress || '0x0000000000000000000000000000000000000000' result = selectedAccount || '0x0000000000000000000000000000000000000000'
break break
// throw not-supported Error // throw not-supported Error

View File

@ -7,6 +7,8 @@ const HostStore = require('./lib/remote-store.js').HostStore
const Web3 = require('web3') const Web3 = require('web3')
const ConfigManager = require('./lib/config-manager') const ConfigManager = require('./lib/config-manager')
const extension = require('./lib/extension') const extension = require('./lib/extension')
const autoFaucet = require('./lib/auto-faucet')
module.exports = class MetamaskController { module.exports = class MetamaskController {
@ -67,7 +69,7 @@ module.exports = class MetamaskController {
addNewKeyring: keyringController.addNewKeyring.bind(keyringController), addNewKeyring: keyringController.addNewKeyring.bind(keyringController),
addNewAccount: keyringController.addNewAccount.bind(keyringController), addNewAccount: keyringController.addNewAccount.bind(keyringController),
submitPassword: keyringController.submitPassword.bind(keyringController), submitPassword: keyringController.submitPassword.bind(keyringController),
setSelectedAddress: keyringController.setSelectedAddress.bind(keyringController), setSelectedAccount: keyringController.setSelectedAccount.bind(keyringController),
approveTransaction: keyringController.approveTransaction.bind(keyringController), approveTransaction: keyringController.approveTransaction.bind(keyringController),
cancelTransaction: keyringController.cancelTransaction.bind(keyringController), cancelTransaction: keyringController.cancelTransaction.bind(keyringController),
signMessage: keyringController.signMessage.bind(keyringController), signMessage: keyringController.signMessage.bind(keyringController),
@ -125,8 +127,8 @@ module.exports = class MetamaskController {
rpcUrl: this.configManager.getCurrentRpcAddress(), rpcUrl: this.configManager.getCurrentRpcAddress(),
// account mgmt // account mgmt
getAccounts: (cb) => { getAccounts: (cb) => {
var selectedAddress = this.configManager.getSelectedAccount() var selectedAccount = this.configManager.getSelectedAccount()
var result = selectedAddress ? [selectedAddress] : [] var result = selectedAccount ? [selectedAccount] : []
cb(null, result) cb(null, result)
}, },
// tx signing // tx signing
@ -174,17 +176,21 @@ module.exports = class MetamaskController {
this.sendUpdate() this.sendUpdate()
}) })
this.keyringController.on('newAccount', (account) => {
autoFaucet(account)
})
// keyringController substate // keyringController substate
function keyringControllerToPublic (state) { function keyringControllerToPublic (state) {
return { return {
selectedAddress: state.selectedAddress, selectedAccount: state.selectedAccount,
} }
} }
// config substate // config substate
function configToPublic (state) { function configToPublic (state) {
return { return {
provider: state.provider, provider: state.provider,
selectedAddress: state.selectedAccount, selectedAccount: state.selectedAccount,
} }
} }
// dump obj into store // dump obj into store
@ -341,7 +347,7 @@ module.exports = class MetamaskController {
var network = this.state.network var network = this.state.network
var url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH` var url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`
if (network === '2') { if (network === '3') {
url = 'https://faucet.metamask.io/' url = 'https://faucet.metamask.io/'
} }

File diff suppressed because one or more lines are too long

View File

@ -133,7 +133,7 @@
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69" "address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69"
} }
}, },
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "1", "network": "1",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -99,7 +99,7 @@
"status": "confirmed", "status": "confirmed",
"containsDelegateCall": false "containsDelegateCall": false
}], }],
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2", "network": "2",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -57,7 +57,7 @@
} }
}, },
"transactions": [], "transactions": [],
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2", "network": "2",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -89,7 +89,7 @@
} }
}, },
"transactions": [], "transactions": [],
"selectedAddress": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80", "selectedAccount": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80",
"network": "2", "network": "2",
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,
"unconfMsgs": {}, "unconfMsgs": {},

View File

@ -57,7 +57,7 @@
} }
}, },
"transactions": [], "transactions": [],
"selectedAddress": "0x843963b837841dad3b0f5969ff271108776616df", "selectedAccount": "0x843963b837841dad3b0f5969ff271108776616df",
"network": "2", "network": "2",
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,
"unconfMsgs": {}, "unconfMsgs": {},

View File

@ -157,7 +157,7 @@
"estimatedGas": "0x5208" "estimatedGas": "0x5208"
} }
], ],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "166", "network": "166",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -54,7 +54,7 @@
} }
}, },
"transactions": [], "transactions": [],
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2", "network": "2",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -62,7 +62,7 @@
"type": "testnet" "type": "testnet"
}, },
"selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc", "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"seedWords": null "seedWords": null
}, },
"appState": { "appState": {

View File

@ -11,7 +11,7 @@
"conversionDate": 1473358355, "conversionDate": 1473358355,
"accounts": {}, "accounts": {},
"transactions": [], "transactions": [],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1473186153102", "network": "1473186153102",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

File diff suppressed because one or more lines are too long

View File

@ -351,7 +351,7 @@
"hash": "0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e" "hash": "0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e"
} }
], ],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1471904489432", "network": "1471904489432",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}} {"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}

File diff suppressed because one or more lines are too long

View File

@ -52,7 +52,7 @@
"hash": "0xad609a6931f54a575ad71222ffc27cd6746017106d5b89f4ad300b37b273f8ac" "hash": "0xad609a6931f54a575ad71222ffc27cd6746017106d5b89f4ad300b37b273f8ac"
} }
], ],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1479753732793", "network": "1479753732793",
"isConfirmed": true, "isConfirmed": true,
"isEthConfirmed": true, "isEthConfirmed": true,

View File

@ -46,7 +46,7 @@
} }
}, },
"transactions": [], "transactions": [],
"selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825", "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1", "network": "1",
"seedWords": null, "seedWords": null,
"isDisclaimerConfirmed": true, "isDisclaimerConfirmed": true,

View File

@ -33,6 +33,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"ap": "^0.2.0",
"async": "^1.5.2", "async": "^1.5.2",
"bip39": "^2.2.0", "bip39": "^2.2.0",
"browserify-derequire": "^0.9.4", "browserify-derequire": "^0.9.4",

View File

@ -3,9 +3,15 @@ var linkGen = require('../../ui/lib/account-link')
describe('account-link', function() { describe('account-link', function() {
it('adds testnet prefix to morden test network', function() { it('adds morden prefix to morden test network', function() {
var result = linkGen('account', '2') var result = linkGen('account', '2')
assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected') assert.notEqual(result.indexOf('morden'), -1, 'testnet included')
assert.notEqual(result.indexOf('account'), -1, 'account included')
})
it('adds testnet prefix to ropsten test network', function() {
var result = linkGen('account', '3')
assert.notEqual(result.indexOf('testnet'), -1, 'testnet included')
assert.notEqual(result.indexOf('account'), -1, 'account included') assert.notEqual(result.indexOf('account'), -1, 'account included')
}) })

View File

@ -44,6 +44,5 @@ describe('SHOW_ACCOUNT_DETAIL', function() {
var resultingState = reducers(initialState, action) var resultingState = reducers(initialState, action)
assert.equal(resultingState.metamask.selectedAccount, action.value) assert.equal(resultingState.metamask.selectedAccount, action.value)
assert.equal(resultingState.metamask.selectedAddress, action.value)
}) })
}) })

View File

@ -52,7 +52,7 @@ describe('IdentityStore to KeyringController migration', function() {
}, },
}) })
idStore._createVault(password, mockVault.seed, null, (err) => { idStore._createVault(password, mockVault.seed, (err) => {
assert.ifError(err, 'createNewVault threw error') assert.ifError(err, 'createNewVault threw error')
originalKeystore = idStore._idmgmt.keyStore originalKeystore = idStore._idmgmt.keyStore

View File

@ -11,7 +11,6 @@ describe('IdentityStore', function() {
describe('#createNewVault', function () { describe('#createNewVault', function () {
let idStore let idStore
let password = 'password123' let password = 'password123'
let entropy = 'entripppppyy duuude'
let seedWords let seedWords
let accounts = [] let accounts = []
let originalKeystore let originalKeystore
@ -26,7 +25,7 @@ describe('IdentityStore', function() {
}, },
}) })
idStore.createNewVault(password, entropy, (err, seeds) => { idStore.createNewVault(password, (err, seeds) => {
assert.ifError(err, 'createNewVault threw error') assert.ifError(err, 'createNewVault threw error')
seedWords = seeds seedWords = seeds
originalKeystore = idStore._idmgmt.keyStore originalKeystore = idStore._idmgmt.keyStore

View File

@ -12,7 +12,6 @@ describe('KeyringController', function() {
let keyringController, state let keyringController, state
let password = 'password123' let password = 'password123'
let entropy = 'entripppppyy duuude'
let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway' let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway'
let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()] let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()]
let accounts = [] let accounts = []
@ -33,7 +32,7 @@ describe('KeyringController', function() {
// Browser crypto is tested in the integration test suite. // Browser crypto is tested in the integration test suite.
keyringController.encryptor = mockEncryptor keyringController.encryptor = mockEncryptor
keyringController.createNewVaultAndKeychain(password, null, function (err, newState) { keyringController.createNewVaultAndKeychain(password, function (err, newState) {
assert.ifError(err) assert.ifError(err)
state = newState state = newState
done() done()
@ -51,7 +50,7 @@ describe('KeyringController', function() {
it('should set a vault on the configManager', function(done) { it('should set a vault on the configManager', function(done) {
keyringController.configManager.setVault(null) keyringController.configManager.setVault(null)
assert(!keyringController.configManager.getVault(), 'no previous vault') assert(!keyringController.configManager.getVault(), 'no previous vault')
keyringController.createNewVaultAndKeychain(password, null, (err, state) => { keyringController.createNewVaultAndKeychain(password, (err, state) => {
assert.ifError(err) assert.ifError(err)
const vault = keyringController.configManager.getVault() const vault = keyringController.configManager.getVault()
assert(vault, 'vault created') assert(vault, 'vault created')

View File

@ -27,9 +27,9 @@ describe('hd-keyring', function() {
assert.equal(accounts[1], secondAcct) assert.equal(accounts[1], secondAcct)
}) })
describe('Keyring.type()', function() { describe('Keyring.type', function() {
it('is a class method that returns the type string.', function() { it('is a class property that returns the type string.', function() {
const type = HdKeyring.type() const type = HdKeyring.type
assert.equal(typeof type, 'string') assert.equal(typeof type, 'string')
}) })
}) })
@ -37,7 +37,7 @@ describe('hd-keyring', function() {
describe('#type', function() { describe('#type', function() {
it('returns the correct value', function() { it('returns the correct value', function() {
const type = keyring.type const type = keyring.type
const correct = HdKeyring.type() const correct = HdKeyring.type
assert.equal(type, correct) assert.equal(type, correct)
}) })
}) })

View File

@ -13,9 +13,9 @@ describe('simple-keyring', function() {
keyring = new SimpleKeyring() keyring = new SimpleKeyring()
}) })
describe('Keyring.type()', function() { describe('Keyring.type', function() {
it('is a class method that returns the type string.', function() { it('is a class property that returns the type string.', function() {
const type = SimpleKeyring.type() const type = SimpleKeyring.type
assert.equal(type, TYPE_STR) assert.equal(type, TYPE_STR)
}) })
}) })

View File

@ -16,7 +16,7 @@ function AccountListItem () {
AccountListItem.prototype.render = function () { AccountListItem.prototype.render = function () {
const identity = this.props.identity const identity = this.props.identity
var isSelected = this.props.selectedAddress === identity.address var isSelected = this.props.selectedAccount === identity.address
var account = this.props.accounts[identity.address] var account = this.props.accounts[identity.address]
const selectedClass = isSelected ? '.selected' : '' const selectedClass = isSelected ? '.selected' : ''

View File

@ -19,7 +19,7 @@ function mapStateToProps (state) {
accounts: state.metamask.accounts, accounts: state.metamask.accounts,
identities: state.metamask.identities, identities: state.metamask.identities,
unconfTxs: state.metamask.unconfTxs, unconfTxs: state.metamask.unconfTxs,
selectedAddress: state.metamask.selectedAddress, selectedAccount: state.metamask.selectedAccount,
scrollToBottom: state.appState.scrollToBottom, scrollToBottom: state.appState.scrollToBottom,
pending, pending,
} }
@ -72,7 +72,7 @@ AccountsScreen.prototype.render = function () {
return h(AccountListItem, { return h(AccountListItem, {
key: `acct-panel-${identity.address}`, key: `acct-panel-${identity.address}`,
identity, identity,
selectedAddress: this.props.selectedAddress, selectedAccount: this.props.selectedAccount,
accounts: this.props.accounts, accounts: this.props.accounts,
onShowDetail: this.onShowDetail.bind(this), onShowDetail: this.onShowDetail.bind(this),
pending, pending,
@ -133,8 +133,8 @@ AccountsScreen.prototype.navigateToConfTx = function () {
AccountsScreen.prototype.onSelect = function (address, event) { AccountsScreen.prototype.onSelect = function (address, event) {
event.stopPropagation() event.stopPropagation()
// if already selected, deselect // if already selected, deselect
if (this.props.selectedAddress === address) address = null if (this.props.selectedAccount === address) address = null
this.props.dispatch(actions.setSelectedAddress(address)) this.props.dispatch(actions.setSelectedAccount(address))
} }
AccountsScreen.prototype.onShowDetail = function (address, event) { AccountsScreen.prototype.onShowDetail = function (address, event) {

View File

@ -71,7 +71,7 @@ var actions = {
TRANSACTION_ERROR: 'TRANSACTION_ERROR', TRANSACTION_ERROR: 'TRANSACTION_ERROR',
NEXT_TX: 'NEXT_TX', NEXT_TX: 'NEXT_TX',
PREVIOUS_TX: 'PREV_TX', PREVIOUS_TX: 'PREV_TX',
setSelectedAddress: setSelectedAddress, setSelectedAccount: setSelectedAccount,
signMsg: signMsg, signMsg: signMsg,
cancelMsg: cancelMsg, cancelMsg: cancelMsg,
sendTx: sendTx, sendTx: sendTx,
@ -201,9 +201,9 @@ function createNewVaultAndRestore (password, seed) {
} }
} }
function createNewVaultAndKeychain (password, entropy) { function createNewVaultAndKeychain (password) {
return (dispatch) => { return (dispatch) => {
background.createNewVaultAndKeychain(password, entropy, (err) => { background.createNewVaultAndKeychain(password, (err) => {
if (err) { if (err) {
return dispatch(actions.showWarning(err.message)) return dispatch(actions.showWarning(err.message))
} }
@ -221,9 +221,11 @@ function requestRevealSeed (password) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
background.submitPassword(password, (err) => { background.submitPassword(password, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message)) if (err) return dispatch(actions.displayWarning(err.message))
background.placeSeedWords() background.placeSeedWords((err) => {
if (err) return dispatch(actions.displayWarning(err.message))
dispatch(actions.hideLoadingIndication())
})
}) })
} }
} }
@ -259,9 +261,9 @@ function showInfoPage () {
} }
} }
function setSelectedAddress (address) { function setSelectedAccount (address) {
return (dispatch) => { return (dispatch) => {
background.setSelectedAddress(address) background.setSelectedAccount(address)
} }
} }
@ -455,7 +457,7 @@ function lockMetamask () {
function showAccountDetail (address) { function showAccountDetail (address) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
background.setSelectedAddress(address, (err, address) => { background.setSelectedAccount(address, (err, address) => {
dispatch(actions.hideLoadingIndication()) dispatch(actions.hideLoadingIndication())
if (err) { if (err) {
return dispatch(actions.displayWarning(err.message)) return dispatch(actions.displayWarning(err.message))

View File

@ -114,8 +114,8 @@ BuyButtonSubview.prototype.formVersionSubview = function () {
width: '225px', width: '225px',
}, },
}, 'In order to access this feature please switch to the Main Network'), }, 'In order to access this feature please switch to the Main Network'),
h('h3.text-transform-uppercase', 'or:'), this.props.network === '3' ? h('h3.text-transform-uppercase', 'or:') : null,
this.props.network === '2' ? h('button.text-transform-uppercase', { this.props.network === '3' ? h('button.text-transform-uppercase', {
onClick: () => this.props.dispatch(actions.buyEth()), onClick: () => this.props.dispatch(actions.buyEth()),
style: { style: {
marginTop: '15px', marginTop: '15px',

View File

@ -16,7 +16,7 @@ PendingMsgDetails.prototype.render = function () {
var msgData = state.txData var msgData = state.txData
var msgParams = msgData.msgParams || {} var msgParams = msgData.msgParams || {}
var address = msgParams.from || state.selectedAddress var address = msgParams.from || state.selectedAccount
var identity = state.identities[address] || { address: address } var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address } var account = state.accounts[address] || { address: address }

View File

@ -24,7 +24,7 @@ PTXP.render = function () {
var txData = props.txData var txData = props.txData
var txParams = txData.txParams || {} var txParams = txData.txParams || {}
var address = txParams.from || props.selectedAddress var address = txParams.from || props.selectedAccount
var identity = props.identities[address] || { address: address } var identity = props.identities[address] || { address: address }
var account = props.accounts[address] var account = props.accounts[address]
var balance = account ? account.balance : '0x0' var balance = account ? account.balance : '0x0'

View File

@ -18,7 +18,7 @@ function mapStateToProps (state) {
return { return {
identities: state.metamask.identities, identities: state.metamask.identities,
accounts: state.metamask.accounts, accounts: state.metamask.accounts,
selectedAddress: state.metamask.selectedAddress, selectedAccount: state.metamask.selectedAccount,
unconfTxs: state.metamask.unconfTxs, unconfTxs: state.metamask.unconfTxs,
unconfMsgs: state.metamask.unconfMsgs, unconfMsgs: state.metamask.unconfMsgs,
index: state.appState.currentView.context, index: state.appState.currentView.context,
@ -90,12 +90,12 @@ ConfirmTxScreen.prototype.render = function () {
// Properties // Properties
txData: txData, txData: txData,
key: txData.id, key: txData.id,
selectedAddress: state.selectedAddress, selectedAccount: state.selectedAccount,
accounts: state.accounts, accounts: state.accounts,
identities: state.identities, identities: state.identities,
insufficientBalance: this.checkBalnceAgainstTx(txData), insufficientBalance: this.checkBalnceAgainstTx(txData),
// Actions // Actions
buyEth: this.buyEth.bind(this, txParams.from || state.selectedAddress), buyEth: this.buyEth.bind(this, txParams.from || state.selectedAccount),
sendTransaction: this.sendTransaction.bind(this, txData), sendTransaction: this.sendTransaction.bind(this, txData),
cancelTransaction: this.cancelTransaction.bind(this, txData), cancelTransaction: this.cancelTransaction.bind(this, txData),
signMessage: this.signMessage.bind(this, txData), signMessage: this.signMessage.bind(this, txData),
@ -120,7 +120,7 @@ ConfirmTxScreen.prototype.checkBalnceAgainstTx = function (txData) {
var state = this.props var state = this.props
var txParams = txData.txParams || {} var txParams = txData.txParams || {}
var address = txParams.from || state.selectedAddress var address = 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'

View File

@ -165,7 +165,7 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
return return
} }
this.props.dispatch(actions.createNewVaultAndKeychain(password, ''/* entropy*/)) this.props.dispatch(actions.createNewVaultAndKeychain(password))
} }
InitializeMenuScreen.prototype.inputChanged = function (event) { InitializeMenuScreen.prototype.inputChanged = function (event) {

View File

@ -285,7 +285,7 @@ function reduceApp (state, action) {
warning: null, warning: null,
currentView: { currentView: {
name: 'accountDetail', name: 'accountDetail',
context: state.metamask.selectedAddress, context: state.metamask.selectedAccount,
}, },
accountDetail: { accountDetail: {
subview: 'transactions', subview: 'transactions',

View File

@ -98,7 +98,6 @@ function reduceMetamask (state, action) {
isUnlocked: true, isUnlocked: true,
isInitialized: true, isInitialized: true,
selectedAccount: action.value, selectedAccount: action.value,
selectedAddress: action.value,
}) })
delete newState.seedWords delete newState.seedWords
return newState return newState

View File

@ -53,14 +53,14 @@ function addUnconfTx (txParams) {
} }
var isUnlocked = false var isUnlocked = false
var selectedAddress = null var selectedAccount = null
function getState () { function getState () {
return { return {
isUnlocked: isUnlocked, isUnlocked: isUnlocked,
identities: isUnlocked ? identities : {}, identities: isUnlocked ? identities : {},
unconfTxs: isUnlocked ? unconfTxs : {}, unconfTxs: isUnlocked ? unconfTxs : {},
selectedAddress: selectedAddress, selectedAccount: selectedAccount,
} }
} }
@ -85,8 +85,8 @@ accountManager.submitPassword = function (password, cb) {
} }
} }
accountManager.setSelectedAddress = function (address, cb) { accountManager.setSelectedAccount = function (address, cb) {
selectedAddress = address selectedAccount = address
cb(null, getState()) cb(null, getState())
this._didUpdate() this._didUpdate()
} }

View File

@ -7,10 +7,10 @@ module.exports = function (address, network) {
link = `http://etherscan.io/address/${address}` link = `http://etherscan.io/address/${address}`
break break
case 2: // morden test net case 2: // morden test net
link = `http://testnet.etherscan.io/address/${address}` link = `http://morden.etherscan.io/address/${address}`
break break
case 3: // ropsten test net case 3: // ropsten test net
link = '' link = `http://testnet.etherscan.io/address/${address}`
break break
default: default:
link = '' link = ''