@metamask-previews/transaction-controller 52.0.0-preview-5a3453d → 52.0.0-preview-e7013a54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +0 -5
  2. package/dist/TransactionController.cjs +2 -13
  3. package/dist/TransactionController.cjs.map +1 -1
  4. package/dist/TransactionController.d.cts.map +1 -1
  5. package/dist/TransactionController.d.mts.map +1 -1
  6. package/dist/TransactionController.mjs +2 -13
  7. package/dist/TransactionController.mjs.map +1 -1
  8. package/dist/gas-flows/DefaultGasFeeFlow.cjs +3 -1
  9. package/dist/gas-flows/DefaultGasFeeFlow.cjs.map +1 -1
  10. package/dist/gas-flows/DefaultGasFeeFlow.d.cts +2 -2
  11. package/dist/gas-flows/DefaultGasFeeFlow.d.cts.map +1 -1
  12. package/dist/gas-flows/DefaultGasFeeFlow.d.mts +2 -2
  13. package/dist/gas-flows/DefaultGasFeeFlow.d.mts.map +1 -1
  14. package/dist/gas-flows/DefaultGasFeeFlow.mjs +3 -1
  15. package/dist/gas-flows/DefaultGasFeeFlow.mjs.map +1 -1
  16. package/dist/gas-flows/LineaGasFeeFlow.cjs +1 -1
  17. package/dist/gas-flows/LineaGasFeeFlow.cjs.map +1 -1
  18. package/dist/gas-flows/LineaGasFeeFlow.d.cts +1 -5
  19. package/dist/gas-flows/LineaGasFeeFlow.d.cts.map +1 -1
  20. package/dist/gas-flows/LineaGasFeeFlow.d.mts +1 -5
  21. package/dist/gas-flows/LineaGasFeeFlow.d.mts.map +1 -1
  22. package/dist/gas-flows/LineaGasFeeFlow.mjs +1 -1
  23. package/dist/gas-flows/LineaGasFeeFlow.mjs.map +1 -1
  24. package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs +1 -1
  25. package/dist/gas-flows/OptimismLayer1GasFeeFlow.cjs.map +1 -1
  26. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts +1 -5
  27. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.cts.map +1 -1
  28. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts +1 -5
  29. package/dist/gas-flows/OptimismLayer1GasFeeFlow.d.mts.map +1 -1
  30. package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs +1 -1
  31. package/dist/gas-flows/OptimismLayer1GasFeeFlow.mjs.map +1 -1
  32. package/dist/gas-flows/OracleLayer1GasFeeFlow.cjs.map +1 -1
  33. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts +1 -5
  34. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.cts.map +1 -1
  35. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts +1 -5
  36. package/dist/gas-flows/OracleLayer1GasFeeFlow.d.mts.map +1 -1
  37. package/dist/gas-flows/OracleLayer1GasFeeFlow.mjs.map +1 -1
  38. package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs +1 -1
  39. package/dist/gas-flows/ScrollLayer1GasFeeFlow.cjs.map +1 -1
  40. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.cts +1 -5
  41. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.cts.map +1 -1
  42. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts +1 -5
  43. package/dist/gas-flows/ScrollLayer1GasFeeFlow.d.mts.map +1 -1
  44. package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs +1 -1
  45. package/dist/gas-flows/ScrollLayer1GasFeeFlow.mjs.map +1 -1
  46. package/dist/gas-flows/TestGasFeeFlow.cjs +1 -1
  47. package/dist/gas-flows/TestGasFeeFlow.cjs.map +1 -1
  48. package/dist/gas-flows/TestGasFeeFlow.d.cts +2 -2
  49. package/dist/gas-flows/TestGasFeeFlow.d.cts.map +1 -1
  50. package/dist/gas-flows/TestGasFeeFlow.d.mts +2 -2
  51. package/dist/gas-flows/TestGasFeeFlow.d.mts.map +1 -1
  52. package/dist/gas-flows/TestGasFeeFlow.mjs +1 -1
  53. package/dist/gas-flows/TestGasFeeFlow.mjs.map +1 -1
  54. package/dist/helpers/GasFeePoller.cjs +4 -9
  55. package/dist/helpers/GasFeePoller.cjs.map +1 -1
  56. package/dist/helpers/GasFeePoller.d.cts +1 -4
  57. package/dist/helpers/GasFeePoller.d.cts.map +1 -1
  58. package/dist/helpers/GasFeePoller.d.mts +1 -4
  59. package/dist/helpers/GasFeePoller.d.mts.map +1 -1
  60. package/dist/helpers/GasFeePoller.mjs +4 -9
  61. package/dist/helpers/GasFeePoller.mjs.map +1 -1
  62. package/dist/types.cjs.map +1 -1
  63. package/dist/types.d.cts +3 -15
  64. package/dist/types.d.cts.map +1 -1
  65. package/dist/types.d.mts +3 -15
  66. package/dist/types.d.mts.map +1 -1
  67. package/dist/types.mjs.map +1 -1
  68. package/dist/utils/feature-flags.cjs +1 -14
  69. package/dist/utils/feature-flags.cjs.map +1 -1
  70. package/dist/utils/feature-flags.d.cts +0 -10
  71. package/dist/utils/feature-flags.d.cts.map +1 -1
  72. package/dist/utils/feature-flags.d.mts +0 -10
  73. package/dist/utils/feature-flags.d.mts.map +1 -1
  74. package/dist/utils/feature-flags.mjs +0 -12
  75. package/dist/utils/feature-flags.mjs.map +1 -1
  76. package/dist/utils/gas-fees.cjs +3 -21
  77. package/dist/utils/gas-fees.cjs.map +1 -1
  78. package/dist/utils/gas-fees.d.cts +0 -14
  79. package/dist/utils/gas-fees.d.cts.map +1 -1
  80. package/dist/utils/gas-fees.d.mts +0 -14
  81. package/dist/utils/gas-fees.d.mts.map +1 -1
  82. package/dist/utils/gas-fees.mjs +2 -19
  83. package/dist/utils/gas-fees.mjs.map +1 -1
  84. package/dist/utils/gas-flow.cjs +2 -3
  85. package/dist/utils/gas-flow.cjs.map +1 -1
  86. package/dist/utils/gas-flow.d.cts +1 -3
  87. package/dist/utils/gas-flow.d.cts.map +1 -1
  88. package/dist/utils/gas-flow.d.mts +1 -3
  89. package/dist/utils/gas-flow.d.mts.map +1 -1
  90. package/dist/utils/gas-flow.mjs +2 -3
  91. package/dist/utils/gas-flow.mjs.map +1 -1
  92. package/dist/utils/layer1-gas-fee-flow.cjs +4 -9
  93. package/dist/utils/layer1-gas-fee-flow.cjs.map +1 -1
  94. package/dist/utils/layer1-gas-fee-flow.d.cts +1 -4
  95. package/dist/utils/layer1-gas-fee-flow.d.cts.map +1 -1
  96. package/dist/utils/layer1-gas-fee-flow.d.mts +1 -4
  97. package/dist/utils/layer1-gas-fee-flow.d.mts.map +1 -1
  98. package/dist/utils/layer1-gas-fee-flow.mjs +4 -9
  99. package/dist/utils/layer1-gas-fee-flow.mjs.map +1 -1
  100. package/package.json +2 -2
  101. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.cjs +0 -145
  102. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.cjs.map +0 -1
  103. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.d.cts +0 -27
  104. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.d.cts.map +0 -1
  105. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.d.mts +0 -27
  106. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.d.mts.map +0 -1
  107. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.mjs +0 -140
  108. package/dist/gas-flows/RandomisedEstimationsGasFeeFlow.mjs.map +0 -1
@@ -1,145 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
- var _RandomisedEstimationsGasFeeFlow_instances, _RandomisedEstimationsGasFeeFlow_getDefaultGasFees, _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees, _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate;
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.randomiseDecimalGWEIAndConvertToHex = exports.RandomisedEstimationsGasFeeFlow = void 0;
10
- const gas_fee_controller_1 = require("@metamask/gas-fee-controller");
11
- const utils_1 = require("@metamask/utils");
12
- const DefaultGasFeeFlow_1 = require("./DefaultGasFeeFlow.cjs");
13
- const logger_1 = require("../logger.cjs");
14
- const types_1 = require("../types.cjs");
15
- const feature_flags_1 = require("../utils/feature-flags.cjs");
16
- const gas_fees_1 = require("../utils/gas-fees.cjs");
17
- const log = (0, utils_1.createModuleLogger)(logger_1.projectLogger, 'randomised-estimation-gas-fee-flow');
18
- const PRESERVE_NUMBER_OF_DIGITS = 2;
19
- /**
20
- * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
21
- */
22
- class RandomisedEstimationsGasFeeFlow {
23
- constructor() {
24
- _RandomisedEstimationsGasFeeFlow_instances.add(this);
25
- }
26
- matchesTransaction({ transactionMeta, messenger, }) {
27
- const { chainId } = transactionMeta;
28
- const randomisedGasFeeDigits = (0, feature_flags_1.getRandomisedGasFeeDigits)(chainId, messenger);
29
- return randomisedGasFeeDigits !== undefined;
30
- }
31
- async getGasFees(request) {
32
- try {
33
- return await __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees).call(this, request);
34
- }
35
- catch (error) {
36
- log('Using default flow as fallback due to error', error);
37
- return await __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getDefaultGasFees).call(this, request);
38
- }
39
- }
40
- }
41
- exports.RandomisedEstimationsGasFeeFlow = RandomisedEstimationsGasFeeFlow;
42
- _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimationsGasFeeFlow_getDefaultGasFees = async function _RandomisedEstimationsGasFeeFlow_getDefaultGasFees(request) {
43
- return new DefaultGasFeeFlow_1.DefaultGasFeeFlow().getGasFees(request);
44
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees = async function _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees(request) {
45
- const { messenger, gasFeeControllerData, transactionMeta } = request;
46
- const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;
47
- const randomisedGasFeeDigits = (0, feature_flags_1.getRandomisedGasFeeDigits)(transactionMeta.chainId, messenger);
48
- let response;
49
- if (gasEstimateType === gas_fee_controller_1.GAS_ESTIMATE_TYPES.FEE_MARKET) {
50
- log('Using fee market estimates', gasFeeEstimates);
51
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates).call(this, gasFeeEstimates, randomisedGasFeeDigits);
52
- log('Randomised fee market estimates', response);
53
- }
54
- else if (gasEstimateType === gas_fee_controller_1.GAS_ESTIMATE_TYPES.LEGACY) {
55
- log('Using legacy estimates', gasFeeEstimates);
56
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates).call(this, gasFeeEstimates, randomisedGasFeeDigits);
57
- log('Randomised legacy estimates', response);
58
- }
59
- else if (gasEstimateType === gas_fee_controller_1.GAS_ESTIMATE_TYPES.ETH_GASPRICE) {
60
- log('Using eth_gasPrice estimates', gasFeeEstimates);
61
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate).call(this, gasFeeEstimates, randomisedGasFeeDigits);
62
- log('Randomised eth_gasPrice estimates', response);
63
- }
64
- else {
65
- throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);
66
- }
67
- return {
68
- estimates: response,
69
- };
70
- }, _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates(gasFeeEstimates, lastNDigits) {
71
- const levels = Object.values(types_1.GasFeeEstimateLevel).reduce((result, level) => ({
72
- ...result,
73
- [level]: __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel).call(this, gasFeeEstimates, level, lastNDigits),
74
- }), {});
75
- return {
76
- type: types_1.GasFeeEstimateType.FeeMarket,
77
- ...levels,
78
- };
79
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel(gasFeeEstimates, level, lastNDigits) {
80
- return {
81
- maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
82
- maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
83
- };
84
- }, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates(gasFeeEstimates, lastNDigits) {
85
- const levels = Object.values(types_1.GasFeeEstimateLevel).reduce((result, level) => ({
86
- ...result,
87
- [level]: __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel).call(this, gasFeeEstimates, level, lastNDigits),
88
- }), {});
89
- return {
90
- type: types_1.GasFeeEstimateType.Legacy,
91
- ...levels,
92
- };
93
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel(gasFeeEstimates, level, lastNDigits) {
94
- return randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level], lastNDigits);
95
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate = function _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate(gasFeeEstimates, lastNDigits) {
96
- return {
97
- type: types_1.GasFeeEstimateType.GasPrice,
98
- gasPrice: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
99
- };
100
- };
101
- /**
102
- * Generates a random number with the specified number of digits that is greater than or equal to the given minimum value.
103
- *
104
- * @param digitCount - The number of digits the random number should have
105
- * @param minValue - The minimum value the random number should have
106
- * @returns A random number with the specified number of digits
107
- */
108
- function generateRandomDigits(digitCount, minValue) {
109
- const multiplier = 10 ** digitCount;
110
- return minValue + Math.floor(Math.random() * (multiplier - minValue));
111
- }
112
- /**
113
- * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
114
- *
115
- * This function preserves the more significant digits while randomizing only the least significant ones,
116
- * ensuring that fees remain close to the original estimation while providing randomisation.
117
- * The randomisation is performed in Wei units for more precision.
118
- *
119
- * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
120
- * @param [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise
121
- * @returns The randomised value converted to Wei in hexadecimal format
122
- */
123
- function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue, numberOfDigitsToRandomizeAtTheEnd) {
124
- const weiDecimalValue = (0, gas_fees_1.gweiDecimalToWeiDecimal)(gweiDecimalValue);
125
- const decimalLength = weiDecimalValue.length;
126
- // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS
127
- const effectiveDigitsToRandomise = Math.min(numberOfDigitsToRandomizeAtTheEnd, decimalLength - PRESERVE_NUMBER_OF_DIGITS);
128
- // Handle the case when the value is 0 or too small
129
- if (Number(weiDecimalValue) === 0 || effectiveDigitsToRandomise <= 0) {
130
- return `0x${Number(weiDecimalValue).toString(16)}`;
131
- }
132
- // Use string manipulation to get the base part (significant digits)
133
- const significantDigitsCount = decimalLength - effectiveDigitsToRandomise;
134
- const significantDigits = weiDecimalValue.slice(0, significantDigitsCount);
135
- // Get the original ending digits using string manipulation
136
- const endingDigits = weiDecimalValue.slice(-effectiveDigitsToRandomise);
137
- const originalEndingDigits = Number(endingDigits);
138
- // Generate random digits that are greater than or equal to the original ending digits
139
- const randomEndingDigits = generateRandomDigits(effectiveDigitsToRandomise, originalEndingDigits);
140
- const basePart = BigInt(significantDigits + '0'.repeat(effectiveDigitsToRandomise));
141
- const randomisedWeiDecimal = basePart + BigInt(randomEndingDigits);
142
- return `0x${randomisedWeiDecimal.toString(16)}`;
143
- }
144
- exports.randomiseDecimalGWEIAndConvertToHex = randomiseDecimalGWEIAndConvertToHex;
145
- //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RandomisedEstimationsGasFeeFlow.cjs","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":";;;;;;;;;AAKA,qEAAkE;AAClE,2CAA+D;AAE/D,+DAAwD;AACxD,0CAA0C;AAa1C,wCAAmE;AACnE,8DAAmE;AACnE,oDAA4D;AAE5D,MAAM,GAAG,GAAG,IAAA,0BAAkB,EAC5B,sBAAa,EACb,oCAAoC,CACrC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAEpC;;GAEG;AACH,MAAa,+BAA+B;IAA5C;;IAgKA,CAAC;IA/JC,kBAAkB,CAAC,EACjB,eAAe,EACf,SAAS,GAIV;QACC,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;QAEpC,MAAM,sBAAsB,GAAG,IAAA,yCAAyB,EACtD,OAAO,EACP,SAAS,CACV,CAAC;QAEF,OAAO,sBAAsB,KAAK,SAAS,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA0B;QACzC,IAAI;YACF,OAAO,MAAM,uBAAA,IAAI,yGAAsB,MAA1B,IAAI,EAAuB,OAAO,CAAC,CAAC;SAClD;QAAC,OAAO,KAAK,EAAE;YACd,GAAG,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;YAC1D,OAAO,MAAM,uBAAA,IAAI,sGAAmB,MAAvB,IAAI,EAAoB,OAAO,CAAC,CAAC;SAC/C;IACH,CAAC;CAuIF;AAhKD,0EAgKC;iHArIC,KAAK,6DACH,OAA0B;IAE1B,OAAO,IAAI,qCAAiB,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACrD,CAAC,0DAED,KAAK,gEACH,OAA0B;IAE1B,MAAM,EAAE,SAAS,EAAE,oBAAoB,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IACrE,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAAC;IAElE,MAAM,sBAAsB,GAAG,IAAA,yCAAyB,EACtD,eAAe,CAAC,OAAO,EACvB,SAAS,CACA,CAAC;IAEZ,IAAI,QAAyB,CAAC;IAE9B,IAAI,eAAe,KAAK,uCAAkB,CAAC,UAAU,EAAE;QACrD,GAAG,CAAC,4BAA4B,EAAE,eAAe,CAAC,CAAC;QACnD,QAAQ,GAAG,uBAAA,IAAI,gHAA6B,MAAjC,IAAI,EACb,eAAe,EACf,sBAAsB,CACvB,CAAC;QACF,GAAG,CAAC,iCAAiC,EAAE,QAAQ,CAAC,CAAC;KAClD;SAAM,IAAI,eAAe,KAAK,uCAAkB,CAAC,MAAM,EAAE;QACxD,GAAG,CAAC,wBAAwB,EAAE,eAAe,CAAC,CAAC;QAC/C,QAAQ,GAAG,uBAAA,IAAI,6GAA0B,MAA9B,IAAI,EACb,eAAe,EACf,sBAAsB,CACvB,CAAC;QACF,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;KAC9C;SAAM,IAAI,eAAe,KAAK,uCAAkB,CAAC,YAAY,EAAE;QAC9D,GAAG,CAAC,8BAA8B,EAAE,eAAe,CAAC,CAAC;QACrD,QAAQ,GAAG,uBAAA,IAAI,kHAA+B,MAAnC,IAAI,EACb,eAAe,EACf,sBAAsB,CACvB,CAAC;QACF,GAAG,CAAC,mCAAmC,EAAE,QAAQ,CAAC,CAAC;KACpD;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,kCAAkC,eAAe,EAAE,CAAC,CAAC;KACtE;IAED,OAAO;QACL,SAAS,EAAE,QAAQ;KACpB,CAAC;AACJ,CAAC,uIAGC,eAA0C,EAC1C,WAAmB;IAEnB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,2BAAmB,CAAC,CAAC,MAAM,CACtD,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAClB,GAAG,MAAM;QACT,CAAC,KAAK,CAAC,EAAE,uBAAA,IAAI,gHAA6B,MAAjC,IAAI,EACX,eAAe,EACf,KAAK,EACL,WAAW,CACZ;KACF,CAAC,EACF,EAA4C,CAC7C,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,0BAAkB,CAAC,SAAS;QAClC,GAAG,MAAM;KACV,CAAC;AACJ,CAAC,uIAGC,eAA0C,EAC1C,KAA0B,EAC1B,WAAmB;IAEnB,OAAO;QACL,YAAY,EAAE,mCAAmC,CAC/C,eAAe,CAAC,KAAK,CAAC,CAAC,qBAAqB,EAC5C,WAAW,CACZ;QACD,oBAAoB,EAAE,mCAAmC,CACvD,eAAe,CAAC,KAAK,CAAC,CAAC,6BAA6B,EACpD,WAAW,CACZ;KACF,CAAC;AACJ,CAAC,iIAGC,eAAuC,EACvC,WAAmB;IAEnB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,2BAAmB,CAAC,CAAC,MAAM,CACtD,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAClB,GAAG,MAAM;QACT,CAAC,KAAK,CAAC,EAAE,uBAAA,IAAI,6GAA0B,MAA9B,IAAI,EACX,eAAe,EACf,KAAK,EACL,WAAW,CACZ;KACF,CAAC,EACF,EAAyC,CAC1C,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,0BAAkB,CAAC,MAAM;QAC/B,GAAG,MAAM;KACV,CAAC;AACJ,CAAC,iIAGC,eAAuC,EACvC,KAA0B,EAC1B,WAAmB;IAEnB,OAAO,mCAAmC,CACxC,eAAe,CAAC,KAAK,CAAC,EACtB,WAAW,CACZ,CAAC;AACJ,CAAC,2IAGC,eAAoC,EACpC,WAAmB;IAEnB,OAAO;QACL,IAAI,EAAE,0BAAkB,CAAC,QAAQ;QACjC,QAAQ,EAAE,mCAAmC,CAC3C,eAAe,CAAC,QAAQ,EACxB,WAAW,CACZ;KACF,CAAC;AACJ,CAAC;AAGH;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,UAAkB,EAAE,QAAgB;IAChE,MAAM,UAAU,GAAG,EAAE,IAAI,UAAU,CAAC;IACpC,OAAO,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,mCAAmC,CACjD,gBAAiC,EACjC,iCAAyC;IAEzC,MAAM,eAAe,GAAG,IAAA,kCAAuB,EAAC,gBAAgB,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC;IAE7C,wFAAwF;IACxF,MAAM,0BAA0B,GAAG,IAAI,CAAC,GAAG,CACzC,iCAAiC,EACjC,aAAa,GAAG,yBAAyB,CAC1C,CAAC;IAEF,mDAAmD;IACnD,IAAI,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,0BAA0B,IAAI,CAAC,EAAE;QACpE,OAAO,KAAK,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAS,CAAC;KAC3D;IAED,oEAAoE;IACpE,MAAM,sBAAsB,GAAG,aAAa,GAAG,0BAA0B,CAAC;IAC1E,MAAM,iBAAiB,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAE3E,2DAA2D;IAC3D,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,0BAA0B,CAAC,CAAC;IACxE,MAAM,oBAAoB,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;IAElD,sFAAsF;IACtF,MAAM,kBAAkB,GAAG,oBAAoB,CAC7C,0BAA0B,EAC1B,oBAAoB,CACrB,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,CACrB,iBAAiB,GAAG,GAAG,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAC3D,CAAC;IACF,MAAM,oBAAoB,GAAG,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAEnE,OAAO,KAAK,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAS,CAAC;AACzD,CAAC;AAtCD,kFAsCC","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 { TransactionControllerMessenger } from '../TransactionController';\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 { getRandomisedGasFeeDigits } 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;\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,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n const { chainId } = transactionMeta;\n\n const randomisedGasFeeDigits = getRandomisedGasFeeDigits(\n chainId,\n messenger,\n );\n\n return randomisedGasFeeDigits !== undefined;\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 { messenger, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomisedGasFeeDigits = getRandomisedGasFeeDigits(\n transactionMeta.chainId,\n messenger,\n ) as number;\n\n let response: GasFeeEstimates;\n\n if (gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET) {\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised fee market estimates', response);\n } else if (gasEstimateType === GAS_ESTIMATE_TYPES.LEGACY) {\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised legacy estimates', response);\n } else if (gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE) {\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n } else {\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 * Generates a random number with the specified number of digits that is greater than or equal to the given minimum value.\n *\n * @param digitCount - The number of digits the random number should have\n * @param minValue - The minimum value the random number should have\n * @returns A random number with the specified number of digits\n */\nfunction generateRandomDigits(digitCount: number, minValue: number): number {\n const multiplier = 10 ** digitCount;\n return minValue + Math.floor(Math.random() * (multiplier - minValue));\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 [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n */\nexport function randomiseDecimalGWEIAndConvertToHex(\n gweiDecimalValue: string | number,\n numberOfDigitsToRandomizeAtTheEnd: number,\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 numberOfDigitsToRandomizeAtTheEnd,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n // Handle the case when the value is 0 or too small\n if (Number(weiDecimalValue) === 0 || effectiveDigitsToRandomise <= 0) {\n return `0x${Number(weiDecimalValue).toString(16)}` as Hex;\n }\n\n // Use string manipulation to get the base part (significant digits)\n const significantDigitsCount = decimalLength - effectiveDigitsToRandomise;\n const significantDigits = weiDecimalValue.slice(0, significantDigitsCount);\n\n // Get the original ending digits using string manipulation\n const endingDigits = weiDecimalValue.slice(-effectiveDigitsToRandomise);\n const originalEndingDigits = Number(endingDigits);\n\n // Generate random digits that are greater than or equal to the original ending digits\n const randomEndingDigits = generateRandomDigits(\n effectiveDigitsToRandomise,\n originalEndingDigits,\n );\n\n const basePart = BigInt(\n significantDigits + '0'.repeat(effectiveDigitsToRandomise),\n );\n const randomisedWeiDecimal = basePart + BigInt(randomEndingDigits);\n\n return `0x${randomisedWeiDecimal.toString(16)}` as Hex;\n}\n"]}
@@ -1,27 +0,0 @@
1
- import { type Hex } from "@metamask/utils";
2
- import type { TransactionControllerMessenger } from "../TransactionController.cjs";
3
- import type { GasFeeFlow, GasFeeFlowRequest, GasFeeFlowResponse, TransactionMeta } from "../types.cjs";
4
- /**
5
- * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
6
- */
7
- export declare class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
8
- #private;
9
- matchesTransaction({ transactionMeta, messenger, }: {
10
- transactionMeta: TransactionMeta;
11
- messenger: TransactionControllerMessenger;
12
- }): boolean;
13
- getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse>;
14
- }
15
- /**
16
- * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
17
- *
18
- * This function preserves the more significant digits while randomizing only the least significant ones,
19
- * ensuring that fees remain close to the original estimation while providing randomisation.
20
- * The randomisation is performed in Wei units for more precision.
21
- *
22
- * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
23
- * @param [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise
24
- * @returns The randomised value converted to Wei in hexadecimal format
25
- */
26
- export declare function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue: string | number, numberOfDigitsToRandomizeAtTheEnd: number): Hex;
27
- //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RandomisedEstimationsGasFeeFlow.d.cts","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAI/D,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAIV,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAGlB,eAAe,EAChB,qBAAiB;AAYlB;;GAEG;AACH,qBAAa,+BAAgC,YAAW,UAAU;;IAChE,kBAAkB,CAAC,EACjB,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO;IAWL,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA8I1E;AAcD;;;;;;;;;;GAUG;AACH,wBAAgB,mCAAmC,CACjD,gBAAgB,EAAE,MAAM,GAAG,MAAM,EACjC,iCAAiC,EAAE,MAAM,GACxC,GAAG,CAmCL"}
@@ -1,27 +0,0 @@
1
- import { type Hex } from "@metamask/utils";
2
- import type { TransactionControllerMessenger } from "../TransactionController.mjs";
3
- import type { GasFeeFlow, GasFeeFlowRequest, GasFeeFlowResponse, TransactionMeta } from "../types.mjs";
4
- /**
5
- * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
6
- */
7
- export declare class RandomisedEstimationsGasFeeFlow implements GasFeeFlow {
8
- #private;
9
- matchesTransaction({ transactionMeta, messenger, }: {
10
- transactionMeta: TransactionMeta;
11
- messenger: TransactionControllerMessenger;
12
- }): boolean;
13
- getGasFees(request: GasFeeFlowRequest): Promise<GasFeeFlowResponse>;
14
- }
15
- /**
16
- * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
17
- *
18
- * This function preserves the more significant digits while randomizing only the least significant ones,
19
- * ensuring that fees remain close to the original estimation while providing randomisation.
20
- * The randomisation is performed in Wei units for more precision.
21
- *
22
- * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
23
- * @param [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise
24
- * @returns The randomised value converted to Wei in hexadecimal format
25
- */
26
- export declare function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue: string | number, numberOfDigitsToRandomizeAtTheEnd: number): Hex;
27
- //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RandomisedEstimationsGasFeeFlow.d.mts","sourceRoot":"","sources":["../../src/gas-flows/RandomisedEstimationsGasFeeFlow.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,GAAG,EAAE,wBAAwB;AAI/D,OAAO,KAAK,EAAE,8BAA8B,EAAE,qCAAiC;AAC/E,OAAO,KAAK,EAIV,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAGlB,eAAe,EAChB,qBAAiB;AAYlB;;GAEG;AACH,qBAAa,+BAAgC,YAAW,UAAU;;IAChE,kBAAkB,CAAC,EACjB,eAAe,EACf,SAAS,GACV,EAAE;QACD,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,8BAA8B,CAAC;KAC3C,GAAG,OAAO;IAWL,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA8I1E;AAcD;;;;;;;;;;GAUG;AACH,wBAAgB,mCAAmC,CACjD,gBAAgB,EAAE,MAAM,GAAG,MAAM,EACjC,iCAAiC,EAAE,MAAM,GACxC,GAAG,CAmCL"}
@@ -1,140 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _RandomisedEstimationsGasFeeFlow_instances, _RandomisedEstimationsGasFeeFlow_getDefaultGasFees, _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees, _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate;
7
- import { GAS_ESTIMATE_TYPES } from "@metamask/gas-fee-controller";
8
- import { createModuleLogger } from "@metamask/utils";
9
- import { DefaultGasFeeFlow } from "./DefaultGasFeeFlow.mjs";
10
- import { projectLogger } from "../logger.mjs";
11
- import { GasFeeEstimateLevel, GasFeeEstimateType } from "../types.mjs";
12
- import { getRandomisedGasFeeDigits } from "../utils/feature-flags.mjs";
13
- import { gweiDecimalToWeiDecimal } from "../utils/gas-fees.mjs";
14
- const log = createModuleLogger(projectLogger, 'randomised-estimation-gas-fee-flow');
15
- const PRESERVE_NUMBER_OF_DIGITS = 2;
16
- /**
17
- * Implementation of a gas fee flow that randomises the last digits of gas fee estimations
18
- */
19
- export class RandomisedEstimationsGasFeeFlow {
20
- constructor() {
21
- _RandomisedEstimationsGasFeeFlow_instances.add(this);
22
- }
23
- matchesTransaction({ transactionMeta, messenger, }) {
24
- const { chainId } = transactionMeta;
25
- const randomisedGasFeeDigits = getRandomisedGasFeeDigits(chainId, messenger);
26
- return randomisedGasFeeDigits !== undefined;
27
- }
28
- async getGasFees(request) {
29
- try {
30
- return await __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees).call(this, request);
31
- }
32
- catch (error) {
33
- log('Using default flow as fallback due to error', error);
34
- return await __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getDefaultGasFees).call(this, request);
35
- }
36
- }
37
- }
38
- _RandomisedEstimationsGasFeeFlow_instances = new WeakSet(), _RandomisedEstimationsGasFeeFlow_getDefaultGasFees = async function _RandomisedEstimationsGasFeeFlow_getDefaultGasFees(request) {
39
- return new DefaultGasFeeFlow().getGasFees(request);
40
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees = async function _RandomisedEstimationsGasFeeFlow_getRandomisedGasFees(request) {
41
- const { messenger, gasFeeControllerData, transactionMeta } = request;
42
- const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;
43
- const randomisedGasFeeDigits = getRandomisedGasFeeDigits(transactionMeta.chainId, messenger);
44
- let response;
45
- if (gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET) {
46
- log('Using fee market estimates', gasFeeEstimates);
47
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates).call(this, gasFeeEstimates, randomisedGasFeeDigits);
48
- log('Randomised fee market estimates', response);
49
- }
50
- else if (gasEstimateType === GAS_ESTIMATE_TYPES.LEGACY) {
51
- log('Using legacy estimates', gasFeeEstimates);
52
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates).call(this, gasFeeEstimates, randomisedGasFeeDigits);
53
- log('Randomised legacy estimates', response);
54
- }
55
- else if (gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE) {
56
- log('Using eth_gasPrice estimates', gasFeeEstimates);
57
- response = __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate).call(this, gasFeeEstimates, randomisedGasFeeDigits);
58
- log('Randomised eth_gasPrice estimates', response);
59
- }
60
- else {
61
- throw new Error(`Unsupported gas estimate type: ${gasEstimateType}`);
62
- }
63
- return {
64
- estimates: response,
65
- };
66
- }, _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseFeeMarketEstimates(gasFeeEstimates, lastNDigits) {
67
- const levels = Object.values(GasFeeEstimateLevel).reduce((result, level) => ({
68
- ...result,
69
- [level]: __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel).call(this, gasFeeEstimates, level, lastNDigits),
70
- }), {});
71
- return {
72
- type: GasFeeEstimateType.FeeMarket,
73
- ...levels,
74
- };
75
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedFeeMarketLevel(gasFeeEstimates, level, lastNDigits) {
76
- return {
77
- maxFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxFeePerGas, lastNDigits),
78
- maxPriorityFeePerGas: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level].suggestedMaxPriorityFeePerGas, lastNDigits),
79
- };
80
- }, _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates = function _RandomisedEstimationsGasFeeFlow_randomiseLegacyEstimates(gasFeeEstimates, lastNDigits) {
81
- const levels = Object.values(GasFeeEstimateLevel).reduce((result, level) => ({
82
- ...result,
83
- [level]: __classPrivateFieldGet(this, _RandomisedEstimationsGasFeeFlow_instances, "m", _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel).call(this, gasFeeEstimates, level, lastNDigits),
84
- }), {});
85
- return {
86
- type: GasFeeEstimateType.Legacy,
87
- ...levels,
88
- };
89
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel = function _RandomisedEstimationsGasFeeFlow_getRandomisedLegacyLevel(gasFeeEstimates, level, lastNDigits) {
90
- return randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates[level], lastNDigits);
91
- }, _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate = function _RandomisedEstimationsGasFeeFlow_getRandomisedGasPriceEstimate(gasFeeEstimates, lastNDigits) {
92
- return {
93
- type: GasFeeEstimateType.GasPrice,
94
- gasPrice: randomiseDecimalGWEIAndConvertToHex(gasFeeEstimates.gasPrice, lastNDigits),
95
- };
96
- };
97
- /**
98
- * Generates a random number with the specified number of digits that is greater than or equal to the given minimum value.
99
- *
100
- * @param digitCount - The number of digits the random number should have
101
- * @param minValue - The minimum value the random number should have
102
- * @returns A random number with the specified number of digits
103
- */
104
- function generateRandomDigits(digitCount, minValue) {
105
- const multiplier = 10 ** digitCount;
106
- return minValue + Math.floor(Math.random() * (multiplier - minValue));
107
- }
108
- /**
109
- * Randomises the least significant digits of a decimal gas fee value and converts it to a hexadecimal Wei value.
110
- *
111
- * This function preserves the more significant digits while randomizing only the least significant ones,
112
- * ensuring that fees remain close to the original estimation while providing randomisation.
113
- * The randomisation is performed in Wei units for more precision.
114
- *
115
- * @param gweiDecimalValue - The original gas fee value in Gwei (decimal)
116
- * @param [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise
117
- * @returns The randomised value converted to Wei in hexadecimal format
118
- */
119
- export function randomiseDecimalGWEIAndConvertToHex(gweiDecimalValue, numberOfDigitsToRandomizeAtTheEnd) {
120
- const weiDecimalValue = gweiDecimalToWeiDecimal(gweiDecimalValue);
121
- const decimalLength = weiDecimalValue.length;
122
- // Determine how many digits to randomise while preserving the PRESERVE_NUMBER_OF_DIGITS
123
- const effectiveDigitsToRandomise = Math.min(numberOfDigitsToRandomizeAtTheEnd, decimalLength - PRESERVE_NUMBER_OF_DIGITS);
124
- // Handle the case when the value is 0 or too small
125
- if (Number(weiDecimalValue) === 0 || effectiveDigitsToRandomise <= 0) {
126
- return `0x${Number(weiDecimalValue).toString(16)}`;
127
- }
128
- // Use string manipulation to get the base part (significant digits)
129
- const significantDigitsCount = decimalLength - effectiveDigitsToRandomise;
130
- const significantDigits = weiDecimalValue.slice(0, significantDigitsCount);
131
- // Get the original ending digits using string manipulation
132
- const endingDigits = weiDecimalValue.slice(-effectiveDigitsToRandomise);
133
- const originalEndingDigits = Number(endingDigits);
134
- // Generate random digits that are greater than or equal to the original ending digits
135
- const randomEndingDigits = generateRandomDigits(effectiveDigitsToRandomise, originalEndingDigits);
136
- const basePart = BigInt(significantDigits + '0'.repeat(effectiveDigitsToRandomise));
137
- const randomisedWeiDecimal = basePart + BigInt(randomEndingDigits);
138
- return `0x${randomisedWeiDecimal.toString(16)}`;
139
- }
140
- //# sourceMappingURL=RandomisedEstimationsGasFeeFlow.mjs.map
@@ -1 +0,0 @@
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 { TransactionControllerMessenger } from '../TransactionController';\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 { getRandomisedGasFeeDigits } 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;\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,\n messenger,\n }: {\n transactionMeta: TransactionMeta;\n messenger: TransactionControllerMessenger;\n }): boolean {\n const { chainId } = transactionMeta;\n\n const randomisedGasFeeDigits = getRandomisedGasFeeDigits(\n chainId,\n messenger,\n );\n\n return randomisedGasFeeDigits !== undefined;\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 { messenger, gasFeeControllerData, transactionMeta } = request;\n const { gasEstimateType, gasFeeEstimates } = gasFeeControllerData;\n\n const randomisedGasFeeDigits = getRandomisedGasFeeDigits(\n transactionMeta.chainId,\n messenger,\n ) as number;\n\n let response: GasFeeEstimates;\n\n if (gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET) {\n log('Using fee market estimates', gasFeeEstimates);\n response = this.#randomiseFeeMarketEstimates(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised fee market estimates', response);\n } else if (gasEstimateType === GAS_ESTIMATE_TYPES.LEGACY) {\n log('Using legacy estimates', gasFeeEstimates);\n response = this.#randomiseLegacyEstimates(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised legacy estimates', response);\n } else if (gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE) {\n log('Using eth_gasPrice estimates', gasFeeEstimates);\n response = this.#getRandomisedGasPriceEstimate(\n gasFeeEstimates,\n randomisedGasFeeDigits,\n );\n log('Randomised eth_gasPrice estimates', response);\n } else {\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 * Generates a random number with the specified number of digits that is greater than or equal to the given minimum value.\n *\n * @param digitCount - The number of digits the random number should have\n * @param minValue - The minimum value the random number should have\n * @returns A random number with the specified number of digits\n */\nfunction generateRandomDigits(digitCount: number, minValue: number): number {\n const multiplier = 10 ** digitCount;\n return minValue + Math.floor(Math.random() * (multiplier - minValue));\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 [numberOfDigitsToRandomizeAtTheEnd] - The number of least significant digits to randomise\n * @returns The randomised value converted to Wei in hexadecimal format\n */\nexport function randomiseDecimalGWEIAndConvertToHex(\n gweiDecimalValue: string | number,\n numberOfDigitsToRandomizeAtTheEnd: number,\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 numberOfDigitsToRandomizeAtTheEnd,\n decimalLength - PRESERVE_NUMBER_OF_DIGITS,\n );\n\n // Handle the case when the value is 0 or too small\n if (Number(weiDecimalValue) === 0 || effectiveDigitsToRandomise <= 0) {\n return `0x${Number(weiDecimalValue).toString(16)}` as Hex;\n }\n\n // Use string manipulation to get the base part (significant digits)\n const significantDigitsCount = decimalLength - effectiveDigitsToRandomise;\n const significantDigits = weiDecimalValue.slice(0, significantDigitsCount);\n\n // Get the original ending digits using string manipulation\n const endingDigits = weiDecimalValue.slice(-effectiveDigitsToRandomise);\n const originalEndingDigits = Number(endingDigits);\n\n // Generate random digits that are greater than or equal to the original ending digits\n const randomEndingDigits = generateRandomDigits(\n effectiveDigitsToRandomise,\n originalEndingDigits,\n );\n\n const basePart = BigInt(\n significantDigits + '0'.repeat(effectiveDigitsToRandomise),\n );\n const randomisedWeiDecimal = basePart + BigInt(randomEndingDigits);\n\n return `0x${randomisedWeiDecimal.toString(16)}` as Hex;\n}\n"]}