@metamask/transaction-controller 56.1.0 → 56.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/dist/TransactionController.cjs +14 -0
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts +4 -2
  5. package/dist/TransactionController.d.cts.map +1 -1
  6. package/dist/TransactionController.d.mts +4 -2
  7. package/dist/TransactionController.d.mts.map +1 -1
  8. package/dist/TransactionController.mjs +15 -1
  9. package/dist/TransactionController.mjs.map +1 -1
  10. package/dist/helpers/PendingTransactionTracker.cjs +34 -3
  11. package/dist/helpers/PendingTransactionTracker.cjs.map +1 -1
  12. package/dist/helpers/PendingTransactionTracker.d.cts +12 -0
  13. package/dist/helpers/PendingTransactionTracker.d.cts.map +1 -1
  14. package/dist/helpers/PendingTransactionTracker.d.mts +12 -0
  15. package/dist/helpers/PendingTransactionTracker.d.mts.map +1 -1
  16. package/dist/helpers/PendingTransactionTracker.mjs +34 -3
  17. package/dist/helpers/PendingTransactionTracker.mjs.map +1 -1
  18. package/dist/hooks/SequentialPublishBatchHook.cjs +114 -0
  19. package/dist/hooks/SequentialPublishBatchHook.cjs.map +1 -0
  20. package/dist/hooks/SequentialPublishBatchHook.d.cts +24 -0
  21. package/dist/hooks/SequentialPublishBatchHook.d.cts.map +1 -0
  22. package/dist/hooks/SequentialPublishBatchHook.d.mts +24 -0
  23. package/dist/hooks/SequentialPublishBatchHook.d.mts.map +1 -0
  24. package/dist/hooks/SequentialPublishBatchHook.mjs +110 -0
  25. package/dist/hooks/SequentialPublishBatchHook.mjs.map +1 -0
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +1 -1
  28. package/dist/index.d.cts.map +1 -1
  29. package/dist/index.d.mts +1 -1
  30. package/dist/index.d.mts.map +1 -1
  31. package/dist/index.mjs.map +1 -1
  32. package/dist/types.cjs.map +1 -1
  33. package/dist/types.d.cts +28 -1
  34. package/dist/types.d.cts.map +1 -1
  35. package/dist/types.d.mts +28 -1
  36. package/dist/types.d.mts.map +1 -1
  37. package/dist/types.mjs.map +1 -1
  38. package/dist/utils/batch.cjs +100 -9
  39. package/dist/utils/batch.cjs.map +1 -1
  40. package/dist/utils/batch.d.cts +7 -0
  41. package/dist/utils/batch.d.cts.map +1 -1
  42. package/dist/utils/batch.d.mts +7 -0
  43. package/dist/utils/batch.d.mts.map +1 -1
  44. package/dist/utils/batch.mjs +100 -9
  45. package/dist/utils/batch.mjs.map +1 -1
  46. package/dist/utils/eip7702.cjs +3 -4
  47. package/dist/utils/eip7702.cjs.map +1 -1
  48. package/dist/utils/eip7702.mjs +3 -4
  49. package/dist/utils/eip7702.mjs.map +1 -1
  50. package/dist/utils/gas-fees.cjs +3 -7
  51. package/dist/utils/gas-fees.cjs.map +1 -1
  52. package/dist/utils/gas-fees.d.cts.map +1 -1
  53. package/dist/utils/gas-fees.d.mts.map +1 -1
  54. package/dist/utils/gas-fees.mjs +3 -7
  55. package/dist/utils/gas-fees.mjs.map +1 -1
  56. package/dist/utils/prepare.cjs +45 -1
  57. package/dist/utils/prepare.cjs.map +1 -1
  58. package/dist/utils/prepare.d.cts.map +1 -1
  59. package/dist/utils/prepare.d.mts.map +1 -1
  60. package/dist/utils/prepare.mjs +46 -1
  61. package/dist/utils/prepare.mjs.map +1 -1
  62. package/dist/utils/transaction-type.cjs +4 -1
  63. package/dist/utils/transaction-type.cjs.map +1 -1
  64. package/dist/utils/transaction-type.d.cts.map +1 -1
  65. package/dist/utils/transaction-type.d.mts.map +1 -1
  66. package/dist/utils/transaction-type.mjs +4 -1
  67. package/dist/utils/transaction-type.mjs.map +1 -1
  68. package/dist/utils/validation.cjs +2 -2
  69. package/dist/utils/validation.cjs.map +1 -1
  70. package/dist/utils/validation.mjs +2 -2
  71. package/dist/utils/validation.mjs.map +1 -1
  72. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"gas-fees.mjs","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n gweiDecToWEIBN,\n query,\n toHex,\n} from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\n\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n SavedGasFees,\n TransactionParams,\n TransactionMeta,\n TransactionType,\n GasFeeFlow,\n} from '../types';\nimport { GasFeeEstimateType, UserFeeLevel } from '../types';\n\nexport type UpdateGasFeesRequest = {\n eip1559: boolean;\n ethQuery: EthQuery;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\n messenger: TransactionControllerMessenger;\n txMeta: TransactionMeta;\n};\n\nexport type GetGasFeeRequest = UpdateGasFeesRequest & {\n initialParams: TransactionParams;\n savedGasFees?: SavedGasFees;\n suggestedGasFees: SuggestedGasFees;\n};\n\ntype SuggestedGasFees = {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n gasPrice?: string;\n};\n\nconst log = createModuleLogger(projectLogger, 'gas-fees');\n\n/**\n * Update the gas fee properties of the provided transaction meta.\n *\n * @param request - The request object.\n */\nexport async function updateGasFees(request: UpdateGasFeesRequest) {\n const { txMeta } = request;\n const initialParams = { ...txMeta.txParams };\n\n const isSwap = SWAP_TRANSACTION_TYPES.includes(\n txMeta.type as TransactionType,\n );\n const savedGasFees = isSwap\n ? undefined\n : request.getSavedGasFees(txMeta.chainId);\n\n const suggestedGasFees = await getSuggestedGasFees(request);\n\n log('Suggested gas fees', suggestedGasFees);\n\n const getGasFeeRequest: GetGasFeeRequest = {\n ...request,\n initialParams,\n savedGasFees,\n suggestedGasFees,\n };\n\n txMeta.txParams.maxFeePerGas = getMaxFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.maxPriorityFeePerGas =\n getMaxPriorityFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.gasPrice = getGasPrice(getGasFeeRequest);\n txMeta.userFeeLevel = getUserFeeLevel(getGasFeeRequest);\n\n log('Updated gas fee properties', {\n maxFeePerGas: txMeta.txParams.maxFeePerGas,\n maxPriorityFeePerGas: txMeta.txParams.maxPriorityFeePerGas,\n gasPrice: txMeta.txParams.gasPrice,\n });\n\n if (txMeta.txParams.maxFeePerGas || txMeta.txParams.maxPriorityFeePerGas) {\n delete txMeta.txParams.gasPrice;\n }\n\n if (txMeta.txParams.gasPrice) {\n delete txMeta.txParams.maxFeePerGas;\n delete txMeta.txParams.maxPriorityFeePerGas;\n }\n\n updateDefaultGasEstimates(txMeta);\n}\n\n/**\n * Convert GWEI from decimal string to WEI as hex string.\n *\n * @param value - The GWEI value as a decimal string.\n * @returns The WEI value in hex.\n */\nexport function gweiDecimalToWeiHex(value: string) {\n return toHex(gweiDecToWEIBN(value));\n}\n\n/**\n * Converts a value from Gwei decimal representation to Wei decimal representation\n *\n * @param gweiDecimal - The value in Gwei as a string or number\n * @returns The value in Wei as a string\n *\n * @example\n * // Convert 1.5 Gwei to Wei\n * gweiDecimalToWeiDecimal(\"1.5\")\n * // Returns \"1500000000\"\n */\nexport function gweiDecimalToWeiDecimal(gweiDecimal: string | number): string {\n const gwei =\n typeof gweiDecimal === 'string' ? gweiDecimal : String(gweiDecimal);\n\n const weiDecimal = Number(gwei) * 1e9;\n\n return weiDecimal.toString();\n}\n\n/**\n * Determine the maxFeePerGas value for the transaction.\n *\n * @param request - The request object.\n * @returns The maxFeePerGas value.\n */\nfunction getMaxFeePerGas(request: GetGasFeeRequest): string | undefined {\n const { savedGasFees, eip1559, initialParams, suggestedGasFees } = request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxFeePerGas = gweiDecimalToWeiHex(savedGasFees.maxBaseFee as string);\n log('Using maxFeePerGas from savedGasFees', maxFeePerGas);\n return maxFeePerGas;\n }\n\n if (initialParams.maxFeePerGas) {\n log('Using maxFeePerGas from request', initialParams.maxFeePerGas);\n return initialParams.maxFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxPriorityFeePerGas) {\n log(\n 'Setting maxFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log(\n 'Setting maxFeePerGas to suggested gasPrice',\n suggestedGasFees.gasPrice,\n );\n return suggestedGasFees.gasPrice;\n }\n\n log('maxFeePerGas not set');\n return undefined;\n}\n\n/**\n * Determine the maxPriorityFeePerGas value for the transaction.\n *\n * @param request - The request object.\n * @returns The maxPriorityFeePerGas value.\n */\nfunction getMaxPriorityFeePerGas(\n request: GetGasFeeRequest,\n): string | undefined {\n const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } =\n request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxPriorityFeePerGas = gweiDecimalToWeiHex(savedGasFees.priorityFee);\n log(\n 'Using maxPriorityFeePerGas from savedGasFees.priorityFee',\n maxPriorityFeePerGas,\n );\n return maxPriorityFeePerGas;\n }\n\n if (initialParams.maxPriorityFeePerGas) {\n log(\n 'Using maxPriorityFeePerGas from request',\n initialParams.maxPriorityFeePerGas,\n );\n return initialParams.maxPriorityFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxPriorityFeePerGas) {\n log(\n 'Using suggested maxPriorityFeePerGas',\n suggestedGasFees.maxPriorityFeePerGas,\n );\n return suggestedGasFees.maxPriorityFeePerGas;\n }\n\n if (txMeta.txParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to maxFeePerGas',\n txMeta.txParams.maxFeePerGas,\n );\n return txMeta.txParams.maxFeePerGas;\n }\n\n log('maxPriorityFeePerGas not set');\n return undefined;\n}\n\n/**\n * Determine the gasPrice value for the transaction.\n *\n * @param request - The request object.\n * @returns The gasPrice value.\n */\nfunction getGasPrice(request: GetGasFeeRequest): string | undefined {\n const { eip1559, initialParams, suggestedGasFees } = request;\n\n if (eip1559) {\n return undefined;\n }\n\n if (initialParams.gasPrice) {\n log('Using gasPrice from request', initialParams.gasPrice);\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log('Using suggested gasPrice', suggestedGasFees.gasPrice);\n return suggestedGasFees.gasPrice;\n }\n\n log('gasPrice not set');\n return undefined;\n}\n\n/**\n * Determine the user fee level.\n *\n * @param request - The request object.\n * @returns The user fee level.\n */\nfunction getUserFeeLevel(request: GetGasFeeRequest): UserFeeLevel | undefined {\n const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } =\n request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n return UserFeeLevel.CUSTOM;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n initialParams.gasPrice\n ) {\n return txMeta.origin === ORIGIN_METAMASK\n ? UserFeeLevel.CUSTOM\n : UserFeeLevel.DAPP_SUGGESTED;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n suggestedGasFees.maxFeePerGas &&\n suggestedGasFees.maxPriorityFeePerGas\n ) {\n return UserFeeLevel.MEDIUM;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n suggestedGasFees.gasPrice\n ) {\n return UserFeeLevel.MEDIUM;\n }\n\n if (txMeta.origin === ORIGIN_METAMASK) {\n return UserFeeLevel.MEDIUM;\n }\n\n return UserFeeLevel.DAPP_SUGGESTED;\n}\n\n/**\n * Update the default gas estimates for the provided transaction.\n *\n * @param txMeta - The transaction metadata.\n */\nfunction updateDefaultGasEstimates(txMeta: TransactionMeta) {\n if (!txMeta.defaultGasEstimates) {\n txMeta.defaultGasEstimates = {};\n }\n\n txMeta.defaultGasEstimates.maxFeePerGas = txMeta.txParams.maxFeePerGas;\n\n txMeta.defaultGasEstimates.maxPriorityFeePerGas =\n txMeta.txParams.maxPriorityFeePerGas;\n\n txMeta.defaultGasEstimates.gasPrice = txMeta.txParams.gasPrice;\n txMeta.defaultGasEstimates.estimateType = txMeta.userFeeLevel;\n}\n\n/**\n * Retrieve the suggested gas fees using the gas fee flows.\n *\n * @param request - The request object.\n * @returns The suggested gas fees.\n */\nasync function getSuggestedGasFees(\n request: UpdateGasFeesRequest,\n): Promise<SuggestedGasFees> {\n const {\n eip1559,\n ethQuery,\n gasFeeFlows,\n getGasFeeEstimates,\n messenger,\n txMeta,\n } = request;\n\n const { networkClientId } = txMeta;\n\n if (\n (!eip1559 && txMeta.txParams.gasPrice) ||\n (eip1559 &&\n txMeta.txParams.maxFeePerGas &&\n txMeta.txParams.maxPriorityFeePerGas)\n ) {\n return {};\n }\n\n const gasFeeFlow = getGasFeeFlow(\n txMeta,\n gasFeeFlows,\n messenger,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n gasFeeControllerData,\n messenger,\n transactionMeta: txMeta,\n });\n\n const gasFeeEstimateType = response.estimates?.type;\n\n switch (gasFeeEstimateType) {\n case GasFeeEstimateType.FeeMarket:\n return response.estimates.medium;\n case GasFeeEstimateType.Legacy:\n return {\n gasPrice: response.estimates.medium,\n };\n case GasFeeEstimateType.GasPrice:\n return { gasPrice: response.estimates.gasPrice };\n default:\n throw new Error(\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Unsupported gas fee estimate type returned from flow: ${gasFeeEstimateType}`,\n );\n }\n } catch (error) {\n log('Failed to get suggested gas fees', error);\n }\n\n const gasPriceDecimal = (await query(ethQuery, 'gasPrice')) as number;\n\n const gasPrice = gasPriceDecimal\n ? add0x(gasPriceDecimal.toString(16))\n : undefined;\n\n return { gasPrice };\n}\n"]}
1
+ {"version":3,"file":"gas-fees.mjs","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ORIGIN_METAMASK,\n gweiDecToWEIBN,\n query,\n toHex,\n} from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport type {\n FetchGasFeeEstimateOptions,\n GasFeeState,\n} from '@metamask/gas-fee-controller';\nimport type { Hex } from '@metamask/utils';\nimport { add0x, createModuleLogger } from '@metamask/utils';\n\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\nimport type { TransactionControllerMessenger } from '../TransactionController';\nimport type {\n SavedGasFees,\n TransactionParams,\n TransactionMeta,\n TransactionType,\n GasFeeFlow,\n} from '../types';\nimport { GasFeeEstimateType, UserFeeLevel } from '../types';\n\nexport type UpdateGasFeesRequest = {\n eip1559: boolean;\n ethQuery: EthQuery;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\n messenger: TransactionControllerMessenger;\n txMeta: TransactionMeta;\n};\n\nexport type GetGasFeeRequest = UpdateGasFeesRequest & {\n initialParams: TransactionParams;\n savedGasFees?: SavedGasFees;\n suggestedGasFees: SuggestedGasFees;\n};\n\ntype SuggestedGasFees = {\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n gasPrice?: string;\n};\n\nconst log = createModuleLogger(projectLogger, 'gas-fees');\n\n/**\n * Update the gas fee properties of the provided transaction meta.\n *\n * @param request - The request object.\n */\nexport async function updateGasFees(request: UpdateGasFeesRequest) {\n const { txMeta } = request;\n const initialParams = { ...txMeta.txParams };\n\n const isSwap = SWAP_TRANSACTION_TYPES.includes(\n txMeta.type as TransactionType,\n );\n const savedGasFees = isSwap\n ? undefined\n : request.getSavedGasFees(txMeta.chainId);\n\n const suggestedGasFees = await getSuggestedGasFees(request);\n\n log('Suggested gas fees', suggestedGasFees);\n\n const getGasFeeRequest: GetGasFeeRequest = {\n ...request,\n initialParams,\n savedGasFees,\n suggestedGasFees,\n };\n\n txMeta.txParams.maxFeePerGas = getMaxFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.maxPriorityFeePerGas =\n getMaxPriorityFeePerGas(getGasFeeRequest);\n\n txMeta.txParams.gasPrice = getGasPrice(getGasFeeRequest);\n txMeta.userFeeLevel = getUserFeeLevel(getGasFeeRequest);\n\n log('Updated gas fee properties', {\n maxFeePerGas: txMeta.txParams.maxFeePerGas,\n maxPriorityFeePerGas: txMeta.txParams.maxPriorityFeePerGas,\n gasPrice: txMeta.txParams.gasPrice,\n });\n\n if (txMeta.txParams.maxFeePerGas || txMeta.txParams.maxPriorityFeePerGas) {\n delete txMeta.txParams.gasPrice;\n }\n\n if (txMeta.txParams.gasPrice) {\n delete txMeta.txParams.maxFeePerGas;\n delete txMeta.txParams.maxPriorityFeePerGas;\n }\n\n updateDefaultGasEstimates(txMeta);\n}\n\n/**\n * Convert GWEI from decimal string to WEI as hex string.\n *\n * @param value - The GWEI value as a decimal string.\n * @returns The WEI value in hex.\n */\nexport function gweiDecimalToWeiHex(value: string) {\n return toHex(gweiDecToWEIBN(value));\n}\n\n/**\n * Converts a value from Gwei decimal representation to Wei decimal representation\n *\n * @param gweiDecimal - The value in Gwei as a string or number\n * @returns The value in Wei as a string\n *\n * @example\n * // Convert 1.5 Gwei to Wei\n * gweiDecimalToWeiDecimal(\"1.5\")\n * // Returns \"1500000000\"\n */\nexport function gweiDecimalToWeiDecimal(gweiDecimal: string | number): string {\n const weiValue = Number(gweiDecimal) * 1e9;\n\n return weiValue.toString().split('.')[0];\n}\n\n/**\n * Determine the maxFeePerGas value for the transaction.\n *\n * @param request - The request object.\n * @returns The maxFeePerGas value.\n */\nfunction getMaxFeePerGas(request: GetGasFeeRequest): string | undefined {\n const { savedGasFees, eip1559, initialParams, suggestedGasFees } = request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxFeePerGas = gweiDecimalToWeiHex(savedGasFees.maxBaseFee as string);\n log('Using maxFeePerGas from savedGasFees', maxFeePerGas);\n return maxFeePerGas;\n }\n\n if (initialParams.maxFeePerGas) {\n log('Using maxFeePerGas from request', initialParams.maxFeePerGas);\n return initialParams.maxFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxPriorityFeePerGas) {\n log(\n 'Setting maxFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log(\n 'Setting maxFeePerGas to suggested gasPrice',\n suggestedGasFees.gasPrice,\n );\n return suggestedGasFees.gasPrice;\n }\n\n log('maxFeePerGas not set');\n return undefined;\n}\n\n/**\n * Determine the maxPriorityFeePerGas value for the transaction.\n *\n * @param request - The request object.\n * @returns The maxPriorityFeePerGas value.\n */\nfunction getMaxPriorityFeePerGas(\n request: GetGasFeeRequest,\n): string | undefined {\n const { eip1559, initialParams, savedGasFees, suggestedGasFees, txMeta } =\n request;\n\n if (!eip1559) {\n return undefined;\n }\n\n if (savedGasFees) {\n const maxPriorityFeePerGas = gweiDecimalToWeiHex(savedGasFees.priorityFee);\n log(\n 'Using maxPriorityFeePerGas from savedGasFees.priorityFee',\n maxPriorityFeePerGas,\n );\n return maxPriorityFeePerGas;\n }\n\n if (initialParams.maxPriorityFeePerGas) {\n log(\n 'Using maxPriorityFeePerGas from request',\n initialParams.maxPriorityFeePerGas,\n );\n return initialParams.maxPriorityFeePerGas;\n }\n\n if (initialParams.gasPrice && !initialParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to gasPrice from request',\n initialParams.gasPrice,\n );\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxPriorityFeePerGas) {\n log(\n 'Using suggested maxPriorityFeePerGas',\n suggestedGasFees.maxPriorityFeePerGas,\n );\n return suggestedGasFees.maxPriorityFeePerGas;\n }\n\n if (txMeta.txParams.maxFeePerGas) {\n log(\n 'Setting maxPriorityFeePerGas to maxFeePerGas',\n txMeta.txParams.maxFeePerGas,\n );\n return txMeta.txParams.maxFeePerGas;\n }\n\n log('maxPriorityFeePerGas not set');\n return undefined;\n}\n\n/**\n * Determine the gasPrice value for the transaction.\n *\n * @param request - The request object.\n * @returns The gasPrice value.\n */\nfunction getGasPrice(request: GetGasFeeRequest): string | undefined {\n const { eip1559, initialParams, suggestedGasFees } = request;\n\n if (eip1559) {\n return undefined;\n }\n\n if (initialParams.gasPrice) {\n log('Using gasPrice from request', initialParams.gasPrice);\n return initialParams.gasPrice;\n }\n\n if (suggestedGasFees.maxFeePerGas) {\n log('Using suggested maxFeePerGas', suggestedGasFees.maxFeePerGas);\n return suggestedGasFees.maxFeePerGas;\n }\n\n if (suggestedGasFees.gasPrice) {\n log('Using suggested gasPrice', suggestedGasFees.gasPrice);\n return suggestedGasFees.gasPrice;\n }\n\n log('gasPrice not set');\n return undefined;\n}\n\n/**\n * Determine the user fee level.\n *\n * @param request - The request object.\n * @returns The user fee level.\n */\nfunction getUserFeeLevel(request: GetGasFeeRequest): UserFeeLevel | undefined {\n const { initialParams, savedGasFees, suggestedGasFees, txMeta } = request;\n\n if (savedGasFees) {\n return UserFeeLevel.CUSTOM;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n initialParams.gasPrice\n ) {\n return txMeta.origin === ORIGIN_METAMASK\n ? UserFeeLevel.CUSTOM\n : UserFeeLevel.DAPP_SUGGESTED;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n suggestedGasFees.maxFeePerGas &&\n suggestedGasFees.maxPriorityFeePerGas\n ) {\n return UserFeeLevel.MEDIUM;\n }\n\n if (\n !initialParams.maxFeePerGas &&\n !initialParams.maxPriorityFeePerGas &&\n suggestedGasFees.gasPrice\n ) {\n return UserFeeLevel.MEDIUM;\n }\n\n if (txMeta.origin === ORIGIN_METAMASK) {\n return UserFeeLevel.MEDIUM;\n }\n\n return UserFeeLevel.DAPP_SUGGESTED;\n}\n\n/**\n * Update the default gas estimates for the provided transaction.\n *\n * @param txMeta - The transaction metadata.\n */\nfunction updateDefaultGasEstimates(txMeta: TransactionMeta) {\n if (!txMeta.defaultGasEstimates) {\n txMeta.defaultGasEstimates = {};\n }\n\n txMeta.defaultGasEstimates.maxFeePerGas = txMeta.txParams.maxFeePerGas;\n\n txMeta.defaultGasEstimates.maxPriorityFeePerGas =\n txMeta.txParams.maxPriorityFeePerGas;\n\n txMeta.defaultGasEstimates.gasPrice = txMeta.txParams.gasPrice;\n txMeta.defaultGasEstimates.estimateType = txMeta.userFeeLevel;\n}\n\n/**\n * Retrieve the suggested gas fees using the gas fee flows.\n *\n * @param request - The request object.\n * @returns The suggested gas fees.\n */\nasync function getSuggestedGasFees(\n request: UpdateGasFeesRequest,\n): Promise<SuggestedGasFees> {\n const {\n eip1559,\n ethQuery,\n gasFeeFlows,\n getGasFeeEstimates,\n messenger,\n txMeta,\n } = request;\n\n const { networkClientId } = txMeta;\n\n if (\n (!eip1559 && txMeta.txParams.gasPrice) ||\n (eip1559 &&\n txMeta.txParams.maxFeePerGas &&\n txMeta.txParams.maxPriorityFeePerGas)\n ) {\n return {};\n }\n\n const gasFeeFlow = getGasFeeFlow(\n txMeta,\n gasFeeFlows,\n messenger,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n gasFeeControllerData,\n messenger,\n transactionMeta: txMeta,\n });\n\n const gasFeeEstimateType = response.estimates?.type;\n\n switch (gasFeeEstimateType) {\n case GasFeeEstimateType.FeeMarket:\n return response.estimates.medium;\n case GasFeeEstimateType.Legacy:\n return {\n gasPrice: response.estimates.medium,\n };\n case GasFeeEstimateType.GasPrice:\n return { gasPrice: response.estimates.gasPrice };\n default:\n throw new Error(\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Unsupported gas fee estimate type returned from flow: ${gasFeeEstimateType}`,\n );\n }\n } catch (error) {\n log('Failed to get suggested gas fees', error);\n }\n\n const gasPriceDecimal = (await query(ethQuery, 'gasPrice')) as number;\n\n const gasPrice = gasPriceDecimal\n ? add0x(gasPriceDecimal.toString(16))\n : undefined;\n\n return { gasPrice };\n}\n"]}
@@ -4,6 +4,7 @@ exports.serializeTransaction = exports.prepareTransaction = exports.HARDFORK = v
4
4
  const common_1 = require("@ethereumjs/common");
5
5
  const tx_1 = require("@ethereumjs/tx");
6
6
  const utils_1 = require("@metamask/utils");
7
+ const lodash_1 = require("lodash");
7
8
  exports.HARDFORK = common_1.Hardfork.Prague;
8
9
  /**
9
10
  * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.
@@ -13,8 +14,9 @@ exports.HARDFORK = common_1.Hardfork.Prague;
13
14
  * @returns The transaction object.
14
15
  */
15
16
  function prepareTransaction(chainId, txParams) {
17
+ const normalizedData = normalizeParams(txParams);
16
18
  // Does not allow `gasPrice` on type 4 transactions.
17
- const data = txParams;
19
+ const data = normalizedData;
18
20
  return tx_1.TransactionFactory.fromTxData(data, {
19
21
  freeze: false,
20
22
  common: getCommonConfiguration(chainId),
@@ -46,4 +48,46 @@ function getCommonConfiguration(chainId) {
46
48
  eips: [7702],
47
49
  });
48
50
  }
51
+ /**
52
+ * Normalize the transaction parameters for compatibility with `ethereumjs/tx`.
53
+ *
54
+ * @param params - The transaction parameters to normalize.
55
+ * @returns The normalized transaction parameters.
56
+ */
57
+ function normalizeParams(params) {
58
+ const newParams = (0, lodash_1.cloneDeep)(params);
59
+ normalizeAuthorizationList(newParams.authorizationList);
60
+ return newParams;
61
+ }
62
+ /**
63
+ * Normalize the authorization list for `ethereumjs/tx` compatibility.
64
+ *
65
+ * @param authorizationList - The list of authorizations to normalize.
66
+ */
67
+ function normalizeAuthorizationList(authorizationList) {
68
+ if (!authorizationList) {
69
+ return;
70
+ }
71
+ for (const authorization of authorizationList) {
72
+ authorization.nonce = removeLeadingZeroes(authorization.nonce);
73
+ authorization.r = removeLeadingZeroes(authorization.r);
74
+ authorization.s = removeLeadingZeroes(authorization.s);
75
+ authorization.yParity = removeLeadingZeroes(authorization.yParity);
76
+ }
77
+ }
78
+ /**
79
+ * Remove leading zeroes from a hexadecimal string.
80
+ *
81
+ * @param value - The hexadecimal string to process.
82
+ * @returns The processed hexadecimal string.
83
+ */
84
+ function removeLeadingZeroes(value) {
85
+ if (!value) {
86
+ return value;
87
+ }
88
+ if (value === '0x0') {
89
+ return '0x';
90
+ }
91
+ return value.replace?.(/^0x(00)+/u, '0x') ?? value;
92
+ }
49
93
  //# sourceMappingURL=prepare.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.cjs","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":";;;AACA,+CAAsD;AAEtD,uCAAoD;AACpD,2CAA6C;AAKhC,QAAA,QAAQ,GAAG,iBAAQ,CAAC,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,OAAY,EACZ,QAA2B;IAE3B,oDAAoD;IACpD,MAAM,IAAI,GAAG,QAAuB,CAAC;IAErC,OAAO,uBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAXD,gDAWC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,WAA6B;IAChE,OAAO,IAAA,kBAAU,EAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7C,CAAC;AAFD,oDAEC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,OAAY;IAC1C,MAAM,iBAAiB,GAAyB;QAC9C,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,eAAe,EAAE,gBAAQ;KAC1B,CAAC;IAEF,OAAO,eAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;QACtC,IAAI,EAAE,CAAC,IAAI,CAAC;KACb,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ChainConfig } from '@ethereumjs/common';\nimport { Common, Hardfork } from '@ethereumjs/common';\nimport type { TypedTransaction, TypedTxData } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport { bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport type { TransactionParams } from '../types';\n\nexport const HARDFORK = Hardfork.Prague;\n\n/**\n * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.\n *\n * @param chainId - Chain ID of the transaction.\n * @param txParams - Transaction parameters.\n * @returns The transaction object.\n */\nexport function prepareTransaction(\n chainId: Hex,\n txParams: TransactionParams,\n): TypedTransaction {\n // Does not allow `gasPrice` on type 4 transactions.\n const data = txParams as TypedTxData;\n\n return TransactionFactory.fromTxData(data, {\n freeze: false,\n common: getCommonConfiguration(chainId),\n });\n}\n\n/**\n * Serializes a transaction object into a hex string.\n *\n * @param transaction - The transaction object.\n * @returns The prefixed hex string.\n */\nexport function serializeTransaction(transaction: TypedTransaction) {\n return bytesToHex(transaction.serialize());\n}\n\n/**\n * Generates the configuration used to prepare transactions.\n *\n * @param chainId - Chain ID.\n * @returns The common configuration.\n */\nfunction getCommonConfiguration(chainId: Hex): Common {\n const customChainParams: Partial<ChainConfig> = {\n chainId: parseInt(chainId, 16),\n defaultHardfork: HARDFORK,\n };\n\n return Common.custom(customChainParams, {\n eips: [7702],\n });\n}\n"]}
1
+ {"version":3,"file":"prepare.cjs","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":";;;AACA,+CAAsD;AAEtD,uCAAoD;AACpD,2CAA6C;AAE7C,mCAAmC;AAItB,QAAA,QAAQ,GAAG,iBAAQ,CAAC,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAChC,OAAY,EACZ,QAA2B;IAE3B,MAAM,cAAc,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEjD,oDAAoD;IACpD,MAAM,IAAI,GAAG,cAA6B,CAAC;IAE3C,OAAO,uBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAbD,gDAaC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,WAA6B;IAChE,OAAO,IAAA,kBAAU,EAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7C,CAAC;AAFD,oDAEC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,OAAY;IAC1C,MAAM,iBAAiB,GAAyB;QAC9C,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,eAAe,EAAE,gBAAQ;KAC1B,CAAC;IAEF,OAAO,eAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;QACtC,IAAI,EAAE,CAAC,IAAI,CAAC;KACb,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,MAAyB;IAChD,MAAM,SAAS,GAAG,IAAA,kBAAS,EAAC,MAAM,CAAC,CAAC;IACpC,0BAA0B,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,0BAA0B,CAAC,iBAAqC;IACvE,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO;KACR;IAED,KAAK,MAAM,aAAa,IAAI,iBAAiB,EAAE;QAC7C,aAAa,CAAC,KAAK,GAAG,mBAAmB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC/D,aAAa,CAAC,CAAC,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACvD,aAAa,CAAC,CAAC,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACvD,aAAa,CAAC,OAAO,GAAG,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;KACpE;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,KAAsB;IACjD,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,KAAK,CAAC;KACd;IAED,IAAI,KAAK,KAAK,KAAK,EAAE;QACnB,OAAO,IAAI,CAAC;KACb;IAED,OAAQ,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,IAAI,CAAS,IAAI,KAAK,CAAC;AAC9D,CAAC","sourcesContent":["import type { ChainConfig } from '@ethereumjs/common';\nimport { Common, Hardfork } from '@ethereumjs/common';\nimport type { TypedTransaction, TypedTxData } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport { bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport type { AuthorizationList, TransactionParams } from '../types';\n\nexport const HARDFORK = Hardfork.Prague;\n\n/**\n * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.\n *\n * @param chainId - Chain ID of the transaction.\n * @param txParams - Transaction parameters.\n * @returns The transaction object.\n */\nexport function prepareTransaction(\n chainId: Hex,\n txParams: TransactionParams,\n): TypedTransaction {\n const normalizedData = normalizeParams(txParams);\n\n // Does not allow `gasPrice` on type 4 transactions.\n const data = normalizedData as TypedTxData;\n\n return TransactionFactory.fromTxData(data, {\n freeze: false,\n common: getCommonConfiguration(chainId),\n });\n}\n\n/**\n * Serializes a transaction object into a hex string.\n *\n * @param transaction - The transaction object.\n * @returns The prefixed hex string.\n */\nexport function serializeTransaction(transaction: TypedTransaction) {\n return bytesToHex(transaction.serialize());\n}\n\n/**\n * Generates the configuration used to prepare transactions.\n *\n * @param chainId - Chain ID.\n * @returns The common configuration.\n */\nfunction getCommonConfiguration(chainId: Hex): Common {\n const customChainParams: Partial<ChainConfig> = {\n chainId: parseInt(chainId, 16),\n defaultHardfork: HARDFORK,\n };\n\n return Common.custom(customChainParams, {\n eips: [7702],\n });\n}\n\n/**\n * Normalize the transaction parameters for compatibility with `ethereumjs/tx`.\n *\n * @param params - The transaction parameters to normalize.\n * @returns The normalized transaction parameters.\n */\nfunction normalizeParams(params: TransactionParams): TransactionParams {\n const newParams = cloneDeep(params);\n normalizeAuthorizationList(newParams.authorizationList);\n return newParams;\n}\n\n/**\n * Normalize the authorization list for `ethereumjs/tx` compatibility.\n *\n * @param authorizationList - The list of authorizations to normalize.\n */\nfunction normalizeAuthorizationList(authorizationList?: AuthorizationList) {\n if (!authorizationList) {\n return;\n }\n\n for (const authorization of authorizationList) {\n authorization.nonce = removeLeadingZeroes(authorization.nonce);\n authorization.r = removeLeadingZeroes(authorization.r);\n authorization.s = removeLeadingZeroes(authorization.s);\n authorization.yParity = removeLeadingZeroes(authorization.yParity);\n }\n}\n\n/**\n * Remove leading zeroes from a hexadecimal string.\n *\n * @param value - The hexadecimal string to process.\n * @returns The processed hexadecimal string.\n */\nfunction removeLeadingZeroes(value: Hex | undefined): Hex | undefined {\n if (!value) {\n return value;\n }\n\n if (value === '0x0') {\n return '0x';\n }\n\n return (value.replace?.(/^0x(00)+/u, '0x') as Hex) ?? value;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.d.cts","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,2BAA2B;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAe,uBAAuB;AAGpE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAElD,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,gBAAgB,iBAEjE"}
1
+ {"version":3,"file":"prepare.d.cts","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,2BAA2B;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAe,uBAAuB;AAGpE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAqB,iBAAiB,EAAE,qBAAiB;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CAUlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,gBAAgB,iBAEjE"}
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.d.mts","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,2BAA2B;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAe,uBAAuB;AAGpE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAiB;AAElD,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,gBAAgB,iBAEjE"}
1
+ {"version":3,"file":"prepare.d.mts","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,QAAQ,EAAE,2BAA2B;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAe,uBAAuB;AAGpE,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAqB,iBAAiB,EAAE,qBAAiB;AAErE,eAAO,MAAM,QAAQ,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,QAAQ,EAAE,iBAAiB,GAC1B,gBAAgB,CAUlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,gBAAgB,iBAEjE"}
@@ -1,6 +1,8 @@
1
1
  import { Common, Hardfork } from "@ethereumjs/common";
2
2
  import { TransactionFactory } from "@ethereumjs/tx";
3
3
  import { bytesToHex } from "@metamask/utils";
4
+ import $lodash from "lodash";
5
+ const { cloneDeep } = $lodash;
4
6
  export const HARDFORK = Hardfork.Prague;
5
7
  /**
6
8
  * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.
@@ -10,8 +12,9 @@ export const HARDFORK = Hardfork.Prague;
10
12
  * @returns The transaction object.
11
13
  */
12
14
  export function prepareTransaction(chainId, txParams) {
15
+ const normalizedData = normalizeParams(txParams);
13
16
  // Does not allow `gasPrice` on type 4 transactions.
14
- const data = txParams;
17
+ const data = normalizedData;
15
18
  return TransactionFactory.fromTxData(data, {
16
19
  freeze: false,
17
20
  common: getCommonConfiguration(chainId),
@@ -41,4 +44,46 @@ function getCommonConfiguration(chainId) {
41
44
  eips: [7702],
42
45
  });
43
46
  }
47
+ /**
48
+ * Normalize the transaction parameters for compatibility with `ethereumjs/tx`.
49
+ *
50
+ * @param params - The transaction parameters to normalize.
51
+ * @returns The normalized transaction parameters.
52
+ */
53
+ function normalizeParams(params) {
54
+ const newParams = cloneDeep(params);
55
+ normalizeAuthorizationList(newParams.authorizationList);
56
+ return newParams;
57
+ }
58
+ /**
59
+ * Normalize the authorization list for `ethereumjs/tx` compatibility.
60
+ *
61
+ * @param authorizationList - The list of authorizations to normalize.
62
+ */
63
+ function normalizeAuthorizationList(authorizationList) {
64
+ if (!authorizationList) {
65
+ return;
66
+ }
67
+ for (const authorization of authorizationList) {
68
+ authorization.nonce = removeLeadingZeroes(authorization.nonce);
69
+ authorization.r = removeLeadingZeroes(authorization.r);
70
+ authorization.s = removeLeadingZeroes(authorization.s);
71
+ authorization.yParity = removeLeadingZeroes(authorization.yParity);
72
+ }
73
+ }
74
+ /**
75
+ * Remove leading zeroes from a hexadecimal string.
76
+ *
77
+ * @param value - The hexadecimal string to process.
78
+ * @returns The processed hexadecimal string.
79
+ */
80
+ function removeLeadingZeroes(value) {
81
+ if (!value) {
82
+ return value;
83
+ }
84
+ if (value === '0x0') {
85
+ return '0x';
86
+ }
87
+ return value.replace?.(/^0x(00)+/u, '0x') ?? value;
88
+ }
44
89
  //# sourceMappingURL=prepare.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.mjs","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,2BAA2B;AAEtD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB;AACpD,OAAO,EAAE,UAAU,EAAE,wBAAwB;AAK7C,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAY,EACZ,QAA2B;IAE3B,oDAAoD;IACpD,MAAM,IAAI,GAAG,QAAuB,CAAC;IAErC,OAAO,kBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAA6B;IAChE,OAAO,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,OAAY;IAC1C,MAAM,iBAAiB,GAAyB;QAC9C,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,eAAe,EAAE,QAAQ;KAC1B,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;QACtC,IAAI,EAAE,CAAC,IAAI,CAAC;KACb,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ChainConfig } from '@ethereumjs/common';\nimport { Common, Hardfork } from '@ethereumjs/common';\nimport type { TypedTransaction, TypedTxData } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport { bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport type { TransactionParams } from '../types';\n\nexport const HARDFORK = Hardfork.Prague;\n\n/**\n * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.\n *\n * @param chainId - Chain ID of the transaction.\n * @param txParams - Transaction parameters.\n * @returns The transaction object.\n */\nexport function prepareTransaction(\n chainId: Hex,\n txParams: TransactionParams,\n): TypedTransaction {\n // Does not allow `gasPrice` on type 4 transactions.\n const data = txParams as TypedTxData;\n\n return TransactionFactory.fromTxData(data, {\n freeze: false,\n common: getCommonConfiguration(chainId),\n });\n}\n\n/**\n * Serializes a transaction object into a hex string.\n *\n * @param transaction - The transaction object.\n * @returns The prefixed hex string.\n */\nexport function serializeTransaction(transaction: TypedTransaction) {\n return bytesToHex(transaction.serialize());\n}\n\n/**\n * Generates the configuration used to prepare transactions.\n *\n * @param chainId - Chain ID.\n * @returns The common configuration.\n */\nfunction getCommonConfiguration(chainId: Hex): Common {\n const customChainParams: Partial<ChainConfig> = {\n chainId: parseInt(chainId, 16),\n defaultHardfork: HARDFORK,\n };\n\n return Common.custom(customChainParams, {\n eips: [7702],\n });\n}\n"]}
1
+ {"version":3,"file":"prepare.mjs","sourceRoot":"","sources":["../../src/utils/prepare.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,2BAA2B;AAEtD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB;AACpD,OAAO,EAAE,UAAU,EAAE,wBAAwB;;;AAM7C,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAY,EACZ,QAA2B;IAE3B,MAAM,cAAc,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAEjD,oDAAoD;IACpD,MAAM,IAAI,GAAG,cAA6B,CAAC;IAE3C,OAAO,kBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE;QACzC,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,sBAAsB,CAAC,OAAO,CAAC;KACxC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAA6B;IAChE,OAAO,UAAU,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,OAAY;IAC1C,MAAM,iBAAiB,GAAyB;QAC9C,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,eAAe,EAAE,QAAQ;KAC1B,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE;QACtC,IAAI,EAAE,CAAC,IAAI,CAAC;KACb,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,MAAyB;IAChD,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,0BAA0B,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,SAAS,0BAA0B,CAAC,iBAAqC;IACvE,IAAI,CAAC,iBAAiB,EAAE;QACtB,OAAO;KACR;IAED,KAAK,MAAM,aAAa,IAAI,iBAAiB,EAAE;QAC7C,aAAa,CAAC,KAAK,GAAG,mBAAmB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC/D,aAAa,CAAC,CAAC,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACvD,aAAa,CAAC,CAAC,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACvD,aAAa,CAAC,OAAO,GAAG,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;KACpE;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,KAAsB;IACjD,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,KAAK,CAAC;KACd;IAED,IAAI,KAAK,KAAK,KAAK,EAAE;QACnB,OAAO,IAAI,CAAC;KACb;IAED,OAAQ,KAAK,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,IAAI,CAAS,IAAI,KAAK,CAAC;AAC9D,CAAC","sourcesContent":["import type { ChainConfig } from '@ethereumjs/common';\nimport { Common, Hardfork } from '@ethereumjs/common';\nimport type { TypedTransaction, TypedTxData } from '@ethereumjs/tx';\nimport { TransactionFactory } from '@ethereumjs/tx';\nimport { bytesToHex } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\nimport { cloneDeep } from 'lodash';\n\nimport type { AuthorizationList, TransactionParams } from '../types';\n\nexport const HARDFORK = Hardfork.Prague;\n\n/**\n * Creates an `etheruemjs/tx` transaction object from the raw transaction parameters.\n *\n * @param chainId - Chain ID of the transaction.\n * @param txParams - Transaction parameters.\n * @returns The transaction object.\n */\nexport function prepareTransaction(\n chainId: Hex,\n txParams: TransactionParams,\n): TypedTransaction {\n const normalizedData = normalizeParams(txParams);\n\n // Does not allow `gasPrice` on type 4 transactions.\n const data = normalizedData as TypedTxData;\n\n return TransactionFactory.fromTxData(data, {\n freeze: false,\n common: getCommonConfiguration(chainId),\n });\n}\n\n/**\n * Serializes a transaction object into a hex string.\n *\n * @param transaction - The transaction object.\n * @returns The prefixed hex string.\n */\nexport function serializeTransaction(transaction: TypedTransaction) {\n return bytesToHex(transaction.serialize());\n}\n\n/**\n * Generates the configuration used to prepare transactions.\n *\n * @param chainId - Chain ID.\n * @returns The common configuration.\n */\nfunction getCommonConfiguration(chainId: Hex): Common {\n const customChainParams: Partial<ChainConfig> = {\n chainId: parseInt(chainId, 16),\n defaultHardfork: HARDFORK,\n };\n\n return Common.custom(customChainParams, {\n eips: [7702],\n });\n}\n\n/**\n * Normalize the transaction parameters for compatibility with `ethereumjs/tx`.\n *\n * @param params - The transaction parameters to normalize.\n * @returns The normalized transaction parameters.\n */\nfunction normalizeParams(params: TransactionParams): TransactionParams {\n const newParams = cloneDeep(params);\n normalizeAuthorizationList(newParams.authorizationList);\n return newParams;\n}\n\n/**\n * Normalize the authorization list for `ethereumjs/tx` compatibility.\n *\n * @param authorizationList - The list of authorizations to normalize.\n */\nfunction normalizeAuthorizationList(authorizationList?: AuthorizationList) {\n if (!authorizationList) {\n return;\n }\n\n for (const authorization of authorizationList) {\n authorization.nonce = removeLeadingZeroes(authorization.nonce);\n authorization.r = removeLeadingZeroes(authorization.r);\n authorization.s = removeLeadingZeroes(authorization.s);\n authorization.yParity = removeLeadingZeroes(authorization.yParity);\n }\n}\n\n/**\n * Remove leading zeroes from a hexadecimal string.\n *\n * @param value - The hexadecimal string to process.\n * @returns The processed hexadecimal string.\n */\nfunction removeLeadingZeroes(value: Hex | undefined): Hex | undefined {\n if (!value) {\n return value;\n }\n\n if (value === '0x0') {\n return '0x';\n }\n\n return (value.replace?.(/^0x(00)+/u, '0x') as Hex) ?? value;\n}\n"]}
@@ -4,6 +4,7 @@ exports.determineTransactionType = exports.ESTIMATE_GAS_ERROR = void 0;
4
4
  const abi_1 = require("@ethersproject/abi");
5
5
  const controller_utils_1 = require("@metamask/controller-utils");
6
6
  const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
7
+ const eip7702_1 = require("./eip7702.cjs");
7
8
  const types_1 = require("../types.cjs");
8
9
  exports.ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';
9
10
  const ERC20Interface = new abi_1.Interface(metamask_eth_abis_1.abiERC20);
@@ -110,7 +111,9 @@ async function readAddressAsContract(ethQuery, address) {
110
111
  contractCode = null;
111
112
  }
112
113
  const isContractAddress = contractCode
113
- ? contractCode !== '0x' && contractCode !== '0x0'
114
+ ? contractCode !== '0x' &&
115
+ contractCode !== '0x0' &&
116
+ !contractCode.startsWith(eip7702_1.DELEGATION_PREFIX)
114
117
  : false;
115
118
  return { contractCode, isContractAddress };
116
119
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-type.cjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionDescription } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\n\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param ethQuery - EthQuery instance.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n ethQuery: EthQuery,\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n if (data && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n const { contractCode: getCodeResponse, isContractAddress } =\n await readAddressAsContract(ethQuery, to);\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = parseStandardTokenTransactionData(data)?.name;\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find(\n (methodName) => methodName.toLowerCase() === (name as string).toLowerCase(),\n );\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @returns A representation of an ethereum contract call.\n */\nfunction parseStandardTokenTransactionData(\n data?: string,\n): TransactionDescription | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return ERC20Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc721 ABI\n }\n\n try {\n return ERC721Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc1155 ABI\n }\n\n try {\n return ERC1155Interface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n try {\n return USDCInterface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n return undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param ethQuery - The Ethereum query object used to interact with the Ethereum blockchain.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n ethQuery: EthQuery,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = await query(ethQuery, 'getCode', [address]);\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' && contractCode !== '0x0'\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
1
+ {"version":3,"file":"transaction-type.cjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionDescription } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\n\nimport { DELEGATION_PREFIX } from './eip7702';\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param ethQuery - EthQuery instance.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n ethQuery: EthQuery,\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n if (data && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n const { contractCode: getCodeResponse, isContractAddress } =\n await readAddressAsContract(ethQuery, to);\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = parseStandardTokenTransactionData(data)?.name;\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find(\n (methodName) => methodName.toLowerCase() === (name as string).toLowerCase(),\n );\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @returns A representation of an ethereum contract call.\n */\nfunction parseStandardTokenTransactionData(\n data?: string,\n): TransactionDescription | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return ERC20Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc721 ABI\n }\n\n try {\n return ERC721Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc1155 ABI\n }\n\n try {\n return ERC1155Interface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n try {\n return USDCInterface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n return undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param ethQuery - The Ethereum query object used to interact with the Ethereum blockchain.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n ethQuery: EthQuery,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = await query(ethQuery, 'getCode', [address]);\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-type.d.cts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAQhD,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,qBAAiB;AAG9E,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,0BAA0B,CAAC,CA+CrC"}
1
+ {"version":3,"file":"transaction-type.d.cts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAShD,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,qBAAiB;AAG9E,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,0BAA0B,CAAC,CA+CrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-type.d.mts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAQhD,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,qBAAiB;AAG9E,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,0BAA0B,CAAC,CA+CrC"}
1
+ {"version":3,"file":"transaction-type.d.mts","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,4BAA4B;AAShD,OAAO,KAAK,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,qBAAiB;AAG9E,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAOrE;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,0BAA0B,CAAC,CA+CrC"}
@@ -1,6 +1,7 @@
1
1
  import { Interface } from "@ethersproject/abi";
2
2
  import { query } from "@metamask/controller-utils";
3
3
  import { abiERC721, abiERC20, abiERC1155, abiFiatTokenV2 } from "@metamask/metamask-eth-abis";
4
+ import { DELEGATION_PREFIX } from "./eip7702.mjs";
4
5
  import { TransactionType } from "../types.mjs";
5
6
  export const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';
6
7
  const ERC20Interface = new Interface(abiERC20);
@@ -106,7 +107,9 @@ async function readAddressAsContract(ethQuery, address) {
106
107
  contractCode = null;
107
108
  }
108
109
  const isContractAddress = contractCode
109
- ? contractCode !== '0x' && contractCode !== '0x0'
110
+ ? contractCode !== '0x' &&
111
+ contractCode !== '0x0' &&
112
+ !contractCode.startsWith(DELEGATION_PREFIX)
110
113
  : false;
111
114
  return { contractCode, isContractAddress };
112
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"transaction-type.mjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionDescription } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\n\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param ethQuery - EthQuery instance.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n ethQuery: EthQuery,\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n if (data && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n const { contractCode: getCodeResponse, isContractAddress } =\n await readAddressAsContract(ethQuery, to);\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = parseStandardTokenTransactionData(data)?.name;\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find(\n (methodName) => methodName.toLowerCase() === (name as string).toLowerCase(),\n );\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @returns A representation of an ethereum contract call.\n */\nfunction parseStandardTokenTransactionData(\n data?: string,\n): TransactionDescription | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return ERC20Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc721 ABI\n }\n\n try {\n return ERC721Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc1155 ABI\n }\n\n try {\n return ERC1155Interface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n try {\n return USDCInterface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n return undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param ethQuery - The Ethereum query object used to interact with the Ethereum blockchain.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n ethQuery: EthQuery,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = await query(ethQuery, 'getCode', [address]);\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' && contractCode !== '0x0'\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
1
+ {"version":3,"file":"transaction-type.mjs","sourceRoot":"","sources":["../../src/utils/transaction-type.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TransactionDescription } from '@ethersproject/abi';\nimport { Interface } from '@ethersproject/abi';\nimport { query } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport {\n abiERC721,\n abiERC20,\n abiERC1155,\n abiFiatTokenV2,\n} from '@metamask/metamask-eth-abis';\n\nimport { DELEGATION_PREFIX } from './eip7702';\nimport type { InferTransactionTypeResult, TransactionParams } from '../types';\nimport { TransactionType } from '../types';\n\nexport const ESTIMATE_GAS_ERROR = 'eth_estimateGas rpc method error';\n\nconst ERC20Interface = new Interface(abiERC20);\nconst ERC721Interface = new Interface(abiERC721);\nconst ERC1155Interface = new Interface(abiERC1155);\nconst USDCInterface = new Interface(abiFiatTokenV2);\n\n/**\n * Determines the type of the transaction by analyzing the txParams.\n * It will never return TRANSACTION_TYPE_CANCEL or TRANSACTION_TYPE_RETRY as these\n * represent specific events that we specify manually at transaction creation.\n *\n * @param txParams - Parameters for the transaction.\n * @param ethQuery - EthQuery instance.\n * @returns A object with the transaction type and the contract code response in Hex.\n */\nexport async function determineTransactionType(\n txParams: TransactionParams,\n ethQuery: EthQuery,\n): Promise<InferTransactionTypeResult> {\n const { data, to } = txParams;\n\n if (data && !to) {\n return { type: TransactionType.deployContract, getCodeResponse: undefined };\n }\n\n const { contractCode: getCodeResponse, isContractAddress } =\n await readAddressAsContract(ethQuery, to);\n\n if (!isContractAddress) {\n return { type: TransactionType.simpleSend, getCodeResponse };\n }\n\n const hasValue = Number(txParams.value ?? '0') !== 0;\n\n const contractInteractionResult = {\n type: TransactionType.contractInteraction,\n getCodeResponse,\n };\n\n if (!data || hasValue) {\n return contractInteractionResult;\n }\n\n const name = parseStandardTokenTransactionData(data)?.name;\n\n if (!name) {\n return contractInteractionResult;\n }\n\n const tokenMethodName = [\n TransactionType.tokenMethodApprove,\n TransactionType.tokenMethodSetApprovalForAll,\n TransactionType.tokenMethodTransfer,\n TransactionType.tokenMethodTransferFrom,\n TransactionType.tokenMethodSafeTransferFrom,\n TransactionType.tokenMethodIncreaseAllowance,\n ].find(\n (methodName) => methodName.toLowerCase() === (name as string).toLowerCase(),\n );\n\n if (tokenMethodName) {\n return { type: tokenMethodName, getCodeResponse };\n }\n\n return contractInteractionResult;\n}\n\n/**\n * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155.\n * The data will decode correctly if the transaction is an interaction with a contract that matches one of these\n * contract standards\n *\n * @param data - Encoded transaction data.\n * @returns A representation of an ethereum contract call.\n */\nfunction parseStandardTokenTransactionData(\n data?: string,\n): TransactionDescription | undefined {\n if (!data) {\n return undefined;\n }\n\n try {\n return ERC20Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc721 ABI\n }\n\n try {\n return ERC721Interface.parseTransaction({ data });\n } catch {\n // ignore and next try to parse with erc1155 ABI\n }\n\n try {\n return ERC1155Interface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n try {\n return USDCInterface.parseTransaction({ data });\n } catch {\n // ignore and return undefined\n }\n\n return undefined;\n}\n\n/**\n * Reads an Ethereum address and determines if it is a contract address.\n *\n * @param ethQuery - The Ethereum query object used to interact with the Ethereum blockchain.\n * @param address - The Ethereum address.\n * @returns An object containing the contract code and a boolean indicating if it is a contract address.\n */\nasync function readAddressAsContract(\n ethQuery: EthQuery,\n address?: string,\n): Promise<{\n contractCode: string | null;\n isContractAddress: boolean;\n}> {\n let contractCode;\n try {\n contractCode = await query(ethQuery, 'getCode', [address]);\n // Not used\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n contractCode = null;\n }\n\n const isContractAddress = contractCode\n ? contractCode !== '0x' &&\n contractCode !== '0x0' &&\n !contractCode.startsWith(DELEGATION_PREFIX)\n : false;\n return { contractCode, isContractAddress };\n}\n"]}
@@ -362,8 +362,8 @@ function validateAuthorization(authorization) {
362
362
  }
363
363
  }
364
364
  const { yParity } = authorization;
365
- if (yParity && !['0x', '0x1'].includes(yParity)) {
366
- throw rpc_errors_1.rpcErrors.invalidParams(`Invalid transaction params: yParity must be '0x' or '0x1'. got: ${yParity}`);
365
+ if (yParity && !['0x0', '0x1'].includes(yParity)) {
366
+ throw rpc_errors_1.rpcErrors.invalidParams(`Invalid transaction params: yParity must be '0x0' or '0x1'. got: ${yParity}`);
367
367
  }
368
368
  }
369
369
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"validation.cjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { JsonRpcError, providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Hex } from '@metamask/utils';\nimport { isStrictHexString, remove0x } from '@metamask/utils';\n\nimport { isEIP1559Transaction } from './utils';\nimport type { Authorization, TransactionBatchRequest } from '../types';\nimport {\n TransactionEnvelopeType,\n TransactionType,\n type TransactionParams,\n} from '../types';\n\nexport enum ErrorCode {\n DuplicateBundleId = 5720,\n BundleTooLarge = 5740,\n RejectedUpgrade = 5750,\n}\n\nconst TRANSACTION_ENVELOPE_TYPES_FEE_MARKET = [\n TransactionEnvelopeType.feeMarket,\n TransactionEnvelopeType.setCode,\n];\n\ntype GasFieldsToValidate =\n | 'gasPrice'\n | 'maxFeePerGas'\n | 'maxPriorityFeePerGas'\n | 'gas'\n | 'gasLimit';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param options - Options bag.\n * @param options.data - The data included in the transaction.\n * @param options.from - The address from which the transaction is initiated.\n * @param options.internalAccounts - The internal accounts added to the wallet.\n * @param options.origin - The origin or source of the transaction.\n * @param options.permittedAddresses - The permitted accounts for the given origin.\n * @param options.selectedAddress - The currently selected Ethereum address in the wallet.\n * @param options.txParams - The transaction parameters.\n * @param options.type - The transaction type.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin({\n data,\n from,\n internalAccounts,\n origin,\n permittedAddresses,\n txParams,\n type,\n}: {\n data?: string;\n from: string;\n internalAccounts?: string[];\n origin?: string;\n permittedAddresses?: string[];\n selectedAddress?: string;\n txParams: TransactionParams;\n type?: TransactionType;\n}) {\n const isInternal = !origin || origin === ORIGIN_METAMASK;\n\n if (isInternal) {\n return;\n }\n\n const { authorizationList, to, type: envelopeType } = txParams;\n\n if (permittedAddresses && !permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n\n if (type === TransactionType.batch) {\n return;\n }\n\n if (authorizationList || envelopeType === TransactionEnvelopeType.setCode) {\n throw rpcErrors.invalidParams(\n 'External EIP-7702 transactions are not supported',\n );\n }\n\n const hasData = Boolean(data && data !== '0x');\n\n if (\n hasData &&\n internalAccounts?.some(\n (account) => account.toLowerCase() === to?.toLowerCase(),\n )\n ) {\n throw rpcErrors.invalidParams(\n 'External transactions to internal accounts cannot include data',\n );\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n * @param chainId - The chain ID of the transaction.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n chainId?: Hex,\n) {\n validateEnvelopeType(txParams.type);\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId, chainId);\n validateGasFeeParams(txParams);\n validateAuthorizationList(txParams);\n}\n\n/**\n * Validates the `type` property, ensuring that if it is specified, it is a valid transaction envelope type.\n *\n * @param type - The transaction envelope type to validate.\n * @throws Throws invalid params if the type is not a valid transaction envelope type.\n */\nfunction validateEnvelopeType(type: string | undefined) {\n if (\n type &&\n !Object.values(TransactionEnvelopeType).includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: \"${type}\". Must be one of: ${Object.values(\n TransactionEnvelopeType,\n ).join(', ')}`,\n );\n }\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": number must be in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value ${value}: number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid \"from\" address ${from}: not a string.`,\n );\n }\n if (!isValidHexAddress(from)) {\n throw rpcErrors.invalidParams('Invalid \"from\" address.');\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param to - The to property to validate.\n * @throws Throws an error if the recipient address is invalid.\n */\nexport function validateParamTo(to?: string) {\n if (!to || typeof to !== 'string') {\n throw rpcErrors.invalidParams(`Invalid \"to\" address`);\n }\n}\n\n/**\n * Validates a transaction batch request.\n *\n * @param options - Options bag.\n * @param options.internalAccounts - The internal accounts added to the wallet.\n * @param options.request - The batch request object.\n * @param options.sizeLimit - The maximum number of calls allowed in a batch request.\n */\nexport function validateBatchRequest({\n internalAccounts,\n request,\n sizeLimit,\n}: {\n internalAccounts: string[];\n request: TransactionBatchRequest;\n sizeLimit: number;\n}) {\n const { origin } = request;\n const isExternal = origin && origin !== ORIGIN_METAMASK;\n\n const internalAccountsNormalized = internalAccounts.map((account) =>\n account.toLowerCase(),\n );\n\n if (\n isExternal &&\n request.transactions.some((nestedTransaction) => {\n const normalizedCallTo =\n nestedTransaction.params.to?.toLowerCase() as string;\n\n const callData = nestedTransaction.params.data;\n\n const isInternalAccount =\n internalAccountsNormalized.includes(normalizedCallTo);\n\n const hasData = Boolean(callData && callData !== '0x');\n\n return isInternalAccount && hasData;\n })\n ) {\n throw rpcErrors.invalidParams(\n 'External calls to internal accounts cannot include data',\n );\n }\n\n if (isExternal && request.transactions.length > sizeLimit) {\n throw new JsonRpcError(\n ErrorCode.BundleTooLarge,\n `Batch size cannot exceed ${sizeLimit}. got: ${request.transactions.length}`,\n );\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainIdParams - The chain ID to validate.\n * @param chainIdNetworkClient - The chain ID of the network client.\n */\nfunction validateParamChainId(chainIdParams?: Hex, chainIdNetworkClient?: Hex) {\n if (\n chainIdParams &&\n chainIdNetworkClient &&\n chainIdParams.toLowerCase?.() !== chainIdNetworkClient.toLowerCase()\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId must match the network client, got: ${chainIdParams}, expected: ${chainIdNetworkClient}`,\n );\n }\n}\n\n/**\n * Validates gas values.\n *\n * @param txParams - The transaction parameters to validate.\n */\nfunction validateGasFeeParams(txParams: TransactionParams) {\n if (txParams.gasPrice) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxPriorityFeePerGas',\n );\n ensureFieldIsValidHex(txParams, 'gasPrice');\n }\n\n if (txParams.maxFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsValidHex(txParams, 'maxFeePerGas');\n }\n\n if (txParams.maxPriorityFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(\n txParams,\n 'maxPriorityFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxPriorityFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsValidHex(txParams, 'maxPriorityFeePerGas');\n }\n\n if (txParams.gasLimit) {\n ensureFieldIsValidHex(txParams, 'gasLimit');\n }\n\n if (txParams.gas) {\n ensureFieldIsValidHex(txParams, 'gas');\n }\n}\n\n/**\n * Ensures that the provided txParams has the proper 'type' specified for the\n * given field, if it is provided. If types do not match throws an\n * invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the\n * expectations for provided field.\n */\nfunction ensureProperTransactionEnvelopeTypeProvided(\n txParams: TransactionParams,\n field: keyof TransactionParams,\n) {\n const type = txParams.type as TransactionEnvelopeType | undefined;\n\n switch (field) {\n case 'authorizationList':\n if (type && type !== TransactionEnvelopeType.setCode) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but including authorizationList requires type: \"${TransactionEnvelopeType.setCode}\"`,\n );\n }\n break;\n case 'maxFeePerGas':\n case 'maxPriorityFeePerGas':\n if (\n type &&\n !TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but including maxFeePerGas and maxPriorityFeePerGas requires type: \"${TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.join(', ')}\"`,\n );\n }\n break;\n case 'gasPrice':\n default:\n if (\n type &&\n TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`,\n );\n }\n }\n}\n\n/**\n * Given two fields, ensure that the second field is not included in txParams,\n * and if it is throw an invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param fieldBeingValidated - The current field being validated\n * @param mutuallyExclusiveField - The field to ensure is not provided\n * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is\n * present in txParams.\n */\nfunction ensureMutuallyExclusiveFieldsNotProvided(\n txParams: TransactionParams,\n fieldBeingValidated: GasFieldsToValidate,\n mutuallyExclusiveField: GasFieldsToValidate,\n) {\n if (typeof txParams[mutuallyExclusiveField] !== 'undefined') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`,\n );\n }\n}\n\n/**\n * Ensures that the provided value for field is a valid hexadecimal.\n * Throws an invalidParams error if field is not a valid hexadecimal.\n *\n * @param data - The object containing the field\n * @param field - The current field being validated\n * @throws {rpcErrors.invalidParams} Throws if field is not a valid hexadecimal\n */\nfunction ensureFieldIsValidHex<T>(data: T, field: keyof T) {\n const value = data[field];\n if (typeof value !== 'string' || !isStrictHexString(value)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${String(field)} is not a valid hexadecimal string. got: (${String(\n value,\n )})`,\n );\n }\n}\n\n/**\n * Validate the authorization list property in the transaction parameters.\n *\n * @param txParams - The transaction parameters containing the authorization list to validate.\n */\nfunction validateAuthorizationList(txParams: TransactionParams) {\n const { authorizationList } = txParams;\n\n if (!authorizationList) {\n return;\n }\n\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'authorizationList');\n\n if (!Array.isArray(authorizationList)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: authorizationList must be an array`,\n );\n }\n\n for (const authorization of authorizationList) {\n validateAuthorization(authorization);\n }\n}\n\n/**\n * Validate an authorization object.\n *\n * @param authorization - The authorization object to validate.\n */\nfunction validateAuthorization(authorization: Authorization) {\n ensureFieldIsValidHex(authorization, 'address');\n validateHexLength(authorization.address, 20, 'address');\n\n for (const field of ['chainId', 'nonce', 'r', 's'] as const) {\n if (authorization[field]) {\n ensureFieldIsValidHex(authorization, field);\n }\n }\n\n const { yParity } = authorization;\n\n if (yParity && !['0x', '0x1'].includes(yParity)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: yParity must be '0x' or '0x1'. got: ${yParity}`,\n );\n }\n}\n\n/**\n * Validate the number of bytes in a hex string.\n *\n * @param value - The hex string to validate.\n * @param lengthBytes - The expected length in bytes.\n * @param fieldName - The name of the field being validated.\n */\nfunction validateHexLength(\n value: string,\n lengthBytes: number,\n fieldName: string,\n) {\n const actualLengthBytes = remove0x(value).length / 2;\n\n if (actualLengthBytes !== lengthBytes) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${fieldName} must be ${lengthBytes} bytes. got: ${actualLengthBytes} bytes`,\n );\n }\n}\n"]}
1
+ {"version":3,"file":"validation.cjs","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { ORIGIN_METAMASK, isValidHexAddress } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { JsonRpcError, providerErrors, rpcErrors } from '@metamask/rpc-errors';\nimport type { Hex } from '@metamask/utils';\nimport { isStrictHexString, remove0x } from '@metamask/utils';\n\nimport { isEIP1559Transaction } from './utils';\nimport type { Authorization, TransactionBatchRequest } from '../types';\nimport {\n TransactionEnvelopeType,\n TransactionType,\n type TransactionParams,\n} from '../types';\n\nexport enum ErrorCode {\n DuplicateBundleId = 5720,\n BundleTooLarge = 5740,\n RejectedUpgrade = 5750,\n}\n\nconst TRANSACTION_ENVELOPE_TYPES_FEE_MARKET = [\n TransactionEnvelopeType.feeMarket,\n TransactionEnvelopeType.setCode,\n];\n\ntype GasFieldsToValidate =\n | 'gasPrice'\n | 'maxFeePerGas'\n | 'maxPriorityFeePerGas'\n | 'gas'\n | 'gasLimit';\n\n/**\n * Validates whether a transaction initiated by a specific 'from' address is permitted by the origin.\n *\n * @param options - Options bag.\n * @param options.data - The data included in the transaction.\n * @param options.from - The address from which the transaction is initiated.\n * @param options.internalAccounts - The internal accounts added to the wallet.\n * @param options.origin - The origin or source of the transaction.\n * @param options.permittedAddresses - The permitted accounts for the given origin.\n * @param options.selectedAddress - The currently selected Ethereum address in the wallet.\n * @param options.txParams - The transaction parameters.\n * @param options.type - The transaction type.\n * @throws Throws an error if the transaction is not permitted.\n */\nexport async function validateTransactionOrigin({\n data,\n from,\n internalAccounts,\n origin,\n permittedAddresses,\n txParams,\n type,\n}: {\n data?: string;\n from: string;\n internalAccounts?: string[];\n origin?: string;\n permittedAddresses?: string[];\n selectedAddress?: string;\n txParams: TransactionParams;\n type?: TransactionType;\n}) {\n const isInternal = !origin || origin === ORIGIN_METAMASK;\n\n if (isInternal) {\n return;\n }\n\n const { authorizationList, to, type: envelopeType } = txParams;\n\n if (permittedAddresses && !permittedAddresses.includes(from)) {\n throw providerErrors.unauthorized({ data: { origin } });\n }\n\n if (type === TransactionType.batch) {\n return;\n }\n\n if (authorizationList || envelopeType === TransactionEnvelopeType.setCode) {\n throw rpcErrors.invalidParams(\n 'External EIP-7702 transactions are not supported',\n );\n }\n\n const hasData = Boolean(data && data !== '0x');\n\n if (\n hasData &&\n internalAccounts?.some(\n (account) => account.toLowerCase() === to?.toLowerCase(),\n )\n ) {\n throw rpcErrors.invalidParams(\n 'External transactions to internal accounts cannot include data',\n );\n }\n}\n\n/**\n * Validates the transaction params for required properties and throws in\n * the event of any validation error.\n *\n * @param txParams - Transaction params object to validate.\n * @param isEIP1559Compatible - whether or not the current network supports EIP-1559 transactions.\n * @param chainId - The chain ID of the transaction.\n */\nexport function validateTxParams(\n txParams: TransactionParams,\n isEIP1559Compatible = true,\n chainId?: Hex,\n) {\n validateEnvelopeType(txParams.type);\n validateEIP1559Compatibility(txParams, isEIP1559Compatible);\n validateParamFrom(txParams.from);\n validateParamRecipient(txParams);\n validateParamValue(txParams.value);\n validateParamData(txParams.data);\n validateParamChainId(txParams.chainId, chainId);\n validateGasFeeParams(txParams);\n validateAuthorizationList(txParams);\n}\n\n/**\n * Validates the `type` property, ensuring that if it is specified, it is a valid transaction envelope type.\n *\n * @param type - The transaction envelope type to validate.\n * @throws Throws invalid params if the type is not a valid transaction envelope type.\n */\nfunction validateEnvelopeType(type: string | undefined) {\n if (\n type &&\n !Object.values(TransactionEnvelopeType).includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: \"${type}\". Must be one of: ${Object.values(\n TransactionEnvelopeType,\n ).join(', ')}`,\n );\n }\n}\n\n/**\n * Validates EIP-1559 compatibility for transaction creation.\n *\n * @param txParams - The transaction parameters to validate.\n * @param isEIP1559Compatible - Indicates if the current network supports EIP-1559.\n * @throws Throws invalid params if the transaction specifies EIP-1559 but the network does not support it.\n */\nfunction validateEIP1559Compatibility(\n txParams: TransactionParams,\n isEIP1559Compatible: boolean,\n) {\n if (isEIP1559Transaction(txParams) && !isEIP1559Compatible) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: params specify an EIP-1559 transaction but the current network does not support EIP-1559',\n );\n }\n}\n\n/**\n * Validates value property, ensuring it is a valid positive integer number\n * denominated in wei.\n *\n * @param value - The value to validate, expressed as a string.\n * @throws Throws an error if the value is not a valid positive integer\n * number denominated in wei.\n * - If the value contains a hyphen (-), it is considered invalid.\n * - If the value contains a decimal point (.), it is considered invalid.\n * - If the value is not a finite number, is NaN, or is not a safe integer, it is considered invalid.\n */\nfunction validateParamValue(value?: string) {\n if (value !== undefined) {\n if (value.includes('-')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": not a positive number.`,\n );\n }\n\n if (value.includes('.')) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value \"${value}\": number must be in wei.`,\n );\n }\n const intValue = parseInt(value, 10);\n const isValid =\n Number.isFinite(intValue) &&\n !Number.isNaN(intValue) &&\n !isNaN(Number(value)) &&\n Number.isSafeInteger(intValue);\n if (!isValid) {\n throw rpcErrors.invalidParams(\n `Invalid transaction value ${value}: number must be a valid number.`,\n );\n }\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param txParams - The transaction parameters object to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamRecipient(txParams: TransactionParams) {\n if (txParams.to === '0x' || txParams.to === undefined) {\n if (txParams.data) {\n delete txParams.to;\n } else {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n } else if (txParams.to !== undefined && !isValidHexAddress(txParams.to)) {\n throw rpcErrors.invalidParams(`Invalid \"to\" address.`);\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param from - The from property to validate.\n * @throws Throws an error if the recipient address is invalid:\n * - If the recipient address is an empty string ('0x') or undefined and the transaction contains data,\n * the \"to\" field is removed from the transaction parameters.\n * - If the recipient address is not a valid hexadecimal Ethereum address, an error is thrown.\n */\nfunction validateParamFrom(from: string) {\n if (!from || typeof from !== 'string') {\n throw rpcErrors.invalidParams(\n `Invalid \"from\" address ${from}: not a string.`,\n );\n }\n if (!isValidHexAddress(from)) {\n throw rpcErrors.invalidParams('Invalid \"from\" address.');\n }\n}\n\n/**\n * Validates the recipient address in a transaction's parameters.\n *\n * @param to - The to property to validate.\n * @throws Throws an error if the recipient address is invalid.\n */\nexport function validateParamTo(to?: string) {\n if (!to || typeof to !== 'string') {\n throw rpcErrors.invalidParams(`Invalid \"to\" address`);\n }\n}\n\n/**\n * Validates a transaction batch request.\n *\n * @param options - Options bag.\n * @param options.internalAccounts - The internal accounts added to the wallet.\n * @param options.request - The batch request object.\n * @param options.sizeLimit - The maximum number of calls allowed in a batch request.\n */\nexport function validateBatchRequest({\n internalAccounts,\n request,\n sizeLimit,\n}: {\n internalAccounts: string[];\n request: TransactionBatchRequest;\n sizeLimit: number;\n}) {\n const { origin } = request;\n const isExternal = origin && origin !== ORIGIN_METAMASK;\n\n const internalAccountsNormalized = internalAccounts.map((account) =>\n account.toLowerCase(),\n );\n\n if (\n isExternal &&\n request.transactions.some((nestedTransaction) => {\n const normalizedCallTo =\n nestedTransaction.params.to?.toLowerCase() as string;\n\n const callData = nestedTransaction.params.data;\n\n const isInternalAccount =\n internalAccountsNormalized.includes(normalizedCallTo);\n\n const hasData = Boolean(callData && callData !== '0x');\n\n return isInternalAccount && hasData;\n })\n ) {\n throw rpcErrors.invalidParams(\n 'External calls to internal accounts cannot include data',\n );\n }\n\n if (isExternal && request.transactions.length > sizeLimit) {\n throw new JsonRpcError(\n ErrorCode.BundleTooLarge,\n `Batch size cannot exceed ${sizeLimit}. got: ${request.transactions.length}`,\n );\n }\n}\n\n/**\n * Validates input data for transactions.\n *\n * @param value - The input data to validate.\n * @throws Throws invalid params if the input data is invalid.\n */\nfunction validateParamData(value?: string) {\n if (value) {\n const ERC20Interface = new Interface(abiERC20);\n try {\n ERC20Interface.parseTransaction({ data: value });\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.message.match(/BUFFER_OVERRUN/u)) {\n throw rpcErrors.invalidParams(\n 'Invalid transaction params: data out-of-bounds, BUFFER_OVERRUN.',\n );\n }\n }\n }\n}\n\n/**\n * Validates chainId type.\n *\n * @param chainIdParams - The chain ID to validate.\n * @param chainIdNetworkClient - The chain ID of the network client.\n */\nfunction validateParamChainId(chainIdParams?: Hex, chainIdNetworkClient?: Hex) {\n if (\n chainIdParams &&\n chainIdNetworkClient &&\n chainIdParams.toLowerCase?.() !== chainIdNetworkClient.toLowerCase()\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: chainId must match the network client, got: ${chainIdParams}, expected: ${chainIdNetworkClient}`,\n );\n }\n}\n\n/**\n * Validates gas values.\n *\n * @param txParams - The transaction parameters to validate.\n */\nfunction validateGasFeeParams(txParams: TransactionParams) {\n if (txParams.gasPrice) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'gasPrice');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'gasPrice',\n 'maxPriorityFeePerGas',\n );\n ensureFieldIsValidHex(txParams, 'gasPrice');\n }\n\n if (txParams.maxFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'maxFeePerGas');\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsValidHex(txParams, 'maxFeePerGas');\n }\n\n if (txParams.maxPriorityFeePerGas) {\n ensureProperTransactionEnvelopeTypeProvided(\n txParams,\n 'maxPriorityFeePerGas',\n );\n ensureMutuallyExclusiveFieldsNotProvided(\n txParams,\n 'maxPriorityFeePerGas',\n 'gasPrice',\n );\n ensureFieldIsValidHex(txParams, 'maxPriorityFeePerGas');\n }\n\n if (txParams.gasLimit) {\n ensureFieldIsValidHex(txParams, 'gasLimit');\n }\n\n if (txParams.gas) {\n ensureFieldIsValidHex(txParams, 'gas');\n }\n}\n\n/**\n * Ensures that the provided txParams has the proper 'type' specified for the\n * given field, if it is provided. If types do not match throws an\n * invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param field - The current field being validated\n * @throws {ethErrors.rpc.invalidParams} Throws if type does not match the\n * expectations for provided field.\n */\nfunction ensureProperTransactionEnvelopeTypeProvided(\n txParams: TransactionParams,\n field: keyof TransactionParams,\n) {\n const type = txParams.type as TransactionEnvelopeType | undefined;\n\n switch (field) {\n case 'authorizationList':\n if (type && type !== TransactionEnvelopeType.setCode) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but including authorizationList requires type: \"${TransactionEnvelopeType.setCode}\"`,\n );\n }\n break;\n case 'maxFeePerGas':\n case 'maxPriorityFeePerGas':\n if (\n type &&\n !TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but including maxFeePerGas and maxPriorityFeePerGas requires type: \"${TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.join(', ')}\"`,\n );\n }\n break;\n case 'gasPrice':\n default:\n if (\n type &&\n TRANSACTION_ENVELOPE_TYPES_FEE_MARKET.includes(\n type as TransactionEnvelopeType,\n )\n ) {\n throw rpcErrors.invalidParams(\n `Invalid transaction envelope type: specified type \"${type}\" but included a gasPrice instead of maxFeePerGas and maxPriorityFeePerGas`,\n );\n }\n }\n}\n\n/**\n * Given two fields, ensure that the second field is not included in txParams,\n * and if it is throw an invalidParams error.\n *\n * @param txParams - The transaction parameters object\n * @param fieldBeingValidated - The current field being validated\n * @param mutuallyExclusiveField - The field to ensure is not provided\n * @throws {ethErrors.rpc.invalidParams} Throws if mutuallyExclusiveField is\n * present in txParams.\n */\nfunction ensureMutuallyExclusiveFieldsNotProvided(\n txParams: TransactionParams,\n fieldBeingValidated: GasFieldsToValidate,\n mutuallyExclusiveField: GasFieldsToValidate,\n) {\n if (typeof txParams[mutuallyExclusiveField] !== 'undefined') {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: specified ${fieldBeingValidated} but also included ${mutuallyExclusiveField}, these cannot be mixed`,\n );\n }\n}\n\n/**\n * Ensures that the provided value for field is a valid hexadecimal.\n * Throws an invalidParams error if field is not a valid hexadecimal.\n *\n * @param data - The object containing the field\n * @param field - The current field being validated\n * @throws {rpcErrors.invalidParams} Throws if field is not a valid hexadecimal\n */\nfunction ensureFieldIsValidHex<T>(data: T, field: keyof T) {\n const value = data[field];\n if (typeof value !== 'string' || !isStrictHexString(value)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${String(field)} is not a valid hexadecimal string. got: (${String(\n value,\n )})`,\n );\n }\n}\n\n/**\n * Validate the authorization list property in the transaction parameters.\n *\n * @param txParams - The transaction parameters containing the authorization list to validate.\n */\nfunction validateAuthorizationList(txParams: TransactionParams) {\n const { authorizationList } = txParams;\n\n if (!authorizationList) {\n return;\n }\n\n ensureProperTransactionEnvelopeTypeProvided(txParams, 'authorizationList');\n\n if (!Array.isArray(authorizationList)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: authorizationList must be an array`,\n );\n }\n\n for (const authorization of authorizationList) {\n validateAuthorization(authorization);\n }\n}\n\n/**\n * Validate an authorization object.\n *\n * @param authorization - The authorization object to validate.\n */\nfunction validateAuthorization(authorization: Authorization) {\n ensureFieldIsValidHex(authorization, 'address');\n validateHexLength(authorization.address, 20, 'address');\n\n for (const field of ['chainId', 'nonce', 'r', 's'] as const) {\n if (authorization[field]) {\n ensureFieldIsValidHex(authorization, field);\n }\n }\n\n const { yParity } = authorization;\n\n if (yParity && !['0x0', '0x1'].includes(yParity)) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: yParity must be '0x0' or '0x1'. got: ${yParity}`,\n );\n }\n}\n\n/**\n * Validate the number of bytes in a hex string.\n *\n * @param value - The hex string to validate.\n * @param lengthBytes - The expected length in bytes.\n * @param fieldName - The name of the field being validated.\n */\nfunction validateHexLength(\n value: string,\n lengthBytes: number,\n fieldName: string,\n) {\n const actualLengthBytes = remove0x(value).length / 2;\n\n if (actualLengthBytes !== lengthBytes) {\n throw rpcErrors.invalidParams(\n `Invalid transaction params: ${fieldName} must be ${lengthBytes} bytes. got: ${actualLengthBytes} bytes`,\n );\n }\n}\n"]}
@@ -355,8 +355,8 @@ function validateAuthorization(authorization) {
355
355
  }
356
356
  }
357
357
  const { yParity } = authorization;
358
- if (yParity && !['0x', '0x1'].includes(yParity)) {
359
- throw rpcErrors.invalidParams(`Invalid transaction params: yParity must be '0x' or '0x1'. got: ${yParity}`);
358
+ if (yParity && !['0x0', '0x1'].includes(yParity)) {
359
+ throw rpcErrors.invalidParams(`Invalid transaction params: yParity must be '0x0' or '0x1'. got: ${yParity}`);
360
360
  }
361
361
  }
362
362
  /**