@metamask-previews/bridge-controller 13.0.0-preview-5867b015 → 13.0.0-preview-493eed9
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 +0 -15
- package/dist/bridge-controller.cjs +4 -59
- package/dist/bridge-controller.cjs.map +1 -1
- package/dist/bridge-controller.d.cts +3 -2
- package/dist/bridge-controller.d.cts.map +1 -1
- package/dist/bridge-controller.d.mts +3 -2
- package/dist/bridge-controller.d.mts.map +1 -1
- package/dist/bridge-controller.mjs +5 -60
- package/dist/bridge-controller.mjs.map +1 -1
- package/dist/constants/bridge.cjs +0 -1
- package/dist/constants/bridge.cjs.map +1 -1
- package/dist/constants/bridge.d.cts.map +1 -1
- package/dist/constants/bridge.d.mts.map +1 -1
- package/dist/constants/bridge.mjs +0 -1
- package/dist/constants/bridge.mjs.map +1 -1
- package/dist/index.cjs +1 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -10
- package/dist/index.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +14 -44
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +14 -44
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/caip-formatters.cjs +1 -25
- package/dist/utils/caip-formatters.cjs.map +1 -1
- package/dist/utils/caip-formatters.d.cts +0 -10
- package/dist/utils/caip-formatters.d.cts.map +1 -1
- package/dist/utils/caip-formatters.d.mts +0 -10
- package/dist/utils/caip-formatters.d.mts.map +1 -1
- package/dist/utils/caip-formatters.mjs +2 -25
- package/dist/utils/caip-formatters.mjs.map +1 -1
- package/dist/utils/fetch.cjs +1 -61
- package/dist/utils/fetch.cjs.map +1 -1
- package/dist/utils/fetch.d.cts +1 -21
- package/dist/utils/fetch.d.cts.map +1 -1
- package/dist/utils/fetch.d.mts +1 -21
- package/dist/utils/fetch.d.mts.map +1 -1
- package/dist/utils/fetch.mjs +0 -59
- package/dist/utils/fetch.mjs.map +1 -1
- package/dist/utils/quote.cjs +1 -177
- package/dist/utils/quote.cjs.map +1 -1
- package/dist/utils/quote.d.cts +1 -62
- package/dist/utils/quote.d.cts.map +1 -1
- package/dist/utils/quote.d.mts +1 -62
- package/dist/utils/quote.d.mts.map +1 -1
- package/dist/utils/quote.mjs +0 -164
- package/dist/utils/quote.mjs.map +1 -1
- package/package.json +4 -8
- package/dist/selectors.cjs +0 -214
- package/dist/selectors.cjs.map +0 -1
- package/dist/selectors.d.cts +0 -1329
- package/dist/selectors.d.cts.map +0 -1
- package/dist/selectors.d.mts +0 -1329
- package/dist/selectors.d.mts.map +0 -1
- package/dist/selectors.mjs +0 -210
- package/dist/selectors.mjs.map +0 -1
- package/dist/utils/assets.cjs +0 -30
- package/dist/utils/assets.cjs.map +0 -1
- package/dist/utils/assets.d.cts +0 -9
- package/dist/utils/assets.d.cts.map +0 -1
- package/dist/utils/assets.d.mts +0 -9
- package/dist/utils/assets.d.mts.map +0 -1
- package/dist/utils/assets.mjs +0 -25
- package/dist/utils/assets.mjs.map +0 -1
package/dist/utils/quote.mjs
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
import { toHex, weiHexToGweiDec } from "@metamask/controller-utils";
|
2
|
-
import { BigNumber } from "bignumber.js";
|
3
|
-
import { isNativeAddress } from "./bridge.mjs";
|
4
1
|
export const isValidQuoteRequest = (partialRequest, requireAmount = true) => {
|
5
2
|
const stringFields = [
|
6
3
|
'srcTokenAddress',
|
@@ -33,165 +30,4 @@ export const isValidQuoteRequest = (partialRequest, requireAmount = true) => {
|
|
33
30
|
? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\d*$/u))
|
34
31
|
: true));
|
35
32
|
};
|
36
|
-
/**
|
37
|
-
* Generates a pseudo-unique string that identifies each quote by aggregator, bridge, and steps
|
38
|
-
*
|
39
|
-
* @param quote - The quote to generate an identifier for
|
40
|
-
* @returns A pseudo-unique string that identifies the quote
|
41
|
-
*/
|
42
|
-
export const getQuoteIdentifier = (quote) => `${quote.bridgeId}-${quote.bridges[0]}-${quote.steps.length}`;
|
43
|
-
const calcTokenAmount = (value, decimals) => {
|
44
|
-
const divisor = new BigNumber(10).pow(decimals ?? 0);
|
45
|
-
return new BigNumber(value).div(divisor);
|
46
|
-
};
|
47
|
-
export const calcSolanaTotalNetworkFee = (bridgeQuote, { exchangeRate, usdExchangeRate }) => {
|
48
|
-
const { solanaFeesInLamports } = bridgeQuote;
|
49
|
-
const solanaFeeInNative = calcTokenAmount(solanaFeesInLamports ?? '0', 9);
|
50
|
-
return {
|
51
|
-
amount: solanaFeeInNative.toString(),
|
52
|
-
valueInCurrency: exchangeRate
|
53
|
-
? solanaFeeInNative.times(exchangeRate).toString()
|
54
|
-
: null,
|
55
|
-
usd: usdExchangeRate
|
56
|
-
? solanaFeeInNative.times(usdExchangeRate).toString()
|
57
|
-
: null,
|
58
|
-
};
|
59
|
-
};
|
60
|
-
export const calcToAmount = ({ destTokenAmount, destAsset }, { exchangeRate, usdExchangeRate }) => {
|
61
|
-
const normalizedDestAmount = calcTokenAmount(destTokenAmount, destAsset.decimals);
|
62
|
-
return {
|
63
|
-
amount: normalizedDestAmount.toString(),
|
64
|
-
valueInCurrency: exchangeRate
|
65
|
-
? normalizedDestAmount.times(exchangeRate).toString()
|
66
|
-
: null,
|
67
|
-
usd: usdExchangeRate
|
68
|
-
? normalizedDestAmount.times(usdExchangeRate).toString()
|
69
|
-
: null,
|
70
|
-
};
|
71
|
-
};
|
72
|
-
export const calcSentAmount = ({ srcTokenAmount, srcAsset, feeData }, { exchangeRate, usdExchangeRate }) => {
|
73
|
-
const normalizedSentAmount = calcTokenAmount(new BigNumber(srcTokenAmount).plus(feeData.metabridge.amount), srcAsset.decimals);
|
74
|
-
return {
|
75
|
-
amount: normalizedSentAmount.toString(),
|
76
|
-
valueInCurrency: exchangeRate
|
77
|
-
? normalizedSentAmount.times(exchangeRate).toString()
|
78
|
-
: null,
|
79
|
-
usd: usdExchangeRate
|
80
|
-
? normalizedSentAmount.times(usdExchangeRate).toString()
|
81
|
-
: null,
|
82
|
-
};
|
83
|
-
};
|
84
|
-
export const calcRelayerFee = (bridgeQuote, { exchangeRate, usdExchangeRate }) => {
|
85
|
-
const { quote: { srcAsset, srcTokenAmount, feeData }, trade, } = bridgeQuote;
|
86
|
-
const relayerFeeInNative = calcTokenAmount(new BigNumber(trade.value || '0x0', 16).minus(isNativeAddress(srcAsset.address)
|
87
|
-
? new BigNumber(srcTokenAmount).plus(feeData.metabridge.amount)
|
88
|
-
: 0), 18);
|
89
|
-
return {
|
90
|
-
amount: relayerFeeInNative,
|
91
|
-
valueInCurrency: exchangeRate
|
92
|
-
? relayerFeeInNative.times(exchangeRate)
|
93
|
-
: null,
|
94
|
-
usd: usdExchangeRate ? relayerFeeInNative.times(usdExchangeRate) : null,
|
95
|
-
};
|
96
|
-
};
|
97
|
-
const calcTotalGasFee = ({ bridgeQuote, feePerGasInDecGwei, priorityFeePerGasInDecGwei, nativeToDisplayCurrencyExchangeRate, nativeToUsdExchangeRate, }) => {
|
98
|
-
const { approval, trade, l1GasFeesInHexWei } = bridgeQuote;
|
99
|
-
const totalGasLimitInDec = new BigNumber(trade.gasLimit?.toString() ?? '0').plus(approval?.gasLimit?.toString() ?? '0');
|
100
|
-
const totalFeePerGasInDecGwei = new BigNumber(feePerGasInDecGwei).plus(priorityFeePerGasInDecGwei);
|
101
|
-
const l1GasFeesInDecGWei = weiHexToGweiDec(toHex(l1GasFeesInHexWei ?? '0'));
|
102
|
-
const gasFeesInDecGwei = totalGasLimitInDec
|
103
|
-
.times(totalFeePerGasInDecGwei)
|
104
|
-
.plus(l1GasFeesInDecGWei);
|
105
|
-
const gasFeesInDecEth = gasFeesInDecGwei.times(new BigNumber(10).pow(-9));
|
106
|
-
const gasFeesInDisplayCurrency = nativeToDisplayCurrencyExchangeRate
|
107
|
-
? gasFeesInDecEth.times(nativeToDisplayCurrencyExchangeRate.toString())
|
108
|
-
: null;
|
109
|
-
const gasFeesInUSD = nativeToUsdExchangeRate
|
110
|
-
? gasFeesInDecEth.times(nativeToUsdExchangeRate.toString())
|
111
|
-
: null;
|
112
|
-
return {
|
113
|
-
amount: gasFeesInDecEth.toString(),
|
114
|
-
valueInCurrency: gasFeesInDisplayCurrency?.toString() ?? null,
|
115
|
-
usd: gasFeesInUSD?.toString() ?? null,
|
116
|
-
};
|
117
|
-
};
|
118
|
-
export const calcEstimatedAndMaxTotalGasFee = ({ bridgeQuote, estimatedBaseFeeInDecGwei, maxFeePerGasInDecGwei, maxPriorityFeePerGasInDecGwei, exchangeRate: nativeToDisplayCurrencyExchangeRate, usdExchangeRate: nativeToUsdExchangeRate, }) => {
|
119
|
-
const { amount, valueInCurrency, usd } = calcTotalGasFee({
|
120
|
-
bridgeQuote,
|
121
|
-
feePerGasInDecGwei: estimatedBaseFeeInDecGwei,
|
122
|
-
priorityFeePerGasInDecGwei: maxPriorityFeePerGasInDecGwei,
|
123
|
-
nativeToDisplayCurrencyExchangeRate,
|
124
|
-
nativeToUsdExchangeRate,
|
125
|
-
});
|
126
|
-
const { amount: amountMax, valueInCurrency: valueInCurrencyMax, usd: usdMax, } = calcTotalGasFee({
|
127
|
-
bridgeQuote,
|
128
|
-
feePerGasInDecGwei: maxFeePerGasInDecGwei,
|
129
|
-
priorityFeePerGasInDecGwei: maxPriorityFeePerGasInDecGwei,
|
130
|
-
nativeToDisplayCurrencyExchangeRate,
|
131
|
-
nativeToUsdExchangeRate,
|
132
|
-
});
|
133
|
-
return {
|
134
|
-
amount,
|
135
|
-
amountMax,
|
136
|
-
valueInCurrency,
|
137
|
-
valueInCurrencyMax,
|
138
|
-
usd,
|
139
|
-
usdMax,
|
140
|
-
};
|
141
|
-
};
|
142
|
-
export const calcTotalEstimatedNetworkFee = (gasFee, relayerFee) => {
|
143
|
-
return {
|
144
|
-
amount: new BigNumber(gasFee.amount).plus(relayerFee.amount).toString(),
|
145
|
-
valueInCurrency: gasFee.valueInCurrency
|
146
|
-
? new BigNumber(gasFee.valueInCurrency)
|
147
|
-
.plus(relayerFee.valueInCurrency || '0')
|
148
|
-
.toString()
|
149
|
-
: null,
|
150
|
-
usd: gasFee.usd
|
151
|
-
? new BigNumber(gasFee.usd).plus(relayerFee.usd || '0').toString()
|
152
|
-
: null,
|
153
|
-
};
|
154
|
-
};
|
155
|
-
export const calcTotalMaxNetworkFee = (gasFee, relayerFee) => {
|
156
|
-
return {
|
157
|
-
amount: new BigNumber(gasFee.amountMax).plus(relayerFee.amount).toString(),
|
158
|
-
valueInCurrency: gasFee.valueInCurrencyMax
|
159
|
-
? new BigNumber(gasFee.valueInCurrencyMax)
|
160
|
-
.plus(relayerFee.valueInCurrency || '0')
|
161
|
-
.toString()
|
162
|
-
: null,
|
163
|
-
usd: gasFee.usdMax
|
164
|
-
? new BigNumber(gasFee.usdMax).plus(relayerFee.usd || '0').toString()
|
165
|
-
: null,
|
166
|
-
};
|
167
|
-
};
|
168
|
-
export const calcAdjustedReturn = (toTokenAmount, totalEstimatedNetworkFee) => ({
|
169
|
-
valueInCurrency: toTokenAmount.valueInCurrency && totalEstimatedNetworkFee.valueInCurrency
|
170
|
-
? new BigNumber(toTokenAmount.valueInCurrency)
|
171
|
-
.minus(totalEstimatedNetworkFee.valueInCurrency)
|
172
|
-
.toString()
|
173
|
-
: null,
|
174
|
-
usd: toTokenAmount.usd && totalEstimatedNetworkFee.usd
|
175
|
-
? new BigNumber(toTokenAmount.usd)
|
176
|
-
.minus(totalEstimatedNetworkFee.usd)
|
177
|
-
.toString()
|
178
|
-
: null,
|
179
|
-
});
|
180
|
-
export const calcSwapRate = (sentAmount, destTokenAmount) => new BigNumber(destTokenAmount).div(sentAmount).toString();
|
181
|
-
export const calcCost = (adjustedReturn, sentAmount) => ({
|
182
|
-
valueInCurrency: adjustedReturn.valueInCurrency && sentAmount.valueInCurrency
|
183
|
-
? new BigNumber(sentAmount.valueInCurrency)
|
184
|
-
.minus(adjustedReturn.valueInCurrency)
|
185
|
-
.toString()
|
186
|
-
: null,
|
187
|
-
usd: adjustedReturn.usd && sentAmount.usd
|
188
|
-
? new BigNumber(sentAmount.usd).minus(adjustedReturn.usd).toString()
|
189
|
-
: null,
|
190
|
-
});
|
191
|
-
export const formatEtaInMinutes = (estimatedProcessingTimeInSeconds) => {
|
192
|
-
if (estimatedProcessingTimeInSeconds < 60) {
|
193
|
-
return `< 1`;
|
194
|
-
}
|
195
|
-
return (estimatedProcessingTimeInSeconds / 60).toFixed();
|
196
|
-
};
|
197
33
|
//# sourceMappingURL=quote.mjs.map
|
package/dist/utils/quote.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"quote.mjs","sourceRoot":"","sources":["../../src/utils/quote.ts"],"names":[],"mappings":"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","sourcesContent":["import { toHex, weiHexToGweiDec } from '@metamask/controller-utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { isNativeAddress } from './bridge';\nimport type {\n ExchangeRate,\n GenericQuoteRequest,\n L1GasFees,\n Quote,\n QuoteResponse,\n SolanaFees,\n} from '../types';\n\nexport const isValidQuoteRequest = (\n partialRequest: Partial<GenericQuoteRequest>,\n requireAmount = true,\n): partialRequest is GenericQuoteRequest => {\n const stringFields = [\n 'srcTokenAddress',\n 'destTokenAddress',\n 'srcChainId',\n 'destChainId',\n 'walletAddress',\n ];\n if (requireAmount) {\n stringFields.push('srcTokenAmount');\n }\n const numberFields = [];\n // if slippage is defined, require it to be a number\n if (partialRequest.slippage !== undefined) {\n numberFields.push('slippage');\n }\n\n return (\n stringFields.every(\n (field) =>\n field in partialRequest &&\n typeof partialRequest[field as keyof typeof partialRequest] ===\n 'string' &&\n partialRequest[field as keyof typeof partialRequest] !== undefined &&\n partialRequest[field as keyof typeof partialRequest] !== '' &&\n partialRequest[field as keyof typeof partialRequest] !== null,\n ) &&\n numberFields.every(\n (field) =>\n field in partialRequest &&\n typeof partialRequest[field as keyof typeof partialRequest] ===\n 'number' &&\n partialRequest[field as keyof typeof partialRequest] !== undefined &&\n !isNaN(Number(partialRequest[field as keyof typeof partialRequest])) &&\n partialRequest[field as keyof typeof partialRequest] !== null,\n ) &&\n (requireAmount\n ? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\\d*$/u))\n : true)\n );\n};\n\n/**\n * Generates a pseudo-unique string that identifies each quote by aggregator, bridge, and steps\n *\n * @param quote - The quote to generate an identifier for\n * @returns A pseudo-unique string that identifies the quote\n */\nexport const getQuoteIdentifier = (quote: QuoteResponse['quote']) =>\n `${quote.bridgeId}-${quote.bridges[0]}-${quote.steps.length}`;\n\nconst calcTokenAmount = (value: string | BigNumber, decimals: number) => {\n const divisor = new BigNumber(10).pow(decimals ?? 0);\n return new BigNumber(value).div(divisor);\n};\n\nexport const calcSolanaTotalNetworkFee = (\n bridgeQuote: QuoteResponse & SolanaFees,\n { exchangeRate, usdExchangeRate }: ExchangeRate,\n) => {\n const { solanaFeesInLamports } = bridgeQuote;\n const solanaFeeInNative = calcTokenAmount(solanaFeesInLamports ?? '0', 9);\n return {\n amount: solanaFeeInNative.toString(),\n valueInCurrency: exchangeRate\n ? solanaFeeInNative.times(exchangeRate).toString()\n : null,\n usd: usdExchangeRate\n ? solanaFeeInNative.times(usdExchangeRate).toString()\n : null,\n };\n};\n\nexport const calcToAmount = (\n { destTokenAmount, destAsset }: Quote,\n { exchangeRate, usdExchangeRate }: ExchangeRate,\n) => {\n const normalizedDestAmount = calcTokenAmount(\n destTokenAmount,\n destAsset.decimals,\n );\n return {\n amount: normalizedDestAmount.toString(),\n valueInCurrency: exchangeRate\n ? normalizedDestAmount.times(exchangeRate).toString()\n : null,\n usd: usdExchangeRate\n ? normalizedDestAmount.times(usdExchangeRate).toString()\n : null,\n };\n};\n\nexport const calcSentAmount = (\n { srcTokenAmount, srcAsset, feeData }: Quote,\n { exchangeRate, usdExchangeRate }: ExchangeRate,\n) => {\n const normalizedSentAmount = calcTokenAmount(\n new BigNumber(srcTokenAmount).plus(feeData.metabridge.amount),\n srcAsset.decimals,\n );\n return {\n amount: normalizedSentAmount.toString(),\n valueInCurrency: exchangeRate\n ? normalizedSentAmount.times(exchangeRate).toString()\n : null,\n usd: usdExchangeRate\n ? normalizedSentAmount.times(usdExchangeRate).toString()\n : null,\n };\n};\n\nexport const calcRelayerFee = (\n bridgeQuote: QuoteResponse,\n { exchangeRate, usdExchangeRate }: ExchangeRate,\n) => {\n const {\n quote: { srcAsset, srcTokenAmount, feeData },\n trade,\n } = bridgeQuote;\n const relayerFeeInNative = calcTokenAmount(\n new BigNumber(trade.value || '0x0', 16).minus(\n isNativeAddress(srcAsset.address)\n ? new BigNumber(srcTokenAmount).plus(feeData.metabridge.amount)\n : 0,\n ),\n 18,\n );\n return {\n amount: relayerFeeInNative,\n valueInCurrency: exchangeRate\n ? relayerFeeInNative.times(exchangeRate)\n : null,\n usd: usdExchangeRate ? relayerFeeInNative.times(usdExchangeRate) : null,\n };\n};\n\nconst calcTotalGasFee = ({\n bridgeQuote,\n feePerGasInDecGwei,\n priorityFeePerGasInDecGwei,\n nativeToDisplayCurrencyExchangeRate,\n nativeToUsdExchangeRate,\n}: {\n bridgeQuote: QuoteResponse & L1GasFees;\n feePerGasInDecGwei: string;\n priorityFeePerGasInDecGwei: string;\n nativeToDisplayCurrencyExchangeRate?: string;\n nativeToUsdExchangeRate?: string;\n}) => {\n const { approval, trade, l1GasFeesInHexWei } = bridgeQuote;\n\n const totalGasLimitInDec = new BigNumber(\n trade.gasLimit?.toString() ?? '0',\n ).plus(approval?.gasLimit?.toString() ?? '0');\n\n const totalFeePerGasInDecGwei = new BigNumber(feePerGasInDecGwei).plus(\n priorityFeePerGasInDecGwei,\n );\n const l1GasFeesInDecGWei = weiHexToGweiDec(toHex(l1GasFeesInHexWei ?? '0'));\n const gasFeesInDecGwei = totalGasLimitInDec\n .times(totalFeePerGasInDecGwei)\n .plus(l1GasFeesInDecGWei);\n const gasFeesInDecEth = gasFeesInDecGwei.times(new BigNumber(10).pow(-9));\n\n const gasFeesInDisplayCurrency = nativeToDisplayCurrencyExchangeRate\n ? gasFeesInDecEth.times(nativeToDisplayCurrencyExchangeRate.toString())\n : null;\n const gasFeesInUSD = nativeToUsdExchangeRate\n ? gasFeesInDecEth.times(nativeToUsdExchangeRate.toString())\n : null;\n\n return {\n amount: gasFeesInDecEth.toString(),\n valueInCurrency: gasFeesInDisplayCurrency?.toString() ?? null,\n usd: gasFeesInUSD?.toString() ?? null,\n };\n};\n\nexport const calcEstimatedAndMaxTotalGasFee = ({\n bridgeQuote,\n estimatedBaseFeeInDecGwei,\n maxFeePerGasInDecGwei,\n maxPriorityFeePerGasInDecGwei,\n exchangeRate: nativeToDisplayCurrencyExchangeRate,\n usdExchangeRate: nativeToUsdExchangeRate,\n}: {\n bridgeQuote: QuoteResponse & L1GasFees;\n estimatedBaseFeeInDecGwei: string;\n maxFeePerGasInDecGwei: string;\n maxPriorityFeePerGasInDecGwei: string;\n} & ExchangeRate) => {\n const { amount, valueInCurrency, usd } = calcTotalGasFee({\n bridgeQuote,\n feePerGasInDecGwei: estimatedBaseFeeInDecGwei,\n priorityFeePerGasInDecGwei: maxPriorityFeePerGasInDecGwei,\n nativeToDisplayCurrencyExchangeRate,\n nativeToUsdExchangeRate,\n });\n const {\n amount: amountMax,\n valueInCurrency: valueInCurrencyMax,\n usd: usdMax,\n } = calcTotalGasFee({\n bridgeQuote,\n feePerGasInDecGwei: maxFeePerGasInDecGwei,\n priorityFeePerGasInDecGwei: maxPriorityFeePerGasInDecGwei,\n nativeToDisplayCurrencyExchangeRate,\n nativeToUsdExchangeRate,\n });\n return {\n amount,\n amountMax,\n valueInCurrency,\n valueInCurrencyMax,\n usd,\n usdMax,\n };\n};\n\nexport const calcTotalEstimatedNetworkFee = (\n gasFee: ReturnType<typeof calcEstimatedAndMaxTotalGasFee>,\n relayerFee: ReturnType<typeof calcRelayerFee>,\n) => {\n return {\n amount: new BigNumber(gasFee.amount).plus(relayerFee.amount).toString(),\n valueInCurrency: gasFee.valueInCurrency\n ? new BigNumber(gasFee.valueInCurrency)\n .plus(relayerFee.valueInCurrency || '0')\n .toString()\n : null,\n usd: gasFee.usd\n ? new BigNumber(gasFee.usd).plus(relayerFee.usd || '0').toString()\n : null,\n };\n};\n\nexport const calcTotalMaxNetworkFee = (\n gasFee: ReturnType<typeof calcEstimatedAndMaxTotalGasFee>,\n relayerFee: ReturnType<typeof calcRelayerFee>,\n) => {\n return {\n amount: new BigNumber(gasFee.amountMax).plus(relayerFee.amount).toString(),\n valueInCurrency: gasFee.valueInCurrencyMax\n ? new BigNumber(gasFee.valueInCurrencyMax)\n .plus(relayerFee.valueInCurrency || '0')\n .toString()\n : null,\n usd: gasFee.usdMax\n ? new BigNumber(gasFee.usdMax).plus(relayerFee.usd || '0').toString()\n : null,\n };\n};\n\nexport const calcAdjustedReturn = (\n toTokenAmount: ReturnType<typeof calcToAmount>,\n totalEstimatedNetworkFee: ReturnType<typeof calcTotalEstimatedNetworkFee>,\n) => ({\n valueInCurrency:\n toTokenAmount.valueInCurrency && totalEstimatedNetworkFee.valueInCurrency\n ? new BigNumber(toTokenAmount.valueInCurrency)\n .minus(totalEstimatedNetworkFee.valueInCurrency)\n .toString()\n : null,\n usd:\n toTokenAmount.usd && totalEstimatedNetworkFee.usd\n ? new BigNumber(toTokenAmount.usd)\n .minus(totalEstimatedNetworkFee.usd)\n .toString()\n : null,\n});\n\nexport const calcSwapRate = (sentAmount: string, destTokenAmount: string) =>\n new BigNumber(destTokenAmount).div(sentAmount).toString();\n\nexport const calcCost = (\n adjustedReturn: ReturnType<typeof calcAdjustedReturn>,\n sentAmount: ReturnType<typeof calcSentAmount>,\n) => ({\n valueInCurrency:\n adjustedReturn.valueInCurrency && sentAmount.valueInCurrency\n ? new BigNumber(sentAmount.valueInCurrency)\n .minus(adjustedReturn.valueInCurrency)\n .toString()\n : null,\n usd:\n adjustedReturn.usd && sentAmount.usd\n ? new BigNumber(sentAmount.usd).minus(adjustedReturn.usd).toString()\n : null,\n});\n\nexport const formatEtaInMinutes = (\n estimatedProcessingTimeInSeconds: number,\n) => {\n if (estimatedProcessingTimeInSeconds < 60) {\n return `< 1`;\n }\n return (estimatedProcessingTimeInSeconds / 60).toFixed();\n};\n"]}
|
1
|
+
{"version":3,"file":"quote.mjs","sourceRoot":"","sources":["../../src/utils/quote.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,cAA4C,EAC5C,aAAa,GAAG,IAAI,EACmB,EAAE;IACzC,MAAM,YAAY,GAAG;QACnB,iBAAiB;QACjB,kBAAkB;QAClB,YAAY;QACZ,aAAa;QACb,eAAe;KAChB,CAAC;IACF,IAAI,aAAa,EAAE;QACjB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;KACrC;IACD,MAAM,YAAY,GAAG,EAAE,CAAC;IACxB,oDAAoD;IACpD,IAAI,cAAc,CAAC,QAAQ,KAAK,SAAS,EAAE;QACzC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;KAC/B;IAED,OAAO,CACL,YAAY,CAAC,KAAK,CAChB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,IAAI,cAAc;QACvB,OAAO,cAAc,CAAC,KAAoC,CAAC;YACzD,QAAQ;QACV,cAAc,CAAC,KAAoC,CAAC,KAAK,SAAS;QAClE,cAAc,CAAC,KAAoC,CAAC,KAAK,EAAE;QAC3D,cAAc,CAAC,KAAoC,CAAC,KAAK,IAAI,CAChE;QACD,YAAY,CAAC,KAAK,CAChB,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,IAAI,cAAc;YACvB,OAAO,cAAc,CAAC,KAAoC,CAAC;gBACzD,QAAQ;YACV,cAAc,CAAC,KAAoC,CAAC,KAAK,SAAS;YAClE,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC,KAAoC,CAAC,CAAC,CAAC;YACpE,cAAc,CAAC,KAAoC,CAAC,KAAK,IAAI,CAChE;QACD,CAAC,aAAa;YACZ,CAAC,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACrE,CAAC,CAAC,IAAI,CAAC,CACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { GenericQuoteRequest } from '../types';\n\nexport const isValidQuoteRequest = (\n partialRequest: Partial<GenericQuoteRequest>,\n requireAmount = true,\n): partialRequest is GenericQuoteRequest => {\n const stringFields = [\n 'srcTokenAddress',\n 'destTokenAddress',\n 'srcChainId',\n 'destChainId',\n 'walletAddress',\n ];\n if (requireAmount) {\n stringFields.push('srcTokenAmount');\n }\n const numberFields = [];\n // if slippage is defined, require it to be a number\n if (partialRequest.slippage !== undefined) {\n numberFields.push('slippage');\n }\n\n return (\n stringFields.every(\n (field) =>\n field in partialRequest &&\n typeof partialRequest[field as keyof typeof partialRequest] ===\n 'string' &&\n partialRequest[field as keyof typeof partialRequest] !== undefined &&\n partialRequest[field as keyof typeof partialRequest] !== '' &&\n partialRequest[field as keyof typeof partialRequest] !== null,\n ) &&\n numberFields.every(\n (field) =>\n field in partialRequest &&\n typeof partialRequest[field as keyof typeof partialRequest] ===\n 'number' &&\n partialRequest[field as keyof typeof partialRequest] !== undefined &&\n !isNaN(Number(partialRequest[field as keyof typeof partialRequest])) &&\n partialRequest[field as keyof typeof partialRequest] !== null,\n ) &&\n (requireAmount\n ? Boolean((partialRequest.srcTokenAmount ?? '').match(/^[1-9]\\d*$/u))\n : true)\n );\n};\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@metamask-previews/bridge-controller",
|
3
|
-
"version": "13.0.0-preview-
|
3
|
+
"version": "13.0.0-preview-493eed9",
|
4
4
|
"description": "Manages bridge-related quote fetching functionality for MetaMask",
|
5
5
|
"keywords": [
|
6
6
|
"MetaMask",
|
@@ -58,12 +58,11 @@
|
|
58
58
|
"@metamask/metamask-eth-abis": "^3.1.1",
|
59
59
|
"@metamask/multichain-network-controller": "^0.3.0",
|
60
60
|
"@metamask/polling-controller": "^13.0.0",
|
61
|
-
"@metamask/utils": "^
|
62
|
-
"
|
61
|
+
"@metamask/snaps-utils": "^8.10.0",
|
62
|
+
"@metamask/utils": "^11.2.0"
|
63
63
|
},
|
64
64
|
"devDependencies": {
|
65
65
|
"@metamask/accounts-controller": "^27.0.0",
|
66
|
-
"@metamask/assets-controllers": "^56.0.0",
|
67
66
|
"@metamask/auto-changelog": "^3.4.4",
|
68
67
|
"@metamask/eth-json-rpc-provider": "^4.1.8",
|
69
68
|
"@metamask/network-controller": "^23.2.0",
|
@@ -76,7 +75,6 @@
|
|
76
75
|
"jest-environment-jsdom": "^27.5.1",
|
77
76
|
"lodash": "^4.17.21",
|
78
77
|
"nock": "^13.3.1",
|
79
|
-
"reselect": "^5.1.1",
|
80
78
|
"ts-jest": "^27.1.4",
|
81
79
|
"typedoc": "^0.24.8",
|
82
80
|
"typedoc-plugin-missing-exports": "^2.0.0",
|
@@ -84,11 +82,9 @@
|
|
84
82
|
},
|
85
83
|
"peerDependencies": {
|
86
84
|
"@metamask/accounts-controller": "^27.0.0",
|
87
|
-
"@metamask/assets-controllers": "^56.0.0",
|
88
85
|
"@metamask/network-controller": "^23.0.0",
|
89
86
|
"@metamask/snaps-controllers": "^9.19.0",
|
90
|
-
"@metamask/transaction-controller": "^54.0.0"
|
91
|
-
"reselect": "^5.1.1"
|
87
|
+
"@metamask/transaction-controller": "^54.0.0"
|
92
88
|
},
|
93
89
|
"engines": {
|
94
90
|
"node": "^18.18 || >=20"
|
package/dist/selectors.cjs
DELETED
@@ -1,214 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.selectBridgeQuotes = exports.selectIsQuoteExpired = exports.selectIsAssetExchangeRateInState = exports.selectExchangeRateByChainIdAndAddress = void 0;
|
4
|
-
const constants_1 = require("@ethersproject/constants");
|
5
|
-
const utils_1 = require("@metamask/utils");
|
6
|
-
const lodash_1 = require("lodash");
|
7
|
-
const reselect_1 = require("reselect");
|
8
|
-
const types_1 = require("./types.cjs");
|
9
|
-
const bridge_1 = require("./utils/bridge.cjs");
|
10
|
-
const caip_formatters_1 = require("./utils/caip-formatters.cjs");
|
11
|
-
const quote_1 = require("./utils/quote.cjs");
|
12
|
-
/**
|
13
|
-
* Creates a structured selector for the bridge controller
|
14
|
-
*/
|
15
|
-
const createStructuredBridgeSelector = reselect_1.createStructuredSelector.withTypes();
|
16
|
-
/**
|
17
|
-
* Creates a typed selector for the bridge controller
|
18
|
-
*/
|
19
|
-
const createBridgeSelector = reselect_1.createSelector.withTypes();
|
20
|
-
const getExchangeRateByChainIdAndAddress = (exchangeRateSources, chainId, address) => {
|
21
|
-
if (!chainId || !address) {
|
22
|
-
return {};
|
23
|
-
}
|
24
|
-
// TODO return usd exchange rate if user has opted into metrics
|
25
|
-
const assetId = (0, caip_formatters_1.formatAddressToAssetId)(address, chainId);
|
26
|
-
if (!assetId) {
|
27
|
-
return {};
|
28
|
-
}
|
29
|
-
const { assetExchangeRates, currencyRates, marketData, conversionRates } = exchangeRateSources;
|
30
|
-
// If the asset exchange rate is available in the bridge controller, use it
|
31
|
-
// This is defined if the token's rate is not available from the assets controllers
|
32
|
-
const bridgeControllerRate = assetExchangeRates?.[assetId] ??
|
33
|
-
assetExchangeRates?.[assetId.toLowerCase()];
|
34
|
-
if (bridgeControllerRate?.exchangeRate) {
|
35
|
-
return bridgeControllerRate;
|
36
|
-
}
|
37
|
-
// If the chain is a Solana chain, use the conversion rate from the multichain assets controller
|
38
|
-
if ((0, bridge_1.isSolanaChainId)(chainId)) {
|
39
|
-
const multichainAssetExchangeRate = conversionRates?.[assetId];
|
40
|
-
if (multichainAssetExchangeRate) {
|
41
|
-
return {
|
42
|
-
exchangeRate: multichainAssetExchangeRate.rate,
|
43
|
-
usdExchangeRate: undefined,
|
44
|
-
};
|
45
|
-
}
|
46
|
-
return {};
|
47
|
-
}
|
48
|
-
// If the chain is an EVM chain, use the conversion rate from the currency rates controller
|
49
|
-
if ((0, bridge_1.isNativeAddress)(address)) {
|
50
|
-
const { symbol } = (0, bridge_1.getNativeAssetForChainId)(chainId);
|
51
|
-
const evmNativeExchangeRate = currencyRates?.[symbol.toLowerCase()];
|
52
|
-
if (evmNativeExchangeRate) {
|
53
|
-
return {
|
54
|
-
exchangeRate: evmNativeExchangeRate?.conversionRate?.toString(),
|
55
|
-
usdExchangeRate: evmNativeExchangeRate?.usdConversionRate?.toString(),
|
56
|
-
};
|
57
|
-
}
|
58
|
-
return {};
|
59
|
-
}
|
60
|
-
// If the chain is an EVM chain and the asset is not the native asset, use the conversion rate from the token rates controller
|
61
|
-
const evmTokenExchangeRates = marketData?.[(0, caip_formatters_1.formatChainIdToHex)(chainId)];
|
62
|
-
const evmTokenExchangeRateForAddress = (0, utils_1.isStrictHexString)(address)
|
63
|
-
? evmTokenExchangeRates?.[address]
|
64
|
-
: null;
|
65
|
-
if (evmTokenExchangeRateForAddress) {
|
66
|
-
return {
|
67
|
-
exchangeRate: evmTokenExchangeRateForAddress?.price.toString(),
|
68
|
-
usdExchangeRate: undefined,
|
69
|
-
};
|
70
|
-
}
|
71
|
-
return {};
|
72
|
-
};
|
73
|
-
/**
|
74
|
-
* Selects the asset exchange rate for a given chain and address
|
75
|
-
*
|
76
|
-
* @param state The state of the bridge controller and its dependency controllers
|
77
|
-
* @param chainId The chain ID of the asset
|
78
|
-
* @param address The address of the asset
|
79
|
-
* @returns The asset exchange rate for the given chain and address
|
80
|
-
*/
|
81
|
-
const selectExchangeRateByChainIdAndAddress = (state, chainId, address) => {
|
82
|
-
return getExchangeRateByChainIdAndAddress(state, chainId, address);
|
83
|
-
};
|
84
|
-
exports.selectExchangeRateByChainIdAndAddress = selectExchangeRateByChainIdAndAddress;
|
85
|
-
/**
|
86
|
-
* Checks whether an exchange rate is available for a given chain and address
|
87
|
-
*
|
88
|
-
* @param params The parameters to pass to {@link getExchangeRateByChainIdAndAddress}
|
89
|
-
* @returns Whether an exchange rate is available for the given chain and address
|
90
|
-
*/
|
91
|
-
const selectIsAssetExchangeRateInState = (...params) => Boolean(getExchangeRateByChainIdAndAddress(...params)?.exchangeRate);
|
92
|
-
exports.selectIsAssetExchangeRateInState = selectIsAssetExchangeRateInState;
|
93
|
-
// Selects cross-chain swap quotes including their metadata
|
94
|
-
const selectBridgeQuotesWithMetadata = createBridgeSelector([
|
95
|
-
({ quotes }) => quotes,
|
96
|
-
(_, { bridgeFeesPerGas }) => bridgeFeesPerGas,
|
97
|
-
createBridgeSelector([
|
98
|
-
(state) => state,
|
99
|
-
({ quoteRequest: { srcChainId } }) => srcChainId,
|
100
|
-
({ quoteRequest: { srcTokenAddress } }) => srcTokenAddress,
|
101
|
-
], exports.selectExchangeRateByChainIdAndAddress),
|
102
|
-
createBridgeSelector([
|
103
|
-
(state) => state,
|
104
|
-
({ quoteRequest: { destChainId } }) => destChainId,
|
105
|
-
({ quoteRequest: { destTokenAddress } }) => destTokenAddress,
|
106
|
-
], exports.selectExchangeRateByChainIdAndAddress),
|
107
|
-
createBridgeSelector([(state) => state, ({ quoteRequest: { srcChainId } }) => srcChainId], (state, chainId) => (0, exports.selectExchangeRateByChainIdAndAddress)(state, chainId, constants_1.AddressZero)),
|
108
|
-
], (quotes, bridgeFeesPerGas, srcTokenExchangeRate, destTokenExchangeRate, nativeExchangeRate) => {
|
109
|
-
const newQuotes = quotes.map((quote) => {
|
110
|
-
const sentAmount = (0, quote_1.calcSentAmount)(quote.quote, srcTokenExchangeRate);
|
111
|
-
const toTokenAmount = (0, quote_1.calcToAmount)(quote.quote, destTokenExchangeRate);
|
112
|
-
let totalEstimatedNetworkFee, gasFee, totalMaxNetworkFee, relayerFee;
|
113
|
-
if ((0, bridge_1.isSolanaChainId)(quote.quote.srcChainId)) {
|
114
|
-
totalEstimatedNetworkFee = (0, quote_1.calcSolanaTotalNetworkFee)(quote, nativeExchangeRate);
|
115
|
-
gasFee = totalEstimatedNetworkFee;
|
116
|
-
totalMaxNetworkFee = totalEstimatedNetworkFee;
|
117
|
-
}
|
118
|
-
else {
|
119
|
-
relayerFee = (0, quote_1.calcRelayerFee)(quote, nativeExchangeRate);
|
120
|
-
gasFee = (0, quote_1.calcEstimatedAndMaxTotalGasFee)({
|
121
|
-
bridgeQuote: quote,
|
122
|
-
...bridgeFeesPerGas,
|
123
|
-
...nativeExchangeRate,
|
124
|
-
});
|
125
|
-
totalEstimatedNetworkFee = (0, quote_1.calcTotalEstimatedNetworkFee)(gasFee, relayerFee);
|
126
|
-
totalMaxNetworkFee = (0, quote_1.calcTotalMaxNetworkFee)(gasFee, relayerFee);
|
127
|
-
}
|
128
|
-
const adjustedReturn = (0, quote_1.calcAdjustedReturn)(toTokenAmount, totalEstimatedNetworkFee);
|
129
|
-
const cost = (0, quote_1.calcCost)(adjustedReturn, sentAmount);
|
130
|
-
return {
|
131
|
-
...quote,
|
132
|
-
// QuoteMetadata fields
|
133
|
-
sentAmount,
|
134
|
-
toTokenAmount,
|
135
|
-
swapRate: (0, quote_1.calcSwapRate)(sentAmount.amount, toTokenAmount.amount),
|
136
|
-
totalNetworkFee: totalEstimatedNetworkFee,
|
137
|
-
totalMaxNetworkFee,
|
138
|
-
gasFee,
|
139
|
-
adjustedReturn,
|
140
|
-
cost,
|
141
|
-
};
|
142
|
-
});
|
143
|
-
return newQuotes;
|
144
|
-
});
|
145
|
-
const selectSortedBridgeQuotes = createBridgeSelector([
|
146
|
-
selectBridgeQuotesWithMetadata,
|
147
|
-
(_, { sortOrder }) => sortOrder,
|
148
|
-
], (quotesWithMetadata, sortOrder) => {
|
149
|
-
switch (sortOrder) {
|
150
|
-
case types_1.SortOrder.ETA_ASC:
|
151
|
-
return (0, lodash_1.orderBy)(quotesWithMetadata, (quote) => quote.estimatedProcessingTimeInSeconds, 'asc');
|
152
|
-
default:
|
153
|
-
return (0, lodash_1.orderBy)(quotesWithMetadata, ({ cost }) => cost.valueInCurrency ? Number(cost.valueInCurrency) : 0, 'asc');
|
154
|
-
}
|
155
|
-
});
|
156
|
-
const selectRecommendedQuote = createBridgeSelector([selectSortedBridgeQuotes], ([recommendedQuote]) => recommendedQuote);
|
157
|
-
const selectActiveQuote = createBridgeSelector([
|
158
|
-
selectRecommendedQuote,
|
159
|
-
(_, { selectedQuote }) => selectedQuote,
|
160
|
-
], (recommendedQuote, selectedQuote) => selectedQuote ?? recommendedQuote);
|
161
|
-
const selectIsQuoteGoingToRefresh = (state, { featureFlagsKey }) => state.quoteRequest.insufficientBal
|
162
|
-
? false
|
163
|
-
: state.quotesRefreshCount <
|
164
|
-
state.bridgeFeatureFlags[featureFlagsKey].maxRefreshCount;
|
165
|
-
const selectQuoteRefreshRate = createBridgeSelector([
|
166
|
-
({ bridgeFeatureFlags }, { featureFlagsKey }) => bridgeFeatureFlags[featureFlagsKey],
|
167
|
-
(state) => state.quoteRequest.srcChainId,
|
168
|
-
], (featureFlags, srcChainId) => (srcChainId
|
169
|
-
? featureFlags.chains[(0, caip_formatters_1.formatChainIdToCaip)(srcChainId)]?.refreshRate
|
170
|
-
: featureFlags.refreshRate) ?? featureFlags.refreshRate);
|
171
|
-
exports.selectIsQuoteExpired = createBridgeSelector([
|
172
|
-
selectIsQuoteGoingToRefresh,
|
173
|
-
({ quotesLastFetched }) => quotesLastFetched,
|
174
|
-
selectQuoteRefreshRate,
|
175
|
-
(_, __, currentTimeInMs) => currentTimeInMs,
|
176
|
-
], (isQuoteGoingToRefresh, quotesLastFetched, refreshRate, currentTimeInMs) => Boolean(!isQuoteGoingToRefresh &&
|
177
|
-
quotesLastFetched &&
|
178
|
-
currentTimeInMs - quotesLastFetched > refreshRate));
|
179
|
-
/**
|
180
|
-
* Selects sorted cross-chain swap quotes. By default, the quotes are sorted by cost in ascending order.
|
181
|
-
*
|
182
|
-
* @param state - The state of the bridge controller and its dependency controllers
|
183
|
-
* @param bridgeFeesPerGas - The merged client transaction and gas controller estimates for gas
|
184
|
-
* @param sortOrder - The sort order of the quotes
|
185
|
-
* @param selectedQuote - The quote that is currently selected by the user, should be cleared by clients when the req params change
|
186
|
-
* @param featureFlagsKey - The feature flags key for the client (e.g. `BridgeFeatureFlagsKey.EXTENSION_CONFIG`
|
187
|
-
* @returns The activeQuote, recommendedQuote, sortedQuotes, and other quote fetching metadata
|
188
|
-
*
|
189
|
-
* @example
|
190
|
-
* ```ts
|
191
|
-
* const bridgeFeesPerGas = useSelector(getGasFeeEstimates);
|
192
|
-
* const quotes = useSelector(state => selectBridgeQuotes(
|
193
|
-
* state.metamask,
|
194
|
-
* {
|
195
|
-
* bridgeFeesPerGas,
|
196
|
-
* sortOrder: state.bridge.sortOrder,
|
197
|
-
* selectedQuote: state.bridge.selectedQuote,
|
198
|
-
* featureFlagsKey: BridgeFeatureFlagsKey.EXTENSION_CONFIG,
|
199
|
-
* }
|
200
|
-
* ));
|
201
|
-
* ```
|
202
|
-
*/
|
203
|
-
exports.selectBridgeQuotes = createStructuredBridgeSelector({
|
204
|
-
sortedQuotes: selectSortedBridgeQuotes,
|
205
|
-
recommendedQuote: selectRecommendedQuote,
|
206
|
-
activeQuote: selectActiveQuote,
|
207
|
-
quotesLastFetchedMs: (state) => state.quotesLastFetched,
|
208
|
-
isLoading: (state) => state.quotesLoadingStatus === types_1.RequestStatus.LOADING,
|
209
|
-
quoteFetchError: (state) => state.quoteFetchError,
|
210
|
-
quotesRefreshCount: (state) => state.quotesRefreshCount,
|
211
|
-
quotesInitialLoadTimeMs: (state) => state.quotesInitialLoadTime,
|
212
|
-
isQuoteGoingToRefresh: selectIsQuoteGoingToRefresh,
|
213
|
-
});
|
214
|
-
//# sourceMappingURL=selectors.cjs.map
|
package/dist/selectors.cjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"selectors.cjs","sourceRoot":"","sources":["../src/selectors.ts"],"names":[],"mappings":"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","sourcesContent":["import { AddressZero } from '@ethersproject/constants';\nimport type {\n CurrencyRateState,\n MultichainAssetsRatesControllerState,\n TokenRatesControllerState,\n} from '@metamask/assets-controllers';\nimport type { CaipAssetType } from '@metamask/utils';\nimport { isStrictHexString } from '@metamask/utils';\nimport { orderBy } from 'lodash';\nimport {\n createSelector as createSelector_,\n createStructuredSelector as createStructuredSelector_,\n} from 'reselect';\n\nimport type {\n BridgeControllerState,\n BridgeFeatureFlagsKey,\n ExchangeRate,\n GenericQuoteRequest,\n QuoteMetadata,\n QuoteResponse,\n} from './types';\nimport { RequestStatus, SortOrder } from './types';\nimport {\n getNativeAssetForChainId,\n isNativeAddress,\n isSolanaChainId,\n} from './utils/bridge';\nimport {\n formatAddressToAssetId,\n formatChainIdToCaip,\n formatChainIdToHex,\n} from './utils/caip-formatters';\nimport {\n calcAdjustedReturn,\n calcCost,\n calcEstimatedAndMaxTotalGasFee,\n calcRelayerFee,\n calcSentAmount,\n calcSolanaTotalNetworkFee,\n calcSwapRate,\n calcToAmount,\n calcTotalEstimatedNetworkFee,\n calcTotalMaxNetworkFee,\n} from './utils/quote';\n\n/**\n * The controller states that provide exchange rates\n */\ntype ExchangeRateControllerState = MultichainAssetsRatesControllerState &\n TokenRatesControllerState &\n CurrencyRateState &\n Pick<BridgeControllerState, 'assetExchangeRates'>;\n/**\n * The state of the bridge controller and all its dependency controllers\n */\nexport type BridgeAppState = BridgeControllerState &\n ExchangeRateControllerState & {\n participateInMetaMetrics: boolean;\n };\n/**\n * Creates a structured selector for the bridge controller\n */\nconst createStructuredBridgeSelector =\n createStructuredSelector_.withTypes<BridgeAppState>();\n/**\n * Creates a typed selector for the bridge controller\n */\nconst createBridgeSelector = createSelector_.withTypes<BridgeAppState>();\n/**\n * The merged client transaction and gas controller estimates for gas\n */\ntype BridgeFeesPerGas = {\n estimatedBaseFeeInDecGwei: string;\n maxPriorityFeePerGasInDecGwei: string;\n maxFeePerGasInDecGwei: string;\n};\n/**\n * Required parameters that clients must provide for the bridge quotes selector\n */\ntype BridgeQuotesClientParams = {\n bridgeFeesPerGas: BridgeFeesPerGas;\n sortOrder: SortOrder;\n selectedQuote: (QuoteResponse & QuoteMetadata) | null;\n featureFlagsKey: BridgeFeatureFlagsKey;\n};\n\nconst getExchangeRateByChainIdAndAddress = (\n exchangeRateSources: ExchangeRateControllerState,\n chainId?: GenericQuoteRequest['srcChainId'],\n address?: GenericQuoteRequest['srcTokenAddress'],\n): ExchangeRate => {\n if (!chainId || !address) {\n return {};\n }\n // TODO return usd exchange rate if user has opted into metrics\n const assetId = formatAddressToAssetId(address, chainId);\n if (!assetId) {\n return {};\n }\n\n const { assetExchangeRates, currencyRates, marketData, conversionRates } =\n exchangeRateSources;\n\n // If the asset exchange rate is available in the bridge controller, use it\n // This is defined if the token's rate is not available from the assets controllers\n const bridgeControllerRate =\n assetExchangeRates?.[assetId] ??\n assetExchangeRates?.[assetId.toLowerCase() as CaipAssetType];\n if (bridgeControllerRate?.exchangeRate) {\n return bridgeControllerRate;\n }\n // If the chain is a Solana chain, use the conversion rate from the multichain assets controller\n if (isSolanaChainId(chainId)) {\n const multichainAssetExchangeRate = conversionRates?.[assetId];\n if (multichainAssetExchangeRate) {\n return {\n exchangeRate: multichainAssetExchangeRate.rate,\n usdExchangeRate: undefined,\n };\n }\n return {};\n }\n // If the chain is an EVM chain, use the conversion rate from the currency rates controller\n if (isNativeAddress(address)) {\n const { symbol } = getNativeAssetForChainId(chainId);\n const evmNativeExchangeRate = currencyRates?.[symbol.toLowerCase()];\n if (evmNativeExchangeRate) {\n return {\n exchangeRate: evmNativeExchangeRate?.conversionRate?.toString(),\n usdExchangeRate: evmNativeExchangeRate?.usdConversionRate?.toString(),\n };\n }\n return {};\n }\n // If the chain is an EVM chain and the asset is not the native asset, use the conversion rate from the token rates controller\n const evmTokenExchangeRates = marketData?.[formatChainIdToHex(chainId)];\n const evmTokenExchangeRateForAddress = isStrictHexString(address)\n ? evmTokenExchangeRates?.[address]\n : null;\n if (evmTokenExchangeRateForAddress) {\n return {\n exchangeRate: evmTokenExchangeRateForAddress?.price.toString(),\n usdExchangeRate: undefined,\n };\n }\n\n return {};\n};\n\n/**\n * Selects the asset exchange rate for a given chain and address\n *\n * @param state The state of the bridge controller and its dependency controllers\n * @param chainId The chain ID of the asset\n * @param address The address of the asset\n * @returns The asset exchange rate for the given chain and address\n */\nexport const selectExchangeRateByChainIdAndAddress = (\n state: BridgeAppState,\n chainId?: GenericQuoteRequest['srcChainId'],\n address?: GenericQuoteRequest['srcTokenAddress'],\n) => {\n return getExchangeRateByChainIdAndAddress(state, chainId, address);\n};\n\n/**\n * Checks whether an exchange rate is available for a given chain and address\n *\n * @param params The parameters to pass to {@link getExchangeRateByChainIdAndAddress}\n * @returns Whether an exchange rate is available for the given chain and address\n */\nexport const selectIsAssetExchangeRateInState = (\n ...params: Parameters<typeof getExchangeRateByChainIdAndAddress>\n) => Boolean(getExchangeRateByChainIdAndAddress(...params)?.exchangeRate);\n\n// Selects cross-chain swap quotes including their metadata\nconst selectBridgeQuotesWithMetadata = createBridgeSelector(\n [\n ({ quotes }) => quotes,\n (_, { bridgeFeesPerGas }: BridgeQuotesClientParams) => bridgeFeesPerGas,\n createBridgeSelector(\n [\n (state) => state,\n ({ quoteRequest: { srcChainId } }) => srcChainId,\n ({ quoteRequest: { srcTokenAddress } }) => srcTokenAddress,\n ],\n selectExchangeRateByChainIdAndAddress,\n ),\n createBridgeSelector(\n [\n (state) => state,\n ({ quoteRequest: { destChainId } }) => destChainId,\n ({ quoteRequest: { destTokenAddress } }) => destTokenAddress,\n ],\n selectExchangeRateByChainIdAndAddress,\n ),\n createBridgeSelector(\n [(state) => state, ({ quoteRequest: { srcChainId } }) => srcChainId],\n (state, chainId) =>\n selectExchangeRateByChainIdAndAddress(state, chainId, AddressZero),\n ),\n ],\n (\n quotes,\n bridgeFeesPerGas,\n srcTokenExchangeRate,\n destTokenExchangeRate,\n nativeExchangeRate,\n ) => {\n const newQuotes = quotes.map((quote) => {\n const sentAmount = calcSentAmount(quote.quote, srcTokenExchangeRate);\n const toTokenAmount = calcToAmount(quote.quote, destTokenExchangeRate);\n\n let totalEstimatedNetworkFee, gasFee, totalMaxNetworkFee, relayerFee;\n\n if (isSolanaChainId(quote.quote.srcChainId)) {\n totalEstimatedNetworkFee = calcSolanaTotalNetworkFee(\n quote,\n nativeExchangeRate,\n );\n gasFee = totalEstimatedNetworkFee;\n totalMaxNetworkFee = totalEstimatedNetworkFee;\n } else {\n relayerFee = calcRelayerFee(quote, nativeExchangeRate);\n gasFee = calcEstimatedAndMaxTotalGasFee({\n bridgeQuote: quote,\n ...bridgeFeesPerGas,\n ...nativeExchangeRate,\n });\n totalEstimatedNetworkFee = calcTotalEstimatedNetworkFee(\n gasFee,\n relayerFee,\n );\n totalMaxNetworkFee = calcTotalMaxNetworkFee(gasFee, relayerFee);\n }\n\n const adjustedReturn = calcAdjustedReturn(\n toTokenAmount,\n totalEstimatedNetworkFee,\n );\n const cost = calcCost(adjustedReturn, sentAmount);\n\n return {\n ...quote,\n // QuoteMetadata fields\n sentAmount,\n toTokenAmount,\n swapRate: calcSwapRate(sentAmount.amount, toTokenAmount.amount),\n totalNetworkFee: totalEstimatedNetworkFee,\n totalMaxNetworkFee,\n gasFee,\n adjustedReturn,\n cost,\n };\n });\n\n return newQuotes;\n },\n);\n\nconst selectSortedBridgeQuotes = createBridgeSelector(\n [\n selectBridgeQuotesWithMetadata,\n (_, { sortOrder }: BridgeQuotesClientParams) => sortOrder,\n ],\n (quotesWithMetadata, sortOrder): (QuoteResponse & QuoteMetadata)[] => {\n switch (sortOrder) {\n case SortOrder.ETA_ASC:\n return orderBy(\n quotesWithMetadata,\n (quote) => quote.estimatedProcessingTimeInSeconds,\n 'asc',\n );\n default:\n return orderBy(\n quotesWithMetadata,\n ({ cost }) =>\n cost.valueInCurrency ? Number(cost.valueInCurrency) : 0,\n 'asc',\n );\n }\n },\n);\n\nconst selectRecommendedQuote = createBridgeSelector(\n [selectSortedBridgeQuotes],\n ([recommendedQuote]) => recommendedQuote,\n);\n\nconst selectActiveQuote = createBridgeSelector(\n [\n selectRecommendedQuote,\n (_, { selectedQuote }: BridgeQuotesClientParams) => selectedQuote,\n ],\n (recommendedQuote, selectedQuote) => selectedQuote ?? recommendedQuote,\n);\n\nconst selectIsQuoteGoingToRefresh = (\n state: BridgeAppState,\n { featureFlagsKey }: BridgeQuotesClientParams,\n) =>\n state.quoteRequest.insufficientBal\n ? false\n : state.quotesRefreshCount <\n state.bridgeFeatureFlags[featureFlagsKey].maxRefreshCount;\n\nconst selectQuoteRefreshRate = createBridgeSelector(\n [\n ({ bridgeFeatureFlags }, { featureFlagsKey }: BridgeQuotesClientParams) =>\n bridgeFeatureFlags[featureFlagsKey],\n (state) => state.quoteRequest.srcChainId,\n ],\n (featureFlags, srcChainId) =>\n (srcChainId\n ? featureFlags.chains[formatChainIdToCaip(srcChainId)]?.refreshRate\n : featureFlags.refreshRate) ?? featureFlags.refreshRate,\n);\n\nexport const selectIsQuoteExpired = createBridgeSelector(\n [\n selectIsQuoteGoingToRefresh,\n ({ quotesLastFetched }) => quotesLastFetched,\n selectQuoteRefreshRate,\n (_, __, currentTimeInMs: number) => currentTimeInMs,\n ],\n (isQuoteGoingToRefresh, quotesLastFetched, refreshRate, currentTimeInMs) =>\n Boolean(\n !isQuoteGoingToRefresh &&\n quotesLastFetched &&\n currentTimeInMs - quotesLastFetched > refreshRate,\n ),\n);\n\n/**\n * Selects sorted cross-chain swap quotes. By default, the quotes are sorted by cost in ascending order.\n *\n * @param state - The state of the bridge controller and its dependency controllers\n * @param bridgeFeesPerGas - The merged client transaction and gas controller estimates for gas\n * @param sortOrder - The sort order of the quotes\n * @param selectedQuote - The quote that is currently selected by the user, should be cleared by clients when the req params change\n * @param featureFlagsKey - The feature flags key for the client (e.g. `BridgeFeatureFlagsKey.EXTENSION_CONFIG`\n * @returns The activeQuote, recommendedQuote, sortedQuotes, and other quote fetching metadata\n *\n * @example\n * ```ts\n * const bridgeFeesPerGas = useSelector(getGasFeeEstimates);\n * const quotes = useSelector(state => selectBridgeQuotes(\n * state.metamask,\n * {\n * bridgeFeesPerGas,\n * sortOrder: state.bridge.sortOrder,\n * selectedQuote: state.bridge.selectedQuote,\n * featureFlagsKey: BridgeFeatureFlagsKey.EXTENSION_CONFIG,\n * }\n * ));\n * ```\n */\nexport const selectBridgeQuotes = createStructuredBridgeSelector({\n sortedQuotes: selectSortedBridgeQuotes,\n recommendedQuote: selectRecommendedQuote,\n activeQuote: selectActiveQuote,\n quotesLastFetchedMs: (state) => state.quotesLastFetched,\n isLoading: (state) => state.quotesLoadingStatus === RequestStatus.LOADING,\n quoteFetchError: (state) => state.quoteFetchError,\n quotesRefreshCount: (state) => state.quotesRefreshCount,\n quotesInitialLoadTimeMs: (state) => state.quotesInitialLoadTime,\n isQuoteGoingToRefresh: selectIsQuoteGoingToRefresh,\n});\n"]}
|