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

Merge pull request #1802 from MetaMask/RestructureNewUI

Restructure new ui branch folders
This commit is contained in:
Dan Finlay 2017-07-20 14:05:12 -07:00 committed by GitHub
commit 6553c9c64b
268 changed files with 645 additions and 295 deletions

View File

@ -2,8 +2,38 @@
## Current Master
## 3.9.1 2017-7-19
- No longer automatically request 1 ropsten ether for the first account in a new vault.
- Now redirects from known malicious sites faster.
- Added a link to our new support page to the help screen.
- Fixed bug where a new transaction would be shown over the current transaction, creating a possible timing attack against user confirmation.
- Fixed bug in nonce tracker where an incorrect nonce would be calculated.
- Lowered minimum gas price to 1 Gwei.
## 3.9.0 2017-7-12
- Now detects and blocks known phishing sites.
## 3.8.6 2017-7-11
- Make transaction resubmission more resilient.
- No longer validate nonce client-side in retry loop.
- Fix bug where insufficient balance error was sometimes shown on successful transactions.
## 3.8.5 2017-7-7
- Fix transaction resubmit logic to fail slightly less eagerly.
## 3.8.4 2017-7-7
- Improve transaction resubmit logic to fail more eagerly when a user would expect it to.
## 3.8.3 2017-7-6
- Re-enable default token list.
- Add origin header to dapp-bound requests to allow providers to throttle sites.
- Fix bug that could sometimes resubmit a transaction that had been stalled due to low balance after balance was restored.
## 3.8.2 2017-7-3

View File

@ -1,10 +1,20 @@
# MetaMask Plugin [![Build Status](https://circleci.com/gh/MetaMask/metamask-plugin.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-plugin)
# MetaMask Plugin [![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension)
## Support
If you're a user seeking support, [here is our support site](http://metamask.consensyssupport.happyfox.com).
## Developing Compatible Dapps
If you're a web dapp developer, we've got two types of guides for you:
- If you've never built a Dapp before, we've got a gentle introduction on [Developing Dapps with Truffle and MetaMask](https://blog.metamask.io/developing-for-metamask-with-truffle/).
### New Dapp Developers
- We recommend this [Learning Solidity](https://karl.tech/learning-solidity-part-1-deploy-a-contract/) tutorial series by Karl Floersch.
- We wrote a (slightly outdated now) gentle introduction on [Developing Dapps with Truffle and MetaMask](https://medium.com/metamask/developing-ethereum-dapps-with-truffle-and-metamask-aa8ad7e363ba).
### Current Dapp Developers
- If you have a Dapp, and you want to ensure compatibility, [here is our guide on building MetaMask-compatible Dapps](https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md)
## Building locally

View File

@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
"version": "3.8.2",
"version": "3.9.1",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
@ -52,6 +52,11 @@
],
"run_at": "document_start",
"all_frames": true
},
{
"run_at": "document_start",
"matches": ["http://*/*", "https://*/*"],
"js": ["scripts/blacklister.js"]
}
],
"permissions": [

View File

@ -0,0 +1,13 @@
const blacklistedDomains = require('etheraddresslookup/blacklists/domains.json')
function detectBlacklistedDomain() {
var strCurrentTab = window.location.hostname
if (blacklistedDomains && blacklistedDomains.includes(strCurrentTab)) {
window.location.href = 'https://metamask.io/phishing.html'
}
}
window.addEventListener('load', function() {
detectBlacklistedDomain()
})

View File

@ -26,6 +26,7 @@ class InfuraController {
this.store.updateState({
infuraNetworkStatus: parsedResponse,
})
return parsedResponse
})
}

View File

@ -1,12 +1,12 @@
const EventEmitter = require('events')
const async = require('async')
const extend = require('xtend')
const Semaphore = require('semaphore')
const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util')
const pify = require('pify')
const TxProviderUtil = require('../lib/tx-utils')
const createId = require('../lib/random-id')
const denodeify = require('denodeify')
const NonceTracker = require('../lib/nonce-tracker')
module.exports = class TransactionController extends EventEmitter {
constructor (opts) {
@ -20,13 +20,26 @@ module.exports = class TransactionController extends EventEmitter {
this.txHistoryLimit = opts.txHistoryLimit
this.provider = opts.provider
this.blockTracker = opts.blockTracker
this.nonceTracker = new NonceTracker({
provider: this.provider,
blockTracker: this.provider._blockTracker,
getPendingTransactions: (address) => {
return this.getFilteredTxList({
from: address,
status: 'submitted',
err: undefined,
})
},
})
this.query = opts.ethQuery
this.txProviderUtils = new TxProviderUtil(this.query)
this.blockTracker.on('rawBlock', this.checkForTxInBlock.bind(this))
this.blockTracker.on('latest', this.resubmitPendingTxs.bind(this))
// this is a little messy but until ethstore has been either
// removed or redone this is to guard against the race condition
// where ethStore hasent been populated by the results yet
this.blockTracker.once('latest', () => this.blockTracker.on('latest', this.resubmitPendingTxs.bind(this)))
this.blockTracker.on('sync', this.queryPendingTxs.bind(this))
this.signEthTx = opts.signTransaction
this.nonceLock = Semaphore(1)
this.ethStore = opts.ethStore
// memstore is computed from a few different stores
this._updateMemstore()
@ -170,29 +183,32 @@ module.exports = class TransactionController extends EventEmitter {
}, {})
}
approveTransaction (txId, cb = warn) {
const self = this
async approveTransaction (txId) {
let nonceLock
try {
// approve
self.setTxStatusApproved(txId)
// only allow one tx at a time for atomic nonce usage
self.nonceLock.take(() => {
// begin signature process
async.waterfall([
(cb) => self.fillInTxParams(txId, cb),
(cb) => self.signTransaction(txId, cb),
(rawTx, cb) => self.publishTransaction(txId, rawTx, cb),
], (err) => {
self.nonceLock.leave()
if (err) {
this.setTxStatusApproved(txId)
// get next nonce
const txMeta = this.getTx(txId)
const fromAddress = txMeta.txParams.from
nonceLock = await this.nonceTracker.getNonceLock(fromAddress)
txMeta.txParams.nonce = nonceLock.nextNonce
this.updateTx(txMeta)
// sign transaction
const rawTx = await this.signTransaction(txId)
await this.publishTransaction(txId, rawTx)
// must set transaction to submitted/failed before releasing lock
nonceLock.releaseLock()
} catch (err) {
this.setTxStatusFailed(txId, {
errCode: err.errCode || err,
message: err.message || 'Transaction failed during approval',
})
return cb(err)
// must set transaction to submitted/failed before releasing lock
if (nonceLock) nonceLock.releaseLock()
// continue with error chain
throw err
}
cb()
})
})
}
cancelTransaction (txId, cb = warn) {
@ -200,13 +216,9 @@ module.exports = class TransactionController extends EventEmitter {
cb()
}
fillInTxParams (txId, cb) {
const txMeta = this.getTx(txId)
this.txProviderUtils.fillInTxParams(txMeta.txParams, (err) => {
if (err) return cb(err)
async updateAndApproveTransaction (txMeta) {
this.updateTx(txMeta)
cb()
})
await this.approveTransaction(txMeta.id)
}
getChainId () {
@ -219,31 +231,27 @@ module.exports = class TransactionController extends EventEmitter {
}
}
signTransaction (txId, cb) {
async signTransaction (txId) {
const txMeta = this.getTx(txId)
const txParams = txMeta.txParams
const fromAddress = txParams.from
// add network/chain id
txParams.chainId = this.getChainId()
const ethTx = this.txProviderUtils.buildEthTxFromParams(txParams)
this.signEthTx(ethTx, fromAddress).then(() => {
const rawTx = await this.signEthTx(ethTx, fromAddress).then(() => {
this.setTxStatusSigned(txMeta.id)
cb(null, ethUtil.bufferToHex(ethTx.serialize()))
}).catch((err) => {
cb(err)
return ethUtil.bufferToHex(ethTx.serialize())
})
return rawTx
}
publishTransaction (txId, rawTx, cb = warn) {
async publishTransaction (txId, rawTx) {
const txMeta = this.getTx(txId)
txMeta.rawTx = rawTx
this.updateTx(txMeta)
this.txProviderUtils.publishTransaction(rawTx, (err, txHash) => {
if (err) return cb(err)
await this.txProviderUtils.publishTransaction(rawTx).then((txHash) => {
this.setTxHash(txId, txHash)
this.setTxStatusSubmitted(txId)
cb()
})
}
@ -261,10 +269,19 @@ module.exports = class TransactionController extends EventEmitter {
to: '0x0..',
from: '0x0..',
status: 'signed',
err: undefined,
}
and returns a list of tx with all
options matching
****************HINT****************
| `err: undefined` is like looking |
| for a tx with no err |
| so you can also search txs that |
| dont have something as well by |
| setting the value as undefined |
************************************
this is for things like filtering a the tx list
for only tx's from 1 account
or for filltering for all txs from one account
@ -413,65 +430,103 @@ module.exports = class TransactionController extends EventEmitter {
const pending = this.getTxsByMetaData('status', 'submitted')
// only try resubmitting if their are transactions to resubmit
if (!pending.length) return
const resubmit = denodeify(this._resubmitTx.bind(this))
Promise.all(pending.map(txMeta => resubmit(txMeta)))
.catch((reason) => {
log.info('Problem resubmitting tx', reason)
pending.forEach((txMeta) => this._resubmitTx(txMeta).catch((err) => {
/*
Dont marked as failed if the error is a "known" transaction warning
"there is already a transaction with the same sender-nonce
but higher/same gas price"
*/
const errorMessage = err.message.toLowerCase()
const isKnownTx = (
// geth
errorMessage.includes('replacement transaction underpriced')
|| errorMessage.includes('known transaction')
// parity
|| errorMessage.includes('gas price too low to replace')
|| errorMessage.includes('transaction with the same hash was already imported')
// other
|| errorMessage.includes('gateway timeout')
|| errorMessage.includes('nonce too low')
)
// ignore resubmit warnings, return early
if (isKnownTx) return
// encountered real error - transition to error state
this.setTxStatusFailed(txMeta.id, {
errCode: err.errCode || err,
message: err.message,
})
}))
}
_resubmitTx (txMeta, cb) {
async _resubmitTx (txMeta, cb) {
const address = txMeta.txParams.from
const balance = this.ethStore.getState().accounts[address].balance
const nonce = Number.parseInt(this.ethStore.getState().accounts[address].nonce)
const txNonce = Number.parseInt(txMeta.txParams.nonce)
const gtBalance = Number.parseInt(txMeta.txParams.value) > Number.parseInt(balance)
if (!('retryCount' in txMeta)) txMeta.retryCount = 0
// if the value of the transaction is greater then the balance
// or the nonce of the transaction is lower then the accounts nonce
// dont resubmit the tx
if (gtBalance || txNonce < nonce) return cb()
// if the value of the transaction is greater then the balance, fail.
if (!this.txProviderUtils.sufficientBalance(txMeta.txParams, balance)) {
const message = 'Insufficient balance.'
this.setTxStatusFailed(txMeta.id, { message })
cb()
return log.error(message)
}
// Only auto-submit already-signed txs:
if (!('rawTx' in txMeta)) return cb()
// Increment a try counter.
txMeta.retryCount++
const rawTx = txMeta.rawTx
this.txProviderUtils.publishTransaction(rawTx, cb)
return await this.txProviderUtils.publishTransaction(rawTx, cb)
}
// checks the network for signed txs and
// if confirmed sets the tx status as 'confirmed'
_checkPendingTxs () {
var signedTxList = this.getFilteredTxList({status: 'submitted'})
if (!signedTxList.length) return
signedTxList.forEach((txMeta) => {
var txHash = txMeta.hash
var txId = txMeta.id
async _checkPendingTxs () {
const signedTxList = this.getFilteredTxList({status: 'submitted'})
// in order to keep the nonceTracker accurate we block it while updating pending transactions
const nonceGlobalLock = await this.nonceTracker.getGlobalLock()
try {
await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta)))
} catch (err) {
console.error('TransactionController - Error updating pending transactions')
console.error(err)
}
nonceGlobalLock.releaseLock()
}
async _checkPendingTx (txMeta) {
const txHash = txMeta.hash
const txId = txMeta.id
// extra check in case there was an uncaught error during the
// signature and submission process
if (!txHash) {
const errReason = {
errCode: 'No hash was provided',
message: 'We had an error while submitting this transaction, please try again.',
}
return this.setTxStatusFailed(txId, errReason)
this.setTxStatusFailed(txId, errReason)
return
}
this.query.getTransactionByHash(txHash, (err, txParams) => {
if (err || !txParams) {
// get latest transaction status
let txParams
try {
txParams = await pify((cb) => this.query.getTransactionByHash(txHash, cb))()
if (!txParams) return
if (txParams.blockNumber) {
this.setTxStatusConfirmed(txId)
}
} catch (err) {
if (err || !txParams) {
txMeta.err = {
isWarning: true,
errorCode: err,
message: 'There was a problem loading this transaction.',
}
this.updateTx(txMeta)
return log.error(err)
log.error(err)
}
if (txParams.blockNumber) {
this.setTxStatusConfirmed(txId)
}
})
})
}
}

View File

@ -1,20 +0,0 @@
const uri = 'https://faucet.metamask.io/'
const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
const env = process.env.METAMASK_ENV
module.exports = function (address) {
// Don't faucet in development or test
if (METAMASK_DEBUG === true || env === 'test') return
global.log.info('auto-fauceting:', address)
const data = address
const headers = new Headers()
headers.append('Content-type', 'application/rawdata')
fetch(uri, {
method: 'POST',
headers,
body: data,
})
.catch((err) => {
console.error(err)
})
}

View File

@ -1,24 +1,9 @@
module.exports = function (promiseFn) {
return function () {
var args = []
for (var i = 0; i < arguments.length - 1; i++) {
args.push(arguments[i])
}
var cb = arguments[arguments.length - 1]
const promiseToCallback = require('promise-to-callback')
const nodeified = promiseFn.apply(this, args)
if (!nodeified) {
const methodName = String(promiseFn).split('(')[0]
throw new Error(`The ${methodName} did not return a Promise, but was nodeified.`)
}
nodeified.then(function (result) {
cb(null, result)
})
.catch(function (reason) {
cb(reason)
})
return nodeified
module.exports = function(fn, context) {
return function(){
const args = [].slice.call(arguments)
const callback = args.pop()
promiseToCallback(fn.apply(context, args))(callback)
}
}

View File

@ -0,0 +1,84 @@
const EthQuery = require('eth-query')
const assert = require('assert')
const Mutex = require('await-semaphore').Mutex
class NonceTracker {
constructor ({ blockTracker, provider, getPendingTransactions }) {
this.blockTracker = blockTracker
this.ethQuery = new EthQuery(provider)
this.getPendingTransactions = getPendingTransactions
this.lockMap = {}
}
async getGlobalLock () {
const globalMutex = this._lookupMutex('global')
// await global mutex free
const releaseLock = await globalMutex.acquire()
return { releaseLock }
}
// releaseLock must be called
// releaseLock must be called after adding signed tx to pending transactions (or discarding)
async getNonceLock (address) {
// await global mutex free
await this._globalMutexFree()
// await lock free, then take lock
const releaseLock = await this._takeMutex(address)
// calculate next nonce
// we need to make sure our base count
// and pending count are from the same block
const currentBlock = await this._getCurrentBlock()
const pendingTransactions = this.getPendingTransactions(address)
const pendingCount = pendingTransactions.length
assert(Number.isInteger(pendingCount), 'nonce-tracker - pendingCount is an integer')
const baseCountHex = await this._getTxCount(address, currentBlock)
const baseCount = parseInt(baseCountHex, 16)
assert(Number.isInteger(baseCount), 'nonce-tracker - baseCount is an integer')
const nextNonce = baseCount + pendingCount
assert(Number.isInteger(nextNonce), 'nonce-tracker - nextNonce is an integer')
// return next nonce and release cb
return { nextNonce, releaseLock }
}
async _getCurrentBlock () {
const currentBlock = this.blockTracker.getCurrentBlock()
if (currentBlock) return currentBlock
return await Promise((reject, resolve) => {
this.blockTracker.once('latest', resolve)
})
}
async _getTxCount (address, currentBlock) {
const blockNumber = currentBlock.number
return new Promise((resolve, reject) => {
this.ethQuery.getTransactionCount(address, blockNumber, (err, result) => {
err ? reject(err) : resolve(result)
})
})
}
async _globalMutexFree () {
const globalMutex = this._lookupMutex('global')
const release = await globalMutex.acquire()
release()
}
async _takeMutex (lockId) {
const mutex = this._lookupMutex(lockId)
const releaseLock = await mutex.acquire()
return releaseLock
}
_lookupMutex (lockId) {
let mutex = this.lockMap[lockId]
if (!mutex) {
mutex = new Mutex()
this.lockMap[lockId] = mutex
}
return mutex
}
}
module.exports = NonceTracker

View File

@ -106,8 +106,13 @@ module.exports = class txProviderUtils {
return ethTx
}
publishTransaction (rawTx, cb) {
this.query.sendRawTransaction(rawTx, cb)
publishTransaction (rawTx) {
return new Promise((resolve, reject) => {
this.query.sendRawTransaction(rawTx, (err, ress) => {
if (err) reject(err)
else resolve(ress)
})
})
}
validateTxParams (txParams, cb) {
@ -118,6 +123,15 @@ module.exports = class txProviderUtils {
}
}
sufficientBalance (txParams, hexBalance) {
const balance = hexToBn(hexBalance)
const value = hexToBn(txParams.value)
const gasLimit = hexToBn(txParams.gas)
const gasPrice = hexToBn(txParams.gasPrice)
const maxCost = value.add(gasLimit.mul(gasPrice))
return balance.gte(maxCost)
}
}

View File

@ -20,7 +20,6 @@ const MessageManager = require('./lib/message-manager')
const PersonalMessageManager = require('./lib/personal-message-manager')
const TransactionController = require('./controllers/transactions')
const ConfigManager = require('./lib/config-manager')
const autoFaucet = require('./lib/auto-faucet')
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
const getBuyEthUrl = require('./lib/buy-eth-url')
@ -90,9 +89,6 @@ module.exports = class MetamaskController extends EventEmitter {
this.keyringController.on('newAccount', (address) => {
this.preferencesController.setSelectedAddress(address)
})
this.keyringController.on('newVault', (address) => {
autoFaucet(address)
})
// address book controller
this.addressBookController = new AddressBookController({
@ -294,34 +290,33 @@ module.exports = class MetamaskController extends EventEmitter {
submitPassword: this.submitPassword.bind(this),
// PreferencesController
setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController),
addToken: nodeify(preferencesController.addToken).bind(preferencesController),
setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab).bind(preferencesController),
setDefaultRpc: nodeify(this.setDefaultRpc).bind(this),
setCustomRpc: nodeify(this.setCustomRpc).bind(this),
setSelectedAddress: nodeify(preferencesController.setSelectedAddress, preferencesController),
addToken: nodeify(preferencesController.addToken, preferencesController),
setCurrentAccountTab: nodeify(preferencesController.setCurrentAccountTab, preferencesController),
setDefaultRpc: nodeify(this.setDefaultRpc, this),
setCustomRpc: nodeify(this.setCustomRpc, this),
// AddressController
setAddressBook: nodeify(addressBookController.setAddressBook).bind(addressBookController),
setAddressBook: nodeify(addressBookController.setAddressBook, addressBookController),
// KeyringController
setLocked: nodeify(keyringController.setLocked).bind(keyringController),
createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController),
createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore).bind(keyringController),
addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController),
saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController),
exportAccount: nodeify(keyringController.exportAccount).bind(keyringController),
setLocked: nodeify(keyringController.setLocked, keyringController),
createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain, keyringController),
createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore, keyringController),
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController),
exportAccount: nodeify(keyringController.exportAccount, keyringController),
// txController
approveTransaction: txController.approveTransaction.bind(txController),
cancelTransaction: txController.cancelTransaction.bind(txController),
updateAndApproveTransaction: this.updateAndApproveTx.bind(this),
updateAndApproveTransaction: nodeify(txController.updateAndApproveTransaction, txController),
// messageManager
signMessage: nodeify(this.signMessage).bind(this),
signMessage: nodeify(this.signMessage, this),
cancelMessage: this.cancelMessage.bind(this),
// personalMessageManager
signPersonalMessage: nodeify(this.signPersonalMessage).bind(this),
signPersonalMessage: nodeify(this.signPersonalMessage, this),
cancelPersonalMessage: this.cancelPersonalMessage.bind(this),
// notices
@ -367,7 +362,7 @@ module.exports = class MetamaskController extends EventEmitter {
function onResponse (err, request, response) {
if (err) return console.error(err)
if (response.error) {
console.error('Error in RPC response:\n', response.error)
console.error('Error in RPC response:\n', response)
}
if (request.isMetamaskInternal) return
log.info(`RPC (${originDomain}):`, request, '->', response)
@ -502,13 +497,6 @@ module.exports = class MetamaskController extends EventEmitter {
})
}
updateAndApproveTx (txMeta, cb) {
log.debug(`MetaMaskController - updateAndApproveTx: ${JSON.stringify(txMeta)}`)
const txController = this.txController
txController.updateTx(txMeta)
txController.approveTransaction(txMeta.id, cb)
}
signMessage (msgParams, cb) {
log.info('MetaMaskController - signMessage')
const msgId = msgParams.metamaskId

View File

@ -0,0 +1,41 @@
const version = 16
/*
This migration sets transactions with the 'Gave up submitting tx.' err message
to a 'failed' stated
*/
const clone = require('clone')
module.exports = {
version,
migrate: function (originalVersionedData) {
const versionedData = clone(originalVersionedData)
versionedData.meta.version = version
try {
const state = versionedData.data
const newState = transformState(state)
versionedData.data = newState
} catch (err) {
console.warn(`MetaMask Migration #${version}` + err.stack)
}
return Promise.resolve(versionedData)
},
}
function transformState (state) {
const newState = state
const transactions = newState.TransactionController.transactions
newState.TransactionController.transactions = transactions.map((txMeta) => {
if (!txMeta.err) return txMeta
if (txMeta.err === 'transaction with the same hash was already imported.') {
txMeta.status = 'submitted'
delete txMeta.err
}
return txMeta
})
return newState
}

View File

@ -0,0 +1,40 @@
const version = 17
/*
This migration sets transactions who were retried and marked as failed to submitted
*/
const clone = require('clone')
module.exports = {
version,
migrate: function (originalVersionedData) {
const versionedData = clone(originalVersionedData)
versionedData.meta.version = version
try {
const state = versionedData.data
const newState = transformState(state)
versionedData.data = newState
} catch (err) {
console.warn(`MetaMask Migration #${version}` + err.stack)
}
return Promise.resolve(versionedData)
},
}
function transformState (state) {
const newState = state
const transactions = newState.TransactionController.transactions
newState.TransactionController.transactions = transactions.map((txMeta) => {
if (!txMeta.status === 'failed') return txMeta
if (txMeta.retryCount > 0 && txMeta.retryCount < 2) {
txMeta.status = 'submitted'
delete txMeta.err
}
return txMeta
})
return newState
}

View File

@ -26,4 +26,6 @@ module.exports = [
require('./013'),
require('./014'),
require('./015'),
require('./016'),
require('./017'),
]

View File

@ -2,7 +2,7 @@ const EventEmitter = require('events').EventEmitter
const async = require('async')
const Dnode = require('dnode')
const EthQuery = require('eth-query')
const launchMetamaskUi = require('../../ui/classic')
const launchMetamaskUi = require('../../ui')
const StreamProvider = require('web3-stream-provider')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex

View File

@ -1,5 +1,5 @@
const injectCss = require('inject-css')
const MetaMaskUiCss = require('../../ui/classic/css')
const MetaMaskUiCss = require('../../ui/css')
const startPopup = require('./popup-core')
const PortStream = require('./lib/port-stream.js')
const isPopupOrNotification = require('./lib/is-popup-or-notification')

View File

@ -2,7 +2,7 @@ const EventEmitter = require('events').EventEmitter
const async = require('async')
const Dnode = require('dnode')
const EthQuery = require('eth-query')
const launchMetamaskUi = require('../../ui/responsive')
const launchMetamaskUi = require('../../responsive-ui')
const StreamProvider = require('web3-stream-provider')
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex

View File

@ -1,6 +1,6 @@
const injectCss = require('inject-css')
const startPopup = require('./responsive-core')
const MetaMaskUiCss = require('../../ui/responsive/css')
const MetaMaskUiCss = require('../../responsive-ui/css')
const PortStream = require('./lib/port-stream.js')
const ExtensionPlatform = require('./platforms/extension')
const extension = require('extensionizer')

View File

@ -1,6 +1,6 @@
machine:
node:
version: 8.0.0
version: 8.1.4
dependencies:
pre:
- "npm i -g testem"

View File

@ -172,6 +172,7 @@ gulp.task('default', ['lint'], function () {
const jsFiles = [
'inpage',
'contentscript',
'blacklister',
'background',
'popup',
'responsive'

View File

@ -7,10 +7,12 @@
"start": "npm run dev",
"dev": "gulp dev --debug",
"disc": "gulp disc --debug",
"dist": "npm install && gulp dist",
"clear": "rm -rf node_modules/eth-contract-metadata && rm -rf node_modules/etheraddresslookup",
"dist": "npm run clear && npm install && gulp dist",
"test": "npm run lint && npm run test-unit && npm run test-integration",
"test-unit": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/**/*.js\"",
"test-responsive": "METAMASK_ENV=test mocha --require test/helper.js --recursive \"test/unit/responsive/**/*.js\"",
"single-test": "METAMASK_ENV=test mocha --require test/helper.js",
"test-integration": "npm run buildMock && npm run buildCiUnits && testem ci -P 2",
"lint": "gulp lint",
"buildCiUnits": "node test/integration/index.js",
@ -46,6 +48,7 @@
},
"dependencies": {
"async": "^1.5.2",
"await-semaphore": "^0.1.1",
"babel-runtime": "^6.23.0",
"bip39": "^2.2.0",
"bluebird": "^3.5.0",
@ -56,19 +59,19 @@
"copy-to-clipboard": "^2.0.0",
"debounce": "^1.0.0",
"deep-extend": "^0.4.1",
"denodeify": "^1.2.1",
"detect-node": "^2.0.3",
"disc": "^1.3.2",
"dnode": "^1.2.2",
"end-of-stream": "^1.1.0",
"ensnare": "^1.0.0",
"eth-bin-to-ops": "^1.0.1",
"eth-contract-metadata": "^1.1.3",
"eth-contract-metadata": "^1.1.4",
"eth-hd-keyring": "^1.1.1",
"eth-query": "^2.1.2",
"eth-sig-util": "^1.1.1",
"eth-sig-util": "^1.2.2",
"eth-simple-keyring": "^1.1.1",
"eth-token-tracker": "^1.1.2",
"etheraddresslookup": "github:409H/EtherAddressLookup",
"ethereumjs-tx": "^1.3.0",
"ethereumjs-util": "ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
"ethereumjs-wallet": "^0.6.0",
@ -125,7 +128,7 @@
"valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "0.19.1",
"web3-provider-engine": "^13.1.1",
"web3-provider-engine": "^13.2.8",
"web3-stream-provider": "^3.0.1",
"xtend": "^4.0.1"
},
@ -175,7 +178,7 @@
"react-addons-test-utils": "^15.5.1",
"react-test-renderer": "^15.5.4",
"react-testutils-additions": "^15.2.0",
"sinon": "^1.17.3",
"sinon": "^2.3.8",
"tape": "^4.5.1",
"testem": "^1.10.3",
"uglifyify": "^3.0.1",

View File

@ -6,7 +6,7 @@ const connect = require('react-redux').connect
const actions = require('./actions')
const NetworkIndicator = require('./components/network')
const txHelper = require('../lib/tx-helper')
const isPopupOrNotification = require('../../../app/scripts/lib/is-popup-or-notification')
const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
const PendingTx = require('./components/pending-tx')
const PendingMsg = require('./components/pending-msg')

View File

Before

Width:  |  Height:  |  Size: 138 KiB

After

Width:  |  Height:  |  Size: 138 KiB

View File

Before

Width:  |  Height:  |  Size: 380 KiB

After

Width:  |  Height:  |  Size: 380 KiB

View File

@ -9,8 +9,8 @@ var cssFiles = {
'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'),
'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'),
'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'),
'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
'react-css': fs.readFileSync(path.join(__dirname, '..', '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
}
function bundleCss () {

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Some files were not shown because too many files have changed in this diff Show More