aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/contentscript.js36
-rw-r--r--app/scripts/inpage.js21
-rw-r--r--app/scripts/keyring-controller.js44
-rw-r--r--app/scripts/lib/auto-reload.js22
-rw-r--r--app/scripts/lib/config-manager.js44
-rw-r--r--app/scripts/lib/id-management.js7
-rw-r--r--app/scripts/lib/idStore.js14
-rw-r--r--app/scripts/lib/inpage-provider.js17
-rw-r--r--app/scripts/lib/obj-multiplex.js8
-rw-r--r--app/scripts/lib/port-stream.js3
-rw-r--r--app/scripts/metamask-controller.js13
12 files changed, 184 insertions, 47 deletions
diff --git a/app/manifest.json b/app/manifest.json
index badeb7cb2..8f5a34ea6 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "2.13.3",
+ "version": "2.13.5",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index b3a560c88..e2a968ac9 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -1,4 +1,5 @@
const LocalMessageDuplexStream = require('post-message-stream')
+const PongStream = require('ping-pong-stream/pong')
const PortStream = require('./lib/port-stream.js')
const ObjectMultiplex = require('./lib/obj-multiplex')
const extension = require('./lib/extension')
@@ -51,20 +52,35 @@ function setupStreams(){
// forward communication plugin->inpage
pageStream.pipe(pluginStream).pipe(pageStream)
- // connect contentscript->inpage reload stream
+ // setup local multistream channels
var mx = ObjectMultiplex()
mx.on('error', console.error)
- mx.pipe(pageStream)
- var reloadStream = mx.createStream('reload')
- reloadStream.on('error', console.error)
+ mx.pipe(pageStream).pipe(mx)
+
+ // connect ping stream
+ var pongStream = new PongStream({ objectMode: true })
+ pongStream.pipe(mx.createStream('pingpong')).pipe(pongStream)
+
+ // ignore unused channels (handled by background)
+ mx.ignoreStream('provider')
+ mx.ignoreStream('publicConfig')
+ mx.ignoreStream('reload')
- // if we lose connection with the plugin, trigger tab refresh
- pluginStream.on('close', function () {
- reloadStream.write({ method: 'reset' })
- })
}
function shouldInjectWeb3(){
- var shouldInject = (window.location.href.indexOf('.pdf') === -1)
- return shouldInject
+ return isAllowedSuffix(window.location.href)
+}
+
+function isAllowedSuffix(testCase) {
+ var prohibitedTypes = ['xml', 'pdf']
+ var currentUrl = window.location.href
+ var currentRegex
+ for (let i = 0; i < prohibitedTypes.length; i++) {
+ currentRegex = new RegExp(`\.${prohibitedTypes[i]}$`)
+ if (currentRegex.test(currentUrl)) {
+ return false
+ }
+ }
+ return true
}
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 28a1223ac..85dd70b4d 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -2,6 +2,8 @@
cleanContextForImports()
require('web3/dist/web3.min.js')
const LocalMessageDuplexStream = require('post-message-stream')
+const PingStream = require('ping-pong-stream/ping')
+const endOfStream = require('end-of-stream')
const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
@@ -29,13 +31,22 @@ web3.setProvider = function () {
console.log('MetaMask - overrode web3.setProvider')
}
console.log('MetaMask - injected web3')
+// export global web3, with usage-detection reload fn
+var triggerReload = setupDappAutoReload(web3)
-//
-// export global web3 with auto dapp reload
-//
-
+// listen for reset requests from metamask
var reloadStream = inpageProvider.multiStream.createStream('reload')
-setupDappAutoReload(web3, reloadStream)
+reloadStream.once('data', triggerReload)
+
+// setup ping timeout autoreload
+// LocalMessageDuplexStream does not self-close, so reload if pingStream fails
+var pingChannel = inpageProvider.multiStream.createStream('pingpong')
+var pingStream = new PingStream({ objectMode: true })
+// wait for first successful reponse
+metamaskStream.once('_data', function(){
+ pingStream.pipe(pingChannel).pipe(pingStream)
+})
+endOfStream(pingStream, triggerReload)
// set web3 defaultAcount
inpageProvider.publicConfigStore.subscribe(function (state) {
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index d96b9c101..db7e5e61e 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -1,7 +1,7 @@
-const scrypt = require('scrypt-async')
-const bitcore = require('bitcore-lib')
-const configManager = require('./lib/config-manager')
const EventEmitter = require('events').EventEmitter
+const encryptor = require('./lib/encryptor')
+const messageManager = require('./lib/message-manager')
+
module.exports = class KeyringController extends EventEmitter {
@@ -12,12 +12,17 @@ module.exports = class KeyringController extends EventEmitter {
this.keyChains = []
}
+ keyFromPassword(password, callback) {
+ deriveKeyFromPassword(password, callback);
+ }
+
+ // Takes a pw and callback, returns a password-dervied key
getKeyForPassword(password, callback) {
let salt = this.configManager.getSalt()
if (!salt) {
salt = generateSalt(32)
- configManager.setSalt(salt)
+ this.configManager.setSalt(salt)
}
var logN = 14
@@ -39,7 +44,21 @@ module.exports = class KeyringController extends EventEmitter {
}
getState() {
- return {}
+ return {
+ isInitialized: !!this.key,
+ isUnlocked: !!this.key,
+ isConfirmed: true, // this.configManager.getConfirmed(),
+ isEthConfirmed: this.configManager.getShouldntShowWarning(),
+ unconfTxs: this.configManager.unconfirmedTxs(),
+ transactions: this.configManager.getTxList(),
+ unconfMsgs: messageManager.unconfirmedMsgs(),
+ messages: messageManager.getMsgList(),
+ selectedAddress: this.configManager.getSelectedAccount(),
+ shapeShiftTxList: this.configManager.getShapeShiftTxList(),
+ currentFiat: this.configManager.getCurrentFiat(),
+ conversionRate: this.configManager.getConversionRate(),
+ conversionDate: this.configManager.getConversionDate(),
+ }
}
setStore(ethStore) {
@@ -47,9 +66,22 @@ module.exports = class KeyringController extends EventEmitter {
}
createNewVault(password, entropy, cb) {
- cb()
+ encryptor.keyFromPassword(password)
+ .then((key) => {
+ this.key = key
+ return encryptor.encryptWithKey(key, {})
+ })
+ .then((encryptedString) => {
+ this.configManager.setVault(encryptedString)
+ cb(null, [])
+ })
+ .catch((err) => {
+ cb(err)
+ })
}
+
+
submitPassword(password, cb) {
cb()
}
diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js
index c4c8053f0..3c90905db 100644
--- a/app/scripts/lib/auto-reload.js
+++ b/app/scripts/lib/auto-reload.js
@@ -3,7 +3,7 @@ const ensnare = require('ensnare')
module.exports = setupDappAutoReload
-function setupDappAutoReload (web3, controlStream) {
+function setupDappAutoReload (web3) {
// export web3 as a global, checking for usage
var pageIsUsingWeb3 = false
var resetWasRequested = false
@@ -16,19 +16,19 @@ function setupDappAutoReload (web3, controlStream) {
global.web3 = web3
}))
- // listen for reset requests from metamask
- controlStream.once('data', function () {
+ return handleResetRequest
+
+ function handleResetRequest() {
resetWasRequested = true
// ignore if web3 was not used
if (!pageIsUsingWeb3) return
// reload after short timeout
- triggerReset()
- })
-
- // reload the page
- function triggerReset () {
- setTimeout(function () {
- global.location.reload()
- }, 500)
+ setTimeout(triggerReset, 500)
}
+
}
+
+// reload the page
+function triggerReset () {
+ global.location.reload()
+} \ No newline at end of file
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index ecc9bc5f7..d12304c46 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -110,6 +110,27 @@ ConfigManager.prototype.setWallet = function (wallet) {
this.setData(data)
}
+ConfigManager.prototype.setVault = function (encryptedString) {
+ var data = this.getData()
+ data.vault = encryptedString
+ this.setData(data)
+}
+
+ConfigManager.prototype.getVault = function () {
+ var data = this.getData()
+ return ('vault' in data) && data.vault
+}
+
+ConfigManager.prototype.getKeychains = function () {
+ return this.migrator.getData().keychains || []
+}
+
+ConfigManager.prototype.setKeychains = function (keychains) {
+ var data = this.migrator.getData()
+ data.keychains = keychains
+ this.setData(data)
+}
+
ConfigManager.prototype.getSelectedAccount = function () {
var config = this.getConfig()
return config.selectedAccount
@@ -249,6 +270,17 @@ ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
// observable
+ConfigManager.prototype.getSalt = function () {
+ var data = this.getData()
+ return ('salt' in data) && data.salt
+}
+
+ConfigManager.prototype.setSalt = function(salt) {
+ var data = this.getData()
+ data.salt = salt
+ this.setData(data)
+}
+
ConfigManager.prototype.subscribe = function (fn) {
this._subs.push(fn)
var unsubscribe = this.unsubscribe.bind(this, fn)
@@ -384,3 +416,15 @@ ConfigManager.prototype.createShapeShiftTx = function (depositAddress, depositTy
}
this.setData(data)
}
+
+ConfigManager.prototype.getGasMultiplier = function () {
+ var data = this.getData()
+ return ('gasMultiplier' in data) && data.gasMultiplier
+}
+
+ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) {
+ var data = this.getData()
+
+ data.gasMultiplier = gasMultiplier
+ this.setData(data)
+}
diff --git a/app/scripts/lib/id-management.js b/app/scripts/lib/id-management.js
index 2d42e1e30..421f2105f 100644
--- a/app/scripts/lib/id-management.js
+++ b/app/scripts/lib/id-management.js
@@ -7,6 +7,7 @@
*/
const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
const Transaction = require('ethereumjs-tx')
module.exports = IdManagement
@@ -24,7 +25,13 @@ function IdManagement (opts) {
}
this.signTx = function (txParams) {
+ // calculate gas with custom gas multiplier
+ var gasMultiplier = this.configManager.getGasMultiplier() || 1
+ var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16)
+ gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10))
+ txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber())
// normalize values
+
txParams.to = ethUtil.addHexPrefix(txParams.to)
txParams.from = ethUtil.addHexPrefix(txParams.from.toLowerCase())
txParams.value = ethUtil.addHexPrefix(txParams.value)
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index 6837a1e8d..9d0ca7f19 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -2,6 +2,7 @@ const EventEmitter = require('events').EventEmitter
const inherits = require('util').inherits
const async = require('async')
const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
const EthQuery = require('eth-query')
const KeyStore = require('eth-lightwallet').keystore
const clone = require('clone')
@@ -112,6 +113,8 @@ IdentityStore.prototype.getState = function () {
currentFiat: configManager.getCurrentFiat(),
conversionRate: configManager.getConversionRate(),
conversionDate: configManager.getConversionDate(),
+ gasMultiplier: configManager.getGasMultiplier(),
+
}))
}
@@ -211,6 +214,7 @@ IdentityStore.prototype.exportAccount = function (address, cb) {
// comes from dapp via zero-client hooked-wallet provider
IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDoneCb, cb) {
const configManager = this.configManager
+
var self = this
// create txData obj with parameters and meta data
var time = (new Date()).getTime()
@@ -222,6 +226,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
txParams: txParams,
time: time,
status: 'unconfirmed',
+ gasMultiplier: configManager.getGasMultiplier() || 1,
}
console.log('addUnconfirmedTransaction:', txData)
@@ -262,7 +267,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
function estimateGas(cb){
query.estimateGas(txParams, function(err, result){
if (err) return cb(err)
- txData.estimatedGas = result
+ txData.estimatedGas = self.addGasBuffer(result)
cb()
})
}
@@ -277,6 +282,13 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
}
}
+IdentityStore.prototype.addGasBuffer = function (gasHex) {
+ var gas = new BN(gasHex, 16)
+ var buffer = new BN('100000', 10)
+ var result = gas.add(buffer)
+ return ethUtil.addHexPrefix(result.toString(16))
+}
+
// comes from metamask ui
IdentityStore.prototype.approveTransaction = function (txId, cb) {
const configManager = this.configManager
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index bcde333d0..c6bfdb4da 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -1,6 +1,6 @@
const Streams = require('mississippi')
-const ObjectMultiplex = require('./obj-multiplex')
const StreamProvider = require('web3-stream-provider')
+const ObjectMultiplex = require('./obj-multiplex')
const RemoteStore = require('./remote-store.js').RemoteStore
module.exports = MetamaskInpageProvider
@@ -11,8 +11,9 @@ function MetamaskInpageProvider (connectionStream) {
// setup connectionStream multiplexing
var multiStream = ObjectMultiplex()
Streams.pipe(connectionStream, multiStream, connectionStream, function (err) {
- console.warn('MetamaskInpageProvider - lost connection to MetaMask')
- if (err) throw err
+ let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask'
+ if (err) warningMsg += '\n' + err.stack
+ console.warn(warningMsg)
})
self.multiStream = multiStream
@@ -20,16 +21,18 @@ function MetamaskInpageProvider (connectionStream) {
var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config')
var storeStream = publicConfigStore.createStream()
Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function (err) {
- console.warn('MetamaskInpageProvider - lost connection to MetaMask publicConfig')
- if (err) throw err
+ let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask publicConfig'
+ if (err) warningMsg += '\n' + err.stack
+ console.warn(warningMsg)
})
self.publicConfigStore = publicConfigStore
// connect to async provider
var asyncProvider = new StreamProvider()
Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function (err) {
- console.warn('MetamaskInpageProvider - lost connection to MetaMask provider')
- if (err) throw err
+ let warningMsg = 'MetamaskInpageProvider - lost connection to MetaMask provider'
+ if (err) warningMsg += '\n' + err.stack
+ console.warn(warningMsg)
})
asyncProvider.on('error', console.error.bind(console))
self.asyncProvider = asyncProvider
diff --git a/app/scripts/lib/obj-multiplex.js b/app/scripts/lib/obj-multiplex.js
index f54ff7653..bd114c394 100644
--- a/app/scripts/lib/obj-multiplex.js
+++ b/app/scripts/lib/obj-multiplex.js
@@ -10,9 +10,9 @@ function ObjectMultiplex (opts) {
var data = chunk.data
var substream = mx.streams[name]
if (!substream) {
- console.warn('orphaned data for stream ' + name)
+ console.warn(`orphaned data for stream "${name}"`)
} else {
- substream.push(data)
+ if (substream.push) substream.push(data)
}
return cb()
})
@@ -36,5 +36,9 @@ function ObjectMultiplex (opts) {
}
return substream
}
+ // ignore streams (dont display orphaned data warning)
+ mx.ignoreStream = function (name) {
+ mx.streams[name] = true
+ }
return mx
}
diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js
index 6f59d4485..6f4ccc6ab 100644
--- a/app/scripts/lib/port-stream.js
+++ b/app/scripts/lib/port-stream.js
@@ -53,8 +53,7 @@ PortDuplexStream.prototype._write = function (msg, encoding, cb) {
}
cb()
} catch (err) {
- console.error(err)
- // this.emit('error', err)
+ // console.error(err)
cb(new Error('PortDuplexStream - disconnected'))
}
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 462c132e6..92551d633 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -57,6 +57,7 @@ module.exports = class MetamaskController {
agreeToEthWarning: this.agreeToEthWarning.bind(this),
setTOSHash: this.setTOSHash.bind(this),
checkTOSChange: this.checkTOSChange.bind(this),
+ setGasMultiplier: this.setGasMultiplier.bind(this),
// forward directly to idStore
createNewVault: idStore.createNewVault.bind(idStore),
@@ -278,9 +279,9 @@ module.exports = class MetamaskController {
checkTOSChange () {
try {
const storedHash = this.configManager.getTOSHash() || 0
- if (storedHash !== global.newTOSHash) {
+ if (storedHash !== global.TOS_HASH) {
this.resetDisclaimer()
- this.setTOSHash(global.newTOSHash)
+ this.setTOSHash(global.TOS_HASH)
}
} catch (e) {
console.error('Error in checking TOS change.')
@@ -395,4 +396,12 @@ module.exports = class MetamaskController {
})
}
+ setGasMultiplier (gasMultiplier, cb) {
+ try {
+ this.configManager.setGasMultiplier(gasMultiplier)
+ cb()
+ } catch (e) {
+ cb(e)
+ }
+ }
}