mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-02-09 01:33:37 +00:00
Resolve custom token conflicts (#767)
* Remove custom token if it conflicts with symbol or address. * Refactor deduping to utils function. Add unit tests for said function. * Fix tscheck
This commit is contained in:
parent
7d2c3e1990
commit
418b186642
@ -19,6 +19,7 @@ import RootReducer from './reducers';
|
|||||||
import promiseMiddleware from 'redux-promise-middleware';
|
import promiseMiddleware from 'redux-promise-middleware';
|
||||||
import { getNodeConfigFromId } from 'utils/node';
|
import { getNodeConfigFromId } from 'utils/node';
|
||||||
import { getNetworkConfigFromId } from 'utils/network';
|
import { getNetworkConfigFromId } from 'utils/network';
|
||||||
|
import { dedupeCustomTokens } from 'utils/tokens';
|
||||||
import sagas from './sagas';
|
import sagas from './sagas';
|
||||||
import { gasPricetoBase } from 'libs/units';
|
import { gasPricetoBase } from 'libs/units';
|
||||||
|
|
||||||
@ -59,7 +60,6 @@ const configureStore = () => {
|
|||||||
}
|
}
|
||||||
: { ...swapInitialState };
|
: { ...swapInitialState };
|
||||||
|
|
||||||
const localCustomTokens = loadStatePropertyOrEmptyObject<CustomTokenState>('customTokens');
|
|
||||||
const savedTransactionState = loadStatePropertyOrEmptyObject<TransactionState>('transaction');
|
const savedTransactionState = loadStatePropertyOrEmptyObject<TransactionState>('transaction');
|
||||||
const savedConfigState = loadStatePropertyOrEmptyObject<ConfigState>('config');
|
const savedConfigState = loadStatePropertyOrEmptyObject<ConfigState>('config');
|
||||||
|
|
||||||
@ -82,6 +82,13 @@ const configureStore = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dedupe custom tokens initially
|
||||||
|
const savedCustomTokensState =
|
||||||
|
loadStatePropertyOrEmptyObject<CustomTokenState>('customTokens') || customTokensInitialState;
|
||||||
|
const initialNetwork =
|
||||||
|
(savedConfigState && savedConfigState.network) || configInitialState.network;
|
||||||
|
const customTokens = dedupeCustomTokens(initialNetwork.tokens, savedCustomTokensState);
|
||||||
|
|
||||||
const persistedInitialState = {
|
const persistedInitialState = {
|
||||||
config: {
|
config: {
|
||||||
...configInitialState,
|
...configInitialState,
|
||||||
@ -100,7 +107,7 @@ const configureStore = () => {
|
|||||||
: transactionInitialState.fields.gasPrice
|
: transactionInitialState.fields.gasPrice
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
customTokens: localCustomTokens || customTokensInitialState,
|
customTokens,
|
||||||
// ONLY LOAD SWAP STATE FROM LOCAL STORAGE IF STEP WAS 3
|
// ONLY LOAD SWAP STATE FROM LOCAL STORAGE IF STEP WAS 3
|
||||||
swap: swapState
|
swap: swapState
|
||||||
};
|
};
|
||||||
|
18
common/utils/tokens.ts
Normal file
18
common/utils/tokens.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Token } from 'config/data';
|
||||||
|
|
||||||
|
export function dedupeCustomTokens(networkTokens: Token[], customTokens: Token[]): Token[] {
|
||||||
|
if (!customTokens.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If any tokens have the same symbol or contract address, remove them
|
||||||
|
const tokenCollisionMap = networkTokens.reduce((prev, token) => {
|
||||||
|
prev[token.symbol] = true;
|
||||||
|
prev[token.address] = true;
|
||||||
|
return prev;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return customTokens.filter(token => {
|
||||||
|
return !tokenCollisionMap[token.address] && !tokenCollisionMap[token.symbol];
|
||||||
|
});
|
||||||
|
}
|
47
spec/utils/tokens.spec.ts
Normal file
47
spec/utils/tokens.spec.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { dedupeCustomTokens } from 'utils/tokens';
|
||||||
|
|
||||||
|
describe('dedupeCustomTokens', () => {
|
||||||
|
const networkTokens = [
|
||||||
|
{
|
||||||
|
address: '0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5',
|
||||||
|
symbol: 'REP',
|
||||||
|
decimal: 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
address: '0xa74476443119A942dE498590Fe1f2454d7D4aC0d',
|
||||||
|
symbol: 'GNT',
|
||||||
|
decimal: 18
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const DUPLICATE_ADDRESS = {
|
||||||
|
address: networkTokens[0].address,
|
||||||
|
symbol: 'REP2',
|
||||||
|
decimal: 18
|
||||||
|
};
|
||||||
|
const DUPLICATE_SYMBOL = {
|
||||||
|
address: '0x0',
|
||||||
|
symbol: networkTokens[1].symbol,
|
||||||
|
decimal: 18
|
||||||
|
};
|
||||||
|
const NONDUPLICATE_CUSTOM = {
|
||||||
|
address: '0x7cB57B5A97eAbe94205C07890BE4c1aD31E486A8',
|
||||||
|
symbol: 'MEW',
|
||||||
|
decimal: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const customTokens = [DUPLICATE_ADDRESS, DUPLICATE_SYMBOL, NONDUPLICATE_CUSTOM];
|
||||||
|
const dedupedTokens = dedupeCustomTokens(networkTokens, customTokens);
|
||||||
|
|
||||||
|
it('Should remove duplicate address custom tokens', () => {
|
||||||
|
expect(dedupedTokens.includes(DUPLICATE_ADDRESS)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should remove duplicate symbol custom tokens', () => {
|
||||||
|
expect(dedupedTokens.includes(DUPLICATE_SYMBOL)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not remove custom tokens that aren’t duplicates', () => {
|
||||||
|
expect(dedupedTokens.includes(NONDUPLICATE_CUSTOM)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user