Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b83f9bc
controller to fetch the token list from metaswaps api
NiranjanaBinoy May 26, 2021
3c9e6f0
integrating TokenListcontroller with AssetsDetectioncontroller and test
NiranjanaBinoy May 27, 2021
eb4c114
fixing lint error
NiranjanaBinoy May 27, 2021
f9ad337
updating the tests
NiranjanaBinoy May 28, 2021
bb1040c
fixing fetchOptions.headers check in TokenListController and check fo…
NiranjanaBinoy May 31, 2021
720eac3
separating the api interaction from controller
NiranjanaBinoy Jun 1, 2021
62ca7b4
fixing the lint and test errors after the rebase
NiranjanaBinoy Jun 3, 2021
07227be
fixing the type for defaultstate from any
NiranjanaBinoy Jun 4, 2021
8f76dbf
exporting the controller
NiranjanaBinoy Jun 5, 2021
bedcbd3
adding new api end points and related functions
NiranjanaBinoy Jun 16, 2021
aeed783
change in fetchtokenList logic and removing topAssets endpoint and re…
NiranjanaBinoy Jun 16, 2021
bfa6485
changing the state variable from to to avoid overwriting in extension
NiranjanaBinoy Jun 22, 2021
239e12c
adding cache and removing tokens with less than 2 occurance and symbo…
NiranjanaBinoy Jun 25, 2021
f5a1209
removing console.log
NiranjanaBinoy Jun 25, 2021
be997b5
updating cache on sync and updation if data avalable is undefined, fe…
NiranjanaBinoy Jun 27, 2021
5b7f953
updating DEFAULT_INTERVAL to 1 hour and DEFAULT_THRESHOLD to 30 minutes
NiranjanaBinoy Jun 27, 2021
57a1799
fixing test failure
NiranjanaBinoy Jun 27, 2021
084cae7
fixing duplicate symbol filtering and adding related test cases
NiranjanaBinoy Jun 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
updating cache on sync and updation if data avalable is undefined, fe…
…tching token on network change and test case updations.
  • Loading branch information
NiranjanaBinoy committed Jun 27, 2021
commit be997b5ae21a04780069eab8cbcda10b4e6aa0be
122 changes: 106 additions & 16 deletions src/assets/TokenListController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const sampleSingleChainState = {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp,
timestamp,
data: sampleMainnetTokenList,
},
},
Expand All @@ -187,7 +187,7 @@ const sampleTwoChainState = {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp,
timestamp,
data: sampleMainnetTokenList,
},
'56': {
Expand Down Expand Up @@ -243,7 +243,7 @@ const existingState = {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp,
timestamp,
data: sampleMainnetTokenList,
},
},
Expand Down Expand Up @@ -274,7 +274,7 @@ const outdatedExistingState = {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp,
timestamp,
data: sampleMainnetTokenList,
},
},
Expand Down Expand Up @@ -303,7 +303,7 @@ const expiredCacheExistingState = {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp - 360000,
timestamp: timestamp - 360000,
data: [
{
address: '0x514910771af9ca656af840dff83e8264ecf986ca',
Expand Down Expand Up @@ -403,7 +403,7 @@ describe('TokenListController', () => {
},
tokensChainsCache: {
'1': {
timeStamp: timestamp,
timestamp,
data: sampleMainnetTokenList,
},
},
Expand Down Expand Up @@ -521,20 +521,46 @@ describe('TokenListController', () => {
sampleSingleChainState.tokensChainsCache[NetworksChainId.mainnet].data,
);
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].timeStamp,
controller.state.tokensChainsCache[NetworksChainId.mainnet].timestamp,
).toBeGreaterThanOrEqual(
sampleSingleChainState.tokensChainsCache[NetworksChainId.mainnet]
.timeStamp,
.timestamp,
);
controller.destroy();
});

it('should update token list from cache', async () => {
it('should update the cache before threshold time if the current data is undefined', async () => {
nock(TOKEN_END_POINT_API)
.get(`/tokens/${NetworksChainId.mainnet}`)
.once()
.reply(200, undefined);

nock(TOKEN_END_POINT_API)
.get(`/tokens/${NetworksChainId.mainnet}`)
.reply(200, sampleMainnetTokenList)
.persist();
const messenger = getRestrictedMessenger();
const controller = new TokenListController({
chainId: NetworksChainId.mainnet,
onNetworkStateChange: (listener) => network.subscribe(listener),
messenger,
interval: 100,
});
await controller.start();
expect(controller.state.tokenList).toStrictEqual({});
expect(controller.state.tokensChainsCache.data).toBeUndefined();
await new Promise<void>((resolve) => setTimeout(() => resolve(), 150));
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
expect(controller.state.tokensChainsCache['1'].data).toStrictEqual(
sampleSingleChainState.tokensChainsCache['1'].data,
);
controller.destroy();
});

it('should update token list from cache before reaching the threshold time', async () => {
const messenger = getRestrictedMessenger();
const controller = new TokenListController({
chainId: NetworksChainId.mainnet,
onNetworkStateChange: (listener) => network.subscribe(listener),
Expand Down Expand Up @@ -580,10 +606,10 @@ describe('TokenListController', () => {
expect(controller.state).toStrictEqual(expiredCacheExistingState);
await controller.start();
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].timeStamp,
controller.state.tokensChainsCache[NetworksChainId.mainnet].timestamp,
).toBeGreaterThan(
sampleSingleChainState.tokensChainsCache[NetworksChainId.mainnet]
.timeStamp,
.timestamp,
);
expect(
controller.state.tokensChainsCache[NetworksChainId.mainnet].data,
Expand Down Expand Up @@ -617,7 +643,7 @@ describe('TokenListController', () => {
chainId: '56',
},
});
await new Promise<void>((resolve) => setTimeout(() => resolve(), 150));
await new Promise<void>((resolve) => setTimeout(() => resolve(), 10));
expect(controller.state.tokenList).toStrictEqual(
sampleTwoChainState.tokenList,
);
Expand All @@ -633,26 +659,90 @@ describe('TokenListController', () => {
controller.destroy();
});

it('should call syncTokens to update the token list in the backend and returns nothing', async () => {
it('should call syncTokens to update the token list in the backend and clears the cache for the next fetch', async () => {
const tokenListBeforeSync = [
{
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
symbol: 'SNX',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Synthetix',
},
];
nock(TOKEN_END_POINT_API)
.get(`/sync/${NetworksChainId.mainnet}`)
.reply(200)
.persist();

nock(TOKEN_END_POINT_API)
.get(`/tokens/${NetworksChainId.mainnet}`)
.once()
.reply(200, tokenListBeforeSync);

nock(TOKEN_END_POINT_API)
.get(`/tokens/${NetworksChainId.mainnet}`)
.reply(200, sampleMainnetTokenList)
.persist();

const messenger = getRestrictedMessenger();
const controller = new TokenListController({
chainId: NetworksChainId.mainnet,
onNetworkStateChange: (listener) => network.subscribe(listener),
messenger,
interval: 200,
});
await controller.start();
expect(controller.state.tokenList).toStrictEqual({
'0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f': {
address: '0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f',
symbol: 'SNX',
decimals: 18,
occurrences: 11,
aggregators: [
'paraswap',
'pmm',
'airswapLight',
'zeroEx',
'bancor',
'coinGecko',
'zapper',
'kleros',
'zerion',
'cmc',
'oneInch',
],
name: 'Synthetix',
},
});
expect(await controller.syncTokens()).toBeUndefined();
expect(controller.state.tokensChainsCache['1']).toStrictEqual({
timestamp: 0,
data: [],
});
await new Promise<void>((resolve) => setTimeout(() => resolve(), 300));
expect(controller.state.tokenList).toStrictEqual(
sampleSingleChainState.tokenList,
);
controller.destroy();
});

it('should return the metadata for a tokenAddress provided', async () => {
nock(TOKEN_END_POINT_API)
.get(
`/tokens/${NetworksChainId.mainnet}?address=0x514910771af9ca656af840dff83e8264ecf986ca`,
)
.get(`/tokens/${NetworksChainId.mainnet}`)
.query({ address: '0x514910771af9ca656af840dff83e8264ecf986ca' })
.reply(200, sampleTokenMetaData)
.persist();
const messenger = getRestrictedMessenger();
Expand Down
26 changes: 22 additions & 4 deletions src/assets/TokenListController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const DEFAULT_THRESHOLD = 360 * 1000;
const name = 'TokenListController';

interface DataCache {
timeStamp: number;
timestamp: number;
data: Token[];
}
interface TokensChainsCache {
Expand Down Expand Up @@ -118,8 +118,9 @@ export class TokenListController extends BaseController<
this.intervalDelay = interval;
this.cacheRefreshThreshold = cacheRefreshThreshold;
this.chainId = chainId;
onNetworkStateChange((networkState) => {
onNetworkStateChange(async (networkState) => {
this.chainId = networkState.provider.chainId;
await safelyExecute(() => this.fetchTokenList());
});
}

Expand Down Expand Up @@ -215,7 +216,10 @@ export class TokenListController extends BaseController<
const { tokensChainsCache, ...tokensData }: TokenListState = this.state;
const dataCache = tokensChainsCache[this.chainId];
const now = Date.now();
if (dataCache && now - dataCache.timeStamp < this.cacheRefreshThreshold) {
if (
dataCache?.data &&
now - dataCache?.timestamp < this.cacheRefreshThreshold
) {
return dataCache.data;
}
const tokenList: Token[] = await safelyExecute(() =>
Expand All @@ -224,7 +228,7 @@ export class TokenListController extends BaseController<
const updatedTokensChainsCache = {
...tokensChainsCache,
[this.chainId]: {
timeStamp: Date.now(),
timestamp: Date.now(),
data: tokenList,
},
};
Expand All @@ -244,6 +248,20 @@ export class TokenListController extends BaseController<
const releaseLock = await this.mutex.acquire();
try {
await safelyExecute(() => syncTokens(this.chainId));
const { tokenList, tokensChainsCache } = this.state;
const updatedTokensChainsCache = {
...tokensChainsCache,
[this.chainId]: {
timestamp: 0,
data: [],
},
};
this.update(() => {
return {
tokenList,
tokensChainsCache: updatedTokensChainsCache,
};
});
} finally {
releaseLock();
}
Expand Down