Merge pull request #1076 from MetaMask/messageManagerCleanUp
Message manager clean up
This commit is contained in:
commit
3afa3592fe
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
## Current Master
|
## Current Master
|
||||||
|
|
||||||
|
- Fix unapproved messages not being included in extension badge.
|
||||||
- Fix rendering bug where the Confirm transaction view would lets you approve transactions when the account has insufficient balance.
|
- Fix rendering bug where the Confirm transaction view would lets you approve transactions when the account has insufficient balance.
|
||||||
- Add ability to import accounts in JSON file format (used by Mist, Geth, MyEtherWallet, and more!)
|
- Add ability to import accounts in JSON file format (used by Mist, Geth, MyEtherWallet, and more!)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ const Migrator = require('./lib/migrator/')
|
||||||
const migrations = require('./migrations/')
|
const migrations = require('./migrations/')
|
||||||
const PortStream = require('./lib/port-stream.js')
|
const PortStream = require('./lib/port-stream.js')
|
||||||
const notification = require('./lib/notifications.js')
|
const notification = require('./lib/notifications.js')
|
||||||
const messageManager = require('./lib/message-manager')
|
|
||||||
const MetamaskController = require('./metamask-controller')
|
const MetamaskController = require('./metamask-controller')
|
||||||
const extension = require('./lib/extension')
|
const extension = require('./lib/extension')
|
||||||
const firstTimeState = require('./first-time-state')
|
const firstTimeState = require('./first-time-state')
|
||||||
|
@ -112,14 +111,14 @@ function setupController (initState) {
|
||||||
|
|
||||||
updateBadge()
|
updateBadge()
|
||||||
controller.txManager.on('updateBadge', updateBadge)
|
controller.txManager.on('updateBadge', updateBadge)
|
||||||
|
controller.messageManager.on('updateBadge', updateBadge)
|
||||||
|
|
||||||
// plugin badge text
|
// plugin badge text
|
||||||
function updateBadge () {
|
function updateBadge () {
|
||||||
var label = ''
|
var label = ''
|
||||||
var unapprovedTxCount = controller.txManager.unapprovedTxCount
|
var unapprovedTxCount = controller.txManager.unapprovedTxCount
|
||||||
var unconfMsgs = messageManager.unconfirmedMsgs()
|
var unapprovedMsgCount = controller.messageManager.unapprovedMsgCount
|
||||||
var unconfMsgLen = Object.keys(unconfMsgs).length
|
var count = unapprovedTxCount + unapprovedMsgCount
|
||||||
var count = unapprovedTxCount + unconfMsgLen
|
|
||||||
if (count) {
|
if (count) {
|
||||||
label = String(count)
|
label = String(count)
|
||||||
}
|
}
|
||||||
|
@ -145,4 +144,4 @@ extension.runtime.onInstalled.addListener(function (details) {
|
||||||
if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
|
if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
|
||||||
extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
|
extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,11 +5,7 @@ const EventEmitter = require('events').EventEmitter
|
||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
const filter = require('promise-filter')
|
const filter = require('promise-filter')
|
||||||
const encryptor = require('browser-passworder')
|
const encryptor = require('browser-passworder')
|
||||||
const createId = require('./lib/random-id')
|
|
||||||
const normalizeAddress = require('./lib/sig-util').normalize
|
const normalizeAddress = require('./lib/sig-util').normalize
|
||||||
const messageManager = require('./lib/message-manager')
|
|
||||||
function noop () {}
|
|
||||||
|
|
||||||
// Keyrings:
|
// Keyrings:
|
||||||
const SimpleKeyring = require('./keyrings/simple')
|
const SimpleKeyring = require('./keyrings/simple')
|
||||||
const HdKeyring = require('./keyrings/hd')
|
const HdKeyring = require('./keyrings/hd')
|
||||||
|
@ -18,7 +14,6 @@ const keyringTypes = [
|
||||||
HdKeyring,
|
HdKeyring,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class KeyringController extends EventEmitter {
|
class KeyringController extends EventEmitter {
|
||||||
|
|
||||||
// PUBLIC METHODS
|
// PUBLIC METHODS
|
||||||
|
@ -42,9 +37,6 @@ class KeyringController extends EventEmitter {
|
||||||
this.ethStore = opts.ethStore
|
this.ethStore = opts.ethStore
|
||||||
this.encryptor = encryptor
|
this.encryptor = encryptor
|
||||||
this.keyrings = []
|
this.keyrings = []
|
||||||
|
|
||||||
this._unconfMsgCbs = {}
|
|
||||||
|
|
||||||
this.getNetwork = opts.getNetwork
|
this.getNetwork = opts.getNetwork
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +70,7 @@ class KeyringController extends EventEmitter {
|
||||||
// in this class, but will need to be Promisified when we move our
|
// in this class, but will need to be Promisified when we move our
|
||||||
// persistence to an async model.
|
// persistence to an async model.
|
||||||
getState () {
|
getState () {
|
||||||
|
|
||||||
// old wallet
|
// old wallet
|
||||||
const memState = this.memStore.getState()
|
const memState = this.memStore.getState()
|
||||||
const result = {
|
const result = {
|
||||||
|
@ -87,9 +80,6 @@ class KeyringController extends EventEmitter {
|
||||||
keyringTypes: memState.keyringTypes,
|
keyringTypes: memState.keyringTypes,
|
||||||
identities: memState.identities,
|
identities: memState.identities,
|
||||||
keyrings: memState.keyrings,
|
keyrings: memState.keyrings,
|
||||||
// messageManager
|
|
||||||
unconfMsgs: messageManager.unconfirmedMsgs(),
|
|
||||||
messages: messageManager.getMsgList(),
|
|
||||||
// configManager
|
// configManager
|
||||||
seedWords: this.configManager.getSeedWords(),
|
seedWords: this.configManager.getSeedWords(),
|
||||||
isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
|
isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
|
||||||
|
@ -284,86 +274,19 @@ class KeyringController extends EventEmitter {
|
||||||
return keyring.signTransaction(fromAddress, ethTx)
|
return keyring.signTransaction(fromAddress, ethTx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Add Unconfirmed Message
|
|
||||||
// @object msgParams
|
|
||||||
// @function cb
|
|
||||||
//
|
|
||||||
// Does not call back, only emits an `update` event.
|
|
||||||
//
|
|
||||||
// Adds the given `msgParams` and `cb` to a local cache,
|
|
||||||
// for displaying to a user for approval before signing or canceling.
|
|
||||||
addUnconfirmedMessage (msgParams, cb) {
|
|
||||||
// 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: 'unconfirmed',
|
|
||||||
}
|
|
||||||
messageManager.addMsg(msgData)
|
|
||||||
console.log('addUnconfirmedMessage:', msgData)
|
|
||||||
|
|
||||||
// keep the cb around for after approval (requires user interaction)
|
|
||||||
// This cb fires completion to the Dapp's write operation.
|
|
||||||
this._unconfMsgCbs[msgId] = cb
|
|
||||||
|
|
||||||
// signal update
|
|
||||||
this.emit('update')
|
|
||||||
return msgId
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel Message
|
|
||||||
// @string msgId
|
|
||||||
// @function cb (optional)
|
|
||||||
//
|
|
||||||
// Calls back to cached `unconfMsgCb`.
|
|
||||||
// Calls back to `cb` if provided.
|
|
||||||
//
|
|
||||||
// Forgets any messages matching `msgId`.
|
|
||||||
cancelMessage (msgId, cb) {
|
|
||||||
var approvalCb = this._unconfMsgCbs[msgId] || noop
|
|
||||||
|
|
||||||
// reject tx
|
|
||||||
approvalCb(null, false)
|
|
||||||
// clean up
|
|
||||||
messageManager.rejectMsg(msgId)
|
|
||||||
delete this._unconfTxCbs[msgId]
|
|
||||||
|
|
||||||
if (cb && typeof cb === 'function') {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign Message
|
// Sign Message
|
||||||
// @object msgParams
|
// @object msgParams
|
||||||
// @function cb
|
|
||||||
//
|
//
|
||||||
// returns Promise(@buffer rawSig)
|
// returns Promise(@buffer rawSig)
|
||||||
// calls back @function cb with @buffer rawSig
|
|
||||||
// calls back cached Dapp's @function unconfMsgCb.
|
|
||||||
//
|
//
|
||||||
// Attempts to sign the provided @object msgParams.
|
// Attempts to sign the provided @object msgParams.
|
||||||
signMessage (msgParams, cb) {
|
signMessage (msgParams) {
|
||||||
try {
|
const address = normalizeAddress(msgParams.from)
|
||||||
const msgId = msgParams.metamaskId
|
return this.getKeyringForAccount(address)
|
||||||
delete msgParams.metamaskId
|
.then((keyring) => {
|
||||||
const approvalCb = this._unconfMsgCbs[msgId] || noop
|
return keyring.signMessage(address, msgParams.data)
|
||||||
|
})
|
||||||
const address = normalizeAddress(msgParams.from)
|
|
||||||
return this.getKeyringForAccount(address)
|
|
||||||
.then((keyring) => {
|
|
||||||
return keyring.signMessage(address, msgParams.data)
|
|
||||||
}).then((rawSig) => {
|
|
||||||
cb(null, rawSig)
|
|
||||||
approvalCb(null, true)
|
|
||||||
messageManager.confirmMsg(msgId)
|
|
||||||
return rawSig
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
cb(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
|
|
|
@ -1,61 +1,110 @@
|
||||||
module.exports = new MessageManager()
|
const EventEmitter = require('events')
|
||||||
|
const ObservableStore = require('obs-store')
|
||||||
|
const createId = require('./random-id')
|
||||||
|
|
||||||
function MessageManager (opts) {
|
|
||||||
this.messages = []
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.getMsgList = function () {
|
module.exports = class MessageManager extends EventEmitter{
|
||||||
return this.messages
|
constructor (opts) {
|
||||||
}
|
super()
|
||||||
|
this.memStore = new ObservableStore({ messages: [] })
|
||||||
MessageManager.prototype.unconfirmedMsgs = function () {
|
|
||||||
var messages = this.getMsgList()
|
|
||||||
return messages.filter(msg => msg.status === 'unconfirmed')
|
|
||||||
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype._saveMsgList = function (msgList) {
|
|
||||||
this.messages = msgList
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.addMsg = function (msg) {
|
|
||||||
var messages = this.getMsgList()
|
|
||||||
messages.push(msg)
|
|
||||||
this._saveMsgList(messages)
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.getMsg = function (msgId) {
|
|
||||||
var messages = this.getMsgList()
|
|
||||||
var matching = messages.filter(msg => msg.id === msgId)
|
|
||||||
return matching.length > 0 ? matching[0] : null
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.confirmMsg = function (msgId) {
|
|
||||||
this._setMsgStatus(msgId, 'confirmed')
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.rejectMsg = function (msgId) {
|
|
||||||
this._setMsgStatus(msgId, 'rejected')
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype._setMsgStatus = function (msgId, status) {
|
|
||||||
var msg = this.getMsg(msgId)
|
|
||||||
if (msg) msg.status = status
|
|
||||||
this.updateMsg(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageManager.prototype.updateMsg = function (msg) {
|
|
||||||
var messages = this.getMsgList()
|
|
||||||
var found, index
|
|
||||||
messages.forEach((otherMsg, i) => {
|
|
||||||
if (otherMsg.id === msg.id) {
|
|
||||||
found = true
|
|
||||||
index = i
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (found) {
|
|
||||||
messages[index] = msg
|
|
||||||
}
|
}
|
||||||
this._saveMsgList(messages)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
getState() {
|
||||||
|
return {
|
||||||
|
unapprovedMsgs: this.getUnapprovedMsgs(),
|
||||||
|
messages: this.getMsgList(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getMsgList () {
|
||||||
|
return this.memStore.getState().messages
|
||||||
|
}
|
||||||
|
|
||||||
|
get unapprovedMsgCount () {
|
||||||
|
return Object.keys(this.getUnapprovedMsgs()).length
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnapprovedMsgs () {
|
||||||
|
let messages = this.getMsgList()
|
||||||
|
return messages.filter(msg => msg.status === 'unapproved')
|
||||||
|
.reduce((result, msg) => { result[msg.id] = msg; return result }, {})
|
||||||
|
}
|
||||||
|
|
||||||
|
addUnapprovedMessage (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',
|
||||||
|
}
|
||||||
|
this.addMsg(msgData)
|
||||||
|
console.log('addUnapprovedMessage:', msgData)
|
||||||
|
|
||||||
|
// keep the cb around for after approval (requires user interaction)
|
||||||
|
// This cb fires completion to the Dapp's write operation.
|
||||||
|
|
||||||
|
// signal update
|
||||||
|
this.emit('update')
|
||||||
|
return msgId
|
||||||
|
}
|
||||||
|
|
||||||
|
addMsg (msg) {
|
||||||
|
let messages = this.getMsgList()
|
||||||
|
messages.push(msg)
|
||||||
|
this._saveMsgList(messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
getMsg (msgId) {
|
||||||
|
let messages = this.getMsgList()
|
||||||
|
let matching = messages.filter(msg => msg.id === msgId)
|
||||||
|
return matching.length > 0 ? matching[0] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
approveMessage (msgParams) {
|
||||||
|
this.setMsgStatusApproved(msgParams.metamaskId)
|
||||||
|
return this.prepMsgForSigning(msgParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
setMsgStatusApproved (msgId) {
|
||||||
|
this._setMsgStatus(msgId, 'approved')
|
||||||
|
}
|
||||||
|
|
||||||
|
prepMsgForSigning (msgParams) {
|
||||||
|
delete msgParams.metamaskId
|
||||||
|
return Promise.resolve(msgParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
rejectMsg (msgId) {
|
||||||
|
this.brodcastMessage(null, msgId, 'rejected')
|
||||||
|
this._setMsgStatus(msgId, 'rejected')
|
||||||
|
}
|
||||||
|
|
||||||
|
brodcastMessage (rawSig, msgId, status) {
|
||||||
|
this.emit(`${msgId}:finished`, {status, rawSig})
|
||||||
|
}
|
||||||
|
// PRIVATE METHODS
|
||||||
|
|
||||||
|
_setMsgStatus (msgId, status) {
|
||||||
|
let msg = this.getMsg(msgId)
|
||||||
|
if (msg) msg.status = status
|
||||||
|
this._updateMsg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateMsg (msg) {
|
||||||
|
let messages = this.getMsgList()
|
||||||
|
let index = messages.findIndex((message) => message.id === msg.id)
|
||||||
|
if (index !== -1) {
|
||||||
|
messages[index] = msg
|
||||||
|
}
|
||||||
|
this._saveMsgList(messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveMsgList (msgList) {
|
||||||
|
this.memStore.updateState({ messages: msgList })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||||
const KeyringController = require('./keyring-controller')
|
const KeyringController = require('./keyring-controller')
|
||||||
const PreferencesController = require('./lib/controllers/preferences')
|
const PreferencesController = require('./lib/controllers/preferences')
|
||||||
const NoticeController = require('./notice-controller')
|
const NoticeController = require('./notice-controller')
|
||||||
const messageManager = require('./lib/message-manager')
|
const MessageManager = require('./lib/message-manager')
|
||||||
const TxManager = require('./transaction-manager')
|
const TxManager = require('./transaction-manager')
|
||||||
const ConfigManager = require('./lib/config-manager')
|
const ConfigManager = require('./lib/config-manager')
|
||||||
const extension = require('./lib/extension')
|
const extension = require('./lib/extension')
|
||||||
|
@ -34,7 +34,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
|
|
||||||
// observable state store
|
// observable state store
|
||||||
this.store = new ObservableStore(initState)
|
this.store = new ObservableStore(initState)
|
||||||
|
|
||||||
// config manager
|
// config manager
|
||||||
this.configManager = new ConfigManager({
|
this.configManager = new ConfigManager({
|
||||||
store: this.store,
|
store: this.store,
|
||||||
|
@ -54,7 +54,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
// eth data query tools
|
// eth data query tools
|
||||||
this.ethQuery = new EthQuery(this.provider)
|
this.ethQuery = new EthQuery(this.provider)
|
||||||
this.ethStore = new EthStore(this.provider)
|
this.ethStore = new EthStore(this.provider)
|
||||||
|
|
||||||
// key mgmt
|
// key mgmt
|
||||||
this.keyringController = new KeyringController({
|
this.keyringController = new KeyringController({
|
||||||
initState: initState.KeyringController,
|
initState: initState.KeyringController,
|
||||||
|
@ -79,7 +79,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
provider: this.provider,
|
provider: this.provider,
|
||||||
blockTracker: this.provider,
|
blockTracker: this.provider,
|
||||||
})
|
})
|
||||||
|
|
||||||
// notices
|
// notices
|
||||||
this.noticeController = new NoticeController({
|
this.noticeController = new NoticeController({
|
||||||
configManager: this.configManager,
|
configManager: this.configManager,
|
||||||
|
@ -89,7 +89,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
// this.noticeController.startPolling()
|
// this.noticeController.startPolling()
|
||||||
|
|
||||||
this.getNetwork()
|
this.getNetwork()
|
||||||
this.messageManager = messageManager
|
this.messageManager = new MessageManager()
|
||||||
this.publicConfigStore = this.initPublicConfigStore()
|
this.publicConfigStore = this.initPublicConfigStore()
|
||||||
|
|
||||||
this.checkTOSChange()
|
this.checkTOSChange()
|
||||||
|
@ -105,6 +105,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
this.ethStore.on('update', this.sendUpdate.bind(this))
|
this.ethStore.on('update', this.sendUpdate.bind(this))
|
||||||
this.keyringController.on('update', this.sendUpdate.bind(this))
|
this.keyringController.on('update', this.sendUpdate.bind(this))
|
||||||
this.txManager.on('update', this.sendUpdate.bind(this))
|
this.txManager.on('update', this.sendUpdate.bind(this))
|
||||||
|
this.messageManager.on('update', this.sendUpdate.bind(this))
|
||||||
this.keyringController.store.subscribe((state) => {
|
this.keyringController.store.subscribe((state) => {
|
||||||
this.store.updateState({ KeyringController: state })
|
this.store.updateState({ KeyringController: state })
|
||||||
})
|
})
|
||||||
|
@ -133,11 +134,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
// tx signing
|
// tx signing
|
||||||
processTransaction: (txParams, cb) => this.newUnapprovedTransaction(txParams, cb),
|
processTransaction: (txParams, cb) => this.newUnapprovedTransaction(txParams, cb),
|
||||||
// msg signing
|
// msg signing
|
||||||
approveMessage: this.newUnsignedMessage.bind(this),
|
processMessage: this.newUnsignedMessage.bind(this),
|
||||||
signMessage: (...args) => {
|
|
||||||
this.keyringController.signMessage(...args)
|
|
||||||
this.sendUpdate()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -169,6 +166,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
//
|
//
|
||||||
|
|
||||||
getState () {
|
getState () {
|
||||||
|
|
||||||
const wallet = this.configManager.getWallet()
|
const wallet = this.configManager.getWallet()
|
||||||
const vault = this.keyringController.store.getState().vault
|
const vault = this.keyringController.store.getState().vault
|
||||||
const isInitialized = (!!wallet || !!vault)
|
const isInitialized = (!!wallet || !!vault)
|
||||||
|
@ -179,6 +177,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
this.state,
|
this.state,
|
||||||
this.ethStore.getState(),
|
this.ethStore.getState(),
|
||||||
this.txManager.getState(),
|
this.txManager.getState(),
|
||||||
|
this.messageManager.getState(),
|
||||||
this.keyringController.getState(),
|
this.keyringController.getState(),
|
||||||
this.preferencesController.store.getState(),
|
this.preferencesController.store.getState(),
|
||||||
this.noticeController.getState(),
|
this.noticeController.getState(),
|
||||||
|
@ -202,6 +201,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
const keyringController = this.keyringController
|
const keyringController = this.keyringController
|
||||||
const preferencesController = this.preferencesController
|
const preferencesController = this.preferencesController
|
||||||
const txManager = this.txManager
|
const txManager = this.txManager
|
||||||
|
const messageManager = this.messageManager
|
||||||
const noticeController = this.noticeController
|
const noticeController = this.noticeController
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -221,7 +221,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
buyEth: this.buyEth.bind(this),
|
buyEth: this.buyEth.bind(this),
|
||||||
// shapeshift
|
// shapeshift
|
||||||
createShapeShiftTx: this.createShapeShiftTx.bind(this),
|
createShapeShiftTx: this.createShapeShiftTx.bind(this),
|
||||||
|
|
||||||
// primary HD keyring management
|
// primary HD keyring management
|
||||||
addNewAccount: this.addNewAccount.bind(this),
|
addNewAccount: this.addNewAccount.bind(this),
|
||||||
placeSeedWords: this.placeSeedWords.bind(this),
|
placeSeedWords: this.placeSeedWords.bind(this),
|
||||||
|
@ -245,8 +245,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
// signing methods
|
// signing methods
|
||||||
approveTransaction: txManager.approveTransaction.bind(txManager),
|
approveTransaction: txManager.approveTransaction.bind(txManager),
|
||||||
cancelTransaction: txManager.cancelTransaction.bind(txManager),
|
cancelTransaction: txManager.cancelTransaction.bind(txManager),
|
||||||
signMessage: keyringController.signMessage.bind(keyringController),
|
signMessage: this.signMessage.bind(this),
|
||||||
cancelMessage: keyringController.cancelMessage.bind(keyringController),
|
cancelMessage: messageManager.rejectMsg.bind(messageManager),
|
||||||
|
|
||||||
// notices
|
// notices
|
||||||
checkNotices: noticeController.updateNoticesList.bind(noticeController),
|
checkNotices: noticeController.updateNoticesList.bind(noticeController),
|
||||||
|
@ -388,20 +388,37 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
newUnsignedMessage (msgParams, cb) {
|
newUnsignedMessage (msgParams, cb) {
|
||||||
var state = this.keyringController.getState()
|
let msgId = this.messageManager.addUnapprovedMessage(msgParams)
|
||||||
if (!state.isUnlocked) {
|
this.sendUpdate()
|
||||||
this.keyringController.addUnconfirmedMessage(msgParams, cb)
|
this.opts.showUnconfirmedMessage()
|
||||||
this.opts.unlockAccountMessage()
|
this.messageManager.once(`${msgId}:finished`, (data) => {
|
||||||
} else {
|
switch (data.status) {
|
||||||
this.addUnconfirmedMessage(msgParams, cb)
|
case 'approved':
|
||||||
this.sendUpdate()
|
return cb(null, data.rawSig)
|
||||||
}
|
case 'rejected':
|
||||||
|
return cb(new Error('MetaMask Message Signature: User denied transaction signature.'))
|
||||||
|
default:
|
||||||
|
return cb(new Error(`MetaMask Message Signature: Unknown problem: ${JSON.stringify(msgParams)}`))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
addUnconfirmedMessage (msgParams, cb) {
|
signMessage (msgParams, cb) {
|
||||||
const keyringController = this.keyringController
|
const msgId = msgParams.metamaskId
|
||||||
const msgId = keyringController.addUnconfirmedMessage(msgParams, cb)
|
// sets the status op the message to 'approved'
|
||||||
this.opts.showUnconfirmedMessage(msgParams, msgId)
|
// and removes the metamaskId for signing
|
||||||
|
return this.messageManager.approveMessage(msgParams)
|
||||||
|
.then((cleanMsgParams) => {
|
||||||
|
// signs the message
|
||||||
|
return this.keyringController.signMessage(cleanMsgParams)
|
||||||
|
})
|
||||||
|
.then((rawSig) => {
|
||||||
|
// tells the listener that the message has been signed
|
||||||
|
// and can be returned to the dapp
|
||||||
|
this.messageManager.brodcastMessage(rawSig, msgId, 'approved')
|
||||||
|
}).then(() => {
|
||||||
|
cb()
|
||||||
|
}).catch((err) => cb(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ module.exports = class TransactionManager extends EventEmitter {
|
||||||
var selectedAddress = this.getSelectedAddress()
|
var selectedAddress = this.getSelectedAddress()
|
||||||
return {
|
return {
|
||||||
transactions: this.getTxList(),
|
transactions: this.getTxList(),
|
||||||
unconfTxs: this.getUnapprovedTxList(),
|
unapprovedTxs: this.getUnapprovedTxList(),
|
||||||
selectedAddressTxList: this.getFilteredTxList({metamaskNetworkId: this.getNetwork(), from: selectedAddress}),
|
selectedAddressTxList: this.getFilteredTxList({metamaskNetworkId: this.getNetwork(), from: selectedAddress}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@
|
||||||
"valid-url": "^1.0.9",
|
"valid-url": "^1.0.9",
|
||||||
"vreme": "^3.0.2",
|
"vreme": "^3.0.2",
|
||||||
"web3": "0.17.0-beta",
|
"web3": "0.17.0-beta",
|
||||||
"web3-provider-engine": "^8.4.0",
|
"web3-provider-engine": "^8.5.0",
|
||||||
"web3-stream-provider": "^2.0.6",
|
"web3-stream-provider": "^2.0.6",
|
||||||
"xtend": "^4.0.1"
|
"xtend": "^4.0.1"
|
||||||
},
|
},
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('tx confirmation screen', function() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
metamask: {
|
metamask: {
|
||||||
unconfTxs: {
|
unapprovedTxs: {
|
||||||
'1457634084250832': {
|
'1457634084250832': {
|
||||||
id: 1457634084250832,
|
id: 1457634084250832,
|
||||||
status: "unconfirmed",
|
status: "unconfirmed",
|
||||||
|
@ -119,7 +119,7 @@ describe('tx confirmation screen', function() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
metamask: {
|
metamask: {
|
||||||
unconfTxs: {
|
unapprovedTxs: {
|
||||||
'1457634084250832': {
|
'1457634084250832': {
|
||||||
id: 1457634084250832,
|
id: 1457634084250832,
|
||||||
status: "unconfirmed",
|
status: "unconfirmed",
|
||||||
|
@ -162,7 +162,7 @@ describe('tx confirmation screen', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
function getUnconfirmedTxCount(state) {
|
function getUnconfirmedTxCount(state) {
|
||||||
var txs = state.metamask.unconfTxs
|
var txs = state.metamask.unapprovedTxs
|
||||||
var count = Object.keys(txs).length
|
var count = Object.keys(txs).length
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
const assert = require('assert')
|
||||||
|
const extend = require('xtend')
|
||||||
|
const EventEmitter = require('events')
|
||||||
|
|
||||||
|
const MessageManger = require('../../app/scripts/lib/message-manager')
|
||||||
|
|
||||||
|
describe('Transaction Manager', function() {
|
||||||
|
let messageManager
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
|
messageManager = new MessageManger ()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#getMsgList', function() {
|
||||||
|
it('when new should return empty array', function() {
|
||||||
|
var result = messageManager.getMsgList()
|
||||||
|
assert.ok(Array.isArray(result))
|
||||||
|
assert.equal(result.length, 0)
|
||||||
|
})
|
||||||
|
it('should also return transactions from local storage if any', function() {
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#_saveMsgList', function() {
|
||||||
|
it('saves the submitted data to the Msg list', function() {
|
||||||
|
var target = [{ foo: 'bar', metamaskNetworkId: 'unit test' }]
|
||||||
|
messageManager._saveMsgList(target)
|
||||||
|
var result = messageManager.getMsgList()
|
||||||
|
assert.equal(result[0].foo, 'bar')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#addMsg', function() {
|
||||||
|
it('adds a Msg returned in getMsgList', function() {
|
||||||
|
var Msg = { id: 1, status: 'approved', metamaskNetworkId: 'unit test' }
|
||||||
|
messageManager.addMsg(Msg)
|
||||||
|
var result = messageManager.getMsgList()
|
||||||
|
assert.ok(Array.isArray(result))
|
||||||
|
assert.equal(result.length, 1)
|
||||||
|
assert.equal(result[0].id, 1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#setMsgStatusApproved', function() {
|
||||||
|
it('sets the Msg status to approved', function() {
|
||||||
|
var Msg = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
|
||||||
|
messageManager.addMsg(Msg)
|
||||||
|
messageManager.setMsgStatusApproved(1)
|
||||||
|
var result = messageManager.getMsgList()
|
||||||
|
assert.ok(Array.isArray(result))
|
||||||
|
assert.equal(result.length, 1)
|
||||||
|
assert.equal(result[0].status, 'approved')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#rejectMsg', function() {
|
||||||
|
it('sets the Msg status to rejected', function() {
|
||||||
|
var Msg = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
|
||||||
|
messageManager.addMsg(Msg)
|
||||||
|
messageManager.rejectMsg(1)
|
||||||
|
var result = messageManager.getMsgList()
|
||||||
|
assert.ok(Array.isArray(result))
|
||||||
|
assert.equal(result.length, 1)
|
||||||
|
assert.equal(result[0].status, 'rejected')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#_updateMsg', function() {
|
||||||
|
it('replaces the Msg with the same id', function() {
|
||||||
|
messageManager.addMsg({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' })
|
||||||
|
messageManager.addMsg({ id: '2', status: 'approved', metamaskNetworkId: 'unit test' })
|
||||||
|
messageManager._updateMsg({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test' })
|
||||||
|
var result = messageManager.getMsg('1')
|
||||||
|
assert.equal(result.hash, 'foo')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#getUnapprovedMsgs', function() {
|
||||||
|
it('returns unapproved Msgs in a hash', function() {
|
||||||
|
messageManager.addMsg({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' })
|
||||||
|
messageManager.addMsg({ id: '2', status: 'approved', metamaskNetworkId: 'unit test' })
|
||||||
|
let result = messageManager.getUnapprovedMsgs()
|
||||||
|
assert.equal(typeof result, 'object')
|
||||||
|
assert.equal(result['1'].status, 'unapproved')
|
||||||
|
assert.equal(result['2'], undefined)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#getMsg', function() {
|
||||||
|
it('returns a Msg with the requested id', function() {
|
||||||
|
messageManager.addMsg({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' })
|
||||||
|
messageManager.addMsg({ id: '2', status: 'approved', metamaskNetworkId: 'unit test' })
|
||||||
|
assert.equal(messageManager.getMsg('1').status, 'unapproved')
|
||||||
|
assert.equal(messageManager.getMsg('2').status, 'approved')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -27,7 +27,7 @@ function mapStateToProps (state) {
|
||||||
address: state.metamask.selectedAddress,
|
address: state.metamask.selectedAddress,
|
||||||
accountDetail: state.appState.accountDetail,
|
accountDetail: state.appState.accountDetail,
|
||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
unconfMsgs: valuesFor(state.metamask.unconfMsgs),
|
unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
|
||||||
shapeShiftTxList: state.metamask.shapeShiftTxList,
|
shapeShiftTxList: state.metamask.shapeShiftTxList,
|
||||||
transactions: state.metamask.selectedAddressTxList || [],
|
transactions: state.metamask.selectedAddressTxList || [],
|
||||||
}
|
}
|
||||||
|
@ -246,11 +246,11 @@ AccountDetailScreen.prototype.subview = function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountDetailScreen.prototype.transactionList = function () {
|
AccountDetailScreen.prototype.transactionList = function () {
|
||||||
const {transactions, unconfMsgs, address, network, shapeShiftTxList } = this.props
|
const {transactions, unapprovedMsgs, address, network, shapeShiftTxList } = this.props
|
||||||
return h(TransactionList, {
|
return h(TransactionList, {
|
||||||
transactions: transactions.sort((a, b) => b.time - a.time),
|
transactions: transactions.sort((a, b) => b.time - a.time),
|
||||||
network,
|
network,
|
||||||
unconfMsgs,
|
unapprovedMsgs,
|
||||||
address,
|
address,
|
||||||
shapeShiftTxList,
|
shapeShiftTxList,
|
||||||
viewPendingTx: (txId) => {
|
viewPendingTx: (txId) => {
|
||||||
|
|
|
@ -10,15 +10,15 @@ const AccountListItem = require('./account-list-item')
|
||||||
module.exports = connect(mapStateToProps)(AccountsScreen)
|
module.exports = connect(mapStateToProps)(AccountsScreen)
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const pendingTxs = valuesFor(state.metamask.unconfTxs)
|
const pendingTxs = valuesFor(state.metamask.unapprovedTxs)
|
||||||
.filter(tx => tx.txParams.metamaskNetworkId === state.metamask.network)
|
.filter(tx => tx.txParams.metamaskNetworkId === state.metamask.network)
|
||||||
const pendingMsgs = valuesFor(state.metamask.unconfMsgs)
|
const pendingMsgs = valuesFor(state.metamask.unapprovedMsgs)
|
||||||
const pending = pendingTxs.concat(pendingMsgs)
|
const pending = pendingTxs.concat(pendingMsgs)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
accounts: state.metamask.accounts,
|
accounts: state.metamask.accounts,
|
||||||
identities: state.metamask.identities,
|
identities: state.metamask.identities,
|
||||||
unconfTxs: state.metamask.unconfTxs,
|
unapprovedTxs: state.metamask.unapprovedTxs,
|
||||||
selectedAddress: state.metamask.selectedAddress,
|
selectedAddress: state.metamask.selectedAddress,
|
||||||
scrollToBottom: state.appState.scrollToBottom,
|
scrollToBottom: state.appState.scrollToBottom,
|
||||||
pending,
|
pending,
|
||||||
|
@ -35,7 +35,7 @@ AccountsScreen.prototype.render = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { keyrings } = props
|
const { keyrings } = props
|
||||||
const identityList = valuesFor(props.identities)
|
const identityList = valuesFor(props.identities)
|
||||||
const unconfTxList = valuesFor(props.unconfTxs)
|
const unapprovedTxList = valuesFor(props.unapprovedTxs)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ AccountsScreen.prototype.render = function () {
|
||||||
h('hr.horizontal-line'),
|
h('hr.horizontal-line'),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
unconfTxList.length ? (
|
unapprovedTxList.length ? (
|
||||||
|
|
||||||
h('.unconftx-link.flex-row.flex-center', {
|
h('.unconftx-link.flex-row.flex-center', {
|
||||||
onClick: this.navigateToConfTx.bind(this),
|
onClick: this.navigateToConfTx.bind(this),
|
||||||
|
|
|
@ -52,8 +52,8 @@ function mapStateToProps (state) {
|
||||||
activeAddress: state.appState.activeAddress,
|
activeAddress: state.appState.activeAddress,
|
||||||
transForward: state.appState.transForward,
|
transForward: state.appState.transForward,
|
||||||
seedWords: state.metamask.seedWords,
|
seedWords: state.metamask.seedWords,
|
||||||
unconfTxs: state.metamask.unconfTxs,
|
unapprovedTxs: state.metamask.unapprovedTxs,
|
||||||
unconfMsgs: state.metamask.unconfMsgs,
|
unapprovedMsgs: state.metamask.unapprovedMsgs,
|
||||||
menuOpen: state.appState.menuOpen,
|
menuOpen: state.appState.menuOpen,
|
||||||
network: state.metamask.network,
|
network: state.metamask.network,
|
||||||
provider: state.metamask.provider,
|
provider: state.metamask.provider,
|
||||||
|
|
|
@ -15,15 +15,9 @@ TransactionIcon.prototype.render = function () {
|
||||||
const { transaction, txParams, isMsg } = this.props
|
const { transaction, txParams, isMsg } = this.props
|
||||||
switch (transaction.status) {
|
switch (transaction.status) {
|
||||||
case 'unapproved':
|
case 'unapproved':
|
||||||
return h('.unapproved-tx', {
|
return h( !isMsg ? '.unapproved-tx-icon' : 'i.fa.fa-certificate.fa-lg', {
|
||||||
style: {
|
style: {
|
||||||
width: '24px',
|
width: '24px',
|
||||||
height: '24px',
|
|
||||||
background: '#4dffff',
|
|
||||||
border: 'solid',
|
|
||||||
borderColor: '#AEAEAE',
|
|
||||||
borderWidth: '0.5px',
|
|
||||||
borderRadius: '13px',
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ TransactionListItem.prototype.render = function () {
|
||||||
var isMsg = ('msgParams' in transaction)
|
var isMsg = ('msgParams' in transaction)
|
||||||
var isTx = ('txParams' in transaction)
|
var isTx = ('txParams' in transaction)
|
||||||
var isPending = transaction.status === 'unapproved'
|
var isPending = transaction.status === 'unapproved'
|
||||||
|
|
||||||
let txParams
|
let txParams
|
||||||
if (isTx) {
|
if (isTx) {
|
||||||
txParams = transaction.txParams
|
txParams = transaction.txParams
|
||||||
|
|
|
@ -13,13 +13,13 @@ function TransactionList () {
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionList.prototype.render = function () {
|
TransactionList.prototype.render = function () {
|
||||||
const { transactions, network, unconfMsgs } = this.props
|
const { transactions, network, unapprovedMsgs } = this.props
|
||||||
|
|
||||||
var shapeShiftTxList
|
var shapeShiftTxList
|
||||||
if (network === '1') {
|
if (network === '1') {
|
||||||
shapeShiftTxList = this.props.shapeShiftTxList
|
shapeShiftTxList = this.props.shapeShiftTxList
|
||||||
}
|
}
|
||||||
const txsToRender = !shapeShiftTxList ? transactions.concat(unconfMsgs) : transactions.concat(unconfMsgs, shapeShiftTxList)
|
const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
|
||||||
.sort((a, b) => b.time - a.time)
|
.sort((a, b) => b.time - a.time)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -20,8 +20,8 @@ function mapStateToProps (state) {
|
||||||
identities: state.metamask.identities,
|
identities: state.metamask.identities,
|
||||||
accounts: state.metamask.accounts,
|
accounts: state.metamask.accounts,
|
||||||
selectedAddress: state.metamask.selectedAddress,
|
selectedAddress: state.metamask.selectedAddress,
|
||||||
unconfTxs: state.metamask.unconfTxs,
|
unapprovedTxs: state.metamask.unapprovedTxs,
|
||||||
unconfMsgs: state.metamask.unconfMsgs,
|
unapprovedMsgs: state.metamask.unapprovedMsgs,
|
||||||
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,
|
||||||
|
@ -39,10 +39,10 @@ ConfirmTxScreen.prototype.render = function () {
|
||||||
|
|
||||||
var network = state.network
|
var network = state.network
|
||||||
var provider = state.provider
|
var provider = state.provider
|
||||||
var unconfTxs = state.unconfTxs
|
var unapprovedTxs = state.unapprovedTxs
|
||||||
var unconfMsgs = state.unconfMsgs
|
var unapprovedMsgs = state.unapprovedMsgs
|
||||||
|
|
||||||
var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
|
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
|
||||||
var index = state.index !== undefined && unconfTxList[index] ? state.index : 0
|
var index = state.index !== undefined && unconfTxList[index] ? state.index : 0
|
||||||
var txData = unconfTxList[index] || {}
|
var txData = unconfTxList[index] || {}
|
||||||
var txParams = txData.params || {}
|
var txParams = txData.params || {}
|
||||||
|
|
|
@ -408,6 +408,16 @@ input.large-input {
|
||||||
.name-label{
|
.name-label{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unapproved-tx-icon {
|
||||||
|
height: 24px;
|
||||||
|
background: #4dffff;
|
||||||
|
border: solid;
|
||||||
|
border-color: #AEAEAE;
|
||||||
|
border-width: 0.5px;
|
||||||
|
border-radius: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
.edit-text {
|
.edit-text {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|
|
@ -307,11 +307,11 @@ function reduceApp (state, action) {
|
||||||
})
|
})
|
||||||
|
|
||||||
case actions.COMPLETED_TX:
|
case actions.COMPLETED_TX:
|
||||||
var unconfTxs = state.metamask.unconfTxs
|
var unapprovedTxs = state.metamask.unapprovedTxs
|
||||||
var unconfMsgs = state.metamask.unconfMsgs
|
var unapprovedMsgs = state.metamask.unapprovedMsgs
|
||||||
var network = state.metamask.network
|
var network = state.metamask.network
|
||||||
|
|
||||||
var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
|
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
|
||||||
.filter(tx => tx !== tx.id)
|
.filter(tx => tx !== tx.id)
|
||||||
|
|
||||||
if (unconfTxList && unconfTxList.length > 0) {
|
if (unconfTxList && unconfTxList.length > 0) {
|
||||||
|
@ -572,18 +572,18 @@ function reduceApp (state, action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasPendingTxs (state) {
|
function hasPendingTxs (state) {
|
||||||
var unconfTxs = state.metamask.unconfTxs
|
var unapprovedTxs = state.metamask.unapprovedTxs
|
||||||
var unconfMsgs = state.metamask.unconfMsgs
|
var unapprovedMsgs = state.metamask.unapprovedMsgs
|
||||||
var network = state.metamask.network
|
var network = state.metamask.network
|
||||||
var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
|
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
|
||||||
return unconfTxList.length > 0
|
return unconfTxList.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexForPending (state, txId) {
|
function indexForPending (state, txId) {
|
||||||
var unconfTxs = state.metamask.unconfTxs
|
var unapprovedTxs = state.metamask.unapprovedTxs
|
||||||
var unconfMsgs = state.metamask.unconfMsgs
|
var unapprovedMsgs = state.metamask.unapprovedMsgs
|
||||||
var network = state.metamask.network
|
var network = state.metamask.network
|
||||||
var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
|
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
|
||||||
let idx
|
let idx
|
||||||
unconfTxList.forEach((tx, i) => {
|
unconfTxList.forEach((tx, i) => {
|
||||||
if (tx.id === txId) {
|
if (tx.id === txId) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ function reduceMetamask (state, action) {
|
||||||
isUnlocked: false,
|
isUnlocked: false,
|
||||||
rpcTarget: 'https://rawtestrpc.metamask.io/',
|
rpcTarget: 'https://rawtestrpc.metamask.io/',
|
||||||
identities: {},
|
identities: {},
|
||||||
unconfTxs: {},
|
unapprovedTxs: {},
|
||||||
currentFiat: 'USD',
|
currentFiat: 'USD',
|
||||||
conversionRate: 0,
|
conversionRate: 0,
|
||||||
conversionDate: 'N/A',
|
conversionDate: 'N/A',
|
||||||
|
@ -76,17 +76,17 @@ function reduceMetamask (state, action) {
|
||||||
case actions.COMPLETED_TX:
|
case actions.COMPLETED_TX:
|
||||||
var stringId = String(action.id)
|
var stringId = String(action.id)
|
||||||
newState = extend(metamaskState, {
|
newState = extend(metamaskState, {
|
||||||
unconfTxs: {},
|
unapprovedTxs: {},
|
||||||
unconfMsgs: {},
|
unapprovedMsgs: {},
|
||||||
})
|
})
|
||||||
for (const id in metamaskState.unconfTxs) {
|
for (const id in metamaskState.unapprovedTxs) {
|
||||||
if (id !== stringId) {
|
if (id !== stringId) {
|
||||||
newState.unconfTxs[id] = metamaskState.unconfTxs[id]
|
newState.unapprovedTxs[id] = metamaskState.unapprovedTxs[id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const id in metamaskState.unconfMsgs) {
|
for (const id in metamaskState.unapprovedMsgs) {
|
||||||
if (id !== stringId) {
|
if (id !== stringId) {
|
||||||
newState.unconfMsgs[id] = metamaskState.unconfMsgs[id]
|
newState.unapprovedMsgs[id] = metamaskState.unapprovedMsgs[id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newState
|
return newState
|
||||||
|
|
|
@ -29,7 +29,7 @@ var identities = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var unconfTxs = {}
|
var unapprovedTxs = {}
|
||||||
addUnconfTx({
|
addUnconfTx({
|
||||||
from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
|
from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
|
||||||
to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
|
to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
|
||||||
|
@ -45,7 +45,7 @@ addUnconfTx({
|
||||||
function addUnconfTx (txParams) {
|
function addUnconfTx (txParams) {
|
||||||
var time = (new Date()).getTime()
|
var time = (new Date()).getTime()
|
||||||
var id = createRandomId()
|
var id = createRandomId()
|
||||||
unconfTxs[id] = {
|
unapprovedTxs[id] = {
|
||||||
id: id,
|
id: id,
|
||||||
txParams: txParams,
|
txParams: txParams,
|
||||||
time: time,
|
time: time,
|
||||||
|
@ -59,7 +59,7 @@ function getState () {
|
||||||
return {
|
return {
|
||||||
isUnlocked: isUnlocked,
|
isUnlocked: isUnlocked,
|
||||||
identities: isUnlocked ? identities : {},
|
identities: isUnlocked ? identities : {},
|
||||||
unconfTxs: isUnlocked ? unconfTxs : {},
|
unapprovedTxs: isUnlocked ? unapprovedTxs : {},
|
||||||
selectedAccount: selectedAccount,
|
selectedAccount: selectedAccount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ function startApp (metamaskState, accountManager, opts) {
|
||||||
})
|
})
|
||||||
|
|
||||||
// if unconfirmed txs, start on txConf page
|
// if unconfirmed txs, start on txConf page
|
||||||
var unconfirmedTxsAll = txHelper(metamaskState.unconfTxs, metamaskState.unconfMsgs, metamaskState.network)
|
var unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.network)
|
||||||
if (unconfirmedTxsAll.length > 0) {
|
if (unapprovedTxsAll.length > 0) {
|
||||||
store.dispatch(actions.showConfTxPage())
|
store.dispatch(actions.showConfTxPage())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const valuesFor = require('../app/util').valuesFor
|
const valuesFor = require('../app/util').valuesFor
|
||||||
|
|
||||||
module.exports = function (unconfTxs, unconfMsgs, network) {
|
module.exports = function (unapprovedTxs, unapprovedMsgs, network) {
|
||||||
var txValues = network ? valuesFor(unconfTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unconfTxs)
|
var txValues = network ? valuesFor(unapprovedTxs).filter(tx => tx.txParams.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
|
||||||
var msgValues = valuesFor(unconfMsgs)
|
var msgValues = valuesFor(unapprovedMsgs)
|
||||||
var allValues = txValues.concat(msgValues)
|
var allValues = txValues.concat(msgValues)
|
||||||
return allValues.sort(tx => tx.time)
|
return allValues.sort(tx => tx.time)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue