From c1a8b82a6759813afa4620ad2fd11bebd9f106c9 Mon Sep 17 00:00:00 2001 From: salimtb Date: Wed, 29 May 2024 10:52:46 +0200 Subject: [PATCH 1/3] feat: Implement market data by Chain ID (#4206) ## Explanation This pull request introduces a significant enhancement to our application's functionality by integrating a new feature that presents market data more comprehensively. This includes updates such as daily percentage changes and the fluctuation in amounts for a variety of assets. To accommodate this, we've expanded our state structure to encapsulate a broader array of data points. Below is a snippet illustrating the enriched data now available: ``` { "0x3845badade8e6dff049820680d1f14bd3903a5d0": { "id": "the-sandbox", "price": 0.00012453786505819405, "marketCap": 282288.57927502826, ... "pricePercentChange1y": -9.725813860523756 }, "0xdac17f958d2ee523a2206206994597c13d831ec7": { "id": "tether", "price": 0.00026894681330590396, "marketCap": 30060069.165317584, ... "pricePercentChange1y": -0.05851492115750438 } } ``` As a result, the TokenRatesController state has been meticulously updated to include this marketData, enriching our application with a more detailed and dynamic representation of asset performance. This enhancement not only broadens the scope of information we provide but also elevates the user experience by offering a granular view of market trends and asset valuations. ## References ## Changelog We've introduced a new marketData property to the application's state, providing a comprehensive overview of market-related information for various assets. This enhancement brings a wealth of data directly into our application. This update significantly enriches the data available within our application, offering users detailed insights into asset performance and market trends. The marketData property is meticulously structured to ensure easy access to a wide array of information, enhancing the overall user experience by providing a granular and dynamic view of the market. ### `@metamask/package-assets-controllers` - **ADDED**: Added `marketData` to TokenRatesState - **REMOVED**: Removed `contractExchangeRates` from TokenRatesState - **REMOVED**: Removed `contractExchangeRatesByChainId` from TokenRatesState ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've highlighted breaking changes using the "BREAKING" category above as appropriate --- .../src/TokenRatesController.test.ts | 290 +++-- .../src/TokenRatesController.ts | 133 +- .../assets-controllers/src/assetsUtil.test.ts | 18 + .../abstract-token-prices-service.ts | 18 + .../token-prices-service/codefi-v2.test.ts | 1160 ++++++++++++++++- .../src/token-prices-service/codefi-v2.ts | 137 +- 6 files changed, 1515 insertions(+), 241 deletions(-) diff --git a/packages/assets-controllers/src/TokenRatesController.test.ts b/packages/assets-controllers/src/TokenRatesController.test.ts index d5d0ae8701..a992905e23 100644 --- a/packages/assets-controllers/src/TokenRatesController.test.ts +++ b/packages/assets-controllers/src/TokenRatesController.test.ts @@ -68,8 +68,7 @@ describe('TokenRatesController', () => { tokenPricesService: buildMockTokenPricesService(), }); expect(controller.state).toStrictEqual({ - contractExchangeRates: {}, - contractExchangeRatesByChainId: {}, + marketData: {}, }); }); @@ -858,7 +857,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); + expect(controller.state.marketData).toStrictEqual({}); }); it('should clear contractExchangeRates state when chain ID changes', async () => { @@ -894,7 +893,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); + expect(controller.state.marketData).toStrictEqual({}); }); it('should not update exchange rates when network state changes without a ticker/chain id change', async () => { @@ -1043,7 +1042,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); + expect(controller.state.marketData).toStrictEqual({}); }); it('should clear contractExchangeRates state when chain ID changes', async () => { @@ -1078,7 +1077,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: 'AAAA-BBBB-CCCC-DDDD', }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); + expect(controller.state.marketData).toStrictEqual({}); }); }); }); @@ -1446,16 +1445,58 @@ describe('TokenRatesController', () => { controller.startPollingByNetworkClientId('mainnet'); await advanceTime({ clock, duration: 0 }); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - { + expect(controller.state).toStrictEqual({ + marketData: { '0x1': { - ETH: { - '0x02': 0.001, - '0x03': 0.002, + '0x02': { + currency: 'ETH', + priceChange1d: 0, + pricePercentChange1d: 0, + tokenAddress: '0x02', + value: 0.001, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: 0.001, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, + }, + '0x03': { + currency: 'ETH', + priceChange1d: 0, + pricePercentChange1d: 0, + tokenAddress: '0x03', + value: 0.002, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: 0.002, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, }, }, }, - ); + }); }); }); @@ -1514,17 +1555,57 @@ describe('TokenRatesController', () => { // downstream promises aren't flushed until the next advanceTime loop await advanceTime({ clock, duration: 1, stepSize: 1 / 3 }); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - { - '0x1': { - LOL: { - // token price in LOL = (token price in ETH) * (ETH value in LOL) - '0x02': 0.0005, - '0x03': 0.001, - }, + expect(controller.state.marketData).toStrictEqual({ + '0x1': { + // token price in LOL = (token price in ETH) * (ETH value in LOL) + '0x02': { + tokenAddress: '0x02', + value: 0.0005, + currency: 'ETH', + pricePercentChange1d: 0, + priceChange1d: 0, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: 0.001, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, + }, + '0x03': { + tokenAddress: '0x03', + value: 0.001, + currency: 'ETH', + pricePercentChange1d: 0, + priceChange1d: 0, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: 0.002, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, }, }, - ); + }); controller.stopAllPolling(); }); @@ -1580,13 +1661,9 @@ describe('TokenRatesController', () => { // downstream promises aren't flushed until the next advanceTime loop await advanceTime({ clock, duration: 1, stepSize: 1 / 3 }); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - { - '0x1': { - LOL: {}, - }, - }, - ); + expect(controller.state.marketData).toStrictEqual({ + '0x1': {}, + }); controller.stopAllPolling(); }); }); @@ -1680,10 +1757,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: InfuraNetworkType.mainnet, }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - {}, - ); + expect(controller.state.marketData).toStrictEqual({}); }, ); }); @@ -1726,10 +1800,13 @@ describe('TokenRatesController', () => { selectedNetworkClientId: InfuraNetworkType.mainnet, }); - expect(controller.state.contractExchangeRates).toStrictEqual({}); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - {}, - ); + expect(controller.state).toStrictEqual({ + marketData: { + '0x1': { + '0x0000000000000000000000000000000000000000': { currency: 'ETH' }, + }, + }, + }); }); }); @@ -1767,10 +1844,7 @@ describe('TokenRatesController', () => { selectedNetworkClientId: InfuraNetworkType.mainnet, }), ).rejects.toThrow('Failed to fetch'); - expect(controller.state.contractExchangeRates).toStrictEqual({}); - expect(controller.state.contractExchangeRatesByChainId).toStrictEqual( - {}, - ); + expect(controller.state.marketData).toStrictEqual({}); }, ); }); @@ -1882,20 +1956,22 @@ describe('TokenRatesController', () => { }); expect(controller.state).toMatchInlineSnapshot(` - Object { - "contractExchangeRates": Object { - "0x0000000000000000000000000000000000000001": 0.001, - "0x0000000000000000000000000000000000000002": 0.002, - }, - "contractExchangeRatesByChainId": Object { - "0x1": Object { - "ETH": Object { - "0x0000000000000000000000000000000000000001": 0.001, - "0x0000000000000000000000000000000000000002": 0.002, - }, + Object { + "marketData": Object { + "0x1": Object { + "0x0000000000000000000000000000000000000001": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000001", + "value": 0.001, + }, + "0x0000000000000000000000000000000000000002": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000002", + "value": 0.002, }, }, - } + }, + } `); }, ); @@ -1952,17 +2028,22 @@ describe('TokenRatesController', () => { }); expect(controller.state).toMatchInlineSnapshot(` - Object { - "contractExchangeRates": Object {}, - "contractExchangeRatesByChainId": Object { - "0x2": Object { - "ETH": Object { - "0x0000000000000000000000000000000000000001": 0.001, - "0x0000000000000000000000000000000000000002": 0.002, - }, + Object { + "marketData": Object { + "0x2": Object { + "0x0000000000000000000000000000000000000001": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000001", + "value": 0.001, + }, + "0x0000000000000000000000000000000000000002": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000002", + "value": 0.002, }, }, - } + }, + } `); }, ); @@ -2046,20 +2127,22 @@ describe('TokenRatesController', () => { // token value in terms of matic should be (token value in eth) * (eth value in matic) expect(controller.state).toMatchInlineSnapshot(` - Object { - "contractExchangeRates": Object { - "0x0000000000000000000000000000000000000001": 0.0005, - "0x0000000000000000000000000000000000000002": 0.001, - }, - "contractExchangeRatesByChainId": Object { - "0x89": Object { - "UNSUPPORTED": Object { - "0x0000000000000000000000000000000000000001": 0.0005, - "0x0000000000000000000000000000000000000002": 0.001, - }, + Object { + "marketData": Object { + "0x89": Object { + "0x0000000000000000000000000000000000000001": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000001", + "value": 0.0005, + }, + "0x0000000000000000000000000000000000000002": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000002", + "value": 0.001, }, }, - } + }, + } `); }, ); @@ -2206,20 +2289,14 @@ describe('TokenRatesController', () => { }); expect(controller.state).toMatchInlineSnapshot(` - Object { - "contractExchangeRates": Object { + Object { + "marketData": Object { + "0x3e7": Object { "0x0000000000000000000000000000000000000001": undefined, "0x0000000000000000000000000000000000000002": undefined, }, - "contractExchangeRatesByChainId": Object { - "0x3e7": Object { - "TST": Object { - "0x0000000000000000000000000000000000000001": undefined, - "0x0000000000000000000000000000000000000002": undefined, - }, - }, - }, - } + }, + } `); }, ); @@ -2279,21 +2356,24 @@ describe('TokenRatesController', () => { await Promise.all([updateExchangeRates(), updateExchangeRates()]); expect(fetchTokenPricesMock).toHaveBeenCalledTimes(1); + expect(controller.state).toMatchInlineSnapshot(` - Object { - "contractExchangeRates": Object { - "0x0000000000000000000000000000000000000001": 0.001, - "0x0000000000000000000000000000000000000002": 0.002, - }, - "contractExchangeRatesByChainId": Object { - "0x1": Object { - "ETH": Object { - "0x0000000000000000000000000000000000000001": 0.001, - "0x0000000000000000000000000000000000000002": 0.002, - }, + Object { + "marketData": Object { + "0x1": Object { + "0x0000000000000000000000000000000000000001": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000001", + "value": 0.001, + }, + "0x0000000000000000000000000000000000000002": Object { + "currency": "ETH", + "tokenAddress": "0x0000000000000000000000000000000000000002", + "value": 0.002, }, }, - } + }, + } `); }, ); @@ -2540,6 +2620,24 @@ async function fetchTokenPricesWithIncreasingPriceForEachToken< tokenAddress, value: (i + 1) / 1000, currency, + pricePercentChange1d: 0, + priceChange1d: 0, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: (i + 1) / 1000, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, }; return { ...obj, diff --git a/packages/assets-controllers/src/TokenRatesController.ts b/packages/assets-controllers/src/TokenRatesController.ts index a564e8b5a0..7d07b46d62 100644 --- a/packages/assets-controllers/src/TokenRatesController.ts +++ b/packages/assets-controllers/src/TokenRatesController.ts @@ -18,6 +18,7 @@ import { isEqual } from 'lodash'; import { reduceInBatchesSerially, TOKEN_PRICES_BATCH_SIZE } from './assetsUtil'; import { fetchExchangeRate as fetchNativeCurrencyExchangeRate } from './crypto-compare-service'; import type { AbstractTokenPricesService } from './token-prices-service/abstract-token-prices-service'; +import { ZERO_ADDRESS } from './token-prices-service/codefi-v2'; import type { TokensState } from './TokensController'; /** @@ -73,6 +74,32 @@ export interface ContractExchangeRates { [address: string]: number | undefined; } +type MarketDataDetails = { + tokenAddress: `0x${string}`; + value: number; + currency: string; + allTimeHigh: number; + allTimeLow: number; + circulatingSupply: number; + dilutedMarketCap: number; + high1d: number; + low1d: number; + marketCap: number; + marketCapPercentChange1d: number; + price: number; + priceChange1d: number; + pricePercentChange1d: number; + pricePercentChange1h: number; + pricePercentChange1y: number; + pricePercentChange7d: number; + pricePercentChange14d: number; + pricePercentChange30d: number; + pricePercentChange200d: number; + totalVolume: number; +}; + +export type ContractMarketData = Record; + enum PollState { Active = 'Active', Inactive = 'Inactive', @@ -82,18 +109,13 @@ enum PollState { * @type TokenRatesState * * Token rates controller state - * @property contractExchangeRates - Hash of token contract addresses to exchange rates (single globally selected chain, will be deprecated soon) - * @property contractExchangeRatesByChainId - Hash of token contract addresses to exchange rates keyed by chain ID and native currency (ticker) + * @property marketData - Market data for tokens, keyed by chain ID and then token contract address. */ // This interface was created before this ESLint rule was added. // Convert to a `type` in a future major version. // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export interface TokenRatesState extends BaseState { - contractExchangeRates: ContractExchangeRates; - contractExchangeRatesByChainId: Record< - Hex, - Record - >; + marketData: Record>; } /** @@ -219,8 +241,7 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< }; this.defaultState = { - contractExchangeRates: {}, - contractExchangeRatesByChainId: {}, + marketData: {}, }; this.initialize(); this.setIntervalLength(interval); @@ -264,7 +285,7 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< this.config.chainId !== chainId || this.config.nativeCurrency !== ticker ) { - this.update({ contractExchangeRates: {} }); + this.update({ ...this.defaultState }); this.configure({ chainId, nativeCurrency: ticker }); if (this.#pollState === PollState.Active) { await this.updateExchangeRates(); @@ -363,9 +384,6 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< } const tokenAddresses = this.#getTokenAddresses(chainId); - if (tokenAddresses.length === 0) { - return; - } const updateKey: `${Hex}:${string}` = `${chainId}:${nativeCurrency}`; if (updateKey in this.#inProcessExchangeRateUpdates) { @@ -384,35 +402,20 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< this.#inProcessExchangeRateUpdates[updateKey] = inProgressUpdate; try { - const newContractExchangeRates = await this.#fetchAndMapExchangeRates({ + const contractInformations = await this.#fetchAndMapExchangeRates({ tokenAddresses, chainId, nativeCurrency, }); - const existingContractExchangeRates = this.state.contractExchangeRates; - const updatedContractExchangeRates = - chainId === this.config.chainId && - nativeCurrency === this.config.nativeCurrency - ? newContractExchangeRates - : existingContractExchangeRates; - - const existingContractExchangeRatesForChainId = - this.state.contractExchangeRatesByChainId[chainId] ?? {}; - const updatedContractExchangeRatesForChainId = { - ...this.state.contractExchangeRatesByChainId, + const marketData = { [chainId]: { - ...existingContractExchangeRatesForChainId, - [nativeCurrency]: { - ...existingContractExchangeRatesForChainId[nativeCurrency], - ...newContractExchangeRates, - }, + ...(contractInformations ?? {}), }, }; this.update({ - contractExchangeRates: updatedContractExchangeRates, - contractExchangeRatesByChainId: updatedContractExchangeRatesForChainId, + marketData, }); updateSucceeded(); } catch (error: unknown) { @@ -451,13 +454,15 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< tokenAddresses: Hex[]; chainId: Hex; nativeCurrency: string; - }): Promise { + }): Promise { if (!this.#tokenPricesService.validateChainIdSupported(chainId)) { return tokenAddresses.reduce((obj, tokenAddress) => { - return { + obj = { ...obj, [tokenAddress]: undefined, }; + + return obj; }, {}); } @@ -468,7 +473,6 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< nativeCurrency, }); } - return await this.#fetchAndMapExchangeRatesForUnsupportedNativeCurrency({ tokenAddresses, nativeCurrency, @@ -509,7 +513,8 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< tokenAddresses: Hex[]; chainId: Hex; nativeCurrency: string; - }): Promise { + }): Promise { + let contractNativeInformations; const tokenPricesByTokenAddress = await reduceInBatchesSerially< Hex, Awaited> @@ -531,13 +536,32 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< }, initialResult: {}, }); + contractNativeInformations = tokenPricesByTokenAddress; - return Object.entries(tokenPricesByTokenAddress).reduce( - (obj, [tokenAddress, tokenPrice]) => { - return { + // fetch for native token + if (tokenAddresses.length === 0) { + const contractNativeInformationsNative = + await this.#tokenPricesService.fetchTokenPrices({ + tokenAddresses: [], + chainId, + currency: nativeCurrency, + }); + + contractNativeInformations = { + [ZERO_ADDRESS]: { + currency: nativeCurrency, + ...contractNativeInformationsNative[ZERO_ADDRESS], + }, + }; + } + return Object.entries(contractNativeInformations).reduce( + (obj, [tokenAddress, token]) => { + obj = { ...obj, - [tokenAddress]: tokenPrice?.value, + [tokenAddress.toLowerCase()]: { ...token }, }; + + return obj; }, {}, ); @@ -561,9 +585,9 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< }: { tokenAddresses: Hex[]; nativeCurrency: string; - }): Promise { + }): Promise { const [ - contractExchangeRates, + contractExchangeInformations, fallbackCurrencyToNativeCurrencyConversionRate, ] = await Promise.all([ this.#fetchAndMapExchangeRatesForSupportedNativeCurrency({ @@ -581,17 +605,22 @@ export class TokenRatesController extends StaticIntervalPollingControllerV1< return {}; } - return Object.entries(contractExchangeRates).reduce( - (obj, [tokenAddress, tokenValue]) => { - return { - ...obj, - [tokenAddress]: tokenValue - ? tokenValue * fallbackCurrencyToNativeCurrencyConversionRate + const updatedContractExchangeRates = Object.entries( + contractExchangeInformations, + ).reduce((acc, [tokenAddress, token]) => { + acc = { + ...acc, + [tokenAddress]: { + ...token, + value: token.value + ? token.value * fallbackCurrencyToNativeCurrencyConversionRate : undefined, - }; - }, - {}, - ); + }, + }; + return acc; + }, {}); + + return updatedContractExchangeRates; } } diff --git a/packages/assets-controllers/src/assetsUtil.test.ts b/packages/assets-controllers/src/assetsUtil.test.ts index 6fb13a06bb..6ec057f88d 100644 --- a/packages/assets-controllers/src/assetsUtil.test.ts +++ b/packages/assets-controllers/src/assetsUtil.test.ts @@ -512,6 +512,24 @@ describe('assetsUtil', () => { tokenAddress: testTokenAddress, value: 0.0004588648479937523, currency: testNativeCurrency, + allTimeHigh: 4000, + allTimeLow: 900, + circulatingSupply: 2000, + dilutedMarketCap: 100, + high1d: 200, + low1d: 100, + marketCap: 1000, + marketCapPercentChange1d: 100, + price: 0.0004588648479937523, + pricePercentChange14d: 100, + pricePercentChange1h: 1, + pricePercentChange1y: 200, + pricePercentChange200d: 300, + pricePercentChange30d: 200, + pricePercentChange7d: 100, + totalVolume: 100, + priceChange1d: 100, + pricePercentChange1d: 100, }, }); diff --git a/packages/assets-controllers/src/token-prices-service/abstract-token-prices-service.ts b/packages/assets-controllers/src/token-prices-service/abstract-token-prices-service.ts index 8fb3e17ff9..c4dca6f9d6 100644 --- a/packages/assets-controllers/src/token-prices-service/abstract-token-prices-service.ts +++ b/packages/assets-controllers/src/token-prices-service/abstract-token-prices-service.ts @@ -7,6 +7,24 @@ export type TokenPrice = { tokenAddress: TokenAddress; value: number; currency: Currency; + allTimeHigh: number; + allTimeLow: number; + circulatingSupply: number; + dilutedMarketCap: number; + high1d: number; + low1d: number; + marketCap: number; + marketCapPercentChange1d: number; + price: number; + priceChange1d: number; + pricePercentChange1d: number; + pricePercentChange1h: number; + pricePercentChange1y: number; + pricePercentChange7d: number; + pricePercentChange14d: number; + pricePercentChange30d: number; + pricePercentChange200d: number; + totalVolume: number; }; /** diff --git a/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts b/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts index 510b837922..7660277bc3 100644 --- a/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts +++ b/packages/assets-controllers/src/token-prices-service/codefi-v2.test.ts @@ -17,43 +17,197 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); - const pricedTokensByAddress = + const marketDataTokensByAddress = await new CodefiTokenPricesServiceV2().fetchTokenPrices({ chainId: '0x1', tokenAddresses: ['0xAAA', '0xBBB', '0xCCC'], currency: 'ETH', }); - expect(pricedTokensByAddress).toStrictEqual({ + expect(marketDataTokensByAddress).toStrictEqual({ + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + value: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 14, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xAAA': { tokenAddress: '0xAAA', value: 148.17205755299946, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.17205755299946, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xBBB': { tokenAddress: '0xBBB', value: 33689.98134554716, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 33689.98134554716, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xCCC': { tokenAddress: '0xCCC', value: 148.1344197578456, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.1344197578456, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); }); @@ -62,15 +216,74 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); @@ -80,15 +293,74 @@ describe('CodefiTokenPricesServiceV2', () => { currency: 'ETH', }); expect(result).toStrictEqual({ + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + value: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 14, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xBBB': { tokenAddress: '0xBBB', value: 33689.98134554716, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 33689.98134554716, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xCCC': { tokenAddress: '0xCCC', value: 148.1344197578456, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.1344197578456, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); }); @@ -97,16 +369,52 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { '0xaaa': {}, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); @@ -117,15 +425,56 @@ describe('CodefiTokenPricesServiceV2', () => { }); expect(result).toStrictEqual({ + '0xAAA': { + currency: 'ETH', + tokenAddress: '0xAAA', + value: undefined, + }, '0xBBB': { tokenAddress: '0xBBB', value: 33689.98134554716, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 33689.98134554716, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xCCC': { tokenAddress: '0xCCC', value: 148.1344197578456, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.1344197578456, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); }); @@ -134,8 +483,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .replyWithError('Failed to fetch') .persist(); @@ -154,8 +505,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(1 + retries) .replyWithError('Failed to fetch'); @@ -175,8 +528,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(retries) .replyWithError('Failed to fetch'); @@ -184,22 +539,99 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); - const pricedTokensByAddress = await new CodefiTokenPricesServiceV2({ + const marketDataTokensByAddress = await new CodefiTokenPricesServiceV2({ retries, }).fetchTokenPrices({ chainId: '0x1', @@ -207,21 +639,98 @@ describe('CodefiTokenPricesServiceV2', () => { currency: 'ETH', }); - expect(pricedTokensByAddress).toStrictEqual({ + expect(marketDataTokensByAddress).toStrictEqual({ + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + value: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 14, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xAAA': { tokenAddress: '0xAAA', value: 148.17205755299946, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.17205755299946, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xBBB': { tokenAddress: '0xBBB', value: 33689.98134554716, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 33689.98134554716, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xCCC': { tokenAddress: '0xCCC', value: 148.1344197578456, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.1344197578456, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); }); @@ -242,19 +751,96 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .delay(degradedThreshold / 2) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); const onDegradedHandler = jest.fn(); @@ -281,27 +867,46 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .replyWithError('Failed to fetch'); // Second interceptor for successful response nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .delay(500) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, }); const onDegradedHandler = jest.fn(); @@ -330,8 +935,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .replyWithError('Failed to fetch'); const onDegradedHandler = jest.fn(); @@ -362,19 +969,36 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .delay(degradedThreshold * 2) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, }); const onDegradedHandler = jest.fn(); @@ -405,27 +1029,46 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .replyWithError('Failed to fetch'); // Second interceptor for successful response nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .delay(degradedThreshold * 2) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, }, }); const onDegradedHandler = jest.fn(); @@ -469,8 +1112,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(maximumConsecutiveFailures) .replyWithError('Failed to fetch'); @@ -478,18 +1123,95 @@ describe('CodefiTokenPricesServiceV2', () => { const successfullCallScope = nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); const service = new CodefiTokenPricesServiceV2({ @@ -538,8 +1260,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(maximumConsecutiveFailures) .replyWithError('Failed to fetch'); @@ -547,18 +1271,95 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); const onBreakHandler = jest.fn(); @@ -602,8 +1403,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(maximumConsecutiveFailures) .replyWithError('Failed to fetch'); @@ -666,8 +1469,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) // The +1 is for the additional request when the circuit is half-open .times(maximumConsecutiveFailures + 1) @@ -680,14 +1485,89 @@ describe('CodefiTokenPricesServiceV2', () => { vsCurrency: 'ETH', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); const service = new CodefiTokenPricesServiceV2({ @@ -762,8 +1642,10 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .times(maximumConsecutiveFailures) .replyWithError('Failed to fetch'); @@ -771,18 +1653,95 @@ describe('CodefiTokenPricesServiceV2', () => { nock('https://price.api.cx.metamask.io') .get('/v2/chains/1/spot-prices') .query({ - tokenAddresses: '0xAAA,0xBBB,0xCCC', + tokenAddresses: + '0x0000000000000000000000000000000000000000,0xAAA,0xBBB,0xCCC', vsCurrency: 'ETH', + includeMarketData: 'true', }) .reply(200, { + '0x0000000000000000000000000000000000000000': { + price: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xaaa': { - eth: 148.17205755299946, + price: 148.17205755299946, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xbbb': { - eth: 33689.98134554716, + price: 33689.98134554716, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xccc': { - eth: 148.1344197578456, + price: 148.1344197578456, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); const service = new CodefiTokenPricesServiceV2({ @@ -821,27 +1780,104 @@ describe('CodefiTokenPricesServiceV2', () => { // Wait for circuit to move to half-open await clock.tickAsync(circuitBreakDuration); - const pricedTokensByAddress = await fetchTokenPricesWithFakeTimers({ + const marketDataTokensByAddress = await fetchTokenPricesWithFakeTimers({ clock, fetchTokenPrices, retries, }); - expect(pricedTokensByAddress).toStrictEqual({ + expect(marketDataTokensByAddress).toStrictEqual({ + '0x0000000000000000000000000000000000000000': { + tokenAddress: '0x0000000000000000000000000000000000000000', + value: 14, + currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 14, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, + }, '0xAAA': { tokenAddress: '0xAAA', value: 148.17205755299946, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.17205755299946, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xBBB': { tokenAddress: '0xBBB', value: 33689.98134554716, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 33689.98134554716, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, '0xCCC': { tokenAddress: '0xCCC', value: 148.1344197578456, currency: 'ETH', + pricePercentChange1d: 1, + priceChange1d: 1, + marketCap: 117219.99428314982, + allTimeHigh: 0.00060467892389492, + allTimeLow: 0.00002303954000865728, + totalVolume: 5155.094053542448, + high1d: 0.00008020715848194385, + low1d: 0.00007792083564549064, + price: 148.1344197578456, + circulatingSupply: 1494269733.9526057, + dilutedMarketCap: 117669.5125951733, + marketCapPercentChange1d: 0.76671, + pricePercentChange1h: -1.0736342953259423, + pricePercentChange7d: -7.351582573655089, + pricePercentChange14d: -1.0799098946709822, + pricePercentChange30d: -25.776321124365992, + pricePercentChange200d: 46.091571238599165, + pricePercentChange1y: -2.2992517267242754, }, }); }); diff --git a/packages/assets-controllers/src/token-prices-service/codefi-v2.ts b/packages/assets-controllers/src/token-prices-service/codefi-v2.ts index 39b403615b..0ffcaaa1f3 100644 --- a/packages/assets-controllers/src/token-prices-service/codefi-v2.ts +++ b/packages/assets-controllers/src/token-prices-service/codefi-v2.ts @@ -18,14 +18,6 @@ import type { TokenPricesByTokenAddress, } from './abstract-token-prices-service'; -/** - * The shape of the data that the /spot-prices endpoint returns. - */ -type SpotPricesEndpointData< - TokenAddress extends Hex, - Currency extends string, -> = Record>; - /** * The list of currencies that can be supplied as the `vsCurrency` parameter to * the `/spot-prices` endpoint, in lowercase form. @@ -155,6 +147,15 @@ export const SUPPORTED_CURRENCIES = [ 'sats', ] as const; +/** + * Represents the zero address, commonly used as a placeholder in blockchain transactions. + * In the context of fetching market data, the zero address is utilized to retrieve information + * specifically for native currencies. This allows for a standardized approach to query market + * data for blockchain-native assets without a specific contract address. + */ +export const ZERO_ADDRESS: Hex = + '0x0000000000000000000000000000000000000000' as const; + /** * A currency that can be supplied as the `vsCurrency` parameter to * the `/spot-prices` endpoint. Covers both uppercase and lowercase versions. @@ -257,6 +258,85 @@ const DEFAULT_TOKEN_PRICE_MAX_CONSECUTIVE_FAILURES = const DEFAULT_DEGRADED_THRESHOLD = 5_000; +/** + * The shape of the data that the /spot-prices endpoint returns. + */ +type MarketData = { + /** + * The all-time highest price of the token. + */ + allTimeHigh: number; + /** + * The all-time lowest price of the token. + */ + allTimeLow: number; + /** + * The number of tokens currently in circulation. + */ + circulatingSupply: number; + /** + * The market cap calculated using the diluted supply. + */ + dilutedMarketCap: number; + /** + * The highest price of the token in the last 24 hours. + */ + high1d: number; + /** + * The lowest price of the token in the last 24 hours. + */ + low1d: number; + /** + * The current market capitalization of the token. + */ + marketCap: number; + /** + * The percentage change in market capitalization over the last 24 hours. + */ + marketCapPercentChange1d: number; + /** + * The current price of the token. + */ + price: number; + /** + * The absolute change in price over the last 24 hours. + */ + priceChange1d: number; + /** + * The percentage change in price over the last 24 hours. + */ + pricePercentChange1d: number; + /** + * The percentage change in price over the last hour. + */ + pricePercentChange1h: number; + /** + * The percentage change in price over the last year. + */ + pricePercentChange1y: number; + /** + * The percentage change in price over the last 7 days. + */ + pricePercentChange7d: number; + /** + * The percentage change in price over the last 14 days. + */ + pricePercentChange14d: number; + /** + * The percentage change in price over the last 30 days. + */ + pricePercentChange30d: number; + /** + * The percentage change in price over the last 200 days. + */ + pricePercentChange200d: number; + /** + * The total trading volume of the token in the last 24 hours. + */ + totalVolume: number; +}; + +type MarketDataByTokenAddress = { [address: Hex]: MarketData }; /** * This version of the token prices service uses V2 of the Codefi Price API to * fetch token prices. @@ -351,17 +431,19 @@ export class CodefiTokenPricesServiceV2 const chainIdAsNumber = hexToNumber(chainId); const url = new URL(`${BASE_URL}/chains/${chainIdAsNumber}/spot-prices`); - url.searchParams.append('tokenAddresses', tokenAddresses.join(',')); + url.searchParams.append( + 'tokenAddresses', + [ZERO_ADDRESS, ...tokenAddresses].join(','), + ); url.searchParams.append('vsCurrency', currency); + url.searchParams.append('includeMarketData', 'true'); - const pricesByCurrencyByTokenAddress: SpotPricesEndpointData< - Lowercase, - Lowercase - > = await this.#tokenPricePolicy.execute(() => - handleFetch(url, { headers: { 'Cache-Control': 'no-cache' } }), - ); + const addressCryptoDataMap: MarketDataByTokenAddress = + await this.#tokenPricePolicy.execute(() => + handleFetch(url, { headers: { 'Cache-Control': 'no-cache' } }), + ); - return tokenAddresses.reduce( + return [ZERO_ADDRESS, ...tokenAddresses].reduce( ( obj: Partial>, tokenAddress, @@ -370,32 +452,25 @@ export class CodefiTokenPricesServiceV2 // to keep track of them and make sure we return the original versions. const lowercasedTokenAddress = tokenAddress.toLowerCase() as Lowercase; - const lowercasedCurrency = - currency.toLowerCase() as Lowercase; - const price = - pricesByCurrencyByTokenAddress[lowercasedTokenAddress]?.[ - lowercasedCurrency - ]; + const marketData = addressCryptoDataMap[lowercasedTokenAddress]; - if (!price) { - // console error instead of throwing to not interrupt the fetching of other tokens in case just one fails - console.error( - `Could not find price for "${tokenAddress}" in "${currency}"`, - ); + if (marketData === undefined) { + return obj; } - const tokenPrice: TokenPrice = { + const { price } = marketData; + + const token: TokenPrice = { tokenAddress, value: price, currency, + ...marketData, }; return { ...obj, - ...(tokenPrice.value !== undefined - ? { [tokenAddress]: tokenPrice } - : {}), + [tokenAddress]: token, }; }, {}, From 6cbaa1c28e3f0847bc1599b9614f7989ae7ac212 Mon Sep 17 00:00:00 2001 From: Monte Lai Date: Wed, 29 May 2024 17:28:16 +0800 Subject: [PATCH 2/3] fix: accounts controller type error (#4331) ## Explanation This PR is a temp fix for the type error `Type instantiation is excessively deep and possibly infinite.` when updating the state. ## References Related to: https://github.com/MetaMask/utils/issues/168 ## Changelog ### `@metamask/accounts-controller` - **FIXED**: Type error during state update ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [ ] I've highlighted breaking changes using the "BREAKING" category above as appropriate --- .../src/AccountsController.test.ts | 32 +++++++------- .../src/AccountsController.ts | 44 +++++++++++++------ packages/accounts-controller/src/utils.ts | 20 +++++++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/packages/accounts-controller/src/AccountsController.test.ts b/packages/accounts-controller/src/AccountsController.test.ts index c76273219d..270274973e 100644 --- a/packages/accounts-controller/src/AccountsController.test.ts +++ b/packages/accounts-controller/src/AccountsController.test.ts @@ -172,9 +172,7 @@ function createExpectedInternalAccount({ name, keyring: { type: keyringType }, importTime: expect.any(Number), - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - lastSelected: undefined, + lastSelected: expect.any(Number), }, }; @@ -739,17 +737,15 @@ describe('AccountsController', () => { const accounts = accountsController.listAccounts(); - expect(accounts).toStrictEqual([ + expect(accounts.map(setLastSelectedAsAny)).toStrictEqual([ mockAccount, mockAccount2WithCustomName, - setLastSelectedAsAny( - createExpectedInternalAccount({ - id: 'mock-id3', - name: 'Account 3', - address: mockAccount3.address, - keyringType: KeyringTypes.hd, - }), - ), + createExpectedInternalAccount({ + id: 'mock-id3', + name: 'Account 3', + address: mockAccount3.address, + keyringType: KeyringTypes.hd, + }), ]); }); @@ -1222,7 +1218,7 @@ describe('AccountsController', () => { metadata: { ...mockSnapAccount.metadata, name: 'Snap Account 1', - lastSelected: undefined, + lastSelected: expect.any(Number), importTime: expect.any(Number), }, }; @@ -1232,7 +1228,7 @@ describe('AccountsController', () => { metadata: { ...mockSnapAccount2.metadata, name: 'Snap Account 2', - lastSelected: undefined, + lastSelected: expect.any(Number), importTime: expect.any(Number), }, }; @@ -1241,7 +1237,9 @@ describe('AccountsController', () => { await accountsController.updateAccounts(); - expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); + expect( + accountsController.listAccounts().map(setLastSelectedAsAny), + ).toStrictEqual(expectedAccounts); }); it('should return an empty array if the snap keyring is not defined', async () => { @@ -1485,7 +1483,9 @@ describe('AccountsController', () => { await accountsController.updateAccounts(); - expect(accountsController.listAccounts()).toStrictEqual(expectedAccounts); + expect( + accountsController.listAccounts().map(setLastSelectedAsAny), + ).toStrictEqual(expectedAccounts); }); it('should throw an error if the keyring type is unknown', async () => { diff --git a/packages/accounts-controller/src/AccountsController.ts b/packages/accounts-controller/src/AccountsController.ts index 49413d63d3..8fec7bc333 100644 --- a/packages/accounts-controller/src/AccountsController.ts +++ b/packages/accounts-controller/src/AccountsController.ts @@ -25,6 +25,7 @@ import type { Keyring, Json } from '@metamask/utils'; import type { Draft } from 'immer'; import { + deepCloneDraft, getUUIDFromAddressOfNormalAccount, isNormalKeyringType, keyringTypeToName, @@ -312,7 +313,12 @@ export class AccountsController extends BaseController< ...account, metadata: { ...account.metadata, name: accountName }, }; - currentState.internalAccounts.accounts[accountId] = internalAccount; + // FIXME: deep clone of old state to get around Type instantiation is excessively deep and possibly infinite. + const newState = deepCloneDraft(currentState); + + newState.internalAccounts.accounts[accountId] = internalAccount; + + return newState; }); } @@ -357,10 +363,11 @@ export class AccountsController extends BaseController< importTime: this.#populateExistingMetadata(existingAccount?.id, 'importTime') ?? Date.now(), - lastSelected: this.#populateExistingMetadata( - existingAccount?.id, - 'lastSelected', - ), + lastSelected: + this.#populateExistingMetadata( + existingAccount?.id, + 'lastSelected', + ) ?? 0, }, }; @@ -368,8 +375,12 @@ export class AccountsController extends BaseController< }, {} as Record); this.update((currentState: Draft) => { - (currentState as AccountsControllerState).internalAccounts.accounts = - accounts; + // FIXME: deep clone of old state to get around Type instantiation is excessively deep and possibly infinite. + const newState = deepCloneDraft(currentState); + + newState.internalAccounts.accounts = accounts; + + return newState; }); } @@ -381,8 +392,12 @@ export class AccountsController extends BaseController< loadBackup(backup: AccountsControllerState): void { if (backup.internalAccounts) { this.update((currentState: Draft) => { - (currentState as AccountsControllerState).internalAccounts = - backup.internalAccounts; + // FIXME: deep clone of old state to get around Type instantiation is excessively deep and possibly infinite. + const newState = deepCloneDraft(currentState); + + newState.internalAccounts = backup.internalAccounts; + + return newState; }); } } @@ -483,7 +498,7 @@ export class AccountsController extends BaseController< name: this.#populateExistingMetadata(id, 'name') ?? '', importTime: this.#populateExistingMetadata(id, 'importTime') ?? Date.now(), - lastSelected: this.#populateExistingMetadata(id, 'lastSelected'), + lastSelected: this.#populateExistingMetadata(id, 'lastSelected') ?? 0, keyring: { type: (keyring as Keyring).type, }, @@ -765,9 +780,10 @@ export class AccountsController extends BaseController< ); this.update((currentState: Draft) => { - (currentState as AccountsControllerState).internalAccounts.accounts[ - newAccount.id - ] = { + // FIXME: deep clone of old state to get around Type instantiation is excessively deep and possibly infinite. + const newState = deepCloneDraft(currentState); + + newState.internalAccounts.accounts[newAccount.id] = { ...newAccount, metadata: { ...newAccount.metadata, @@ -776,6 +792,8 @@ export class AccountsController extends BaseController< lastSelected: Date.now(), }, }; + + return newState; }); this.setSelectedAccount(newAccount.id); diff --git a/packages/accounts-controller/src/utils.ts b/packages/accounts-controller/src/utils.ts index d3cb5aede2..458523c1f5 100644 --- a/packages/accounts-controller/src/utils.ts +++ b/packages/accounts-controller/src/utils.ts @@ -1,9 +1,13 @@ import { toBuffer } from '@ethereumjs/util'; import { isCustodyKeyring, KeyringTypes } from '@metamask/keyring-controller'; +import { deepClone } from '@metamask/snaps-utils'; import { sha256 } from 'ethereum-cryptography/sha256'; +import type { Draft } from 'immer'; import type { V4Options } from 'uuid'; import { v4 as uuid } from 'uuid'; +import type { AccountsControllerState } from './AccountsController'; + /** * Returns the name of the keyring type. * @@ -79,3 +83,19 @@ export function isNormalKeyringType(keyringType: KeyringTypes): boolean { // adapted later on if we have new kind of keyrings! return keyringType !== KeyringTypes.snap; } + +/** + * WARNING: To be removed once type issue is fixed. https://github.com/MetaMask/utils/issues/168 + * + * Creates a deep clone of the given object. + * This is to get around error `Type instantiation is excessively deep and possibly infinite.` + * + * @param obj - The object to be cloned. + * @returns The deep clone of the object. + */ +export function deepCloneDraft( + obj: Draft, +): AccountsControllerState { + // We use unknown here because the type inference when using structured clone leads to the same type error. + return deepClone(obj) as unknown as AccountsControllerState; +} From 85832f4fc1241c741c80725552104b23c203a1d9 Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Wed, 29 May 2024 20:16:31 +0900 Subject: [PATCH 3/3] Release/156.0.0 (#4332) --- package.json | 2 +- packages/assets-controllers/package.json | 4 +- packages/ens-controller/package.json | 4 +- packages/gas-fee-controller/package.json | 4 +- packages/network-controller/CHANGELOG.md | 9 ++++- packages/network-controller/package.json | 2 +- packages/polling-controller/package.json | 4 +- .../queued-request-controller/package.json | 4 +- .../selected-network-controller/package.json | 4 +- packages/transaction-controller/CHANGELOG.md | 10 ++++- packages/transaction-controller/package.json | 6 +-- .../user-operation-controller/package.json | 8 ++-- yarn.lock | 40 +++++++++---------- 13 files changed, 58 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index a98e5f24ca..6520612e7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/core-monorepo", - "version": "155.0.0", + "version": "156.0.0", "private": true, "description": "Monorepo for packages shared between MetaMask clients", "repository": { diff --git a/packages/assets-controllers/package.json b/packages/assets-controllers/package.json index 62fa534e3b..ede0136cfb 100644 --- a/packages/assets-controllers/package.json +++ b/packages/assets-controllers/package.json @@ -55,7 +55,7 @@ "@metamask/eth-query": "^4.0.0", "@metamask/keyring-controller": "^16.0.0", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/polling-controller": "^6.0.2", "@metamask/preferences-controller": "^11.0.0", "@metamask/rpc-errors": "^6.2.1", @@ -91,7 +91,7 @@ "@metamask/accounts-controller": "^14.0.0", "@metamask/approval-controller": "^6.0.0", "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.0.0", + "@metamask/network-controller": "^18.1.2", "@metamask/preferences-controller": "^11.0.0" }, "engines": { diff --git a/packages/ens-controller/package.json b/packages/ens-controller/package.json index 91e4e191b8..1529da5fb1 100644 --- a/packages/ens-controller/package.json +++ b/packages/ens-controller/package.json @@ -49,7 +49,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", "jest": "^27.5.1", @@ -59,7 +59,7 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.0.0" + "@metamask/network-controller": "^18.1.2" }, "engines": { "node": ">=16.0.0" diff --git a/packages/gas-fee-controller/package.json b/packages/gas-fee-controller/package.json index 2bcb5ad3e4..461074006f 100644 --- a/packages/gas-fee-controller/package.json +++ b/packages/gas-fee-controller/package.json @@ -45,7 +45,7 @@ "@metamask/controller-utils": "^9.1.0", "@metamask/eth-query": "^4.0.0", "@metamask/ethjs-unit": "^0.3.0", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/polling-controller": "^6.0.2", "@metamask/utils": "^8.3.0", "@types/bn.js": "^5.1.5", @@ -67,7 +67,7 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.0.0" + "@metamask/network-controller": "^18.1.2" }, "engines": { "node": ">=16.0.0" diff --git a/packages/network-controller/CHANGELOG.md b/packages/network-controller/CHANGELOG.md index 2bda6ef0eb..1da5a057ef 100644 --- a/packages/network-controller/CHANGELOG.md +++ b/packages/network-controller/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [18.1.2] + +### Fixed + +- Update from `eth-block-tracker` to `@metamask/eth-block-tracker` `^9.0.2`, mitigating redundant polling loops ([#4309](https://github.com/MetaMask/core/pull/4309)) + ## [18.1.1] ### Added @@ -482,7 +488,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.1...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.2...HEAD +[18.1.2]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.1...@metamask/network-controller@18.1.2 [18.1.1]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.1.0...@metamask/network-controller@18.1.1 [18.1.0]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.0.1...@metamask/network-controller@18.1.0 [18.0.1]: https://github.com/MetaMask/core/compare/@metamask/network-controller@18.0.0...@metamask/network-controller@18.0.1 diff --git a/packages/network-controller/package.json b/packages/network-controller/package.json index d8b0cfa355..8e828dd185 100644 --- a/packages/network-controller/package.json +++ b/packages/network-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/network-controller", - "version": "18.1.1", + "version": "18.1.2", "description": "Provides an interface to the currently selected network via a MetaMask-compatible provider object", "keywords": [ "MetaMask", diff --git a/packages/polling-controller/package.json b/packages/polling-controller/package.json index 75cb9f48a4..9b7167968c 100644 --- a/packages/polling-controller/package.json +++ b/packages/polling-controller/package.json @@ -43,7 +43,7 @@ "dependencies": { "@metamask/base-controller": "^5.0.2", "@metamask/controller-utils": "^9.1.0", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/utils": "^8.3.0", "@types/uuid": "^8.3.0", "fast-json-stable-stringify": "^2.1.0", @@ -61,7 +61,7 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.0.0" + "@metamask/network-controller": "^18.1.2" }, "engines": { "node": ">=16.0.0" diff --git a/packages/queued-request-controller/package.json b/packages/queued-request-controller/package.json index 670c1dfa15..57ab804a1e 100644 --- a/packages/queued-request-controller/package.json +++ b/packages/queued-request-controller/package.json @@ -50,7 +50,7 @@ }, "devDependencies": { "@metamask/auto-changelog": "^3.4.4", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/selected-network-controller": "^13.0.0", "@types/jest": "^27.4.1", "deepmerge": "^4.2.2", @@ -65,7 +65,7 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.0.0", + "@metamask/network-controller": "^18.1.2", "@metamask/selected-network-controller": "^13.0.0" }, "engines": { diff --git a/packages/selected-network-controller/package.json b/packages/selected-network-controller/package.json index 9b067f86ff..8b2f273e41 100644 --- a/packages/selected-network-controller/package.json +++ b/packages/selected-network-controller/package.json @@ -43,7 +43,7 @@ "dependencies": { "@metamask/base-controller": "^5.0.2", "@metamask/json-rpc-engine": "^8.0.2", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/permission-controller": "^9.1.0", "@metamask/swappable-obj-proxy": "^2.2.0", "@metamask/utils": "^8.3.0" @@ -63,7 +63,7 @@ "typescript": "~4.9.5" }, "peerDependencies": { - "@metamask/network-controller": "^18.0.0", + "@metamask/network-controller": "^18.1.2", "@metamask/permission-controller": "^9.0.0" }, "engines": { diff --git a/packages/transaction-controller/CHANGELOG.md b/packages/transaction-controller/CHANGELOG.md index d73fae04a2..5d5a2005b8 100644 --- a/packages/transaction-controller/CHANGELOG.md +++ b/packages/transaction-controller/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [30.0.0] + +### Fixed + +- **BREAKING**: Update from `nonce-tracker@^3.0.0` to `@metamask/nonce-tracker@^5.0.0` to mitigate issue with redundant polling loops in block tracker. ([#4309](https://github.com/MetaMask/core/pull/4309)) + - The constructor now expects the `blockTracker` option being an instance of `@metamask/eth-block-tracker` instead of`eth-block-tracker`. + ## [29.1.0] ### Changed @@ -839,7 +846,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 All changes listed after this point were applied to this package following the monorepo conversion. -[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.1.0...HEAD +[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@30.0.0...HEAD +[30.0.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.1.0...@metamask/transaction-controller@30.0.0 [29.1.0]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.0.2...@metamask/transaction-controller@29.1.0 [29.0.2]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.0.1...@metamask/transaction-controller@29.0.2 [29.0.1]: https://github.com/MetaMask/core/compare/@metamask/transaction-controller@29.0.0...@metamask/transaction-controller@29.0.1 diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index 759f21333e..2689d3466e 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/transaction-controller", - "version": "29.1.0", + "version": "30.0.0", "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation", "keywords": [ "MetaMask", @@ -53,7 +53,7 @@ "@metamask/eth-query": "^4.0.0", "@metamask/gas-fee-controller": "^15.1.2", "@metamask/metamask-eth-abis": "^3.1.1", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/nonce-tracker": "^5.0.0", "@metamask/rpc-errors": "^6.2.1", "@metamask/utils": "^8.3.0", @@ -85,7 +85,7 @@ "@babel/runtime": "^7.23.9", "@metamask/approval-controller": "^6.0.0", "@metamask/gas-fee-controller": "^15.0.0", - "@metamask/network-controller": "^18.0.0" + "@metamask/network-controller": "^18.1.2" }, "engines": { "node": ">=16.0.0" diff --git a/packages/user-operation-controller/package.json b/packages/user-operation-controller/package.json index 5a691d2101..40bb1628a8 100644 --- a/packages/user-operation-controller/package.json +++ b/packages/user-operation-controller/package.json @@ -48,10 +48,10 @@ "@metamask/eth-query": "^4.0.0", "@metamask/gas-fee-controller": "^15.1.2", "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.1.1", + "@metamask/network-controller": "^18.1.2", "@metamask/polling-controller": "^6.0.2", "@metamask/rpc-errors": "^6.2.1", - "@metamask/transaction-controller": "^29.1.0", + "@metamask/transaction-controller": "^30.0.0", "@metamask/utils": "^8.3.0", "bn.js": "^5.2.1", "immer": "^9.0.6", @@ -73,8 +73,8 @@ "@metamask/approval-controller": "^6.0.0", "@metamask/gas-fee-controller": "^15.0.0", "@metamask/keyring-controller": "^16.0.0", - "@metamask/network-controller": "^18.0.0", - "@metamask/transaction-controller": "^29.0.0" + "@metamask/network-controller": "^18.1.2", + "@metamask/transaction-controller": "^30.0.0" }, "engines": { "node": ">=16.0.0" diff --git a/yarn.lock b/yarn.lock index 0a490afe69..a6da8e93ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1726,7 +1726,7 @@ __metadata: "@metamask/keyring-api": ^6.1.1 "@metamask/keyring-controller": ^16.0.0 "@metamask/metamask-eth-abis": ^3.1.1 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/polling-controller": ^6.0.2 "@metamask/preferences-controller": ^11.0.0 "@metamask/rpc-errors": ^6.2.1 @@ -1756,7 +1756,7 @@ __metadata: "@metamask/accounts-controller": ^14.0.0 "@metamask/approval-controller": ^6.0.0 "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 "@metamask/preferences-controller": ^11.0.0 languageName: unknown linkType: soft @@ -2000,7 +2000,7 @@ __metadata: "@metamask/auto-changelog": ^3.4.4 "@metamask/base-controller": ^5.0.2 "@metamask/controller-utils": ^9.1.0 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 deepmerge: ^4.2.2 @@ -2011,7 +2011,7 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 languageName: unknown linkType: soft @@ -2313,7 +2313,7 @@ __metadata: "@metamask/controller-utils": ^9.1.0 "@metamask/eth-query": ^4.0.0 "@metamask/ethjs-unit": ^0.3.0 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/polling-controller": ^6.0.2 "@metamask/utils": ^8.3.0 "@types/bn.js": ^5.1.5 @@ -2331,7 +2331,7 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 languageName: unknown linkType: soft @@ -2519,7 +2519,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/network-controller@^18.1.1, @metamask/network-controller@workspace:packages/network-controller": +"@metamask/network-controller@^18.1.2, @metamask/network-controller@workspace:packages/network-controller": version: 0.0.0-use.local resolution: "@metamask/network-controller@workspace:packages/network-controller" dependencies: @@ -2692,7 +2692,7 @@ __metadata: "@metamask/auto-changelog": ^3.4.4 "@metamask/base-controller": ^5.0.2 "@metamask/controller-utils": ^9.1.0 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 "@types/uuid": ^8.3.0 @@ -2706,7 +2706,7 @@ __metadata: typescript: ~4.9.5 uuid: ^8.3.2 peerDependencies: - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 languageName: unknown linkType: soft @@ -2790,7 +2790,7 @@ __metadata: "@metamask/base-controller": ^5.0.2 "@metamask/controller-utils": ^9.1.0 "@metamask/json-rpc-engine": ^8.0.2 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/rpc-errors": ^6.2.1 "@metamask/selected-network-controller": ^13.0.0 "@metamask/swappable-obj-proxy": ^2.2.0 @@ -2807,7 +2807,7 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 "@metamask/selected-network-controller": ^13.0.0 languageName: unknown linkType: soft @@ -2864,7 +2864,7 @@ __metadata: "@metamask/auto-changelog": ^3.4.4 "@metamask/base-controller": ^5.0.2 "@metamask/json-rpc-engine": ^8.0.2 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/permission-controller": ^9.1.0 "@metamask/swappable-obj-proxy": ^2.2.0 "@metamask/utils": ^8.3.0 @@ -2880,7 +2880,7 @@ __metadata: typedoc-plugin-missing-exports: ^2.0.0 typescript: ~4.9.5 peerDependencies: - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 "@metamask/permission-controller": ^9.0.0 languageName: unknown linkType: soft @@ -3036,7 +3036,7 @@ __metadata: languageName: node linkType: hard -"@metamask/transaction-controller@^29.1.0, @metamask/transaction-controller@workspace:packages/transaction-controller": +"@metamask/transaction-controller@^30.0.0, @metamask/transaction-controller@workspace:packages/transaction-controller": version: 0.0.0-use.local resolution: "@metamask/transaction-controller@workspace:packages/transaction-controller" dependencies: @@ -3055,7 +3055,7 @@ __metadata: "@metamask/ethjs-provider-http": ^0.3.0 "@metamask/gas-fee-controller": ^15.1.2 "@metamask/metamask-eth-abis": ^3.1.1 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/nonce-tracker": ^5.0.0 "@metamask/rpc-errors": ^6.2.1 "@metamask/utils": ^8.3.0 @@ -3081,7 +3081,7 @@ __metadata: "@babel/runtime": ^7.23.9 "@metamask/approval-controller": ^6.0.0 "@metamask/gas-fee-controller": ^15.0.0 - "@metamask/network-controller": ^18.0.0 + "@metamask/network-controller": ^18.1.2 languageName: unknown linkType: soft @@ -3096,10 +3096,10 @@ __metadata: "@metamask/eth-query": ^4.0.0 "@metamask/gas-fee-controller": ^15.1.2 "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.1.1 + "@metamask/network-controller": ^18.1.2 "@metamask/polling-controller": ^6.0.2 "@metamask/rpc-errors": ^6.2.1 - "@metamask/transaction-controller": ^29.1.0 + "@metamask/transaction-controller": ^30.0.0 "@metamask/utils": ^8.3.0 "@types/jest": ^27.4.1 bn.js: ^5.2.1 @@ -3117,8 +3117,8 @@ __metadata: "@metamask/approval-controller": ^6.0.0 "@metamask/gas-fee-controller": ^15.0.0 "@metamask/keyring-controller": ^16.0.0 - "@metamask/network-controller": ^18.0.0 - "@metamask/transaction-controller": ^29.0.0 + "@metamask/network-controller": ^18.1.2 + "@metamask/transaction-controller": ^30.0.0 languageName: unknown linkType: soft