From 89ea071240377cc369b5fc426f523a038079855b Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Mon, 7 Dec 2020 12:46:10 -0800 Subject: [PATCH] Receive accounts with isUnlocked notification (#121) This refactors some methods on the main class to account for the fact that accounts will be received with with the `isUnlocked` notification. --- src/MetaMaskInpageProvider.js | 53 ++++++++++--------------- test/MetaMaskInpageProvider.rpc.test.js | 4 +- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/MetaMaskInpageProvider.js b/src/MetaMaskInpageProvider.js index f3cb232e..d62168af 100644 --- a/src/MetaMaskInpageProvider.js +++ b/src/MetaMaskInpageProvider.js @@ -147,17 +147,17 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { this._initializeState() - // handle JSON RPC notifications + // handle JSON-RPC notifications jsonRpcConnection.events.on('notification', (payload) => { - const { method, params, result } = payload + const { method, params } = payload if (method === 'metamask_accountsChanged') { - this._handleAccountsChanged(result) + this._handleAccountsChanged(params) } else if (method === 'metamask_unlockStateChanged') { - this._handleUnlockStateChanged(result) + this._handleUnlockStateChanged(params) } else if (method === 'metamask_chainChanged') { - this._handleChainChanged(result) + this._handleChainChanged(params) } else if (EMITTED_NOTIFICATIONS.includes(method)) { this.emit('notification', payload) // deprecated this.emit('message', { @@ -323,7 +323,7 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { this.emit('connect', { chainId }) this._handleChainChanged({ chainId, networkVersion }) - this._handleUnlockStateChanged(isUnlocked) + this._handleUnlockStateChanged({ accounts, isUnlocked }) this._handleAccountsChanged(accounts) } catch (error) { this._log.error( @@ -343,9 +343,8 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { * @private * @param {Object} payload - The RPC request object. * @param {Function} callback - The consumer's callback. - * @param {boolean} [isInternal=false] - Whether the request is internal. */ - _rpcRequest (payload, callback, isInternal = false) { + _rpcRequest (payload, callback) { let cb = callback if (!Array.isArray(payload)) { @@ -364,7 +363,6 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { this._handleAccountsChanged( res.result || [], payload.method === 'eth_accounts', - isInternal, ) callback(err, res) } @@ -403,10 +401,8 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { * @param {string[]} accounts - The new accounts value. * @param {boolean} isEthAccounts - Whether the accounts value was returned by * a call to eth_accounts. - * @param {boolean} isInternal - Whether the accounts value was returned by an - * internally initiated request. */ - _handleAccountsChanged (accounts, isEthAccounts = false, isInternal = false) { + _handleAccountsChanged (accounts, isEthAccounts = false) { let _accounts = accounts if (!Array.isArray(accounts)) { @@ -421,8 +417,8 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { if (!dequal(this._state.accounts, _accounts)) { // we should always have the correct accounts even before eth_accounts - // returns, except in cases where isInternal is true - if (isEthAccounts && this._state.accounts !== null && !isInternal) { + // returns + if (isEthAccounts && this._state.accounts !== null) { this._log.error( `MetaMask: 'eth_accounts' unexpectedly updated accounts. Please report this bug.`, _accounts, @@ -477,14 +473,19 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { } /** - * Upon receipt of a new isUnlocked state, emits the corresponding event - * and sets relevant public state. + * Upon receipt of a new isUnlocked state, sets relevant public state. + * Calls the accounts changed handler with the received accounts, or an empty + * array. + * * Does nothing if the received value is equal to the existing value. + * There are no lock/unlock events. * * @private - * @param {boolean} isUnlocked - The latest isUnlocked value. + * @param {Object} opts - Options bag. + * @param {string[]} [opts.accounts] - The exposed accounts, if any. + * @param {boolean} opts.isUnlocked - The latest isUnlocked value. */ - _handleUnlockStateChanged (isUnlocked) { + _handleUnlockStateChanged ({ accounts, isUnlocked }) { if (typeof isUnlocked !== 'boolean') { this._log.error('MetaMask: Received invalid isUnlocked parameter. Please report this bug.') return @@ -492,21 +493,7 @@ module.exports = class MetaMaskInpageProvider extends SafeEventEmitter { if (isUnlocked !== this._state.isUnlocked) { this._state.isUnlocked = isUnlocked - - if (isUnlocked) { - - // this will get the exposed accounts, if any - try { - this._rpcRequest( - { method: 'eth_accounts', params: [] }, - NOOP, - true, // indicating that eth_accounts _should_ update accounts - ) - } catch (_) { /* no-op */ } - } else { - // accounts are never exposed when the extension is locked - this._handleAccountsChanged([]) - } + this._handleAccountsChanged(accounts || []) } } diff --git a/test/MetaMaskInpageProvider.rpc.test.js b/test/MetaMaskInpageProvider.rpc.test.js index 56bee785..5aa4b927 100644 --- a/test/MetaMaskInpageProvider.rpc.test.js +++ b/test/MetaMaskInpageProvider.rpc.test.js @@ -420,7 +420,7 @@ describe('MetaMaskInpageProvider: RPC', () => { ) expect(provider._handleAccountsChanged) - .toHaveBeenCalledWith(['0x1'], true, false) + .toHaveBeenCalledWith(['0x1'], true) expect(err).toBeNull() expect(res).toStrictEqual({ result: ['0x1'] }) @@ -445,7 +445,7 @@ describe('MetaMaskInpageProvider: RPC', () => { ) expect(provider._handleAccountsChanged) - .toHaveBeenCalledWith([], true, false) + .toHaveBeenCalledWith([], true) expect(err).toStrictEqual(new Error('foo')) expect(res).toStrictEqual({ error: 'foo' })