@metamask/assets-controller 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -1
- package/dist/AssetsController-method-action-types.cjs.map +1 -1
- package/dist/AssetsController-method-action-types.d.cts +14 -3
- package/dist/AssetsController-method-action-types.d.cts.map +1 -1
- package/dist/AssetsController-method-action-types.d.mts +14 -3
- package/dist/AssetsController-method-action-types.d.mts.map +1 -1
- package/dist/AssetsController-method-action-types.mjs.map +1 -1
- package/dist/AssetsController.cjs +46 -5
- package/dist/AssetsController.cjs.map +1 -1
- package/dist/AssetsController.d.cts +12 -6
- package/dist/AssetsController.d.cts.map +1 -1
- package/dist/AssetsController.d.mts +12 -6
- package/dist/AssetsController.d.mts.map +1 -1
- package/dist/AssetsController.mjs +47 -6
- package/dist/AssetsController.mjs.map +1 -1
- package/dist/data-sources/PriceDataSource.cjs +48 -29
- package/dist/data-sources/PriceDataSource.cjs.map +1 -1
- package/dist/data-sources/PriceDataSource.d.cts.map +1 -1
- package/dist/data-sources/PriceDataSource.d.mts.map +1 -1
- package/dist/data-sources/PriceDataSource.mjs +48 -29
- package/dist/data-sources/PriceDataSource.mjs.map +1 -1
- package/dist/data-sources/RpcDataSource.cjs +102 -18
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +102 -18
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +1 -1
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +9 -11
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +9 -11
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/formatExchangeRatesForBridge.cjs +67 -60
- package/dist/utils/formatExchangeRatesForBridge.cjs.map +1 -1
- package/dist/utils/formatExchangeRatesForBridge.d.cts +5 -35
- package/dist/utils/formatExchangeRatesForBridge.d.cts.map +1 -1
- package/dist/utils/formatExchangeRatesForBridge.d.mts +5 -35
- package/dist/utils/formatExchangeRatesForBridge.d.mts.map +1 -1
- package/dist/utils/formatExchangeRatesForBridge.mjs +68 -61
- package/dist/utils/formatExchangeRatesForBridge.mjs.map +1 -1
- package/dist/utils/formatStateForTransactionPay.cjs +125 -0
- package/dist/utils/formatStateForTransactionPay.cjs.map +1 -0
- package/dist/utils/formatStateForTransactionPay.d.cts +66 -0
- package/dist/utils/formatStateForTransactionPay.d.cts.map +1 -0
- package/dist/utils/formatStateForTransactionPay.d.mts +66 -0
- package/dist/utils/formatStateForTransactionPay.d.mts.map +1 -0
- package/dist/utils/formatStateForTransactionPay.mjs +121 -0
- package/dist/utils/formatStateForTransactionPay.mjs.map +1 -0
- package/dist/utils/index.cjs +3 -1
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +3 -1
- package/dist/utils/index.d.cts.map +1 -1
- package/dist/utils/index.d.mts +3 -1
- package/dist/utils/index.d.mts.map +1 -1
- package/dist/utils/index.mjs +1 -0
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +8 -8
|
@@ -5,11 +5,6 @@ const util_1 = require("@ethereumjs/util");
|
|
|
5
5
|
const assets_controllers_1 = require("@metamask/assets-controllers");
|
|
6
6
|
const utils_1 = require("@metamask/utils");
|
|
7
7
|
const utils_2 = require("@metamask/utils");
|
|
8
|
-
function getPriceNumber(price) {
|
|
9
|
-
return typeof price === 'object' && price !== null && 'price' in price
|
|
10
|
-
? Number(price.price)
|
|
11
|
-
: Number.NaN;
|
|
12
|
-
}
|
|
13
8
|
/**
|
|
14
9
|
* Converts AssetsController state (assetsPrice, selectedCurrency) into the
|
|
15
10
|
* same format the bridge expects from MultichainAssetsRatesController,
|
|
@@ -17,62 +12,55 @@ function getPriceNumber(price) {
|
|
|
17
12
|
* a single action when useAssetsControllerForRates is true.
|
|
18
13
|
*
|
|
19
14
|
* @param params - Conversion parameters.
|
|
20
|
-
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data
|
|
15
|
+
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).
|
|
21
16
|
* @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').
|
|
22
17
|
* @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.
|
|
23
18
|
* @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').
|
|
24
|
-
* @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.
|
|
25
19
|
* @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.
|
|
26
20
|
*/
|
|
27
21
|
function formatExchangeRatesForBridge(params) {
|
|
28
|
-
const { assetsPrice, selectedCurrency, nativeAssetIdentifiers = {}, networkConfigurationsByChainId = {},
|
|
22
|
+
const { assetsPrice, selectedCurrency, nativeAssetIdentifiers = {}, networkConfigurationsByChainId = {}, } = params;
|
|
29
23
|
const conversionRates = {};
|
|
30
24
|
const currencyRates = {};
|
|
31
25
|
const marketData = {};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
const currencyCaip = assets_controllers_1.MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()];
|
|
27
|
+
if (!currencyCaip) {
|
|
28
|
+
return {
|
|
29
|
+
conversionRates: {},
|
|
30
|
+
currencyRates: {},
|
|
31
|
+
marketData: {},
|
|
32
|
+
currentCurrency: selectedCurrency,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const fungibleAssetsPrice = Object.entries(assetsPrice).reduce((acc, [assetId, priceData]) => {
|
|
36
|
+
if (priceData.assetPriceType === 'fungible') {
|
|
37
|
+
acc[assetId] = priceData;
|
|
38
|
+
}
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
for (const [assetId, priceData] of Object.entries(fungibleAssetsPrice)) {
|
|
42
|
+
const { price, usdPrice, lastUpdated } = priceData;
|
|
43
|
+
if (price < 0) {
|
|
42
44
|
continue;
|
|
43
45
|
}
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
? Number(priceData.lastUpdated)
|
|
48
|
-
: Date.now();
|
|
49
|
-
const conversionTime = lastUpdated > 1e12 ? lastUpdated / 1000 : lastUpdated;
|
|
50
|
-
const expirationTime = conversionTime + expirationOffset;
|
|
46
|
+
const lastUpdatedInSeconds = lastUpdated / 1000;
|
|
47
|
+
const expirationOffsetInSeconds = 60;
|
|
48
|
+
const expirationTime = lastUpdatedInSeconds + expirationOffsetInSeconds;
|
|
51
49
|
try {
|
|
52
50
|
const parsed = (0, utils_2.parseCaipAssetType)(assetId);
|
|
53
51
|
const chainIdParsed = (0, utils_2.parseCaipChainId)(parsed.chainId);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
if (chainIdParsed.namespace === 'eip155') {
|
|
69
|
-
const chainIdHex = (0, utils_1.numberToHex)(parseInt(chainRef, 10));
|
|
70
|
-
const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] ?? null;
|
|
71
|
-
const symbol = networkConfigurationsByChainId[chainIdHex]?.nativeCurrency ?? 'ETH';
|
|
72
|
-
const nativePrice = nativeAssetId && assetsPrice[nativeAssetId]
|
|
73
|
-
? getPriceNumber(assetsPrice[nativeAssetId])
|
|
74
|
-
: Number.NaN;
|
|
75
|
-
let tokenAddress = null;
|
|
52
|
+
if (chainIdParsed.namespace === utils_1.KnownCaipNamespace.Eip155) {
|
|
53
|
+
const chainIdHex = (0, utils_1.numberToHex)(parseInt(chainIdParsed.reference, 10));
|
|
54
|
+
const nativeAssetId = nativeAssetIdentifiers[parsed.chainId];
|
|
55
|
+
const nativeCurrencySymbol = networkConfigurationsByChainId[chainIdHex]?.nativeCurrency;
|
|
56
|
+
const nativeAssetUsdPrice = nativeAssetId && fungibleAssetsPrice[nativeAssetId]?.usdPrice;
|
|
57
|
+
if (!nativeAssetId ||
|
|
58
|
+
!nativeCurrencySymbol ||
|
|
59
|
+
nativeAssetUsdPrice === undefined) {
|
|
60
|
+
// If we do not have a native asset for that chain or a price for it, the asset needs to be skipped
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
let tokenAddress;
|
|
76
64
|
if (parsed.assetNamespace === 'erc20') {
|
|
77
65
|
tokenAddress = (0, util_1.toChecksumAddress)(String(parsed.assetReference));
|
|
78
66
|
}
|
|
@@ -80,33 +68,52 @@ function formatExchangeRatesForBridge(params) {
|
|
|
80
68
|
tokenAddress = '0x0000000000000000000000000000000000000000';
|
|
81
69
|
}
|
|
82
70
|
if (tokenAddress && nativeAssetId) {
|
|
83
|
-
const priceInNative =
|
|
84
|
-
? price / nativePrice
|
|
85
|
-
: price;
|
|
71
|
+
const priceInNative = nativeAssetUsdPrice > 0 ? usdPrice / nativeAssetUsdPrice : usdPrice;
|
|
86
72
|
if (!marketData[chainIdHex]) {
|
|
87
73
|
marketData[chainIdHex] = {};
|
|
88
74
|
}
|
|
89
|
-
const baseMarketData = typeof priceData === 'object' && priceData !== null
|
|
90
|
-
? priceData
|
|
91
|
-
: {};
|
|
92
75
|
marketData[chainIdHex][tokenAddress] = {
|
|
93
|
-
...
|
|
76
|
+
...priceData,
|
|
94
77
|
price: priceInNative,
|
|
95
|
-
currency:
|
|
78
|
+
currency: nativeCurrencySymbol,
|
|
96
79
|
assetId,
|
|
97
80
|
chainId: chainIdHex,
|
|
98
81
|
tokenAddress,
|
|
99
82
|
};
|
|
100
83
|
}
|
|
101
84
|
if (parsed.assetNamespace === 'slip44' && nativeAssetId) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
usdConversionRate: price,
|
|
85
|
+
currencyRates[nativeCurrencySymbol] = {
|
|
86
|
+
conversionDate: lastUpdatedInSeconds,
|
|
87
|
+
conversionRate: price,
|
|
88
|
+
usdConversionRate: usdPrice,
|
|
107
89
|
};
|
|
108
90
|
}
|
|
109
91
|
}
|
|
92
|
+
else {
|
|
93
|
+
conversionRates[assetId] = {
|
|
94
|
+
rate: String(price),
|
|
95
|
+
currency: currencyCaip,
|
|
96
|
+
conversionTime: lastUpdatedInSeconds,
|
|
97
|
+
expirationTime,
|
|
98
|
+
marketData: {
|
|
99
|
+
fungible: true,
|
|
100
|
+
allTimeHigh: `${priceData.allTimeHigh}`,
|
|
101
|
+
allTimeLow: `${priceData.allTimeLow}`,
|
|
102
|
+
circulatingSupply: `${priceData.circulatingSupply}`,
|
|
103
|
+
marketCap: `${priceData.marketCap}`,
|
|
104
|
+
totalVolume: `${priceData.totalVolume}`,
|
|
105
|
+
pricePercentChange: {
|
|
106
|
+
PT1H: priceData.pricePercentChange1h,
|
|
107
|
+
P1D: priceData.pricePercentChange1d,
|
|
108
|
+
P7D: priceData.pricePercentChange7d,
|
|
109
|
+
P14D: priceData.pricePercentChange14d,
|
|
110
|
+
P30D: priceData.pricePercentChange30d,
|
|
111
|
+
P200D: priceData.pricePercentChange200d,
|
|
112
|
+
P1Y: priceData.pricePercentChange1y,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
110
117
|
}
|
|
111
118
|
catch {
|
|
112
119
|
// Skip malformed asset IDs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatExchangeRatesForBridge.cjs","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { toChecksumAddress } from '@ethereumjs/util';\nimport { MAP_CAIP_CURRENCIES } from '@metamask/assets-controllers';\nimport { numberToHex } from '@metamask/utils';\nimport { parseCaipAssetType, parseCaipChainId } from '@metamask/utils';\n\nimport type { AssetPrice, Caip19AssetId } from '../types';\n\n/**\n * Bridge-compatible conversion rate entry (MultichainAssetsRatesController shape).\n */\nexport type BridgeConversionRateEntry = {\n rate: string;\n currency?: string;\n conversionTime?: number;\n expirationTime?: number;\n marketData?: Record<string, unknown>;\n};\n\n/**\n * Bridge-compatible currency rate entry (CurrencyRateController shape).\n */\nexport type BridgeCurrencyRateEntry = {\n conversionDate: number;\n conversionRate: number;\n usdConversionRate: number;\n};\n\n/**\n * Bridge-compatible market data entry (TokenRatesController marketData shape).\n */\nexport type BridgeMarketDataEntry = {\n price: number;\n currency: string;\n assetId?: string;\n chainId?: string;\n tokenAddress?: string;\n [key: string]: unknown;\n};\n\n/**\n * Exchange rates in the format expected by the bridge controller:\n * conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)\n * + marketData (TokenRatesController) + currentCurrency.\n */\nexport type BridgeExchangeRatesFormat = {\n conversionRates: Record<string, BridgeConversionRateEntry>;\n currencyRates: Record<string, BridgeCurrencyRateEntry>;\n marketData: Record<string, Record<string, BridgeMarketDataEntry>>;\n currentCurrency: string;\n};\n\nfunction getPriceNumber(price: AssetPrice): number {\n return typeof price === 'object' && price !== null && 'price' in price\n ? Number((price as { price: number }).price)\n : Number.NaN;\n}\n\n/**\n * Converts AssetsController state (assetsPrice, selectedCurrency) into the\n * same format the bridge expects from MultichainAssetsRatesController,\n * CurrencyRateController, and TokenRatesController so the bridge can use\n * a single action when useAssetsControllerForRates is true.\n *\n * @param params - Conversion parameters.\n * @param params.assetsPrice - Map of CAIP-19 asset ID to price data. Prices are in USD.\n * @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').\n * @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.\n * @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').\n * @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.\n * @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.\n */\nexport function formatExchangeRatesForBridge(params: {\n assetsPrice: Record<string, AssetPrice>;\n selectedCurrency: string;\n nativeAssetIdentifiers?: Record<string, string>;\n networkConfigurationsByChainId?: Record<string, { nativeCurrency?: string }>;\n usdToSelectedCurrencyRate?: number;\n}): BridgeExchangeRatesFormat {\n const {\n assetsPrice,\n selectedCurrency,\n nativeAssetIdentifiers = {},\n networkConfigurationsByChainId = {},\n usdToSelectedCurrencyRate,\n } = params;\n const conversionRates: Record<string, BridgeConversionRateEntry> = {};\n const currencyRates: Record<string, BridgeCurrencyRateEntry> = {};\n const marketData: Record<string, Record<string, BridgeMarketDataEntry>> = {};\n\n // Same as MultichainAssetsRatesController: resolve CAIP currency from selectedCurrency, default to USD\n const currencyCaip =\n MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()] ??\n MAP_CAIP_CURRENCIES.usd;\n\n const expirationOffset = 60;\n\n // Price in assetsPrice is in USD. For bridge: conversionRate = in user's currency, usdConversionRate = in USD.\n const isUsd = selectedCurrency.toLowerCase() === 'usd';\n const rateUserCurrencyPerUsd = isUsd ? 1 : (usdToSelectedCurrencyRate ?? 1);\n\n for (const [assetId, priceData] of Object.entries(assetsPrice)) {\n const price = getPriceNumber(priceData);\n if (Number.isNaN(price) || price < 0) {\n continue;\n }\n\n const lastUpdated =\n typeof priceData === 'object' &&\n priceData !== null &&\n 'lastUpdated' in priceData\n ? Number((priceData as { lastUpdated: number }).lastUpdated)\n : Date.now();\n const conversionTime =\n lastUpdated > 1e12 ? lastUpdated / 1000 : lastUpdated;\n const expirationTime = conversionTime + expirationOffset;\n\n try {\n const parsed = parseCaipAssetType(assetId as Caip19AssetId);\n const chainIdParsed = parseCaipChainId(parsed.chainId);\n const chainRef = chainIdParsed.reference;\n\n // conversionRates: only non-EVM assets (bridge uses this for non-EVM chains). Rate in selected currency.\n if (chainIdParsed.namespace !== 'eip155') {\n const priceInUserCurrency = price * rateUserCurrencyPerUsd;\n conversionRates[assetId] = {\n rate: String(priceInUserCurrency),\n currency: currencyCaip,\n conversionTime,\n expirationTime,\n marketData:\n typeof priceData === 'object' && priceData !== null\n ? (priceData as Record<string, unknown>)\n : undefined,\n };\n }\n\n if (chainIdParsed.namespace === 'eip155') {\n const chainIdHex = numberToHex(parseInt(chainRef, 10));\n const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] ?? null;\n const symbol =\n networkConfigurationsByChainId[chainIdHex]?.nativeCurrency ?? 'ETH';\n const nativePrice =\n nativeAssetId && assetsPrice[nativeAssetId]\n ? getPriceNumber(assetsPrice[nativeAssetId])\n : Number.NaN;\n\n let tokenAddress: string | null = null;\n if (parsed.assetNamespace === 'erc20') {\n tokenAddress = toChecksumAddress(String(parsed.assetReference));\n } else if (parsed.assetNamespace === 'slip44') {\n tokenAddress = '0x0000000000000000000000000000000000000000';\n }\n\n if (tokenAddress && nativeAssetId) {\n const priceInNative =\n !Number.isNaN(nativePrice) && nativePrice > 0\n ? price / nativePrice\n : price;\n if (!marketData[chainIdHex]) {\n marketData[chainIdHex] = {};\n }\n const baseMarketData =\n typeof priceData === 'object' && priceData !== null\n ? (priceData as Record<string, unknown>)\n : {};\n marketData[chainIdHex][tokenAddress] = {\n ...baseMarketData,\n price: priceInNative,\n currency: symbol,\n assetId,\n chainId: chainIdHex,\n tokenAddress,\n };\n }\n\n if (parsed.assetNamespace === 'slip44' && nativeAssetId) {\n // conversionRate = native price in user's currency; usdConversionRate = native price in USD (bridge uses ratio for USD conversion)\n currencyRates[symbol] = {\n conversionDate: conversionTime,\n conversionRate: price * rateUserCurrencyPerUsd,\n usdConversionRate: price,\n };\n }\n }\n } catch {\n // Skip malformed asset IDs\n }\n }\n\n return {\n conversionRates,\n currencyRates,\n marketData,\n currentCurrency: selectedCurrency,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"formatExchangeRatesForBridge.cjs","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { toChecksumAddress } from '@ethereumjs/util';\nimport {\n CurrencyRateState,\n MAP_CAIP_CURRENCIES,\n MarketDataDetails,\n MultichainAssetsRatesControllerState,\n TokenRatesControllerState,\n} from '@metamask/assets-controllers';\nimport { Hex, KnownCaipNamespace, numberToHex } from '@metamask/utils';\nimport { parseCaipAssetType, parseCaipChainId } from '@metamask/utils';\n\nimport type { AssetPrice, FungibleAssetPrice, Caip19AssetId } from '../types';\n\n/**\n * Exchange rates in the format expected by the bridge controller:\n * conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)\n * + marketData (TokenRatesController) + currentCurrency.\n */\nexport type BridgeExchangeRatesFormat = {\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currencyRates: CurrencyRateState['currencyRates'];\n marketData: TokenRatesControllerState['marketData'];\n currentCurrency: string;\n};\n\n/**\n * Converts AssetsController state (assetsPrice, selectedCurrency) into the\n * same format the bridge expects from MultichainAssetsRatesController,\n * CurrencyRateController, and TokenRatesController so the bridge can use\n * a single action when useAssetsControllerForRates is true.\n *\n * @param params - Conversion parameters.\n * @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).\n * @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').\n * @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.\n * @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').\n * @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.\n */\nexport function formatExchangeRatesForBridge(params: {\n assetsPrice: Record<string, AssetPrice>;\n selectedCurrency: string;\n nativeAssetIdentifiers?: Record<string, string>;\n networkConfigurationsByChainId?: Record<string, { nativeCurrency?: string }>;\n}): BridgeExchangeRatesFormat {\n const {\n assetsPrice,\n selectedCurrency,\n nativeAssetIdentifiers = {},\n networkConfigurationsByChainId = {},\n } = params;\n const conversionRates: MultichainAssetsRatesControllerState['conversionRates'] =\n {};\n const currencyRates: CurrencyRateState['currencyRates'] = {};\n const marketData: TokenRatesControllerState['marketData'] = {};\n\n const currencyCaip = MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()];\n if (!currencyCaip) {\n return {\n conversionRates: {},\n currencyRates: {},\n marketData: {},\n currentCurrency: selectedCurrency,\n };\n }\n\n const fungibleAssetsPrice = Object.entries(assetsPrice).reduce<\n Record<Caip19AssetId, FungibleAssetPrice>\n >((acc, [assetId, priceData]) => {\n if (priceData.assetPriceType === 'fungible') {\n acc[assetId as Caip19AssetId] = priceData;\n }\n return acc;\n }, {});\n\n for (const [assetId, priceData] of Object.entries(fungibleAssetsPrice)) {\n const { price, usdPrice, lastUpdated } = priceData;\n if (price < 0) {\n continue;\n }\n\n const lastUpdatedInSeconds = lastUpdated / 1000;\n const expirationOffsetInSeconds = 60;\n const expirationTime = lastUpdatedInSeconds + expirationOffsetInSeconds;\n\n try {\n const parsed = parseCaipAssetType(assetId as Caip19AssetId);\n const chainIdParsed = parseCaipChainId(parsed.chainId);\n\n if (chainIdParsed.namespace === KnownCaipNamespace.Eip155) {\n const chainIdHex = numberToHex(parseInt(chainIdParsed.reference, 10));\n\n const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] as\n | Caip19AssetId\n | undefined;\n\n const nativeCurrencySymbol =\n networkConfigurationsByChainId[chainIdHex]?.nativeCurrency;\n\n const nativeAssetUsdPrice =\n nativeAssetId && fungibleAssetsPrice[nativeAssetId]?.usdPrice;\n\n if (\n !nativeAssetId ||\n !nativeCurrencySymbol ||\n nativeAssetUsdPrice === undefined\n ) {\n // If we do not have a native asset for that chain or a price for it, the asset needs to be skipped\n continue;\n }\n\n let tokenAddress: Hex | undefined;\n if (parsed.assetNamespace === 'erc20') {\n tokenAddress = toChecksumAddress(String(parsed.assetReference));\n } else if (parsed.assetNamespace === 'slip44') {\n tokenAddress = '0x0000000000000000000000000000000000000000';\n }\n\n if (tokenAddress && nativeAssetId) {\n const priceInNative =\n nativeAssetUsdPrice > 0 ? usdPrice / nativeAssetUsdPrice : usdPrice;\n if (!marketData[chainIdHex]) {\n marketData[chainIdHex] = {};\n }\n marketData[chainIdHex][tokenAddress] = {\n ...priceData,\n price: priceInNative,\n currency: nativeCurrencySymbol,\n assetId,\n chainId: chainIdHex,\n tokenAddress,\n } as MarketDataDetails;\n }\n\n if (parsed.assetNamespace === 'slip44' && nativeAssetId) {\n currencyRates[nativeCurrencySymbol] = {\n conversionDate: lastUpdatedInSeconds,\n conversionRate: price,\n usdConversionRate: usdPrice,\n };\n }\n } else {\n conversionRates[assetId as Caip19AssetId] = {\n rate: String(price),\n currency: currencyCaip,\n conversionTime: lastUpdatedInSeconds,\n expirationTime,\n marketData: {\n fungible: true,\n allTimeHigh: `${priceData.allTimeHigh}`,\n allTimeLow: `${priceData.allTimeLow}`,\n circulatingSupply: `${priceData.circulatingSupply}`,\n marketCap: `${priceData.marketCap}`,\n totalVolume: `${priceData.totalVolume}`,\n pricePercentChange: {\n PT1H: priceData.pricePercentChange1h as number,\n P1D: priceData.pricePercentChange1d as number,\n P7D: priceData.pricePercentChange7d as number,\n P14D: priceData.pricePercentChange14d as number,\n P30D: priceData.pricePercentChange30d as number,\n P200D: priceData.pricePercentChange200d as number,\n P1Y: priceData.pricePercentChange1y as number,\n },\n },\n } as MultichainAssetsRatesControllerState['conversionRates'][Caip19AssetId];\n }\n } catch {\n // Skip malformed asset IDs\n }\n }\n\n return {\n conversionRates,\n currencyRates,\n marketData,\n currentCurrency: selectedCurrency,\n };\n}\n"]}
|
|
@@ -1,42 +1,14 @@
|
|
|
1
|
+
import { CurrencyRateState, MultichainAssetsRatesControllerState, TokenRatesControllerState } from "@metamask/assets-controllers";
|
|
1
2
|
import type { AssetPrice } from "../types.cjs";
|
|
2
|
-
/**
|
|
3
|
-
* Bridge-compatible conversion rate entry (MultichainAssetsRatesController shape).
|
|
4
|
-
*/
|
|
5
|
-
export type BridgeConversionRateEntry = {
|
|
6
|
-
rate: string;
|
|
7
|
-
currency?: string;
|
|
8
|
-
conversionTime?: number;
|
|
9
|
-
expirationTime?: number;
|
|
10
|
-
marketData?: Record<string, unknown>;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Bridge-compatible currency rate entry (CurrencyRateController shape).
|
|
14
|
-
*/
|
|
15
|
-
export type BridgeCurrencyRateEntry = {
|
|
16
|
-
conversionDate: number;
|
|
17
|
-
conversionRate: number;
|
|
18
|
-
usdConversionRate: number;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Bridge-compatible market data entry (TokenRatesController marketData shape).
|
|
22
|
-
*/
|
|
23
|
-
export type BridgeMarketDataEntry = {
|
|
24
|
-
price: number;
|
|
25
|
-
currency: string;
|
|
26
|
-
assetId?: string;
|
|
27
|
-
chainId?: string;
|
|
28
|
-
tokenAddress?: string;
|
|
29
|
-
[key: string]: unknown;
|
|
30
|
-
};
|
|
31
3
|
/**
|
|
32
4
|
* Exchange rates in the format expected by the bridge controller:
|
|
33
5
|
* conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)
|
|
34
6
|
* + marketData (TokenRatesController) + currentCurrency.
|
|
35
7
|
*/
|
|
36
8
|
export type BridgeExchangeRatesFormat = {
|
|
37
|
-
conversionRates:
|
|
38
|
-
currencyRates:
|
|
39
|
-
marketData:
|
|
9
|
+
conversionRates: MultichainAssetsRatesControllerState['conversionRates'];
|
|
10
|
+
currencyRates: CurrencyRateState['currencyRates'];
|
|
11
|
+
marketData: TokenRatesControllerState['marketData'];
|
|
40
12
|
currentCurrency: string;
|
|
41
13
|
};
|
|
42
14
|
/**
|
|
@@ -46,11 +18,10 @@ export type BridgeExchangeRatesFormat = {
|
|
|
46
18
|
* a single action when useAssetsControllerForRates is true.
|
|
47
19
|
*
|
|
48
20
|
* @param params - Conversion parameters.
|
|
49
|
-
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data
|
|
21
|
+
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).
|
|
50
22
|
* @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').
|
|
51
23
|
* @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.
|
|
52
24
|
* @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').
|
|
53
|
-
* @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.
|
|
54
25
|
* @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.
|
|
55
26
|
*/
|
|
56
27
|
export declare function formatExchangeRatesForBridge(params: {
|
|
@@ -60,6 +31,5 @@ export declare function formatExchangeRatesForBridge(params: {
|
|
|
60
31
|
networkConfigurationsByChainId?: Record<string, {
|
|
61
32
|
nativeCurrency?: string;
|
|
62
33
|
}>;
|
|
63
|
-
usdToSelectedCurrencyRate?: number;
|
|
64
34
|
}): BridgeExchangeRatesFormat;
|
|
65
35
|
//# sourceMappingURL=formatExchangeRatesForBridge.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatExchangeRatesForBridge.d.cts","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"formatExchangeRatesForBridge.d.cts","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAGjB,oCAAoC,EACpC,yBAAyB,EAC1B,qCAAqC;AAItC,OAAO,KAAK,EAAE,UAAU,EAAqC,qBAAiB;AAE9E;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,EAAE,oCAAoC,CAAC,iBAAiB,CAAC,CAAC;IACzE,aAAa,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAClD,UAAU,EAAE,yBAAyB,CAAC,YAAY,CAAC,CAAC;IACpD,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,8BAA8B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9E,GAAG,yBAAyB,CAqI5B"}
|
|
@@ -1,42 +1,14 @@
|
|
|
1
|
+
import { CurrencyRateState, MultichainAssetsRatesControllerState, TokenRatesControllerState } from "@metamask/assets-controllers";
|
|
1
2
|
import type { AssetPrice } from "../types.mjs";
|
|
2
|
-
/**
|
|
3
|
-
* Bridge-compatible conversion rate entry (MultichainAssetsRatesController shape).
|
|
4
|
-
*/
|
|
5
|
-
export type BridgeConversionRateEntry = {
|
|
6
|
-
rate: string;
|
|
7
|
-
currency?: string;
|
|
8
|
-
conversionTime?: number;
|
|
9
|
-
expirationTime?: number;
|
|
10
|
-
marketData?: Record<string, unknown>;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Bridge-compatible currency rate entry (CurrencyRateController shape).
|
|
14
|
-
*/
|
|
15
|
-
export type BridgeCurrencyRateEntry = {
|
|
16
|
-
conversionDate: number;
|
|
17
|
-
conversionRate: number;
|
|
18
|
-
usdConversionRate: number;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Bridge-compatible market data entry (TokenRatesController marketData shape).
|
|
22
|
-
*/
|
|
23
|
-
export type BridgeMarketDataEntry = {
|
|
24
|
-
price: number;
|
|
25
|
-
currency: string;
|
|
26
|
-
assetId?: string;
|
|
27
|
-
chainId?: string;
|
|
28
|
-
tokenAddress?: string;
|
|
29
|
-
[key: string]: unknown;
|
|
30
|
-
};
|
|
31
3
|
/**
|
|
32
4
|
* Exchange rates in the format expected by the bridge controller:
|
|
33
5
|
* conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)
|
|
34
6
|
* + marketData (TokenRatesController) + currentCurrency.
|
|
35
7
|
*/
|
|
36
8
|
export type BridgeExchangeRatesFormat = {
|
|
37
|
-
conversionRates:
|
|
38
|
-
currencyRates:
|
|
39
|
-
marketData:
|
|
9
|
+
conversionRates: MultichainAssetsRatesControllerState['conversionRates'];
|
|
10
|
+
currencyRates: CurrencyRateState['currencyRates'];
|
|
11
|
+
marketData: TokenRatesControllerState['marketData'];
|
|
40
12
|
currentCurrency: string;
|
|
41
13
|
};
|
|
42
14
|
/**
|
|
@@ -46,11 +18,10 @@ export type BridgeExchangeRatesFormat = {
|
|
|
46
18
|
* a single action when useAssetsControllerForRates is true.
|
|
47
19
|
*
|
|
48
20
|
* @param params - Conversion parameters.
|
|
49
|
-
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data
|
|
21
|
+
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).
|
|
50
22
|
* @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').
|
|
51
23
|
* @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.
|
|
52
24
|
* @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').
|
|
53
|
-
* @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.
|
|
54
25
|
* @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.
|
|
55
26
|
*/
|
|
56
27
|
export declare function formatExchangeRatesForBridge(params: {
|
|
@@ -60,6 +31,5 @@ export declare function formatExchangeRatesForBridge(params: {
|
|
|
60
31
|
networkConfigurationsByChainId?: Record<string, {
|
|
61
32
|
nativeCurrency?: string;
|
|
62
33
|
}>;
|
|
63
|
-
usdToSelectedCurrencyRate?: number;
|
|
64
34
|
}): BridgeExchangeRatesFormat;
|
|
65
35
|
//# sourceMappingURL=formatExchangeRatesForBridge.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatExchangeRatesForBridge.d.mts","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"formatExchangeRatesForBridge.d.mts","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAGjB,oCAAoC,EACpC,yBAAyB,EAC1B,qCAAqC;AAItC,OAAO,KAAK,EAAE,UAAU,EAAqC,qBAAiB;AAE9E;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,EAAE,oCAAoC,CAAC,iBAAiB,CAAC,CAAC;IACzE,aAAa,EAAE,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAClD,UAAU,EAAE,yBAAyB,CAAC,YAAY,CAAC,CAAC;IACpD,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,8BAA8B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC9E,GAAG,yBAAyB,CAqI5B"}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { toChecksumAddress } from "@ethereumjs/util";
|
|
2
2
|
import { MAP_CAIP_CURRENCIES } from "@metamask/assets-controllers";
|
|
3
|
-
import { numberToHex } from "@metamask/utils";
|
|
3
|
+
import { KnownCaipNamespace, numberToHex } from "@metamask/utils";
|
|
4
4
|
import { parseCaipAssetType, parseCaipChainId } from "@metamask/utils";
|
|
5
|
-
function getPriceNumber(price) {
|
|
6
|
-
return typeof price === 'object' && price !== null && 'price' in price
|
|
7
|
-
? Number(price.price)
|
|
8
|
-
: Number.NaN;
|
|
9
|
-
}
|
|
10
5
|
/**
|
|
11
6
|
* Converts AssetsController state (assetsPrice, selectedCurrency) into the
|
|
12
7
|
* same format the bridge expects from MultichainAssetsRatesController,
|
|
@@ -14,62 +9,55 @@ function getPriceNumber(price) {
|
|
|
14
9
|
* a single action when useAssetsControllerForRates is true.
|
|
15
10
|
*
|
|
16
11
|
* @param params - Conversion parameters.
|
|
17
|
-
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data
|
|
12
|
+
* @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).
|
|
18
13
|
* @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').
|
|
19
14
|
* @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.
|
|
20
15
|
* @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').
|
|
21
|
-
* @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.
|
|
22
16
|
* @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.
|
|
23
17
|
*/
|
|
24
18
|
export function formatExchangeRatesForBridge(params) {
|
|
25
|
-
const { assetsPrice, selectedCurrency, nativeAssetIdentifiers = {}, networkConfigurationsByChainId = {},
|
|
19
|
+
const { assetsPrice, selectedCurrency, nativeAssetIdentifiers = {}, networkConfigurationsByChainId = {}, } = params;
|
|
26
20
|
const conversionRates = {};
|
|
27
21
|
const currencyRates = {};
|
|
28
22
|
const marketData = {};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
const currencyCaip = MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()];
|
|
24
|
+
if (!currencyCaip) {
|
|
25
|
+
return {
|
|
26
|
+
conversionRates: {},
|
|
27
|
+
currencyRates: {},
|
|
28
|
+
marketData: {},
|
|
29
|
+
currentCurrency: selectedCurrency,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const fungibleAssetsPrice = Object.entries(assetsPrice).reduce((acc, [assetId, priceData]) => {
|
|
33
|
+
if (priceData.assetPriceType === 'fungible') {
|
|
34
|
+
acc[assetId] = priceData;
|
|
35
|
+
}
|
|
36
|
+
return acc;
|
|
37
|
+
}, {});
|
|
38
|
+
for (const [assetId, priceData] of Object.entries(fungibleAssetsPrice)) {
|
|
39
|
+
const { price, usdPrice, lastUpdated } = priceData;
|
|
40
|
+
if (price < 0) {
|
|
39
41
|
continue;
|
|
40
42
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
? Number(priceData.lastUpdated)
|
|
45
|
-
: Date.now();
|
|
46
|
-
const conversionTime = lastUpdated > 1e12 ? lastUpdated / 1000 : lastUpdated;
|
|
47
|
-
const expirationTime = conversionTime + expirationOffset;
|
|
43
|
+
const lastUpdatedInSeconds = lastUpdated / 1000;
|
|
44
|
+
const expirationOffsetInSeconds = 60;
|
|
45
|
+
const expirationTime = lastUpdatedInSeconds + expirationOffsetInSeconds;
|
|
48
46
|
try {
|
|
49
47
|
const parsed = parseCaipAssetType(assetId);
|
|
50
48
|
const chainIdParsed = parseCaipChainId(parsed.chainId);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
if (chainIdParsed.namespace === 'eip155') {
|
|
66
|
-
const chainIdHex = numberToHex(parseInt(chainRef, 10));
|
|
67
|
-
const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] ?? null;
|
|
68
|
-
const symbol = networkConfigurationsByChainId[chainIdHex]?.nativeCurrency ?? 'ETH';
|
|
69
|
-
const nativePrice = nativeAssetId && assetsPrice[nativeAssetId]
|
|
70
|
-
? getPriceNumber(assetsPrice[nativeAssetId])
|
|
71
|
-
: Number.NaN;
|
|
72
|
-
let tokenAddress = null;
|
|
49
|
+
if (chainIdParsed.namespace === KnownCaipNamespace.Eip155) {
|
|
50
|
+
const chainIdHex = numberToHex(parseInt(chainIdParsed.reference, 10));
|
|
51
|
+
const nativeAssetId = nativeAssetIdentifiers[parsed.chainId];
|
|
52
|
+
const nativeCurrencySymbol = networkConfigurationsByChainId[chainIdHex]?.nativeCurrency;
|
|
53
|
+
const nativeAssetUsdPrice = nativeAssetId && fungibleAssetsPrice[nativeAssetId]?.usdPrice;
|
|
54
|
+
if (!nativeAssetId ||
|
|
55
|
+
!nativeCurrencySymbol ||
|
|
56
|
+
nativeAssetUsdPrice === undefined) {
|
|
57
|
+
// If we do not have a native asset for that chain or a price for it, the asset needs to be skipped
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
let tokenAddress;
|
|
73
61
|
if (parsed.assetNamespace === 'erc20') {
|
|
74
62
|
tokenAddress = toChecksumAddress(String(parsed.assetReference));
|
|
75
63
|
}
|
|
@@ -77,33 +65,52 @@ export function formatExchangeRatesForBridge(params) {
|
|
|
77
65
|
tokenAddress = '0x0000000000000000000000000000000000000000';
|
|
78
66
|
}
|
|
79
67
|
if (tokenAddress && nativeAssetId) {
|
|
80
|
-
const priceInNative =
|
|
81
|
-
? price / nativePrice
|
|
82
|
-
: price;
|
|
68
|
+
const priceInNative = nativeAssetUsdPrice > 0 ? usdPrice / nativeAssetUsdPrice : usdPrice;
|
|
83
69
|
if (!marketData[chainIdHex]) {
|
|
84
70
|
marketData[chainIdHex] = {};
|
|
85
71
|
}
|
|
86
|
-
const baseMarketData = typeof priceData === 'object' && priceData !== null
|
|
87
|
-
? priceData
|
|
88
|
-
: {};
|
|
89
72
|
marketData[chainIdHex][tokenAddress] = {
|
|
90
|
-
...
|
|
73
|
+
...priceData,
|
|
91
74
|
price: priceInNative,
|
|
92
|
-
currency:
|
|
75
|
+
currency: nativeCurrencySymbol,
|
|
93
76
|
assetId,
|
|
94
77
|
chainId: chainIdHex,
|
|
95
78
|
tokenAddress,
|
|
96
79
|
};
|
|
97
80
|
}
|
|
98
81
|
if (parsed.assetNamespace === 'slip44' && nativeAssetId) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
usdConversionRate: price,
|
|
82
|
+
currencyRates[nativeCurrencySymbol] = {
|
|
83
|
+
conversionDate: lastUpdatedInSeconds,
|
|
84
|
+
conversionRate: price,
|
|
85
|
+
usdConversionRate: usdPrice,
|
|
104
86
|
};
|
|
105
87
|
}
|
|
106
88
|
}
|
|
89
|
+
else {
|
|
90
|
+
conversionRates[assetId] = {
|
|
91
|
+
rate: String(price),
|
|
92
|
+
currency: currencyCaip,
|
|
93
|
+
conversionTime: lastUpdatedInSeconds,
|
|
94
|
+
expirationTime,
|
|
95
|
+
marketData: {
|
|
96
|
+
fungible: true,
|
|
97
|
+
allTimeHigh: `${priceData.allTimeHigh}`,
|
|
98
|
+
allTimeLow: `${priceData.allTimeLow}`,
|
|
99
|
+
circulatingSupply: `${priceData.circulatingSupply}`,
|
|
100
|
+
marketCap: `${priceData.marketCap}`,
|
|
101
|
+
totalVolume: `${priceData.totalVolume}`,
|
|
102
|
+
pricePercentChange: {
|
|
103
|
+
PT1H: priceData.pricePercentChange1h,
|
|
104
|
+
P1D: priceData.pricePercentChange1d,
|
|
105
|
+
P7D: priceData.pricePercentChange7d,
|
|
106
|
+
P14D: priceData.pricePercentChange14d,
|
|
107
|
+
P30D: priceData.pricePercentChange30d,
|
|
108
|
+
P200D: priceData.pricePercentChange200d,
|
|
109
|
+
P1Y: priceData.pricePercentChange1y,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
107
114
|
}
|
|
108
115
|
catch {
|
|
109
116
|
// Skip malformed asset IDs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatExchangeRatesForBridge.mjs","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { toChecksumAddress } from '@ethereumjs/util';\nimport { MAP_CAIP_CURRENCIES } from '@metamask/assets-controllers';\nimport { numberToHex } from '@metamask/utils';\nimport { parseCaipAssetType, parseCaipChainId } from '@metamask/utils';\n\nimport type { AssetPrice, Caip19AssetId } from '../types';\n\n/**\n * Bridge-compatible conversion rate entry (MultichainAssetsRatesController shape).\n */\nexport type BridgeConversionRateEntry = {\n rate: string;\n currency?: string;\n conversionTime?: number;\n expirationTime?: number;\n marketData?: Record<string, unknown>;\n};\n\n/**\n * Bridge-compatible currency rate entry (CurrencyRateController shape).\n */\nexport type BridgeCurrencyRateEntry = {\n conversionDate: number;\n conversionRate: number;\n usdConversionRate: number;\n};\n\n/**\n * Bridge-compatible market data entry (TokenRatesController marketData shape).\n */\nexport type BridgeMarketDataEntry = {\n price: number;\n currency: string;\n assetId?: string;\n chainId?: string;\n tokenAddress?: string;\n [key: string]: unknown;\n};\n\n/**\n * Exchange rates in the format expected by the bridge controller:\n * conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)\n * + marketData (TokenRatesController) + currentCurrency.\n */\nexport type BridgeExchangeRatesFormat = {\n conversionRates: Record<string, BridgeConversionRateEntry>;\n currencyRates: Record<string, BridgeCurrencyRateEntry>;\n marketData: Record<string, Record<string, BridgeMarketDataEntry>>;\n currentCurrency: string;\n};\n\nfunction getPriceNumber(price: AssetPrice): number {\n return typeof price === 'object' && price !== null && 'price' in price\n ? Number((price as { price: number }).price)\n : Number.NaN;\n}\n\n/**\n * Converts AssetsController state (assetsPrice, selectedCurrency) into the\n * same format the bridge expects from MultichainAssetsRatesController,\n * CurrencyRateController, and TokenRatesController so the bridge can use\n * a single action when useAssetsControllerForRates is true.\n *\n * @param params - Conversion parameters.\n * @param params.assetsPrice - Map of CAIP-19 asset ID to price data. Prices are in USD.\n * @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').\n * @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.\n * @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').\n * @param params.usdToSelectedCurrencyRate - Optional rate: 1 USD = this many units of selected currency. Required for correct bridge USD conversion when selectedCurrency is not 'usd'. When omitted and selectedCurrency !== 'usd', currencyRates will use the same value for conversionRate and usdConversionRate (ratio 1), which produces incorrect USD rates.\n * @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.\n */\nexport function formatExchangeRatesForBridge(params: {\n assetsPrice: Record<string, AssetPrice>;\n selectedCurrency: string;\n nativeAssetIdentifiers?: Record<string, string>;\n networkConfigurationsByChainId?: Record<string, { nativeCurrency?: string }>;\n usdToSelectedCurrencyRate?: number;\n}): BridgeExchangeRatesFormat {\n const {\n assetsPrice,\n selectedCurrency,\n nativeAssetIdentifiers = {},\n networkConfigurationsByChainId = {},\n usdToSelectedCurrencyRate,\n } = params;\n const conversionRates: Record<string, BridgeConversionRateEntry> = {};\n const currencyRates: Record<string, BridgeCurrencyRateEntry> = {};\n const marketData: Record<string, Record<string, BridgeMarketDataEntry>> = {};\n\n // Same as MultichainAssetsRatesController: resolve CAIP currency from selectedCurrency, default to USD\n const currencyCaip =\n MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()] ??\n MAP_CAIP_CURRENCIES.usd;\n\n const expirationOffset = 60;\n\n // Price in assetsPrice is in USD. For bridge: conversionRate = in user's currency, usdConversionRate = in USD.\n const isUsd = selectedCurrency.toLowerCase() === 'usd';\n const rateUserCurrencyPerUsd = isUsd ? 1 : (usdToSelectedCurrencyRate ?? 1);\n\n for (const [assetId, priceData] of Object.entries(assetsPrice)) {\n const price = getPriceNumber(priceData);\n if (Number.isNaN(price) || price < 0) {\n continue;\n }\n\n const lastUpdated =\n typeof priceData === 'object' &&\n priceData !== null &&\n 'lastUpdated' in priceData\n ? Number((priceData as { lastUpdated: number }).lastUpdated)\n : Date.now();\n const conversionTime =\n lastUpdated > 1e12 ? lastUpdated / 1000 : lastUpdated;\n const expirationTime = conversionTime + expirationOffset;\n\n try {\n const parsed = parseCaipAssetType(assetId as Caip19AssetId);\n const chainIdParsed = parseCaipChainId(parsed.chainId);\n const chainRef = chainIdParsed.reference;\n\n // conversionRates: only non-EVM assets (bridge uses this for non-EVM chains). Rate in selected currency.\n if (chainIdParsed.namespace !== 'eip155') {\n const priceInUserCurrency = price * rateUserCurrencyPerUsd;\n conversionRates[assetId] = {\n rate: String(priceInUserCurrency),\n currency: currencyCaip,\n conversionTime,\n expirationTime,\n marketData:\n typeof priceData === 'object' && priceData !== null\n ? (priceData as Record<string, unknown>)\n : undefined,\n };\n }\n\n if (chainIdParsed.namespace === 'eip155') {\n const chainIdHex = numberToHex(parseInt(chainRef, 10));\n const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] ?? null;\n const symbol =\n networkConfigurationsByChainId[chainIdHex]?.nativeCurrency ?? 'ETH';\n const nativePrice =\n nativeAssetId && assetsPrice[nativeAssetId]\n ? getPriceNumber(assetsPrice[nativeAssetId])\n : Number.NaN;\n\n let tokenAddress: string | null = null;\n if (parsed.assetNamespace === 'erc20') {\n tokenAddress = toChecksumAddress(String(parsed.assetReference));\n } else if (parsed.assetNamespace === 'slip44') {\n tokenAddress = '0x0000000000000000000000000000000000000000';\n }\n\n if (tokenAddress && nativeAssetId) {\n const priceInNative =\n !Number.isNaN(nativePrice) && nativePrice > 0\n ? price / nativePrice\n : price;\n if (!marketData[chainIdHex]) {\n marketData[chainIdHex] = {};\n }\n const baseMarketData =\n typeof priceData === 'object' && priceData !== null\n ? (priceData as Record<string, unknown>)\n : {};\n marketData[chainIdHex][tokenAddress] = {\n ...baseMarketData,\n price: priceInNative,\n currency: symbol,\n assetId,\n chainId: chainIdHex,\n tokenAddress,\n };\n }\n\n if (parsed.assetNamespace === 'slip44' && nativeAssetId) {\n // conversionRate = native price in user's currency; usdConversionRate = native price in USD (bridge uses ratio for USD conversion)\n currencyRates[symbol] = {\n conversionDate: conversionTime,\n conversionRate: price * rateUserCurrencyPerUsd,\n usdConversionRate: price,\n };\n }\n }\n } catch {\n // Skip malformed asset IDs\n }\n }\n\n return {\n conversionRates,\n currencyRates,\n marketData,\n currentCurrency: selectedCurrency,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"formatExchangeRatesForBridge.mjs","sourceRoot":"","sources":["../../src/utils/formatExchangeRatesForBridge.ts"],"names":[],"mappings":"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","sourcesContent":["import { toChecksumAddress } from '@ethereumjs/util';\nimport {\n CurrencyRateState,\n MAP_CAIP_CURRENCIES,\n MarketDataDetails,\n MultichainAssetsRatesControllerState,\n TokenRatesControllerState,\n} from '@metamask/assets-controllers';\nimport { Hex, KnownCaipNamespace, numberToHex } from '@metamask/utils';\nimport { parseCaipAssetType, parseCaipChainId } from '@metamask/utils';\n\nimport type { AssetPrice, FungibleAssetPrice, Caip19AssetId } from '../types';\n\n/**\n * Exchange rates in the format expected by the bridge controller:\n * conversionRates (MultichainAssetsRatesController) + currencyRates (CurrencyRateController)\n * + marketData (TokenRatesController) + currentCurrency.\n */\nexport type BridgeExchangeRatesFormat = {\n conversionRates: MultichainAssetsRatesControllerState['conversionRates'];\n currencyRates: CurrencyRateState['currencyRates'];\n marketData: TokenRatesControllerState['marketData'];\n currentCurrency: string;\n};\n\n/**\n * Converts AssetsController state (assetsPrice, selectedCurrency) into the\n * same format the bridge expects from MultichainAssetsRatesController,\n * CurrencyRateController, and TokenRatesController so the bridge can use\n * a single action when useAssetsControllerForRates is true.\n *\n * @param params - Conversion parameters.\n * @param params.assetsPrice - Map of CAIP-19 asset ID to price data (must include both `price` and `usdPrice`).\n * @param params.selectedCurrency - ISO 4217 currency code (e.g. 'usd').\n * @param params.nativeAssetIdentifiers - Optional map of CAIP-2 chain ID to native asset ID (e.g. from NetworkEnablementController state). When provided, used for EVM native lookups.\n * @param params.networkConfigurationsByChainId - Optional map of Hex chain ID to network config (e.g. from NetworkController state). Used to resolve native currency symbol via `nativeCurrency`; keys are Hex (e.g. '0x1').\n * @returns Bridge-compatible conversionRates, currencyRates, marketData, currentCurrency.\n */\nexport function formatExchangeRatesForBridge(params: {\n assetsPrice: Record<string, AssetPrice>;\n selectedCurrency: string;\n nativeAssetIdentifiers?: Record<string, string>;\n networkConfigurationsByChainId?: Record<string, { nativeCurrency?: string }>;\n}): BridgeExchangeRatesFormat {\n const {\n assetsPrice,\n selectedCurrency,\n nativeAssetIdentifiers = {},\n networkConfigurationsByChainId = {},\n } = params;\n const conversionRates: MultichainAssetsRatesControllerState['conversionRates'] =\n {};\n const currencyRates: CurrencyRateState['currencyRates'] = {};\n const marketData: TokenRatesControllerState['marketData'] = {};\n\n const currencyCaip = MAP_CAIP_CURRENCIES[selectedCurrency.toLowerCase()];\n if (!currencyCaip) {\n return {\n conversionRates: {},\n currencyRates: {},\n marketData: {},\n currentCurrency: selectedCurrency,\n };\n }\n\n const fungibleAssetsPrice = Object.entries(assetsPrice).reduce<\n Record<Caip19AssetId, FungibleAssetPrice>\n >((acc, [assetId, priceData]) => {\n if (priceData.assetPriceType === 'fungible') {\n acc[assetId as Caip19AssetId] = priceData;\n }\n return acc;\n }, {});\n\n for (const [assetId, priceData] of Object.entries(fungibleAssetsPrice)) {\n const { price, usdPrice, lastUpdated } = priceData;\n if (price < 0) {\n continue;\n }\n\n const lastUpdatedInSeconds = lastUpdated / 1000;\n const expirationOffsetInSeconds = 60;\n const expirationTime = lastUpdatedInSeconds + expirationOffsetInSeconds;\n\n try {\n const parsed = parseCaipAssetType(assetId as Caip19AssetId);\n const chainIdParsed = parseCaipChainId(parsed.chainId);\n\n if (chainIdParsed.namespace === KnownCaipNamespace.Eip155) {\n const chainIdHex = numberToHex(parseInt(chainIdParsed.reference, 10));\n\n const nativeAssetId = nativeAssetIdentifiers[parsed.chainId] as\n | Caip19AssetId\n | undefined;\n\n const nativeCurrencySymbol =\n networkConfigurationsByChainId[chainIdHex]?.nativeCurrency;\n\n const nativeAssetUsdPrice =\n nativeAssetId && fungibleAssetsPrice[nativeAssetId]?.usdPrice;\n\n if (\n !nativeAssetId ||\n !nativeCurrencySymbol ||\n nativeAssetUsdPrice === undefined\n ) {\n // If we do not have a native asset for that chain or a price for it, the asset needs to be skipped\n continue;\n }\n\n let tokenAddress: Hex | undefined;\n if (parsed.assetNamespace === 'erc20') {\n tokenAddress = toChecksumAddress(String(parsed.assetReference));\n } else if (parsed.assetNamespace === 'slip44') {\n tokenAddress = '0x0000000000000000000000000000000000000000';\n }\n\n if (tokenAddress && nativeAssetId) {\n const priceInNative =\n nativeAssetUsdPrice > 0 ? usdPrice / nativeAssetUsdPrice : usdPrice;\n if (!marketData[chainIdHex]) {\n marketData[chainIdHex] = {};\n }\n marketData[chainIdHex][tokenAddress] = {\n ...priceData,\n price: priceInNative,\n currency: nativeCurrencySymbol,\n assetId,\n chainId: chainIdHex,\n tokenAddress,\n } as MarketDataDetails;\n }\n\n if (parsed.assetNamespace === 'slip44' && nativeAssetId) {\n currencyRates[nativeCurrencySymbol] = {\n conversionDate: lastUpdatedInSeconds,\n conversionRate: price,\n usdConversionRate: usdPrice,\n };\n }\n } else {\n conversionRates[assetId as Caip19AssetId] = {\n rate: String(price),\n currency: currencyCaip,\n conversionTime: lastUpdatedInSeconds,\n expirationTime,\n marketData: {\n fungible: true,\n allTimeHigh: `${priceData.allTimeHigh}`,\n allTimeLow: `${priceData.allTimeLow}`,\n circulatingSupply: `${priceData.circulatingSupply}`,\n marketCap: `${priceData.marketCap}`,\n totalVolume: `${priceData.totalVolume}`,\n pricePercentChange: {\n PT1H: priceData.pricePercentChange1h as number,\n P1D: priceData.pricePercentChange1d as number,\n P7D: priceData.pricePercentChange7d as number,\n P14D: priceData.pricePercentChange14d as number,\n P30D: priceData.pricePercentChange30d as number,\n P200D: priceData.pricePercentChange200d as number,\n P1Y: priceData.pricePercentChange1y as number,\n },\n },\n } as MultichainAssetsRatesControllerState['conversionRates'][Caip19AssetId];\n }\n } catch {\n // Skip malformed asset IDs\n }\n }\n\n return {\n conversionRates,\n currencyRates,\n marketData,\n currentCurrency: selectedCurrency,\n };\n}\n"]}
|