@metamask-previews/transaction-pay-controller 30.1.0-preview-51ecba2 → 30.1.0-preview-b50d61887

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 CHANGED
@@ -7,14 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Added
11
-
12
- - Support Predict withdraw in `ServerStrategy` ([#10702](https://github.com/MetaMask/core/pull/10702))
13
- - Polymarket deposit wallet withdrawals unwrap directly to a provider deposit address, then sweep any leftover or refunded USDC.e back into the deposit wallet.
14
- - Polymarket deposit wallet withdrawals have no source network fee, as the Polymarket relayer pays origin gas.
15
- - Non-atomic post-quote payment overrides, such as withdrawing to a Money Account, settle on the override recipient and run the override calls as a second leg.
16
- - Post-quote quotes honour `refundTo`, include the original transaction in gas estimation, and reserve the gas fee token cost from the source amount.
17
-
18
10
  ### Changed
19
11
 
20
12
  - Bump `@metamask/transaction-controller` from `^72.2.0` to `^72.2.1` ([#10817](https://github.com/MetaMask/core/pull/10817))
@@ -1 +1 @@
1
- {"version":3,"file":"server-quotes.d.ts","sourceRoot":"","sources":["../../../src/strategy/server/server-quotes.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,2BAA2B,EAI3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAuBxB,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,YAAY,CAAC;AA6CpB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CAY7C"}
1
+ {"version":3,"file":"server-quotes.d.ts","sourceRoot":"","sources":["../../../src/strategy/server/server-quotes.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,2BAA2B,EAI3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAmBxB,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,YAAY,CAAC;AA6CpB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CAY7C"}
@@ -5,16 +5,12 @@ import { BigNumber } from 'bignumber.js';
5
5
  import { CHAIN_ID_HYPERCORE, PaymentOverride, TransactionPayStrategy, } from '../../constants.js';
6
6
  import { projectLogger } from '../../logger.js';
7
7
  import { getFiatValueFromUsd } from '../../utils/amounts.js';
8
- import { getSlippage, isEIP7702Chain } from '../../utils/feature-flags.js';
8
+ import { getFeatureFlags, getSlippage, isEIP7702Chain, } from '../../utils/feature-flags.js';
9
9
  import { GasPaymentMode, resolveGasPayment, resolveGasStationCost, } from '../../utils/gas-payment.js';
10
10
  import { calculateGasCost, getGasFee } from '../../utils/gas.js';
11
- import { getPolymarketDepositWalletOverrides, getPredictWithdrawFeeTokenAccount, getPredictWithdrawSafeAddress, } from '../../utils/polymarket/withdraw.js';
12
- import { reservePostQuoteGas } from '../../utils/post-quote.js';
13
- import { estimateSourceGas } from '../../utils/quote-gas.js';
14
- import { resolveNonAtomicRecipient } from '../../utils/second-leg.js';
11
+ import { estimateQuoteGasLimits } from '../../utils/quote-gas.js';
15
12
  import { getTokenFiatRate } from '../../utils/token.js';
16
13
  import { getQuotePricing, TradeType } from '../../utils/trade-type.js';
17
- import { hasServerDepositStep } from './deposit-step.js';
18
14
  import { normalizeServerPerpsRequest } from './perps.js';
19
15
  import { fetchServerQuote } from './server-api.js';
20
16
  const log = createModuleLogger(projectLogger, 'server-quotes');
@@ -41,68 +37,31 @@ export async function getServerQuotes(request) {
41
37
  return quotes.flat();
42
38
  }
43
39
  async function getQuotesForRequest(quoteRequest, fullRequest) {
40
+ const { accountSupports7702, messenger, signal, transaction } = fullRequest;
44
41
  try {
45
- const quotes = await fetchQuotes(quoteRequest, fullRequest);
46
- if (!quoteRequest.isPostQuote) {
47
- return quotes;
48
- }
49
- // Post-quote flows commit the whole source balance, so any gas paid in the
50
- // source token has to be reserved by re-quoting the same provider for less.
51
- return await Promise.all(quotes.map((quote) => reservePostQuoteGas({
52
- quote,
53
- requote: (adjustedRequest) => requoteProvider(adjustedRequest, fullRequest, quote.original),
54
- })));
42
+ const body = await buildServerQuoteRequest(quoteRequest, transaction, messenger, accountSupports7702);
43
+ log('Request body', body);
44
+ const response = await fetchServerQuote(messenger, body, signal);
45
+ log('Raw quote response', response);
46
+ const fulfilledResults = response.results.filter(isFulfilledResult);
47
+ // The second leg runs from `request.recipient`, so it has to match the
48
+ // executing account the quote settles on.
49
+ const settledRequest = {
50
+ ...quoteRequest,
51
+ recipient: transaction.txParams.from,
52
+ };
53
+ const normalized = await Promise.all(fulfilledResults.map((result) => normalizeQuote(result, settledRequest, messenger, body.tradeType === TradeType.ExactInput, transaction, accountSupports7702, isSecondLegRequired(body, quoteRequest, transaction, result.quote))));
54
+ log('Normalized quotes', normalized);
55
+ return normalized;
55
56
  }
56
57
  catch (error) {
57
58
  log('Error fetching quotes', { error });
58
59
  return [];
59
60
  }
60
61
  }
61
- async function requoteProvider(quoteRequest, fullRequest, { provider }) {
62
- const [quote] = await fetchQuotes(quoteRequest, fullRequest, provider);
63
- if (!quote) {
64
- throw new Error(`No re-quote from provider: ${provider}`);
65
- }
66
- return quote;
67
- }
68
- async function fetchQuotes(quoteRequest, fullRequest, provider) {
69
- const { accountSupports7702, messenger, signal, transaction } = fullRequest;
70
- const settledRequest = await resolveSettledRequest(quoteRequest, transaction, messenger);
71
- const body = await buildServerQuoteRequest(settledRequest, transaction, messenger, accountSupports7702);
72
- if (provider) {
73
- body.providers = [provider];
74
- }
75
- log('Request body', body);
76
- const response = await fetchServerQuote(messenger, body, signal);
77
- log('Raw quote response', response);
78
- const fulfilledResults = response.results.filter((result) => isFulfilledResult(result) &&
79
- (!provider || result.provider === provider) &&
80
- isUsableDepositAddressQuote(body, result));
81
- const normalized = await Promise.all(fulfilledResults.map((result) => normalizeQuote(result, settledRequest, messenger, body, transaction, accountSupports7702, isSecondLegRequired(body, settledRequest, transaction, result.quote))));
82
- log('Normalized quotes', normalized);
83
- return normalized;
84
- }
85
- /**
86
- * Carry the account the funds settle on as the request recipient.
87
- *
88
- * The second leg runs from `request.recipient`, which has to match where the
89
- * funds actually landed. Non-atomic flows settle on the account submitting the
90
- * second leg, such as the Money Account of a Predict withdraw. Otherwise the
91
- * quote settles on the executing account rather than the payer.
92
- *
93
- * @param quoteRequest - Quote request.
94
- * @param transaction - Original transaction meta.
95
- * @param messenger - Controller messenger.
96
- * @returns The request with the settlement recipient applied.
97
- */
98
- async function resolveSettledRequest(quoteRequest, transaction, messenger) {
99
- const recipient = (await resolveNonAtomicRecipient(transaction, quoteRequest, messenger)) ??
100
- transaction.txParams.from;
101
- return { ...quoteRequest, recipient };
102
- }
103
62
  async function buildServerQuoteRequest(quoteRequest, transaction, messenger, accountSupports7702) {
104
63
  const normalizedRequest = normalizeServerPerpsRequest(quoteRequest, transaction);
105
- const { atomic, from, isMaxAmount, isPolymarketDepositWallet, isPostQuote, paymentOverride, refundTo, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = normalizedRequest;
64
+ const { atomic, from, isMaxAmount, isPostQuote, paymentOverride, sourceChainId, sourceTokenAddress, sourceTokenAmount, targetAmountMinimum, targetChainId, targetTokenAddress, } = normalizedRequest;
106
65
  const singleData = getSingleTransactionData(transaction);
107
66
  const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;
108
67
  const isTokenTransfer = !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));
@@ -111,12 +70,9 @@ async function buildServerQuoteRequest(quoteRequest, transaction, messenger, acc
111
70
  const executionAccount = transaction.txParams.from;
112
71
  const recipient = isTokenTransfer && singleData
113
72
  ? decodeTransferRecipient(singleData)
114
- : (normalizedRequest.recipient ?? executionAccount);
73
+ : executionAccount;
115
74
  const isHypercoreSource = sourceChainId === CHAIN_ID_HYPERCORE;
116
- // Deposit wallet withdraws are broadcast by the Polymarket relayer rather
117
- // than as a gasless EIP-7702 batch, so the provider must not quote gasless.
118
75
  const supportsGasless = !isHypercoreSource &&
119
- !isPolymarketDepositWallet &&
120
76
  accountSupports7702 &&
121
77
  isEIP7702Chain(messenger, sourceChainId);
122
78
  const body = {
@@ -127,9 +83,6 @@ async function buildServerQuoteRequest(quoteRequest, transaction, messenger, acc
127
83
  slippage: Math.round(getSlippage(messenger, sourceChainId, sourceTokenAddress) * 10000),
128
84
  supportsGasless,
129
85
  };
130
- if (isPolymarketDepositWallet) {
131
- await applyDepositWalletOverrides(body, from, messenger);
132
- }
133
86
  const hasNoData = singleData === undefined || singleData === '0x';
134
87
  const skipDelegation = hasNoData ||
135
88
  isTokenTransfer ||
@@ -139,13 +92,8 @@ async function buildServerQuoteRequest(quoteRequest, transaction, messenger, acc
139
92
  // they must not be embedded in the quote.
140
93
  atomic === false ||
141
94
  (isPostQuote ?? false) ||
142
- (isMaxAmount ?? false) ||
143
- // The deposit wallet funds the quote with a plain token transfer, so there
144
- // are no calls to embed.
145
- (isPolymarketDepositWallet ?? false);
146
- if (isPostQuote &&
147
- atomic !== false &&
148
- paymentOverride === PaymentOverride.MoneyAccount) {
95
+ (isMaxAmount ?? false);
96
+ if (isPostQuote && paymentOverride === PaymentOverride.MoneyAccount) {
149
97
  await processMoneyAccountPostQuote(transaction, normalizedRequest, body, messenger);
150
98
  }
151
99
  else if (!skipDelegation) {
@@ -179,12 +127,6 @@ async function buildServerQuoteRequest(quoteRequest, transaction, messenger, acc
179
127
  body.authorizationList = normalizeAuthorizationList(delegation.authorizationList);
180
128
  }
181
129
  }
182
- else if (isPostQuote || atomic === false) {
183
- // Honour the caller's refund address so a failed quote refunds the account
184
- // the funds came from, such as the Predict Safe, rather than the payer. A
185
- // deposit wallet refund address is kept, as the sweep reads refunds there.
186
- body.refundTo ??= refundTo;
187
- }
188
130
  const pricing = getQuotePricing({
189
131
  hasCalls: Boolean(body.calls?.length),
190
132
  sourceTokenAmount,
@@ -228,24 +170,6 @@ function canDeferCalls({ accountSupports7702, messenger, targetChainId, transact
228
170
  transaction.chainId === targetChainId &&
229
171
  isEIP7702Chain(messenger, targetChainId));
230
172
  }
231
- /**
232
- * Quote a deposit wallet Predict withdraw from the deposit wallet itself.
233
- *
234
- * The deposit wallet funds the provider's deposit address with the USDC.e
235
- * unwrapped from its pUSD, and is also the refund address so the sweep can wrap
236
- * any refund back into pUSD.
237
- *
238
- * @param body - Quote request body to update.
239
- * @param from - The user EOA that owns the deposit wallet.
240
- * @param messenger - Controller messenger.
241
- */
242
- async function applyDepositWalletOverrides(body, from, messenger) {
243
- const { depositWallet, sourceTokenAddress } = await getPolymarketDepositWalletOverrides(from, messenger);
244
- body.source = { ...body.source, token: sourceTokenAddress };
245
- body.sender = depositWallet;
246
- body.refundTo = depositWallet;
247
- body.useDepositAddress = true;
248
- }
249
173
  function normalizeAuthorizationList(authorizationList) {
250
174
  return authorizationList.map((entry) => ({
251
175
  address: entry.address,
@@ -306,8 +230,6 @@ function shouldRequestQuote(quoteRequest) {
306
230
  *
307
231
  * A second leg is needed either because we declined to embed the calls, or
308
232
  * because the provider that won the quote told us it will not execute them.
309
- * Non-atomic post-quote flows always need one: their calls come from the
310
- * payment override rather than the transaction, and run once funds settle.
311
233
  *
312
234
  * @param body - The built server quote request.
313
235
  * @param quoteRequest - The originating quote request.
@@ -321,19 +243,6 @@ function isSecondLegRequired(body, quoteRequest, transaction, quote) {
321
243
  if (body.calls?.length && !quote.callsDeferred) {
322
244
  return false;
323
245
  }
324
- // HyperCore settles off-chain, so there is no target-chain transfer to read
325
- // a settled amount from. Checks the built body rather than the original
326
- // request, since perps deposits are only rewritten to HyperCore there.
327
- if (body.target.chainId === HYPERCORE_CHAIN_ID_NUMBER ||
328
- body.source.chainId === HYPERCORE_CHAIN_ID_NUMBER) {
329
- return false;
330
- }
331
- // Post-quote flows submit the original transaction alongside the quote, so
332
- // the second leg never re-runs it. Only non-atomic flows have override calls
333
- // left to run once the funds settle.
334
- if (quoteRequest.isPostQuote) {
335
- return quoteRequest.atomic === false;
336
- }
337
246
  // No calls to run. Plain funding transfers and empty calldata are already
338
247
  // satisfied by the quote delivering the target token to the recipient.
339
248
  if (!transaction.nestedTransactions?.length) {
@@ -346,12 +255,23 @@ function isSecondLegRequired(body, quoteRequest, transaction, quote) {
346
255
  if (singleData.startsWith(TOKEN_TRANSFER_FOUR_BYTE)) {
347
256
  return false;
348
257
  }
258
+ // HyperCore settles off-chain, so there is no target-chain transfer to read
259
+ // a settled amount from. Checks the built body rather than the original
260
+ // request, since perps deposits are only rewritten to HyperCore there.
261
+ if (body.target.chainId === HYPERCORE_CHAIN_ID_NUMBER ||
262
+ body.source.chainId === HYPERCORE_CHAIN_ID_NUMBER) {
263
+ return false;
264
+ }
265
+ // Post-quote flows submit the original transaction separately, so running it
266
+ // again as a second leg would double-execute it.
267
+ if (quoteRequest.isPostQuote) {
268
+ return false;
269
+ }
349
270
  return true;
350
271
  }
351
- async function normalizeQuote(result, quoteRequest, messenger, body, transaction, accountSupports7702, requiresSecondLeg) {
272
+ async function normalizeQuote(result, quoteRequest, messenger, isInputBased, transaction, accountSupports7702, requiresSecondLeg) {
352
273
  const { quote } = result;
353
274
  const { gasless } = quote;
354
- const isInputBased = body.tradeType === TradeType.ExactInput;
355
275
  const transactionSteps = quote.steps.filter(isTransactionStep);
356
276
  const isSignatureOnly = transactionSteps.length === 0;
357
277
  const sourceNetwork = await calculateSourceNetworkCost({
@@ -359,7 +279,6 @@ async function normalizeQuote(result, quoteRequest, messenger, body, transaction
359
279
  gasless: gasless || isSignatureOnly,
360
280
  messenger,
361
281
  quoteRequest,
362
- sender: body.sender,
363
282
  steps: transactionSteps,
364
283
  transaction,
365
284
  });
@@ -433,7 +352,7 @@ async function normalizeQuote(result, quoteRequest, messenger, body, transaction
433
352
  },
434
353
  };
435
354
  }
436
- async function calculateSourceNetworkCost({ accountSupports7702, gasless, messenger, quoteRequest, sender, steps, transaction, }) {
355
+ async function calculateSourceNetworkCost({ accountSupports7702, gasless, messenger, quoteRequest, steps, transaction, }) {
437
356
  const noFees = {
438
357
  estimate: ZERO_AMOUNT,
439
358
  gasLimits: [],
@@ -442,11 +361,9 @@ async function calculateSourceNetworkCost({ accountSupports7702, gasless, messen
442
361
  maxFeePerGas: undefined,
443
362
  maxPriorityFeePerGas: undefined,
444
363
  };
445
- const { from, isPolymarketDepositWallet, sourceChainId, sourceTokenAddress } = quoteRequest;
446
- // A deposit wallet withdraw is broadcast by the Polymarket relayer, which
447
- // pays the gas, so the user only signs.
364
+ const { from, sourceChainId, sourceTokenAddress } = quoteRequest;
448
365
  const gasPayment = resolveGasPayment({
449
- isDelegated: gasless || Boolean(isPolymarketDepositWallet),
366
+ isDelegated: gasless,
450
367
  sourceTokenAddress,
451
368
  sponsorship: {
452
369
  accountSupports7702,
@@ -455,10 +372,7 @@ async function calculateSourceNetworkCost({ accountSupports7702, gasless, messen
455
372
  },
456
373
  });
457
374
  if (gasPayment.mode === GasPaymentMode.Delegation) {
458
- log('Zeroing source network fees as the user does not pay origin gas', {
459
- gasless,
460
- isPolymarketDepositWallet,
461
- });
375
+ log('Zeroing source network fees for gasless quote');
462
376
  return noFees;
463
377
  }
464
378
  if (gasPayment.mode === GasPaymentMode.Sponsored) {
@@ -475,38 +389,34 @@ async function calculateSourceNetworkCost({ accountSupports7702, gasless, messen
475
389
  : { maxFeePerGas: undefined, maxPriorityFeePerGas: undefined };
476
390
  const maxFeePerGas = firstStep.maxFeePerGas ?? gasFeeEstimate.maxFeePerGas;
477
391
  const maxPriorityFeePerGas = firstStep.maxPriorityFeePerGas ?? gasFeeEstimate.maxPriorityFeePerGas;
478
- // Legacy Safe Predict withdraws hold the source token in the Safe, so deposit
479
- // routes are estimated from the Safe. Swap routes keep the sender, as DEX
480
- // aggregators reject contract callers.
481
- const fromOverride = getPredictWithdrawSafeAddress(quoteRequest, transaction, hasServerDepositStep(steps));
482
- const { gasLimits, is7702, totalGasEstimate, totalGasLimit } = await estimateSourceGas({
483
- fromOverride,
392
+ const gasTransactions = steps.map((step) => stepToGasTransaction(step, from));
393
+ const gasResult = await estimateQuoteGasLimits({
394
+ fallbackGas: getFeatureFlags(messenger).relayFallbackGas,
395
+ fallbackOnSimulationFailure: true,
484
396
  messenger,
485
- request: quoteRequest,
486
- transaction,
487
- transactions: steps.map((step) => stepToGasTransaction(step, sender)),
397
+ transactions: gasTransactions,
488
398
  });
399
+ const { is7702 } = gasResult;
400
+ const gasLimits = is7702
401
+ ? [gasResult.gasLimits[0].max]
402
+ : gasResult.gasLimits.map((gasLimit) => gasLimit.max);
489
403
  const estimate = calculateGasCost({
490
404
  chainId: chainIdHex,
491
- gas: totalGasEstimate,
405
+ gas: gasResult.totalGasEstimate,
492
406
  maxFeePerGas: maxFeePerGas ?? '0',
493
407
  maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',
494
408
  messenger,
495
409
  });
496
410
  const max = calculateGasCost({
497
411
  chainId: chainIdHex,
498
- gas: totalGasLimit,
412
+ gas: gasResult.totalGasLimit,
499
413
  isMax: true,
500
414
  maxFeePerGas: maxFeePerGas ?? '0',
501
415
  maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',
502
416
  messenger,
503
417
  });
504
418
  const fees = { maxFeePerGas, maxPriorityFeePerGas };
505
- // Every Predict withdraw holds the source token in the Safe, so the fee token
506
- // lookup must use it even on swap routes.
507
- const feeTokenAccount = getPredictWithdrawFeeTokenAccount(quoteRequest, transaction);
508
419
  const gasStationCost = await resolveGasStationCost({
509
- feeTokenAccount,
510
420
  firstStepData: {
511
421
  data: firstStep.data,
512
422
  to: firstStep.to,
@@ -519,16 +429,13 @@ async function calculateSourceNetworkCost({ accountSupports7702, gasless, messen
519
429
  sourceChainId,
520
430
  sourceTokenAddress,
521
431
  },
522
- totalGasEstimate,
523
- totalItemCount: feeTokenAccount
524
- ? steps.length + 1
525
- : Math.max(steps.length, gasLimits.length),
432
+ totalGasEstimate: gasResult.totalGasEstimate,
433
+ totalItemCount: steps.length,
526
434
  });
527
435
  if (!gasStationCost.amount) {
528
436
  return { estimate, gasLimits, is7702, max, ...fees };
529
437
  }
530
438
  log('Using gas fee token for source network', {
531
- feeTokenAccount,
532
439
  gasFeeTokenCost: gasStationCost.amount,
533
440
  });
534
441
  return {
@@ -562,25 +469,6 @@ function isFulfilledResult(result) {
562
469
  result.quote.input !== undefined &&
563
470
  result.quote.output !== undefined);
564
471
  }
565
- /**
566
- * Whether a quote can be funded as requested. A deposit-address request is only
567
- * usable when the quote funds the provider with a plain token transfer, since
568
- * that transfer is what gets replaced by an unwrap straight to the deposit
569
- * address.
570
- *
571
- * @param body - The built server quote request.
572
- * @param result - Fulfilled provider result.
573
- * @returns True when the quote is usable.
574
- */
575
- function isUsableDepositAddressQuote(body, result) {
576
- if (!body.useDepositAddress || hasServerDepositStep(result.quote.steps)) {
577
- return true;
578
- }
579
- log('Ignoring deposit address quote without a plain token transfer', {
580
- provider: result.provider,
581
- });
582
- return false;
583
- }
584
472
  function decodeTransferRecipient(data) {
585
473
  return TRANSFER_INTERFACE.decodeFunctionData('transfer', data).to.toLowerCase();
586
474
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server-quotes.js","sourceRoot":"","sources":["../../../src/strategy/server/server-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\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 {\n CHAIN_ID_HYPERCORE,\n PaymentOverride,\n TransactionPayStrategy,\n} from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayFees,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getFiatValueFromUsd } from '../../utils/amounts.js';\nimport { getSlippage, isEIP7702Chain } from '../../utils/feature-flags.js';\nimport {\n GasPaymentMode,\n resolveGasPayment,\n resolveGasStationCost,\n} from '../../utils/gas-payment.js';\nimport { calculateGasCost, getGasFee } from '../../utils/gas.js';\nimport {\n getPolymarketDepositWalletOverrides,\n getPredictWithdrawFeeTokenAccount,\n getPredictWithdrawSafeAddress,\n} from '../../utils/polymarket/withdraw.js';\nimport { reservePostQuoteGas } from '../../utils/post-quote.js';\nimport { estimateSourceGas } from '../../utils/quote-gas.js';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas.js';\nimport { resolveNonAtomicRecipient } from '../../utils/second-leg.js';\nimport { getTokenFiatRate } from '../../utils/token.js';\nimport { getQuotePricing, TradeType } from '../../utils/trade-type.js';\nimport { hasServerDepositStep } from './deposit-step.js';\nimport { normalizeServerPerpsRequest } from './perps.js';\nimport { fetchServerQuote } from './server-api.js';\nimport type {\n ServerQuote,\n ServerQuotePayload,\n ServerQuoteRequest,\n ServerQuoteResult,\n ServerTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'server-quotes');\nconst HYPERCORE_CHAIN_ID_NUMBER = Number(CHAIN_ID_HYPERCORE);\nconst TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\nconst TRANSFER_INTERFACE = new Interface([\n 'function transfer(address to, uint256 amount)',\n]);\nconst ZERO_AMOUNT = { fiat: '0', human: '0', raw: '0', usd: '0' };\nconst ZERO_FIAT_VALUE = { fiat: '0', usd: '0' };\n\ntype FulfilledServerQuoteResult = ServerQuoteResult & {\n quote: NonNullable<ServerQuoteResult['quote']>;\n};\n\n/**\n * A quote request whose pricing is not yet decided.\n *\n * The pricing basis depends on whether calls end up bundled into the request,\n * so it is derived once the calls are known. A step that bundles calls may pin\n * `amount` itself, in which case that amount wins.\n */\ntype ServerQuoteRequestDraft = Omit<\n ServerQuoteRequest,\n 'amount' | 'tradeType'\n> &\n Partial<Pick<ServerQuoteRequest, 'amount'>>;\n\ntype SourceNetworkCost = Pick<\n TransactionPayFees['sourceNetwork'],\n 'estimate' | 'max'\n> & {\n gasLimits: number[];\n is7702: boolean;\n isSourceGasFeeToken?: boolean;\n maxFeePerGas: string | undefined;\n maxPriorityFeePerGas: string | undefined;\n};\n\nfunction isTransactionStep(\n step: ServerQuote['steps'][number],\n): step is ServerTransactionStep {\n return step.type === 'transaction';\n}\n\n/**\n * Fetch server intents-api quotes and normalize them into Transaction Pay quotes.\n *\n * @param request - Quote request context.\n * @returns Normalized server strategy quotes.\n */\nexport async function getServerQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<ServerQuote>[]> {\n const quoteRequests = request.requests.filter(shouldRequestQuote);\n\n log('Fetching quotes', { quoteRequests });\n\n const quotes = await Promise.all(\n quoteRequests.map((quoteRequest) =>\n getQuotesForRequest(quoteRequest, request),\n ),\n );\n\n return quotes.flat();\n}\n\nasync function getQuotesForRequest(\n quoteRequest: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<ServerQuote>[]> {\n try {\n const quotes = await fetchQuotes(quoteRequest, fullRequest);\n\n if (!quoteRequest.isPostQuote) {\n return quotes;\n }\n\n // Post-quote flows commit the whole source balance, so any gas paid in the\n // source token has to be reserved by re-quoting the same provider for less.\n return await Promise.all(\n quotes.map((quote) =>\n reservePostQuoteGas({\n quote,\n requote: (adjustedRequest) =>\n requoteProvider(adjustedRequest, fullRequest, quote.original),\n }),\n ),\n );\n } catch (error) {\n log('Error fetching quotes', { error });\n return [];\n }\n}\n\nasync function requoteProvider(\n quoteRequest: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n { provider }: ServerQuote,\n): Promise<TransactionPayQuote<ServerQuote>> {\n const [quote] = await fetchQuotes(quoteRequest, fullRequest, provider);\n\n if (!quote) {\n throw new Error(`No re-quote from provider: ${provider}`);\n }\n\n return quote;\n}\n\nasync function fetchQuotes(\n quoteRequest: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n provider?: string,\n): Promise<TransactionPayQuote<ServerQuote>[]> {\n const { accountSupports7702, messenger, signal, transaction } = fullRequest;\n\n const settledRequest = await resolveSettledRequest(\n quoteRequest,\n transaction,\n messenger,\n );\n\n const body = await buildServerQuoteRequest(\n settledRequest,\n transaction,\n messenger,\n accountSupports7702,\n );\n\n if (provider) {\n body.providers = [provider];\n }\n\n log('Request body', body);\n\n const response = await fetchServerQuote(messenger, body, signal);\n\n log('Raw quote response', response);\n\n const fulfilledResults = response.results.filter(\n (result): result is FulfilledServerQuoteResult =>\n isFulfilledResult(result) &&\n (!provider || result.provider === provider) &&\n isUsableDepositAddressQuote(body, result),\n );\n\n const normalized = await Promise.all(\n fulfilledResults.map((result) =>\n normalizeQuote(\n result,\n settledRequest,\n messenger,\n body,\n transaction,\n accountSupports7702,\n isSecondLegRequired(body, settledRequest, transaction, result.quote),\n ),\n ),\n );\n\n log('Normalized quotes', normalized);\n\n return normalized;\n}\n\n/**\n * Carry the account the funds settle on as the request recipient.\n *\n * The second leg runs from `request.recipient`, which has to match where the\n * funds actually landed. Non-atomic flows settle on the account submitting the\n * second leg, such as the Money Account of a Predict withdraw. Otherwise the\n * quote settles on the executing account rather than the payer.\n *\n * @param quoteRequest - Quote request.\n * @param transaction - Original transaction meta.\n * @param messenger - Controller messenger.\n * @returns The request with the settlement recipient applied.\n */\nasync function resolveSettledRequest(\n quoteRequest: QuoteRequest,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n): Promise<QuoteRequest> {\n const recipient =\n (await resolveNonAtomicRecipient(transaction, quoteRequest, messenger)) ??\n (transaction.txParams.from as Hex);\n\n return { ...quoteRequest, recipient };\n}\n\nasync function buildServerQuoteRequest(\n quoteRequest: QuoteRequest,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n accountSupports7702: boolean,\n): Promise<ServerQuoteRequest> {\n const normalizedRequest = normalizeServerPerpsRequest(\n quoteRequest,\n transaction,\n );\n const {\n atomic,\n from,\n isMaxAmount,\n isPolymarketDepositWallet,\n isPostQuote,\n paymentOverride,\n refundTo,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = normalizedRequest;\n\n const singleData = getSingleTransactionData(transaction);\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n // `from` is the payer, which differs from the account the transaction's calls\n // run from when an account override (e.g. Money Account) is active.\n const executionAccount = transaction.txParams.from as Hex;\n\n const recipient =\n isTokenTransfer && singleData\n ? decodeTransferRecipient(singleData)\n : (normalizedRequest.recipient ?? executionAccount);\n\n const isHypercoreSource = sourceChainId === CHAIN_ID_HYPERCORE;\n\n // Deposit wallet withdraws are broadcast by the Polymarket relayer rather\n // than as a gasless EIP-7702 batch, so the provider must not quote gasless.\n const supportsGasless =\n !isHypercoreSource &&\n !isPolymarketDepositWallet &&\n accountSupports7702 &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: ServerQuoteRequestDraft = {\n source: { chainId: Number(sourceChainId), token: sourceTokenAddress },\n target: { chainId: Number(targetChainId), token: targetTokenAddress },\n sender: from,\n recipient,\n slippage: Math.round(\n getSlippage(messenger, sourceChainId, sourceTokenAddress) * 10000,\n ),\n supportsGasless,\n };\n\n if (isPolymarketDepositWallet) {\n await applyDepositWalletOverrides(body, from, messenger);\n }\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation =\n hasNoData ||\n isTokenTransfer ||\n isHypercore ||\n isHypercoreSource ||\n // Explicitly non-atomic requests want the calls run after settlement, so\n // they must not be embedded in the quote.\n atomic === false ||\n (isPostQuote ?? false) ||\n (isMaxAmount ?? false) ||\n // The deposit wallet funds the quote with a plain token transfer, so there\n // are no calls to embed.\n (isPolymarketDepositWallet ?? false);\n\n if (\n isPostQuote &&\n atomic !== false &&\n paymentOverride === PaymentOverride.MoneyAccount\n ) {\n await processMoneyAccountPostQuote(\n transaction,\n normalizedRequest,\n body,\n messenger,\n );\n } else if (!skipDelegation) {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n body.calls = [\n {\n data: buildTransferData(executionAccount, targetAmountMinimum),\n to: targetTokenAddress,\n value: '0x0',\n },\n {\n data: delegation.data,\n to: delegation.to,\n value: delegation.value,\n },\n ];\n\n // Prefer atomic execution, but let providers that cannot run the calls\n // still quote for the funds. Only this path can fall back to a second leg:\n // the calls run as the execution account, which is also the recipient, so\n // we can submit them ourselves once the funds land. Post-quote flows submit\n // their own calls and must not opt in.\n if (\n canDeferCalls({\n accountSupports7702,\n messenger,\n targetChainId,\n transaction,\n })\n ) {\n body.supportsDeferredCalls = true;\n }\n\n if (delegation.authorizationList?.length) {\n body.authorizationList = normalizeAuthorizationList(\n delegation.authorizationList,\n );\n }\n } else if (isPostQuote || atomic === false) {\n // Honour the caller's refund address so a failed quote refunds the account\n // the funds came from, such as the Predict Safe, rather than the payer. A\n // deposit wallet refund address is kept, as the sweep reads refunds there.\n body.refundTo ??= refundTo;\n }\n\n const pricing = getQuotePricing({\n hasCalls: Boolean(body.calls?.length),\n sourceTokenAmount,\n targetAmountMinimum,\n transaction,\n });\n\n return {\n ...body,\n // A step that bundled its own calls has already pinned the amount those\n // calls consume, so it wins over the derived amount.\n amount: body.amount ?? pricing.amount,\n tradeType: pricing.tradeType,\n };\n}\n\n/**\n * Whether we can run the calls ourselves after the quote settles without\n * involving the user, so a funds-only quote is acceptable.\n *\n * The second leg is an internal, sponsored EIP-7702 batch on the target chain,\n * so the account must be able to sign EIP-7702 authorizations, the target chain\n * must support EIP-7702, and MetaMask must sponsor gas for the transaction on\n * that chain. Otherwise the user would need native gas on the target chain.\n *\n * Temporarily, only nested transactions are supported as second-leg calls, as\n * they are what the second leg re-encodes for the settled amount. Calls that\n * exist only on the top-level transaction are not deferred, so a provider that\n * cannot execute them declines rather than returning a funds-only quote.\n *\n * @param options - Check options.\n * @param options.accountSupports7702 - Whether the account can sign EIP-7702\n * authorizations.\n * @param options.messenger - Controller messenger.\n * @param options.targetChainId - Chain the second leg would run on.\n * @param options.transaction - Transaction being paid for.\n * @returns Whether the calls can be deferred to a second leg.\n */\nfunction canDeferCalls({\n accountSupports7702,\n messenger,\n targetChainId,\n transaction,\n}: {\n accountSupports7702: boolean;\n messenger: TransactionPayControllerMessenger;\n targetChainId: Hex;\n transaction: TransactionMeta;\n}): boolean {\n return (\n Boolean(transaction.nestedTransactions?.length) &&\n accountSupports7702 &&\n transaction.isGasFeeSponsored === true &&\n transaction.chainId === targetChainId &&\n isEIP7702Chain(messenger, targetChainId)\n );\n}\n\n/**\n * Quote a deposit wallet Predict withdraw from the deposit wallet itself.\n *\n * The deposit wallet funds the provider's deposit address with the USDC.e\n * unwrapped from its pUSD, and is also the refund address so the sweep can wrap\n * any refund back into pUSD.\n *\n * @param body - Quote request body to update.\n * @param from - The user EOA that owns the deposit wallet.\n * @param messenger - Controller messenger.\n */\nasync function applyDepositWalletOverrides(\n body: ServerQuoteRequestDraft,\n from: Hex,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { depositWallet, sourceTokenAddress } =\n await getPolymarketDepositWalletOverrides(from, messenger);\n\n body.source = { ...body.source, token: sourceTokenAddress };\n body.sender = depositWallet;\n body.refundTo = depositWallet;\n body.useDepositAddress = true;\n}\n\nfunction normalizeAuthorizationList(\n authorizationList: AuthorizationList,\n): NonNullable<ServerQuoteRequest['authorizationList']> {\n return authorizationList.map((entry) => ({\n address: entry.address,\n chainId: Number(entry.chainId),\n nonce: Number(entry.nonce),\n r: entry.r as Hex,\n s: entry.s as Hex,\n yParity: Number(entry.yParity),\n }));\n}\n\nasync function processMoneyAccountPostQuote(\n transaction: TransactionMeta,\n request: QuoteRequest,\n body: ServerQuoteRequestDraft,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { transactionData: transactionDataList } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const transactionData = transactionDataList[transaction.id];\n const amountHuman = transactionData?.tokens?.[0]?.amountHuman ?? '0';\n\n const {\n calls: overrideCalls,\n recipient,\n authorizationList,\n } = await messenger.call('TransactionPayController:getPaymentOverrideData', {\n amount: amountHuman,\n transaction,\n transactionData,\n });\n\n if (!overrideCalls.length) {\n log('No payment override calls for money account post-quote');\n return;\n }\n\n const fundingRecipient = recipient ?? request.from;\n const rawAmount = transactionData?.tokens?.[0]?.amountRaw ?? '0';\n\n // The bundled calls transfer exactly this amount, so pin it rather than\n // letting the amount be derived from the request.\n body.amount = rawAmount;\n\n // Settle directly on the Money Account. The deposit calls are delegated from\n // the Money Account, so the funds have to be there before they run.\n body.recipient = fundingRecipient;\n\n body.calls = overrideCalls.map((call) => ({\n data: call.data as Hex,\n to: call.to as Hex,\n value: call.value ?? '0x0',\n }));\n\n if (authorizationList?.length) {\n body.authorizationList = normalizeAuthorizationList(authorizationList);\n }\n\n log('Added money account post-quote calls to server quote body', {\n callCount: overrideCalls.length,\n });\n}\n\nfunction shouldRequestQuote(quoteRequest: QuoteRequest): boolean {\n return (\n quoteRequest.targetAmountMinimum !== '0' ||\n Boolean(quoteRequest.isPostQuote) ||\n Boolean(quoteRequest.isMaxAmount) ||\n Boolean(quoteRequest.isHyperliquidSource)\n );\n}\n\n/**\n * Determines whether the transaction's calls must be submitted as a separate\n * second leg on the target chain after the quote settles.\n *\n * `atomic` is only a hint: whether the calls can be executed by the provider\n * depends on the flow, so this checks what the built request actually carries\n * rather than what the caller asked for. Flows with nothing to run, or that\n * submit their own calls, are excluded.\n *\n * A second leg is needed either because we declined to embed the calls, or\n * because the provider that won the quote told us it will not execute them.\n * Non-atomic post-quote flows always need one: their calls come from the\n * payment override rather than the transaction, and run once funds settle.\n *\n * @param body - The built server quote request.\n * @param quoteRequest - The originating quote request.\n * @param transaction - Original transaction meta.\n * @param quote - The provider's quote payload.\n * @returns `true` when a second leg is required.\n */\nfunction isSecondLegRequired(\n body: ServerQuoteRequest,\n quoteRequest: QuoteRequest,\n transaction: TransactionMeta,\n quote: ServerQuotePayload,\n): boolean {\n // Embedded calls are executed by the provider as part of the quote, unless\n // it quoted for the funds alone and told us to run the calls ourselves.\n if (body.calls?.length && !quote.callsDeferred) {\n return false;\n }\n\n // HyperCore settles off-chain, so there is no target-chain transfer to read\n // a settled amount from. Checks the built body rather than the original\n // request, since perps deposits are only rewritten to HyperCore there.\n if (\n body.target.chainId === HYPERCORE_CHAIN_ID_NUMBER ||\n body.source.chainId === HYPERCORE_CHAIN_ID_NUMBER\n ) {\n return false;\n }\n\n // Post-quote flows submit the original transaction alongside the quote, so\n // the second leg never re-runs it. Only non-atomic flows have override calls\n // left to run once the funds settle.\n if (quoteRequest.isPostQuote) {\n return quoteRequest.atomic === false;\n }\n\n // No calls to run. Plain funding transfers and empty calldata are already\n // satisfied by the quote delivering the target token to the recipient.\n if (!transaction.nestedTransactions?.length) {\n return false;\n }\n\n const singleData = getSingleTransactionData(transaction);\n\n if (singleData === undefined || singleData === '0x') {\n return false;\n }\n\n if (singleData.startsWith(TOKEN_TRANSFER_FOUR_BYTE)) {\n return false;\n }\n\n return true;\n}\n\nasync function normalizeQuote(\n result: FulfilledServerQuoteResult,\n quoteRequest: QuoteRequest,\n messenger: TransactionPayControllerMessenger,\n body: ServerQuoteRequest,\n transaction: TransactionMeta,\n accountSupports7702: boolean,\n requiresSecondLeg: boolean,\n): Promise<TransactionPayQuote<ServerQuote>> {\n const { quote } = result;\n const { gasless } = quote;\n const isInputBased = body.tradeType === TradeType.ExactInput;\n const transactionSteps = quote.steps.filter(isTransactionStep);\n const isSignatureOnly = transactionSteps.length === 0;\n const sourceNetwork = await calculateSourceNetworkCost({\n accountSupports7702,\n gasless: gasless || isSignatureOnly,\n messenger,\n quoteRequest,\n sender: body.sender,\n steps: transactionSteps,\n transaction,\n });\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quoteRequest.sourceTokenAddress,\n quoteRequest.sourceChainId,\n );\n\n const usdToFiatRate = sourceFiatRate\n ? new BigNumber(sourceFiatRate.fiatRate).dividedBy(sourceFiatRate.usdRate)\n : new BigNumber(1);\n\n const targetFiatRate = getTokenFiatRate(\n messenger,\n quoteRequest.targetTokenAddress,\n quoteRequest.targetChainId,\n );\n\n const metaMask = getFiatValueFromUsd(\n new BigNumber(quote.fees.metamask),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n new BigNumber(quote.fees.provider),\n usdToFiatRate,\n );\n\n return {\n dust: ZERO_FIAT_VALUE,\n estimatedDuration: quote.duration,\n fees: {\n ...(sourceNetwork.isSourceGasFeeToken\n ? { isSourceGasFeeToken: true }\n : {}),\n metaMask,\n provider,\n sourceNetwork: {\n estimate: sourceNetwork.estimate,\n max: sourceNetwork.max,\n },\n targetNetwork: ZERO_FIAT_VALUE,\n },\n isInputBased,\n original: {\n client: {\n gasLimits: sourceNetwork.gasLimits,\n is7702: sourceNetwork.is7702,\n maxFeePerGas: sourceNetwork.maxFeePerGas,\n maxPriorityFeePerGas: sourceNetwork.maxPriorityFeePerGas,\n },\n duration: quote.duration,\n fees: quote.fees,\n gasless,\n id: quote.id,\n input: quote.input,\n output: quote.output,\n provider: result.provider,\n steps: quote.steps,\n },\n request: quoteRequest,\n requiresSecondLeg,\n sourceAmount: {\n fiat: sourceFiatRate\n ? new BigNumber(quote.input.formatted)\n .multipliedBy(sourceFiatRate.fiatRate)\n .toString(10)\n : '0',\n human: quote.input.formatted,\n raw: quote.input.raw,\n usd: sourceFiatRate\n ? new BigNumber(quote.input.formatted)\n .multipliedBy(sourceFiatRate.usdRate)\n .toString(10)\n : '0',\n },\n strategy: TransactionPayStrategy.Server,\n targetAmount: {\n fiat: targetFiatRate\n ? new BigNumber(quote.output.formatted)\n .multipliedBy(targetFiatRate.fiatRate)\n .toString(10)\n : '0',\n usd: targetFiatRate\n ? new BigNumber(quote.output.formatted)\n .multipliedBy(targetFiatRate.usdRate)\n .toString(10)\n : '0',\n },\n };\n}\n\nasync function calculateSourceNetworkCost({\n accountSupports7702,\n gasless,\n messenger,\n quoteRequest,\n sender,\n steps,\n transaction,\n}: {\n accountSupports7702: boolean | undefined;\n gasless: boolean;\n messenger: TransactionPayControllerMessenger;\n quoteRequest: QuoteRequest;\n sender: Hex;\n steps: ServerTransactionStep[];\n transaction: TransactionMeta;\n}): Promise<SourceNetworkCost> {\n const noFees = {\n estimate: ZERO_AMOUNT,\n gasLimits: [],\n is7702: false,\n max: ZERO_AMOUNT,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n };\n\n const { from, isPolymarketDepositWallet, sourceChainId, sourceTokenAddress } =\n quoteRequest;\n\n // A deposit wallet withdraw is broadcast by the Polymarket relayer, which\n // pays the gas, so the user only signs.\n const gasPayment = resolveGasPayment({\n isDelegated: gasless || Boolean(isPolymarketDepositWallet),\n sourceTokenAddress,\n sponsorship: {\n accountSupports7702,\n request: quoteRequest,\n transaction,\n },\n });\n\n if (gasPayment.mode === GasPaymentMode.Delegation) {\n log('Zeroing source network fees as the user does not pay origin gas', {\n gasless,\n isPolymarketDepositWallet,\n });\n return noFees;\n }\n\n if (gasPayment.mode === GasPaymentMode.Sponsored) {\n log('Zeroing source network fees for sponsored same-chain server route');\n\n // Gas limit is zero as sponsored transactions go through the EIP-7702\n // gas station hook and do not require user-paid gas.\n return { ...noFees, gasLimits: [0], is7702: true };\n }\n\n const firstStep = steps[0];\n const chainIdHex = toHex(firstStep.chainId);\n\n const needsGasFeeEstimate =\n !firstStep.maxFeePerGas && !firstStep.maxPriorityFeePerGas;\n\n const gasFeeEstimate = needsGasFeeEstimate\n ? getGasFee(chainIdHex, messenger)\n : { maxFeePerGas: undefined, maxPriorityFeePerGas: undefined };\n\n const maxFeePerGas = firstStep.maxFeePerGas ?? gasFeeEstimate.maxFeePerGas;\n const maxPriorityFeePerGas =\n firstStep.maxPriorityFeePerGas ?? gasFeeEstimate.maxPriorityFeePerGas;\n\n // Legacy Safe Predict withdraws hold the source token in the Safe, so deposit\n // routes are estimated from the Safe. Swap routes keep the sender, as DEX\n // aggregators reject contract callers.\n const fromOverride = getPredictWithdrawSafeAddress(\n quoteRequest,\n transaction,\n hasServerDepositStep(steps),\n );\n\n const { gasLimits, is7702, totalGasEstimate, totalGasLimit } =\n await estimateSourceGas({\n fromOverride,\n messenger,\n request: quoteRequest,\n transaction,\n transactions: steps.map((step) => stepToGasTransaction(step, sender)),\n });\n\n const estimate = calculateGasCost({\n chainId: chainIdHex,\n gas: totalGasEstimate,\n maxFeePerGas: maxFeePerGas ?? '0',\n maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',\n messenger,\n });\n\n const max = calculateGasCost({\n chainId: chainIdHex,\n gas: totalGasLimit,\n isMax: true,\n maxFeePerGas: maxFeePerGas ?? '0',\n maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',\n messenger,\n });\n\n const fees = { maxFeePerGas, maxPriorityFeePerGas };\n\n // Every Predict withdraw holds the source token in the Safe, so the fee token\n // lookup must use it even on swap routes.\n const feeTokenAccount = getPredictWithdrawFeeTokenAccount(\n quoteRequest,\n transaction,\n );\n\n const gasStationCost = await resolveGasStationCost({\n feeTokenAccount,\n firstStepData: {\n data: firstStep.data,\n to: firstStep.to,\n value: firstStep.value,\n },\n messenger,\n nativeGasCostRaw: max.raw,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate,\n totalItemCount: feeTokenAccount\n ? steps.length + 1\n : Math.max(steps.length, gasLimits.length),\n });\n\n if (!gasStationCost.amount) {\n return { estimate, gasLimits, is7702, max, ...fees };\n }\n\n log('Using gas fee token for source network', {\n feeTokenAccount,\n gasFeeTokenCost: gasStationCost.amount,\n });\n\n return {\n estimate: gasStationCost.amount,\n gasLimits,\n is7702,\n isSourceGasFeeToken: true,\n max: gasStationCost.amount,\n ...fees,\n };\n}\n\nfunction stepToGasTransaction(\n step: ServerTransactionStep,\n from: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(step.chainId),\n data: step.data,\n from,\n to: step.to,\n value: step.value,\n };\n}\n\nfunction getSingleTransactionData(\n transaction: TransactionMeta,\n): Hex | undefined {\n for (const nested of transaction.nestedTransactions ?? []) {\n if (nested.data && nested.data !== '0x') {\n return nested.data;\n }\n }\n\n return transaction.txParams?.data as Hex | undefined;\n}\n\nfunction isFulfilledResult(\n result: ServerQuoteResult,\n): result is FulfilledServerQuoteResult {\n return (\n result.quote?.id !== undefined &&\n result.quote.input !== undefined &&\n result.quote.output !== undefined\n );\n}\n\n/**\n * Whether a quote can be funded as requested. A deposit-address request is only\n * usable when the quote funds the provider with a plain token transfer, since\n * that transfer is what gets replaced by an unwrap straight to the deposit\n * address.\n *\n * @param body - The built server quote request.\n * @param result - Fulfilled provider result.\n * @returns True when the quote is usable.\n */\nfunction isUsableDepositAddressQuote(\n body: ServerQuoteRequest,\n result: FulfilledServerQuoteResult,\n): boolean {\n if (!body.useDepositAddress || hasServerDepositStep(result.quote.steps)) {\n return true;\n }\n\n log('Ignoring deposit address quote without a plain token transfer', {\n provider: result.provider,\n });\n\n return false;\n}\n\nfunction decodeTransferRecipient(data: Hex): Hex {\n return TRANSFER_INTERFACE.decodeFunctionData(\n 'transfer',\n data,\n ).to.toLowerCase() as Hex;\n}\n\nfunction buildTransferData(recipient: Hex, amountRaw: string): Hex {\n return TRANSFER_INTERFACE.encodeFunctionData('transfer', [\n recipient,\n amountRaw,\n ]) as Hex;\n}\n"]}
1
+ {"version":3,"file":"server-quotes.js","sourceRoot":"","sources":["../../../src/strategy/server/server-quotes.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { toHex } from '@metamask/controller-utils';\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 {\n CHAIN_ID_HYPERCORE,\n PaymentOverride,\n TransactionPayStrategy,\n} from '../../constants.js';\nimport { projectLogger } from '../../logger.js';\nimport type {\n PayStrategyGetQuotesRequest,\n QuoteRequest,\n TransactionPayControllerMessenger,\n TransactionPayFees,\n TransactionPayQuote,\n} from '../../types.js';\nimport { getFiatValueFromUsd } from '../../utils/amounts.js';\nimport {\n getFeatureFlags,\n getSlippage,\n isEIP7702Chain,\n} from '../../utils/feature-flags.js';\nimport {\n GasPaymentMode,\n resolveGasPayment,\n resolveGasStationCost,\n} from '../../utils/gas-payment.js';\nimport { calculateGasCost, getGasFee } from '../../utils/gas.js';\nimport { estimateQuoteGasLimits } from '../../utils/quote-gas.js';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas.js';\nimport { getTokenFiatRate } from '../../utils/token.js';\nimport { getQuotePricing, TradeType } from '../../utils/trade-type.js';\nimport { normalizeServerPerpsRequest } from './perps.js';\nimport { fetchServerQuote } from './server-api.js';\nimport type {\n ServerQuote,\n ServerQuotePayload,\n ServerQuoteRequest,\n ServerQuoteResult,\n ServerTransactionStep,\n} from './types.js';\n\nconst log = createModuleLogger(projectLogger, 'server-quotes');\nconst HYPERCORE_CHAIN_ID_NUMBER = Number(CHAIN_ID_HYPERCORE);\nconst TOKEN_TRANSFER_FOUR_BYTE = '0xa9059cbb';\nconst TRANSFER_INTERFACE = new Interface([\n 'function transfer(address to, uint256 amount)',\n]);\nconst ZERO_AMOUNT = { fiat: '0', human: '0', raw: '0', usd: '0' };\nconst ZERO_FIAT_VALUE = { fiat: '0', usd: '0' };\n\ntype FulfilledServerQuoteResult = ServerQuoteResult & {\n quote: NonNullable<ServerQuoteResult['quote']>;\n};\n\n/**\n * A quote request whose pricing is not yet decided.\n *\n * The pricing basis depends on whether calls end up bundled into the request,\n * so it is derived once the calls are known. A step that bundles calls may pin\n * `amount` itself, in which case that amount wins.\n */\ntype ServerQuoteRequestDraft = Omit<\n ServerQuoteRequest,\n 'amount' | 'tradeType'\n> &\n Partial<Pick<ServerQuoteRequest, 'amount'>>;\n\ntype SourceNetworkCost = Pick<\n TransactionPayFees['sourceNetwork'],\n 'estimate' | 'max'\n> & {\n gasLimits: number[];\n is7702: boolean;\n isSourceGasFeeToken?: boolean;\n maxFeePerGas: string | undefined;\n maxPriorityFeePerGas: string | undefined;\n};\n\nfunction isTransactionStep(\n step: ServerQuote['steps'][number],\n): step is ServerTransactionStep {\n return step.type === 'transaction';\n}\n\n/**\n * Fetch server intents-api quotes and normalize them into Transaction Pay quotes.\n *\n * @param request - Quote request context.\n * @returns Normalized server strategy quotes.\n */\nexport async function getServerQuotes(\n request: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<ServerQuote>[]> {\n const quoteRequests = request.requests.filter(shouldRequestQuote);\n\n log('Fetching quotes', { quoteRequests });\n\n const quotes = await Promise.all(\n quoteRequests.map((quoteRequest) =>\n getQuotesForRequest(quoteRequest, request),\n ),\n );\n\n return quotes.flat();\n}\n\nasync function getQuotesForRequest(\n quoteRequest: QuoteRequest,\n fullRequest: PayStrategyGetQuotesRequest,\n): Promise<TransactionPayQuote<ServerQuote>[]> {\n const { accountSupports7702, messenger, signal, transaction } = fullRequest;\n\n try {\n const body = await buildServerQuoteRequest(\n quoteRequest,\n transaction,\n messenger,\n accountSupports7702,\n );\n\n log('Request body', body);\n\n const response = await fetchServerQuote(messenger, body, signal);\n\n log('Raw quote response', response);\n\n const fulfilledResults = response.results.filter(isFulfilledResult);\n\n // The second leg runs from `request.recipient`, so it has to match the\n // executing account the quote settles on.\n const settledRequest = {\n ...quoteRequest,\n recipient: transaction.txParams.from as Hex,\n };\n\n const normalized = await Promise.all(\n fulfilledResults.map((result) =>\n normalizeQuote(\n result,\n settledRequest,\n messenger,\n body.tradeType === TradeType.ExactInput,\n transaction,\n accountSupports7702,\n isSecondLegRequired(body, quoteRequest, transaction, result.quote),\n ),\n ),\n );\n\n log('Normalized quotes', normalized);\n\n return normalized;\n } catch (error) {\n log('Error fetching quotes', { error });\n return [];\n }\n}\n\nasync function buildServerQuoteRequest(\n quoteRequest: QuoteRequest,\n transaction: TransactionMeta,\n messenger: TransactionPayControllerMessenger,\n accountSupports7702: boolean,\n): Promise<ServerQuoteRequest> {\n const normalizedRequest = normalizeServerPerpsRequest(\n quoteRequest,\n transaction,\n );\n const {\n atomic,\n from,\n isMaxAmount,\n isPostQuote,\n paymentOverride,\n sourceChainId,\n sourceTokenAddress,\n sourceTokenAmount,\n targetAmountMinimum,\n targetChainId,\n targetTokenAddress,\n } = normalizedRequest;\n\n const singleData = getSingleTransactionData(transaction);\n const isHypercore = targetChainId === CHAIN_ID_HYPERCORE;\n const isTokenTransfer =\n !isHypercore && Boolean(singleData?.startsWith(TOKEN_TRANSFER_FOUR_BYTE));\n\n // `from` is the payer, which differs from the account the transaction's calls\n // run from when an account override (e.g. Money Account) is active.\n const executionAccount = transaction.txParams.from as Hex;\n\n const recipient =\n isTokenTransfer && singleData\n ? decodeTransferRecipient(singleData)\n : executionAccount;\n\n const isHypercoreSource = sourceChainId === CHAIN_ID_HYPERCORE;\n const supportsGasless =\n !isHypercoreSource &&\n accountSupports7702 &&\n isEIP7702Chain(messenger, sourceChainId);\n\n const body: ServerQuoteRequestDraft = {\n source: { chainId: Number(sourceChainId), token: sourceTokenAddress },\n target: { chainId: Number(targetChainId), token: targetTokenAddress },\n sender: from,\n recipient,\n slippage: Math.round(\n getSlippage(messenger, sourceChainId, sourceTokenAddress) * 10000,\n ),\n supportsGasless,\n };\n\n const hasNoData = singleData === undefined || singleData === '0x';\n const skipDelegation =\n hasNoData ||\n isTokenTransfer ||\n isHypercore ||\n isHypercoreSource ||\n // Explicitly non-atomic requests want the calls run after settlement, so\n // they must not be embedded in the quote.\n atomic === false ||\n (isPostQuote ?? false) ||\n (isMaxAmount ?? false);\n\n if (isPostQuote && paymentOverride === PaymentOverride.MoneyAccount) {\n await processMoneyAccountPostQuote(\n transaction,\n normalizedRequest,\n body,\n messenger,\n );\n } else if (!skipDelegation) {\n const delegation = await messenger.call(\n 'TransactionPayController:getDelegationTransaction',\n { transaction },\n );\n\n body.calls = [\n {\n data: buildTransferData(executionAccount, targetAmountMinimum),\n to: targetTokenAddress,\n value: '0x0',\n },\n {\n data: delegation.data,\n to: delegation.to,\n value: delegation.value,\n },\n ];\n\n // Prefer atomic execution, but let providers that cannot run the calls\n // still quote for the funds. Only this path can fall back to a second leg:\n // the calls run as the execution account, which is also the recipient, so\n // we can submit them ourselves once the funds land. Post-quote flows submit\n // their own calls and must not opt in.\n if (\n canDeferCalls({\n accountSupports7702,\n messenger,\n targetChainId,\n transaction,\n })\n ) {\n body.supportsDeferredCalls = true;\n }\n\n if (delegation.authorizationList?.length) {\n body.authorizationList = normalizeAuthorizationList(\n delegation.authorizationList,\n );\n }\n }\n\n const pricing = getQuotePricing({\n hasCalls: Boolean(body.calls?.length),\n sourceTokenAmount,\n targetAmountMinimum,\n transaction,\n });\n\n return {\n ...body,\n // A step that bundled its own calls has already pinned the amount those\n // calls consume, so it wins over the derived amount.\n amount: body.amount ?? pricing.amount,\n tradeType: pricing.tradeType,\n };\n}\n\n/**\n * Whether we can run the calls ourselves after the quote settles without\n * involving the user, so a funds-only quote is acceptable.\n *\n * The second leg is an internal, sponsored EIP-7702 batch on the target chain,\n * so the account must be able to sign EIP-7702 authorizations, the target chain\n * must support EIP-7702, and MetaMask must sponsor gas for the transaction on\n * that chain. Otherwise the user would need native gas on the target chain.\n *\n * Temporarily, only nested transactions are supported as second-leg calls, as\n * they are what the second leg re-encodes for the settled amount. Calls that\n * exist only on the top-level transaction are not deferred, so a provider that\n * cannot execute them declines rather than returning a funds-only quote.\n *\n * @param options - Check options.\n * @param options.accountSupports7702 - Whether the account can sign EIP-7702\n * authorizations.\n * @param options.messenger - Controller messenger.\n * @param options.targetChainId - Chain the second leg would run on.\n * @param options.transaction - Transaction being paid for.\n * @returns Whether the calls can be deferred to a second leg.\n */\nfunction canDeferCalls({\n accountSupports7702,\n messenger,\n targetChainId,\n transaction,\n}: {\n accountSupports7702: boolean;\n messenger: TransactionPayControllerMessenger;\n targetChainId: Hex;\n transaction: TransactionMeta;\n}): boolean {\n return (\n Boolean(transaction.nestedTransactions?.length) &&\n accountSupports7702 &&\n transaction.isGasFeeSponsored === true &&\n transaction.chainId === targetChainId &&\n isEIP7702Chain(messenger, targetChainId)\n );\n}\n\nfunction normalizeAuthorizationList(\n authorizationList: AuthorizationList,\n): NonNullable<ServerQuoteRequest['authorizationList']> {\n return authorizationList.map((entry) => ({\n address: entry.address,\n chainId: Number(entry.chainId),\n nonce: Number(entry.nonce),\n r: entry.r as Hex,\n s: entry.s as Hex,\n yParity: Number(entry.yParity),\n }));\n}\n\nasync function processMoneyAccountPostQuote(\n transaction: TransactionMeta,\n request: QuoteRequest,\n body: ServerQuoteRequestDraft,\n messenger: TransactionPayControllerMessenger,\n): Promise<void> {\n const { transactionData: transactionDataList } = messenger.call(\n 'TransactionPayController:getState',\n );\n\n const transactionData = transactionDataList[transaction.id];\n const amountHuman = transactionData?.tokens?.[0]?.amountHuman ?? '0';\n\n const {\n calls: overrideCalls,\n recipient,\n authorizationList,\n } = await messenger.call('TransactionPayController:getPaymentOverrideData', {\n amount: amountHuman,\n transaction,\n transactionData,\n });\n\n if (!overrideCalls.length) {\n log('No payment override calls for money account post-quote');\n return;\n }\n\n const fundingRecipient = recipient ?? request.from;\n const rawAmount = transactionData?.tokens?.[0]?.amountRaw ?? '0';\n\n // The bundled calls transfer exactly this amount, so pin it rather than\n // letting the amount be derived from the request.\n body.amount = rawAmount;\n\n // Settle directly on the Money Account. The deposit calls are delegated from\n // the Money Account, so the funds have to be there before they run.\n body.recipient = fundingRecipient;\n\n body.calls = overrideCalls.map((call) => ({\n data: call.data as Hex,\n to: call.to as Hex,\n value: call.value ?? '0x0',\n }));\n\n if (authorizationList?.length) {\n body.authorizationList = normalizeAuthorizationList(authorizationList);\n }\n\n log('Added money account post-quote calls to server quote body', {\n callCount: overrideCalls.length,\n });\n}\n\nfunction shouldRequestQuote(quoteRequest: QuoteRequest): boolean {\n return (\n quoteRequest.targetAmountMinimum !== '0' ||\n Boolean(quoteRequest.isPostQuote) ||\n Boolean(quoteRequest.isMaxAmount) ||\n Boolean(quoteRequest.isHyperliquidSource)\n );\n}\n\n/**\n * Determines whether the transaction's calls must be submitted as a separate\n * second leg on the target chain after the quote settles.\n *\n * `atomic` is only a hint: whether the calls can be executed by the provider\n * depends on the flow, so this checks what the built request actually carries\n * rather than what the caller asked for. Flows with nothing to run, or that\n * submit their own calls, are excluded.\n *\n * A second leg is needed either because we declined to embed the calls, or\n * because the provider that won the quote told us it will not execute them.\n *\n * @param body - The built server quote request.\n * @param quoteRequest - The originating quote request.\n * @param transaction - Original transaction meta.\n * @param quote - The provider's quote payload.\n * @returns `true` when a second leg is required.\n */\nfunction isSecondLegRequired(\n body: ServerQuoteRequest,\n quoteRequest: QuoteRequest,\n transaction: TransactionMeta,\n quote: ServerQuotePayload,\n): boolean {\n // Embedded calls are executed by the provider as part of the quote, unless\n // it quoted for the funds alone and told us to run the calls ourselves.\n if (body.calls?.length && !quote.callsDeferred) {\n return false;\n }\n\n // No calls to run. Plain funding transfers and empty calldata are already\n // satisfied by the quote delivering the target token to the recipient.\n if (!transaction.nestedTransactions?.length) {\n return false;\n }\n\n const singleData = getSingleTransactionData(transaction);\n\n if (singleData === undefined || singleData === '0x') {\n return false;\n }\n\n if (singleData.startsWith(TOKEN_TRANSFER_FOUR_BYTE)) {\n return false;\n }\n\n // HyperCore settles off-chain, so there is no target-chain transfer to read\n // a settled amount from. Checks the built body rather than the original\n // request, since perps deposits are only rewritten to HyperCore there.\n if (\n body.target.chainId === HYPERCORE_CHAIN_ID_NUMBER ||\n body.source.chainId === HYPERCORE_CHAIN_ID_NUMBER\n ) {\n return false;\n }\n\n // Post-quote flows submit the original transaction separately, so running it\n // again as a second leg would double-execute it.\n if (quoteRequest.isPostQuote) {\n return false;\n }\n\n return true;\n}\n\nasync function normalizeQuote(\n result: FulfilledServerQuoteResult,\n quoteRequest: QuoteRequest,\n messenger: TransactionPayControllerMessenger,\n isInputBased: boolean,\n transaction: TransactionMeta,\n accountSupports7702: boolean,\n requiresSecondLeg: boolean,\n): Promise<TransactionPayQuote<ServerQuote>> {\n const { quote } = result;\n const { gasless } = quote;\n const transactionSteps = quote.steps.filter(isTransactionStep);\n const isSignatureOnly = transactionSteps.length === 0;\n const sourceNetwork = await calculateSourceNetworkCost({\n accountSupports7702,\n gasless: gasless || isSignatureOnly,\n messenger,\n quoteRequest,\n steps: transactionSteps,\n transaction,\n });\n\n const sourceFiatRate = getTokenFiatRate(\n messenger,\n quoteRequest.sourceTokenAddress,\n quoteRequest.sourceChainId,\n );\n\n const usdToFiatRate = sourceFiatRate\n ? new BigNumber(sourceFiatRate.fiatRate).dividedBy(sourceFiatRate.usdRate)\n : new BigNumber(1);\n\n const targetFiatRate = getTokenFiatRate(\n messenger,\n quoteRequest.targetTokenAddress,\n quoteRequest.targetChainId,\n );\n\n const metaMask = getFiatValueFromUsd(\n new BigNumber(quote.fees.metamask),\n usdToFiatRate,\n );\n\n const provider = getFiatValueFromUsd(\n new BigNumber(quote.fees.provider),\n usdToFiatRate,\n );\n\n return {\n dust: ZERO_FIAT_VALUE,\n estimatedDuration: quote.duration,\n fees: {\n ...(sourceNetwork.isSourceGasFeeToken\n ? { isSourceGasFeeToken: true }\n : {}),\n metaMask,\n provider,\n sourceNetwork: {\n estimate: sourceNetwork.estimate,\n max: sourceNetwork.max,\n },\n targetNetwork: ZERO_FIAT_VALUE,\n },\n isInputBased,\n original: {\n client: {\n gasLimits: sourceNetwork.gasLimits,\n is7702: sourceNetwork.is7702,\n maxFeePerGas: sourceNetwork.maxFeePerGas,\n maxPriorityFeePerGas: sourceNetwork.maxPriorityFeePerGas,\n },\n duration: quote.duration,\n fees: quote.fees,\n gasless,\n id: quote.id,\n input: quote.input,\n output: quote.output,\n provider: result.provider,\n steps: quote.steps,\n },\n request: quoteRequest,\n requiresSecondLeg,\n sourceAmount: {\n fiat: sourceFiatRate\n ? new BigNumber(quote.input.formatted)\n .multipliedBy(sourceFiatRate.fiatRate)\n .toString(10)\n : '0',\n human: quote.input.formatted,\n raw: quote.input.raw,\n usd: sourceFiatRate\n ? new BigNumber(quote.input.formatted)\n .multipliedBy(sourceFiatRate.usdRate)\n .toString(10)\n : '0',\n },\n strategy: TransactionPayStrategy.Server,\n targetAmount: {\n fiat: targetFiatRate\n ? new BigNumber(quote.output.formatted)\n .multipliedBy(targetFiatRate.fiatRate)\n .toString(10)\n : '0',\n usd: targetFiatRate\n ? new BigNumber(quote.output.formatted)\n .multipliedBy(targetFiatRate.usdRate)\n .toString(10)\n : '0',\n },\n };\n}\n\nasync function calculateSourceNetworkCost({\n accountSupports7702,\n gasless,\n messenger,\n quoteRequest,\n steps,\n transaction,\n}: {\n accountSupports7702: boolean | undefined;\n gasless: boolean;\n messenger: TransactionPayControllerMessenger;\n quoteRequest: QuoteRequest;\n steps: ServerTransactionStep[];\n transaction: TransactionMeta;\n}): Promise<SourceNetworkCost> {\n const noFees = {\n estimate: ZERO_AMOUNT,\n gasLimits: [],\n is7702: false,\n max: ZERO_AMOUNT,\n maxFeePerGas: undefined,\n maxPriorityFeePerGas: undefined,\n };\n\n const { from, sourceChainId, sourceTokenAddress } = quoteRequest;\n\n const gasPayment = resolveGasPayment({\n isDelegated: gasless,\n sourceTokenAddress,\n sponsorship: {\n accountSupports7702,\n request: quoteRequest,\n transaction,\n },\n });\n\n if (gasPayment.mode === GasPaymentMode.Delegation) {\n log('Zeroing source network fees for gasless quote');\n return noFees;\n }\n\n if (gasPayment.mode === GasPaymentMode.Sponsored) {\n log('Zeroing source network fees for sponsored same-chain server route');\n\n // Gas limit is zero as sponsored transactions go through the EIP-7702\n // gas station hook and do not require user-paid gas.\n return { ...noFees, gasLimits: [0], is7702: true };\n }\n\n const firstStep = steps[0];\n const chainIdHex = toHex(firstStep.chainId);\n\n const needsGasFeeEstimate =\n !firstStep.maxFeePerGas && !firstStep.maxPriorityFeePerGas;\n\n const gasFeeEstimate = needsGasFeeEstimate\n ? getGasFee(chainIdHex, messenger)\n : { maxFeePerGas: undefined, maxPriorityFeePerGas: undefined };\n\n const maxFeePerGas = firstStep.maxFeePerGas ?? gasFeeEstimate.maxFeePerGas;\n const maxPriorityFeePerGas =\n firstStep.maxPriorityFeePerGas ?? gasFeeEstimate.maxPriorityFeePerGas;\n\n const gasTransactions = steps.map((step) => stepToGasTransaction(step, from));\n\n const gasResult = await estimateQuoteGasLimits({\n fallbackGas: getFeatureFlags(messenger).relayFallbackGas,\n fallbackOnSimulationFailure: true,\n messenger,\n transactions: gasTransactions,\n });\n\n const { is7702 } = gasResult;\n const gasLimits = is7702\n ? [gasResult.gasLimits[0].max]\n : gasResult.gasLimits.map((gasLimit) => gasLimit.max);\n\n const estimate = calculateGasCost({\n chainId: chainIdHex,\n gas: gasResult.totalGasEstimate,\n maxFeePerGas: maxFeePerGas ?? '0',\n maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',\n messenger,\n });\n\n const max = calculateGasCost({\n chainId: chainIdHex,\n gas: gasResult.totalGasLimit,\n isMax: true,\n maxFeePerGas: maxFeePerGas ?? '0',\n maxPriorityFeePerGas: maxPriorityFeePerGas ?? '0',\n messenger,\n });\n\n const fees = { maxFeePerGas, maxPriorityFeePerGas };\n\n const gasStationCost = await resolveGasStationCost({\n firstStepData: {\n data: firstStep.data,\n to: firstStep.to,\n value: firstStep.value,\n },\n messenger,\n nativeGasCostRaw: max.raw,\n request: {\n from,\n sourceChainId,\n sourceTokenAddress,\n },\n totalGasEstimate: gasResult.totalGasEstimate,\n totalItemCount: steps.length,\n });\n\n if (!gasStationCost.amount) {\n return { estimate, gasLimits, is7702, max, ...fees };\n }\n\n log('Using gas fee token for source network', {\n gasFeeTokenCost: gasStationCost.amount,\n });\n\n return {\n estimate: gasStationCost.amount,\n gasLimits,\n is7702,\n isSourceGasFeeToken: true,\n max: gasStationCost.amount,\n ...fees,\n };\n}\n\nfunction stepToGasTransaction(\n step: ServerTransactionStep,\n from: Hex,\n): QuoteGasTransaction {\n return {\n chainId: toHex(step.chainId),\n data: step.data,\n from,\n to: step.to,\n value: step.value,\n };\n}\n\nfunction getSingleTransactionData(\n transaction: TransactionMeta,\n): Hex | undefined {\n for (const nested of transaction.nestedTransactions ?? []) {\n if (nested.data && nested.data !== '0x') {\n return nested.data;\n }\n }\n\n return transaction.txParams?.data as Hex | undefined;\n}\n\nfunction isFulfilledResult(\n result: ServerQuoteResult,\n): result is FulfilledServerQuoteResult {\n return (\n result.quote?.id !== undefined &&\n result.quote.input !== undefined &&\n result.quote.output !== undefined\n );\n}\n\nfunction decodeTransferRecipient(data: Hex): Hex {\n return TRANSFER_INTERFACE.decodeFunctionData(\n 'transfer',\n data,\n ).to.toLowerCase() as Hex;\n}\n\nfunction buildTransferData(recipient: Hex, amountRaw: string): Hex {\n return TRANSFER_INTERFACE.encodeFunctionData('transfer', [\n recipient,\n amountRaw,\n ]) as Hex;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"server-submit.d.ts","sourceRoot":"","sources":["../../../src/strategy/server/server-submit.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,MAAM,gBAAgB,CAAC;AAgCxB,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,YAAY,CAAC;AAkDpB;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,OAAO,CAAC;IAAE,eAAe,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC,CAgBpC"}
1
+ {"version":3,"file":"server-submit.d.ts","sourceRoot":"","sources":["../../../src/strategy/server/server-submit.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAK3C,OAAO,KAAK,EACV,yBAAyB,EAG1B,MAAM,gBAAgB,CAAC;AA2BxB,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,YAAY,CAAC;AA4CpB;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,CAAC,WAAW,CAAC,GAC9C,OAAO,CAAC;IAAE,eAAe,CAAC,EAAE,GAAG,CAAA;CAAE,CAAC,CAgBpC"}