{"version":3,"file":"relay-submit.cjs","sourceRoot":"","sources":["../../../src/strategy/relay/relay-submit.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n  ORIGIN_METAMASK,\n  successfulFetch,\n  toHex,\n} from '@metamask/controller-utils';\nimport type { TransactionParams } from '@metamask/transaction-controller';\nimport type { TransactionMeta } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { createModuleLogger } from '@metamask/utils';\n\nimport { RELAY_URL_BASE } from './constants';\nimport type { RelayQuote, RelayStatus } from './types';\nimport { projectLogger } from '../../logger';\nimport type {\n  PayStrategyExecuteRequest,\n  TransactionPayControllerMessenger,\n} from '../../types';\nimport {\n  updateTransaction,\n  waitForTransactionConfirmed,\n} from '../../utils/transaction';\n\nconst log = createModuleLogger(projectLogger, 'relay-strategy');\n\n/**\n * Submits Relay quotes.\n *\n * @param request - Request object.\n * @returns An object containing the transaction hash if available.\n */\nexport async function submitRelayQuotes(\n  request: PayStrategyExecuteRequest<RelayQuote>,\n): Promise<{ transactionHash?: Hex }> {\n  log('Executing quotes', request);\n\n  const { quotes, messenger, transaction } = request;\n\n  let transactionHash: Hex | undefined;\n\n  for (const quote of quotes) {\n    ({ transactionHash } = await executeSingleQuote(\n      quote.original,\n      messenger,\n      transaction,\n    ));\n  }\n\n  const isSkipTransaction = quotes.some((q) => q.original.skipTransaction);\n\n  if (isSkipTransaction) {\n    log('Skipping original transaction', transactionHash);\n    return { transactionHash };\n  }\n\n  return { transactionHash: undefined };\n}\n\n/**\n * Executes a single Relay quote.\n *\n * @param quote - Relay quote to execute.\n * @param messenger - Controller messenger.\n * @param transaction - Original transaction meta.\n * @returns An object containing the transaction hash if available.\n */\nasync function executeSingleQuote(\n  quote: RelayQuote,\n  messenger: TransactionPayControllerMessenger,\n  transaction: TransactionMeta,\n) {\n  log('Executing single quote', quote);\n\n  const { kind } = quote.steps[0];\n\n  if (kind !== 'transaction') {\n    throw new Error(`Unsupported step kind: ${kind as string}`);\n  }\n\n  const transactionParams = quote.steps[0].items[0].data;\n  const chainId = toHex(transactionParams.chainId);\n  const normalizedParams = normalizeParams(transactionParams);\n\n  const networkClientId = messenger.call(\n    'NetworkController:findNetworkClientIdByChainId',\n    chainId,\n  );\n\n  log('Adding transaction', {\n    chainId,\n    normalizedParams,\n    networkClientId,\n  });\n\n  const result = await messenger.call(\n    'TransactionController:addTransaction',\n    normalizedParams,\n    {\n      networkClientId,\n      origin: ORIGIN_METAMASK,\n      requireApproval: false,\n    },\n  );\n\n  const { transactionMeta, result: transactionHashPromise } = result;\n\n  updateTransaction(\n    {\n      transactionId: transaction.id,\n      messenger,\n      note: 'Add required transaction ID',\n    },\n    (tx) => {\n      if (!tx.requiredTransactionIds) {\n        tx.requiredTransactionIds = [];\n      }\n\n      tx.requiredTransactionIds.push(transactionMeta.id);\n    },\n  );\n\n  log('Added transaction', transactionMeta);\n\n  const transactionHash = (await transactionHashPromise) as Hex;\n\n  log('Submitted transaction', transactionHash);\n\n  await waitForTransactionConfirmed(transactionMeta.id, messenger);\n\n  log('Transaction confirmed', transactionMeta.id);\n\n  await waitForRelayCompletion(quote);\n\n  log('Relay request completed');\n\n  if (quote.skipTransaction) {\n    log('Updating intent complete flag on transaction', transaction.id);\n\n    updateTransaction(\n      {\n        transactionId: transaction.id,\n        messenger,\n        note: 'Intent complete after Relay completion',\n      },\n      (tx) => {\n        tx.isIntentComplete = true;\n        tx.txParams.nonce = undefined;\n      },\n    );\n  }\n\n  return { transactionHash };\n}\n\n/**\n * Wait for a Relay request to complete.\n *\n * @param quote - Relay quote associated with the request.\n * @returns A promise that resolves when the Relay request is complete.\n */\nasync function waitForRelayCompletion(quote: RelayQuote) {\n  const { endpoint, method } = quote.steps[0].items[0].check;\n  const url = `${RELAY_URL_BASE}${endpoint}`;\n\n  while (true) {\n    const response = await successfulFetch(url, { method });\n    const status = (await response.json()) as RelayStatus;\n\n    log('Polled status', status.status, status);\n\n    if (status.status === 'success') {\n      return;\n    }\n\n    if (['failure', 'refund'].includes(status.status)) {\n      throw new Error(`Relay request failed with status: ${status.status}`);\n    }\n\n    await new Promise((resolve) => setTimeout(resolve, 1000));\n  }\n}\n\n/**\n * Normalize the parameters from a relay quote step to match TransactionParams.\n *\n * @param params - Parameters from a relay quote step.\n * @returns Normalized transaction parameters.\n */\nfunction normalizeParams(\n  params: RelayQuote['steps'][0]['items'][0]['data'],\n): TransactionParams {\n  return {\n    data: params.data,\n    from: params.from,\n    gas: toHex(params.gas),\n    maxFeePerGas: toHex(params.maxFeePerGas),\n    maxPriorityFeePerGas: toHex(params.maxPriorityFeePerGas),\n    to: params.to,\n    value: params.value,\n  };\n}\n"]}