Skip to content

Commit 94b9e96

Browse files
committed
prices v3 upgrade
1 parent 0237263 commit 94b9e96

File tree

2 files changed

+175
-2
lines changed

2 files changed

+175
-2
lines changed

packages/assets-controllers/src/token-prices-service/abstract-token-prices-service.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,29 @@ export type AbstractTokenPricesService<
9393
currency: Currency;
9494
}): Promise<Partial<TokenPricesByTokenAddress<TokenAddress, Currency>>>;
9595

96+
// fetchTokenPricesV3({
97+
// assets,
98+
// currency,
99+
// }: {
100+
// assets: (
101+
// | { address: Hex; chainId: Hex }
102+
// | { address: CaipAssetType; chainId: CaipChainId }
103+
// )[];
104+
// currency: SupportedCurrency;
105+
// }): (MarketData & {
106+
// assetId: CaipAssetType;
107+
// currency: SupportedCurrency;
108+
// } & (
109+
// | {
110+
// address: Hex;
111+
// chainId: Hex;
112+
// }
113+
// | {
114+
// address: CaipAssetType;
115+
// chainId: CaipChainId;
116+
// }
117+
// ))[];
118+
96119
/**
97120
* Retrieves exchange rates in the given currency.
98121
*

packages/assets-controllers/src/token-prices-service/codefi-v2.ts

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
ChainId,
23
createServicePolicy,
34
DEFAULT_CIRCUIT_BREAK_DURATION,
45
DEFAULT_DEGRADED_THRESHOLD,
@@ -7,15 +8,29 @@ import {
78
handleFetch,
89
} from '@metamask/controller-utils';
910
import type { ServicePolicy } from '@metamask/controller-utils';
10-
import type { Hex } from '@metamask/utils';
11-
import { hexToNumber } from '@metamask/utils';
11+
import type {
12+
CaipAssetReference,
13+
CaipAssetType,
14+
CaipChainId,
15+
Hex,
16+
} from '@metamask/utils';
17+
import {
18+
hexToNumber,
19+
isCaipAssetId,
20+
isCaipAssetType,
21+
isHexString,
22+
isStrictHexString,
23+
KnownCaipNamespace,
24+
toCaipChainId,
25+
} from '@metamask/utils';
1226

1327
import type {
1428
AbstractTokenPricesService,
1529
ExchangeRatesByCurrency,
1630
TokenPrice,
1731
TokenPricesByTokenAddress,
1832
} from './abstract-token-prices-service';
33+
import { accountAddressToCaipReference } from 'src/assetsUtil';
1934

2035
/**
2136
* The list of currencies that can be supplied as the `vsCurrency` parameter to
@@ -174,6 +189,50 @@ const chainIdToNativeTokenAddress: Record<Hex, Hex> = {
174189
export const getNativeTokenAddress = (chainId: Hex): Hex =>
175190
chainIdToNativeTokenAddress[chainId] ?? ZERO_ADDRESS;
176191

192+
// We can only support PricesAPI V3 for EVM chains that have a CAIP-19 native asset mapping.
193+
export const HEX_CHAIN_ID_TO_CAIP19_NATIVE_ASSET_MAP: Record<
194+
Hex,
195+
CaipAssetType
196+
> = {
197+
'0x1': 'eip155:1/slip44:60', // Ethereum Mainnet
198+
'0xa': 'eip155:10/slip44:60', // OP Mainnet
199+
'0x19': 'eip155:25/slip44:394', // Cronos Mainnet
200+
'0x38': 'eip155:56/slip44:714', // BNB Smart Chain Mainnet
201+
'0x39': 'eip155:57/slip44:57', // Syscoin Mainnet
202+
// '0x42': 'eip155:1/slip44:60', // OKXChain Mainnet
203+
// '0x46': 'eip155:1/slip44:60', // Hoo Smart Chain
204+
// '0x52': 'eip155:1/slip44:60', // Meter Mainnet
205+
// '0x58': 'eip155:1/slip44:60', // TomoChain
206+
// '0x64': 'eip155:1/slip44:60', // Gnosis
207+
// '0x6a': 'eip155:1/slip44:60', // Velas EVM Mainnet
208+
// '0x7a': 'eip155:1/slip44:60', // Fuse Mainnet
209+
// '0x80': 'eip155:1/slip44:60', // Huobi ECO Chain Mainnet
210+
'0x89': 'eip155:137/slip44:966', // Polygon Mainnet
211+
'0x8f': 'eip155:143/slip44:268435779', // Monad Mainnet
212+
// '0x92': 'eip155:1/slip44:60', // Sonic Mainnet
213+
// '0xfa': 'eip155:1/slip44:60', // Fantom Opera
214+
// '0x120': 'eip155:1/slip44:60', // Boba Network
215+
// '0x141': 'eip155:1/slip44:60', // KCC Mainnet
216+
// '0x144': 'eip155:1/slip44:60', // zkSync Era Mainnet
217+
// '0x150': 'eip155:1/slip44:60', // Shiden
218+
// '0x169': 'eip155:1/slip44:60', // Theta Mainnet
219+
// '0x440': 'eip155:1/slip44:60', // Metis Andromeda Mainnet
220+
// '0x504': 'eip155:1/slip44:60', // Moonbeam
221+
// '0x505': 'eip155:1/slip44:60', // Moonriver
222+
'0x531': 'eip155:1329/slip44:19000118', // Sei Mainnet
223+
// '0x1388': 'eip155:1/slip44:60', // Mantle
224+
'0x2105': 'eip155:8453/slip44:60', // Base
225+
// '0x2710': 'eip155:1/slip44:60', // Smart Bitcoin Cash
226+
'0xa4b1': 'eip155:42161/slip44:60', // Arbitrum One
227+
// '0xa4ec': 'eip155:1/slip44:60', // Celo Mainnet
228+
// '0xa516': 'eip155:1/slip44:60', // Oasis Emerald
229+
'0xa86a': 'eip155:43114/slip44:9000', // Avalanche C-Chain
230+
'0xe708': 'eip155:59144/slip44:60', // Linea Mainnet
231+
// '0x518af': 'eip155:1/slip44:60', // Polis Mainnet
232+
// '0x4e454152': 'eip155:1/slip44:60', // Aurora Mainnet
233+
// '0x63564c40': 'eip155:1/slip44:60', // Harmony Mainnet Shard 0
234+
};
235+
177236
/**
178237
* A currency that can be supplied as the `vsCurrency` parameter to
179238
* the `/spot-prices` endpoint. Covers both uppercase and lowercase versions.
@@ -273,13 +332,25 @@ export const SUPPORTED_CHAIN_IDS = [
273332
*/
274333
type SupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
275334

335+
const SLIP44_CHAIN_MAP: Record<string, CaipAssetReference> = {
336+
ETH: 'slip44:60',
337+
POL: 'slip44:966',
338+
BNB: 'slip44:714',
339+
AVAX: 'slip44:9000',
340+
TESTETH: 'slip44:60',
341+
SEI: 'slip44:19000118',
342+
MON: 'slip44:268435779',
343+
};
344+
276345
/**
277346
* All requests to V2 of the Price API start with this.
278347
*/
279348
const BASE_URL = 'https://price.api.cx.metamask.io/v2';
280349

281350
const BASE_URL_V1 = 'https://price.api.cx.metamask.io/v1';
282351

352+
const BASE_URL_V3 = 'https://price.api.cx.metamask.io/v3';
353+
283354
/**
284355
* The shape of the data that the /spot-prices endpoint returns.
285356
*/
@@ -534,6 +605,85 @@ export class CodefiTokenPricesServiceV2
534605
) as Partial<TokenPricesByTokenAddress<Hex, SupportedCurrency>>;
535606
}
536607

608+
async fetchTokenPricesV3({
609+
assets,
610+
currency,
611+
}: {
612+
assets: (
613+
| { address: Hex; chainId: Hex }
614+
| { address: CaipAssetType; chainId: CaipChainId }
615+
)[];
616+
currency: SupportedCurrency;
617+
}) {
618+
const assetsWithIds: ({ assetId: CaipAssetType } & (
619+
| { address: Hex; chainId: Hex }
620+
| { address: CaipAssetType; chainId: CaipChainId }
621+
))[] = assets.map((asset) => {
622+
if (isStrictHexString(asset.address)) {
623+
const caipChainId = toCaipChainId(
624+
KnownCaipNamespace.Eip155,
625+
hexToNumber(asset.chainId).toString(),
626+
);
627+
628+
const nativeAsset =
629+
HEX_CHAIN_ID_TO_CAIP19_NATIVE_ASSET_MAP[asset.chainId as Hex];
630+
631+
return {
632+
assetId: nativeAsset ?? `${caipChainId}/erc20:${asset.address}`,
633+
address: asset.address,
634+
chainId: asset.chainId as Hex,
635+
};
636+
}
637+
638+
return {
639+
assetId: asset.address,
640+
address: asset.address,
641+
chainId: asset.chainId as CaipChainId,
642+
};
643+
});
644+
645+
const url = new URL(`${BASE_URL_V3}/spot-prices`);
646+
url.searchParams.append(
647+
'assetIds',
648+
assetsWithIds.map((asset) => asset.assetId).join(','),
649+
);
650+
url.searchParams.append('vsCurrency', currency);
651+
url.searchParams.append('includeMarketData', 'true');
652+
653+
const addressCryptoDataMap: { [assetId: CaipAssetType]: MarketData } =
654+
await this.#policy.execute(() =>
655+
handleFetch(url, { headers: { 'Cache-Control': 'no-cache' } }),
656+
);
657+
658+
return assetsWithIds
659+
.map((assetWithId) => {
660+
const marketData = addressCryptoDataMap[assetWithId.assetId];
661+
662+
if (!marketData) {
663+
return undefined;
664+
}
665+
666+
return {
667+
...assetWithId,
668+
currency,
669+
...marketData,
670+
};
671+
})
672+
.filter(Boolean) as (MarketData & {
673+
assetId: CaipAssetType;
674+
currency: SupportedCurrency;
675+
} & (
676+
| {
677+
address: Hex;
678+
chainId: Hex;
679+
}
680+
| {
681+
address: CaipAssetType;
682+
chainId: CaipChainId;
683+
}
684+
))[];
685+
}
686+
537687
/**
538688
* Retrieves exchange rates in the given base currency.
539689
*

0 commit comments

Comments
 (0)