mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-23 02:10:12 +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 { LISTED_CONTRACT_ADDRESSES } from '../../../shared/constants/tokens';
|
||||||
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
|
import { NETWORK_TYPE_TO_ID_MAP } from '../../../shared/constants/network';
|
||||||
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
|
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
|
||||||
|
import { NETWORK_EVENTS } from './network';
|
||||||
|
|
||||||
export default class PreferencesController {
|
export default class PreferencesController {
|
||||||
/**
|
/**
|
||||||
@ -72,7 +73,7 @@ export default class PreferencesController {
|
|||||||
this.store.setMaxListeners(12);
|
this.store.setMaxListeners(12);
|
||||||
this.openPopup = opts.openPopup;
|
this.openPopup = opts.openPopup;
|
||||||
this.migrateAddressBookState = opts.migrateAddressBookState;
|
this.migrateAddressBookState = opts.migrateAddressBookState;
|
||||||
this._subscribeProviderType();
|
this._subscribeToNetworkDidChange();
|
||||||
|
|
||||||
global.setPreference = (key, value) => {
|
global.setPreference = (key, value) => {
|
||||||
return this.setFeatureFlag(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() {
|
_subscribeToNetworkDidChange() {
|
||||||
this.network.providerStore.subscribe(() => {
|
this.network.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => {
|
||||||
const { tokens, hiddenTokens } = this._getTokenRelatedStates();
|
const { tokens, hiddenTokens } = this._getTokenRelatedStates();
|
||||||
this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens);
|
this._updateAccountTokens(tokens, this.getAssetImages(), hiddenTokens);
|
||||||
});
|
});
|
||||||
@ -689,12 +689,12 @@ export default class PreferencesController {
|
|||||||
_updateAccountTokens(tokens, assetImages, hiddenTokens) {
|
_updateAccountTokens(tokens, assetImages, hiddenTokens) {
|
||||||
const {
|
const {
|
||||||
accountTokens,
|
accountTokens,
|
||||||
providerType,
|
chainId,
|
||||||
selectedAddress,
|
selectedAddress,
|
||||||
accountHiddenTokens,
|
accountHiddenTokens,
|
||||||
} = this._getTokenRelatedStates();
|
} = this._getTokenRelatedStates();
|
||||||
accountTokens[selectedAddress][providerType] = tokens;
|
accountTokens[selectedAddress][chainId] = tokens;
|
||||||
accountHiddenTokens[selectedAddress][providerType] = hiddenTokens;
|
accountHiddenTokens[selectedAddress][chainId] = hiddenTokens;
|
||||||
this.store.updateState({
|
this.store.updateState({
|
||||||
accountTokens,
|
accountTokens,
|
||||||
tokens,
|
tokens,
|
||||||
@ -730,27 +730,27 @@ export default class PreferencesController {
|
|||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
selectedAddress = this.store.getState().selectedAddress;
|
selectedAddress = this.store.getState().selectedAddress;
|
||||||
}
|
}
|
||||||
const providerType = this.network.providerStore.getState().type;
|
const chainId = this.network.getCurrentChainId();
|
||||||
if (!(selectedAddress in accountTokens)) {
|
if (!(selectedAddress in accountTokens)) {
|
||||||
accountTokens[selectedAddress] = {};
|
accountTokens[selectedAddress] = {};
|
||||||
}
|
}
|
||||||
if (!(selectedAddress in accountHiddenTokens)) {
|
if (!(selectedAddress in accountHiddenTokens)) {
|
||||||
accountHiddenTokens[selectedAddress] = {};
|
accountHiddenTokens[selectedAddress] = {};
|
||||||
}
|
}
|
||||||
if (!(providerType in accountTokens[selectedAddress])) {
|
if (!(chainId in accountTokens[selectedAddress])) {
|
||||||
accountTokens[selectedAddress][providerType] = [];
|
accountTokens[selectedAddress][chainId] = [];
|
||||||
}
|
}
|
||||||
if (!(providerType in accountHiddenTokens[selectedAddress])) {
|
if (!(chainId in accountHiddenTokens[selectedAddress])) {
|
||||||
accountHiddenTokens[selectedAddress][providerType] = [];
|
accountHiddenTokens[selectedAddress][chainId] = [];
|
||||||
}
|
}
|
||||||
const tokens = accountTokens[selectedAddress][providerType];
|
const tokens = accountTokens[selectedAddress][chainId];
|
||||||
const hiddenTokens = accountHiddenTokens[selectedAddress][providerType];
|
const hiddenTokens = accountHiddenTokens[selectedAddress][chainId];
|
||||||
return {
|
return {
|
||||||
tokens,
|
tokens,
|
||||||
accountTokens,
|
accountTokens,
|
||||||
hiddenTokens,
|
hiddenTokens,
|
||||||
accountHiddenTokens,
|
accountHiddenTokens,
|
||||||
providerType,
|
chainId,
|
||||||
selectedAddress,
|
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('./049').default,
|
||||||
require('./050').default,
|
require('./050').default,
|
||||||
require('./051').default,
|
require('./051').default,
|
||||||
|
require('./052').default,
|
||||||
];
|
];
|
||||||
|
|
||||||
export default migrations;
|
export default migrations;
|
||||||
|
@ -1,19 +1,39 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import { ObservableStore } from '@metamask/obs-store';
|
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import PreferencesController from '../../../../app/scripts/controllers/preferences';
|
import PreferencesController from '../../../../app/scripts/controllers/preferences';
|
||||||
|
import {
|
||||||
|
MAINNET_CHAIN_ID,
|
||||||
|
RINKEBY_CHAIN_ID,
|
||||||
|
} from '../../../../shared/constants/network';
|
||||||
|
|
||||||
describe('preferences controller', function () {
|
describe('preferences controller', function () {
|
||||||
let preferencesController;
|
let preferencesController;
|
||||||
let network;
|
let network;
|
||||||
|
let currentChainId;
|
||||||
|
let triggerNetworkChange;
|
||||||
|
let switchToMainnet;
|
||||||
|
let switchToRinkeby;
|
||||||
const migrateAddressBookState = sinon.stub();
|
const migrateAddressBookState = sinon.stub();
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
network = { providerStore: new ObservableStore({ type: 'mainnet' }) };
|
currentChainId = MAINNET_CHAIN_ID;
|
||||||
|
network = {
|
||||||
|
getCurrentChainId: () => currentChainId,
|
||||||
|
on: sinon.spy(),
|
||||||
|
};
|
||||||
preferencesController = new PreferencesController({
|
preferencesController = new PreferencesController({
|
||||||
migrateAddressBookState,
|
migrateAddressBookState,
|
||||||
network,
|
network,
|
||||||
});
|
});
|
||||||
|
triggerNetworkChange = network.on.firstCall.args[1];
|
||||||
|
switchToMainnet = () => {
|
||||||
|
currentChainId = MAINNET_CHAIN_ID;
|
||||||
|
triggerNetworkChange();
|
||||||
|
};
|
||||||
|
switchToRinkeby = () => {
|
||||||
|
currentChainId = RINKEBY_CHAIN_ID;
|
||||||
|
triggerNetworkChange();
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
@ -230,12 +250,10 @@ describe('preferences controller', function () {
|
|||||||
const symbolFirst = 'ABBR';
|
const symbolFirst = 'ABBR';
|
||||||
const symbolSecond = 'ABBB';
|
const symbolSecond = 'ABBB';
|
||||||
const decimals = 5;
|
const decimals = 5;
|
||||||
|
|
||||||
network.providerStore.updateState({ type: 'mainnet' });
|
|
||||||
await preferencesController.addToken(addressFirst, symbolFirst, decimals);
|
await preferencesController.addToken(addressFirst, symbolFirst, decimals);
|
||||||
const tokensFirstAddress = preferencesController.getTokens();
|
const tokensFirstAddress = preferencesController.getTokens();
|
||||||
|
|
||||||
network.providerStore.updateState({ type: 'rinkeby' });
|
switchToRinkeby();
|
||||||
await preferencesController.addToken(
|
await preferencesController.addToken(
|
||||||
addressSecond,
|
addressSecond,
|
||||||
symbolSecond,
|
symbolSecond,
|
||||||
@ -304,14 +322,13 @@ describe('preferences controller', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a token from its state on corresponding network', async 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('0xa', 'A', 4);
|
||||||
await preferencesController.addToken('0xb', 'B', 5);
|
await preferencesController.addToken('0xb', 'B', 5);
|
||||||
network.providerStore.updateState({ type: 'rinkeby' });
|
switchToRinkeby();
|
||||||
await preferencesController.addToken('0xa', 'A', 4);
|
await preferencesController.addToken('0xa', 'A', 4);
|
||||||
await preferencesController.addToken('0xb', 'B', 5);
|
await preferencesController.addToken('0xb', 'B', 5);
|
||||||
const initialTokensSecond = preferencesController.getTokens();
|
const initialTokensSecond = preferencesController.getTokens();
|
||||||
network.providerStore.updateState({ type: 'mainnet' });
|
switchToMainnet();
|
||||||
await preferencesController.removeToken('0xa');
|
await preferencesController.removeToken('0xa');
|
||||||
|
|
||||||
const tokensFirst = preferencesController.getTokens();
|
const tokensFirst = preferencesController.getTokens();
|
||||||
@ -320,7 +337,7 @@ describe('preferences controller', function () {
|
|||||||
const [token1] = tokensFirst;
|
const [token1] = tokensFirst;
|
||||||
assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 });
|
assert.deepEqual(token1, { address: '0xb', symbol: 'B', decimals: 5 });
|
||||||
|
|
||||||
network.providerStore.updateState({ type: 'rinkeby' });
|
switchToRinkeby();
|
||||||
const tokensSecond = preferencesController.getTokens();
|
const tokensSecond = preferencesController.getTokens();
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
tokensSecond,
|
tokensSecond,
|
||||||
@ -371,11 +388,10 @@ describe('preferences controller', function () {
|
|||||||
|
|
||||||
describe('on updateStateNetworkType', function () {
|
describe('on updateStateNetworkType', function () {
|
||||||
it('should remove a token from its state on corresponding network', async 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('0xa', 'A', 4);
|
||||||
await preferencesController.addToken('0xb', 'B', 5);
|
await preferencesController.addToken('0xb', 'B', 5);
|
||||||
const initialTokensFirst = preferencesController.getTokens();
|
const initialTokensFirst = preferencesController.getTokens();
|
||||||
network.providerStore.updateState({ type: 'rinkeby' });
|
switchToRinkeby();
|
||||||
await preferencesController.addToken('0xa', 'C', 4);
|
await preferencesController.addToken('0xa', 'C', 4);
|
||||||
await preferencesController.addToken('0xb', 'D', 5);
|
await preferencesController.addToken('0xb', 'D', 5);
|
||||||
const initialTokensSecond = preferencesController.getTokens();
|
const initialTokensSecond = preferencesController.getTokens();
|
||||||
@ -386,9 +402,9 @@ describe('preferences controller', function () {
|
|||||||
'tokens not equal for different networks and tokens',
|
'tokens not equal for different networks and tokens',
|
||||||
);
|
);
|
||||||
|
|
||||||
network.providerStore.updateState({ type: 'mainnet' });
|
switchToMainnet();
|
||||||
const tokensFirst = preferencesController.getTokens();
|
const tokensFirst = preferencesController.getTokens();
|
||||||
network.providerStore.updateState({ type: 'rinkeby' });
|
switchToRinkeby();
|
||||||
const tokensSecond = preferencesController.getTokens();
|
const tokensSecond = preferencesController.getTokens();
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
tokensFirst,
|
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