Skip to content

Commit

Permalink
Consolidate token list controller data (#527)
Browse files Browse the repository at this point in the history
* Add utils function to convert contract metadata logo to iconUrl. Return same token type regardless of static or dynamic from token list controller.

* Provide ContractMap type for legacy tokens. Update TokenListController tests. Add util test for converting logo to URL.

* Provide root path for TokenListController. NOTE: Static tokens will return with ABSOLUTE file paths. Client side will need to be aware of that.

* Export Token as TokenListToken from TokenListController to prevent conflict with TokenRateController.

* Clean up TokenListController. Update static logo path.

* Clean up TokenListController. Fix TokenListController tests.

* Fix github actions linting

* Fix more github actions linting

* Fix even more github actions linting

* Fix last github actions linting

* Allow for more time for token list controller API calls before timeout

* Fix linting error

* Add back newline to EOF package.json

* Update contract metadata version

* Up token list timeout to 10s

* Update split logic

* Add getFileExt utility and test

* Add back caret to contract-metadata

* Update description for fetchFromCache function

* Remove iconPath

* Remove unused enum & comment

Co-authored-by: Ricky Miller <ricky.miller@gmail.com>
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
  • Loading branch information
3 people authored and MajorLift committed Oct 11, 2023
1 parent abb155c commit b32fb8d
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 126 deletions.
6 changes: 5 additions & 1 deletion src/apis/token-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ function getTokenMetadataURL(chainId: string, tokenAddress: string) {
return `${END_POINT}/token/${chainId}?address=${tokenAddress}`;
}

// Token list averages 1.6 MB in size
// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.
const timeout = 10000;

/**
* Fetches the list of token metadata for a given network chainId
*
Expand Down Expand Up @@ -61,7 +65,7 @@ async function queryApi(apiURL: string): Promise<Response> {
};
fetchOptions.headers = new window.Headers();
fetchOptions.headers.set('Content-Type', 'application/json');
return await timeoutFetch(apiURL, fetchOptions);
return await timeoutFetch(apiURL, fetchOptions, timeout);
}

/**
Expand Down
98 changes: 39 additions & 59 deletions src/assets/TokenListController.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { stub } from 'sinon';
import nock from 'nock';
import contractmap from '@metamask/contract-metadata';
import contractMap from '@metamask/contract-metadata';
import { ControllerMessenger } from '../ControllerMessenger';
import {
NetworkController,
Expand All @@ -11,17 +11,27 @@ import {
TokenListController,
TokenListStateChange,
GetTokenListState,
TokenListMap,
ContractMap,
} from './TokenListController';

const name = 'TokenListController';
const TOKEN_END_POINT_API = 'https://token-api.airswap-prod.codefi.network';
const timestamp = Date.now();

const staticTokenList: any = {};
for (const tokenAddress in contractmap) {
const { erc20, logo, ...token } = contractmap[tokenAddress];
const staticTokenList: TokenListMap = {};
for (const tokenAddress in contractMap) {
const { erc20, logo: filePath, ...token } = (contractMap as ContractMap)[
tokenAddress
];
if (erc20) {
staticTokenList[tokenAddress] = { ...token, iconUrl: logo };
staticTokenList[tokenAddress] = {
...token,
address: tokenAddress,
iconUrl: filePath,
occurrences: null,
aggregators: null,
};
}
}
const sampleMainnetTokenList = [
Expand Down Expand Up @@ -90,48 +100,6 @@ const sampleMainnetTokenList = [
},
];
const sampleWithDuplicateSymbols = [
{
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
symbol: 'SNX',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Synthetix',
iconUrl: 'https://airswap-token-images.s3.amazonaws.com/SNX.png',
},
{
address: '0x514910771af9ca656af840dff83e8264ecf986ca',
symbol: 'SNX',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Chainlink',
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/LINK.png',
},
{
address: '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c',
symbol: 'BNT',
Expand Down Expand Up @@ -185,15 +153,6 @@ const sampleWithLessThan2Occurences = [
name: 'Chainlink',
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/LINK.png',
},
{
address: '0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c',
symbol: 'BNT',
decimals: 18,
occurrences: 1,
aggregators: ['paraswap'],
name: 'Bancor',
iconUrl: 'https://s3.amazonaws.com/airswap-token-images/BNT.png',
},
];
const sampleBinanceTokenList = [
{
Expand Down Expand Up @@ -716,7 +675,14 @@ describe('TokenListController', () => {
});
expect(controller.state).toStrictEqual(existingState);
await controller.start();
expect(controller.state).toStrictEqual(sampleSingleChainState);
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].data,
).toStrictEqual(
sampleSingleChainState.tokensChainsCache[NetworksChainId.mainnet].data,
);
controller.destroy();
});

Expand Down Expand Up @@ -831,7 +797,14 @@ describe('TokenListController', () => {
});
expect(controller.state).toStrictEqual(outdatedExistingState);
await controller.start();
expect(controller.state).toStrictEqual(sampleSingleChainState);
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].data,
).toStrictEqual(
sampleSingleChainState.tokensChainsCache[NetworksChainId.mainnet].data,
);
controller.destroy();
});

Expand Down Expand Up @@ -884,7 +857,14 @@ describe('TokenListController', () => {
});
expect(controller.state).toStrictEqual(existingState);
await controller.start();
expect(controller.state).toStrictEqual(sampleSingleChainState);
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].data,
).toStrictEqual(
sampleTwoChainState.tokensChainsCache[NetworksChainId.mainnet].data,
);
network.update({
provider: {
type: 'rpc',
Expand Down
Loading

0 comments on commit b32fb8d

Please sign in to comment.