mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
Add eth_signTypedData handler
This commit is contained in:
parent
cdf41c2857
commit
c2b8dada91
@ -124,7 +124,8 @@ function setupController (initState) {
|
|||||||
var unapprovedTxCount = controller.txController.getUnapprovedTxCount()
|
var unapprovedTxCount = controller.txController.getUnapprovedTxCount()
|
||||||
var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
|
var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
|
||||||
var unapprovedPersonalMsgs = controller.personalMessageManager.unapprovedPersonalMsgCount
|
var unapprovedPersonalMsgs = controller.personalMessageManager.unapprovedPersonalMsgCount
|
||||||
var count = unapprovedTxCount + unapprovedMsgCount + unapprovedPersonalMsgs
|
var unapprovedTypedMsgs = controller.typedMessageManager.unapprovedTypedMessagesCount
|
||||||
|
var count = unapprovedTxCount + unapprovedMsgCount + unapprovedPersonalMsgs + unapprovedTypedMsgs
|
||||||
if (count) {
|
if (count) {
|
||||||
label = String(count)
|
label = String(count)
|
||||||
}
|
}
|
||||||
|
108
app/scripts/lib/typed-message-manager.js
Normal file
108
app/scripts/lib/typed-message-manager.js
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
const EventEmitter = require('events')
|
||||||
|
const ObservableStore = require('obs-store')
|
||||||
|
const createId = require('./random-id')
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = class TypedMessageManager extends EventEmitter {
|
||||||
|
constructor (opts) {
|
||||||
|
super()
|
||||||
|
this.memStore = new ObservableStore({
|
||||||
|
unapprovedTypedMessages: {},
|
||||||
|
unapprovedTypedMessagesCount: 0,
|
||||||
|
})
|
||||||
|
this.messages = []
|
||||||
|
}
|
||||||
|
|
||||||
|
get unapprovedTypedMessagesCount () {
|
||||||
|
return Object.keys(this.getUnapprovedMsgs()).length
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnapprovedMsgs () {
|
||||||
|
return this.messages.filter(msg => msg.status === 'unapproved')
|
||||||
|
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
addUnapprovedMessage (msgParams) {
|
||||||
|
log.debug(`TypedMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`)
|
||||||
|
// create txData obj with parameters and meta data
|
||||||
|
var time = (new Date()).getTime()
|
||||||
|
var msgId = createId()
|
||||||
|
var msgData = {
|
||||||
|
id: msgId,
|
||||||
|
msgParams: msgParams,
|
||||||
|
time: time,
|
||||||
|
status: 'unapproved',
|
||||||
|
type: 'eth_signTypedData',
|
||||||
|
}
|
||||||
|
this.addMsg(msgData)
|
||||||
|
|
||||||
|
// signal update
|
||||||
|
this.emit('update')
|
||||||
|
return msgId
|
||||||
|
}
|
||||||
|
|
||||||
|
addMsg (msg) {
|
||||||
|
this.messages.push(msg)
|
||||||
|
this._saveMsgList()
|
||||||
|
}
|
||||||
|
|
||||||
|
getMsg (msgId) {
|
||||||
|
return this.messages.find(msg => msg.id === msgId)
|
||||||
|
}
|
||||||
|
|
||||||
|
approveMessage (msgParams) {
|
||||||
|
this.setMsgStatusApproved(msgParams.metamaskId)
|
||||||
|
return this.prepMsgForSigning(msgParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
setMsgStatusApproved (msgId) {
|
||||||
|
this._setMsgStatus(msgId, 'approved')
|
||||||
|
}
|
||||||
|
|
||||||
|
setMsgStatusSigned (msgId, rawSig) {
|
||||||
|
const msg = this.getMsg(msgId)
|
||||||
|
msg.rawSig = rawSig
|
||||||
|
this._updateMsg(msg)
|
||||||
|
this._setMsgStatus(msgId, 'signed')
|
||||||
|
}
|
||||||
|
|
||||||
|
prepMsgForSigning (msgParams) {
|
||||||
|
delete msgParams.metamaskId
|
||||||
|
return Promise.resolve(msgParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
rejectMsg (msgId) {
|
||||||
|
this._setMsgStatus(msgId, 'rejected')
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// PRIVATE METHODS
|
||||||
|
//
|
||||||
|
|
||||||
|
_setMsgStatus (msgId, status) {
|
||||||
|
const msg = this.getMsg(msgId)
|
||||||
|
if (!msg) throw new Error('TypedMessageManager - Message not found for id: "${msgId}".')
|
||||||
|
msg.status = status
|
||||||
|
this._updateMsg(msg)
|
||||||
|
this.emit(`${msgId}:${status}`, msg)
|
||||||
|
if (status === 'rejected' || status === 'signed') {
|
||||||
|
this.emit(`${msgId}:finished`, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateMsg (msg) {
|
||||||
|
const index = this.messages.findIndex((message) => message.id === msg.id)
|
||||||
|
if (index !== -1) {
|
||||||
|
this.messages[index] = msg
|
||||||
|
}
|
||||||
|
this._saveMsgList()
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveMsgList () {
|
||||||
|
const unapprovedTypedMessages = this.getUnapprovedMsgs()
|
||||||
|
const unapprovedTypedMessagesCount = Object.keys(unapprovedTypedMessages).length
|
||||||
|
this.memStore.updateState({ unapprovedTypedMessages, unapprovedTypedMessagesCount })
|
||||||
|
this.emit('updateBadge')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -25,6 +25,7 @@ const InfuraController = require('./controllers/infura')
|
|||||||
const BlacklistController = require('./controllers/blacklist')
|
const BlacklistController = require('./controllers/blacklist')
|
||||||
const MessageManager = require('./lib/message-manager')
|
const MessageManager = require('./lib/message-manager')
|
||||||
const PersonalMessageManager = require('./lib/personal-message-manager')
|
const PersonalMessageManager = require('./lib/personal-message-manager')
|
||||||
|
const TypedMessageManager = require('./lib/typed-message-manager')
|
||||||
const TransactionController = require('./controllers/transactions')
|
const TransactionController = require('./controllers/transactions')
|
||||||
const BalancesController = require('./controllers/computed-balances')
|
const BalancesController = require('./controllers/computed-balances')
|
||||||
const ConfigManager = require('./lib/config-manager')
|
const ConfigManager = require('./lib/config-manager')
|
||||||
@ -154,6 +155,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
this.networkController.lookupNetwork()
|
this.networkController.lookupNetwork()
|
||||||
this.messageManager = new MessageManager()
|
this.messageManager = new MessageManager()
|
||||||
this.personalMessageManager = new PersonalMessageManager()
|
this.personalMessageManager = new PersonalMessageManager()
|
||||||
|
this.typedMessageManager = new TypedMessageManager()
|
||||||
this.publicConfigStore = this.initPublicConfigStore()
|
this.publicConfigStore = this.initPublicConfigStore()
|
||||||
|
|
||||||
// manual disk state subscriptions
|
// manual disk state subscriptions
|
||||||
@ -195,6 +197,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
this.balancesController.store.subscribe(this.sendUpdate.bind(this))
|
this.balancesController.store.subscribe(this.sendUpdate.bind(this))
|
||||||
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
||||||
this.personalMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
this.personalMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
||||||
|
this.typedMessageManager.memStore.subscribe(this.sendUpdate.bind(this))
|
||||||
this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
|
this.keyringController.memStore.subscribe(this.sendUpdate.bind(this))
|
||||||
this.preferencesController.store.subscribe(this.sendUpdate.bind(this))
|
this.preferencesController.store.subscribe(this.sendUpdate.bind(this))
|
||||||
this.addressBookController.store.subscribe(this.sendUpdate.bind(this))
|
this.addressBookController.store.subscribe(this.sendUpdate.bind(this))
|
||||||
@ -234,6 +237,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
processMessage: this.newUnsignedMessage.bind(this),
|
processMessage: this.newUnsignedMessage.bind(this),
|
||||||
// personal_sign msg signing
|
// personal_sign msg signing
|
||||||
processPersonalMessage: this.newUnsignedPersonalMessage.bind(this),
|
processPersonalMessage: this.newUnsignedPersonalMessage.bind(this),
|
||||||
|
processTypedMessage: this.newUnsignedTypedMessage.bind(this),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,6 +280,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
this.txController.memStore.getState(),
|
this.txController.memStore.getState(),
|
||||||
this.messageManager.memStore.getState(),
|
this.messageManager.memStore.getState(),
|
||||||
this.personalMessageManager.memStore.getState(),
|
this.personalMessageManager.memStore.getState(),
|
||||||
|
this.typedMessageManager.memStore.getState(),
|
||||||
this.keyringController.memStore.getState(),
|
this.keyringController.memStore.getState(),
|
||||||
this.balancesController.store.getState(),
|
this.balancesController.store.getState(),
|
||||||
this.preferencesController.store.getState(),
|
this.preferencesController.store.getState(),
|
||||||
@ -354,6 +359,10 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
signPersonalMessage: nodeify(this.signPersonalMessage, this),
|
signPersonalMessage: nodeify(this.signPersonalMessage, this),
|
||||||
cancelPersonalMessage: this.cancelPersonalMessage.bind(this),
|
cancelPersonalMessage: this.cancelPersonalMessage.bind(this),
|
||||||
|
|
||||||
|
// personalMessageManager
|
||||||
|
signTypedMessage: nodeify(this.signTypedMessage, this),
|
||||||
|
cancelTypedMessage: this.cancelTypedMessage.bind(this),
|
||||||
|
|
||||||
// notices
|
// notices
|
||||||
checkNotices: noticeController.updateNoticesList.bind(noticeController),
|
checkNotices: noticeController.updateNoticesList.bind(noticeController),
|
||||||
markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
|
markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
|
||||||
@ -546,6 +555,23 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newUnsignedTypedMessage (msgParams, cb) {
|
||||||
|
const msgId = this.typedMessageManager.addUnapprovedMessage(msgParams)
|
||||||
|
this.sendUpdate()
|
||||||
|
this.opts.showUnconfirmedMessage()
|
||||||
|
this.typedMessageManager.once(`${msgId}:finished`, (data) => {
|
||||||
|
console.log(data)
|
||||||
|
switch (data.status) {
|
||||||
|
case 'signed':
|
||||||
|
return cb(null, data.rawSig)
|
||||||
|
case 'rejected':
|
||||||
|
return cb(new Error('MetaMask Message Signature: User denied message signature.'))
|
||||||
|
default:
|
||||||
|
return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
signMessage (msgParams, cb) {
|
signMessage (msgParams, cb) {
|
||||||
log.info('MetaMaskController - signMessage')
|
log.info('MetaMaskController - signMessage')
|
||||||
const msgId = msgParams.metamaskId
|
const msgId = msgParams.metamaskId
|
||||||
@ -608,6 +634,24 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signTypedMessage (msgParams) {
|
||||||
|
log.info('MetaMaskController - signTypedMessage')
|
||||||
|
const msgId = msgParams.metamaskId
|
||||||
|
// sets the status op the message to 'approved'
|
||||||
|
// and removes the metamaskId for signing
|
||||||
|
return this.typedMessageManager.approveMessage(msgParams)
|
||||||
|
.then((cleanMsgParams) => {
|
||||||
|
// signs the message
|
||||||
|
return this.keyringController.signTypedMessage(cleanMsgParams)
|
||||||
|
})
|
||||||
|
.then((rawSig) => {
|
||||||
|
// tells the listener that the message has been signed
|
||||||
|
// and can be returned to the dapp
|
||||||
|
this.typedMessageManager.setMsgStatusSigned(msgId, rawSig)
|
||||||
|
return this.getState()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
cancelPersonalMessage (msgId, cb) {
|
cancelPersonalMessage (msgId, cb) {
|
||||||
const messageManager = this.personalMessageManager
|
const messageManager = this.personalMessageManager
|
||||||
messageManager.rejectMsg(msgId)
|
messageManager.rejectMsg(msgId)
|
||||||
@ -616,6 +660,14 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cancelTypedMessage (msgId, cb) {
|
||||||
|
const messageManager = this.typedMessageManager
|
||||||
|
messageManager.rejectMsg(msgId)
|
||||||
|
if (cb && typeof cb === 'function') {
|
||||||
|
cb(null, this.getState())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
markAccountsFound (cb) {
|
markAccountsFound (cb) {
|
||||||
this.configManager.setLostAccounts([])
|
this.configManager.setLostAccounts([])
|
||||||
this.sendUpdate()
|
this.sendUpdate()
|
||||||
|
@ -97,6 +97,8 @@ var actions = {
|
|||||||
cancelMsg: cancelMsg,
|
cancelMsg: cancelMsg,
|
||||||
signPersonalMsg,
|
signPersonalMsg,
|
||||||
cancelPersonalMsg,
|
cancelPersonalMsg,
|
||||||
|
signTypedMsg,
|
||||||
|
cancelTypedMsg,
|
||||||
signTx: signTx,
|
signTx: signTx,
|
||||||
updateAndApproveTx,
|
updateAndApproveTx,
|
||||||
cancelTx: cancelTx,
|
cancelTx: cancelTx,
|
||||||
@ -395,6 +397,25 @@ function signPersonalMsg (msgData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function signTypedMsg (msgData) {
|
||||||
|
log.debug('action - signTypedMsg')
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(actions.showLoadingIndication())
|
||||||
|
|
||||||
|
log.debug(`actions calling background.signTypedMessage`)
|
||||||
|
background.signTypedMessage(msgData, (err, newState) => {
|
||||||
|
log.debug('signTypedMessage called back')
|
||||||
|
dispatch(actions.updateMetamaskState(newState))
|
||||||
|
dispatch(actions.hideLoadingIndication())
|
||||||
|
|
||||||
|
if (err) log.error(err)
|
||||||
|
if (err) return dispatch(actions.displayWarning(err.message))
|
||||||
|
|
||||||
|
dispatch(actions.completedTx(msgData.metamaskId))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function signTx (txData) {
|
function signTx (txData) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(actions.showLoadingIndication())
|
dispatch(actions.showLoadingIndication())
|
||||||
@ -449,6 +470,12 @@ function cancelPersonalMsg (msgData) {
|
|||||||
return actions.completedTx(id)
|
return actions.completedTx(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelTypedMsg (msgData) {
|
||||||
|
const id = msgData.id
|
||||||
|
background.cancelTypedMessage(id)
|
||||||
|
return actions.completedTx(id)
|
||||||
|
}
|
||||||
|
|
||||||
function cancelTx (txData) {
|
function cancelTx (txData) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
log.debug(`background.cancelTransaction`)
|
log.debug(`background.cancelTransaction`)
|
||||||
|
59
ui/app/components/pending-typed-msg-details.js
Normal file
59
ui/app/components/pending-typed-msg-details.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
const Component = require('react').Component
|
||||||
|
const h = require('react-hyperscript')
|
||||||
|
const inherits = require('util').inherits
|
||||||
|
|
||||||
|
const AccountPanel = require('./account-panel')
|
||||||
|
const TypedMessageRenderer = require('./typed-message-renderer')
|
||||||
|
|
||||||
|
module.exports = PendingMsgDetails
|
||||||
|
|
||||||
|
inherits(PendingMsgDetails, Component)
|
||||||
|
function PendingMsgDetails () {
|
||||||
|
Component.call(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingMsgDetails.prototype.render = function () {
|
||||||
|
var state = this.props
|
||||||
|
var msgData = state.txData
|
||||||
|
|
||||||
|
var msgParams = msgData.msgParams || {}
|
||||||
|
var address = msgParams.from || state.selectedAddress
|
||||||
|
var identity = state.identities[address] || { address: address }
|
||||||
|
var account = state.accounts[address] || { address: address }
|
||||||
|
|
||||||
|
var { data } = msgParams
|
||||||
|
|
||||||
|
return (
|
||||||
|
h('div', {
|
||||||
|
key: msgData.id,
|
||||||
|
style: {
|
||||||
|
margin: '10px 20px',
|
||||||
|
},
|
||||||
|
}, [
|
||||||
|
|
||||||
|
// account that will sign
|
||||||
|
h(AccountPanel, {
|
||||||
|
showFullAddress: true,
|
||||||
|
identity: identity,
|
||||||
|
account: account,
|
||||||
|
imageifyIdenticons: state.imageifyIdenticons,
|
||||||
|
}),
|
||||||
|
|
||||||
|
// message data
|
||||||
|
h('div', {
|
||||||
|
style: {
|
||||||
|
height: '260px',
|
||||||
|
},
|
||||||
|
}, [
|
||||||
|
h('label.font-small', { style: { display: 'block' } }, 'YOU ARE SIGNING'),
|
||||||
|
h(TypedMessageRenderer, {
|
||||||
|
value: data,
|
||||||
|
style: {
|
||||||
|
height: '215px',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
|
||||||
|
])
|
||||||
|
)
|
||||||
|
}
|
46
ui/app/components/pending-typed-msg.js
Normal file
46
ui/app/components/pending-typed-msg.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
const Component = require('react').Component
|
||||||
|
const h = require('react-hyperscript')
|
||||||
|
const inherits = require('util').inherits
|
||||||
|
const PendingTxDetails = require('./pending-typed-msg-details')
|
||||||
|
|
||||||
|
module.exports = PendingMsg
|
||||||
|
|
||||||
|
inherits(PendingMsg, Component)
|
||||||
|
function PendingMsg () {
|
||||||
|
Component.call(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingMsg.prototype.render = function () {
|
||||||
|
var state = this.props
|
||||||
|
var msgData = state.txData
|
||||||
|
|
||||||
|
return (
|
||||||
|
|
||||||
|
h('div', {
|
||||||
|
key: msgData.id,
|
||||||
|
}, [
|
||||||
|
|
||||||
|
// header
|
||||||
|
h('h3', {
|
||||||
|
style: {
|
||||||
|
fontWeight: 'bold',
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
}, 'Sign Message'),
|
||||||
|
|
||||||
|
// message details
|
||||||
|
h(PendingTxDetails, state),
|
||||||
|
|
||||||
|
// sign + cancel
|
||||||
|
h('.flex-row.flex-space-around', [
|
||||||
|
h('button', {
|
||||||
|
onClick: state.cancelTypedMessage,
|
||||||
|
}, 'Cancel'),
|
||||||
|
h('button', {
|
||||||
|
onClick: state.signTypedMessage,
|
||||||
|
}, 'Sign'),
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
42
ui/app/components/typed-message-renderer.js
Normal file
42
ui/app/components/typed-message-renderer.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const Component = require('react').Component
|
||||||
|
const h = require('react-hyperscript')
|
||||||
|
const inherits = require('util').inherits
|
||||||
|
const ethUtil = require('ethereumjs-util')
|
||||||
|
const extend = require('xtend')
|
||||||
|
|
||||||
|
module.exports = TypedMessageRenderer
|
||||||
|
|
||||||
|
inherits(TypedMessageRenderer, Component)
|
||||||
|
function TypedMessageRenderer () {
|
||||||
|
Component.call(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedMessageRenderer.prototype.render = function () {
|
||||||
|
const props = this.props
|
||||||
|
const { value, style } = props
|
||||||
|
const text = renderTypedData(value)
|
||||||
|
|
||||||
|
const defaultStyle = extend({
|
||||||
|
width: '315px',
|
||||||
|
maxHeight: '210px',
|
||||||
|
resize: 'none',
|
||||||
|
border: 'none',
|
||||||
|
background: 'white',
|
||||||
|
padding: '3px',
|
||||||
|
}, style)
|
||||||
|
|
||||||
|
return (
|
||||||
|
h('div.font-small', {
|
||||||
|
style: defaultStyle,
|
||||||
|
}, text)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTypedData(values) {
|
||||||
|
return values.map(function (value) {
|
||||||
|
return h('div', {}, [
|
||||||
|
h('strong', {style: {display: 'block', fontWeight: 'bold', textTransform: 'capitalize'}}, String(value.name) + ':'),
|
||||||
|
h('div', {}, value.value)
|
||||||
|
])
|
||||||
|
})
|
||||||
|
}
|
@ -10,6 +10,7 @@ const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notific
|
|||||||
const PendingTx = require('./components/pending-tx')
|
const PendingTx = require('./components/pending-tx')
|
||||||
const PendingMsg = require('./components/pending-msg')
|
const PendingMsg = require('./components/pending-msg')
|
||||||
const PendingPersonalMsg = require('./components/pending-personal-msg')
|
const PendingPersonalMsg = require('./components/pending-personal-msg')
|
||||||
|
const PendingTypedMsg = require('./components/pending-typed-msg')
|
||||||
const Loading = require('./components/loading')
|
const Loading = require('./components/loading')
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(ConfirmTxScreen)
|
module.exports = connect(mapStateToProps)(ConfirmTxScreen)
|
||||||
@ -22,6 +23,7 @@ function mapStateToProps (state) {
|
|||||||
unapprovedTxs: state.metamask.unapprovedTxs,
|
unapprovedTxs: state.metamask.unapprovedTxs,
|
||||||
unapprovedMsgs: state.metamask.unapprovedMsgs,
|
unapprovedMsgs: state.metamask.unapprovedMsgs,
|
||||||
unapprovedPersonalMsgs: state.metamask.unapprovedPersonalMsgs,
|
unapprovedPersonalMsgs: state.metamask.unapprovedPersonalMsgs,
|
||||||
|
unapprovedTypedMessages: state.metamask.unapprovedTypedMessages,
|
||||||
index: state.appState.currentView.context,
|
index: state.appState.currentView.context,
|
||||||
warning: state.appState.warning,
|
warning: state.appState.warning,
|
||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
@ -41,9 +43,9 @@ function ConfirmTxScreen () {
|
|||||||
ConfirmTxScreen.prototype.render = function () {
|
ConfirmTxScreen.prototype.render = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { network, provider, unapprovedTxs, currentCurrency, computedBalances,
|
const { network, provider, unapprovedTxs, currentCurrency, computedBalances,
|
||||||
unapprovedMsgs, unapprovedPersonalMsgs, conversionRate, blockGasLimit } = props
|
unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, conversionRate, blockGasLimit } = props
|
||||||
|
|
||||||
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
|
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network)
|
||||||
|
|
||||||
var txData = unconfTxList[props.index] || {}
|
var txData = unconfTxList[props.index] || {}
|
||||||
var txParams = txData.params || {}
|
var txParams = txData.params || {}
|
||||||
@ -112,8 +114,10 @@ ConfirmTxScreen.prototype.render = function () {
|
|||||||
cancelAllTransactions: this.cancelAllTransactions.bind(this, unconfTxList),
|
cancelAllTransactions: this.cancelAllTransactions.bind(this, unconfTxList),
|
||||||
signMessage: this.signMessage.bind(this, txData),
|
signMessage: this.signMessage.bind(this, txData),
|
||||||
signPersonalMessage: this.signPersonalMessage.bind(this, txData),
|
signPersonalMessage: this.signPersonalMessage.bind(this, txData),
|
||||||
|
signTypedMessage: this.signTypedMessage.bind(this, txData),
|
||||||
cancelMessage: this.cancelMessage.bind(this, txData),
|
cancelMessage: this.cancelMessage.bind(this, txData),
|
||||||
cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
|
cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
|
||||||
|
cancelTypedMessage: this.cancelTypedMessage.bind(this, txData)
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
@ -136,6 +140,9 @@ function currentTxView (opts) {
|
|||||||
} else if (type === 'personal_sign') {
|
} else if (type === 'personal_sign') {
|
||||||
log.debug('rendering personal_sign message')
|
log.debug('rendering personal_sign message')
|
||||||
return h(PendingPersonalMsg, opts)
|
return h(PendingPersonalMsg, opts)
|
||||||
|
} else if (type === 'eth_signTypedData') {
|
||||||
|
log.debug('rendering eth_signTypedData message')
|
||||||
|
return h(PendingTypedMsg, opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -184,6 +191,14 @@ ConfirmTxScreen.prototype.signPersonalMessage = function (msgData, event) {
|
|||||||
this.props.dispatch(actions.signPersonalMsg(params))
|
this.props.dispatch(actions.signPersonalMsg(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfirmTxScreen.prototype.signTypedMessage = function (msgData, event) {
|
||||||
|
log.info('conf-tx.js: signing typed message')
|
||||||
|
var params = msgData.msgParams
|
||||||
|
params.metamaskId = msgData.id
|
||||||
|
this.stopPropagation(event)
|
||||||
|
this.props.dispatch(actions.signTypedMsg(params))
|
||||||
|
}
|
||||||
|
|
||||||
ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
|
ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
|
||||||
log.info('canceling message')
|
log.info('canceling message')
|
||||||
this.stopPropagation(event)
|
this.stopPropagation(event)
|
||||||
@ -196,6 +211,12 @@ ConfirmTxScreen.prototype.cancelPersonalMessage = function (msgData, event) {
|
|||||||
this.props.dispatch(actions.cancelPersonalMsg(msgData))
|
this.props.dispatch(actions.cancelPersonalMsg(msgData))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfirmTxScreen.prototype.cancelTypedMessage = function (msgData, event) {
|
||||||
|
log.info('canceling typed message')
|
||||||
|
this.stopPropagation(event)
|
||||||
|
this.props.dispatch(actions.cancelTypedMsg(msgData))
|
||||||
|
}
|
||||||
|
|
||||||
ConfirmTxScreen.prototype.goHome = function (event) {
|
ConfirmTxScreen.prototype.goHome = function (event) {
|
||||||
this.stopPropagation(event)
|
this.stopPropagation(event)
|
||||||
this.props.dispatch(actions.goHome())
|
this.props.dispatch(actions.goHome())
|
||||||
|
@ -574,9 +574,9 @@ function checkUnconfActions (state) {
|
|||||||
|
|
||||||
function getUnconfActionList (state) {
|
function getUnconfActionList (state) {
|
||||||
const { unapprovedTxs, unapprovedMsgs,
|
const { unapprovedTxs, unapprovedMsgs,
|
||||||
unapprovedPersonalMsgs, network } = state.metamask
|
unapprovedPersonalMsgs, unapprovedTypedMessages, network } = state.metamask
|
||||||
|
|
||||||
const unconfActionList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
|
const unconfActionList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, network)
|
||||||
return unconfActionList
|
return unconfActionList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ function startApp (metamaskState, accountManager, opts) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// if unconfirmed txs, start on txConf page
|
// if unconfirmed txs, start on txConf page
|
||||||
const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.network)
|
const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network)
|
||||||
if (unapprovedTxsAll.length > 0) {
|
if (unapprovedTxsAll.length > 0) {
|
||||||
store.dispatch(actions.showConfTxPage())
|
store.dispatch(actions.showConfTxPage())
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
const valuesFor = require('../app/util').valuesFor
|
const valuesFor = require('../app/util').valuesFor
|
||||||
|
|
||||||
module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, network) {
|
module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network) {
|
||||||
log.debug('tx-helper called with params:')
|
log.debug('tx-helper called with params:')
|
||||||
log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, network })
|
log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, typedMessages, network })
|
||||||
|
|
||||||
const txValues = network ? valuesFor(unapprovedTxs).filter(txMeta => txMeta.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
|
const txValues = network ? valuesFor(unapprovedTxs).filter(txMeta => txMeta.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
|
||||||
log.debug(`tx helper found ${txValues.length} unapproved txs`)
|
log.debug(`tx helper found ${txValues.length} unapproved txs`)
|
||||||
|
|
||||||
const msgValues = valuesFor(unapprovedMsgs)
|
const msgValues = valuesFor(unapprovedMsgs)
|
||||||
log.debug(`tx helper found ${msgValues.length} unsigned messages`)
|
log.debug(`tx helper found ${msgValues.length} unsigned messages`)
|
||||||
let allValues = txValues.concat(msgValues)
|
let allValues = txValues.concat(msgValues)
|
||||||
|
|
||||||
const personalValues = valuesFor(personalMsgs)
|
const personalValues = valuesFor(personalMsgs)
|
||||||
log.debug(`tx helper found ${personalValues.length} unsigned personal messages`)
|
log.debug(`tx helper found ${personalValues.length} unsigned personal messages`)
|
||||||
allValues = allValues.concat(personalValues)
|
allValues = allValues.concat(personalValues)
|
||||||
|
|
||||||
|
const typedValues = valuesFor(typedMessages)
|
||||||
|
log.debug(`tx helper found ${typedValues.length} unsigned typed messages`)
|
||||||
|
allValues = allValues.concat(typedValues)
|
||||||
|
|
||||||
allValues = allValues.sort((a, b) => {
|
allValues = allValues.sort((a, b) => {
|
||||||
return a.time > b.time
|
return a.time > b.time
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user