mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
cache balances by chain id (#10545)
This commit is contained in:
parent
d44c4d3747
commit
e42658b590
@ -3,7 +3,7 @@ import { ObservableStore } from '@metamask/obs-store';
|
|||||||
/**
|
/**
|
||||||
* @typedef {Object} CachedBalancesOptions
|
* @typedef {Object} CachedBalancesOptions
|
||||||
* @property {Object} accountTracker An {@code AccountTracker} reference
|
* @property {Object} accountTracker An {@code AccountTracker} reference
|
||||||
* @property {Function} getNetwork A function to get the current network
|
* @property {Function} getCurrentChainId A function to get the current chain id
|
||||||
* @property {Object} initState The initial controller state
|
* @property {Object} initState The initial controller state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -18,10 +18,10 @@ export default class CachedBalancesController {
|
|||||||
* @param {CachedBalancesOptions} [opts] - Controller configuration parameters
|
* @param {CachedBalancesOptions} [opts] - Controller configuration parameters
|
||||||
*/
|
*/
|
||||||
constructor(opts = {}) {
|
constructor(opts = {}) {
|
||||||
const { accountTracker, getNetwork } = opts;
|
const { accountTracker, getCurrentChainId } = opts;
|
||||||
|
|
||||||
this.accountTracker = accountTracker;
|
this.accountTracker = accountTracker;
|
||||||
this.getNetwork = getNetwork;
|
this.getCurrentChainId = getCurrentChainId;
|
||||||
|
|
||||||
const initState = { cachedBalances: {}, ...opts.initState };
|
const initState = { cachedBalances: {}, ...opts.initState };
|
||||||
this.store = new ObservableStore(initState);
|
this.store = new ObservableStore(initState);
|
||||||
@ -30,37 +30,37 @@ export default class CachedBalancesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the cachedBalances property for the current network. Cached balances will be updated to those in the passed accounts
|
* Updates the cachedBalances property for the current chain. Cached balances will be updated to those in the passed accounts
|
||||||
* if balances in the passed accounts are truthy.
|
* if balances in the passed accounts are truthy.
|
||||||
*
|
*
|
||||||
* @param {Object} obj - The the recently updated accounts object for the current network
|
* @param {Object} obj - The the recently updated accounts object for the current chain
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async updateCachedBalances({ accounts }) {
|
async updateCachedBalances({ accounts }) {
|
||||||
const network = await this.getNetwork();
|
const chainId = this.getCurrentChainId();
|
||||||
const balancesToCache = await this._generateBalancesToCache(
|
const balancesToCache = await this._generateBalancesToCache(
|
||||||
accounts,
|
accounts,
|
||||||
network,
|
chainId,
|
||||||
);
|
);
|
||||||
this.store.updateState({
|
this.store.updateState({
|
||||||
cachedBalances: balancesToCache,
|
cachedBalances: balancesToCache,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_generateBalancesToCache(newAccounts, currentNetwork) {
|
_generateBalancesToCache(newAccounts, chainId) {
|
||||||
const { cachedBalances } = this.store.getState();
|
const { cachedBalances } = this.store.getState();
|
||||||
const currentNetworkBalancesToCache = { ...cachedBalances[currentNetwork] };
|
const currentChainBalancesToCache = { ...cachedBalances[chainId] };
|
||||||
|
|
||||||
Object.keys(newAccounts).forEach((accountID) => {
|
Object.keys(newAccounts).forEach((accountID) => {
|
||||||
const account = newAccounts[accountID];
|
const account = newAccounts[accountID];
|
||||||
|
|
||||||
if (account.balance) {
|
if (account.balance) {
|
||||||
currentNetworkBalancesToCache[accountID] = account.balance;
|
currentChainBalancesToCache[accountID] = account.balance;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const balancesToCache = {
|
const balancesToCache = {
|
||||||
...cachedBalances,
|
...cachedBalances,
|
||||||
[currentNetwork]: currentNetworkBalancesToCache,
|
[chainId]: currentChainBalancesToCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
return balancesToCache;
|
return balancesToCache;
|
||||||
|
@ -218,7 +218,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
|
|
||||||
this.cachedBalancesController = new CachedBalancesController({
|
this.cachedBalancesController = new CachedBalancesController({
|
||||||
accountTracker: this.accountTracker,
|
accountTracker: this.accountTracker,
|
||||||
getNetwork: this.networkController.getNetworkState.bind(
|
getCurrentChainId: this.networkController.getCurrentChainId.bind(
|
||||||
this.networkController,
|
this.networkController,
|
||||||
),
|
),
|
||||||
initState: initState.CachedBalancesController,
|
initState: initState.CachedBalancesController,
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances';
|
import CachedBalancesController from '../../../../app/scripts/controllers/cached-balances';
|
||||||
|
import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network';
|
||||||
|
|
||||||
describe('CachedBalancesController', function () {
|
describe('CachedBalancesController', function () {
|
||||||
describe('updateCachedBalances', function () {
|
describe('updateCachedBalances', function () {
|
||||||
it('should update the cached balances', async function () {
|
it('should update the cached balances', async function () {
|
||||||
const controller = new CachedBalancesController({
|
const controller = new CachedBalancesController({
|
||||||
getNetwork: () => Promise.resolve(17),
|
getCurrentChainId: () => KOVAN_CHAIN_ID,
|
||||||
accountTracker: {
|
accountTracker: {
|
||||||
store: {
|
store: {
|
||||||
subscribe: () => undefined,
|
subscribe: () => undefined,
|
||||||
@ -26,7 +27,7 @@ describe('CachedBalancesController', function () {
|
|||||||
assert.equal(controller._generateBalancesToCache.callCount, 1);
|
assert.equal(controller._generateBalancesToCache.callCount, 1);
|
||||||
assert.deepEqual(controller._generateBalancesToCache.args[0], [
|
assert.deepEqual(controller._generateBalancesToCache.args[0], [
|
||||||
'mockAccounts',
|
'mockAccounts',
|
||||||
17,
|
KOVAN_CHAIN_ID,
|
||||||
]);
|
]);
|
||||||
assert.equal(
|
assert.equal(
|
||||||
controller.store.getState().cachedBalances,
|
controller.store.getState().cachedBalances,
|
||||||
@ -45,7 +46,7 @@ describe('CachedBalancesController', function () {
|
|||||||
},
|
},
|
||||||
initState: {
|
initState: {
|
||||||
cachedBalances: {
|
cachedBalances: {
|
||||||
17: {
|
[KOVAN_CHAIN_ID]: {
|
||||||
a: '0x1',
|
a: '0x1',
|
||||||
b: '0x2',
|
b: '0x2',
|
||||||
c: '0x3',
|
c: '0x3',
|
||||||
@ -65,11 +66,11 @@ describe('CachedBalancesController', function () {
|
|||||||
b: { balance: null },
|
b: { balance: null },
|
||||||
c: { balance: '0x5' },
|
c: { balance: '0x5' },
|
||||||
},
|
},
|
||||||
17,
|
KOVAN_CHAIN_ID,
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
17: {
|
[KOVAN_CHAIN_ID]: {
|
||||||
a: '0x4',
|
a: '0x4',
|
||||||
b: '0x2',
|
b: '0x2',
|
||||||
c: '0x5',
|
c: '0x5',
|
||||||
@ -91,7 +92,7 @@ describe('CachedBalancesController', function () {
|
|||||||
},
|
},
|
||||||
initState: {
|
initState: {
|
||||||
cachedBalances: {
|
cachedBalances: {
|
||||||
17: {
|
[KOVAN_CHAIN_ID]: {
|
||||||
a: '0x1',
|
a: '0x1',
|
||||||
b: '0x2',
|
b: '0x2',
|
||||||
c: '0x3',
|
c: '0x3',
|
||||||
@ -110,7 +111,7 @@ describe('CachedBalancesController', function () {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert.deepEqual(result, {
|
assert.deepEqual(result, {
|
||||||
17: {
|
[KOVAN_CHAIN_ID]: {
|
||||||
a: '0x1',
|
a: '0x1',
|
||||||
b: '0x2',
|
b: '0x2',
|
||||||
c: '0x3',
|
c: '0x3',
|
||||||
@ -127,7 +128,7 @@ describe('CachedBalancesController', function () {
|
|||||||
it('should subscribe to the account tracker with the updateCachedBalances method', async function () {
|
it('should subscribe to the account tracker with the updateCachedBalances method', async function () {
|
||||||
const subscribeSpy = sinon.spy();
|
const subscribeSpy = sinon.spy();
|
||||||
const controller = new CachedBalancesController({
|
const controller = new CachedBalancesController({
|
||||||
getNetwork: () => Promise.resolve(17),
|
getCurrentChainId: () => KOVAN_CHAIN_ID,
|
||||||
accountTracker: {
|
accountTracker: {
|
||||||
store: {
|
store: {
|
||||||
subscribe: subscribeSpy,
|
subscribe: subscribeSpy,
|
||||||
|
@ -11,10 +11,9 @@ import { renderWithProvider } from '../../../../../../../test/lib/render-helpers
|
|||||||
|
|
||||||
import * as actions from '../../../../../store/actions';
|
import * as actions from '../../../../../store/actions';
|
||||||
import UnconnectedAccountAlert from '..';
|
import UnconnectedAccountAlert from '..';
|
||||||
|
import { KOVAN_CHAIN_ID } from '../../../../../../../shared/constants/network';
|
||||||
|
|
||||||
describe('Unconnected Account Alert', function () {
|
describe('Unconnected Account Alert', function () {
|
||||||
const network = '123';
|
|
||||||
|
|
||||||
const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b';
|
const selectedAddress = '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b';
|
||||||
|
|
||||||
const identities = {
|
const identities = {
|
||||||
@ -40,7 +39,7 @@ describe('Unconnected Account Alert', function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const cachedBalances = {
|
const cachedBalances = {
|
||||||
123: {
|
[KOVAN_CHAIN_ID]: {
|
||||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': '0x0',
|
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': '0x0',
|
||||||
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': '0x0',
|
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': '0x0',
|
||||||
},
|
},
|
||||||
@ -58,12 +57,14 @@ describe('Unconnected Account Alert', function () {
|
|||||||
|
|
||||||
const mockState = {
|
const mockState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
network,
|
|
||||||
selectedAddress,
|
selectedAddress,
|
||||||
identities,
|
identities,
|
||||||
accounts,
|
accounts,
|
||||||
cachedBalances,
|
cachedBalances,
|
||||||
keyrings,
|
keyrings,
|
||||||
|
provider: {
|
||||||
|
chainId: KOVAN_CHAIN_ID,
|
||||||
|
},
|
||||||
permissionsHistory: {
|
permissionsHistory: {
|
||||||
'https://test.dapp': {
|
'https://test.dapp': {
|
||||||
eth_accounts: {
|
eth_accounts: {
|
||||||
|
@ -127,9 +127,16 @@ export function getMetaMaskAccountsRaw(state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getMetaMaskCachedBalances(state) {
|
export function getMetaMaskCachedBalances(state) {
|
||||||
|
const chainId = getCurrentChainId(state);
|
||||||
|
|
||||||
|
// Fallback to fetching cached balances from network id
|
||||||
|
// this can eventually be removed
|
||||||
const network = getCurrentNetworkId(state);
|
const network = getCurrentNetworkId(state);
|
||||||
|
|
||||||
return state.metamask.cachedBalances[network];
|
return (
|
||||||
|
state.metamask.cachedBalances[chainId] ??
|
||||||
|
state.metamask.cachedBalances[network]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -155,7 +162,7 @@ export function isBalanceCached(state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getSelectedAccountCachedBalance(state) {
|
export function getSelectedAccountCachedBalance(state) {
|
||||||
const cachedBalances = state.metamask.cachedBalances[state.metamask.network];
|
const cachedBalances = getMetaMaskCachedBalances(state);
|
||||||
const selectedAddress = getSelectedAddress(state);
|
const selectedAddress = getSelectedAddress(state);
|
||||||
|
|
||||||
return cachedBalances && cachedBalances[selectedAddress];
|
return cachedBalances && cachedBalances[selectedAddress];
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { KOVAN_CHAIN_ID } from '../../../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
getConnectedDomainsForSelectedAddress,
|
getConnectedDomainsForSelectedAddress,
|
||||||
getOrderedConnectedAccountsForActiveTab,
|
getOrderedConnectedAccountsForActiveTab,
|
||||||
@ -163,6 +164,9 @@ describe('selectors', function () {
|
|||||||
url: 'https://remix.ethereum.org/',
|
url: 'https://remix.ethereum.org/',
|
||||||
},
|
},
|
||||||
metamask: {
|
metamask: {
|
||||||
|
provider: {
|
||||||
|
chainId: KOVAN_CHAIN_ID,
|
||||||
|
},
|
||||||
accounts: {
|
accounts: {
|
||||||
0x7250739de134d33ec7ab1ee592711e15098c9d2d: {
|
0x7250739de134d33ec7ab1ee592711e15098c9d2d: {
|
||||||
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
address: '0x7250739de134d33ec7ab1ee592711e15098c9d2d',
|
||||||
|
Loading…
Reference in New Issue
Block a user