@metamask/transaction-pay-controller 22.7.0 → 23.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -1
- package/dist/TransactionPayController-method-action-types.cjs.map +1 -1
- package/dist/TransactionPayController-method-action-types.d.cts +15 -1
- package/dist/TransactionPayController-method-action-types.d.cts.map +1 -1
- package/dist/TransactionPayController-method-action-types.d.mts +15 -1
- package/dist/TransactionPayController-method-action-types.d.mts.map +1 -1
- package/dist/TransactionPayController-method-action-types.mjs.map +1 -1
- package/dist/TransactionPayController.cjs +19 -3
- package/dist/TransactionPayController.cjs.map +1 -1
- package/dist/TransactionPayController.d.cts +13 -2
- package/dist/TransactionPayController.d.cts.map +1 -1
- package/dist/TransactionPayController.d.mts +13 -2
- package/dist/TransactionPayController.d.mts.map +1 -1
- package/dist/TransactionPayController.mjs +19 -3
- package/dist/TransactionPayController.mjs.map +1 -1
- package/dist/constants.cjs +1 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +1 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/strategy/across/across-submit.cjs +2 -1
- package/dist/strategy/across/across-submit.cjs.map +1 -1
- package/dist/strategy/across/across-submit.d.cts.map +1 -1
- package/dist/strategy/across/across-submit.d.mts.map +1 -1
- package/dist/strategy/across/across-submit.mjs +2 -1
- package/dist/strategy/across/across-submit.mjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.cjs +20 -3
- package/dist/strategy/relay/relay-quotes.cjs.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.cts.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.mts.map +1 -1
- package/dist/strategy/relay/relay-quotes.mjs +20 -3
- package/dist/strategy/relay/relay-quotes.mjs.map +1 -1
- package/dist/strategy/relay/relay-submit.cjs +27 -13
- package/dist/strategy/relay/relay-submit.cjs.map +1 -1
- package/dist/strategy/relay/relay-submit.d.cts.map +1 -1
- package/dist/strategy/relay/relay-submit.d.mts.map +1 -1
- package/dist/strategy/relay/relay-submit.mjs +27 -13
- package/dist/strategy/relay/relay-submit.mjs.map +1 -1
- package/dist/strategy/server/ServerStrategy.cjs +35 -0
- package/dist/strategy/server/ServerStrategy.cjs.map +1 -0
- package/dist/strategy/server/ServerStrategy.d.cts +15 -0
- package/dist/strategy/server/ServerStrategy.d.cts.map +1 -0
- package/dist/strategy/server/ServerStrategy.d.mts +15 -0
- package/dist/strategy/server/ServerStrategy.d.mts.map +1 -0
- package/dist/strategy/server/ServerStrategy.mjs +31 -0
- package/dist/strategy/server/ServerStrategy.mjs.map +1 -0
- package/dist/strategy/server/constants.cjs +11 -0
- package/dist/strategy/server/constants.cjs.map +1 -0
- package/dist/strategy/server/constants.d.cts +8 -0
- package/dist/strategy/server/constants.d.cts.map +1 -0
- package/dist/strategy/server/constants.d.mts +8 -0
- package/dist/strategy/server/constants.d.mts.map +1 -0
- package/dist/strategy/server/constants.mjs +8 -0
- package/dist/strategy/server/constants.mjs.map +1 -0
- package/dist/strategy/server/perps.cjs +71 -0
- package/dist/strategy/server/perps.cjs.map +1 -0
- package/dist/strategy/server/perps.d.cts +36 -0
- package/dist/strategy/server/perps.d.cts.map +1 -0
- package/dist/strategy/server/perps.d.mts +36 -0
- package/dist/strategy/server/perps.d.mts.map +1 -0
- package/dist/strategy/server/perps.mjs +66 -0
- package/dist/strategy/server/perps.mjs.map +1 -0
- package/dist/strategy/server/server-api.cjs +98 -0
- package/dist/strategy/server/server-api.cjs.map +1 -0
- package/dist/strategy/server/server-api.d.cts +35 -0
- package/dist/strategy/server/server-api.d.cts.map +1 -0
- package/dist/strategy/server/server-api.d.mts +35 -0
- package/dist/strategy/server/server-api.d.mts.map +1 -0
- package/dist/strategy/server/server-api.mjs +92 -0
- package/dist/strategy/server/server-api.mjs.map +1 -0
- package/dist/strategy/server/server-quotes.cjs +315 -0
- package/dist/strategy/server/server-quotes.cjs.map +1 -0
- package/dist/strategy/server/server-quotes.d.cts +10 -0
- package/dist/strategy/server/server-quotes.d.cts.map +1 -0
- package/dist/strategy/server/server-quotes.d.mts +10 -0
- package/dist/strategy/server/server-quotes.d.mts.map +1 -0
- package/dist/strategy/server/server-quotes.mjs +311 -0
- package/dist/strategy/server/server-quotes.mjs.map +1 -0
- package/dist/strategy/server/server-submit.cjs +296 -0
- package/dist/strategy/server/server-submit.cjs.map +1 -0
- package/dist/strategy/server/server-submit.d.cts +13 -0
- package/dist/strategy/server/server-submit.d.cts.map +1 -0
- package/dist/strategy/server/server-submit.d.mts +13 -0
- package/dist/strategy/server/server-submit.d.mts.map +1 -0
- package/dist/strategy/server/server-submit.mjs +292 -0
- package/dist/strategy/server/server-submit.mjs.map +1 -0
- package/dist/strategy/server/types.cjs +26 -0
- package/dist/strategy/server/types.cjs.map +1 -0
- package/dist/strategy/server/types.d.cts +153 -0
- package/dist/strategy/server/types.d.cts.map +1 -0
- package/dist/strategy/server/types.d.mts +153 -0
- package/dist/strategy/server/types.d.mts.map +1 -0
- package/dist/strategy/server/types.mjs +23 -0
- package/dist/strategy/server/types.mjs.map +1 -0
- package/dist/tests/messenger-mock.cjs +6 -0
- package/dist/tests/messenger-mock.cjs.map +1 -1
- package/dist/tests/messenger-mock.d.cts +256 -3
- package/dist/tests/messenger-mock.d.cts.map +1 -1
- package/dist/tests/messenger-mock.d.mts +256 -3
- package/dist/tests/messenger-mock.d.mts.map +1 -1
- package/dist/tests/messenger-mock.mjs +6 -0
- package/dist/tests/messenger-mock.mjs.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +45 -18
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +45 -18
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils/feature-flags.cjs +43 -3
- package/dist/utils/feature-flags.cjs.map +1 -1
- package/dist/utils/feature-flags.d.cts +21 -0
- package/dist/utils/feature-flags.d.cts.map +1 -1
- package/dist/utils/feature-flags.d.mts +21 -0
- package/dist/utils/feature-flags.d.mts.map +1 -1
- package/dist/utils/feature-flags.mjs +40 -2
- package/dist/utils/feature-flags.mjs.map +1 -1
- package/dist/utils/gas.cjs +13 -11
- package/dist/utils/gas.cjs.map +1 -1
- package/dist/utils/gas.d.cts +12 -0
- package/dist/utils/gas.d.cts.map +1 -1
- package/dist/utils/gas.d.mts +12 -0
- package/dist/utils/gas.d.mts.map +1 -1
- package/dist/utils/gas.mjs +12 -11
- package/dist/utils/gas.mjs.map +1 -1
- package/dist/utils/provider.cjs +61 -0
- package/dist/utils/provider.cjs.map +1 -0
- package/dist/utils/provider.d.cts +59 -0
- package/dist/utils/provider.d.cts.map +1 -0
- package/dist/utils/provider.d.mts +59 -0
- package/dist/utils/provider.d.mts.map +1 -0
- package/dist/utils/provider.mjs +56 -0
- package/dist/utils/provider.mjs.map +1 -0
- package/dist/utils/quotes.cjs +9 -3
- package/dist/utils/quotes.cjs.map +1 -1
- package/dist/utils/quotes.d.cts.map +1 -1
- package/dist/utils/quotes.d.mts.map +1 -1
- package/dist/utils/quotes.mjs +10 -4
- package/dist/utils/quotes.mjs.map +1 -1
- package/dist/utils/strategy.cjs +3 -0
- package/dist/utils/strategy.cjs.map +1 -1
- package/dist/utils/strategy.d.cts.map +1 -1
- package/dist/utils/strategy.d.mts.map +1 -1
- package/dist/utils/strategy.mjs +3 -0
- package/dist/utils/strategy.mjs.map +1 -1
- package/dist/utils/token.cjs +28 -16
- package/dist/utils/token.cjs.map +1 -1
- package/dist/utils/token.d.cts +4 -0
- package/dist/utils/token.d.cts.map +1 -1
- package/dist/utils/token.d.mts +4 -0
- package/dist/utils/token.d.mts.map +1 -1
- package/dist/utils/token.mjs +28 -16
- package/dist/utils/token.mjs.map +1 -1
- package/dist/utils/transaction.cjs +28 -20
- package/dist/utils/transaction.cjs.map +1 -1
- package/dist/utils/transaction.d.cts.map +1 -1
- package/dist/utils/transaction.d.mts.map +1 -1
- package/dist/utils/transaction.mjs +28 -20
- package/dist/utils/transaction.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -7,6 +7,7 @@ const utils_1 = require("@metamask/utils");
|
|
|
7
7
|
const bignumber_js_1 = require("bignumber.js");
|
|
8
8
|
const logger_1 = require("../../logger.cjs");
|
|
9
9
|
const feature_flags_1 = require("../../utils/feature-flags.cjs");
|
|
10
|
+
const provider_1 = require("../../utils/provider.cjs");
|
|
10
11
|
const token_1 = require("../../utils/token.cjs");
|
|
11
12
|
const transaction_1 = require("../../utils/transaction.cjs");
|
|
12
13
|
const constants_1 = require("./constants.cjs");
|
|
@@ -236,7 +237,7 @@ async function submitTransactions(quote, transaction, messenger) {
|
|
|
236
237
|
// In post-quote flows (e.g. Predict withdraw), the source tokens are held in
|
|
237
238
|
// the Safe — not the EOA — and only become available after the original tx
|
|
238
239
|
// executes as part of the batch. Skip the EOA balance check here.
|
|
239
|
-
if (!quote.request.isPostQuote) {
|
|
240
|
+
if (!quote.request.isPostQuote && !quote.request.paymentOverride) {
|
|
240
241
|
await validateSourceBalance(quote, messenger);
|
|
241
242
|
}
|
|
242
243
|
const normalizedParams = params.map((singleParams) => normalizeParams(singleParams, messenger));
|
|
@@ -251,7 +252,21 @@ async function submitTransactions(quote, transaction, messenger) {
|
|
|
251
252
|
const hasAccountOverride = quote.request.from.toLowerCase() !==
|
|
252
253
|
transaction.txParams.from.toLowerCase();
|
|
253
254
|
let allParams = normalizedParams;
|
|
254
|
-
if (
|
|
255
|
+
if (quote.request.paymentOverride) {
|
|
256
|
+
const { transactionData } = messenger.call('TransactionPayController:getState');
|
|
257
|
+
const { calls: overrideTxs } = await messenger.call('TransactionPayController:getPaymentOverrideData', {
|
|
258
|
+
amount: quote.sourceAmount.human,
|
|
259
|
+
transaction,
|
|
260
|
+
transactionData: transactionData[transaction.id],
|
|
261
|
+
});
|
|
262
|
+
if (overrideTxs.length > 0) {
|
|
263
|
+
allParams = [
|
|
264
|
+
...overrideTxs,
|
|
265
|
+
...normalizedParams,
|
|
266
|
+
];
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if (isPostQuote && transaction.txParams.to) {
|
|
255
270
|
const prependedParams = hasAccountOverride
|
|
256
271
|
? await buildDelegatedOriginalParams(transaction, messenger)
|
|
257
272
|
: {
|
|
@@ -307,7 +322,7 @@ async function buildDelegatedOriginalParams(transaction, messenger) {
|
|
|
307
322
|
async function submitViaRelayExecute(quote, transaction, messenger, allParams) {
|
|
308
323
|
const { from, sourceChainId } = quote.request;
|
|
309
324
|
const { requestId } = quote.original.steps[0];
|
|
310
|
-
const networkClientId =
|
|
325
|
+
const networkClientId = (0, provider_1.getNetworkClientId)(messenger, sourceChainId);
|
|
311
326
|
const sourceCallTransaction = {
|
|
312
327
|
...transaction,
|
|
313
328
|
chainId: sourceChainId,
|
|
@@ -378,7 +393,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
378
393
|
const transactionIds = [];
|
|
379
394
|
const { from, sourceChainId, sourceTokenAddress } = quote.request;
|
|
380
395
|
const { isPostQuote } = quote.request;
|
|
381
|
-
const networkClientId =
|
|
396
|
+
const networkClientId = (0, provider_1.getNetworkClientId)(messenger, sourceChainId);
|
|
382
397
|
log('Adding transactions', {
|
|
383
398
|
normalizedParams: allParams,
|
|
384
399
|
sourceChainId,
|
|
@@ -434,6 +449,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
434
449
|
const gasLimit7702 = metamask.is7702
|
|
435
450
|
? (0, controller_utils_1.toHex)(metamask.gasLimits[0])
|
|
436
451
|
: undefined;
|
|
452
|
+
const prependCount = allParams.length - normalizedParams.length;
|
|
437
453
|
const transactions = allParams.map((singleParams, index) => {
|
|
438
454
|
const gasLimit = gasLimits[index];
|
|
439
455
|
const gas = gasLimit === undefined || gasLimit7702 ? undefined : (0, controller_utils_1.toHex)(gasLimit);
|
|
@@ -446,7 +462,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
446
462
|
to: singleParams.to,
|
|
447
463
|
value: singleParams.value,
|
|
448
464
|
},
|
|
449
|
-
type: getTransactionType(
|
|
465
|
+
type: getTransactionType(prependCount, index, getEffectiveTransactionType(transaction), normalizedParams.length),
|
|
450
466
|
};
|
|
451
467
|
});
|
|
452
468
|
await messenger.call('TransactionController:addTransactionBatch', {
|
|
@@ -478,19 +494,17 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
478
494
|
/**
|
|
479
495
|
* Determine the transaction type for a given index in the batch.
|
|
480
496
|
*
|
|
481
|
-
* @param
|
|
497
|
+
* @param prependCount - Number of non-relay txs prepended to the batch.
|
|
482
498
|
* @param index - Index of the transaction in the batch.
|
|
483
|
-
* @param originalType - Type of the original transaction (used for
|
|
484
|
-
* @param relayParamCount - Number of relay-only params (excludes prepended
|
|
499
|
+
* @param originalType - Type of the original transaction (used for prepended indices).
|
|
500
|
+
* @param relayParamCount - Number of relay-only params (excludes prepended txs).
|
|
485
501
|
* @returns The transaction type.
|
|
486
502
|
*/
|
|
487
|
-
function getTransactionType(
|
|
488
|
-
|
|
489
|
-
if (isPostQuote && index === 0) {
|
|
503
|
+
function getTransactionType(prependCount, index, originalType, relayParamCount) {
|
|
504
|
+
if (prependCount > 0 && index < prependCount) {
|
|
490
505
|
return originalType;
|
|
491
506
|
}
|
|
492
|
-
|
|
493
|
-
const relayIndex = isPostQuote ? index - 1 : index;
|
|
507
|
+
const relayIndex = index - prependCount;
|
|
494
508
|
const depositType = getRelayDepositType(originalType);
|
|
495
509
|
// Single relay step is always a deposit (no approval needed)
|
|
496
510
|
if (relayParamCount === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":";;;AAAA,iEAAoE;AACpE,6EAAmE;AAOnE,2CAAqD;AACrD,+CAAyC;AAEzC,6CAA6C;AAM7C,iEAImC;AACnC,iDAI2B;AAC3B,6DAKiC;AACjC,+CAIqB;AACrB,qEAAmE;AACnE,wDAG+B;AAC/B,+CAAiE;AASjE,MAAM,aAAa,GAAG,KAAY,CAAC;AAEnC,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,gBAAgB,CAAC,CAAC;AAEhE;;;;;GAKG;AACI,KAAK,UAAU,iBAAiB,CACrC,OAA8C;IAE9C,GAAG,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAEjC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEnD,IAAI,eAAgC,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,CAAC,EAAE,eAAe,EAAE,GAAG,MAAM,kBAAkB,CAC7C,KAAK,EACL,SAAS,EACT,WAAW,CACZ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAC7B,CAAC;AAlBD,8CAkBC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAsC,EACtC,SAA4C,EAC5C,WAA4B;IAE5B,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;IAErC,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEtE,IAAA,+BAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,uCAAuC;KAC9C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,CAAC,CACF,CAAC;IAEF,IAAI,+BAA+B,GAAG,EAAE,CAAC;IAEzC,IAAI,KAAK,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACtC,MAAM,IAAA,gDAAyB,EAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACxE,CAAC;SAAM,IAAI,YAAY,EAAE,CAAC;QACxB,MAAM,EAAE,UAAU,EAAE,qBAAqB,EAAE,GACzC,MAAM,IAAA,mCAAwB,EAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACvE,+BAA+B,GAAG,qBAAqB,CAAC;QACxD,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,MAAM,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,SAAS,EAAE;QACzE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,GAAG,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;YAClC,kBAAkB,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,eAAe,EAAE,YAAY;KAC9B,CAAC,CAAC;IAEH,GAAG,CAAC,yBAAyB,EAAE,UAAU,CAAC,CAAC;IAE3C,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,IAAA,uCAA4B,EAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE;YAChE,WAAW,EAAE,UAAU,CAAC,MAAM;YAC9B,qBAAqB,EAAE,+BAA+B;SACvD,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,IAAA,+BAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,wCAAwC;KAC/C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC7B,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC;AACpD,CAAC;AAED,SAAS,kBAAkB,CACzB,WAA4B,EAC5B,SAA4C,EAC5C,UAAe;IAEf,IAAA,+BAAiB,EACf;QACE,aAAa,EAAE,WAAW,CAAC,EAAE;QAC7B,SAAS;QACT,IAAI,EAAE,mCAAmC;KAC1C,EACD,CAAC,EAAE,EAAE,EAAE;QACL,EAAE,CAAC,WAAW,KAAd,EAAE,CAAC,WAAW,GAAK,EAAE,EAAC;QACtB,EAAE,CAAC,WAAW,CAAC,UAAU,GAAG,UAAU,CAAC;IACzC,CAAC,CACF,CAAC;AACJ,CAAC;AAOD,KAAK,UAAU,sBAAsB,CACnC,KAAiB,EACjB,SAA4C,EAC5C,OAGC;IAED,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IAElD,MAAM,WAAW,GACf,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO;QACzC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;IAE7C,MAAM,mBAAmB,GACvB,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC;IAE9D,IAAI,WAAW,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACxC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAErC,MAAM,eAAe,GAAG,IAAA,uCAAuB,EAAC,SAAS,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,IAAA,sCAAsB,EAAC,SAAS,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,cAAc,KAAK,SAAS,IAAI,cAAc,GAAG,CAAC,CAAC;IAEtE,GAAG,CAAC,gBAAgB,EAAE,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,UAAmC,CAAC;IAExC,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAuC,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAA,0BAAc,EAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC5C,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;YAE3B,IAAI,CAAC,iBAAiB,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;gBACpD,iBAAiB,GAAG,IAAI,CAAC;gBACzB,YAAY,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAQ,CAAC,CAAC;YAC9C,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,UAAU,GACb,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAS,IAAI,aAAa,CAAC;gBAC1D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;YAC3C,CAAC;YAED,IAAI,CAAC,kCAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpD,IAAI,kCAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnD,IAAI,eAAe,EAAE,CAAC;wBACpB,GAAG,CAAC,2CAA2C,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;wBAChE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;oBACnC,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,uCAAuC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAED,IAAI,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,cAAc,EAAE,CAAC;YAC3D,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,kBAAkB,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,IAAI,eAAe,EAAE,CAAC;gBACpB,GAAG,CAAC,qCAAqC,EAAE,YAAY,CAAC,CAAC;gBACzD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC/B,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,MAAgD,EAChD,SAA4C;IAE5C,MAAM,YAAY,GAAG,IAAA,+BAAe,EAAC,SAAS,CAAC,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC;QAC3D,YAAY,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,YAAY,CAAC;QACxC,oBAAoB,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,oBAAoB,CAAC;QACxD,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,KAAK,EAAE,IAAA,wBAAK,EAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC;KAClC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,qBAAqB,CAClC,KAAsC,EACtC,SAA4C;IAE5C,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAElE,MAAM,4BAA4B,GAAG,IAAA,6BAAqB,EACxD,kBAAkB,EAClB,aAAa,EACb,0BAAkB,CAAC,QAAQ,CAC5B,CAAC;IAEF,IAAI,cAAsB,CAAC;IAE3B,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,IAAA,2BAAmB,EACxC,SAAS,EACT,IAAI,EACJ,aAAa,EACb,4BAA4B,CAC7B,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,2CAA4C,KAAe,CAAC,OAAO,EAAE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,wBAAS,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,wBAAS,CAAC,cAAc,CAAC,CAAC;IAE9C,GAAG,CAAC,2BAA2B,EAAE;QAC/B,IAAI;QACJ,aAAa;QACb,kBAAkB;QAClB,cAAc;QACd,cAAc,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;KAC5C,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,uDAAuD;YACrD,aAAa,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI;YAC5C,cAAc,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,KAAK,UAAU,kBAAkB,CAC/B,KAAsC,EACtC,WAA4B,EAC5B,SAA4C;IAE5C,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAC1B,CAAC,IAAI,EAAgC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CACpE,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,oBAAoB,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAC5B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CACpD,EAAE,IAAI,CAAC;IAER,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,kEAAkE;IAClE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QAC/B,MAAM,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACnD,eAAe,CAAC,YAAY,EAAE,SAAS,CAAC,CACzC,CAAC;IAEF,oEAAoE;IACpE,wDAAwD;IACxD,sEAAsE;IACtE,4EAA4E;IAC5E,0EAA0E;IAC1E,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,kBAAkB,GACtB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE;QAC/B,WAAW,CAAC,QAAQ,CAAC,IAAY,CAAC,WAAW,EAAE,CAAC;IAEnD,IAAI,SAAS,GAAG,gBAAgB,CAAC;IAEjC,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,eAAe,GAAG,kBAAkB;YACxC,CAAC,CAAC,MAAM,4BAA4B,CAAC,WAAW,EAAE,SAAS,CAAC;YAC5D,CAAC,CAAE;gBACC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAuB;gBAClD,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI;gBAC/B,EAAE,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE;gBAC3B,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAwB;aAC/B,CAAC;QAE5B,SAAS,GAAG,CAAC,eAAe,EAAE,GAAG,gBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACtC,OAAO,MAAM,qBAAqB,CAChC,KAAK,EACL,WAAW,EACX,SAAS,EACT,SAAS,CACV,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,8BAA8B,CACzC,KAAK,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,SAAS,CACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,4BAA4B,CACzC,WAA4B,EAC5B,SAA4C;IAE5C,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,IAAI,CACrC,mDAAmD,EACnD,EAAE,WAAW,EAAE,CAChB,CAAC;IAEF,GAAG,CAAC,6CAA6C,EAAE,UAAU,CAAC,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAW;QACtC,EAAE,EAAE,UAAU,CAAC,EAAE;QACjB,KAAK,EAAE,UAAU,CAAC,KAAK;KACxB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,qBAAqB,CAClC,KAAsC,EACtC,WAA4B,EAC5B,SAA4C,EAC5C,SAA8B;IAE9B,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9C,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CACpC,gDAAgD,EAChD,aAAa,CACd,CAAC;IAEF,MAAM,qBAAqB,GAAG;QAC5B,GAAG,WAAW;QACd,OAAO,EAAE,aAAa;QACtB,eAAe;QACf,kBAAkB,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC7C,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAQ;YAClC,EAAE,EAAE,MAAM,CAAC,EAAS;YACpB,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAQ;SACtC,CAAC,CAAC;QACH,QAAQ,EAAE;YACR,GAAG,WAAW,CAAC,QAAQ;YACvB,IAAI;SACL;KACiB,CAAC;IAErB,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,IAAI,CACrC,mDAAmD,EACnD,EAAE,WAAW,EAAE,qBAAqB,EAAE,CACvC,CAAC;IAEF,GAAG,CAAC,oCAAoC,EAAE,UAAU,CAAC,CAAC;IAEtD,MAAM,WAAW,GAAwB;QACvC,aAAa,EAAE,UAAU;QACzB,IAAI,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC,aAAa,CAAC;YAC9B,EAAE,EAAE,UAAU,CAAC,EAAE;YACjB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,KAAK,EAAE,IAAI,wBAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;YAChD,GAAG,CAAC,UAAU,CAAC,iBAAiB,EAAE,MAAM;gBACtC,CAAC,CAAC;oBACE,iBAAiB,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAC7D,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;wBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;wBACzB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;wBAC7B,CAAC,EAAE,IAAI,CAAC,CAAQ;wBAChB,CAAC,EAAE,IAAI,CAAC,CAAQ;qBACjB,CAAC,CAAC;iBACJ;gBACH,CAAC,CAAC,EAAE,CAAC;SACR;QACD,gBAAgB,EAAE;YAChB,aAAa,EAAE,KAAK;SACrB;QACD,SAAS;KACV,CAAC;IAEF,GAAG,CAAC,8BAA8B,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3D,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,IAAA,8BAAkB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,kBAAkB,OAAO,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;IAEtC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,UAAU,8BAA8B,CAC3C,KAAsC,EACtC,WAA4B,EAC5B,SAA4C,EAC5C,gBAAqC,EACrC,SAA8B;IAE9B,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAClE,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;IAEtC,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CACpC,gDAAgD,EAChD,aAAa,CACd,CAAC;IAEF,GAAG,CAAC,qBAAqB,EAAE;QACzB,gBAAgB,EAAE,SAAS;QAC3B,aAAa;QACb,IAAI;QACJ,eAAe;KAChB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,EAAE,GAAG,IAAA,mCAAqB,EACnC,aAAa,EACb,IAAI,EACJ,SAAS,EACT,CAAC,aAAa,EAAE,EAAE;QAChB,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAEnC,IAAA,+BAAiB,EACf;YACE,aAAa,EAAE,WAAW,CAAC,EAAE;YAC7B,SAAS;YACT,IAAI,EAAE,mDAAmD;SAC1D,EACD,CAAC,EAAE,EAAE,EAAE;YACL,EAAE,CAAC,sBAAsB,KAAzB,EAAE,CAAC,sBAAsB,GAAK,EAAE,EAAC;YACjC,EAAE,CAAC,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,IAAI,MAA+C,CAAC;IAEpD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB;QAChD,CAAC,CAAC,kBAAkB;QACpB,CAAC,CAAC,SAAS,CAAC;IAEd,GAAG,CAAC,yBAAyB,EAAE;QAC7B,WAAW;QACX,WAAW;QACX,cAAc,EAAE,SAAS,CAAC,MAAM;KACjC,CAAC,CAAC;IAEH,MAAM,WAAW,GACf,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO;QAClD,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC;IAEtD,MAAM,iBAAiB,GACrB,WAAW,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,EAAE,MAAM;QAC7D,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,OAAO,EAAE,IAAA,wBAAK,EAAC,CAAC,CAAC,OAAO,CAAC;SAC1B,CAAC,CAAC;QACL,CAAC,CAAC,SAAS,CAAC;IAEhB,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;IACpC,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IAE/B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,iBAAiB,GAAG;YACxB,GAAG,SAAS,CAAC,CAAC,CAAC;YACf,iBAAiB;YACjB,GAAG,EAAE,IAAA,wBAAK,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC;SACzB,CAAC;QAEF,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAC3B,sCAAsC,EACtC,iBAAiB,EACjB;YACE,WAAW;YACX,eAAe;YACf,MAAM,EAAE,kCAAe;YACvB,UAAU,EAAE,IAAI;YAChB,eAAe,EAAE,KAAK;YACtB,IAAI,EAAE,mBAAmB,CAAC,2BAA2B,CAAC,WAAW,CAAC,CAAC;SACpE,CACF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM;YAClC,CAAC,CAAC,IAAA,wBAAK,EAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE;YACzD,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,GAAG,GACP,QAAQ,KAAK,SAAS,IAAI,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAA,wBAAK,EAAC,QAAQ,CAAC,CAAC;YAEvE,OAAO;gBACL,MAAM,EAAE;oBACN,IAAI,EAAE,YAAY,CAAC,IAAW;oBAC9B,GAAG;oBACH,YAAY,EAAE,YAAY,CAAC,YAAmB;oBAC9C,oBAAoB,EAAE,YAAY,CAAC,oBAA2B;oBAC9D,EAAE,EAAE,YAAY,CAAC,EAAS;oBAC1B,KAAK,EAAE,YAAY,CAAC,KAAY;iBACjC;gBACD,IAAI,EAAE,kBAAkB,CACtB,WAAW,EACX,KAAK,EACL,2BAA2B,CAAC,WAAW,CAAC,EACxC,gBAAgB,CAAC,MAAM,CACxB;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,SAAS,CAAC,IAAI,CAAC,2CAA2C,EAAE;YAChE,IAAI;YACJ,WAAW,EAAE,CAAC,YAAY;YAC1B,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC;YAClC,iBAAiB,EAAE,OAAO,CAAC,YAAY,CAAC;YACxC,WAAW;YACX,YAAY;YACZ,eAAe;YACf,MAAM,EAAE,kCAAe;YACvB,UAAU,EAAE,IAAI;YAChB,gBAAgB,EAAE,IAAI;YACtB,eAAe,EAAE,KAAK;YACtB,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IAED,GAAG,EAAE,CAAC;IAEN,GAAG,CAAC,oBAAoB,EAAE,cAAc,CAAC,CAAC;IAE1C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CACf,cAAc,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,yCAA2B,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAC3E,CAAC;IAEF,GAAG,CAAC,4BAA4B,EAAE,cAAc,CAAC,CAAC;IAElD,MAAM,IAAI,GAAG,IAAA,4BAAc,EAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC;IAE1E,OAAO,IAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CACzB,WAAgC,EAChC,KAAa,EACb,YAAqC,EACrC,eAAuB;IAEvB,iDAAiD;IACjD,IAAI,WAAW,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,mEAAmE;IACnE,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEnD,MAAM,WAAW,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;IAEtD,6DAA6D;IAC7D,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,wCAAe,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC;AAC7E,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAC1B,YAAqC;IAErC,OAAO,CACL,CAAC,YAAY,IAAI,+BAAmB,CAAC,YAAY,CAAC,CAAC;QACnD,wCAAe,CAAC,YAAY,CAC7B,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,2BAA2B,CAClC,WAA4B;IAE5B,IAAI,WAAW,CAAC,IAAI,KAAK,wCAAe,CAAC,KAAK,EAAE,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,kBAAkB,EAAE,IAAI,CACrD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,IAAI,+BAAmB,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,SAAS,CAC9D,EAAE,IAAI,CAAC;IAER,OAAO,UAAU,IAAI,WAAW,CAAC,IAAI,CAAC;AACxC,CAAC","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n TransactionMeta,\n} 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 {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction';\nimport {\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw';\nimport { getRelayStatus, submitRelayExecute } from './relay-api';\nimport type {\n RelayExecuteRequest,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types';\n\nconst FALLBACK_HASH = '0x0' as Hex;\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n await submitTransactions(quote, transaction, messenger);\n }\n\n const completion = await waitForRelayCompletion(quote.original, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Relay request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: completion.targetHash };\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\ntype RelayCompletionOutcome = {\n status: RelayStatus | 'timeout';\n targetHash?: Hex;\n};\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Relay request failed with status: ${status.status}`);\n }\n throw new Error(`Relay returned unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Relay polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas: toHex(params.maxFeePerGas),\n maxPriorityFeePerGas: toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n const { steps } = quote.original;\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const params = txSteps.flatMap((step) => step.items).map((item) => item.data);\n const SUPPORTED_STEP_KINDS = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !SUPPORTED_STEP_KINDS.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote) {\n await validateSourceBalance(quote, messenger);\n }\n\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n let allParams = normalizedParams;\n\n if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(transaction, messenger)\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via Relay's /execute endpoint.\n *\n * Combines all source calls (approve + deposit, and optionally the\n * original transaction for post-quote flows) into a single EIP-7702\n * delegation transaction using getDelegationTransaction, then submits\n * it to Relay's /execute endpoint for gasless execution.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param allParams - All source transaction params to combine.\n * @returns Fallback hash (actual hash comes from relay status polling).\n */\nasync function submitViaRelayExecute(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n allParams: TransactionParams[],\n): Promise<Hex> {\n const { from, sourceChainId } = quote.request;\n const { requestId } = quote.original.steps[0];\n\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n sourceChainId,\n );\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions: allParams.map((params) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n })),\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for source calls', delegation);\n\n const executeBody: RelayExecuteRequest = {\n executionKind: 'rawCalls',\n data: {\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n },\n executionOptions: {\n subsidizeFees: false,\n },\n requestId,\n };\n\n log('Submitting via Relay execute', { executeBody, from });\n\n let result;\n try {\n result = await submitRelayExecute(messenger, executeBody);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Relay execute: ${message}`);\n }\n\n log('Relay execute response', result);\n\n return FALLBACK_HASH;\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n sourceChainId,\n );\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const gasFeeToken = quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n const gasLimit7702 = metamask.is7702\n ? toHex(metamask.gasLimits[0])\n : undefined;\n\n const transactions = allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n isPostQuote,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n\n await messenger.call('TransactionController:addTransactionBatch', {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions,\n });\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n return hash as Hex;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param isPostQuote - Whether this is a post-quote flow.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for post-quote index 0).\n * @param relayParamCount - Number of relay-only params (excludes prepended original tx).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n isPostQuote: boolean | undefined,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n // Post-quote index 0 is the original transaction\n if (isPostQuote && index === 0) {\n return originalType;\n }\n\n // Adjust index for post-quote flows where original tx is prepended\n const relayIndex = isPostQuote ? index - 1 : index;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n TransactionMeta,\n} 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 {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags';\nimport { getNetworkClientId } from '../../utils/provider';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction';\nimport {\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw';\nimport { getRelayStatus, submitRelayExecute } from './relay-api';\nimport type {\n RelayExecuteRequest,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types';\n\nconst FALLBACK_HASH = '0x0' as Hex;\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n await submitTransactions(quote, transaction, messenger);\n }\n\n const completion = await waitForRelayCompletion(quote.original, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Relay request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: completion.targetHash };\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\ntype RelayCompletionOutcome = {\n status: RelayStatus | 'timeout';\n targetHash?: Hex;\n};\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Relay request failed with status: ${status.status}`);\n }\n throw new Error(`Relay returned unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Relay polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas: toHex(params.maxFeePerGas),\n maxPriorityFeePerGas: toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n const { steps } = quote.original;\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const params = txSteps.flatMap((step) => step.items).map((item) => item.data);\n const SUPPORTED_STEP_KINDS = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !SUPPORTED_STEP_KINDS.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(transaction, messenger)\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via Relay's /execute endpoint.\n *\n * Combines all source calls (approve + deposit, and optionally the\n * original transaction for post-quote flows) into a single EIP-7702\n * delegation transaction using getDelegationTransaction, then submits\n * it to Relay's /execute endpoint for gasless execution.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param allParams - All source transaction params to combine.\n * @returns Fallback hash (actual hash comes from relay status polling).\n */\nasync function submitViaRelayExecute(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n allParams: TransactionParams[],\n): Promise<Hex> {\n const { from, sourceChainId } = quote.request;\n const { requestId } = quote.original.steps[0];\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions: allParams.map((params) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n })),\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for source calls', delegation);\n\n const executeBody: RelayExecuteRequest = {\n executionKind: 'rawCalls',\n data: {\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n },\n executionOptions: {\n subsidizeFees: false,\n },\n requestId,\n };\n\n log('Submitting via Relay execute', { executeBody, from });\n\n let result;\n try {\n result = await submitRelayExecute(messenger, executeBody);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Relay execute: ${message}`);\n }\n\n log('Relay execute response', result);\n\n return FALLBACK_HASH;\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const gasFeeToken = quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n const gasLimit7702 = metamask.is7702\n ? toHex(metamask.gasLimits[0])\n : undefined;\n\n const prependCount = allParams.length - normalizedParams.length;\n\n const transactions = allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n\n await messenger.call('TransactionController:addTransactionBatch', {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions,\n });\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n return hash as Hex;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,wBAAoB;
|
|
1
|
+
{"version":3,"file":"relay-submit.d.cts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,wBAAoB;AA6BrB,OAAO,KAAK,EAEV,UAAU,EAIX,oBAAgB;AAMjB;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,yBAAyB,CAAC,UAAU,CAAC,GAC7C,OAAO,CAAC;IAAE,eAAe,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC,CAgBpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,wBAAoB;
|
|
1
|
+
{"version":3,"file":"relay-submit.d.mts","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,wBAAoB;AA6BrB,OAAO,KAAK,EAEV,UAAU,EAIX,oBAAgB;AAMjB;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,yBAAyB,CAAC,UAAU,CAAC,GAC7C,OAAO,CAAC;IAAE,eAAe,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC,CAgBpC"}
|
|
@@ -4,6 +4,7 @@ import { createModuleLogger } from "@metamask/utils";
|
|
|
4
4
|
import { BigNumber } from "bignumber.js";
|
|
5
5
|
import { projectLogger } from "../../logger.mjs";
|
|
6
6
|
import { getFeatureFlags, getRelayPollingInterval, getRelayPollingTimeout } from "../../utils/feature-flags.mjs";
|
|
7
|
+
import { getNetworkClientId } from "../../utils/provider.mjs";
|
|
7
8
|
import { getLiveTokenBalance, normalizeTokenAddress, TokenAddressTarget } from "../../utils/token.mjs";
|
|
8
9
|
import { collectTransactionIds, getTransaction, updateTransaction, waitForTransactionConfirmed } from "../../utils/transaction.mjs";
|
|
9
10
|
import { RELAY_DEPOSIT_TYPES, RELAY_FAILURE_STATUSES, RELAY_PENDING_STATUSES } from "./constants.mjs";
|
|
@@ -232,7 +233,7 @@ async function submitTransactions(quote, transaction, messenger) {
|
|
|
232
233
|
// In post-quote flows (e.g. Predict withdraw), the source tokens are held in
|
|
233
234
|
// the Safe — not the EOA — and only become available after the original tx
|
|
234
235
|
// executes as part of the batch. Skip the EOA balance check here.
|
|
235
|
-
if (!quote.request.isPostQuote) {
|
|
236
|
+
if (!quote.request.isPostQuote && !quote.request.paymentOverride) {
|
|
236
237
|
await validateSourceBalance(quote, messenger);
|
|
237
238
|
}
|
|
238
239
|
const normalizedParams = params.map((singleParams) => normalizeParams(singleParams, messenger));
|
|
@@ -247,7 +248,21 @@ async function submitTransactions(quote, transaction, messenger) {
|
|
|
247
248
|
const hasAccountOverride = quote.request.from.toLowerCase() !==
|
|
248
249
|
transaction.txParams.from.toLowerCase();
|
|
249
250
|
let allParams = normalizedParams;
|
|
250
|
-
if (
|
|
251
|
+
if (quote.request.paymentOverride) {
|
|
252
|
+
const { transactionData } = messenger.call('TransactionPayController:getState');
|
|
253
|
+
const { calls: overrideTxs } = await messenger.call('TransactionPayController:getPaymentOverrideData', {
|
|
254
|
+
amount: quote.sourceAmount.human,
|
|
255
|
+
transaction,
|
|
256
|
+
transactionData: transactionData[transaction.id],
|
|
257
|
+
});
|
|
258
|
+
if (overrideTxs.length > 0) {
|
|
259
|
+
allParams = [
|
|
260
|
+
...overrideTxs,
|
|
261
|
+
...normalizedParams,
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else if (isPostQuote && transaction.txParams.to) {
|
|
251
266
|
const prependedParams = hasAccountOverride
|
|
252
267
|
? await buildDelegatedOriginalParams(transaction, messenger)
|
|
253
268
|
: {
|
|
@@ -303,7 +318,7 @@ async function buildDelegatedOriginalParams(transaction, messenger) {
|
|
|
303
318
|
async function submitViaRelayExecute(quote, transaction, messenger, allParams) {
|
|
304
319
|
const { from, sourceChainId } = quote.request;
|
|
305
320
|
const { requestId } = quote.original.steps[0];
|
|
306
|
-
const networkClientId = messenger
|
|
321
|
+
const networkClientId = getNetworkClientId(messenger, sourceChainId);
|
|
307
322
|
const sourceCallTransaction = {
|
|
308
323
|
...transaction,
|
|
309
324
|
chainId: sourceChainId,
|
|
@@ -374,7 +389,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
374
389
|
const transactionIds = [];
|
|
375
390
|
const { from, sourceChainId, sourceTokenAddress } = quote.request;
|
|
376
391
|
const { isPostQuote } = quote.request;
|
|
377
|
-
const networkClientId = messenger
|
|
392
|
+
const networkClientId = getNetworkClientId(messenger, sourceChainId);
|
|
378
393
|
log('Adding transactions', {
|
|
379
394
|
normalizedParams: allParams,
|
|
380
395
|
sourceChainId,
|
|
@@ -430,6 +445,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
430
445
|
const gasLimit7702 = metamask.is7702
|
|
431
446
|
? toHex(metamask.gasLimits[0])
|
|
432
447
|
: undefined;
|
|
448
|
+
const prependCount = allParams.length - normalizedParams.length;
|
|
433
449
|
const transactions = allParams.map((singleParams, index) => {
|
|
434
450
|
const gasLimit = gasLimits[index];
|
|
435
451
|
const gas = gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);
|
|
@@ -442,7 +458,7 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
442
458
|
to: singleParams.to,
|
|
443
459
|
value: singleParams.value,
|
|
444
460
|
},
|
|
445
|
-
type: getTransactionType(
|
|
461
|
+
type: getTransactionType(prependCount, index, getEffectiveTransactionType(transaction), normalizedParams.length),
|
|
446
462
|
};
|
|
447
463
|
});
|
|
448
464
|
await messenger.call('TransactionController:addTransactionBatch', {
|
|
@@ -474,19 +490,17 @@ async function submitViaTransactionController(quote, transaction, messenger, nor
|
|
|
474
490
|
/**
|
|
475
491
|
* Determine the transaction type for a given index in the batch.
|
|
476
492
|
*
|
|
477
|
-
* @param
|
|
493
|
+
* @param prependCount - Number of non-relay txs prepended to the batch.
|
|
478
494
|
* @param index - Index of the transaction in the batch.
|
|
479
|
-
* @param originalType - Type of the original transaction (used for
|
|
480
|
-
* @param relayParamCount - Number of relay-only params (excludes prepended
|
|
495
|
+
* @param originalType - Type of the original transaction (used for prepended indices).
|
|
496
|
+
* @param relayParamCount - Number of relay-only params (excludes prepended txs).
|
|
481
497
|
* @returns The transaction type.
|
|
482
498
|
*/
|
|
483
|
-
function getTransactionType(
|
|
484
|
-
|
|
485
|
-
if (isPostQuote && index === 0) {
|
|
499
|
+
function getTransactionType(prependCount, index, originalType, relayParamCount) {
|
|
500
|
+
if (prependCount > 0 && index < prependCount) {
|
|
486
501
|
return originalType;
|
|
487
502
|
}
|
|
488
|
-
|
|
489
|
-
const relayIndex = isPostQuote ? index - 1 : index;
|
|
503
|
+
const relayIndex = index - prependCount;
|
|
490
504
|
const depositType = getRelayDepositType(originalType);
|
|
491
505
|
// Single relay step is always a deposit (no approval needed)
|
|
492
506
|
if (relayParamCount === 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n TransactionMeta,\n} 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 {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction';\nimport {\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw';\nimport { getRelayStatus, submitRelayExecute } from './relay-api';\nimport type {\n RelayExecuteRequest,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types';\n\nconst FALLBACK_HASH = '0x0' as Hex;\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n await submitTransactions(quote, transaction, messenger);\n }\n\n const completion = await waitForRelayCompletion(quote.original, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Relay request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: completion.targetHash };\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\ntype RelayCompletionOutcome = {\n status: RelayStatus | 'timeout';\n targetHash?: Hex;\n};\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Relay request failed with status: ${status.status}`);\n }\n throw new Error(`Relay returned unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Relay polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas: toHex(params.maxFeePerGas),\n maxPriorityFeePerGas: toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n const { steps } = quote.original;\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const params = txSteps.flatMap((step) => step.items).map((item) => item.data);\n const SUPPORTED_STEP_KINDS = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !SUPPORTED_STEP_KINDS.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote) {\n await validateSourceBalance(quote, messenger);\n }\n\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n let allParams = normalizedParams;\n\n if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(transaction, messenger)\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via Relay's /execute endpoint.\n *\n * Combines all source calls (approve + deposit, and optionally the\n * original transaction for post-quote flows) into a single EIP-7702\n * delegation transaction using getDelegationTransaction, then submits\n * it to Relay's /execute endpoint for gasless execution.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param allParams - All source transaction params to combine.\n * @returns Fallback hash (actual hash comes from relay status polling).\n */\nasync function submitViaRelayExecute(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n allParams: TransactionParams[],\n): Promise<Hex> {\n const { from, sourceChainId } = quote.request;\n const { requestId } = quote.original.steps[0];\n\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n sourceChainId,\n );\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions: allParams.map((params) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n })),\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for source calls', delegation);\n\n const executeBody: RelayExecuteRequest = {\n executionKind: 'rawCalls',\n data: {\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n },\n executionOptions: {\n subsidizeFees: false,\n },\n requestId,\n };\n\n log('Submitting via Relay execute', { executeBody, from });\n\n let result;\n try {\n result = await submitRelayExecute(messenger, executeBody);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Relay execute: ${message}`);\n }\n\n log('Relay execute response', result);\n\n return FALLBACK_HASH;\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n sourceChainId,\n );\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const gasFeeToken = quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n const gasLimit7702 = metamask.is7702\n ? toHex(metamask.gasLimits[0])\n : undefined;\n\n const transactions = allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n isPostQuote,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n\n await messenger.call('TransactionController:addTransactionBatch', {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions,\n });\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n return hash as Hex;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param isPostQuote - Whether this is a post-quote flow.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for post-quote index 0).\n * @param relayParamCount - Number of relay-only params (excludes prepended original tx).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n isPostQuote: boolean | undefined,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n // Post-quote index 0 is the original transaction\n if (isPostQuote && index === 0) {\n return originalType;\n }\n\n // Adjust index for post-quote flows where original tx is prepended\n const relayIndex = isPostQuote ? index - 1 : index;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"relay-submit.mjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import { ORIGIN_METAMASK, toHex } from '@metamask/controller-utils';\nimport { TransactionType } from '@metamask/transaction-controller';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport type {\n AuthorizationList,\n TransactionMeta,\n} 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 {\n PayStrategyExecuteRequest,\n TransactionPayControllerMessenger,\n TransactionPayQuote,\n} from '../../types';\nimport {\n getFeatureFlags,\n getRelayPollingInterval,\n getRelayPollingTimeout,\n} from '../../utils/feature-flags';\nimport { getNetworkClientId } from '../../utils/provider';\nimport {\n getLiveTokenBalance,\n normalizeTokenAddress,\n TokenAddressTarget,\n} from '../../utils/token';\nimport {\n collectTransactionIds,\n getTransaction,\n updateTransaction,\n waitForTransactionConfirmed,\n} from '../../utils/transaction';\nimport {\n RELAY_DEPOSIT_TYPES,\n RELAY_FAILURE_STATUSES,\n RELAY_PENDING_STATUSES,\n} from './constants';\nimport { submitHyperliquidWithdraw } from './hyperliquid-withdraw';\nimport {\n sweepPolymarketDepositWallet,\n submitPolymarketWithdraw,\n} from './polymarket/withdraw';\nimport { getRelayStatus, submitRelayExecute } from './relay-api';\nimport type {\n RelayExecuteRequest,\n RelayQuote,\n RelayStatus,\n RelayStatusResponse,\n RelayTransactionStep,\n} from './types';\n\nconst FALLBACK_HASH = '0x0' as Hex;\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing quotes', request);\n\n const { quotes, messenger, transaction } = request;\n\n let transactionHash: Hex | undefined;\n\n for (const quote of quotes) {\n ({ transactionHash } = await executeSingleQuote(\n quote,\n messenger,\n transaction,\n ));\n }\n\n return { transactionHash };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n transaction: TransactionMeta,\n): Promise<{ transactionHash?: Hex }> {\n log('Executing single quote', quote);\n\n const isPolymarket = Boolean(quote.request.isPolymarketDepositWallet);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Remove nonce from skipped transaction',\n },\n (tx) => {\n tx.txParams.nonce = undefined;\n },\n );\n\n let polymarketPreSubmitUsdceBalance = 0n;\n\n if (quote.request.isHyperliquidSource) {\n await submitHyperliquidWithdraw(quote, quote.request.from, messenger);\n } else if (isPolymarket) {\n const { sourceHash, preSubmitUsdceBalance } =\n await submitPolymarketWithdraw(quote, quote.request.from, messenger);\n polymarketPreSubmitUsdceBalance = preSubmitUsdceBalance;\n setRelaySourceHash(transaction, messenger, sourceHash);\n } else {\n await submitTransactions(quote, transaction, messenger);\n }\n\n const completion = await waitForRelayCompletion(quote.original, messenger, {\n onSourceHash: (hash) => {\n log('Source hash received', hash);\n setRelaySourceHash(transaction, messenger, hash);\n },\n tolerateFailure: isPolymarket,\n });\n\n log('Relay request completed', completion);\n\n if (isPolymarket) {\n await sweepPolymarketDepositWallet(quote.request.from, messenger, {\n relayStatus: completion.status,\n preSubmitUsdceBalance: polymarketPreSubmitUsdceBalance,\n });\n\n if (completion.status !== 'success') {\n throw new Error(`Relay request failed with status: ${completion.status}`);\n }\n }\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Intent complete after Relay completion',\n },\n (tx) => {\n tx.isIntentComplete = true;\n },\n );\n\n return { transactionHash: completion.targetHash };\n}\n\nfunction setRelaySourceHash(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n sourceHash: Hex,\n): void {\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add source hash from Relay status',\n },\n (tx) => {\n tx.metamaskPay ??= {};\n tx.metamaskPay.sourceHash = sourceHash;\n },\n );\n}\n\ntype RelayCompletionOutcome = {\n status: RelayStatus | 'timeout';\n targetHash?: Hex;\n};\n\nasync function waitForRelayCompletion(\n quote: RelayQuote,\n messenger: TransactionPayControllerMessenger,\n options: {\n onSourceHash?: (hash: Hex) => void;\n tolerateFailure?: boolean;\n },\n): Promise<RelayCompletionOutcome> {\n const { onSourceHash, tolerateFailure } = options;\n\n const isSameChain =\n quote.details.currencyIn.currency.chainId ===\n quote.details.currencyOut.currency.chainId;\n\n const isSingleDepositStep =\n quote.steps.length === 1 && quote.steps[0].id === 'deposit';\n\n if (isSameChain && !isSingleDepositStep) {\n log('Skipping polling as same chain');\n return { status: 'success', targetHash: FALLBACK_HASH };\n }\n\n const { requestId } = quote.steps[0];\n\n const pollingInterval = getRelayPollingInterval(messenger);\n const pollingTimeout = getRelayPollingTimeout(messenger);\n const hasTimeout = pollingTimeout !== undefined && pollingTimeout > 0;\n\n log('Polling config', { pollingInterval, pollingTimeout });\n const startTime = Date.now();\n\n let sourceHashEmitted = false;\n let lastStatus: RelayStatus | undefined;\n\n while (true) {\n let status: RelayStatusResponse | undefined;\n\n try {\n status = await getRelayStatus(requestId);\n } catch (error) {\n log('Polling network error', error);\n }\n\n if (status) {\n log('Polled status', status.status, status);\n lastStatus = status.status;\n\n if (!sourceHashEmitted && status.inTxHashes?.length) {\n sourceHashEmitted = true;\n onSourceHash?.(status.inTxHashes[0] as Hex);\n }\n\n if (status.status === 'success') {\n const targetHash =\n (status.txHashes?.slice(-1)[0] as Hex) ?? FALLBACK_HASH;\n return { status: 'success', targetHash };\n }\n\n if (!RELAY_PENDING_STATUSES.includes(status.status)) {\n if (RELAY_FAILURE_STATUSES.includes(status.status)) {\n if (tolerateFailure) {\n log('Relay ended in failure status (tolerated)', status.status);\n return { status: status.status };\n }\n throw new Error(`Relay request failed with status: ${status.status}`);\n }\n throw new Error(`Relay returned unrecognized status: ${status.status}`);\n }\n }\n\n if (hasTimeout && Date.now() - startTime >= pollingTimeout) {\n const statusDetail = lastStatus ? ` (last status: ${lastStatus})` : '';\n if (tolerateFailure) {\n log('Relay polling timed out (tolerated)', statusDetail);\n return { status: 'timeout' };\n }\n throw new Error(`Relay polling timed out${statusDetail}`);\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollingInterval));\n }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @param messenger - Controller messenger.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n params: RelayTransactionStep['items'][0]['data'],\n messenger: TransactionPayControllerMessenger,\n): TransactionParams {\n const featureFlags = getFeatureFlags(messenger);\n\n return {\n data: params.data,\n from: params.from,\n gas: toHex(params.gas ?? featureFlags.relayFallbackGas.max),\n maxFeePerGas: toHex(params.maxFeePerGas),\n maxPriorityFeePerGas: toHex(params.maxPriorityFeePerGas),\n to: params.to,\n value: toHex(params.value ?? '0'),\n };\n}\n\n/**\n * Validate the source token balance is sufficient for the relay deposit.\n *\n * Reads the live balance from TokenBalancesController and compares it against\n * the quote's required source amount to prevent submitting transactions that\n * will revert on-chain due to insufficient balance.\n *\n * @param quote - Relay quote containing the required source amount.\n * @param messenger - Controller messenger.\n */\nasync function validateSourceBalance(\n quote: TransactionPayQuote<RelayQuote>,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n\n const normalizedSourceTokenAddress = normalizeTokenAddress(\n sourceTokenAddress,\n sourceChainId,\n TokenAddressTarget.MetaMask,\n );\n\n let currentBalance: string;\n\n try {\n currentBalance = await getLiveTokenBalance(\n messenger,\n from,\n sourceChainId,\n normalizedSourceTokenAddress,\n );\n } catch (error) {\n throw new Error(\n `Cannot validate payment token balance - ${(error as Error).message}`,\n );\n }\n\n const requiredAmount = new BigNumber(quote.sourceAmount.raw);\n const balance = new BigNumber(currentBalance);\n\n log('Validating source balance', {\n from,\n sourceChainId,\n sourceTokenAddress,\n currentBalance,\n requiredAmount: requiredAmount.toString(10),\n });\n\n if (balance.isLessThan(requiredAmount)) {\n throw new Error(\n `Insufficient source token balance for relay deposit. ` +\n `Required: ${requiredAmount.toString(10)}, ` +\n `Available: ${balance.toString(10)}`,\n );\n }\n}\n\n/**\n * Submit transactions for a relay quote.\n *\n * On EIP-7702 supported chains, combines the source calls via\n * getDelegationTransaction and submits through Relay's /execute endpoint\n * (gasless — Relay's relayer pays origin gas).\n *\n * On other chains, adds the transactions directly via the\n * TransactionController and waits for on-chain confirmation.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitTransactions(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<Hex> {\n const { steps } = quote.original;\n const txSteps = steps.filter(\n (step): step is RelayTransactionStep => step.kind === 'transaction',\n );\n const params = txSteps.flatMap((step) => step.items).map((item) => item.data);\n const SUPPORTED_STEP_KINDS = ['transaction', 'signature'];\n const invalidKind = steps.find(\n (step) => !SUPPORTED_STEP_KINDS.includes(step.kind),\n )?.kind;\n\n if (invalidKind) {\n throw new Error(`Unsupported step kind: ${invalidKind}`);\n }\n\n // In post-quote flows (e.g. Predict withdraw), the source tokens are held in\n // the Safe — not the EOA — and only become available after the original tx\n // executes as part of the batch. Skip the EOA balance check here.\n if (!quote.request.isPostQuote && !quote.request.paymentOverride) {\n await validateSourceBalance(quote, messenger);\n }\n\n const normalizedParams = params.map((singleParams) =>\n normalizeParams(singleParams, messenger),\n );\n\n // For post-quote flows, prepend the original transaction so it gets\n // included in the batch alongside the relay deposit(s).\n // This always results in multiple params, so it takes the batch path.\n // When an accountOverride is set (detected by `from` divergence between the\n // quote and the original tx), the override account does not directly hold\n // the funds for the original call, so the prepended tx is replaced with a\n // delegation tx that redeems the original call on its behalf.\n const { isPostQuote } = quote.request;\n const hasAccountOverride =\n quote.request.from.toLowerCase() !==\n (transaction.txParams.from as Hex).toLowerCase();\n\n let allParams = normalizedParams;\n\n if (quote.request.paymentOverride) {\n const { transactionData } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const { calls: overrideTxs } = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: quote.sourceAmount.human,\n transaction,\n transactionData: transactionData[transaction.id],\n },\n );\n\n if (overrideTxs.length > 0) {\n allParams = [\n ...(overrideTxs as TransactionParams[]),\n ...normalizedParams,\n ];\n }\n } else if (isPostQuote && transaction.txParams.to) {\n const prependedParams = hasAccountOverride\n ? await buildDelegatedOriginalParams(transaction, messenger)\n : ({\n data: transaction.txParams.data as Hex | undefined,\n from: transaction.txParams.from,\n to: transaction.txParams.to,\n value: transaction.txParams.value as Hex | undefined,\n } as TransactionParams);\n\n allParams = [prependedParams, ...normalizedParams];\n }\n\n if (quote.original.metamask.isExecute) {\n return await submitViaRelayExecute(\n quote,\n transaction,\n messenger,\n allParams,\n );\n }\n\n return await submitViaTransactionController(\n quote,\n transaction,\n messenger,\n normalizedParams,\n allParams,\n );\n}\n\n/**\n * Build TransactionParams for a delegation that redeems the original\n * post-quote transaction on behalf of the override account. Used when the\n * override account cannot execute the original call directly.\n *\n * The original tx is already on the correct chain and from the money\n * account, so it can be passed through to `getDelegationTransaction`\n * unchanged.\n *\n * @param transaction - Original transaction meta to be redeemed.\n * @param messenger - Controller messenger.\n * @returns Transaction params for the delegation tx.\n */\nasync function buildDelegatedOriginalParams(\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<TransactionParams> {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n log('Delegation result for prepended original tx', delegation);\n\n return {\n data: delegation.data,\n from: transaction.txParams.from as Hex,\n to: delegation.to,\n value: delegation.value,\n };\n}\n\n/**\n * Submit source transactions via Relay's /execute endpoint.\n *\n * Combines all source calls (approve + deposit, and optionally the\n * original transaction for post-quote flows) into a single EIP-7702\n * delegation transaction using getDelegationTransaction, then submits\n * it to Relay's /execute endpoint for gasless execution.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param allParams - All source transaction params to combine.\n * @returns Fallback hash (actual hash comes from relay status polling).\n */\nasync function submitViaRelayExecute(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n allParams: TransactionParams[],\n): Promise<Hex> {\n const { from, sourceChainId } = quote.request;\n const { requestId } = quote.original.steps[0];\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n const sourceCallTransaction = {\n ...transaction,\n chainId: sourceChainId,\n networkClientId,\n nestedTransactions: allParams.map((params) => ({\n data: (params.data ?? '0x') as Hex,\n to: params.to as Hex,\n value: (params.value ?? '0x0') as Hex,\n })),\n txParams: {\n ...transaction.txParams,\n from,\n },\n } as TransactionMeta;\n\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction: sourceCallTransaction },\n );\n\n log('Delegation result for source calls', delegation);\n\n const executeBody: RelayExecuteRequest = {\n executionKind: 'rawCalls',\n data: {\n chainId: Number(sourceChainId),\n to: delegation.to,\n data: delegation.data,\n value: new BigNumber(delegation.value).toFixed(),\n ...(delegation.authorizationList?.length\n ? {\n authorizationList: delegation.authorizationList.map((auth) => ({\n chainId: Number(auth.chainId),\n address: auth.address,\n nonce: Number(auth.nonce),\n yParity: Number(auth.yParity),\n r: auth.r as Hex,\n s: auth.s as Hex,\n })),\n }\n : {}),\n },\n executionOptions: {\n subsidizeFees: false,\n },\n requestId,\n };\n\n log('Submitting via Relay execute', { executeBody, from });\n\n let result;\n try {\n result = await submitRelayExecute(messenger, executeBody);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Relay execute: ${message}`);\n }\n\n log('Relay execute response', result);\n\n return FALLBACK_HASH;\n}\n\n/**\n * Submit source transactions via the TransactionController.\n *\n * Uses addTransaction for single params or addTransactionBatch for\n * multiple params. Waits for all transactions to be confirmed on-chain.\n *\n * @param quote - Relay quote.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @param normalizedParams - Normalized relay-only params (without prepended original tx).\n * @param allParams - All params including any prepended original tx for post-quote flows.\n * @returns Hash of the last submitted transaction.\n */\nasync function submitViaTransactionController(\n quote: TransactionPayQuote<RelayQuote>,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n normalizedParams: TransactionParams[],\n allParams: TransactionParams[],\n): Promise<Hex> {\n const transactionIds: string[] = [];\n const { from, sourceChainId, sourceTokenAddress } = quote.request;\n const { isPostQuote } = quote.request;\n\n const networkClientId = getNetworkClientId(messenger, sourceChainId);\n\n log('Adding transactions', {\n normalizedParams: allParams,\n sourceChainId,\n from,\n networkClientId,\n });\n\n const { end } = collectTransactionIds(\n sourceChainId,\n from,\n messenger,\n (transactionId) => {\n transactionIds.push(transactionId);\n\n updateTransaction(\n {\n transactionId: transaction.id,\n messenger,\n note: 'Add required transaction ID from Relay submission',\n },\n (tx) => {\n tx.requiredTransactionIds ??= [];\n tx.requiredTransactionIds.push(transactionId);\n },\n );\n },\n );\n\n let result: { result: Promise<string> } | undefined;\n\n const gasFeeToken = quote.fees.isSourceGasFeeToken\n ? sourceTokenAddress\n : undefined;\n\n log('Submitting transactions', {\n isPostQuote,\n gasFeeToken,\n allParamsCount: allParams.length,\n });\n\n const isSameChain =\n quote.original.details.currencyIn.currency.chainId ===\n quote.original.details.currencyOut.currency.chainId;\n\n const authorizationList: AuthorizationList | undefined =\n isSameChain && quote.original.request.authorizationList?.length\n ? quote.original.request.authorizationList.map((a) => ({\n address: a.address,\n chainId: toHex(a.chainId),\n }))\n : undefined;\n\n const { metamask } = quote.original;\n const { gasLimits } = metamask;\n\n if (allParams.length === 1) {\n const transactionParams = {\n ...allParams[0],\n authorizationList,\n gas: toHex(gasLimits[0]),\n };\n\n result = await messenger.call(\n 'TransactionController:addTransaction',\n transactionParams,\n {\n gasFeeToken,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n requireApproval: false,\n type: getRelayDepositType(getEffectiveTransactionType(transaction)),\n },\n );\n } else {\n const gasLimit7702 = metamask.is7702\n ? toHex(metamask.gasLimits[0])\n : undefined;\n\n const prependCount = allParams.length - normalizedParams.length;\n\n const transactions = allParams.map((singleParams, index) => {\n const gasLimit = gasLimits[index];\n const gas =\n gasLimit === undefined || gasLimit7702 ? undefined : toHex(gasLimit);\n\n return {\n params: {\n data: singleParams.data as Hex,\n gas,\n maxFeePerGas: singleParams.maxFeePerGas as Hex,\n maxPriorityFeePerGas: singleParams.maxPriorityFeePerGas as Hex,\n to: singleParams.to as Hex,\n value: singleParams.value as Hex,\n },\n type: getTransactionType(\n prependCount,\n index,\n getEffectiveTransactionType(transaction),\n normalizedParams.length,\n ),\n };\n });\n\n await messenger.call('TransactionController:addTransactionBatch', {\n from,\n disable7702: !gasLimit7702,\n disableHook: Boolean(gasLimit7702),\n disableSequential: Boolean(gasLimit7702),\n gasFeeToken,\n gasLimit7702,\n networkClientId,\n origin: ORIGIN_METAMASK,\n isInternal: true,\n overwriteUpgrade: true,\n requireApproval: false,\n transactions,\n });\n }\n\n end();\n\n log('Added transactions', transactionIds);\n\n if (result) {\n const txHash = await result.result;\n log('Submitted transaction', txHash);\n }\n\n await Promise.all(\n transactionIds.map((txId) => waitForTransactionConfirmed(txId, messenger)),\n );\n\n log('All transactions confirmed', transactionIds);\n\n const hash = getTransaction(transactionIds.slice(-1)[0], messenger)?.hash;\n\n return hash as Hex;\n}\n\n/**\n * Determine the transaction type for a given index in the batch.\n *\n * @param prependCount - Number of non-relay txs prepended to the batch.\n * @param index - Index of the transaction in the batch.\n * @param originalType - Type of the original transaction (used for prepended indices).\n * @param relayParamCount - Number of relay-only params (excludes prepended txs).\n * @returns The transaction type.\n */\nfunction getTransactionType(\n prependCount: number,\n index: number,\n originalType: TransactionMeta['type'],\n relayParamCount: number,\n): TransactionMeta['type'] {\n if (prependCount > 0 && index < prependCount) {\n return originalType;\n }\n\n const relayIndex = index - prependCount;\n\n const depositType = getRelayDepositType(originalType);\n\n // Single relay step is always a deposit (no approval needed)\n if (relayParamCount === 1) {\n return depositType;\n }\n\n return relayIndex === 0 ? TransactionType.tokenMethodApprove : depositType;\n}\n\n/**\n * Get the relay deposit transaction type based on the parent transaction type.\n *\n * @param originalType - Type of the parent transaction.\n * @returns The mapped relay deposit type, or `relayDeposit` as a fallback.\n */\nfunction getRelayDepositType(\n originalType: TransactionMeta['type'],\n): TransactionType {\n return (\n (originalType && RELAY_DEPOSIT_TYPES[originalType]) ??\n TransactionType.relayDeposit\n );\n}\n\n/**\n * Get the effective transaction type, resolving through nested transactions\n * when the top-level type is `batch`.\n *\n * @param transaction - The transaction metadata.\n * @returns The resolved type from nested transactions, or the top-level type.\n */\nfunction getEffectiveTransactionType(\n transaction: TransactionMeta,\n): TransactionMeta['type'] {\n if (transaction.type !== TransactionType.batch) {\n return transaction.type;\n }\n\n const nestedType = transaction.nestedTransactions?.find(\n (tx) => tx.type && RELAY_DEPOSIT_TYPES[tx.type] !== undefined,\n )?.type;\n\n return nestedType ?? transaction.type;\n}\n"]}
|