@metamask-previews/transaction-pay-controller 30.3.1-preview-35f016caa → 30.3.2-preview-c1f9a0f
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 +16 -1
- package/dist/strategy/across/AcrossStrategy.d.ts.map +1 -1
- package/dist/strategy/across/AcrossStrategy.js +3 -3
- package/dist/strategy/across/AcrossStrategy.js.map +1 -1
- package/dist/strategy/across/across-actions.js +2 -2
- package/dist/strategy/across/across-actions.js.map +1 -1
- package/dist/strategy/across/across-quotes.js +1 -1
- package/dist/strategy/across/across-quotes.js.map +1 -1
- package/dist/strategy/across/across-submit.d.ts.map +1 -1
- package/dist/strategy/across/across-submit.js +4 -2
- package/dist/strategy/across/across-submit.js.map +1 -1
- package/dist/strategy/across/perps.d.ts +4 -23
- package/dist/strategy/across/perps.d.ts.map +1 -1
- package/dist/strategy/across/perps.js +5 -42
- package/dist/strategy/across/perps.js.map +1 -1
- package/dist/strategy/relay/relay-quotes.d.ts.map +1 -1
- package/dist/strategy/relay/relay-quotes.js +42 -84
- package/dist/strategy/relay/relay-quotes.js.map +1 -1
- package/dist/strategy/server/perps.d.ts +4 -24
- package/dist/strategy/server/perps.d.ts.map +1 -1
- package/dist/strategy/server/perps.js +7 -66
- package/dist/strategy/server/perps.js.map +1 -1
- package/dist/strategy/server/server-quotes.d.ts.map +1 -1
- package/dist/strategy/server/server-quotes.js +39 -70
- package/dist/strategy/server/server-quotes.js.map +1 -1
- package/dist/utils/perps.d.ts +56 -0
- package/dist/utils/perps.d.ts.map +1 -0
- package/dist/utils/perps.js +112 -0
- package/dist/utils/perps.js.map +1 -0
- package/dist/utils/post-quote-payment-override.d.ts +42 -0
- package/dist/utils/post-quote-payment-override.d.ts.map +1 -0
- package/dist/utils/post-quote-payment-override.js +55 -0
- package/dist/utils/post-quote-payment-override.js.map +1 -0
- package/dist/utils/quote-recipient.d.ts +22 -0
- package/dist/utils/quote-recipient.d.ts.map +1 -0
- package/dist/utils/quote-recipient.js +41 -0
- package/dist/utils/quote-recipient.js.map +1 -0
- package/dist/utils/second-leg.d.ts +1 -21
- package/dist/utils/second-leg.d.ts.map +1 -1
- package/dist/utils/second-leg.js +0 -36
- package/dist/utils/second-leg.js.map +1 -1
- package/dist/utils/source-amounts.d.ts.map +1 -1
- package/dist/utils/source-amounts.js +8 -8
- package/dist/utils/source-amounts.js.map +1 -1
- package/package.json +4 -4
|
@@ -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 { CHAIN_ID_HYPERCORE, TransactionPayStrategy } 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 { processPostQuotePaymentOverride } from '../../utils/post-quote-payment-override.js';\nimport { reservePostQuoteGas } from '../../utils/post-quote.js';\nimport { estimateSourceGas } from '../../utils/quote-gas.js';\nimport type { QuoteGasTransaction } from '../../utils/quote-gas.js';\nimport { resolveQuoteRecipient } from '../../utils/quote-recipient.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 body = await buildServerQuoteRequest(\n quoteRequest,\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 { ...quoteRequest, recipient: body.recipient },\n messenger,\n body,\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}\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 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 &&\n atomic !== false &&\n !isPostQuote &&\n !isPolymarketDepositWallet &&\n !normalizedRequest.skipProcessTransactions &&\n 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 tokenTransferRecipient =\n isTokenTransfer && singleData\n ? decodeTransferRecipient(singleData)\n : undefined;\n\n const override = await processPostQuotePaymentOverride({\n messenger,\n request: normalizedRequest,\n transaction,\n });\n const recipient = await resolveQuoteRecipient({\n messenger,\n request: {\n ...normalizedRequest,\n recipient: override?.recipient ?? tokenTransferRecipient,\n },\n transaction,\n });\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 (override) {\n body.amount = override.amount;\n body.calls = override.calls;\n\n if (override.authorizationList?.length) {\n body.authorizationList = normalizeAuthorizationList(\n override.authorizationList,\n );\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. The response determines whether execution is\n // deferred. Post-quote flows submit 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\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 (body.target.chainId === HYPERCORE_CHAIN_ID_NUMBER) {\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 if (body.source.chainId === HYPERCORE_CHAIN_ID_NUMBER) {\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 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"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
2
|
+
import type { Hex } from '@metamask/utils';
|
|
3
|
+
import type { QuoteRequest } from '../types.js';
|
|
4
|
+
type PerpsTransaction = Pick<TransactionMeta, 'txParams' | 'nestedTransactions'>;
|
|
5
|
+
/**
|
|
6
|
+
* Detect whether a transaction is a Hyperliquid perps deposit by inspecting
|
|
7
|
+
* the parent transaction (and any nested transactions) for a call to the
|
|
8
|
+
* Hyperliquid bridge or an ERC-20 transfer to it.
|
|
9
|
+
*
|
|
10
|
+
* Transaction type is intentionally NOT consulted so that any caller
|
|
11
|
+
* funnelling a bridge deposit through Pay is supported.
|
|
12
|
+
*
|
|
13
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
14
|
+
* @returns Whether the transaction deposits into the Hyperliquid bridge.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isPerpsDepositTransaction(transaction: PerpsTransaction | undefined): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Detect whether a quote request is a Hyperliquid perps deposit, meaning the
|
|
19
|
+
* parent transaction deposits into the Hyperliquid bridge and the request
|
|
20
|
+
* targets the Arbitrum USDC it requires.
|
|
21
|
+
*
|
|
22
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
23
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
24
|
+
* @returns Whether the request matches a Hyperliquid perps deposit.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isPerpsDepositRequest(request: Pick<QuoteRequest, 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'>, transaction: PerpsTransaction | undefined): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Rewrite a Hyperliquid perps-deposit quote request into a HyperCore direct
|
|
29
|
+
* deposit.
|
|
30
|
+
*
|
|
31
|
+
* Transaction pay starts from the parent on-chain asset (Arbitrum USDC,
|
|
32
|
+
* 6 decimals), while HyperCore expects an 8-decimal amount, so the target
|
|
33
|
+
* amount is shifted accordingly.
|
|
34
|
+
*
|
|
35
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
36
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
37
|
+
* @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to
|
|
38
|
+
* set as the target token.
|
|
39
|
+
* @returns Normalized request, or the original request if not a perps deposit.
|
|
40
|
+
*/
|
|
41
|
+
export declare function normalizePerpsDepositRequest(request: QuoteRequest, transaction: PerpsTransaction | undefined, hypercoreUsdcAddress: Hex): QuoteRequest;
|
|
42
|
+
/**
|
|
43
|
+
* Rewrite a Hyperliquid perps-withdraw quote request so the source is
|
|
44
|
+
* HyperCore USDC rather than Arbitrum USDC.
|
|
45
|
+
*
|
|
46
|
+
* The source amount is provided in 6 decimals and shifted to the 8 decimals
|
|
47
|
+
* HyperCore expects.
|
|
48
|
+
*
|
|
49
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
50
|
+
* @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to
|
|
51
|
+
* set as the source token.
|
|
52
|
+
* @returns Normalized request, or the original request if not a perps withdraw.
|
|
53
|
+
*/
|
|
54
|
+
export declare function normalizePerpsWithdrawRequest(request: QuoteRequest, hypercoreUsdcAddress: Hex): QuoteRequest;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=perps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perps.d.ts","sourceRoot":"","sources":["../../src/utils/perps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAU3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,KAAK,gBAAgB,GAAG,IAAI,CAC1B,eAAe,EACf,UAAU,GAAG,oBAAoB,CAClC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,gBAAgB,GAAG,SAAS,GACxC,OAAO,CAeT;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CACX,YAAY,EACZ,aAAa,GAAG,eAAe,GAAG,oBAAoB,CACvD,EACD,WAAW,EAAE,gBAAgB,GAAG,SAAS,GACxC,OAAO,CAQT;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,gBAAgB,GAAG,SAAS,EACzC,oBAAoB,EAAE,GAAG,GACxB,YAAY,CAWd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,YAAY,EACrB,oBAAoB,EAAE,GAAG,GACxB,YAAY,CAad"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { BigNumber } from 'bignumber.js';
|
|
2
|
+
import { ARBITRUM_USDC_ADDRESS, CHAIN_ID_ARBITRUM, CHAIN_ID_HYPERCORE, HYPERCORE_USDC_DECIMALS, USDC_DECIMALS, } from '../constants.js';
|
|
3
|
+
import { extractErc20TransferRecipient } from './polymarket/calldata.js';
|
|
4
|
+
const HYPERLIQUID_BRIDGE_ADDRESS_LOWER = '0x2df1c51e09aecf9cacb7bc98cb1742757f163df7';
|
|
5
|
+
/**
|
|
6
|
+
* Detect whether a transaction is a Hyperliquid perps deposit by inspecting
|
|
7
|
+
* the parent transaction (and any nested transactions) for a call to the
|
|
8
|
+
* Hyperliquid bridge or an ERC-20 transfer to it.
|
|
9
|
+
*
|
|
10
|
+
* Transaction type is intentionally NOT consulted so that any caller
|
|
11
|
+
* funnelling a bridge deposit through Pay is supported.
|
|
12
|
+
*
|
|
13
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
14
|
+
* @returns Whether the transaction deposits into the Hyperliquid bridge.
|
|
15
|
+
*/
|
|
16
|
+
export function isPerpsDepositTransaction(transaction) {
|
|
17
|
+
if (!transaction) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const calls = [
|
|
21
|
+
transaction.txParams,
|
|
22
|
+
...(transaction.nestedTransactions ?? []),
|
|
23
|
+
];
|
|
24
|
+
return calls.some((call) => isBridgeAddress(call?.to) ||
|
|
25
|
+
isBridgeAddress(getTransferRecipient(call?.data)));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Detect whether a quote request is a Hyperliquid perps deposit, meaning the
|
|
29
|
+
* parent transaction deposits into the Hyperliquid bridge and the request
|
|
30
|
+
* targets the Arbitrum USDC it requires.
|
|
31
|
+
*
|
|
32
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
33
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
34
|
+
* @returns Whether the request matches a Hyperliquid perps deposit.
|
|
35
|
+
*/
|
|
36
|
+
export function isPerpsDepositRequest(request, transaction) {
|
|
37
|
+
return (request.isPostQuote !== true &&
|
|
38
|
+
request.targetChainId === CHAIN_ID_ARBITRUM &&
|
|
39
|
+
request.targetTokenAddress.toLowerCase() ===
|
|
40
|
+
ARBITRUM_USDC_ADDRESS.toLowerCase() &&
|
|
41
|
+
isPerpsDepositTransaction(transaction));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Rewrite a Hyperliquid perps-deposit quote request into a HyperCore direct
|
|
45
|
+
* deposit.
|
|
46
|
+
*
|
|
47
|
+
* Transaction pay starts from the parent on-chain asset (Arbitrum USDC,
|
|
48
|
+
* 6 decimals), while HyperCore expects an 8-decimal amount, so the target
|
|
49
|
+
* amount is shifted accordingly.
|
|
50
|
+
*
|
|
51
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
52
|
+
* @param transaction - Parent transaction whose calls are inspected.
|
|
53
|
+
* @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to
|
|
54
|
+
* set as the target token.
|
|
55
|
+
* @returns Normalized request, or the original request if not a perps deposit.
|
|
56
|
+
*/
|
|
57
|
+
export function normalizePerpsDepositRequest(request, transaction, hypercoreUsdcAddress) {
|
|
58
|
+
if (!isPerpsDepositRequest(request, transaction)) {
|
|
59
|
+
return request;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
...request,
|
|
63
|
+
targetAmountMinimum: toHypercoreAmount(request.targetAmountMinimum),
|
|
64
|
+
targetChainId: CHAIN_ID_HYPERCORE,
|
|
65
|
+
targetTokenAddress: hypercoreUsdcAddress,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Rewrite a Hyperliquid perps-withdraw quote request so the source is
|
|
70
|
+
* HyperCore USDC rather than Arbitrum USDC.
|
|
71
|
+
*
|
|
72
|
+
* The source amount is provided in 6 decimals and shifted to the 8 decimals
|
|
73
|
+
* HyperCore expects.
|
|
74
|
+
*
|
|
75
|
+
* @param request - Quote request from the transaction-pay controller.
|
|
76
|
+
* @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to
|
|
77
|
+
* set as the source token.
|
|
78
|
+
* @returns Normalized request, or the original request if not a perps withdraw.
|
|
79
|
+
*/
|
|
80
|
+
export function normalizePerpsWithdrawRequest(request, hypercoreUsdcAddress) {
|
|
81
|
+
if (!request.isHyperliquidSource) {
|
|
82
|
+
return request;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
...request,
|
|
86
|
+
sourceChainId: CHAIN_ID_HYPERCORE,
|
|
87
|
+
sourceTokenAddress: hypercoreUsdcAddress,
|
|
88
|
+
sourceTokenAmount: request.sourceTokenAmount
|
|
89
|
+
? toHypercoreAmount(request.sourceTokenAmount)
|
|
90
|
+
: request.sourceTokenAmount,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function getTransferRecipient(data) {
|
|
94
|
+
if (!data) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
return extractErc20TransferRecipient(data);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function isBridgeAddress(address) {
|
|
105
|
+
return address?.toLowerCase() === HYPERLIQUID_BRIDGE_ADDRESS_LOWER;
|
|
106
|
+
}
|
|
107
|
+
function toHypercoreAmount(amount) {
|
|
108
|
+
return new BigNumber(amount)
|
|
109
|
+
.shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)
|
|
110
|
+
.toFixed(0);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=perps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perps.js","sourceRoot":"","sources":["../../src/utils/perps.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AAEzE,MAAM,gCAAgC,GACpC,4CAA4C,CAAC;AAO/C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CACvC,WAAyC;IAEzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,KAAK,GAAG;QACZ,WAAW,CAAC,QAAQ;QACpB,GAAG,CAAC,WAAW,CAAC,kBAAkB,IAAI,EAAE,CAAC;KAC1C,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,IAAI,EAAE,EAAE,CACP,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC;QACzB,eAAe,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CACpD,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAGC,EACD,WAAyC;IAEzC,OAAO,CACL,OAAO,CAAC,WAAW,KAAK,IAAI;QAC5B,OAAO,CAAC,aAAa,KAAK,iBAAiB;QAC3C,OAAO,CAAC,kBAAkB,CAAC,WAAW,EAAE;YACtC,qBAAqB,CAAC,WAAW,EAAE;QACrC,yBAAyB,CAAC,WAAW,CAAC,CACvC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAqB,EACrB,WAAyC,EACzC,oBAAyB;IAEzB,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,mBAAmB,EAAE,iBAAiB,CAAC,OAAO,CAAC,mBAAmB,CAAC;QACnE,aAAa,EAAE,kBAAkB;QACjC,kBAAkB,EAAE,oBAAoB;KACzC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,6BAA6B,CAC3C,OAAqB,EACrB,oBAAyB;IAEzB,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,aAAa,EAAE,kBAAkB;QACjC,kBAAkB,EAAE,oBAAoB;QACxC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC1C,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,iBAAiB,CAAC;YAC9C,CAAC,CAAC,OAAO,CAAC,iBAAiB;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAwB;IACpD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,6BAA6B,CAAC,IAAW,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,OAA2B;IAClD,OAAO,OAAO,EAAE,WAAW,EAAE,KAAK,gCAAgC,CAAC;AACrE,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc;IACvC,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC;SACzB,SAAS,CAAC,uBAAuB,GAAG,aAAa,CAAC;SAClD,OAAO,CAAC,CAAC,CAAC,CAAC;AAChB,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { BigNumber } from 'bignumber.js';\n\nimport {\n ARBITRUM_USDC_ADDRESS,\n CHAIN_ID_ARBITRUM,\n CHAIN_ID_HYPERCORE,\n HYPERCORE_USDC_DECIMALS,\n USDC_DECIMALS,\n} from '../constants.js';\nimport type { QuoteRequest } from '../types.js';\nimport { extractErc20TransferRecipient } from './polymarket/calldata.js';\n\nconst HYPERLIQUID_BRIDGE_ADDRESS_LOWER =\n '0x2df1c51e09aecf9cacb7bc98cb1742757f163df7';\n\ntype PerpsTransaction = Pick<\n TransactionMeta,\n 'txParams' | 'nestedTransactions'\n>;\n\n/**\n * Detect whether a transaction is a Hyperliquid perps deposit by inspecting\n * the parent transaction (and any nested transactions) for a call to the\n * Hyperliquid bridge or an ERC-20 transfer to it.\n *\n * Transaction type is intentionally NOT consulted so that any caller\n * funnelling a bridge deposit through Pay is supported.\n *\n * @param transaction - Parent transaction whose calls are inspected.\n * @returns Whether the transaction deposits into the Hyperliquid bridge.\n */\nexport function isPerpsDepositTransaction(\n transaction: PerpsTransaction | undefined,\n): boolean {\n if (!transaction) {\n return false;\n }\n\n const calls = [\n transaction.txParams,\n ...(transaction.nestedTransactions ?? []),\n ];\n\n return calls.some(\n (call) =>\n isBridgeAddress(call?.to) ||\n isBridgeAddress(getTransferRecipient(call?.data)),\n );\n}\n\n/**\n * Detect whether a quote request is a Hyperliquid perps deposit, meaning the\n * parent transaction deposits into the Hyperliquid bridge and the request\n * targets the Arbitrum USDC it requires.\n *\n * @param request - Quote request from the transaction-pay controller.\n * @param transaction - Parent transaction whose calls are inspected.\n * @returns Whether the request matches a Hyperliquid perps deposit.\n */\nexport function isPerpsDepositRequest(\n request: Pick<\n QuoteRequest,\n 'isPostQuote' | 'targetChainId' | 'targetTokenAddress'\n >,\n transaction: PerpsTransaction | undefined,\n): boolean {\n return (\n request.isPostQuote !== true &&\n request.targetChainId === CHAIN_ID_ARBITRUM &&\n request.targetTokenAddress.toLowerCase() ===\n ARBITRUM_USDC_ADDRESS.toLowerCase() &&\n isPerpsDepositTransaction(transaction)\n );\n}\n\n/**\n * Rewrite a Hyperliquid perps-deposit quote request into a HyperCore direct\n * deposit.\n *\n * Transaction pay starts from the parent on-chain asset (Arbitrum USDC,\n * 6 decimals), while HyperCore expects an 8-decimal amount, so the target\n * amount is shifted accordingly.\n *\n * @param request - Quote request from the transaction-pay controller.\n * @param transaction - Parent transaction whose calls are inspected.\n * @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to\n * set as the target token.\n * @returns Normalized request, or the original request if not a perps deposit.\n */\nexport function normalizePerpsDepositRequest(\n request: QuoteRequest,\n transaction: PerpsTransaction | undefined,\n hypercoreUsdcAddress: Hex,\n): QuoteRequest {\n if (!isPerpsDepositRequest(request, transaction)) {\n return request;\n }\n\n return {\n ...request,\n targetAmountMinimum: toHypercoreAmount(request.targetAmountMinimum),\n targetChainId: CHAIN_ID_HYPERCORE,\n targetTokenAddress: hypercoreUsdcAddress,\n };\n}\n\n/**\n * Rewrite a Hyperliquid perps-withdraw quote request so the source is\n * HyperCore USDC rather than Arbitrum USDC.\n *\n * The source amount is provided in 6 decimals and shifted to the 8 decimals\n * HyperCore expects.\n *\n * @param request - Quote request from the transaction-pay controller.\n * @param hypercoreUsdcAddress - Strategy-specific HyperCore USDC address to\n * set as the source token.\n * @returns Normalized request, or the original request if not a perps withdraw.\n */\nexport function normalizePerpsWithdrawRequest(\n request: QuoteRequest,\n hypercoreUsdcAddress: Hex,\n): QuoteRequest {\n if (!request.isHyperliquidSource) {\n return request;\n }\n\n return {\n ...request,\n sourceChainId: CHAIN_ID_HYPERCORE,\n sourceTokenAddress: hypercoreUsdcAddress,\n sourceTokenAmount: request.sourceTokenAmount\n ? toHypercoreAmount(request.sourceTokenAmount)\n : request.sourceTokenAmount,\n };\n}\n\nfunction getTransferRecipient(data: string | undefined): Hex | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return extractErc20TransferRecipient(data as Hex);\n } catch {\n return undefined;\n }\n}\n\nfunction isBridgeAddress(address: string | undefined): boolean {\n return address?.toLowerCase() === HYPERLIQUID_BRIDGE_ADDRESS_LOWER;\n}\n\nfunction toHypercoreAmount(amount: string): string {\n return new BigNumber(amount)\n .shiftedBy(HYPERCORE_USDC_DECIMALS - USDC_DECIMALS)\n .toFixed(0);\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
2
|
+
import type { Hex } from '@metamask/utils';
|
|
3
|
+
import type { GetPaymentOverrideDataResponse, QuoteRequest, TransactionPayControllerMessenger } from '../types.js';
|
|
4
|
+
type PostQuotePaymentOverride = Omit<GetPaymentOverrideDataResponse, 'calls'> & {
|
|
5
|
+
amount: string;
|
|
6
|
+
calls: {
|
|
7
|
+
data: Hex;
|
|
8
|
+
to: Hex;
|
|
9
|
+
value: Hex;
|
|
10
|
+
}[];
|
|
11
|
+
recipient: Hex;
|
|
12
|
+
};
|
|
13
|
+
type PaymentOverrideOptions = {
|
|
14
|
+
messenger: TransactionPayControllerMessenger;
|
|
15
|
+
transaction: TransactionMeta;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Prepare an atomic post-quote override for a provider-specific request body.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Quote and callback context.
|
|
21
|
+
* @param options.request - Quote request determining override eligibility.
|
|
22
|
+
* @returns Validated calls, funding amount and authorization data, if applicable.
|
|
23
|
+
*/
|
|
24
|
+
export declare function processPostQuotePaymentOverride({ request, ...options }: PaymentOverrideOptions & {
|
|
25
|
+
request: QuoteRequest;
|
|
26
|
+
}): Promise<PostQuotePaymentOverride | undefined>;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the post-quote funding account and calls from the client callback.
|
|
29
|
+
* Both atomic and non-atomic overrides require a recipient, including when
|
|
30
|
+
* the callback cannot build any calls. Pre-quote callbacks have no such rule.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Callback context.
|
|
33
|
+
* @param options.messenger - Controller messenger.
|
|
34
|
+
* @param options.transaction - Original transaction metadata.
|
|
35
|
+
* @returns Override data with its required recipient and raw funding amount.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getPostQuotePaymentOverrideData({ messenger, transaction, }: PaymentOverrideOptions): Promise<GetPaymentOverrideDataResponse & {
|
|
38
|
+
amount: string;
|
|
39
|
+
recipient: Hex;
|
|
40
|
+
}>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=post-quote-payment-override.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-quote-payment-override.d.ts","sourceRoot":"","sources":["../../src/utils/post-quote-payment-override.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,EACV,8BAA8B,EAC9B,YAAY,EACZ,iCAAiC,EAClC,MAAM,aAAa,CAAC;AAErB,KAAK,wBAAwB,GAAG,IAAI,CAClC,8BAA8B,EAC9B,OAAO,CACR,GAAG;IACF,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,GAAG,CAAC;QAAC,EAAE,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,EAAE,CAAC;IAC5C,SAAS,EAAE,GAAG,CAAC;CAChB,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC5B,SAAS,EAAE,iCAAiC,CAAC;IAC7C,WAAW,EAAE,eAAe,CAAC;CAC9B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,OAAO,EACP,GAAG,OAAO,EACX,EAAE,sBAAsB,GAAG;IAC1B,OAAO,EAAE,YAAY,CAAC;CACvB,GAAG,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAuBhD;AAED;;;;;;;;;GASG;AACH,wBAAsB,+BAA+B,CAAC,EACpD,SAAS,EACT,WAAW,GACZ,EAAE,sBAAsB,GAAG,OAAO,CACjC,8BAA8B,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,GAAG,CAAA;CAAE,CACpE,CAwBA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prepare an atomic post-quote override for a provider-specific request body.
|
|
3
|
+
*
|
|
4
|
+
* @param options - Quote and callback context.
|
|
5
|
+
* @param options.request - Quote request determining override eligibility.
|
|
6
|
+
* @returns Validated calls, funding amount and authorization data, if applicable.
|
|
7
|
+
*/
|
|
8
|
+
export async function processPostQuotePaymentOverride({ request, ...options }) {
|
|
9
|
+
if (!request.isPostQuote ||
|
|
10
|
+
request.atomic === false ||
|
|
11
|
+
request.paymentOverride === undefined) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
const override = await getPostQuotePaymentOverrideData(options);
|
|
15
|
+
if (!override.calls.length) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
...override,
|
|
20
|
+
calls: override.calls.map((call) => ({
|
|
21
|
+
data: call.data,
|
|
22
|
+
to: call.to,
|
|
23
|
+
value: call.value ?? '0x0',
|
|
24
|
+
})),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the post-quote funding account and calls from the client callback.
|
|
29
|
+
* Both atomic and non-atomic overrides require a recipient, including when
|
|
30
|
+
* the callback cannot build any calls. Pre-quote callbacks have no such rule.
|
|
31
|
+
*
|
|
32
|
+
* @param options - Callback context.
|
|
33
|
+
* @param options.messenger - Controller messenger.
|
|
34
|
+
* @param options.transaction - Original transaction metadata.
|
|
35
|
+
* @returns Override data with its required recipient and raw funding amount.
|
|
36
|
+
*/
|
|
37
|
+
export async function getPostQuotePaymentOverrideData({ messenger, transaction, }) {
|
|
38
|
+
const { transactionData: transactionDataList } = messenger.call('TransactionPayController:getState');
|
|
39
|
+
const transactionData = transactionDataList[transaction.id];
|
|
40
|
+
const token = transactionData?.tokens?.[0];
|
|
41
|
+
const override = await messenger.call('TransactionPayController:getPaymentOverrideData', {
|
|
42
|
+
amount: token?.amountHuman ?? '0',
|
|
43
|
+
transaction,
|
|
44
|
+
transactionData,
|
|
45
|
+
});
|
|
46
|
+
if (!override.recipient) {
|
|
47
|
+
throw new Error('Missing post-quote payment override recipient');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
...override,
|
|
51
|
+
amount: token?.amountRaw ?? '0',
|
|
52
|
+
recipient: override.recipient,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=post-quote-payment-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"post-quote-payment-override.js","sourceRoot":"","sources":["../../src/utils/post-quote-payment-override.ts"],"names":[],"mappings":"AAuBA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EACpD,OAAO,EACP,GAAG,OAAO,EAGX;IACC,IACE,CAAC,OAAO,CAAC,WAAW;QACpB,OAAO,CAAC,MAAM,KAAK,KAAK;QACxB,OAAO,CAAC,eAAe,KAAK,SAAS,EACrC,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,+BAA+B,CAAC,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,GAAG,QAAQ;QACX,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACnC,IAAI,EAAE,IAAI,CAAC,IAAW;YACtB,EAAE,EAAE,IAAI,CAAC,EAAS;YAClB,KAAK,EAAG,IAAI,CAAC,KAAa,IAAI,KAAK;SACpC,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EACpD,SAAS,EACT,WAAW,GACY;IAGvB,MAAM,EAAE,eAAe,EAAE,mBAAmB,EAAE,GAAG,SAAS,CAAC,IAAI,CAC7D,mCAAmC,CACpC,CAAC;IACF,MAAM,eAAe,GAAG,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,eAAe,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CACnC,iDAAiD,EACjD;QACE,MAAM,EAAE,KAAK,EAAE,WAAW,IAAI,GAAG;QACjC,WAAW;QACX,eAAe;KAChB,CACF,CAAC;IAEF,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,OAAO;QACL,GAAG,QAAQ;QACX,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,GAAG;QAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;KAC9B,CAAC;AACJ,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n GetPaymentOverrideDataResponse,\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../types.js';\n\ntype PostQuotePaymentOverride = Omit<\n GetPaymentOverrideDataResponse,\n 'calls'\n> & {\n amount: string;\n calls: { data: Hex; to: Hex; value: Hex }[];\n recipient: Hex;\n};\n\ntype PaymentOverrideOptions = {\n messenger: TransactionPayControllerMessenger;\n transaction: TransactionMeta;\n};\n\n/**\n * Prepare an atomic post-quote override for a provider-specific request body.\n *\n * @param options - Quote and callback context.\n * @param options.request - Quote request determining override eligibility.\n * @returns Validated calls, funding amount and authorization data, if applicable.\n */\nexport async function processPostQuotePaymentOverride({\n request,\n ...options\n}: PaymentOverrideOptions & {\n request: QuoteRequest;\n}): Promise<PostQuotePaymentOverride | undefined> {\n if (\n !request.isPostQuote ||\n request.atomic === false ||\n request.paymentOverride === undefined\n ) {\n return undefined;\n }\n\n const override = await getPostQuotePaymentOverrideData(options);\n\n if (!override.calls.length) {\n return undefined;\n }\n\n return {\n ...override,\n calls: override.calls.map((call) => ({\n data: call.data as Hex,\n to: call.to as Hex,\n value: (call.value as Hex) ?? '0x0',\n })),\n };\n}\n\n/**\n * Resolve the post-quote funding account and calls from the client callback.\n * Both atomic and non-atomic overrides require a recipient, including when\n * the callback cannot build any calls. Pre-quote callbacks have no such rule.\n *\n * @param options - Callback context.\n * @param options.messenger - Controller messenger.\n * @param options.transaction - Original transaction metadata.\n * @returns Override data with its required recipient and raw funding amount.\n */\nexport async function getPostQuotePaymentOverrideData({\n messenger,\n transaction,\n}: PaymentOverrideOptions): Promise<\n GetPaymentOverrideDataResponse & { amount: string; recipient: Hex }\n> {\n const { transactionData: transactionDataList } = messenger.call(\n 'TransactionPayController:getState',\n );\n const transactionData = transactionDataList[transaction.id];\n const token = transactionData?.tokens?.[0];\n const override = await messenger.call(\n 'TransactionPayController:getPaymentOverrideData',\n {\n amount: token?.amountHuman ?? '0',\n transaction,\n transactionData,\n },\n );\n\n if (!override.recipient) {\n throw new Error('Missing post-quote payment override recipient');\n }\n\n return {\n ...override,\n amount: token?.amountRaw ?? '0',\n recipient: override.recipient,\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TransactionMeta } from '@metamask/transaction-controller';
|
|
2
|
+
import type { Hex } from '@metamask/utils';
|
|
3
|
+
import type { QuoteRequest, TransactionPayControllerMessenger } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the quote recipient used by both Relay and Server.
|
|
6
|
+
*
|
|
7
|
+
* Non-atomic execution must be funded on its execution account. Ordinary
|
|
8
|
+
* post-quote withdrawals pay the selected receiving account in `request.from`.
|
|
9
|
+
* Deposits default to the original transaction's execution account.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Recipient resolution options.
|
|
12
|
+
* @param options.messenger - Controller messenger.
|
|
13
|
+
* @param options.request - Quote request.
|
|
14
|
+
* @param options.transaction - Original transaction metadata.
|
|
15
|
+
* @returns The recipient to use for the quote body.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveQuoteRecipient({ messenger, request, transaction, }: {
|
|
18
|
+
messenger: TransactionPayControllerMessenger;
|
|
19
|
+
request: QuoteRequest;
|
|
20
|
+
transaction: TransactionMeta;
|
|
21
|
+
}): Promise<Hex>;
|
|
22
|
+
//# sourceMappingURL=quote-recipient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote-recipient.d.ts","sourceRoot":"","sources":["../../src/utils/quote-recipient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,EACV,YAAY,EACZ,iCAAiC,EAClC,MAAM,aAAa,CAAC;AAGrB;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,SAAS,EACT,OAAO,EACP,WAAW,GACZ,EAAE;IACD,SAAS,EAAE,iCAAiC,CAAC;IAC7C,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,eAAe,CAAC;CAC9B,GAAG,OAAO,CAAC,GAAG,CAAC,CA+Bf"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getPostQuotePaymentOverrideData } from './post-quote-payment-override.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the quote recipient used by both Relay and Server.
|
|
4
|
+
*
|
|
5
|
+
* Non-atomic execution must be funded on its execution account. Ordinary
|
|
6
|
+
* post-quote withdrawals pay the selected receiving account in `request.from`.
|
|
7
|
+
* Deposits default to the original transaction's execution account.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Recipient resolution options.
|
|
10
|
+
* @param options.messenger - Controller messenger.
|
|
11
|
+
* @param options.request - Quote request.
|
|
12
|
+
* @param options.transaction - Original transaction metadata.
|
|
13
|
+
* @returns The recipient to use for the quote body.
|
|
14
|
+
*/
|
|
15
|
+
export async function resolveQuoteRecipient({ messenger, request, transaction, }) {
|
|
16
|
+
const executionAccount = transaction.txParams.from;
|
|
17
|
+
if (request.atomic === false && request.isPostQuote) {
|
|
18
|
+
// The client identifies the account executing target-side override calls.
|
|
19
|
+
const { recipient } = await getPostQuotePaymentOverrideData({
|
|
20
|
+
messenger,
|
|
21
|
+
transaction,
|
|
22
|
+
});
|
|
23
|
+
return recipient;
|
|
24
|
+
}
|
|
25
|
+
if (request.atomic === false) {
|
|
26
|
+
// Fund the original execution account before submitting its second leg.
|
|
27
|
+
return executionAccount;
|
|
28
|
+
}
|
|
29
|
+
if (request.recipient) {
|
|
30
|
+
// Preserve an explicit payout recipient once second-leg funding is handled.
|
|
31
|
+
return request.recipient;
|
|
32
|
+
}
|
|
33
|
+
if (request.isPostQuote) {
|
|
34
|
+
// Ordinary withdrawals pay the selected receiving account, which can differ
|
|
35
|
+
// from the account executing the source withdrawal.
|
|
36
|
+
return request.from;
|
|
37
|
+
}
|
|
38
|
+
// Deposits default to the execution account, which can differ from the payer.
|
|
39
|
+
return executionAccount;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=quote-recipient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quote-recipient.js","sourceRoot":"","sources":["../../src/utils/quote-recipient.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC1C,SAAS,EACT,OAAO,EACP,WAAW,GAKZ;IACC,MAAM,gBAAgB,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAW,CAAC;IAE1D,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACpD,0EAA0E;QAC1E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,+BAA+B,CAAC;YAC1D,SAAS;YACT,WAAW;SACZ,CAAC,CAAC;QAEH,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,wEAAwE;QACxE,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,4EAA4E;QAC5E,OAAO,OAAO,CAAC,SAAS,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,4EAA4E;QAC5E,oDAAoD;QACpD,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB,CAAC;IAED,8EAA8E;IAC9E,OAAO,gBAAgB,CAAC;AAC1B,CAAC","sourcesContent":["import type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n QuoteRequest,\n TransactionPayControllerMessenger,\n} from '../types.js';\nimport { getPostQuotePaymentOverrideData } from './post-quote-payment-override.js';\n\n/**\n * Resolve the quote recipient used by both Relay and Server.\n *\n * Non-atomic execution must be funded on its execution account. Ordinary\n * post-quote withdrawals pay the selected receiving account in `request.from`.\n * Deposits default to the original transaction's execution account.\n *\n * @param options - Recipient resolution options.\n * @param options.messenger - Controller messenger.\n * @param options.request - Quote request.\n * @param options.transaction - Original transaction metadata.\n * @returns The recipient to use for the quote body.\n */\nexport async function resolveQuoteRecipient({\n messenger,\n request,\n transaction,\n}: {\n messenger: TransactionPayControllerMessenger;\n request: QuoteRequest;\n transaction: TransactionMeta;\n}): Promise<Hex> {\n const executionAccount = transaction.txParams.from as Hex;\n\n if (request.atomic === false && request.isPostQuote) {\n // The client identifies the account executing target-side override calls.\n const { recipient } = await getPostQuotePaymentOverrideData({\n messenger,\n transaction,\n });\n\n return recipient;\n }\n\n if (request.atomic === false) {\n // Fund the original execution account before submitting its second leg.\n return executionAccount;\n }\n\n if (request.recipient) {\n // Preserve an explicit payout recipient once second-leg funding is handled.\n return request.recipient;\n }\n\n if (request.isPostQuote) {\n // Ordinary withdrawals pay the selected receiving account, which can differ\n // from the account executing the source withdrawal.\n return request.from;\n }\n\n // Deposits default to the execution account, which can differ from the payer.\n return executionAccount;\n}\n"]}
|