Merge pull request #354 from poanetwork/vb-fix-accounts_changged_event_emitting

Fix `accountsChanged` event emittance (a part of EIP-1193)
This commit is contained in:
Victor Baranov 2020-04-14 09:30:24 +03:00 committed by GitHub
commit c7550231dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 238 additions and 257 deletions

View File

@ -2,6 +2,7 @@
## Current Master
- [#354](https://github.com/poanetwork/nifty-wallet/pull/354) - Fix `accountsChanged` event emittance (a part of EIP-1193)
- [#353](https://github.com/poanetwork/nifty-wallet/pull/353) - Fix synchronous eth_accounts request
## 5.0.1 Mon Apr 06 2020

View File

@ -145,7 +145,6 @@ setupMetamaskMeshMetrics()
* @property {Object} infuraNetworkStatus - An object of infura network status checks.
* @property {Block[]} recentBlocks - An array of recent blocks, used to calculate an effective but cheap gas price.
* @property {Array} shapeShiftTxList - An array of objects describing shapeshift exchange attempts.
* @property {Array} lostAccounts - TODO: Remove this feature. A leftover from the version-3 migration where our seed-phrase library changed to fix a bug where some accounts were mis-generated, but we recovered the old accounts as "lost" instead of losing them.
* @property {boolean} forgottenPassword - Returns true if the user has initiated the password recovery screen, is recovering from seed phrase.
*/
@ -267,6 +266,9 @@ function setupController (initState, initLangCode) {
getRequestAccountTabIds: () => {
return requestAccountTabIds
},
getOpenMetamaskTabsIds: () => {
return openMetamaskTabsIDs
},
encryptor: isEdge ? new EdgeEncryptor() : undefined,
})
global.metamaskController = controller

View File

@ -298,13 +298,18 @@ export class PermissionsController {
*/
async updatePermittedAccounts (origin, accounts) {
await this.validatePermittedAccounts(accounts)
// await this.validatePermittedAccounts(accounts)
this.permissions.updateCaveatFor(
origin, 'eth_accounts', CAVEAT_NAMES.exposedAccounts, accounts,
)
// this.permissions.updateCaveatFor(
// origin, 'eth_accounts', CAVEAT_NAMES.exposedAccounts, accounts,
// )
this.notifyDomain(origin, {
// this.notifyDomain(origin, {
// method: NOTIFICATION_NAMES.accountsChanged,
// result: accounts,
// })
this.notifyAllDomains({
method: NOTIFICATION_NAMES.accountsChanged,
result: accounts,
})
@ -378,14 +383,14 @@ export class PermissionsController {
// if the accounts changed from the perspective of the dapp,
// update "last seen" time for the origin and account(s)
// exception: no accounts -> no times to update
if (
payload.method === NOTIFICATION_NAMES.accountsChanged &&
Array.isArray(payload.result)
) {
this.permissionsLog.updateAccountsHistory(
origin, payload.result,
)
}
// if (
// payload.method === NOTIFICATION_NAMES.accountsChanged &&
// Array.isArray(payload.result)
// ) {
// this.permissionsLog.updateAccountsHistory(
// origin, payload.result,
// )
// }
this._notifyDomain(origin, payload)
@ -448,8 +453,8 @@ export class PermissionsController {
// do nothing if the account is not permitted for the origin, or
// if it's already first in the array of permitted accounts
if (
!permittedAccounts.includes(account) ||
permittedAccounts[0] === account
!permittedAccounts.includes(account)
// || permittedAccounts[0] === account
) {
return
}

View File

@ -61,23 +61,6 @@ const inpageProvider = new MetamaskInpageProvider(metamaskStream)
// set a high max listener count to avoid unnecesary warnings
inpageProvider.setMaxListeners(100)
// Augment the provider with its enable method
inpageProvider.enable = function (options = {}) {
return new Promise((resolve, reject) => {
if (options.mockRejection) {
reject('User rejected account access')
} else {
inpageProvider.sendAsync({ method: 'eth_accounts', params: [] }, (error, response) => {
if (error) {
reject(error)
} else {
resolve(response.result)
}
})
}
})
}
// Work around for web3@1.0 deleting the bound `sendAsync` but not the unbound
// `sendAsync` method on the prototype, causing `this` reference issues
const proxiedInpageProvider = new Proxy(inpageProvider, {

View File

@ -1,4 +1,4 @@
const ObservableStore = require('obs-store')
import ObservableStore from 'obs-store'
/**
* An ObservableStore that can composes a flat
@ -46,34 +46,6 @@ class ComposableObservableStore extends ObservableStore {
}
return flatState
}
/**
* Merges all child store state into a single object rather than
* returning an object keyed by child store class name
* Removes heavy objects that are not needed on UI
*
* @returns {Object} - Object containing merged child store state
*/
getFilteredFlatState () {
let flatState = {}
for (const key in this.config) {
let nextState
if (key === 'RecentBlocksController') {
nextState = {}
} else if (key === 'TxController') {
const state = this.config[key].getState()
const txList = state.selectedAddressTxList.map(item => ({...item, history: null, nonceDetails: null}))
nextState = {
...state,
selectedAddressTxList: txList,
}
} else {
nextState = this.config[key].getState()
}
flatState = { ...flatState, ...nextState }
}
return flatState
}
}
module.exports = ComposableObservableStore

View File

@ -42,8 +42,8 @@ const TransactionController = require('./controllers/transactions')
const BalancesController = require('./controllers/computed-balances')
const TokenRatesController = require('./controllers/token-rates')
const DetectTokensController = require('./controllers/detect-tokens')
// import { PermissionsController } from './controllers/permissions'
// import getRestrictedMethods from './controllers/permissions/restrictedMethods'
import { PermissionsController } from './controllers/permissions'
import getRestrictedMethods from './controllers/permissions/restrictedMethods'
const nodeify = require('./lib/nodeify')
const accountImporter = require('./account-import-strategies')
import { Mutex } from 'await-semaphore'
@ -57,7 +57,6 @@ import log from 'loglevel'
const TrezorKeyring = require('eth-trezor-keyring')
const LedgerBridgeKeyring = require('eth-ledger-bridge-keyring')
import EthQuery from 'eth-query'
const sigUtil = require('eth-sig-util')
import nanoid from 'nanoid'
const { importTypes } = require('../../old-ui/app/accounts/import/enums')
const { LEDGER, TREZOR } = require('../../old-ui/app/components/connect-hardware/enum')
@ -208,13 +207,13 @@ module.exports = class MetamaskController extends EventEmitter {
this.keyringController.memStore.subscribe((s) => this._onKeyringControllerUpdate(s))
this.keyringController.on('unlock', () => this.emit('unlock'))
// this.permissionsController = new PermissionsController({
// getKeyringAccounts: this.keyringController.getAccounts.bind(this.keyringController),
// getRestrictedMethods,
// notifyDomain: this.notifyConnections.bind(this),
// notifyAllDomains: this.notifyAllConnections.bind(this),
// platform: opts.platform,
// }, initState.PermissionsController, initState.PermissionsMetadata)
this.permissionsController = new PermissionsController({
getKeyringAccounts: this.keyringController.getAccounts.bind(this.keyringController),
getRestrictedMethods,
notifyDomain: this.notifyConnections.bind(this),
notifyAllDomains: this.notifyAllConnections.bind(this),
platform: opts.platform,
}, initState.PermissionsController, initState.PermissionsMetadata)
// detect tokens controller
this.detectTokensController = new DetectTokensController({
@ -295,8 +294,8 @@ module.exports = class MetamaskController extends EventEmitter {
NetworkController: this.networkController.store,
InfuraController: this.infuraController.store,
CachedBalancesController: this.cachedBalancesController.store,
// PermissionsController: this.permissionsController.permissions,
// PermissionsMetadata: this.permissionsController.store,
PermissionsController: this.permissionsController.permissions,
PermissionsMetadata: this.permissionsController.store,
})
this.memStore = new ComposableObservableStore(null, {
@ -319,8 +318,8 @@ module.exports = class MetamaskController extends EventEmitter {
NoticeController: this.noticeController.memStore,
ShapeshiftController: this.shapeshiftController.store,
InfuraController: this.infuraController.store,
// PermissionsController: this.permissionsController.permissions,
// PermissionsMetadata: this.permissionsController.store,
PermissionsController: this.permissionsController.permissions,
PermissionsMetadata: this.permissionsController.store,
})
this.memStore.subscribe(this.sendUpdate.bind(this))
}
@ -407,11 +406,7 @@ module.exports = class MetamaskController extends EventEmitter {
return {
...{ isInitialized },
...this.memStore.getFilteredFlatState(),
...{
// TODO: Remove usages of lost accounts
lostAccounts: [],
},
...this.memStore.getFlatState(),
}
}
@ -530,7 +525,7 @@ module.exports = class MetamaskController extends EventEmitter {
checkNotices: noticeController.updateNoticesList.bind(noticeController),
markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
// // permissions
// permissions
// approvePermissionsRequest: nodeify(permissionsController.approvePermissionsRequest, permissionsController),
// clearPermissions: permissionsController.clearPermissions.bind(permissionsController),
// getApprovedAccounts: nodeify(permissionsController.getAccounts.bind(permissionsController)),
@ -538,7 +533,7 @@ module.exports = class MetamaskController extends EventEmitter {
// removePermissionsFor: permissionsController.removePermissionsFor.bind(permissionsController),
// updatePermittedAccounts: nodeify(permissionsController.updatePermittedAccounts, permissionsController),
// legacyExposeAccounts: nodeify(permissionsController.legacyExposeAccounts, permissionsController),
// handleNewAccountSelected: nodeify(this.handleNewAccountSelected, this),
handleNewAccountSelected: nodeify(this.handleNewAccountSelected, this),
}
}
@ -1101,6 +1096,17 @@ module.exports = class MetamaskController extends EventEmitter {
await this.preferencesController.setSelectedAddress(accounts[0])
}
/**
* Handle when a new account is selected for the given origin in the UI.
* Stores the address by origin and notifies external providers associated
* with the origin.
* @param {string} origin - The origin for which the address was selected.
* @param {string} address - The new selected address.
*/
async handleNewAccountSelected (origin, address) {
this.permissionsController.handleNewAccountSelected(origin, address)
}
// ---------------------------------------------------------------------------
// Identity Management (signature operations)
@ -1137,8 +1143,8 @@ module.exports = class MetamaskController extends EventEmitter {
/**
* Signifies user intent to complete an eth_sign method.
*
* @param {Object} msgParams The params passed to eth_call.
* @returns {Promise<Object>} Full state update.
* @param {Object} msgParams - The params passed to eth_call.
* @returns {Promise<Object>} - Full state update.
*/
signMessage (msgParams) {
log.info('MetaMaskController - signMessage')
@ -1147,16 +1153,16 @@ module.exports = class MetamaskController extends EventEmitter {
// sets the status op the message to 'approved'
// and removes the metamaskId for signing
return this.messageManager.approveMessage(msgParams)
.then((cleanMsgParams) => {
.then((cleanMsgParams) => {
// signs the message
return this.keyringController.signMessage(cleanMsgParams)
})
.then((rawSig) => {
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.setMsgStatusSigned(msgId, rawSig)
return this.getState()
})
this.messageManager.setMsgStatusSigned(msgId, rawSig)
return this.getState()
})
}
/**
@ -1205,16 +1211,16 @@ module.exports = class MetamaskController extends EventEmitter {
// sets the status op the message to 'approved'
// and removes the metamaskId for signing
return this.personalMessageManager.approveMessage(msgParams)
.then((cleanMsgParams) => {
.then((cleanMsgParams) => {
// signs the message
return this.keyringController.signPersonalMessage(cleanMsgParams)
})
.then((rawSig) => {
return this.keyringController.signPersonalMessage(cleanMsgParams)
})
.then((rawSig) => {
// tells the listener that the message has been signed
// and can be returned to the dapp
this.personalMessageManager.setMsgStatusSigned(msgId, rawSig)
return this.getState()
})
this.personalMessageManager.setMsgStatusSigned(msgId, rawSig)
return this.getState()
})
}
/**
@ -1239,80 +1245,80 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {Object} req - (optional) the original request, containing the origin
* Passed back to the requesting Dapp.
*/
async newRequestDecryptMessage (msgParams, req) {
const promise = this.decryptMessageManager.addUnapprovedMessageAsync(msgParams, req)
this.sendUpdate()
this.opts.showUnconfirmedMessage()
return promise
}
/**
* Only decypt message and don't touch transaction state
*
* @param {Object} msgParams - The params of the message to decrypt.
* @returns {Promise<Object>} - A full state update.
*/
async decryptMessageInline (msgParams) {
log.info('MetaMaskController - decryptMessageInline')
// decrypt the message inline
const msgId = msgParams.metamaskId
const msg = this.decryptMessageManager.getMsg(msgId)
try {
const stripped = ethUtil.stripHexPrefix(msgParams.data)
const buff = Buffer.from(stripped, 'hex')
msgParams.data = JSON.parse(buff.toString('utf8'))
msg.rawData = await this.keyringController.decryptMessage(msgParams)
} catch (e) {
msg.error = e.message
async newRequestDecryptMessage (msgParams, req) {
const promise = this.decryptMessageManager.addUnapprovedMessageAsync(msgParams, req)
this.sendUpdate()
this.opts.showUnconfirmedMessage()
return promise
}
this.decryptMessageManager._updateMsg(msg)
return this.getState()
}
/**
* Only decypt message and don't touch transaction state
*
* @param {Object} msgParams - The params of the message to decrypt.
* @returns {Promise<Object>} - A full state update.
*/
async decryptMessageInline (msgParams) {
log.info('MetaMaskController - decryptMessageInline')
// decrypt the message inline
const msgId = msgParams.metamaskId
const msg = this.decryptMessageManager.getMsg(msgId)
try {
const stripped = ethUtil.stripHexPrefix(msgParams.data)
const buff = Buffer.from(stripped, 'hex')
msgParams.data = JSON.parse(buff.toString('utf8'))
/**
* Signifies a user's approval to decrypt a message in queue.
* Triggers decrypt, and the callback function from newUnsignedDecryptMessage.
*
* @param {Object} msgParams - The params of the message to decrypt & return to the Dapp.
* @returns {Promise<Object>} - A full state update.
*/
async decryptMessage (msgParams) {
log.info('MetaMaskController - decryptMessage')
const msgId = msgParams.metamaskId
// sets the status op the message to 'approved'
// and removes the metamaskId for decryption
try {
const cleanMsgParams = await this.decryptMessageManager.approveMessage(msgParams)
msg.rawData = await this.keyringController.decryptMessage(msgParams)
} catch (e) {
msg.error = e.message
}
this.decryptMessageManager._updateMsg(msg)
const stripped = ethUtil.stripHexPrefix(cleanMsgParams.data)
const buff = Buffer.from(stripped, 'hex')
cleanMsgParams.data = JSON.parse(buff.toString('utf8'))
// decrypt the message
const rawMess = await this.keyringController.decryptMessage(cleanMsgParams)
// tells the listener that the message has been decrypted and can be returned to the dapp
this.decryptMessageManager.setMsgStatusDecrypted(msgId, rawMess)
} catch (error) {
log.info('MetaMaskController - eth_decrypt failed.', error)
this.decryptMessageManager.errorMessage(msgId, error)
return this.getState()
}
return this.getState()
}
/**
* Used to cancel a eth_decrypt type message.
* @param {string} msgId - The ID of the message to cancel.
* @param {Function} cb - The callback function called with a full state update.
*/
cancelDecryptMessage (msgId, cb) {
const messageManager = this.decryptMessageManager
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
/**
* Signifies a user's approval to decrypt a message in queue.
* Triggers decrypt, and the callback function from newUnsignedDecryptMessage.
*
* @param {Object} msgParams - The params of the message to decrypt & return to the Dapp.
* @returns {Promise<Object>} - A full state update.
*/
async decryptMessage (msgParams) {
log.info('MetaMaskController - decryptMessage')
const msgId = msgParams.metamaskId
// sets the status op the message to 'approved'
// and removes the metamaskId for decryption
try {
const cleanMsgParams = await this.decryptMessageManager.approveMessage(msgParams)
const stripped = ethUtil.stripHexPrefix(cleanMsgParams.data)
const buff = Buffer.from(stripped, 'hex')
cleanMsgParams.data = JSON.parse(buff.toString('utf8'))
// decrypt the message
const rawMess = await this.keyringController.decryptMessage(cleanMsgParams)
// tells the listener that the message has been decrypted and can be returned to the dapp
this.decryptMessageManager.setMsgStatusDecrypted(msgId, rawMess)
} catch (error) {
log.info('MetaMaskController - eth_decrypt failed.', error)
this.decryptMessageManager.errorMessage(msgId, error)
}
return this.getState()
}
/**
* Used to cancel a eth_decrypt type message.
* @param {string} msgId - The ID of the message to cancel.
* @param {Function} cb - The callback function called with a full state update.
*/
cancelDecryptMessage (msgId, cb) {
const messageManager = this.decryptMessageManager
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
}
}
}
// eth_getEncryptionPublicKey methods
@ -1323,53 +1329,53 @@ cancelDecryptMessage (msgId, cb) {
* @param {Object} req - (optional) the original request, containing the origin
* Passed back to the requesting Dapp.
*/
async newRequestEncryptionPublicKey (msgParams, req) {
const promise = this.encryptionPublicKeyManager.addUnapprovedMessageAsync(msgParams, req)
this.sendUpdate()
this.opts.showUnconfirmedMessage()
return promise
}
/**
* Signifies a user's approval to receiving encryption public key in queue.
* Triggers receiving, and the callback function from newUnsignedEncryptionPublicKey.
*
* @param {Object} msgParams - The params of the message to receive & return to the Dapp.
* @returns {Promise<Object>} - A full state update.
*/
async encryptionPublicKey (msgParams) {
log.info('MetaMaskController - encryptionPublicKey')
const msgId = msgParams.metamaskId
// sets the status op the message to 'approved'
// and removes the metamaskId for decryption
try {
const params = await this.encryptionPublicKeyManager.approveMessage(msgParams)
// EncryptionPublicKey message
const publicKey = await this.keyringController.getEncryptionPublicKey(params.data)
// tells the listener that the message has been processed
// and can be returned to the dapp
this.encryptionPublicKeyManager.setMsgStatusReceived(msgId, publicKey)
} catch (error) {
log.info('MetaMaskController - eth_getEncryptionPublicKey failed.', error)
this.encryptionPublicKeyManager.errorMessage(msgId, error)
async newRequestEncryptionPublicKey (msgParams, req) {
const promise = this.encryptionPublicKeyManager.addUnapprovedMessageAsync(msgParams, req)
this.sendUpdate()
this.opts.showUnconfirmedMessage()
return promise
}
return this.getState()
}
/**
* Used to cancel a eth_getEncryptionPublicKey type message.
* @param {string} msgId - The ID of the message to cancel.
* @param {Function} cb - The callback function called with a full state update.
*/
cancelEncryptionPublicKey (msgId, cb) {
const messageManager = this.encryptionPublicKeyManager
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
/**
* Signifies a user's approval to receiving encryption public key in queue.
* Triggers receiving, and the callback function from newUnsignedEncryptionPublicKey.
*
* @param {Object} msgParams - The params of the message to receive & return to the Dapp.
* @returns {Promise<Object>} - A full state update.
*/
async encryptionPublicKey (msgParams) {
log.info('MetaMaskController - encryptionPublicKey')
const msgId = msgParams.metamaskId
// sets the status op the message to 'approved'
// and removes the metamaskId for decryption
try {
const params = await this.encryptionPublicKeyManager.approveMessage(msgParams)
// EncryptionPublicKey message
const publicKey = await this.keyringController.getEncryptionPublicKey(params.data)
// tells the listener that the message has been processed
// and can be returned to the dapp
this.encryptionPublicKeyManager.setMsgStatusReceived(msgId, publicKey)
} catch (error) {
log.info('MetaMaskController - eth_getEncryptionPublicKey failed.', error)
this.encryptionPublicKeyManager.errorMessage(msgId, error)
}
return this.getState()
}
/**
* Used to cancel a eth_getEncryptionPublicKey type message.
* @param {string} msgId - The ID of the message to cancel.
* @param {Function} cb - The callback function called with a full state update.
*/
cancelEncryptionPublicKey (msgId, cb) {
const messageManager = this.encryptionPublicKeyManager
messageManager.rejectMsg(msgId)
if (cb && typeof cb === 'function') {
cb(null, this.getState())
}
}
}
// eth_signTypedData methods
@ -1399,19 +1405,16 @@ cancelEncryptionPublicKey (msgId, cb) {
const version = msgParams.version
try {
const cleanMsgParams = await this.typedMessageManager.approveMessage(msgParams)
const address = sigUtil.normalize(cleanMsgParams.from)
const keyring = await this.keyringController.getKeyringForAccount(address)
const wallet = keyring._getWalletForAccount(address)
const privKey = ethUtil.toBuffer(wallet.getPrivateKey())
let signature
switch (version) {
case 'V1':
signature = sigUtil.signTypedDataLegacy(privKey, { data: cleanMsgParams.data })
break
case 'V3':
signature = sigUtil.signTypedData(privKey, { data: JSON.parse(cleanMsgParams.data) })
break
// For some reason every version after V1 used stringified params.
if (version !== 'V1') {
// But we don't have to require that. We can stop suggesting it now:
if (typeof cleanMsgParams.data === 'string') {
cleanMsgParams.data = JSON.parse(cleanMsgParams.data)
}
}
const signature = await this.keyringController.signTypedMessage(cleanMsgParams, { version })
this.typedMessageManager.setMsgStatusSigned(msgId, signature)
return this.getState()
} catch (error) {

48
package-lock.json generated
View File

@ -11369,11 +11369,12 @@
}
},
"eth-hd-keyring": {
"version": "github:vbaranov/eth-hd-keyring#3a77a565439d5555e52b955f3457f2fcd2753a81",
"from": "github:vbaranov/eth-hd-keyring#2.0.2",
"version": "github:vbaranov/eth-hd-keyring#2c761c59e7cc978da6a612bf6d9833d8ea95efb5",
"from": "github:vbaranov/eth-hd-keyring#2.1.0",
"requires": {
"bip39": "^2.2.0",
"eth-sig-util": "^2.0.1",
"eth-sig-util": "^2.4.4",
"eth-simple-keyring": "^3.5.0",
"ethereumjs-abi": "^0.6.5",
"ethereumjs-util": "^5.1.1",
"ethereumjs-wallet": "^0.6.0",
@ -11631,30 +11632,21 @@
}
},
"eth-keychain-controller": {
"version": "github:vbaranov/KeyringController#9b54d5596212f033a0b17f2ae27b3dd2de8df270",
"from": "github:vbaranov/KeyringController#5.1.0",
"version": "github:vbaranov/KeyringController#a39087f825b1cbffc663ef002d7d66ade3c5944b",
"from": "github:vbaranov/KeyringController#5.2.0",
"requires": {
"bip39": "^2.4.0",
"bluebird": "^3.5.0",
"browser-passworder": "^2.0.3",
"eth-hd-keyring": "github:vbaranov/eth-hd-keyring#2.0.2",
"eth-hd-keyring": "github:vbaranov/eth-hd-keyring#2.1.0",
"eth-sig-util": "^1.4.0",
"eth-simple-keyring": "^2.0.0",
"eth-simple-keyring": "^3.5.0",
"ethereumjs-util": "^5.1.2",
"loglevel": "^1.5.0",
"obs-store": "^2.4.1",
"obs-store": "^4.0.3",
"promise-filter": "^1.1.0"
},
"dependencies": {
"babelify": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz",
"integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=",
"requires": {
"babel-core": "^6.0.14",
"object-assign": "^4.0.0"
}
},
"eth-sig-util": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz",
@ -11687,18 +11679,6 @@
}
}
}
},
"obs-store": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/obs-store/-/obs-store-2.4.1.tgz",
"integrity": "sha512-wpA8G4uSn8cnCKZ0pFTvqsamvy0Sm1hR2ot0Qonbfj5yBMwdAp/eD4vDI+U/ZCbV1hb2V5GapL8YKUdGCvahgg==",
"requires": {
"babel-preset-es2015": "^6.22.0",
"babelify": "^7.3.0",
"readable-stream": "^2.2.2",
"through2": "^2.0.3",
"xtend": "^4.0.1"
}
}
}
},
@ -11916,11 +11896,11 @@
}
},
"eth-simple-keyring": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eth-simple-keyring/-/eth-simple-keyring-2.1.0.tgz",
"integrity": "sha512-31emUxGHOVhYzlPoEGyfrn1Usi2ZI9qDqMnDHwG0R0HdIuF/I10qlf401MkiD9lcMDuvgJkLpqqAvGxrKrFCwA==",
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/eth-simple-keyring/-/eth-simple-keyring-3.5.0.tgz",
"integrity": "sha512-z9IPt9aoMWAw5Zc3Jk/HKbWPJNc7ivZ5ECNtl3ZoQUGRnwoWO71W5+liVPJtXFNacGOOGsBfqTqrXL9C4EnYYQ==",
"requires": {
"eth-sig-util": "^2.0.1",
"eth-sig-util": "^2.5.0",
"ethereumjs-abi": "^0.6.5",
"ethereumjs-util": "^5.1.1",
"ethereumjs-wallet": "^0.6.0",
@ -45006,7 +44986,7 @@
"dev": true
},
"nifty-wallet-inpage-provider": {
"version": "github:poanetwork/nifty-wallet-inpage-provider#77cc9859e40ecd9720e3c5cc690b0abf5693014b",
"version": "github:poanetwork/nifty-wallet-inpage-provider#68b7b0733c7cc7ce9712a316e851d87b4cb0b191",
"from": "github:poanetwork/nifty-wallet-inpage-provider#1.5.0",
"requires": {
"eth-json-rpc-errors": "^2.0.2",

View File

@ -115,7 +115,7 @@
"eth-json-rpc-filters": "github:poanetwork/eth-json-rpc-filters#3.0.2",
"eth-json-rpc-infura": "^4.0.2",
"eth-json-rpc-middleware": "^4.4.1",
"eth-keychain-controller": "github:vbaranov/KeyringController#5.1.0",
"eth-keychain-controller": "github:vbaranov/KeyringController#5.2.0",
"eth-ledger-bridge-keyring": "github:vbaranov/eth-ledger-bridge-keyring#0.1.0-clear-accounts-flag",
"eth-method-registry": "^1.0.0",
"eth-net-props": "^1.0.33",

View File

@ -364,6 +364,12 @@ var actions = {
confirmChangePassword,
createCancelTransaction,
SET_REQUEST_ACCOUNT_TABS: 'SET_REQUEST_ACCOUNT_TABS',
setRequestAccountTabIds,
getRequestAccountTabIds,
setOpenMetamaskTabsIDs,
getOpenMetamaskTabsIds,
}
module.exports = actions
@ -1723,6 +1729,7 @@ function showAccountDetail (address) {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
background.handleNewAccountSelected(origin, address)
dispatch(updateTokens(tokens))
dispatch({
type: actions.SHOW_ACCOUNT_DETAIL,
@ -2761,3 +2768,31 @@ function confirmChangePassword () {
type: actions.CONFIRM_CHANGE_PASSWORD,
}
}
function setRequestAccountTabIds (requestAccountTabIds) {
return {
type: actions.SET_REQUEST_ACCOUNT_TABS,
value: requestAccountTabIds,
}
}
function getRequestAccountTabIds () {
return async (dispatch) => {
const requestAccountTabIds = await pify(background.getRequestAccountTabIds).call(background)
dispatch(setRequestAccountTabIds(requestAccountTabIds))
}
}
function setOpenMetamaskTabsIDs (openMetaMaskTabIDs) {
return {
type: actions.SET_OPEN_METAMASK_TAB_IDS,
value: openMetaMaskTabIDs,
}
}
function getOpenMetamaskTabsIds () {
return async (dispatch) => {
const openMetaMaskTabIDs = await pify(background.getOpenMetamaskTabsIds).call(background)
dispatch(setOpenMetamaskTabsIDs(openMetaMaskTabIDs))
}
}