@metamask-previews/transaction-pay-controller 22.3.1-preview-150787a7d → 22.3.1-preview-2fd84c8
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 +5 -0
- package/dist/strategy/fiat/fiat-submit.cjs +15 -29
- package/dist/strategy/fiat/fiat-submit.cjs.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.cts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.d.mts.map +1 -1
- package/dist/strategy/fiat/fiat-submit.mjs +17 -31
- package/dist/strategy/fiat/fiat-submit.mjs.map +1 -1
- package/dist/strategy/fiat/utils.cjs +76 -1
- package/dist/strategy/fiat/utils.cjs.map +1 -1
- package/dist/strategy/fiat/utils.d.cts +34 -0
- package/dist/strategy/fiat/utils.d.cts.map +1 -1
- package/dist/strategy/fiat/utils.d.mts +34 -0
- package/dist/strategy/fiat/utils.d.mts.map +1 -1
- package/dist/strategy/fiat/utils.mjs +73 -0
- package/dist/strategy/fiat/utils.mjs.map +1 -1
- package/dist/utils/transaction.cjs +137 -1
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts +24 -0
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts +24 -0
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +135 -0
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Derive fiat order source amount from on-chain transaction data (`order.txHash`) with fallback to `order.cryptoAmount` ([#8694](https://github.com/MetaMask/core/pull/8694))
|
|
13
|
+
- Persist fiat order ID and provider code on `transaction.metamaskPay` before polling, so activity views can query order status after controller state cleanup ([#8694](https://github.com/MetaMask/core/pull/8694))
|
|
14
|
+
|
|
10
15
|
## [22.3.1]
|
|
11
16
|
|
|
12
17
|
### Changed
|
|
@@ -6,6 +6,7 @@ const utils_1 = require("@metamask/utils");
|
|
|
6
6
|
const bignumber_js_1 = require("bignumber.js");
|
|
7
7
|
const logger_1 = require("../../logger.cjs");
|
|
8
8
|
const token_1 = require("../../utils/token.cjs");
|
|
9
|
+
const transaction_1 = require("../../utils/transaction.cjs");
|
|
9
10
|
const relay_quotes_1 = require("../relay/relay-quotes.cjs");
|
|
10
11
|
const relay_submit_1 = require("../relay/relay-submit.cjs");
|
|
11
12
|
const utils_2 = require("./utils.cjs");
|
|
@@ -46,6 +47,14 @@ async function submitFiatQuotes(request) {
|
|
|
46
47
|
if (!providerCode) {
|
|
47
48
|
throw new Error('Missing provider code for fiat submission');
|
|
48
49
|
}
|
|
50
|
+
(0, transaction_1.updateTransaction)({
|
|
51
|
+
transactionId,
|
|
52
|
+
messenger,
|
|
53
|
+
note: 'Persist fiat order metadata',
|
|
54
|
+
}, (tx) => {
|
|
55
|
+
tx.metamaskPay ?? (tx.metamaskPay = {});
|
|
56
|
+
tx.metamaskPay.fiat = { orderId, provider: providerCode };
|
|
57
|
+
});
|
|
49
58
|
log('Starting fiat order polling', {
|
|
50
59
|
orderId,
|
|
51
60
|
providerCode,
|
|
@@ -79,28 +88,6 @@ function extractProviderCode(provider) {
|
|
|
79
88
|
const parts = provider.split('/').filter(Boolean);
|
|
80
89
|
return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;
|
|
81
90
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Converts the order's human-readable crypto amount to a raw token amount.
|
|
84
|
-
*
|
|
85
|
-
* @param options - The conversion options.
|
|
86
|
-
* @param options.cryptoAmount - Human-readable crypto amount from the completed order.
|
|
87
|
-
* @param options.decimals - Token decimals for the fiat asset.
|
|
88
|
-
* @returns The raw token amount as a string.
|
|
89
|
-
*/
|
|
90
|
-
function getRawSourceAmountFromOrder({ cryptoAmount, decimals, }) {
|
|
91
|
-
const normalizedAmount = new bignumber_js_1.BigNumber(String(cryptoAmount));
|
|
92
|
-
if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {
|
|
93
|
-
throw new Error(`Invalid fiat order crypto amount: ${String(cryptoAmount)}`);
|
|
94
|
-
}
|
|
95
|
-
const rawAmount = normalizedAmount
|
|
96
|
-
.shiftedBy(decimals)
|
|
97
|
-
.decimalPlaces(0, bignumber_js_1.BigNumber.ROUND_DOWN)
|
|
98
|
-
.toFixed(0);
|
|
99
|
-
if (!new bignumber_js_1.BigNumber(rawAmount).gt(0)) {
|
|
100
|
-
throw new Error('Computed fiat order source amount is not positive');
|
|
101
|
-
}
|
|
102
|
-
return rawAmount;
|
|
103
|
-
}
|
|
104
91
|
/**
|
|
105
92
|
* Validates that the completed order's crypto asset matches the expected fiat asset.
|
|
106
93
|
*
|
|
@@ -218,13 +205,12 @@ async function submitRelayAfterFiatCompletion({ order, request, }) {
|
|
|
218
205
|
orderCrypto: order.cryptoCurrency,
|
|
219
206
|
transactionId,
|
|
220
207
|
});
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
decimals: tokenInfo.decimals,
|
|
208
|
+
const walletAddress = transaction.txParams.from;
|
|
209
|
+
const sourceAmountRaw = await (0, utils_2.resolveSourceAmountRaw)({
|
|
210
|
+
messenger,
|
|
211
|
+
order,
|
|
212
|
+
fiatAsset,
|
|
213
|
+
walletAddress,
|
|
228
214
|
});
|
|
229
215
|
const baseRequest = quotes[0].request;
|
|
230
216
|
const relayRequest = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { buildCaipAssetType, getTokenInfo } from '../../utils/token';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport { submitRelayQuotes } from '../relay/relay-submit';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\n\nconst ORDER_POLL_INTERVAL_MS = 1000;\nconst ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;\nconst MAX_SLIPPAGE_PERCENT = 5;\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const walletAddress = transaction.txParams.from as Hex | undefined;\n\n if (!walletAddress) {\n throw new Error('Missing wallet address for fiat submission');\n }\n\n const state = messenger.call('TransactionPayController:getState');\n const fiatPayment = state.transactionData[transactionId]?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID for fiat submission');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code for fiat submission');\n }\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const order = await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n return await submitRelayAfterFiatCompletion({ order, request });\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * @param provider - Provider string (e.g. `/providers/transak-native`).\n * @returns The provider code, or `null` if the format is invalid.\n */\nfunction extractProviderCode(provider: string | undefined): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nfunction getRawSourceAmountFromOrder({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Fiat order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Fiat order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Validates that the re-quoted relay target output hasn't drifted beyond the\n * acceptable slippage threshold compared to the original quote shown to the user.\n *\n * @param options - The validation options.\n * @param options.originalTargetRaw - Raw target amount from the original relay quote.\n * @param options.reQuotedTargetRaw - Raw target amount from the re-quoted relay.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateRelaySlippage({\n originalTargetRaw,\n reQuotedTargetRaw,\n transactionId,\n}: {\n originalTargetRaw: string;\n reQuotedTargetRaw: string;\n transactionId: string;\n}): void {\n const original = new BigNumber(originalTargetRaw);\n const reQuoted = new BigNumber(reQuotedTargetRaw);\n\n if (!original.gt(0) || !reQuoted.gt(0)) {\n return;\n }\n\n const slippagePercent = original\n .minus(reQuoted)\n .dividedBy(original)\n .multipliedBy(100);\n\n log('Relay slippage check', {\n originalTargetRaw,\n reQuotedTargetRaw,\n slippagePercent: slippagePercent.toFixed(2),\n transactionId,\n });\n\n if (slippagePercent.gt(MAX_SLIPPAGE_PERCENT)) {\n throw new Error(\n `Relay re-quote slippage too high for transaction ` +\n `${slippagePercent.toFixed(2)}% exceeds ${MAX_SLIPPAGE_PERCENT}% max`,\n );\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= ORDER_POLL_TIMEOUT_MS) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, ORDER_POLL_INTERVAL_MS));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (!quotes.length) {\n throw new Error('Missing fiat quote for relay submission');\n }\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n throw new Error(\n `Unable to resolve token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n const sourceAmountRaw = getRawSourceAmountFromOrder({\n cryptoAmount: order.cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n\n const baseRequest = quotes[0].request;\n const relayRequest: QuoteRequest = {\n ...baseRequest,\n isMaxAmount: true,\n isPostQuote: false,\n sourceBalanceRaw: sourceAmountRaw,\n sourceTokenAmount: sourceAmountRaw,\n };\n\n log('Re-quoting relay from completed fiat order', {\n completedOrderAmount: order.cryptoAmount,\n relayRequest,\n sourceAmountRaw,\n transactionId,\n });\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702: request.accountSupports7702,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n if (!relayQuotes.length) {\n throw new Error('No relay quotes returned for completed fiat order');\n }\n\n const originalRelayQuote = quotes[0].original.relayQuote;\n validateRelaySlippage({\n originalTargetRaw: originalRelayQuote.details.currencyOut.amount,\n reQuotedTargetRaw: relayQuotes[0].original.details.currencyOut.amount,\n transactionId,\n });\n\n log('Received relay quotes for completed fiat order', {\n relayQuoteCount: relayQuotes.length,\n transactionId,\n });\n\n const relaySubmitRequest: PayStrategyExecuteRequest<RelayQuote> = {\n accountSupports7702: request.accountSupports7702,\n isSmartTransaction: request.isSmartTransaction,\n messenger,\n quotes: relayQuotes,\n transaction,\n };\n\n const relayResult = await submitRelayQuotes(relaySubmitRequest);\n\n log('Relay submission completed after fiat order', {\n relayResult,\n transactionId,\n });\n\n return relayResult;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fiat-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":";;;AAIA,iEAA8D;AAE9D,2CAAqD;AACrD,+CAAyC;AAEzC,6CAA6C;AAO7C,iDAAuD;AACvD,6DAA4D;AAC5D,4DAAuD;AACvD,4DAA0D;AAI1D,uCAAgF;AAEhF,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,aAAa,CAAC,CAAC;AAE7D,MAAM,sBAAsB,GAAG,IAAI,CAAC;AACpC,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAC7C,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,MAAM,yBAAyB,GAAuB;IACpD,mCAAgB,CAAC,SAAS;IAC1B,mCAAgB,CAAC,MAAM;IACvB,mCAAgB,CAAC,SAAS;CAC3B,CAAC;AAEF;;;;;;;;;;GAUG;AACI,KAAK,UAAU,gBAAgB,CACpC,OAA6C;IAE7C,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,CAAC;IACrC,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAuB,CAAC;IAEnE,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC;IACtE,MAAM,OAAO,GAAG,WAAW,EAAE,OAAO,CAAC;IAErC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE5E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,IAAA,+BAAiB,EACf;QACE,aAAa;QACb,SAAS;QACT,IAAI,EAAE,6BAA6B;KACpC,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,WAAW,KAAd,EAAE,CAAC,WAAW,GAAK,EAAE,EAAC;QACtB,EAAE,CAAC,WAAW,CAAC,IAAI,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;IAC5D,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,6BAA6B,EAAE;QACjC,OAAO;QACP,YAAY;QACZ,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,sBAAsB,CAAC;QACzC,SAAS;QACT,SAAS,EAAE,OAAO;QAClB,YAAY;QACZ,aAAa;QACb,aAAa;KACd,CAAC,CAAC;IAEH,GAAG,CAAC,sBAAsB,EAAE;QAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,OAAO;QACP,aAAa;KACd,CAAC,CAAC;IAEH,OAAO,MAAM,8BAA8B,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAClE,CAAC;AA1DD,4CA0DC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,QAA4B;IACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACzE,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,kBAAkB,CAAC,EAC1B,aAAa,EACb,WAAW,EACX,aAAa,GAKd;IACC,MAAM,YAAY,GAAG,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACzD,MAAM,eAAe,GAAG,IAAA,0BAAkB,EACxC,aAAa,CAAC,OAAO,EACrB,aAAa,CAAC,OAAO,CACtB,CAAC,WAAW,EAAE,CAAC;IAChB,MAAM,eAAe,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAEzD,IAAI,YAAY,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,6CAA6C,aAAa,IAAI;YAC5D,YAAY,eAAe,SAAS,YAAY,EAAE,CACrD,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,6CAA6C,aAAa,IAAI;YAC5D,YAAY,eAAe,SAAS,YAAY,EAAE,CACrD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,qBAAqB,CAAC,EAC7B,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GAKd;IACC,MAAM,QAAQ,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,IAAI,wBAAS,CAAC,iBAAiB,CAAC,CAAC;IAElD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAG,QAAQ;SAC7B,KAAK,CAAC,QAAQ,CAAC;SACf,SAAS,CAAC,QAAQ,CAAC;SACnB,YAAY,CAAC,GAAG,CAAC,CAAC;IAErB,GAAG,CAAC,sBAAsB,EAAE;QAC1B,iBAAiB;QACjB,iBAAiB;QACjB,eAAe,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,aAAa;KACd,CAAC,CAAC;IAEH,IAAI,eAAe,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,mDAAmD;YACjD,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,oBAAoB,OAAO,CACxE,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,sBAAsB,CAAC,EACpC,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,GAOd;IACC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,UAA8B,CAAC;IAEnC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,KAA6B,CAAC;QAElC,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAC1B,0BAA0B,EAC1B,YAAY,EACZ,SAAS,EACT,aAAa,CACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;YAE1B,GAAG,CAAC,mBAAmB,EAAE;gBACvB,WAAW,EAAE,KAAK,CAAC,MAAM;gBACzB,YAAY;gBACZ,aAAa;aACd,CAAC,CAAC;YAEH,IAAI,KAAK,CAAC,MAAM,KAAK,mCAAgB,CAAC,SAAS,EAAE,CAAC;gBAChD,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAI,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,qBAAqB,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CACb,8CAA8C,UAAU,GAAG,CAC5D,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,8BAA8B,CAAC,EAC5C,KAAK,EACL,OAAO,GAIR;IACC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,aAAa,GAAG,WAAW,CAAC,EAAE,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,SAAS,GAAG,IAAA,qCAA6B,EAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAExE,kBAAkB,CAAC;QACjB,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,KAAK,CAAC,cAAc;QACjC,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAW,CAAC;IAEvD,MAAM,eAAe,GAAG,MAAM,IAAA,8BAAsB,EAAC;QACnD,SAAS;QACT,KAAK;QACL,SAAS;QACT,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACtC,MAAM,YAAY,GAAiB;QACjC,GAAG,WAAW;QACd,WAAW,EAAE,IAAI;QACjB,WAAW,EAAE,KAAK;QAClB,gBAAgB,EAAE,eAAe;QACjC,iBAAiB,EAAE,eAAe;KACnC,CAAC;IAEF,GAAG,CAAC,4CAA4C,EAAE;QAChD,oBAAoB,EAAE,KAAK,CAAC,YAAY;QACxC,YAAY;QACZ,eAAe;QACf,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,MAAM,IAAA,6BAAc,EAAC;QACvC,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,SAAS;QACT,QAAQ,EAAE,CAAC,YAAY,CAAC;QACxB,WAAW;KACZ,CAAC,CAAC;IAEH,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;IACzD,qBAAqB,CAAC;QACpB,iBAAiB,EAAE,kBAAkB,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM;QAChE,iBAAiB,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM;QACrE,aAAa;KACd,CAAC,CAAC;IAEH,GAAG,CAAC,gDAAgD,EAAE;QACpD,eAAe,EAAE,WAAW,CAAC,MAAM;QACnC,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAA0C;QAChE,mBAAmB,EAAE,OAAO,CAAC,mBAAmB;QAChD,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,SAAS;QACT,MAAM,EAAE,WAAW;QACnB,WAAW;KACZ,CAAC;IAEF,MAAM,WAAW,GAAG,MAAM,IAAA,gCAAiB,EAAC,kBAAkB,CAAC,CAAC;IAEhE,GAAG,CAAC,6CAA6C,EAAE;QACjD,WAAW;QACX,aAAa;KACd,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import type {\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { buildCaipAssetType } from '../../utils/token';\nimport { updateTransaction } from '../../utils/transaction';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport { submitRelayQuotes } from '../relay/relay-submit';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment, resolveSourceAmountRaw } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\n\nconst ORDER_POLL_INTERVAL_MS = 1000;\nconst ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;\nconst MAX_SLIPPAGE_PERCENT = 5;\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const walletAddress = transaction.txParams.from as Hex | undefined;\n\n if (!walletAddress) {\n throw new Error('Missing wallet address for fiat submission');\n }\n\n const state = messenger.call('TransactionPayController:getState');\n const fiatPayment = state.transactionData[transactionId]?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID for fiat submission');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code for fiat submission');\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Persist fiat order metadata',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.fiat = { orderId, provider: providerCode };\n },\n );\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const order = await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n return await submitRelayAfterFiatCompletion({ order, request });\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * @param provider - Provider string (e.g. `/providers/transak-native`).\n * @returns The provider code, or `null` if the format is invalid.\n */\nfunction extractProviderCode(provider: string | undefined): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;\n}\n\n/**\n * Validates that the completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Fiat order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Fiat order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Validates that the re-quoted relay target output hasn't drifted beyond the\n * acceptable slippage threshold compared to the original quote shown to the user.\n *\n * @param options - The validation options.\n * @param options.originalTargetRaw - Raw target amount from the original relay quote.\n * @param options.reQuotedTargetRaw - Raw target amount from the re-quoted relay.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateRelaySlippage({\n originalTargetRaw,\n reQuotedTargetRaw,\n transactionId,\n}: {\n originalTargetRaw: string;\n reQuotedTargetRaw: string;\n transactionId: string;\n}): void {\n const original = new BigNumber(originalTargetRaw);\n const reQuoted = new BigNumber(reQuotedTargetRaw);\n\n if (!original.gt(0) || !reQuoted.gt(0)) {\n return;\n }\n\n const slippagePercent = original\n .minus(reQuoted)\n .dividedBy(original)\n .multipliedBy(100);\n\n log('Relay slippage check', {\n originalTargetRaw,\n reQuotedTargetRaw,\n slippagePercent: slippagePercent.toFixed(2),\n transactionId,\n });\n\n if (slippagePercent.gt(MAX_SLIPPAGE_PERCENT)) {\n throw new Error(\n `Relay re-quote slippage too high for transaction ` +\n `${slippagePercent.toFixed(2)}% exceeds ${MAX_SLIPPAGE_PERCENT}% max`,\n );\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= ORDER_POLL_TIMEOUT_MS) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, ORDER_POLL_INTERVAL_MS));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (!quotes.length) {\n throw new Error('Missing fiat quote for relay submission');\n }\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const walletAddress = transaction.txParams.from as Hex;\n\n const sourceAmountRaw = await resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n });\n\n const baseRequest = quotes[0].request;\n const relayRequest: QuoteRequest = {\n ...baseRequest,\n isMaxAmount: true,\n isPostQuote: false,\n sourceBalanceRaw: sourceAmountRaw,\n sourceTokenAmount: sourceAmountRaw,\n };\n\n log('Re-quoting relay from completed fiat order', {\n completedOrderAmount: order.cryptoAmount,\n relayRequest,\n sourceAmountRaw,\n transactionId,\n });\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702: request.accountSupports7702,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n if (!relayQuotes.length) {\n throw new Error('No relay quotes returned for completed fiat order');\n }\n\n const originalRelayQuote = quotes[0].original.relayQuote;\n validateRelaySlippage({\n originalTargetRaw: originalRelayQuote.details.currencyOut.amount,\n reQuotedTargetRaw: relayQuotes[0].original.details.currencyOut.amount,\n transactionId,\n });\n\n log('Received relay quotes for completed fiat order', {\n relayQuoteCount: relayQuotes.length,\n transactionId,\n });\n\n const relaySubmitRequest: PayStrategyExecuteRequest<RelayQuote> = {\n accountSupports7702: request.accountSupports7702,\n isSmartTransaction: request.isSmartTransaction,\n messenger,\n quotes: relayQuotes,\n transaction,\n };\n\n const relayResult = await submitRelayQuotes(relaySubmitRequest);\n\n log('Relay submission completed after fiat order', {\n relayResult,\n transactionId,\n });\n\n return relayResult;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat-submit.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,wBAAoB;
|
|
1
|
+
{"version":3,"file":"fiat-submit.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,wBAAoB;AAOrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAezC;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,GAC5C,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAwD/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat-submit.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,wBAAoB;
|
|
1
|
+
{"version":3,"file":"fiat-submit.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,yBAAyB,EAG1B,wBAAoB;AAOrB,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AAezC;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,yBAAyB,CAAC,SAAS,CAAC,GAC5C,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,CAwD/C"}
|
|
@@ -2,10 +2,11 @@ import { RampsOrderStatus } from "@metamask/ramps-controller";
|
|
|
2
2
|
import { createModuleLogger } from "@metamask/utils";
|
|
3
3
|
import { BigNumber } from "bignumber.js";
|
|
4
4
|
import { projectLogger } from "../../logger.mjs";
|
|
5
|
-
import { buildCaipAssetType
|
|
5
|
+
import { buildCaipAssetType } from "../../utils/token.mjs";
|
|
6
|
+
import { updateTransaction } from "../../utils/transaction.mjs";
|
|
6
7
|
import { getRelayQuotes } from "../relay/relay-quotes.mjs";
|
|
7
8
|
import { submitRelayQuotes } from "../relay/relay-submit.mjs";
|
|
8
|
-
import { deriveFiatAssetForFiatPayment } from "./utils.mjs";
|
|
9
|
+
import { deriveFiatAssetForFiatPayment, resolveSourceAmountRaw } from "./utils.mjs";
|
|
9
10
|
const log = createModuleLogger(projectLogger, 'fiat-submit');
|
|
10
11
|
const ORDER_POLL_INTERVAL_MS = 1000;
|
|
11
12
|
const ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;
|
|
@@ -43,6 +44,14 @@ export async function submitFiatQuotes(request) {
|
|
|
43
44
|
if (!providerCode) {
|
|
44
45
|
throw new Error('Missing provider code for fiat submission');
|
|
45
46
|
}
|
|
47
|
+
updateTransaction({
|
|
48
|
+
transactionId,
|
|
49
|
+
messenger,
|
|
50
|
+
note: 'Persist fiat order metadata',
|
|
51
|
+
}, (tx) => {
|
|
52
|
+
tx.metamaskPay ?? (tx.metamaskPay = {});
|
|
53
|
+
tx.metamaskPay.fiat = { orderId, provider: providerCode };
|
|
54
|
+
});
|
|
46
55
|
log('Starting fiat order polling', {
|
|
47
56
|
orderId,
|
|
48
57
|
providerCode,
|
|
@@ -75,28 +84,6 @@ function extractProviderCode(provider) {
|
|
|
75
84
|
const parts = provider.split('/').filter(Boolean);
|
|
76
85
|
return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;
|
|
77
86
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Converts the order's human-readable crypto amount to a raw token amount.
|
|
80
|
-
*
|
|
81
|
-
* @param options - The conversion options.
|
|
82
|
-
* @param options.cryptoAmount - Human-readable crypto amount from the completed order.
|
|
83
|
-
* @param options.decimals - Token decimals for the fiat asset.
|
|
84
|
-
* @returns The raw token amount as a string.
|
|
85
|
-
*/
|
|
86
|
-
function getRawSourceAmountFromOrder({ cryptoAmount, decimals, }) {
|
|
87
|
-
const normalizedAmount = new BigNumber(String(cryptoAmount));
|
|
88
|
-
if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {
|
|
89
|
-
throw new Error(`Invalid fiat order crypto amount: ${String(cryptoAmount)}`);
|
|
90
|
-
}
|
|
91
|
-
const rawAmount = normalizedAmount
|
|
92
|
-
.shiftedBy(decimals)
|
|
93
|
-
.decimalPlaces(0, BigNumber.ROUND_DOWN)
|
|
94
|
-
.toFixed(0);
|
|
95
|
-
if (!new BigNumber(rawAmount).gt(0)) {
|
|
96
|
-
throw new Error('Computed fiat order source amount is not positive');
|
|
97
|
-
}
|
|
98
|
-
return rawAmount;
|
|
99
|
-
}
|
|
100
87
|
/**
|
|
101
88
|
* Validates that the completed order's crypto asset matches the expected fiat asset.
|
|
102
89
|
*
|
|
@@ -214,13 +201,12 @@ async function submitRelayAfterFiatCompletion({ order, request, }) {
|
|
|
214
201
|
orderCrypto: order.cryptoCurrency,
|
|
215
202
|
transactionId,
|
|
216
203
|
});
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
decimals: tokenInfo.decimals,
|
|
204
|
+
const walletAddress = transaction.txParams.from;
|
|
205
|
+
const sourceAmountRaw = await resolveSourceAmountRaw({
|
|
206
|
+
messenger,
|
|
207
|
+
order,
|
|
208
|
+
fiatAsset,
|
|
209
|
+
walletAddress,
|
|
224
210
|
});
|
|
225
211
|
const baseRequest = quotes[0].request;
|
|
226
212
|
const relayRequest = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fiat-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { buildCaipAssetType, getTokenInfo } from '../../utils/token';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport { submitRelayQuotes } from '../relay/relay-submit';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\n\nconst ORDER_POLL_INTERVAL_MS = 1000;\nconst ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;\nconst MAX_SLIPPAGE_PERCENT = 5;\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const walletAddress = transaction.txParams.from as Hex | undefined;\n\n if (!walletAddress) {\n throw new Error('Missing wallet address for fiat submission');\n }\n\n const state = messenger.call('TransactionPayController:getState');\n const fiatPayment = state.transactionData[transactionId]?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID for fiat submission');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code for fiat submission');\n }\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const order = await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n return await submitRelayAfterFiatCompletion({ order, request });\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * @param provider - Provider string (e.g. `/providers/transak-native`).\n * @returns The provider code, or `null` if the format is invalid.\n */\nfunction extractProviderCode(provider: string | undefined): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nfunction getRawSourceAmountFromOrder({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n\n/**\n * Validates that the completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Fiat order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Fiat order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Validates that the re-quoted relay target output hasn't drifted beyond the\n * acceptable slippage threshold compared to the original quote shown to the user.\n *\n * @param options - The validation options.\n * @param options.originalTargetRaw - Raw target amount from the original relay quote.\n * @param options.reQuotedTargetRaw - Raw target amount from the re-quoted relay.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateRelaySlippage({\n originalTargetRaw,\n reQuotedTargetRaw,\n transactionId,\n}: {\n originalTargetRaw: string;\n reQuotedTargetRaw: string;\n transactionId: string;\n}): void {\n const original = new BigNumber(originalTargetRaw);\n const reQuoted = new BigNumber(reQuotedTargetRaw);\n\n if (!original.gt(0) || !reQuoted.gt(0)) {\n return;\n }\n\n const slippagePercent = original\n .minus(reQuoted)\n .dividedBy(original)\n .multipliedBy(100);\n\n log('Relay slippage check', {\n originalTargetRaw,\n reQuotedTargetRaw,\n slippagePercent: slippagePercent.toFixed(2),\n transactionId,\n });\n\n if (slippagePercent.gt(MAX_SLIPPAGE_PERCENT)) {\n throw new Error(\n `Relay re-quote slippage too high for transaction ` +\n `${slippagePercent.toFixed(2)}% exceeds ${MAX_SLIPPAGE_PERCENT}% max`,\n );\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= ORDER_POLL_TIMEOUT_MS) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, ORDER_POLL_INTERVAL_MS));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (!quotes.length) {\n throw new Error('Missing fiat quote for relay submission');\n }\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n throw new Error(\n `Unable to resolve token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n const sourceAmountRaw = getRawSourceAmountFromOrder({\n cryptoAmount: order.cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n\n const baseRequest = quotes[0].request;\n const relayRequest: QuoteRequest = {\n ...baseRequest,\n isMaxAmount: true,\n isPostQuote: false,\n sourceBalanceRaw: sourceAmountRaw,\n sourceTokenAmount: sourceAmountRaw,\n };\n\n log('Re-quoting relay from completed fiat order', {\n completedOrderAmount: order.cryptoAmount,\n relayRequest,\n sourceAmountRaw,\n transactionId,\n });\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702: request.accountSupports7702,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n if (!relayQuotes.length) {\n throw new Error('No relay quotes returned for completed fiat order');\n }\n\n const originalRelayQuote = quotes[0].original.relayQuote;\n validateRelaySlippage({\n originalTargetRaw: originalRelayQuote.details.currencyOut.amount,\n reQuotedTargetRaw: relayQuotes[0].original.details.currencyOut.amount,\n transactionId,\n });\n\n log('Received relay quotes for completed fiat order', {\n relayQuoteCount: relayQuotes.length,\n transactionId,\n });\n\n const relaySubmitRequest: PayStrategyExecuteRequest<RelayQuote> = {\n accountSupports7702: request.accountSupports7702,\n isSmartTransaction: request.isSmartTransaction,\n messenger,\n quotes: relayQuotes,\n transaction,\n };\n\n const relayResult = await submitRelayQuotes(relaySubmitRequest);\n\n log('Relay submission completed after fiat order', {\n relayResult,\n transactionId,\n });\n\n return relayResult;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fiat-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/fiat/fiat-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n RampsOrder,\n RampsOrderCryptoCurrency,\n} from '@metamask/ramps-controller';\nimport { RampsOrderStatus } from '@metamask/ramps-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type {\n PayStrategy,\n PayStrategyExecuteRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../../types';\nimport { buildCaipAssetType } from '../../utils/token';\nimport { updateTransaction } from '../../utils/transaction';\nimport { getRelayQuotes } from '../relay/relay-quotes';\nimport { submitRelayQuotes } from '../relay/relay-submit';\nimport type { RelayQuote } from '../relay/types';\nimport type { TransactionPayFiatAsset } from './constants';\nimport type { FiatQuote } from './types';\nimport { deriveFiatAssetForFiatPayment, resolveSourceAmountRaw } from './utils';\n\nconst log = createModuleLogger(projectLogger, 'fiat-submit');\n\nconst ORDER_POLL_INTERVAL_MS = 1000;\nconst ORDER_POLL_TIMEOUT_MS = 10 * 60 * 1000;\nconst MAX_SLIPPAGE_PERCENT = 5;\n\nconst TERMINAL_FAILURE_STATUSES: RampsOrderStatus[] = [\n RampsOrderStatus.Cancelled,\n RampsOrderStatus.Failed,\n RampsOrderStatus.IdExpired,\n];\n\n/**\n * Submits fiat strategy quotes by polling the on-ramp order until completion,\n * then re-quoting and submitting the relay leg with the settled crypto amount.\n *\n * @param request - Strategy execute request containing fiat quotes, messenger, and transaction metadata.\n * @param request.messenger - Controller messenger for cross-controller calls.\n * @param request.quotes - Fiat quotes to execute (exactly one expected).\n * @param request.transaction - Original transaction metadata.\n * @param request.isSmartTransaction - Callback to check smart transaction eligibility.\n * @returns An object containing the relay transaction hash if available.\n */\nexport async function submitFiatQuotes(\n request: PayStrategyExecuteRequest<FiatQuote>,\n): ReturnType<PayStrategy<FiatQuote>['execute']> {\n const { messenger, transaction } = request;\n const transactionId = transaction.id;\n const walletAddress = transaction.txParams.from as Hex | undefined;\n\n if (!walletAddress) {\n throw new Error('Missing wallet address for fiat submission');\n }\n\n const state = messenger.call('TransactionPayController:getState');\n const fiatPayment = state.transactionData[transactionId]?.fiatPayment;\n const orderId = fiatPayment?.orderId;\n\n if (!orderId) {\n throw new Error('Missing order ID for fiat submission');\n }\n\n const providerCode = extractProviderCode(fiatPayment?.rampsQuote?.provider);\n\n if (!providerCode) {\n throw new Error('Missing provider code for fiat submission');\n }\n\n updateTransaction(\n {\n transactionId,\n messenger,\n note: 'Persist fiat order metadata',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.fiat = { orderId, provider: providerCode };\n },\n );\n\n log('Starting fiat order polling', {\n orderId,\n providerCode,\n transactionId,\n });\n\n const order = await waitForOrderCompletion({\n messenger,\n orderCode: orderId,\n providerCode,\n transactionId,\n walletAddress,\n });\n\n log('Fiat order completed', {\n cryptoAmount: order.cryptoAmount,\n orderId,\n transactionId,\n });\n\n return await submitRelayAfterFiatCompletion({ order, request });\n}\n\n/**\n * Extracts the provider code from a ramps provider string.\n *\n * @param provider - Provider string (e.g. `/providers/transak-native`).\n * @returns The provider code, or `null` if the format is invalid.\n */\nfunction extractProviderCode(provider: string | undefined): string | null {\n if (!provider) {\n return null;\n }\n\n const parts = provider.split('/').filter(Boolean);\n return parts.length >= 2 && parts[0] === 'providers' ? parts[1] : null;\n}\n\n/**\n * Validates that the completed order's crypto asset matches the expected fiat asset.\n *\n * @param options - The validation options.\n * @param options.expectedAsset - The expected fiat asset derived from the transaction type.\n * @param options.orderCrypto - The crypto currency information from the completed order.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateOrderAsset({\n expectedAsset,\n orderCrypto,\n transactionId,\n}: {\n expectedAsset: TransactionPayFiatAsset;\n orderCrypto: RampsOrderCryptoCurrency | undefined;\n transactionId: string;\n}): void {\n const orderAssetId = orderCrypto?.assetId?.toLowerCase();\n const expectedAssetId = buildCaipAssetType(\n expectedAsset.chainId,\n expectedAsset.address,\n ).toLowerCase();\n const expectedChainId = expectedAssetId.split('/')[0];\n const orderChainId = orderCrypto?.chainId?.toLowerCase();\n\n if (orderAssetId && orderAssetId !== expectedAssetId) {\n throw new Error(\n `Fiat order asset mismatch for transaction ${transactionId}: ` +\n `expected ${expectedAssetId}, got ${orderAssetId}`,\n );\n }\n\n if (orderChainId && orderChainId !== expectedChainId) {\n throw new Error(\n `Fiat order chain mismatch for transaction ${transactionId}: ` +\n `expected ${expectedChainId}, got ${orderChainId}`,\n );\n }\n}\n\n/**\n * Validates that the re-quoted relay target output hasn't drifted beyond the\n * acceptable slippage threshold compared to the original quote shown to the user.\n *\n * @param options - The validation options.\n * @param options.originalTargetRaw - Raw target amount from the original relay quote.\n * @param options.reQuotedTargetRaw - Raw target amount from the re-quoted relay.\n * @param options.transactionId - Transaction ID for error reporting.\n */\nfunction validateRelaySlippage({\n originalTargetRaw,\n reQuotedTargetRaw,\n transactionId,\n}: {\n originalTargetRaw: string;\n reQuotedTargetRaw: string;\n transactionId: string;\n}): void {\n const original = new BigNumber(originalTargetRaw);\n const reQuoted = new BigNumber(reQuotedTargetRaw);\n\n if (!original.gt(0) || !reQuoted.gt(0)) {\n return;\n }\n\n const slippagePercent = original\n .minus(reQuoted)\n .dividedBy(original)\n .multipliedBy(100);\n\n log('Relay slippage check', {\n originalTargetRaw,\n reQuotedTargetRaw,\n slippagePercent: slippagePercent.toFixed(2),\n transactionId,\n });\n\n if (slippagePercent.gt(MAX_SLIPPAGE_PERCENT)) {\n throw new Error(\n `Relay re-quote slippage too high for transaction ` +\n `${slippagePercent.toFixed(2)}% exceeds ${MAX_SLIPPAGE_PERCENT}% max`,\n );\n }\n}\n\n/**\n * Polls the on-ramp order until it reaches a terminal status.\n *\n * @param options - The polling options.\n * @param options.messenger - Controller messenger for calling `RampsController:getOrder`.\n * @param options.orderCode - The order identifier within the provider.\n * @param options.providerCode - The on-ramp provider code (e.g. \"transak\").\n * @param options.transactionId - Transaction ID for logging.\n * @param options.walletAddress - Wallet address associated with the order.\n * @returns The completed order data.\n */\nasync function waitForOrderCompletion({\n messenger,\n orderCode,\n providerCode,\n transactionId,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n orderCode: string;\n providerCode: string;\n transactionId: string;\n walletAddress: string;\n}): Promise<RampsOrder> {\n const startTime = Date.now();\n let lastStatus: string | undefined;\n\n while (true) {\n let order: RampsOrder | undefined;\n\n try {\n order = await messenger.call(\n 'RampsController:getOrder',\n providerCode,\n orderCode,\n walletAddress,\n );\n } catch (error) {\n log('Order polling network error', error);\n }\n\n if (order) {\n lastStatus = order.status;\n\n log('Polled fiat order', {\n orderStatus: order.status,\n providerCode,\n transactionId,\n });\n\n if (order.status === RampsOrderStatus.Completed) {\n return order;\n }\n\n if (TERMINAL_FAILURE_STATUSES.includes(order.status)) {\n throw new Error(`Fiat order ${order.status.toLowerCase()}`);\n }\n }\n\n if (Date.now() - startTime >= ORDER_POLL_TIMEOUT_MS) {\n throw new Error(\n `Fiat order polling timed out (last status: ${lastStatus})`,\n );\n }\n\n await new Promise((resolve) => setTimeout(resolve, ORDER_POLL_INTERVAL_MS));\n }\n}\n\n/**\n * Re-quotes and submits the relay leg using the settled amount from a completed fiat order.\n *\n * @param options - The submission options.\n * @param options.order - The completed on-ramp order containing the settled crypto amount.\n * @param options.request - The original fiat strategy execute request.\n * @returns An object containing the relay transaction hash if available.\n */\nasync function submitRelayAfterFiatCompletion({\n order,\n request,\n}: {\n order: RampsOrder;\n request: PayStrategyExecuteRequest<FiatQuote>;\n}): Promise<{ transactionHash?: Hex }> {\n const { messenger, quotes, transaction } = request;\n const transactionId = transaction.id;\n\n if (!quotes.length) {\n throw new Error('Missing fiat quote for relay submission');\n }\n\n if (quotes.length > 1) {\n throw new Error('Multiple fiat quotes are not supported for submission');\n }\n\n const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);\n\n validateOrderAsset({\n expectedAsset: fiatAsset,\n orderCrypto: order.cryptoCurrency,\n transactionId,\n });\n\n const walletAddress = transaction.txParams.from as Hex;\n\n const sourceAmountRaw = await resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n });\n\n const baseRequest = quotes[0].request;\n const relayRequest: QuoteRequest = {\n ...baseRequest,\n isMaxAmount: true,\n isPostQuote: false,\n sourceBalanceRaw: sourceAmountRaw,\n sourceTokenAmount: sourceAmountRaw,\n };\n\n log('Re-quoting relay from completed fiat order', {\n completedOrderAmount: order.cryptoAmount,\n relayRequest,\n sourceAmountRaw,\n transactionId,\n });\n\n const relayQuotes = await getRelayQuotes({\n accountSupports7702: request.accountSupports7702,\n messenger,\n requests: [relayRequest],\n transaction,\n });\n\n if (!relayQuotes.length) {\n throw new Error('No relay quotes returned for completed fiat order');\n }\n\n const originalRelayQuote = quotes[0].original.relayQuote;\n validateRelaySlippage({\n originalTargetRaw: originalRelayQuote.details.currencyOut.amount,\n reQuotedTargetRaw: relayQuotes[0].original.details.currencyOut.amount,\n transactionId,\n });\n\n log('Received relay quotes for completed fiat order', {\n relayQuoteCount: relayQuotes.length,\n transactionId,\n });\n\n const relaySubmitRequest: PayStrategyExecuteRequest<RelayQuote> = {\n accountSupports7702: request.accountSupports7702,\n isSmartTransaction: request.isSmartTransaction,\n messenger,\n quotes: relayQuotes,\n transaction,\n };\n\n const relayResult = await submitRelayQuotes(relaySubmitRequest);\n\n log('Relay submission completed after fiat order', {\n relayResult,\n transactionId,\n });\n\n return relayResult;\n}\n"]}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveFiatAssetForFiatPayment = void 0;
|
|
3
|
+
exports.getRawSourceAmountFromOrderCryptoAmount = exports.resolveSourceAmountRaw = exports.deriveFiatAssetForFiatPayment = void 0;
|
|
4
4
|
const transaction_controller_1 = require("@metamask/transaction-controller");
|
|
5
|
+
const utils_1 = require("@metamask/utils");
|
|
6
|
+
const bignumber_js_1 = require("bignumber.js");
|
|
7
|
+
const logger_1 = require("../../logger.cjs");
|
|
5
8
|
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
9
|
+
const token_1 = require("../../utils/token.cjs");
|
|
10
|
+
const transaction_1 = require("../../utils/transaction.cjs");
|
|
6
11
|
const constants_1 = require("./constants.cjs");
|
|
12
|
+
const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'fiat-utils');
|
|
7
13
|
function deriveFiatAssetForFiatPayment(transaction, messenger) {
|
|
8
14
|
const txType = resolveTransactionType(transaction);
|
|
9
15
|
return (0, feature_flags_1.getFiatAssetPerTransactionType)(messenger, txType);
|
|
@@ -15,4 +21,73 @@ function resolveTransactionType(transaction) {
|
|
|
15
21
|
}
|
|
16
22
|
return transaction.nestedTransactions?.find((tx) => tx.type && constants_1.FIAT_ASSET_ID_BY_TX_TYPE[tx.type] !== undefined)?.type;
|
|
17
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolves the raw source amount for a completed fiat order.
|
|
26
|
+
*
|
|
27
|
+
* Attempts to read the actual transferred amount from the on-chain transaction
|
|
28
|
+
* identified by `order.txHash`. If the on-chain read fails or returns
|
|
29
|
+
* no amount, falls back to computing the amount from `order.cryptoAmount`.
|
|
30
|
+
*
|
|
31
|
+
* @param options - The resolution options.
|
|
32
|
+
* @param options.messenger - Controller messenger for network access.
|
|
33
|
+
* @param options.order - The completed on-ramp order.
|
|
34
|
+
* @param options.fiatAsset - The fiat asset describing the expected token.
|
|
35
|
+
* @param options.walletAddress - Recipient wallet address for on-chain lookup.
|
|
36
|
+
* @returns The raw (atomic) source amount as a decimal string.
|
|
37
|
+
*/
|
|
38
|
+
async function resolveSourceAmountRaw({ messenger, order, fiatAsset, walletAddress, }) {
|
|
39
|
+
if (order.txHash) {
|
|
40
|
+
try {
|
|
41
|
+
const onChainAmount = await (0, transaction_1.getTransferredAmountFromTxHash)({
|
|
42
|
+
messenger,
|
|
43
|
+
txHash: order.txHash,
|
|
44
|
+
chainId: fiatAsset.chainId,
|
|
45
|
+
tokenAddress: fiatAsset.address,
|
|
46
|
+
walletAddress,
|
|
47
|
+
});
|
|
48
|
+
if (onChainAmount) {
|
|
49
|
+
log('Resolved source amount from on-chain transaction', {
|
|
50
|
+
txHash: order.txHash,
|
|
51
|
+
onChainAmount,
|
|
52
|
+
});
|
|
53
|
+
return onChainAmount;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
log('Failed to read on-chain amount, falling back to order.cryptoAmount', { txHash: order.txHash, error });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const tokenInfo = (0, token_1.getTokenInfo)(messenger, fiatAsset.address, fiatAsset.chainId);
|
|
61
|
+
if (!tokenInfo) {
|
|
62
|
+
throw new Error(`Unable to resolve token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`);
|
|
63
|
+
}
|
|
64
|
+
return getRawSourceAmountFromOrderCryptoAmount({
|
|
65
|
+
cryptoAmount: order.cryptoAmount,
|
|
66
|
+
decimals: tokenInfo.decimals,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
exports.resolveSourceAmountRaw = resolveSourceAmountRaw;
|
|
70
|
+
/**
|
|
71
|
+
* Converts the order's human-readable crypto amount to a raw token amount.
|
|
72
|
+
*
|
|
73
|
+
* @param options - The conversion options.
|
|
74
|
+
* @param options.cryptoAmount - Human-readable crypto amount from the completed order.
|
|
75
|
+
* @param options.decimals - Token decimals for the fiat asset.
|
|
76
|
+
* @returns The raw token amount as a string.
|
|
77
|
+
*/
|
|
78
|
+
function getRawSourceAmountFromOrderCryptoAmount({ cryptoAmount, decimals, }) {
|
|
79
|
+
const normalizedAmount = new bignumber_js_1.BigNumber(String(cryptoAmount));
|
|
80
|
+
if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {
|
|
81
|
+
throw new Error(`Invalid fiat order crypto amount: ${String(cryptoAmount)}`);
|
|
82
|
+
}
|
|
83
|
+
const rawAmount = normalizedAmount
|
|
84
|
+
.shiftedBy(decimals)
|
|
85
|
+
.decimalPlaces(0, bignumber_js_1.BigNumber.ROUND_DOWN)
|
|
86
|
+
.toFixed(0);
|
|
87
|
+
if (!new bignumber_js_1.BigNumber(rawAmount).gt(0)) {
|
|
88
|
+
throw new Error('Computed fiat order source amount is not positive');
|
|
89
|
+
}
|
|
90
|
+
return rawAmount;
|
|
91
|
+
}
|
|
92
|
+
exports.getRawSourceAmountFromOrderCryptoAmount = getRawSourceAmountFromOrderCryptoAmount;
|
|
18
93
|
//# sourceMappingURL=utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RampsOrder } from '@metamask/ramps-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport { projectLogger } from '../../logger';\nimport type { TransactionPayControllerMessenger } from '../../types';\nimport { getFiatAssetPerTransactionType } from '../../utils/feature-flags';\nimport { getTokenInfo } from '../../utils/token';\nimport { getTransferredAmountFromTxHash } from '../../utils/transaction';\nimport type { TransactionPayFiatAsset } from './constants';\nimport { FIAT_ASSET_ID_BY_TX_TYPE } from './constants';\n\nconst log = createModuleLogger(projectLogger, 'fiat-utils');\n\nexport function deriveFiatAssetForFiatPayment(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): TransactionPayFiatAsset {\n const txType = resolveTransactionType(transaction);\n\n return getFiatAssetPerTransactionType(messenger, txType);\n}\n\nfunction resolveTransactionType(\n transaction: TransactionMeta,\n): TransactionType | undefined {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n return transaction.nestedTransactions?.find(\n (tx) => tx.type && FIAT_ASSET_ID_BY_TX_TYPE[tx.type] !== undefined,\n )?.type;\n}\n\n/**\n * Resolves the raw source amount for a completed fiat order.\n *\n * Attempts to read the actual transferred amount from the on-chain transaction\n * identified by `order.txHash`. If the on-chain read fails or returns\n * no amount, falls back to computing the amount from `order.cryptoAmount`.\n *\n * @param options - The resolution options.\n * @param options.messenger - Controller messenger for network access.\n * @param options.order - The completed on-ramp order.\n * @param options.fiatAsset - The fiat asset describing the expected token.\n * @param options.walletAddress - Recipient wallet address for on-chain lookup.\n * @returns The raw (atomic) source amount as a decimal string.\n */\nexport async function resolveSourceAmountRaw({\n messenger,\n order,\n fiatAsset,\n walletAddress,\n}: {\n messenger: TransactionPayControllerMessenger;\n order: RampsOrder;\n fiatAsset: TransactionPayFiatAsset;\n walletAddress: Hex;\n}): Promise<string> {\n if (order.txHash) {\n try {\n const onChainAmount = await getTransferredAmountFromTxHash({\n messenger,\n txHash: order.txHash,\n chainId: fiatAsset.chainId,\n tokenAddress: fiatAsset.address,\n walletAddress,\n });\n\n if (onChainAmount) {\n log('Resolved source amount from on-chain transaction', {\n txHash: order.txHash,\n onChainAmount,\n });\n return onChainAmount;\n }\n } catch (error) {\n log(\n 'Failed to read on-chain amount, falling back to order.cryptoAmount',\n { txHash: order.txHash, error },\n );\n }\n }\n\n const tokenInfo = getTokenInfo(\n messenger,\n fiatAsset.address,\n fiatAsset.chainId,\n );\n\n if (!tokenInfo) {\n throw new Error(\n `Unable to resolve token info for fiat asset ${fiatAsset.address} on chain ${fiatAsset.chainId}`,\n );\n }\n\n return getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount: order.cryptoAmount,\n decimals: tokenInfo.decimals,\n });\n}\n\n/**\n * Converts the order's human-readable crypto amount to a raw token amount.\n *\n * @param options - The conversion options.\n * @param options.cryptoAmount - Human-readable crypto amount from the completed order.\n * @param options.decimals - Token decimals for the fiat asset.\n * @returns The raw token amount as a string.\n */\nexport function getRawSourceAmountFromOrderCryptoAmount({\n cryptoAmount,\n decimals,\n}: {\n cryptoAmount: RampsOrder['cryptoAmount'];\n decimals: number;\n}): string {\n const normalizedAmount = new BigNumber(String(cryptoAmount));\n\n if (!normalizedAmount.isFinite() || normalizedAmount.lte(0)) {\n throw new Error(\n `Invalid fiat order crypto amount: ${String(cryptoAmount)}`,\n );\n }\n\n const rawAmount = normalizedAmount\n .shiftedBy(decimals)\n .decimalPlaces(0, BigNumber.ROUND_DOWN)\n .toFixed(0);\n\n if (!new BigNumber(rawAmount).gt(0)) {\n throw new Error('Computed fiat order source amount is not positive');\n }\n\n return rawAmount;\n}\n"]}
|
|
@@ -1,5 +1,39 @@
|
|
|
1
|
+
import type { RampsOrder } from "@metamask/ramps-controller";
|
|
1
2
|
import type { TransactionMeta } from "@metamask/transaction-controller";
|
|
3
|
+
import type { Hex } from "@metamask/utils";
|
|
2
4
|
import type { TransactionPayControllerMessenger } from "../../types.cjs";
|
|
3
5
|
import type { TransactionPayFiatAsset } from "./constants.cjs";
|
|
4
6
|
export declare function deriveFiatAssetForFiatPayment(transaction: TransactionMeta, messenger: TransactionPayControllerMessenger): TransactionPayFiatAsset;
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the raw source amount for a completed fiat order.
|
|
9
|
+
*
|
|
10
|
+
* Attempts to read the actual transferred amount from the on-chain transaction
|
|
11
|
+
* identified by `order.txHash`. If the on-chain read fails or returns
|
|
12
|
+
* no amount, falls back to computing the amount from `order.cryptoAmount`.
|
|
13
|
+
*
|
|
14
|
+
* @param options - The resolution options.
|
|
15
|
+
* @param options.messenger - Controller messenger for network access.
|
|
16
|
+
* @param options.order - The completed on-ramp order.
|
|
17
|
+
* @param options.fiatAsset - The fiat asset describing the expected token.
|
|
18
|
+
* @param options.walletAddress - Recipient wallet address for on-chain lookup.
|
|
19
|
+
* @returns The raw (atomic) source amount as a decimal string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSourceAmountRaw({ messenger, order, fiatAsset, walletAddress, }: {
|
|
22
|
+
messenger: TransactionPayControllerMessenger;
|
|
23
|
+
order: RampsOrder;
|
|
24
|
+
fiatAsset: TransactionPayFiatAsset;
|
|
25
|
+
walletAddress: Hex;
|
|
26
|
+
}): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Converts the order's human-readable crypto amount to a raw token amount.
|
|
29
|
+
*
|
|
30
|
+
* @param options - The conversion options.
|
|
31
|
+
* @param options.cryptoAmount - Human-readable crypto amount from the completed order.
|
|
32
|
+
* @param options.decimals - Token decimals for the fiat asset.
|
|
33
|
+
* @returns The raw token amount as a string.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getRawSourceAmountFromOrderCryptoAmount({ cryptoAmount, decimals, }: {
|
|
36
|
+
cryptoAmount: RampsOrder['cryptoAmount'];
|
|
37
|
+
decimals: number;
|
|
38
|
+
}): string;
|
|
5
39
|
//# sourceMappingURL=utils.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;
|
|
1
|
+
{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAIrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAIzB;AAcD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT"}
|
|
@@ -1,5 +1,39 @@
|
|
|
1
|
+
import type { RampsOrder } from "@metamask/ramps-controller";
|
|
1
2
|
import type { TransactionMeta } from "@metamask/transaction-controller";
|
|
3
|
+
import type { Hex } from "@metamask/utils";
|
|
2
4
|
import type { TransactionPayControllerMessenger } from "../../types.mjs";
|
|
3
5
|
import type { TransactionPayFiatAsset } from "./constants.mjs";
|
|
4
6
|
export declare function deriveFiatAssetForFiatPayment(transaction: TransactionMeta, messenger: TransactionPayControllerMessenger): TransactionPayFiatAsset;
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the raw source amount for a completed fiat order.
|
|
9
|
+
*
|
|
10
|
+
* Attempts to read the actual transferred amount from the on-chain transaction
|
|
11
|
+
* identified by `order.txHash`. If the on-chain read fails or returns
|
|
12
|
+
* no amount, falls back to computing the amount from `order.cryptoAmount`.
|
|
13
|
+
*
|
|
14
|
+
* @param options - The resolution options.
|
|
15
|
+
* @param options.messenger - Controller messenger for network access.
|
|
16
|
+
* @param options.order - The completed on-ramp order.
|
|
17
|
+
* @param options.fiatAsset - The fiat asset describing the expected token.
|
|
18
|
+
* @param options.walletAddress - Recipient wallet address for on-chain lookup.
|
|
19
|
+
* @returns The raw (atomic) source amount as a decimal string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSourceAmountRaw({ messenger, order, fiatAsset, walletAddress, }: {
|
|
22
|
+
messenger: TransactionPayControllerMessenger;
|
|
23
|
+
order: RampsOrder;
|
|
24
|
+
fiatAsset: TransactionPayFiatAsset;
|
|
25
|
+
walletAddress: Hex;
|
|
26
|
+
}): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Converts the order's human-readable crypto amount to a raw token amount.
|
|
29
|
+
*
|
|
30
|
+
* @param options - The conversion options.
|
|
31
|
+
* @param options.cryptoAmount - Human-readable crypto amount from the completed order.
|
|
32
|
+
* @param options.decimals - Token decimals for the fiat asset.
|
|
33
|
+
* @returns The raw token amount as a string.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getRawSourceAmountFromOrderCryptoAmount({ cryptoAmount, decimals, }: {
|
|
36
|
+
cryptoAmount: RampsOrder['cryptoAmount'];
|
|
37
|
+
decimals: number;
|
|
38
|
+
}): string;
|
|
5
39
|
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;
|
|
1
|
+
{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../../src/strategy/fiat/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mCAAmC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,yCAAyC;AAExE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,wBAAoB;AAIrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAoB;AAK3D,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,iCAAiC,GAC3C,uBAAuB,CAIzB;AAcD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,sBAAsB,CAAC,EAC3C,SAAS,EACT,KAAK,EACL,SAAS,EACT,aAAa,GACd,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,GAAG,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0ClB;AAED;;;;;;;GAOG;AACH,wBAAgB,uCAAuC,CAAC,EACtD,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;IACzC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAmBT"}
|