Skip to content

Commit

Permalink
fix: fix multichain import token
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Nov 11, 2024
1 parent 7896869 commit bdcf0f0
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 8 deletions.
138 changes: 138 additions & 0 deletions packages/assets-controllers/src/TokensController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,84 @@ describe('TokensController', () => {
});
});

it('should add tokens and update existing ones and detected tokens', async () => {
const selectedAddress = '0x0001';
const selectedAccount = createMockInternalAccount({
address: selectedAddress,
});
await withController(
{
mockNetworkClientConfigurationsByNetworkClientId: {
networkClientId1: buildCustomNetworkClientConfiguration({
chainId: '0x1',
}),
},
mocks: {
getSelectedAccount: selectedAccount,
getAccount: selectedAccount,
},
},
async ({ controller }) => {
await controller.addDetectedTokens(
[
{
address: '0x01',
symbol: 'barA',
decimals: 2,
},
],
{
selectedAddress: '0x0001',
chainId: '0x1',
},
);

await controller.addTokens(
[
{
address: '0x01',
symbol: 'barA',
decimals: 2,
aggregators: [],
name: 'Token1',
},
{
address: '0x02',
symbol: 'barB',
decimals: 2,
aggregators: [],
name: 'Token2',
},
],
'networkClientId1',
);

expect(controller.state.allTokens).toStrictEqual({
'0x1': {
'0x0001': [
{
address: '0x01',
symbol: 'barA',
decimals: 2,
aggregators: [],
name: 'Token1',
image: undefined,
},
{
address: '0x02',
symbol: 'barB',
decimals: 2,
aggregators: [],
name: 'Token2',
image: undefined,
},
],
},
});
},
);
});

it('should add detected tokens', async () => {
await withController(async ({ controller }) => {
await controller.addDetectedTokens([
Expand Down Expand Up @@ -2142,6 +2220,66 @@ describe('TokensController', () => {
},
);
});

it('should clear allDetectedTokens under chain ID and selected address when a detected token is added to tokens list', async () => {
const selectedAddress = '0x1';
const selectedAccount = createMockInternalAccount({
address: selectedAddress,
});
const tokenAddress = '0x01';
const dummyDetectedTokens = [
{
address: tokenAddress,
symbol: 'barA',
decimals: 2,
aggregators: [],
isERC721: undefined,
name: undefined,
image: undefined,
},
];
const dummyTokens = [
{
address: tokenAddress,
symbol: 'barA',
decimals: 2,
aggregators: [],
isERC721: undefined,
name: undefined,
image: undefined,
},
];

await withController(
{
options: {
chainId: ChainId.mainnet,
},
mocks: {
getSelectedAccount: selectedAccount,
},
},
async ({ controller }) => {
// First, add detected tokens
await controller.addDetectedTokens(dummyDetectedTokens);
expect(
controller.state.allDetectedTokens[ChainId.mainnet][
selectedAddress
],
).toStrictEqual(dummyDetectedTokens);

// Now, add the same token to the tokens list
await controller.addTokens(dummyTokens);

// Check that allDetectedTokens for the selected address is cleared
expect(
controller.state.allDetectedTokens[ChainId.mainnet][
selectedAddress
],
).toStrictEqual([]);
},
);
});
});

describe('when TokenListController:stateChange is published', () => {
Expand Down
26 changes: 18 additions & 8 deletions packages/assets-controllers/src/TokensController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,13 +462,16 @@ export class TokensController extends BaseController<
*/
async addTokens(tokensToImport: Token[], networkClientId?: NetworkClientId) {
const releaseLock = await this.#mutex.acquire();
const { tokens, detectedTokens, ignoredTokens } = this.state;
const { ignoredTokens, allDetectedTokens } = this.state;
const importedTokensMap: { [key: string]: true } = {};
// Used later to dedupe imported tokens
const newTokensMap = tokens.reduce((output, current) => {
output[current.address] = current;
return output;
}, {} as { [address: string]: Token });
const newTokensMap = Object.values(tokensToImport).reduce(
(output, token) => {
output[token.address] = token;
return output;
},
{} as { [address: string]: Token },
);
try {
tokensToImport.forEach((tokenToAdd) => {
const { address, symbol, decimals, image, aggregators, name } =
Expand All @@ -488,9 +491,6 @@ export class TokensController extends BaseController<
});
const newTokens = Object.values(newTokensMap);

const newDetectedTokens = detectedTokens.filter(
(token) => !importedTokensMap[token.address.toLowerCase()],
);
const newIgnoredTokens = ignoredTokens.filter(
(tokenAddress) => !newTokensMap[tokenAddress.toLowerCase()],
);
Expand All @@ -503,6 +503,16 @@ export class TokensController extends BaseController<
).configuration.chainId;
}

const newDetectedTokens =
interactingChainId &&
allDetectedTokens[interactingChainId]?.[this.#getSelectedAddress()]
? allDetectedTokens[interactingChainId]?.[
this.#getSelectedAddress()
].filter(
(token: Token) => !importedTokensMap[token.address.toLowerCase()],
)
: [];

const { newAllTokens, newAllDetectedTokens, newAllIgnoredTokens } =
this.#getNewAllTokensState({
newTokens,
Expand Down

0 comments on commit bdcf0f0

Please sign in to comment.