@metamask-previews/transaction-controller 51.0.0-preview-29fe07c → 51.0.0-preview-8abae216

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.
@@ -15,7 +15,7 @@ const types_1 = require("../types.cjs");
15
15
  const feature_flags_1 = require("../utils/feature-flags.cjs");
16
16
  const gas_fees_1 = require("../utils/gas-fees.cjs");
17
17
  const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'randomised-estimation-gas-fee-flow');
18
- const PRESERVE_NUMBER_OF_DIGITS = 1;
18
+ const PRESERVE_NUMBER_OF_DIGITS = 2;
19
19
  const DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;
20
20
  /**
21
21
  * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
@@ -82,8 +82,8 @@ _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimatio
82
82
  };
83
83
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel(gasFeeEstimates, level, lastNDigits) {
84
84
  return {
85
- maxFeePerGas: randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
86
- maxPriorityFeePerGas: randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
85
+ maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
86
+ maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
87
87
  };
88
88
  }, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates(gasFeeEstimates, lastNDigits) {
89
89
  const levels = Object.values(types_1.GasFeeEstimateLevel).reduce((result, level) => ({
@@ -95,11 +95,11 @@ _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimatio
95
95
  ...levels,
96
96
  };
97
97
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel(gasFeeEstimates, level, lastNDigits) {
98
- return randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level], lastNDigits);
98
+ return randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level], lastNDigits);
99
99
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate = function _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate(gasFeeEstimates, lastNDigits) {
100
100
  return {
101
101
  type: types_1.GasFeeEstimateType.GasPrice,
102
- gasPrice: randomiseDecimalValueAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
102
+ gasPrice: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
103
103
  };
104
104
  };
105
105
  /**
@@ -116,47 +116,44 @@ function getRandomisedGasFeeConfig(featureFlags) {
116
116
  * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
117
117
  *
118
118
  * This function preserves the more significant digits while randomizing only the least significant ones,
119
- * ensuring that fees remain close to the original estimation while providing fingerprinting protection.
119
+ * ensuring that fees remain close to the original estimation while providing randomisation.
120
+ * The randomisation is performed in Wei units for more precision.
120
121
  *
121
122
  * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
122
123
  * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise
123
124
  * @returns The randomised value converted to Wei in hexadecimal format
124
125
  *
125
126
  * @example
126
- * // Randomise last 3 digits of "200000"
127
- * randomiseDecimalValueAndConvertToHex("200000", 3)
128
- * // Decimal output range: 200000 to 200999
127
+ * // Randomise last 3 digits of "5" Gwei (5000000000 Wei)
128
+ * randomiseDecimalGWEIAndConvertToHex("5", 3)
129
+ * // Decimal output range: 5000000000 to 5000000999 Wei
130
+ * // Hex output range: 0x12a05f200 to 0x12a05f3e7
129
131
  *
130
132
  * @example
131
- * // Randomise last 5 digits of "200000"
132
- * randomiseDecimalValueAndConvertToHex("200000", 5)
133
- * // Decimal output range: 200000 to 299999
133
+ * // Randomise last 6 digits of "10.5" Gwei (10500000000 Wei)
134
+ * randomiseDecimalGWEIAndConvertToHex("10.5", 6)
135
+ * // Decimal output range: 10500000000 to 10500999999 Wei
136
+ * // Hex output range: 0x27312d600 to 0x27313f9cf
134
137
  *
135
138
  * @example
136
- * // Randomise last 6 digits of "200000"
137
- * randomiseDecimalValueAndConvertToHex("200000", 6)
138
- * // Decimal output range: 200000 to 299999
139
- *
140
- * @example
141
- * // Randomise last 8 digits of "200000"
142
- * randomiseDecimalValueAndConvertToHex("200000", 8)
143
- * // Decimal output range: 200000 to 299999
139
+ * // Randomise last 9 digits of "42" Gwei (42000000000 Wei)
140
+ * randomiseDecimalGWEIAndConvertToHex("42", 9)
141
+ * // Decimal output range: 42000000000 to 42999999999 Wei
142
+ * // Hex output range: 0x9c7652400 to 0x9fffff9ff
144
143
  */
145
- function randomiseDecimalValueAndConvertToHex(gweiDecimalValue, lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE) {
146
- const decimalValue = typeof gweiDecimalValue === 'string'
147
- ? gweiDecimalValue
148
- : gweiDecimalValue.toString();
149
- const decimalLength = decimalValue.length;
144
+ function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue, lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE) {
145
+ const weiDecimalValue = (0, gas_fees_1.gweiDecimalToWeiDecimal)(gweiDecimalValue);
146
+ const decimalLength = weiDecimalValue.length;
150
147
  // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS
151
148
  const effectiveDigitsToRandomise = Math.min(lastNumberOfDigitsToRandomise, decimalLength - PRESERVE_NUMBER_OF_DIGITS);
152
149
  const multiplier = 10 ** effectiveDigitsToRandomise;
153
150
  // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact
154
- const basePart = Math.floor(Number(decimalValue) / multiplier) * multiplier;
151
+ const basePart = Math.floor(Number(weiDecimalValue) / multiplier) * multiplier;
155
152
  // Generate random digits
156
153
  const randomDigits = Math.floor(Math.random() * multiplier);
157
154
  // Combine base and random parts
158
- const randomisedDecimal = basePart + randomDigits;
159
- // Convert to gwei to hex
160
- return (0, gas_fees_1.gweiDecimalToWeiHex)(randomisedDecimal.toString());
155
+ const randomisedWeiDecimal = basePart + randomDigits;
156
+ // Convert wei decimal to hex
157
+ return `0x${randomisedWeiDecimal.toString(16)}`;
161
158
  }
162
159
  //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"RandomisedEstimationsGasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LegacyGasPriceEstimate,\n GasFeeEstimates as FeeMarketGasPriceEstimate,\n EthGasPriceEstimate,\n} from '@metamask/gas-fee-controller';\nimport { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type {\n FeeMarketGasFeeEstimateForLevel,\n FeeMarketGasFeeEstimates,\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n GasPriceGasFeeEstimates,\n LegacyGasFeeEstimates,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\nimport type { TransactionControllerFeatureFlags } from '../utils/feature-flags';\nimport { FEATURE_FLAG_RANDOMISE_GAS_FEES } from '../utils/feature-flags';\nimport { gweiDecimalToWeiHex } from '../utils/gas-fees';\n\nconst log = createModuleLogger(\n projectLogger,\n 'randomised-estimation-gas-fee-flow',\n);\n\nconst PRESERVE_NUMBER_OF_DIGITS = 1;\nconst DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;\n\n/**\n * Implementation of a gas fee flow that randomises the last digits of gas fee estimations\n */\nexport class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {\n matchesTransaction(\n transactionMeta: TransactionMeta,\n featureFlags: TransactionControllerFeatureFlags,\n ): boolean {\n const { chainId } = transactionMeta;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n\n const enabledChainIds = Object.keys(randomiseGasFeesConfig);\n\n return enabledChainIds.includes(chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getRandomisedGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return await this.#getDefaultGasFees(request);\n }\n }\n\n async #getDefaultGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n\n async #getRandomisedGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { featureFlags, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n const lastNDigits = randomiseGasFeesConfig[transactionMeta.chainId];\n\n let response: GasFeeEstimates;\n\n switch (gasEstimateType) {\n case GAS_ESTIMATE_TYPES.FEE_MARKET:\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n lastNDigits,\n );\n log('Randomised fee market estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.LEGACY:\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates as LegacyGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised legacy estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.ETH_GASPRICE:\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates as EthGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n break;\n default:\n throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);\n }\n\n return {\n estimates: response,\n };\n }\n\n #randomiseFeeMarketEstimates(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedFeeMarketLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<FeeMarketGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.FeeMarket,\n ...levels,\n };\n }\n\n #getRandomisedFeeMarketLevel(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimateForLevel {\n return {\n maxFeePerGas: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxFeePerGas,\n lastNDigits,\n ),\n maxPriorityFeePerGas: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxPriorityFeePerGas,\n lastNDigits,\n ),\n };\n }\n\n #randomiseLegacyEstimates(\n gasFeeEstimates: LegacyGasPriceEstimate,\n lastNDigits: number,\n ): LegacyGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedLegacyLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<LegacyGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.Legacy,\n ...levels,\n };\n }\n\n #getRandomisedLegacyLevel(\n gasFeeEstimates: LegacyGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): Hex {\n return randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level],\n lastNDigits,\n );\n }\n\n #getRandomisedGasPriceEstimate(\n gasFeeEstimates: EthGasPriceEstimate,\n lastNDigits: number,\n ): GasPriceGasFeeEstimates {\n return {\n type: GasFeeEstimateType.GasPrice,\n gasPrice: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates.gasPrice,\n lastNDigits,\n ),\n };\n }\n}\n\n/**\n * Returns the randomised gas fee config from the feature flags\n *\n * @param featureFlags - All feature flags\n * @returns The randomised gas fee config\n */\nfunction getRandomisedGasFeeConfig(\n featureFlags: TransactionControllerFeatureFlags,\n): Record<Hex, number> {\n const randomiseGasFeesConfig =\n featureFlags?.[FEATURE_FLAG_RANDOMISE_GAS_FEES]?.config ?? {};\n\n return randomiseGasFeesConfig;\n}\n\n/**\n * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.\n *\n * This function preserves the more significant digits while randomizing only the least significant ones,\n * ensuring that fees remain close to the original estimation while providing fingerprinting protection.\n *\n * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)\n * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n *\n * @example\n * // Randomise last 3 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 3)\n * // Decimal output range: 200000 to 200999\n *\n * @example\n * // Randomise last 5 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 5)\n * // Decimal output range: 200000 to 299999\n *\n * @example\n * // Randomise last 6 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 6)\n * // Decimal output range: 200000 to 299999\n *\n * @example\n * // Randomise last 8 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 8)\n * // Decimal output range: 200000 to 299999\n */\nfunction randomiseDecimalValueAndConvertToHex(\n gweiDecimalValue: string | number,\n lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE,\n): Hex {\n const decimalValue =\n typeof gweiDecimalValue === 'string'\n ? gweiDecimalValue\n : gweiDecimalValue.toString();\n\n const decimalLength = decimalValue.length;\n\n // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS\n const effectiveDigitsToRandomise = Math.min(\n lastNumberOfDigitsToRandomise,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n const multiplier = 10 ** effectiveDigitsToRandomise;\n\n // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact\n const basePart = Math.floor(Number(decimalValue) / multiplier) * multiplier;\n\n // Generate random digits\n const randomDigits = Math.floor(Math.random() * multiplier);\n\n // Combine base and random parts\n const randomisedDecimal = basePart + randomDigits;\n\n // Convert to gwei to hex\n return gweiDecimalToWeiHex(randomisedDecimal.toString());\n}\n"]}
1
+ {"version":3,"file":"RandomisedEstimationsGasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LegacyGasPriceEstimate,\n GasFeeEstimates as FeeMarketGasPriceEstimate,\n EthGasPriceEstimate,\n} from '@metamask/gas-fee-controller';\nimport { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type {\n FeeMarketGasFeeEstimateForLevel,\n FeeMarketGasFeeEstimates,\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n GasPriceGasFeeEstimates,\n LegacyGasFeeEstimates,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\nimport type { TransactionControllerFeatureFlags } from '../utils/feature-flags';\nimport { FEATURE_FLAG_RANDOMISE_GAS_FEES } from '../utils/feature-flags';\nimport { gweiDecimalToWeiDecimal } from '../utils/gas-fees';\n\nconst log = createModuleLogger(\n projectLogger,\n 'randomised-estimation-gas-fee-flow',\n);\n\nconst PRESERVE_NUMBER_OF_DIGITS = 2;\nconst DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;\n\n/**\n * Implementation of a gas fee flow that randomises the last digits of gas fee estimations\n */\nexport class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {\n matchesTransaction(\n transactionMeta: TransactionMeta,\n featureFlags: TransactionControllerFeatureFlags,\n ): boolean {\n const { chainId } = transactionMeta;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n\n const enabledChainIds = Object.keys(randomiseGasFeesConfig);\n\n return enabledChainIds.includes(chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getRandomisedGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return await this.#getDefaultGasFees(request);\n }\n }\n\n async #getDefaultGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n\n async #getRandomisedGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { featureFlags, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n const lastNDigits = randomiseGasFeesConfig[transactionMeta.chainId];\n\n let response: GasFeeEstimates;\n\n switch (gasEstimateType) {\n case GAS_ESTIMATE_TYPES.FEE_MARKET:\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n lastNDigits,\n );\n log('Randomised fee market estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.LEGACY:\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates as LegacyGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised legacy estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.ETH_GASPRICE:\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates as EthGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n break;\n default:\n throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);\n }\n\n return {\n estimates: response,\n };\n }\n\n #randomiseFeeMarketEstimates(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedFeeMarketLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<FeeMarketGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.FeeMarket,\n ...levels,\n };\n }\n\n #getRandomisedFeeMarketLevel(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimateForLevel {\n return {\n maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxFeePerGas,\n lastNDigits,\n ),\n maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxPriorityFeePerGas,\n lastNDigits,\n ),\n };\n }\n\n #randomiseLegacyEstimates(\n gasFeeEstimates: LegacyGasPriceEstimate,\n lastNDigits: number,\n ): LegacyGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedLegacyLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<LegacyGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.Legacy,\n ...levels,\n };\n }\n\n #getRandomisedLegacyLevel(\n gasFeeEstimates: LegacyGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): Hex {\n return randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level],\n lastNDigits,\n );\n }\n\n #getRandomisedGasPriceEstimate(\n gasFeeEstimates: EthGasPriceEstimate,\n lastNDigits: number,\n ): GasPriceGasFeeEstimates {\n return {\n type: GasFeeEstimateType.GasPrice,\n gasPrice: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates.gasPrice,\n lastNDigits,\n ),\n };\n }\n}\n\n/**\n * Returns the randomised gas fee config from the feature flags\n *\n * @param featureFlags - All feature flags\n * @returns The randomised gas fee config\n */\nfunction getRandomisedGasFeeConfig(\n featureFlags: TransactionControllerFeatureFlags,\n): Record<Hex, number> {\n const randomiseGasFeesConfig =\n featureFlags?.[FEATURE_FLAG_RANDOMISE_GAS_FEES]?.config ?? {};\n\n return randomiseGasFeesConfig;\n}\n\n/**\n * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.\n *\n * This function preserves the more significant digits while randomizing only the least significant ones,\n * ensuring that fees remain close to the original estimation while providing randomisation.\n * The randomisation is performed in Wei units for more precision.\n *\n * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)\n * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n *\n * @example\n * // Randomise last 3 digits of \"5\" Gwei (5000000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"5\", 3)\n * // Decimal output range: 5000000000 to 5000000999 Wei\n * // Hex output range: 0x12a05f200 to 0x12a05f3e7\n *\n * @example\n * // Randomise last 6 digits of \"10.5\" Gwei (10500000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"10.5\", 6)\n * // Decimal output range: 10500000000 to 10500999999 Wei\n * // Hex output range: 0x27312d600 to 0x27313f9cf\n *\n * @example\n * // Randomise last 9 digits of \"42\" Gwei (42000000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"42\", 9)\n * // Decimal output range: 42000000000 to 42999999999 Wei\n * // Hex output range: 0x9c7652400 to 0x9fffff9ff\n */\nfunction randomiseDecimalGWEIAndConvertToHex(\n gweiDecimalValue: string | number,\n lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE,\n): Hex {\n const weiDecimalValue = gweiDecimalToWeiDecimal(gweiDecimalValue);\n const decimalLength = weiDecimalValue.length;\n\n // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS\n const effectiveDigitsToRandomise = Math.min(\n lastNumberOfDigitsToRandomise,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n const multiplier = 10 ** effectiveDigitsToRandomise;\n\n // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact\n const basePart =\n Math.floor(Number(weiDecimalValue) / multiplier) * multiplier;\n\n // Generate random digits\n const randomDigits = Math.floor(Math.random() * multiplier);\n\n // Combine base and random parts\n const randomisedWeiDecimal = basePart + randomDigits;\n\n // Convert wei decimal to hex\n return `0x${randomisedWeiDecimal.toString(16)}` as Hex;\n}\n"]}
@@ -10,9 +10,9 @@ import { DefaultGasFeeFlow } from "./DefaultGasFeeFlow.mjs";
10
10
  import { projectLogger } from "../logger.mjs";
11
11
  import { GasFeeEstimateLevel, GasFeeEstimateType } from "../types.mjs";
12
12
  import { FEATURE_FLAG_RANDOMISE_GAS_FEES } from "../utils/feature-flags.mjs";
13
- import { gweiDecimalToWeiHex } from "../utils/gas-fees.mjs";
13
+ import { gweiDecimalToWeiDecimal } from "../utils/gas-fees.mjs";
14
14
  const log = createModuleLogger(projectLogger, 'randomised-estimation-gas-fee-flow');
15
- const PRESERVE_NUMBER_OF_DIGITS = 1;
15
+ const PRESERVE_NUMBER_OF_DIGITS = 2;
16
16
  const DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;
17
17
  /**
18
18
  * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
@@ -78,8 +78,8 @@ _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimatio
78
78
  };
79
79
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel(gasFeeEstimates, level, lastNDigits) {
80
80
  return {
81
- maxFeePerGas: randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
82
- maxPriorityFeePerGas: randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
81
+ maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
82
+ maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
83
83
  };
84
84
  }, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates(gasFeeEstimates, lastNDigits) {
85
85
  const levels = Object.values(GasFeeEstimateLevel).reduce((result, level) => ({
@@ -91,11 +91,11 @@ _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimatio
91
91
  ...levels,
92
92
  };
93
93
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel(gasFeeEstimates, level, lastNDigits) {
94
- return randomiseDecimalValueAndConvertToHex(gasFeeEstimates[level], lastNDigits);
94
+ return randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level], lastNDigits);
95
95
  }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate = function _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate(gasFeeEstimates, lastNDigits) {
96
96
  return {
97
97
  type: GasFeeEstimateType.GasPrice,
98
- gasPrice: randomiseDecimalValueAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
98
+ gasPrice: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
99
99
  };
100
100
  };
101
101
  /**
@@ -112,47 +112,44 @@ function getRandomisedGasFeeConfig(featureFlags) {
112
112
  * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
113
113
  *
114
114
  * This function preserves the more significant digits while randomizing only the least significant ones,
115
- * ensuring that fees remain close to the original estimation while providing fingerprinting protection.
115
+ * ensuring that fees remain close to the original estimation while providing randomisation.
116
+ * The randomisation is performed in Wei units for more precision.
116
117
  *
117
118
  * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
118
119
  * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise
119
120
  * @returns The randomised value converted to Wei in hexadecimal format
120
121
  *
121
122
  * @example
122
- * // Randomise last 3 digits of "200000"
123
- * randomiseDecimalValueAndConvertToHex("200000", 3)
124
- * // Decimal output range: 200000 to 200999
123
+ * // Randomise last 3 digits of "5" Gwei (5000000000 Wei)
124
+ * randomiseDecimalGWEIAndConvertToHex("5", 3)
125
+ * // Decimal output range: 5000000000 to 5000000999 Wei
126
+ * // Hex output range: 0x12a05f200 to 0x12a05f3e7
125
127
  *
126
128
  * @example
127
- * // Randomise last 5 digits of "200000"
128
- * randomiseDecimalValueAndConvertToHex("200000", 5)
129
- * // Decimal output range: 200000 to 299999
129
+ * // Randomise last 6 digits of "10.5" Gwei (10500000000 Wei)
130
+ * randomiseDecimalGWEIAndConvertToHex("10.5", 6)
131
+ * // Decimal output range: 10500000000 to 10500999999 Wei
132
+ * // Hex output range: 0x27312d600 to 0x27313f9cf
130
133
  *
131
134
  * @example
132
- * // Randomise last 6 digits of "200000"
133
- * randomiseDecimalValueAndConvertToHex("200000", 6)
134
- * // Decimal output range: 200000 to 299999
135
- *
136
- * @example
137
- * // Randomise last 8 digits of "200000"
138
- * randomiseDecimalValueAndConvertToHex("200000", 8)
139
- * // Decimal output range: 200000 to 299999
135
+ * // Randomise last 9 digits of "42" Gwei (42000000000 Wei)
136
+ * randomiseDecimalGWEIAndConvertToHex("42", 9)
137
+ * // Decimal output range: 42000000000 to 42999999999 Wei
138
+ * // Hex output range: 0x9c7652400 to 0x9fffff9ff
140
139
  */
141
- function randomiseDecimalValueAndConvertToHex(gweiDecimalValue, lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE) {
142
- const decimalValue = typeof gweiDecimalValue === 'string'
143
- ? gweiDecimalValue
144
- : gweiDecimalValue.toString();
145
- const decimalLength = decimalValue.length;
140
+ function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue, lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE) {
141
+ const weiDecimalValue = gweiDecimalToWeiDecimal(gweiDecimalValue);
142
+ const decimalLength = weiDecimalValue.length;
146
143
  // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS
147
144
  const effectiveDigitsToRandomise = Math.min(lastNumberOfDigitsToRandomise, decimalLength - PRESERVE_NUMBER_OF_DIGITS);
148
145
  const multiplier = 10 ** effectiveDigitsToRandomise;
149
146
  // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact
150
- const basePart = Math.floor(Number(decimalValue) / multiplier) * multiplier;
147
+ const basePart = Math.floor(Number(weiDecimalValue) / multiplier) * multiplier;
151
148
  // Generate random digits
152
149
  const randomDigits = Math.floor(Math.random() * multiplier);
153
150
  // Combine base and random parts
154
- const randomisedDecimal = basePart + randomDigits;
155
- // Convert to gwei to hex
156
- return gweiDecimalToWeiHex(randomisedDecimal.toString());
151
+ const randomisedWeiDecimal = basePart + randomDigits;
152
+ // Convert wei decimal to hex
153
+ return `0x${randomisedWeiDecimal.toString(16)}`;
157
154
  }
158
155
  //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"RandomisedEstimationsGasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LegacyGasPriceEstimate,\n GasFeeEstimates as FeeMarketGasPriceEstimate,\n EthGasPriceEstimate,\n} from '@metamask/gas-fee-controller';\nimport { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type {\n FeeMarketGasFeeEstimateForLevel,\n FeeMarketGasFeeEstimates,\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n GasPriceGasFeeEstimates,\n LegacyGasFeeEstimates,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\nimport type { TransactionControllerFeatureFlags } from '../utils/feature-flags';\nimport { FEATURE_FLAG_RANDOMISE_GAS_FEES } from '../utils/feature-flags';\nimport { gweiDecimalToWeiHex } from '../utils/gas-fees';\n\nconst log = createModuleLogger(\n projectLogger,\n 'randomised-estimation-gas-fee-flow',\n);\n\nconst PRESERVE_NUMBER_OF_DIGITS = 1;\nconst DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;\n\n/**\n * Implementation of a gas fee flow that randomises the last digits of gas fee estimations\n */\nexport class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {\n matchesTransaction(\n transactionMeta: TransactionMeta,\n featureFlags: TransactionControllerFeatureFlags,\n ): boolean {\n const { chainId } = transactionMeta;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n\n const enabledChainIds = Object.keys(randomiseGasFeesConfig);\n\n return enabledChainIds.includes(chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getRandomisedGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return await this.#getDefaultGasFees(request);\n }\n }\n\n async #getDefaultGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n\n async #getRandomisedGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { featureFlags, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n const lastNDigits = randomiseGasFeesConfig[transactionMeta.chainId];\n\n let response: GasFeeEstimates;\n\n switch (gasEstimateType) {\n case GAS_ESTIMATE_TYPES.FEE_MARKET:\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n lastNDigits,\n );\n log('Randomised fee market estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.LEGACY:\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates as LegacyGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised legacy estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.ETH_GASPRICE:\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates as EthGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n break;\n default:\n throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);\n }\n\n return {\n estimates: response,\n };\n }\n\n #randomiseFeeMarketEstimates(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedFeeMarketLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<FeeMarketGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.FeeMarket,\n ...levels,\n };\n }\n\n #getRandomisedFeeMarketLevel(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimateForLevel {\n return {\n maxFeePerGas: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxFeePerGas,\n lastNDigits,\n ),\n maxPriorityFeePerGas: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxPriorityFeePerGas,\n lastNDigits,\n ),\n };\n }\n\n #randomiseLegacyEstimates(\n gasFeeEstimates: LegacyGasPriceEstimate,\n lastNDigits: number,\n ): LegacyGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedLegacyLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<LegacyGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.Legacy,\n ...levels,\n };\n }\n\n #getRandomisedLegacyLevel(\n gasFeeEstimates: LegacyGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): Hex {\n return randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates[level],\n lastNDigits,\n );\n }\n\n #getRandomisedGasPriceEstimate(\n gasFeeEstimates: EthGasPriceEstimate,\n lastNDigits: number,\n ): GasPriceGasFeeEstimates {\n return {\n type: GasFeeEstimateType.GasPrice,\n gasPrice: randomiseDecimalValueAndConvertToHex(\n gasFeeEstimates.gasPrice,\n lastNDigits,\n ),\n };\n }\n}\n\n/**\n * Returns the randomised gas fee config from the feature flags\n *\n * @param featureFlags - All feature flags\n * @returns The randomised gas fee config\n */\nfunction getRandomisedGasFeeConfig(\n featureFlags: TransactionControllerFeatureFlags,\n): Record<Hex, number> {\n const randomiseGasFeesConfig =\n featureFlags?.[FEATURE_FLAG_RANDOMISE_GAS_FEES]?.config ?? {};\n\n return randomiseGasFeesConfig;\n}\n\n/**\n * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.\n *\n * This function preserves the more significant digits while randomizing only the least significant ones,\n * ensuring that fees remain close to the original estimation while providing fingerprinting protection.\n *\n * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)\n * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n *\n * @example\n * // Randomise last 3 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 3)\n * // Decimal output range: 200000 to 200999\n *\n * @example\n * // Randomise last 5 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 5)\n * // Decimal output range: 200000 to 299999\n *\n * @example\n * // Randomise last 6 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 6)\n * // Decimal output range: 200000 to 299999\n *\n * @example\n * // Randomise last 8 digits of \"200000\"\n * randomiseDecimalValueAndConvertToHex(\"200000\", 8)\n * // Decimal output range: 200000 to 299999\n */\nfunction randomiseDecimalValueAndConvertToHex(\n gweiDecimalValue: string | number,\n lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE,\n): Hex {\n const decimalValue =\n typeof gweiDecimalValue === 'string'\n ? gweiDecimalValue\n : gweiDecimalValue.toString();\n\n const decimalLength = decimalValue.length;\n\n // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS\n const effectiveDigitsToRandomise = Math.min(\n lastNumberOfDigitsToRandomise,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n const multiplier = 10 ** effectiveDigitsToRandomise;\n\n // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact\n const basePart = Math.floor(Number(decimalValue) / multiplier) * multiplier;\n\n // Generate random digits\n const randomDigits = Math.floor(Math.random() * multiplier);\n\n // Combine base and random parts\n const randomisedDecimal = basePart + randomDigits;\n\n // Convert to gwei to hex\n return gweiDecimalToWeiHex(randomisedDecimal.toString());\n}\n"]}
1
+ {"version":3,"file":"RandomisedEstimationsGasFeeFlow.mjs","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n LegacyGasPriceEstimate,\n GasFeeEstimates as FeeMarketGasPriceEstimate,\n EthGasPriceEstimate,\n} from '@metamask/gas-fee-controller';\nimport { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller';\nimport { createModuleLogger, type Hex } from '@metamask/utils';\n\nimport { DefaultGasFeeFlow } from './DefaultGasFeeFlow';\nimport { projectLogger } from '../logger';\nimport type {\n FeeMarketGasFeeEstimateForLevel,\n FeeMarketGasFeeEstimates,\n GasFeeEstimates,\n GasFeeFlow,\n GasFeeFlowRequest,\n GasFeeFlowResponse,\n GasPriceGasFeeEstimates,\n LegacyGasFeeEstimates,\n TransactionMeta,\n} from '../types';\nimport { GasFeeEstimateLevel, GasFeeEstimateType } from '../types';\nimport type { TransactionControllerFeatureFlags } from '../utils/feature-flags';\nimport { FEATURE_FLAG_RANDOMISE_GAS_FEES } from '../utils/feature-flags';\nimport { gweiDecimalToWeiDecimal } from '../utils/gas-fees';\n\nconst log = createModuleLogger(\n projectLogger,\n 'randomised-estimation-gas-fee-flow',\n);\n\nconst PRESERVE_NUMBER_OF_DIGITS = 2;\nconst DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE = 4;\n\n/**\n * Implementation of a gas fee flow that randomises the last digits of gas fee estimations\n */\nexport class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {\n matchesTransaction(\n transactionMeta: TransactionMeta,\n featureFlags: TransactionControllerFeatureFlags,\n ): boolean {\n const { chainId } = transactionMeta;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n\n const enabledChainIds = Object.keys(randomiseGasFeesConfig);\n\n return enabledChainIds.includes(chainId);\n }\n\n async getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse> {\n try {\n return await this.#getRandomisedGasFees(request);\n } catch (error) {\n log('Using default flow as fallback due to error', error);\n return await this.#getDefaultGasFees(request);\n }\n }\n\n async #getDefaultGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n return new DefaultGasFeeFlow().getGasFees(request);\n }\n\n async #getRandomisedGasFees(\n request: GasFeeFlowRequest,\n ): Promise<GasFeeFlowResponse> {\n const { featureFlags, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomiseGasFeesConfig = getRandomisedGasFeeConfig(featureFlags);\n const lastNDigits = randomiseGasFeesConfig[transactionMeta.chainId];\n\n let response: GasFeeEstimates;\n\n switch (gasEstimateType) {\n case GAS_ESTIMATE_TYPES.FEE_MARKET:\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n lastNDigits,\n );\n log('Randomised fee market estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.LEGACY:\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates as LegacyGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised legacy estimates', response);\n break;\n case GAS_ESTIMATE_TYPES.ETH_GASPRICE:\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates as EthGasPriceEstimate,\n lastNDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n break;\n default:\n throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);\n }\n\n return {\n estimates: response,\n };\n }\n\n #randomiseFeeMarketEstimates(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedFeeMarketLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<FeeMarketGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.FeeMarket,\n ...levels,\n };\n }\n\n #getRandomisedFeeMarketLevel(\n gasFeeEstimates: FeeMarketGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): FeeMarketGasFeeEstimateForLevel {\n return {\n maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxFeePerGas,\n lastNDigits,\n ),\n maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level].suggestedMaxPriorityFeePerGas,\n lastNDigits,\n ),\n };\n }\n\n #randomiseLegacyEstimates(\n gasFeeEstimates: LegacyGasPriceEstimate,\n lastNDigits: number,\n ): LegacyGasFeeEstimates {\n const levels = Object.values(GasFeeEstimateLevel).reduce(\n (result, level) => ({\n ...result,\n [level]: this.#getRandomisedLegacyLevel(\n gasFeeEstimates,\n level,\n lastNDigits,\n ),\n }),\n {} as Omit<LegacyGasFeeEstimates, 'type'>,\n );\n\n return {\n type: GasFeeEstimateType.Legacy,\n ...levels,\n };\n }\n\n #getRandomisedLegacyLevel(\n gasFeeEstimates: LegacyGasPriceEstimate,\n level: GasFeeEstimateLevel,\n lastNDigits: number,\n ): Hex {\n return randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates[level],\n lastNDigits,\n );\n }\n\n #getRandomisedGasPriceEstimate(\n gasFeeEstimates: EthGasPriceEstimate,\n lastNDigits: number,\n ): GasPriceGasFeeEstimates {\n return {\n type: GasFeeEstimateType.GasPrice,\n gasPrice: randomiseDecimalGWEIAndConvertToHex(\n gasFeeEstimates.gasPrice,\n lastNDigits,\n ),\n };\n }\n}\n\n/**\n * Returns the randomised gas fee config from the feature flags\n *\n * @param featureFlags - All feature flags\n * @returns The randomised gas fee config\n */\nfunction getRandomisedGasFeeConfig(\n featureFlags: TransactionControllerFeatureFlags,\n): Record<Hex, number> {\n const randomiseGasFeesConfig =\n featureFlags?.[FEATURE_FLAG_RANDOMISE_GAS_FEES]?.config ?? {};\n\n return randomiseGasFeesConfig;\n}\n\n/**\n * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.\n *\n * This function preserves the more significant digits while randomizing only the least significant ones,\n * ensuring that fees remain close to the original estimation while providing randomisation.\n * The randomisation is performed in Wei units for more precision.\n *\n * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)\n * @param [lastNumberOfDigitsToRandomise] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n *\n * @example\n * // Randomise last 3 digits of \"5\" Gwei (5000000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"5\", 3)\n * // Decimal output range: 5000000000 to 5000000999 Wei\n * // Hex output range: 0x12a05f200 to 0x12a05f3e7\n *\n * @example\n * // Randomise last 6 digits of \"10.5\" Gwei (10500000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"10.5\", 6)\n * // Decimal output range: 10500000000 to 10500999999 Wei\n * // Hex output range: 0x27312d600 to 0x27313f9cf\n *\n * @example\n * // Randomise last 9 digits of \"42\" Gwei (42000000000 Wei)\n * randomiseDecimalGWEIAndConvertToHex(\"42\", 9)\n * // Decimal output range: 42000000000 to 42999999999 Wei\n * // Hex output range: 0x9c7652400 to 0x9fffff9ff\n */\nfunction randomiseDecimalGWEIAndConvertToHex(\n gweiDecimalValue: string | number,\n lastNumberOfDigitsToRandomise = DEFAULT_NUMBER_OF_DIGITS_TO_RANDOMISE,\n): Hex {\n const weiDecimalValue = gweiDecimalToWeiDecimal(gweiDecimalValue);\n const decimalLength = weiDecimalValue.length;\n\n // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS\n const effectiveDigitsToRandomise = Math.min(\n lastNumberOfDigitsToRandomise,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n const multiplier = 10 ** effectiveDigitsToRandomise;\n\n // Remove last digits - this keeps the first (decimalLength - effectiveDigitsToRandomise) digits intact\n const basePart =\n Math.floor(Number(weiDecimalValue) / multiplier) * multiplier;\n\n // Generate random digits\n const randomDigits = Math.floor(Math.random() * multiplier);\n\n // Combine base and random parts\n const randomisedWeiDecimal = basePart + randomDigits;\n\n // Convert wei decimal to hex\n return `0x${randomisedWeiDecimal.toString(16)}` as Hex;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gweiDecimalToWeiHex = exports.updateGasFees = void 0;
3
+ exports.gweiDecimalToWeiDecimal = exports.gweiDecimalToWeiHex = exports.updateGasFees = void 0;
4
4
  const controller_utils_1 = require("@metamask/controller-utils");
5
5
  const utils_1 = require("@metamask/utils");
6
6
  const gas_flow_1 = require("./gas-flow.cjs");
@@ -58,6 +58,23 @@ function gweiDecimalToWeiHex(value) {
58
58
  return (0, controller_utils_1.toHex)((0, controller_utils_1.gweiDecToWEIBN)(value));
59
59
  }
60
60
  exports.gweiDecimalToWeiHex = gweiDecimalToWeiHex;
61
+ /**
62
+ * Converts a value from Gwei decimal representation to Wei decimal representation
63
+ *
64
+ * @param gweiDecimal - The value in Gwei as a string or number
65
+ * @returns The value in Wei as a string
66
+ *
67
+ * @example
68
+ * // Convert 1.5 Gwei to Wei
69
+ * gweiDecimalToWeiDecimal("1.5")
70
+ * // Returns "1500000000"
71
+ */
72
+ function gweiDecimalToWeiDecimal(gweiDecimal) {
73
+ const gwei = typeof gweiDecimal === 'string' ? gweiDecimal : gweiDecimal.toString();
74
+ const weiDecimal = Number(gwei) * 1e9;
75
+ return weiDecimal.toString();
76
+ }
77
+ exports.gweiDecimalToWeiDecimal = gweiDecimalToWeiDecimal;
61
78
  /**
62
79
  * Determine the maxFeePerGas value for the transaction.
63
80
  *
@@ -1 +1 @@
1
- {"version":3,"file":"gas-fees.cjs","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 type { TransactionControllerFeatureFlags } from './feature-flags';\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\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 featureFlags: TransactionControllerFeatureFlags;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\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 * 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 (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 featureFlags,\n gasFeeFlows,\n getGasFeeEstimates,\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 featureFlags,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n featureFlags,\n gasFeeControllerData,\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.cjs","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":";;;AAAA,iEAKoC;AAOpC,2CAA4D;AAG5D,6CAA2C;AAC3C,uCAAiD;AACjD,0CAA0C;AAQ1C,wCAA4D;AA0B5D,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAAC,sBAAa,EAAE,UAAU,CAAC,CAAC;AAE1D;;;;GAIG;AACI,KAAK,UAAU,aAAa,CAAC,OAA6B;IAC/D,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC3B,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAE7C,MAAM,MAAM,GAAG,8BAAsB,CAAC,QAAQ,CAC5C,MAAM,CAAC,IAAuB,CAC/B,CAAC;IACF,MAAM,YAAY,GAAG,MAAM;QACzB,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE5C,MAAM,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE5D,GAAG,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC;IAE5C,MAAM,gBAAgB,GAAqB;QACzC,GAAG,OAAO;QACV,aAAa;QACb,YAAY;QACZ,gBAAgB;KACjB,CAAC;IAEF,MAAM,CAAC,QAAQ,CAAC,YAAY,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAEjE,MAAM,CAAC,QAAQ,CAAC,oBAAoB;QAClC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;IAE5C,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,CAAC,YAAY,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAExD,GAAG,CAAC,4BAA4B,EAAE;QAChC,YAAY,EAAE,MAAM,CAAC,QAAQ,CAAC,YAAY;QAC1C,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,oBAAoB;QAC1D,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;KACnC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,IAAI,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE;QACxE,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;KACjC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;QACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC;KAC7C;IAED,yBAAyB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AA9CD,sCA8CC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,KAAa;IAC/C,OAAO,IAAA,wBAAK,EAAC,IAAA,iCAAc,EAAC,KAAK,CAAC,CAAC,CAAC;AACtC,CAAC;AAFD,kDAEC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,uBAAuB,CAAC,WAA4B;IAClE,MAAM,IAAI,GACR,OAAO,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;IAEzE,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IAEtC,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC;AAC/B,CAAC;AAPD,0DAOC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,OAAyB;IAChD,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAE3E,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,YAAY,EAAE;QAChB,MAAM,YAAY,GAAG,mBAAmB,CAAC,YAAY,CAAC,UAAoB,CAAC,CAAC;QAC5E,GAAG,CAAC,sCAAsC,EAAE,YAAY,CAAC,CAAC;QAC1D,OAAO,YAAY,CAAC;KACrB;IAED,IAAI,aAAa,CAAC,YAAY,EAAE;QAC9B,GAAG,CAAC,iCAAiC,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;QACnE,OAAO,aAAa,CAAC,YAAY,CAAC;KACnC;IAED,IAAI,aAAa,CAAC,QAAQ,IAAI,CAAC,aAAa,CAAC,oBAAoB,EAAE;QACjE,GAAG,CACD,+CAA+C,EAC/C,aAAa,CAAC,QAAQ,CACvB,CAAC;QACF,OAAO,aAAa,CAAC,QAAQ,CAAC;KAC/B;IAED,IAAI,gBAAgB,CAAC,YAAY,EAAE;QACjC,GAAG,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACnE,OAAO,gBAAgB,CAAC,YAAY,CAAC;KACtC;IAED,IAAI,gBAAgB,CAAC,QAAQ,EAAE;QAC7B,GAAG,CACD,4CAA4C,EAC5C,gBAAgB,CAAC,QAAQ,CAC1B,CAAC;QACF,OAAO,gBAAgB,CAAC,QAAQ,CAAC;KAClC;IAED,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC5B,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,uBAAuB,CAC9B,OAAyB;IAEzB,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,EAAE,GACtE,OAAO,CAAC;IAEV,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,YAAY,EAAE;QAChB,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC3E,GAAG,CACD,0DAA0D,EAC1D,oBAAoB,CACrB,CAAC;QACF,OAAO,oBAAoB,CAAC;KAC7B;IAED,IAAI,aAAa,CAAC,oBAAoB,EAAE;QACtC,GAAG,CACD,yCAAyC,EACzC,aAAa,CAAC,oBAAoB,CACnC,CAAC;QACF,OAAO,aAAa,CAAC,oBAAoB,CAAC;KAC3C;IAED,IAAI,aAAa,CAAC,QAAQ,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE;QACzD,GAAG,CACD,uDAAuD,EACvD,aAAa,CAAC,QAAQ,CACvB,CAAC;QACF,OAAO,aAAa,CAAC,QAAQ,CAAC;KAC/B;IAED,IAAI,gBAAgB,CAAC,oBAAoB,EAAE;QACzC,GAAG,CACD,sCAAsC,EACtC,gBAAgB,CAAC,oBAAoB,CACtC,CAAC;QACF,OAAO,gBAAgB,CAAC,oBAAoB,CAAC;KAC9C;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE;QAChC,GAAG,CACD,8CAA8C,EAC9C,MAAM,CAAC,QAAQ,CAAC,YAAY,CAC7B,CAAC;QACF,OAAO,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;KACrC;IAED,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACpC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,OAAyB;IAC5C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAE7D,IAAI,OAAO,EAAE;QACX,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,aAAa,CAAC,QAAQ,EAAE;QAC1B,GAAG,CAAC,6BAA6B,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,aAAa,CAAC,QAAQ,CAAC;KAC/B;IAED,IAAI,gBAAgB,CAAC,YAAY,EAAE;QACjC,GAAG,CAAC,8BAA8B,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QACnE,OAAO,gBAAgB,CAAC,YAAY,CAAC;KACtC;IAED,IAAI,gBAAgB,CAAC,QAAQ,EAAE;QAC7B,GAAG,CAAC,0BAA0B,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,gBAAgB,CAAC,QAAQ,CAAC;KAClC;IAED,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACxB,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,OAAyB;IAChD,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,EAAE,GACtE,OAAO,CAAC;IAEV,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,YAAY,EAAE;QAChB,OAAO,oBAAY,CAAC,MAAM,CAAC;KAC5B;IAED,IACE,CAAC,aAAa,CAAC,YAAY;QAC3B,CAAC,aAAa,CAAC,oBAAoB;QACnC,aAAa,CAAC,QAAQ,EACtB;QACA,OAAO,MAAM,CAAC,MAAM,KAAK,kCAAe;YACtC,CAAC,CAAC,oBAAY,CAAC,MAAM;YACrB,CAAC,CAAC,oBAAY,CAAC,cAAc,CAAC;KACjC;IAED,IACE,CAAC,aAAa,CAAC,YAAY;QAC3B,CAAC,aAAa,CAAC,oBAAoB;QACnC,gBAAgB,CAAC,YAAY;QAC7B,gBAAgB,CAAC,oBAAoB,EACrC;QACA,OAAO,oBAAY,CAAC,MAAM,CAAC;KAC5B;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,kCAAe,EAAE;QACrC,OAAO,oBAAY,CAAC,MAAM,CAAC;KAC5B;IAED,OAAO,oBAAY,CAAC,cAAc,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAS,yBAAyB,CAAC,MAAuB;IACxD,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE;QAC/B,MAAM,CAAC,mBAAmB,GAAG,EAAE,CAAC;KACjC;IAED,MAAM,CAAC,mBAAmB,CAAC,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;IAEvE,MAAM,CAAC,mBAAmB,CAAC,oBAAoB;QAC7C,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAEvC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC/D,MAAM,CAAC,mBAAmB,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,mBAAmB,CAChC,OAA6B;IAE7B,MAAM,EACJ,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,GAAG,OAAO,CAAC;IAEZ,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC;IAEnC,IACE,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACtC,CAAC,OAAO;YACN,MAAM,CAAC,QAAQ,CAAC,YAAY;YAC5B,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EACvC;QACA,OAAO,EAAE,CAAC;KACX;IAED,MAAM,UAAU,GAAG,IAAA,wBAAa,EAC9B,MAAM,EACN,WAAW,EACX,YAAY,CACC,CAAC;IAEhB,IAAI;QACF,MAAM,oBAAoB,GAAG,MAAM,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;QAE3E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC;YAC3C,QAAQ;YACR,YAAY;YACZ,oBAAoB;YACpB,eAAe,EAAE,MAAM;SACxB,CAAC,CAAC;QAEH,MAAM,kBAAkB,GAAG,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;QAEpD,QAAQ,kBAAkB,EAAE;YAC1B,KAAK,0BAAkB,CAAC,SAAS;gBAC/B,OAAO,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC;YACnC,KAAK,0BAAkB,CAAC,MAAM;gBAC5B,OAAO;oBACL,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM;iBACpC,CAAC;YACJ,KAAK,0BAAkB,CAAC,QAAQ;gBAC9B,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACnD;gBACE,MAAM,IAAI,KAAK;gBACb,gFAAgF;gBAChF,4EAA4E;gBAC5E,yDAAyD,kBAAkB,EAAE,CAC9E,CAAC;SACL;KACF;IAAC,OAAO,KAAK,EAAE;QACd,GAAG,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;KAChD;IAED,MAAM,eAAe,GAAG,CAAC,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAW,CAAC;IAEtE,MAAM,QAAQ,GAAG,eAAe;QAC9B,CAAC,CAAC,IAAA,aAAK,EAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC","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 type { TransactionControllerFeatureFlags } from './feature-flags';\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\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 featureFlags: TransactionControllerFeatureFlags;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\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 : gweiDecimal.toString();\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 (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 featureFlags,\n gasFeeFlows,\n getGasFeeEstimates,\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 featureFlags,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n featureFlags,\n gasFeeControllerData,\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"]}
@@ -35,5 +35,17 @@ export declare function updateGasFees(request: UpdateGasFeesRequest): Promise<vo
35
35
  * @returns The WEI value in hex.
36
36
  */
37
37
  export declare function gweiDecimalToWeiHex(value: string): `0x${string}`;
38
+ /**
39
+ * Converts a value from Gwei decimal representation to Wei decimal representation
40
+ *
41
+ * @param gweiDecimal - The value in Gwei as a string or number
42
+ * @returns The value in Wei as a string
43
+ *
44
+ * @example
45
+ * // Convert 1.5 Gwei to Wei
46
+ * gweiDecimalToWeiDecimal("1.5")
47
+ * // Returns "1500000000"
48
+ */
49
+ export declare function gweiDecimalToWeiDecimal(gweiDecimal: string | number): string;
38
50
  export {};
39
51
  //# sourceMappingURL=gas-fees.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gas-fees.d.cts","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,4BAAwB;AAIzE,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAEf,UAAU,EACX,qBAAiB;AAGlB,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,iCAAiC,CAAC;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kBAAkB,EAAE,CAClB,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,YAAY,GAAG,SAAS,CAAC;IAC5D,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG;IACpD,aAAa,EAAE,iBAAiB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,iBA8ChE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAEhD"}
1
+ {"version":3,"file":"gas-fees.d.cts","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,4BAAwB;AAIzE,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAEf,UAAU,EACX,qBAAiB;AAGlB,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,iCAAiC,CAAC;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kBAAkB,EAAE,CAClB,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,YAAY,GAAG,SAAS,CAAC;IAC5D,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG;IACpD,aAAa,EAAE,iBAAiB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,iBA8ChE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAEhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAO5E"}
@@ -35,5 +35,17 @@ export declare function updateGasFees(request: UpdateGasFeesRequest): Promise<vo
35
35
  * @returns The WEI value in hex.
36
36
  */
37
37
  export declare function gweiDecimalToWeiHex(value: string): `0x${string}`;
38
+ /**
39
+ * Converts a value from Gwei decimal representation to Wei decimal representation
40
+ *
41
+ * @param gweiDecimal - The value in Gwei as a string or number
42
+ * @returns The value in Wei as a string
43
+ *
44
+ * @example
45
+ * // Convert 1.5 Gwei to Wei
46
+ * gweiDecimalToWeiDecimal("1.5")
47
+ * // Returns "1500000000"
48
+ */
49
+ export declare function gweiDecimalToWeiDecimal(gweiDecimal: string | number): string;
38
50
  export {};
39
51
  //# sourceMappingURL=gas-fees.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gas-fees.d.mts","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,4BAAwB;AAIzE,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAEf,UAAU,EACX,qBAAiB;AAGlB,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,iCAAiC,CAAC;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kBAAkB,EAAE,CAClB,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,YAAY,GAAG,SAAS,CAAC;IAC5D,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG;IACpD,aAAa,EAAE,iBAAiB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,iBA8ChE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAEhD"}
1
+ {"version":3,"file":"gas-fees.d.mts","sourceRoot":"","sources":["../../src/utils/gas-fees.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,4BAA4B;AAChD,OAAO,KAAK,EACV,0BAA0B,EAC1B,WAAW,EACZ,qCAAqC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,iCAAiC,EAAE,4BAAwB;AAIzE,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,eAAe,EAEf,UAAU,EACX,qBAAiB;AAGlB,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,iCAAiC,CAAC;IAChD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kBAAkB,EAAE,CAClB,OAAO,EAAE,0BAA0B,KAChC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,eAAe,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,YAAY,GAAG,SAAS,CAAC;IAC5D,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG;IACpD,aAAa,EAAE,iBAAiB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gBAAgB,EAAE,gBAAgB,CAAC;CACpC,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,iBA8ChE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAEhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAO5E"}
@@ -53,6 +53,22 @@ export async function updateGasFees(request) {
53
53
  export function gweiDecimalToWeiHex(value) {
54
54
  return toHex(gweiDecToWEIBN(value));
55
55
  }
56
+ /**
57
+ * Converts a value from Gwei decimal representation to Wei decimal representation
58
+ *
59
+ * @param gweiDecimal - The value in Gwei as a string or number
60
+ * @returns The value in Wei as a string
61
+ *
62
+ * @example
63
+ * // Convert 1.5 Gwei to Wei
64
+ * gweiDecimalToWeiDecimal("1.5")
65
+ * // Returns "1500000000"
66
+ */
67
+ export function gweiDecimalToWeiDecimal(gweiDecimal) {
68
+ const gwei = typeof gweiDecimal === 'string' ? gweiDecimal : gweiDecimal.toString();
69
+ const weiDecimal = Number(gwei) * 1e9;
70
+ return weiDecimal.toString();
71
+ }
56
72
  /**
57
73
  * Determine the maxFeePerGas value for the transaction.
58
74
  *
@@ -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 type { TransactionControllerFeatureFlags } from './feature-flags';\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\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 featureFlags: TransactionControllerFeatureFlags;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\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 * 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 (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 featureFlags,\n gasFeeFlows,\n getGasFeeEstimates,\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 featureFlags,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n featureFlags,\n gasFeeControllerData,\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 type { TransactionControllerFeatureFlags } from './feature-flags';\nimport { getGasFeeFlow } from './gas-flow';\nimport { SWAP_TRANSACTION_TYPES } from './swaps';\nimport { projectLogger } from '../logger';\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 featureFlags: TransactionControllerFeatureFlags;\n gasFeeFlows: GasFeeFlow[];\n getGasFeeEstimates: (\n options: FetchGasFeeEstimateOptions,\n ) => Promise<GasFeeState>;\n getSavedGasFees: (chainId: Hex) => SavedGasFees | undefined;\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 : gweiDecimal.toString();\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 (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 featureFlags,\n gasFeeFlows,\n getGasFeeEstimates,\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 featureFlags,\n ) as GasFeeFlow;\n\n try {\n const gasFeeControllerData = await getGasFeeEstimates({ networkClientId });\n\n const response = await gasFeeFlow.getGasFees({\n ethQuery,\n featureFlags,\n gasFeeControllerData,\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/transaction-controller",
3
- "version": "51.0.0-preview-29fe07c",
3
+ "version": "51.0.0-preview-8abae216",
4
4
  "description": "Stores transactions alongside their periodically updated statuses and manages interactions such as approval and cancellation",
5
5
  "keywords": [
6
6
  "MetaMask",