mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
key tokens by chainId (#10510)
This commit is contained in:
parent
dedadee346
commit
caa32d87fb
@ -8,6 +8,7 @@ import log from 'loglevel';
|
||||
import { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens';
|
||||
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
|
||||
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
|
||||
import { NETWORK_EVENTS } from './network';
|
||||
|
||||
export default class PreferencesController {
|
||||
/**
|
||||
@ -72,7 +73,7 @@ export default class PreferencesController {
|
||||
this.store.setMaxListeners(12);
|
||||
this.openPopup = opts.openPopup;
|
||||
this.migrateAddressBookState = opts.migrateAddressBookState;
|
||||
this._subscribeProviderType();
|
||||
this._subscribeToNetworkDidChange();
|
||||
|
||||
global.setPreference = (key, value) => {
|
||||
return this.setFeatureFlag(key, value);
|
||||
@ -667,12 +668,11 @@ export default class PreferencesController {
|
||||
//
|
||||
|
||||
/**
|
||||
* Subscription to network provider type.
|
||||
*
|
||||
*
|
||||
* Handle updating token list to reflect current network by listening for the
|
||||
* NETWORK_DID_CHANGE event.
|
||||
*/
|
||||
_subscribeProviderType() {
|
||||
this.network.providerStore.subscribe(() => {
|
||||
_subscribeToNetworkDidChange() {
|
||||
this.network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => {
|
||||
const { tokens, hiddenTokens } = this._getTokenRelatedStates();
|
||||
this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens);
|
||||
});
|
||||
@ -689,12 +689,12 @@ export default class PreferencesController {
|
||||
_updateAccountTokens(tokens, assetImages, hiddenTokens) {
|
||||
const {
|
||||
accountTokens,
|
||||
providerType,
|
||||
chainId,
|
||||
selectedAddress,
|
||||
accountHiddenTokens,
|
||||
} = this._getTokenRelatedStates();
|
||||
accountTokens[selectedAddress][providerType] = tokens;
|
||||
accountHiddenTokens[selectedAddress][providerType] = hiddenTokens;
|
||||
accountTokens[selectedAddress][chainId] = tokens;
|
||||
accountHiddenTokens[selectedAddress][chainId] = hiddenTokens;
|
||||
this.store.updateState({
|
||||
accountTokens,
|
||||
tokens,
|
||||
@ -730,27 +730,27 @@ export default class PreferencesController {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
selectedAddress = this.store.getState().selectedAddress;
|
||||
}
|
||||
const providerType = this.network.providerStore.getState().type;
|
||||
const chainId = this.network.getCurrentChainId();
|
||||
if (!(selectedAddress in accountTokens)) {
|
||||
accountTokens[selectedAddress] = {};
|
||||
}
|
||||
if (!(selectedAddress in accountHiddenTokens)) {
|
||||
accountHiddenTokens[selectedAddress] = {};
|
||||
}
|
||||
if (!(providerType in accountTokens[selectedAddress])) {
|
||||
accountTokens[selectedAddress][providerType] = [];
|
||||
if (!(chainId in accountTokens[selectedAddress])) {
|
||||
accountTokens[selectedAddress][chainId] = [];
|
||||
}
|
||||
if (!(providerType in accountHiddenTokens[selectedAddress])) {
|
||||
accountHiddenTokens[selectedAddress][providerType] = [];
|
||||
if (!(chainId in accountHiddenTokens[selectedAddress])) {
|
||||
accountHiddenTokens[selectedAddress][chainId] = [];
|
||||
}
|
||||
const tokens = accountTokens[selectedAddress][providerType];
|
||||
const hiddenTokens = accountHiddenTokens[selectedAddress][providerType];
|
||||
const tokens = accountTokens[selectedAddress][chainId];
|
||||
const hiddenTokens = accountHiddenTokens[selectedAddress][chainId];
|
||||
return {
|
||||
tokens,
|
||||
accountTokens,
|
||||
hiddenTokens,
|
||||
accountHiddenTokens,
|
||||
providerType,
|
||||
chainId,
|
||||
selectedAddress,
|
||||
};
|
||||
}
|
||||
|
125
app/scripts/migrations/052.js
Normal file
125
app/scripts/migrations/052.js
Normal file
@ -0,0 +1,125 @@
|
||||
import { cloneDeep } from 'lodash';
|
||||
import {
|
||||
GOERLI,
|
||||
GOERLI_CHAIN_ID,
|
||||
KOVAN,
|
||||
KOVAN_CHAIN_ID,
|
||||
MAINNET,
|
||||
MAINNET_CHAIN_ID,
|
||||
NETWORK_TYPE_RPC,
|
||||
RINKEBY,
|
||||
RINKEBY_CHAIN_ID,
|
||||
ROPSTEN,
|
||||
ROPSTEN_CHAIN_ID,
|
||||
} from '../../../shared/constants/network';
|
||||
|
||||
const version = 52;
|
||||
|
||||
/**
|
||||
* Migrate tokens in Preferences to be keyed by chainId instead of
|
||||
* providerType. To prevent breaking user's MetaMask and selected
|
||||
* tokens, this migration copies the RPC entry into *every* custom RPC
|
||||
* chainId.
|
||||
*/
|
||||
export default {
|
||||
version,
|
||||
async migrate(originalVersionedData) {
|
||||
const versionedData = cloneDeep(originalVersionedData);
|
||||
versionedData.meta.version = version;
|
||||
const state = versionedData.data;
|
||||
versionedData.data = transformState(state);
|
||||
return versionedData;
|
||||
},
|
||||
};
|
||||
|
||||
function transformState(state = {}) {
|
||||
if (state.PreferencesController) {
|
||||
const {
|
||||
accountTokens,
|
||||
accountHiddenTokens,
|
||||
frequentRpcListDetail,
|
||||
} = state.PreferencesController;
|
||||
|
||||
const newAccountTokens = {};
|
||||
const newAccountHiddenTokens = {};
|
||||
|
||||
if (accountTokens && Object.keys(accountTokens).length > 0) {
|
||||
for (const address of Object.keys(accountTokens)) {
|
||||
newAccountTokens[address] = {};
|
||||
if (accountTokens[address][NETWORK_TYPE_RPC]) {
|
||||
frequentRpcListDetail.forEach((detail) => {
|
||||
newAccountTokens[address][detail.chainId] =
|
||||
accountTokens[address][NETWORK_TYPE_RPC];
|
||||
});
|
||||
}
|
||||
for (const providerType of Object.keys(accountTokens[address])) {
|
||||
switch (providerType) {
|
||||
case MAINNET:
|
||||
newAccountTokens[address][MAINNET_CHAIN_ID] =
|
||||
accountTokens[address][MAINNET];
|
||||
break;
|
||||
case ROPSTEN:
|
||||
newAccountTokens[address][ROPSTEN_CHAIN_ID] =
|
||||
accountTokens[address][ROPSTEN];
|
||||
break;
|
||||
case RINKEBY:
|
||||
newAccountTokens[address][RINKEBY_CHAIN_ID] =
|
||||
accountTokens[address][RINKEBY];
|
||||
break;
|
||||
case GOERLI:
|
||||
newAccountTokens[address][GOERLI_CHAIN_ID] =
|
||||
accountTokens[address][GOERLI];
|
||||
break;
|
||||
case KOVAN:
|
||||
newAccountTokens[address][KOVAN_CHAIN_ID] =
|
||||
accountTokens[address][KOVAN];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
state.PreferencesController.accountTokens = newAccountTokens;
|
||||
}
|
||||
|
||||
if (accountHiddenTokens && Object.keys(accountHiddenTokens).length > 0) {
|
||||
for (const address of Object.keys(accountHiddenTokens)) {
|
||||
newAccountHiddenTokens[address] = {};
|
||||
if (accountHiddenTokens[address][NETWORK_TYPE_RPC]) {
|
||||
frequentRpcListDetail.forEach((detail) => {
|
||||
newAccountHiddenTokens[address][detail.chainId] =
|
||||
accountHiddenTokens[address][NETWORK_TYPE_RPC];
|
||||
});
|
||||
}
|
||||
for (const providerType of Object.keys(accountHiddenTokens[address])) {
|
||||
switch (providerType) {
|
||||
case MAINNET:
|
||||
newAccountHiddenTokens[address][MAINNET_CHAIN_ID] =
|
||||
accountHiddenTokens[address][MAINNET];
|
||||
break;
|
||||
case ROPSTEN:
|
||||
newAccountHiddenTokens[address][ROPSTEN_CHAIN_ID] =
|
||||
accountHiddenTokens[address][ROPSTEN];
|
||||
break;
|
||||
case RINKEBY:
|
||||
newAccountHiddenTokens[address][RINKEBY_CHAIN_ID] =
|
||||
accountHiddenTokens[address][RINKEBY];
|
||||
break;
|
||||
case GOERLI:
|
||||
newAccountHiddenTokens[address][GOERLI_CHAIN_ID] =
|
||||
accountHiddenTokens[address][GOERLI];
|
||||
break;
|
||||
case KOVAN:
|
||||
newAccountHiddenTokens[address][KOVAN_CHAIN_ID] =
|
||||
accountHiddenTokens[address][KOVAN];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
state.PreferencesController.accountHiddenTokens = newAccountHiddenTokens;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
@ -56,6 +56,7 @@ const migrations = [
|
||||
require('./049').default,
|
||||
require('./050').default,
|
||||
require('./051').default,
|
||||
require('./052').default,
|
||||
];
|
||||
|
||||
export default migrations;
|
||||
|
@ -1,19 +1,39 @@
|
||||
import assert from 'assert';
|
||||
import { ObservableStore } from '@metamask/obs-store';
|
||||
import sinon from 'sinon';
|
||||
import PreferencesController from '../../../../app/scripts/controllers/preferences';
|
||||
import {
|
||||
MAINNET_CHAIN_ID,
|
||||
RINKEBY_CHAIN_ID,
|
||||
} from '../../../../shared/constants/network';
|
||||
|
||||
describe('preferences controller', function () {
|
||||
let preferencesController;
|
||||
let network;
|
||||
let currentChainId;
|
||||
let triggerNetworkChange;
|
||||
let switchToMainnet;
|
||||
let switchToRinkeby;
|
||||
const migrateAddressBookState = sinon.stub();
|
||||
|
||||
beforeEach(function () {
|
||||
network = { providerStore: new ObservableStore({ type: 'mainnet' }) };
|
||||
currentChainId = MAINNET_CHAIN_ID;
|
||||
network = {
|
||||
getCurrentChainId: () => currentChainId,
|
||||
on: sinon.spy(),
|
||||
};
|
||||
preferencesController = new PreferencesController({
|
||||
migrateAddressBookState,
|
||||
network,
|
||||
});
|
||||
triggerNetworkChange = network.on.firstCall.args[1];
|
||||
switchToMainnet = () => {
|
||||
currentChainId = MAINNET_CHAIN_ID;
|
||||
triggerNetworkChange();
|
||||
};
|
||||
switchToRinkeby = () => {
|
||||
currentChainId = RINKEBY_CHAIN_ID;
|
||||
triggerNetworkChange();
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@ -230,12 +250,10 @@ describe('preferences controller', function () {
|
||||
const symbolFirst = 'ABBR';
|
||||
const symbolSecond = 'ABBB';
|
||||
const decimals = 5;
|
||||
|
||||
network.providerStore.updateState({ type: 'mainnet' });
|
||||
await preferencesController.addToken(addressFirst, symbolFirst, decimals);
|
||||
const tokensFirstAddress = preferencesController.getTokens();
|
||||
|
||||
network.providerStore.updateState({ type: 'rinkeby' });
|
||||
switchToRinkeby();
|
||||
await preferencesController.addToken(
|
||||
addressSecond,
|
||||
symbolSecond,
|
||||
@ -304,14 +322,13 @@ describe('preferences controller', function () {
|
||||
});
|
||||
|
||||
it('should remove a token from its state on corresponding network', async function () {
|
||||
network.providerStore.updateState({ type: 'mainnet' });
|
||||
await preferencesController.addToken('0xa', 'A', 4);
|
||||
await preferencesController.addToken('0xb', 'B', 5);
|
||||
network.providerStore.updateState({ type: 'rinkeby' });
|
||||
switchToRinkeby();
|
||||
await preferencesController.addToken('0xa', 'A', 4);
|
||||
await preferencesController.addToken('0xb', 'B', 5);
|
||||
const initialTokensSecond = preferencesController.getTokens();
|
||||
network.providerStore.updateState({ type: 'mainnet' });
|
||||
switchToMainnet();
|
||||
await preferencesController.removeToken('0xa');
|
||||
|
||||
const tokensFirst = preferencesController.getTokens();
|
||||
@ -320,7 +337,7 @@ describe('preferences controller', function () {
|
||||
const [token1] = tokensFirst;
|
||||
assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 });
|
||||
|
||||
network.providerStore.updateState({ type: 'rinkeby' });
|
||||
switchToRinkeby();
|
||||
const tokensSecond = preferencesController.getTokens();
|
||||
assert.deepEqual(
|
||||
tokensSecond,
|
||||
@ -371,11 +388,10 @@ describe('preferences controller', function () {
|
||||
|
||||
describe('on updateStateNetworkType', function () {
|
||||
it('should remove a token from its state on corresponding network', async function () {
|
||||
network.providerStore.updateState({ type: 'mainnet' });
|
||||
await preferencesController.addToken('0xa', 'A', 4);
|
||||
await preferencesController.addToken('0xb', 'B', 5);
|
||||
const initialTokensFirst = preferencesController.getTokens();
|
||||
network.providerStore.updateState({ type: 'rinkeby' });
|
||||
switchToRinkeby();
|
||||
await preferencesController.addToken('0xa', 'C', 4);
|
||||
await preferencesController.addToken('0xb', 'D', 5);
|
||||
const initialTokensSecond = preferencesController.getTokens();
|
||||
@ -386,9 +402,9 @@ describe('preferences controller', function () {
|
||||
'tokens not equal for different networks and tokens',
|
||||
);
|
||||
|
||||
network.providerStore.updateState({ type: 'mainnet' });
|
||||
switchToMainnet();
|
||||
const tokensFirst = preferencesController.getTokens();
|
||||
network.providerStore.updateState({ type: 'rinkeby' });
|
||||
switchToRinkeby();
|
||||
const tokensSecond = preferencesController.getTokens();
|
||||
assert.deepEqual(
|
||||
tokensFirst,
|
||||
|
424
test/unit/migrations/052-test.js
Normal file
424
test/unit/migrations/052-test.js
Normal file
@ -0,0 +1,424 @@
|
||||
import assert from 'assert';
|
||||
import migration52 from '../../../app/scripts/migrations/052';
|
||||
import {
|
||||
GOERLI,
|
||||
GOERLI_CHAIN_ID,
|
||||
KOVAN,
|
||||
KOVAN_CHAIN_ID,
|
||||
MAINNET,
|
||||
MAINNET_CHAIN_ID,
|
||||
NETWORK_TYPE_RPC,
|
||||
RINKEBY,
|
||||
RINKEBY_CHAIN_ID,
|
||||
ROPSTEN,
|
||||
ROPSTEN_CHAIN_ID,
|
||||
} from '../../../shared/constants/network';
|
||||
|
||||
const TOKEN1 = { symbol: 'TST', address: '0x10', decimals: 18 };
|
||||
const TOKEN2 = { symbol: 'TXT', address: '0x11', decimals: 18 };
|
||||
const TOKEN3 = { symbol: 'TVT', address: '0x12', decimals: 18 };
|
||||
const TOKEN4 = { symbol: 'TAT', address: '0x13', decimals: 18 };
|
||||
|
||||
describe('migration #52', function () {
|
||||
it('should update the version metadata', async function () {
|
||||
const oldStorage = {
|
||||
meta: {
|
||||
version: 52,
|
||||
},
|
||||
data: {},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.meta, {
|
||||
version: 52,
|
||||
});
|
||||
});
|
||||
|
||||
it(`should move ${MAINNET} tokens and hidden tokens to be keyed by ${MAINNET_CHAIN_ID} for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[MAINNET]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[MAINNET]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[MAINNET]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[MAINNET]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[MAINNET_CHAIN_ID]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[MAINNET_CHAIN_ID]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[MAINNET_CHAIN_ID]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[MAINNET_CHAIN_ID]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should move ${RINKEBY} tokens and hidden tokens to be keyed by ${RINKEBY_CHAIN_ID} for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[RINKEBY]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[RINKEBY]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[RINKEBY]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[RINKEBY]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[RINKEBY_CHAIN_ID]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[RINKEBY_CHAIN_ID]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[RINKEBY_CHAIN_ID]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[RINKEBY_CHAIN_ID]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should move ${KOVAN} tokens and hidden tokens to be keyed by ${KOVAN_CHAIN_ID} for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[KOVAN]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[KOVAN]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[KOVAN]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[KOVAN]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[KOVAN_CHAIN_ID]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[KOVAN_CHAIN_ID]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[KOVAN_CHAIN_ID]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[KOVAN_CHAIN_ID]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should move ${GOERLI} tokens and hidden tokens to be keyed by ${GOERLI_CHAIN_ID} for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[GOERLI]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[GOERLI]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[GOERLI]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[GOERLI]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[GOERLI_CHAIN_ID]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[GOERLI_CHAIN_ID]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[GOERLI_CHAIN_ID]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[GOERLI_CHAIN_ID]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should move ${ROPSTEN} tokens and hidden tokens to be keyed by ${ROPSTEN_CHAIN_ID} for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[ROPSTEN]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[ROPSTEN]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[ROPSTEN]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[ROPSTEN]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[ROPSTEN_CHAIN_ID]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[ROPSTEN_CHAIN_ID]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[ROPSTEN_CHAIN_ID]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[ROPSTEN_CHAIN_ID]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should duplicate ${NETWORK_TYPE_RPC} tokens and hidden tokens to all custom networks for each address`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
frequentRpcListDetail: [
|
||||
{ chainId: '0xab' },
|
||||
{ chainId: '0x12' },
|
||||
{ chainId: '0xfa' },
|
||||
],
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
frequentRpcListDetail: [
|
||||
{ chainId: '0xab' },
|
||||
{ chainId: '0x12' },
|
||||
{ chainId: '0xfa' },
|
||||
],
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
'0xab': [TOKEN1],
|
||||
'0x12': [TOKEN1],
|
||||
'0xfa': [TOKEN1],
|
||||
},
|
||||
'0x1112': {
|
||||
'0xab': [TOKEN3],
|
||||
'0x12': [TOKEN3],
|
||||
'0xfa': [TOKEN3],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
'0xab': [TOKEN1, TOKEN2],
|
||||
'0x12': [TOKEN1, TOKEN2],
|
||||
'0xfa': [TOKEN1, TOKEN2],
|
||||
},
|
||||
'0x1112': {
|
||||
'0xab': [TOKEN1, TOKEN3],
|
||||
'0x12': [TOKEN1, TOKEN3],
|
||||
'0xfa': [TOKEN1, TOKEN3],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it(`should overwrite ${NETWORK_TYPE_RPC} tokens with built in networks if chainIds match`, async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
PreferencesController: {
|
||||
frequentRpcListDetail: [{ chainId: '0x1' }],
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN3],
|
||||
[MAINNET]: [TOKEN1],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
[NETWORK_TYPE_RPC]: [TOKEN1, TOKEN2],
|
||||
[MAINNET]: [TOKEN3, TOKEN4],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
PreferencesController: {
|
||||
frequentRpcListDetail: [{ chainId: '0x1' }],
|
||||
accountHiddenTokens: {
|
||||
'0x1111': {
|
||||
'0x1': [TOKEN1],
|
||||
},
|
||||
},
|
||||
accountTokens: {
|
||||
'0x1111': {
|
||||
'0x1': [TOKEN3, TOKEN4],
|
||||
},
|
||||
},
|
||||
bar: 'baz',
|
||||
},
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
|
||||
it('should do nothing if no PreferencesController key', async function () {
|
||||
const oldStorage = {
|
||||
meta: {},
|
||||
data: {
|
||||
foo: 'bar',
|
||||
},
|
||||
};
|
||||
|
||||
const newStorage = await migration52.migrate(oldStorage);
|
||||
assert.deepStrictEqual(newStorage.data, {
|
||||
foo: 'bar',
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user