mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge remote-tracking branch 'mm/master' into NewUI-flat
This commit is contained in:
commit
dbc539ac55
@ -2,12 +2,16 @@
|
||||
|
||||
## Current Master
|
||||
|
||||
- Added a deprecation warning for web3 https://github.com/ethereum/mist/releases/tag/v0.9.0
|
||||
|
||||
## 3.9.6 2017-8-09
|
||||
|
||||
- Replace account screen with an account drop-down menu.
|
||||
- Replace confusing buttons with a new account-specific drop-down menu.
|
||||
- Replace account buttons with a new account-specific drop-down menu.
|
||||
|
||||
## 3.9.5 2017-8-04
|
||||
|
||||
- Improved phishing detection configuration update rate
|
||||
- Improved phishing detection configuration update rate
|
||||
|
||||
## 3.9.4 2017-8-03
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
# MetaMask Plugin [![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/)
|
||||
# MetaMask Plugin
|
||||
[![Build Status](https://circleci.com/gh/MetaMask/metamask-extension.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-extension) [![Coverage Status](https://coveralls.io/repos/github/MetaMask/metamask-extension/badge.svg?branch=master)](https://coveralls.io/github/MetaMask/metamask-extension?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/metamask-extension.svg)](https://greenkeeper.io/) [![Stories in Ready](https://badge.waffle.io/MetaMask/metamask-extension.png?label=in%20progress&title=waffle.io)](http://waffle.io/MetaMask/metamask-extension)
|
||||
|
||||
|
||||
## Support
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "MetaMask",
|
||||
"short_name": "Metamask",
|
||||
"version": "3.9.5",
|
||||
"version": "3.9.6",
|
||||
"manifest_version": 2,
|
||||
"author": "https://metamask.io",
|
||||
"description": "Ethereum Browser Extension",
|
||||
|
@ -12,4 +12,9 @@ module.exports = {
|
||||
kovan: KOVAN_RPC_URL,
|
||||
rinkeby: RINKEBY_RPC_URL,
|
||||
},
|
||||
networkNames: {
|
||||
3: 'Ropsten',
|
||||
4: 'Rinkeby',
|
||||
42: 'Kovan',
|
||||
},
|
||||
}
|
||||
|
@ -5,7 +5,10 @@ function setupDappAutoReload (web3, observable) {
|
||||
global.web3 = new Proxy(web3, {
|
||||
get: (_web3, name) => {
|
||||
// get the time of use
|
||||
if (name !== '_used') _web3._used = Date.now()
|
||||
if (name !== '_used') {
|
||||
console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/ethereum/mist/releases/tag/v0.9.0')
|
||||
_web3._used = Date.now()
|
||||
}
|
||||
return _web3[name]
|
||||
},
|
||||
set: (_web3, name, value) => {
|
||||
|
@ -20,7 +20,15 @@ module.exports = class txProvideUtil {
|
||||
|
||||
async analyzeGasUsage (txMeta) {
|
||||
const block = await this.query.getBlockByNumber('latest', true)
|
||||
const estimatedGasHex = await this.estimateTxGas(txMeta, block.gasLimit)
|
||||
let estimatedGasHex
|
||||
try {
|
||||
estimatedGasHex = await this.estimateTxGas(txMeta, block.gasLimit)
|
||||
} catch (err) {
|
||||
if (err.message.includes('Transaction execution error.')) {
|
||||
txMeta.simulationFails = true
|
||||
return txMeta
|
||||
}
|
||||
}
|
||||
this.setTxGas(txMeta, block.gasLimit, estimatedGasHex)
|
||||
return txMeta
|
||||
}
|
||||
@ -35,8 +43,8 @@ module.exports = class txProvideUtil {
|
||||
const saferGasLimitBN = BnMultiplyByFraction(blockGasLimitBN, 19, 20)
|
||||
txParams.gas = bnToHex(saferGasLimitBN)
|
||||
}
|
||||
// run tx, see if it will OOG
|
||||
return this.query.estimateGas(txParams)
|
||||
// run tx
|
||||
return await this.query.estimateGas(txParams)
|
||||
}
|
||||
|
||||
setTxGas (txMeta, blockGasLimitHex, estimatedGasHex) {
|
||||
|
@ -80,7 +80,7 @@
|
||||
"ethereumjs-util": "github:ethereumjs/ethereumjs-util#ac5d0908536b447083ea422b435da27f26615de9",
|
||||
"ethereumjs-wallet": "^0.6.0",
|
||||
"ethjs-ens": "^2.0.0",
|
||||
"ethjs-query": "^0.2.6",
|
||||
"ethjs-query": "^0.2.9",
|
||||
"express": "^4.14.0",
|
||||
"extension-link-enabler": "^1.0.0",
|
||||
"extensionizer": "^1.0.0",
|
||||
|
121
ui/app/account-detail.js
Normal file
121
ui/app/account-detail.js
Normal file
@ -0,0 +1,121 @@
|
||||
const inherits = require('util').inherits
|
||||
const extend = require('xtend')
|
||||
const Component = require('react').Component
|
||||
const h = require('react-hyperscript')
|
||||
const connect = require('react-redux').connect
|
||||
const actions = require('./actions')
|
||||
const valuesFor = require('./util').valuesFor
|
||||
const Identicon = require('./components/identicon')
|
||||
const EthBalance = require('./components/eth-balance')
|
||||
const TransactionList = require('./components/transaction-list')
|
||||
const ExportAccountView = require('./components/account-export')
|
||||
const ethUtil = require('ethereumjs-util')
|
||||
const EditableLabel = require('./components/editable-label')
|
||||
const TabBar = require('./components/tab-bar')
|
||||
const TokenList = require('./components/token-list')
|
||||
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
|
||||
|
||||
module.exports = connect(mapStateToProps)(AccountDetailScreen)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {
|
||||
metamask: state.metamask,
|
||||
identities: state.metamask.identities,
|
||||
accounts: state.metamask.accounts,
|
||||
address: state.metamask.selectedAddress,
|
||||
accountDetail: state.appState.accountDetail,
|
||||
network: state.metamask.network,
|
||||
unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
|
||||
shapeShiftTxList: state.metamask.shapeShiftTxList,
|
||||
transactions: state.metamask.selectedAddressTxList || [],
|
||||
conversionRate: state.metamask.conversionRate,
|
||||
currentCurrency: state.metamask.currentCurrency,
|
||||
currentAccountTab: state.metamask.currentAccountTab,
|
||||
tokens: state.metamask.tokens,
|
||||
}
|
||||
}
|
||||
|
||||
inherits(AccountDetailScreen, Component)
|
||||
function AccountDetailScreen () {
|
||||
Component.call(this)
|
||||
}
|
||||
|
||||
// Note: This component is no longer used. Leaving the file for reference:
|
||||
// - structuring routing for add token
|
||||
// - state required for TxList
|
||||
// Delete file when those features are complete
|
||||
AccountDetailScreen.prototype.render = function () {}
|
||||
|
||||
AccountDetailScreen.prototype.subview = function () {
|
||||
var subview
|
||||
try {
|
||||
subview = this.props.accountDetail.subview
|
||||
} catch (e) {
|
||||
subview = null
|
||||
}
|
||||
|
||||
switch (subview) {
|
||||
case 'transactions':
|
||||
return this.tabSections()
|
||||
case 'export':
|
||||
var state = extend({key: 'export'}, this.props)
|
||||
return h(ExportAccountView, state)
|
||||
default:
|
||||
return this.tabSections()
|
||||
}
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.tabSections = function () {
|
||||
const { currentAccountTab } = this.props
|
||||
|
||||
return h('section.tabSection.full-flex-height.grow-tenx', [
|
||||
|
||||
h(TabBar, {
|
||||
tabs: [
|
||||
{ content: 'Sent', key: 'history' },
|
||||
{ content: 'Tokens', key: 'tokens' },
|
||||
],
|
||||
defaultTab: currentAccountTab || 'history',
|
||||
tabSelected: (key) => {
|
||||
this.props.dispatch(actions.setCurrentAccountTab(key))
|
||||
},
|
||||
}),
|
||||
|
||||
this.tabSwitchView(),
|
||||
])
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.tabSwitchView = function () {
|
||||
const props = this.props
|
||||
const { address, network } = props
|
||||
const { currentAccountTab, tokens } = this.props
|
||||
|
||||
switch (currentAccountTab) {
|
||||
case 'tokens':
|
||||
return h(TokenList, {
|
||||
userAddress: address,
|
||||
network,
|
||||
tokens,
|
||||
addToken: () => this.props.dispatch(actions.showAddTokenPage()),
|
||||
})
|
||||
default:
|
||||
return this.transactionList()
|
||||
}
|
||||
}
|
||||
|
||||
AccountDetailScreen.prototype.transactionList = function () {
|
||||
const {transactions, unapprovedMsgs, address,
|
||||
network, shapeShiftTxList, conversionRate } = this.props
|
||||
|
||||
return h(TransactionList, {
|
||||
transactions: transactions.sort((a, b) => b.time - a.time),
|
||||
network,
|
||||
unapprovedMsgs,
|
||||
conversionRate,
|
||||
address,
|
||||
shapeShiftTxList,
|
||||
viewPendingTx: (txId) => {
|
||||
this.props.dispatch(actions.viewPendingTx(txId))
|
||||
},
|
||||
})
|
||||
}
|
@ -8,6 +8,7 @@ const ShapeshiftForm = require('./shapeshift-form')
|
||||
const Loading = require('./loading')
|
||||
const AccountPanel = require('./account-panel')
|
||||
const RadioList = require('./custom-radio-list')
|
||||
const networkNames = require('../../../app/scripts/config.js').networkNames
|
||||
|
||||
module.exports = connect(mapStateToProps)(BuyButtonSubview)
|
||||
|
||||
@ -30,16 +31,30 @@ function BuyButtonSubview () {
|
||||
}
|
||||
|
||||
BuyButtonSubview.prototype.render = function () {
|
||||
return (
|
||||
h('div', {
|
||||
style: {
|
||||
width: '100%',
|
||||
},
|
||||
}, [
|
||||
this.headerSubview(),
|
||||
this.primarySubview(),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
BuyButtonSubview.prototype.headerSubview = function () {
|
||||
const props = this.props
|
||||
const isLoading = props.isSubLoading
|
||||
|
||||
return (
|
||||
h('.buy-eth-section.flex-column', {
|
||||
|
||||
h('.flex-column', {
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
}, [
|
||||
// back button
|
||||
|
||||
// header bar (back button, label)
|
||||
h('.flex-row', {
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
@ -63,6 +78,8 @@ BuyButtonSubview.prototype.render = function () {
|
||||
},
|
||||
}, 'Buy Eth'),
|
||||
]),
|
||||
|
||||
// loading indication
|
||||
h('div', {
|
||||
style: {
|
||||
position: 'absolute',
|
||||
@ -70,8 +87,10 @@ BuyButtonSubview.prototype.render = function () {
|
||||
left: '49vw',
|
||||
},
|
||||
}, [
|
||||
h(Loading, {isLoading}),
|
||||
h(Loading, { isLoading }),
|
||||
]),
|
||||
|
||||
// account panel
|
||||
h('div', {
|
||||
style: {
|
||||
width: '80%',
|
||||
@ -83,17 +102,92 @@ BuyButtonSubview.prototype.render = function () {
|
||||
account: props.account,
|
||||
}),
|
||||
]),
|
||||
h('h3.text-transform-uppercase', {
|
||||
|
||||
h('.flex-row', {
|
||||
style: {
|
||||
paddingLeft: '15px',
|
||||
fontFamily: 'Montserrat Light',
|
||||
width: '100vw',
|
||||
background: 'rgb(235, 235, 235)',
|
||||
color: 'rgb(174, 174, 174)',
|
||||
paddingTop: '4px',
|
||||
paddingBottom: '4px',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
}, 'Select Service'),
|
||||
}, [
|
||||
h('h3.text-transform-uppercase.flex-center', {
|
||||
style: {
|
||||
paddingLeft: '15px',
|
||||
width: '100vw',
|
||||
background: 'rgb(235, 235, 235)',
|
||||
color: 'rgb(174, 174, 174)',
|
||||
paddingTop: '4px',
|
||||
paddingBottom: '4px',
|
||||
},
|
||||
}, 'Select Service'),
|
||||
]),
|
||||
|
||||
])
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
BuyButtonSubview.prototype.primarySubview = function () {
|
||||
const props = this.props
|
||||
const network = props.network
|
||||
|
||||
switch (network) {
|
||||
case 'loading':
|
||||
return
|
||||
|
||||
case '1':
|
||||
return this.mainnetSubview()
|
||||
|
||||
// Ropsten, Rinkeby, Kovan
|
||||
case '3':
|
||||
case '4':
|
||||
case '42':
|
||||
const networkName = networkNames[network]
|
||||
const label = `${networkName} Test Faucet`
|
||||
return (
|
||||
h('div.flex-column', {
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
margin: '20px 50px',
|
||||
},
|
||||
}, [
|
||||
h('button.text-transform-uppercase', {
|
||||
onClick: () => this.props.dispatch(actions.buyEth({ network })),
|
||||
style: {
|
||||
marginTop: '15px',
|
||||
},
|
||||
}, label),
|
||||
// Kovan only: Dharma loans beta
|
||||
network === '42' ? (
|
||||
h('button.text-transform-uppercase', {
|
||||
onClick: () => this.navigateTo('https://borrow.dharma.io/'),
|
||||
style: {
|
||||
marginTop: '15px',
|
||||
},
|
||||
}, 'Borrow With Dharma (Beta)')
|
||||
) : null,
|
||||
])
|
||||
)
|
||||
|
||||
default:
|
||||
return (
|
||||
h('h2.error', 'Unknown network ID')
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BuyButtonSubview.prototype.mainnetSubview = function () {
|
||||
const props = this.props
|
||||
|
||||
return (
|
||||
|
||||
h('.flex-column', {
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
},
|
||||
}, [
|
||||
|
||||
h('.flex-row.selected-exchange', {
|
||||
style: {
|
||||
position: 'relative',
|
||||
@ -115,6 +209,7 @@ BuyButtonSubview.prototype.render = function () {
|
||||
onClick: this.radioHandler.bind(this),
|
||||
}),
|
||||
]),
|
||||
|
||||
h('h3.text-transform-uppercase', {
|
||||
style: {
|
||||
paddingLeft: '15px',
|
||||
@ -126,8 +221,10 @@ BuyButtonSubview.prototype.render = function () {
|
||||
paddingBottom: '4px',
|
||||
},
|
||||
}, props.buyView.subview),
|
||||
|
||||
this.formVersionSubview(),
|
||||
])
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@ -139,39 +236,6 @@ BuyButtonSubview.prototype.formVersionSubview = function () {
|
||||
} else if (this.props.buyView.formView.shapeshift) {
|
||||
return h(ShapeshiftForm, this.props)
|
||||
}
|
||||
} else {
|
||||
return h('div.flex-column', {
|
||||
style: {
|
||||
alignItems: 'center',
|
||||
margin: '20px 50px',
|
||||
},
|
||||
}, [
|
||||
h('h3.text-transform-uppercase', {
|
||||
style: {
|
||||
width: '225px',
|
||||
marginBottom: '15px',
|
||||
},
|
||||
}, 'In order to access this feature, please switch to the Main Network'),
|
||||
((network === '3') || (network === '4') || (network === '42')) ? h('h3.text-transform-uppercase', 'or go to the') : null,
|
||||
(network === '3') ? h('button.text-transform-uppercase', {
|
||||
onClick: () => this.props.dispatch(actions.buyEth({ network })),
|
||||
style: {
|
||||
marginTop: '15px',
|
||||
},
|
||||
}, 'Ropsten Test Faucet') : null,
|
||||
(network === '4') ? h('button.text-transform-uppercase', {
|
||||
onClick: () => this.props.dispatch(actions.buyEth({ network })),
|
||||
style: {
|
||||
marginTop: '15px',
|
||||
},
|
||||
}, 'Rinkeby Test Faucet') : null,
|
||||
(network === '42') ? h('button.text-transform-uppercase', {
|
||||
onClick: () => this.props.dispatch(actions.buyEth({ network })),
|
||||
style: {
|
||||
marginTop: '15px',
|
||||
},
|
||||
}, 'Kovan Test Faucet') : null,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,16 @@ class AccountDropdowns extends Component {
|
||||
},
|
||||
},
|
||||
),
|
||||
h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, identity.name || ''),
|
||||
h('span', {
|
||||
style: {
|
||||
marginLeft: '20px',
|
||||
fontSize: '24px',
|
||||
maxWidth: '145px',
|
||||
whiteSpace: 'nowrap',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
},
|
||||
}, identity.name || ''),
|
||||
h('span', { style: { marginLeft: '20px', fontSize: '24px' } }, isSelected ? h('.check', '✓') : null),
|
||||
]
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user