@metamask-previews/gas-fee-controller 6.1.1-preview.d32a7cc

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 (44) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/LICENSE +20 -0
  3. package/README.md +15 -0
  4. package/dist/GasFeeController.d.ts +231 -0
  5. package/dist/GasFeeController.d.ts.map +1 -0
  6. package/dist/GasFeeController.js +262 -0
  7. package/dist/GasFeeController.js.map +1 -0
  8. package/dist/determineGasFeeCalculations.d.ts +41 -0
  9. package/dist/determineGasFeeCalculations.d.ts.map +1 -0
  10. package/dist/determineGasFeeCalculations.js +87 -0
  11. package/dist/determineGasFeeCalculations.js.map +1 -0
  12. package/dist/fetchBlockFeeHistory.d.ts +116 -0
  13. package/dist/fetchBlockFeeHistory.d.ts.map +1 -0
  14. package/dist/fetchBlockFeeHistory.js +202 -0
  15. package/dist/fetchBlockFeeHistory.js.map +1 -0
  16. package/dist/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.d.ts +17 -0
  17. package/dist/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.d.ts.map +1 -0
  18. package/dist/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.js +89 -0
  19. package/dist/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.js.map +1 -0
  20. package/dist/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.d.ts +12 -0
  21. package/dist/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.d.ts.map +1 -0
  22. package/dist/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.js +32 -0
  23. package/dist/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.js.map +1 -0
  24. package/dist/fetchGasEstimatesViaEthFeeHistory/medianOf.d.ts +11 -0
  25. package/dist/fetchGasEstimatesViaEthFeeHistory/medianOf.d.ts.map +1 -0
  26. package/dist/fetchGasEstimatesViaEthFeeHistory/medianOf.js +17 -0
  27. package/dist/fetchGasEstimatesViaEthFeeHistory/medianOf.js.map +1 -0
  28. package/dist/fetchGasEstimatesViaEthFeeHistory/types.d.ts +8 -0
  29. package/dist/fetchGasEstimatesViaEthFeeHistory/types.d.ts.map +1 -0
  30. package/dist/fetchGasEstimatesViaEthFeeHistory/types.js +3 -0
  31. package/dist/fetchGasEstimatesViaEthFeeHistory/types.js.map +1 -0
  32. package/dist/fetchGasEstimatesViaEthFeeHistory.d.ts +22 -0
  33. package/dist/fetchGasEstimatesViaEthFeeHistory.d.ts.map +1 -0
  34. package/dist/fetchGasEstimatesViaEthFeeHistory.js +53 -0
  35. package/dist/fetchGasEstimatesViaEthFeeHistory.js.map +1 -0
  36. package/dist/gas-util.d.ts +43 -0
  37. package/dist/gas-util.d.ts.map +1 -0
  38. package/dist/gas-util.js +140 -0
  39. package/dist/gas-util.js.map +1 -0
  40. package/dist/index.d.ts +2 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +18 -0
  43. package/dist/index.js.map +1 -0
  44. package/package.json +66 -0
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const controller_utils_1 = require("@metamask/controller-utils");
7
+ const ethereumjs_util_1 = require("ethereumjs-util");
8
+ const ethjs_unit_1 = require("ethjs-unit");
9
+ const medianOf_1 = __importDefault(require("./medianOf"));
10
+ const PRIORITY_LEVELS = ['low', 'medium', 'high'];
11
+ const PRIORITY_LEVEL_PERCENTILES = [10, 20, 30];
12
+ const SETTINGS_BY_PRIORITY_LEVEL = {
13
+ low: {
14
+ percentile: 10,
15
+ baseFeePercentageMultiplier: new ethereumjs_util_1.BN(110),
16
+ priorityFeePercentageMultiplier: new ethereumjs_util_1.BN(94),
17
+ minSuggestedMaxPriorityFeePerGas: new ethereumjs_util_1.BN(1000000000),
18
+ estimatedWaitTimes: {
19
+ minWaitTimeEstimate: 15000,
20
+ maxWaitTimeEstimate: 30000,
21
+ },
22
+ },
23
+ medium: {
24
+ percentile: 20,
25
+ baseFeePercentageMultiplier: new ethereumjs_util_1.BN(120),
26
+ priorityFeePercentageMultiplier: new ethereumjs_util_1.BN(97),
27
+ minSuggestedMaxPriorityFeePerGas: new ethereumjs_util_1.BN(1500000000),
28
+ estimatedWaitTimes: {
29
+ minWaitTimeEstimate: 15000,
30
+ maxWaitTimeEstimate: 45000,
31
+ },
32
+ },
33
+ high: {
34
+ percentile: 30,
35
+ baseFeePercentageMultiplier: new ethereumjs_util_1.BN(125),
36
+ priorityFeePercentageMultiplier: new ethereumjs_util_1.BN(98),
37
+ minSuggestedMaxPriorityFeePerGas: new ethereumjs_util_1.BN(2000000000),
38
+ estimatedWaitTimes: {
39
+ minWaitTimeEstimate: 15000,
40
+ maxWaitTimeEstimate: 60000,
41
+ },
42
+ },
43
+ };
44
+ /**
45
+ * Calculates a set of estimates assigned to a particular priority level based on the data returned
46
+ * by `eth_feeHistory`.
47
+ *
48
+ * @param priorityLevel - The level of fees that dictates how soon a transaction may go through
49
+ * ("low", "medium", or "high").
50
+ * @param blocks - A set of blocks as obtained from {@link fetchBlockFeeHistory}.
51
+ * @returns The estimates.
52
+ */
53
+ function calculateEstimatesForPriorityLevel(priorityLevel, blocks) {
54
+ const settings = SETTINGS_BY_PRIORITY_LEVEL[priorityLevel];
55
+ const latestBaseFeePerGas = blocks[blocks.length - 1].baseFeePerGas;
56
+ const adjustedBaseFee = latestBaseFeePerGas
57
+ .mul(settings.baseFeePercentageMultiplier)
58
+ .divn(100);
59
+ const priorityFees = blocks
60
+ .map((block) => {
61
+ return 'priorityFeesByPercentile' in block
62
+ ? block.priorityFeesByPercentile[settings.percentile]
63
+ : null;
64
+ })
65
+ .filter(ethereumjs_util_1.BN.isBN);
66
+ const medianPriorityFee = (0, medianOf_1.default)(priorityFees);
67
+ const adjustedPriorityFee = medianPriorityFee
68
+ .mul(settings.priorityFeePercentageMultiplier)
69
+ .divn(100);
70
+ const suggestedMaxPriorityFeePerGas = ethereumjs_util_1.BN.max(adjustedPriorityFee, settings.minSuggestedMaxPriorityFeePerGas);
71
+ const suggestedMaxFeePerGas = adjustedBaseFee.add(suggestedMaxPriorityFeePerGas);
72
+ return Object.assign(Object.assign({}, settings.estimatedWaitTimes), { suggestedMaxPriorityFeePerGas: (0, ethjs_unit_1.fromWei)(suggestedMaxPriorityFeePerGas, controller_utils_1.GWEI), suggestedMaxFeePerGas: (0, ethjs_unit_1.fromWei)(suggestedMaxFeePerGas, controller_utils_1.GWEI) });
73
+ }
74
+ /**
75
+ * Calculates a set of estimates suitable for different priority levels based on the data returned
76
+ * by `eth_feeHistory`.
77
+ *
78
+ * @param blocks - A set of blocks populated with data for priority fee percentiles 10, 20, and 30,
79
+ * obtained via {@link BlockFeeHistoryDatasetFetcher}.
80
+ * @returns The estimates.
81
+ */
82
+ function calculateGasFeeEstimatesForPriorityLevels(blocks) {
83
+ return PRIORITY_LEVELS.reduce((obj, priorityLevel) => {
84
+ const gasEstimatesForPriorityLevel = calculateEstimatesForPriorityLevel(priorityLevel, blocks);
85
+ return Object.assign(Object.assign({}, obj), { [priorityLevel]: gasEstimatesForPriorityLevel });
86
+ }, {});
87
+ }
88
+ exports.default = calculateGasFeeEstimatesForPriorityLevels;
89
+ //# sourceMappingURL=calculateGasFeeEstimatesForPriorityLevels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculateGasFeeEstimatesForPriorityLevels.js","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.ts"],"names":[],"mappings":"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","sourcesContent":["import { GWEI } from '@metamask/controller-utils';\nimport { BN } from 'ethereumjs-util';\nimport { fromWei } from 'ethjs-unit';\n\nimport medianOf from './medianOf';\nimport type { FeeHistoryBlock } from '../fetchBlockFeeHistory';\nimport type { Eip1559GasFee, GasFeeEstimates } from '../GasFeeController';\n\nexport type PriorityLevel = (typeof PRIORITY_LEVELS)[number];\nexport type Percentile = (typeof PRIORITY_LEVEL_PERCENTILES)[number];\n\nconst PRIORITY_LEVELS = ['low', 'medium', 'high'] as const;\nconst PRIORITY_LEVEL_PERCENTILES = [10, 20, 30] as const;\nconst SETTINGS_BY_PRIORITY_LEVEL = {\n low: {\n percentile: 10 as Percentile,\n baseFeePercentageMultiplier: new BN(110),\n priorityFeePercentageMultiplier: new BN(94),\n minSuggestedMaxPriorityFeePerGas: new BN(1_000_000_000),\n estimatedWaitTimes: {\n minWaitTimeEstimate: 15_000,\n maxWaitTimeEstimate: 30_000,\n },\n },\n medium: {\n percentile: 20 as Percentile,\n baseFeePercentageMultiplier: new BN(120),\n priorityFeePercentageMultiplier: new BN(97),\n minSuggestedMaxPriorityFeePerGas: new BN(1_500_000_000),\n estimatedWaitTimes: {\n minWaitTimeEstimate: 15_000,\n maxWaitTimeEstimate: 45_000,\n },\n },\n high: {\n percentile: 30 as Percentile,\n baseFeePercentageMultiplier: new BN(125),\n priorityFeePercentageMultiplier: new BN(98),\n minSuggestedMaxPriorityFeePerGas: new BN(2_000_000_000),\n estimatedWaitTimes: {\n minWaitTimeEstimate: 15_000,\n maxWaitTimeEstimate: 60_000,\n },\n },\n};\n\n/**\n * Calculates a set of estimates assigned to a particular priority level based on the data returned\n * by `eth_feeHistory`.\n *\n * @param priorityLevel - The level of fees that dictates how soon a transaction may go through\n * (\"low\", \"medium\", or \"high\").\n * @param blocks - A set of blocks as obtained from {@link fetchBlockFeeHistory}.\n * @returns The estimates.\n */\nfunction calculateEstimatesForPriorityLevel(\n priorityLevel: PriorityLevel,\n blocks: FeeHistoryBlock<Percentile>[],\n): Eip1559GasFee {\n const settings = SETTINGS_BY_PRIORITY_LEVEL[priorityLevel];\n\n const latestBaseFeePerGas = blocks[blocks.length - 1].baseFeePerGas;\n\n const adjustedBaseFee = latestBaseFeePerGas\n .mul(settings.baseFeePercentageMultiplier)\n .divn(100);\n const priorityFees = blocks\n .map((block) => {\n return 'priorityFeesByPercentile' in block\n ? block.priorityFeesByPercentile[settings.percentile]\n : null;\n })\n .filter(BN.isBN);\n const medianPriorityFee = medianOf(priorityFees);\n const adjustedPriorityFee = medianPriorityFee\n .mul(settings.priorityFeePercentageMultiplier)\n .divn(100);\n\n const suggestedMaxPriorityFeePerGas = BN.max(\n adjustedPriorityFee,\n settings.minSuggestedMaxPriorityFeePerGas,\n );\n const suggestedMaxFeePerGas = adjustedBaseFee.add(\n suggestedMaxPriorityFeePerGas,\n );\n\n return {\n ...settings.estimatedWaitTimes,\n suggestedMaxPriorityFeePerGas: fromWei(suggestedMaxPriorityFeePerGas, GWEI),\n suggestedMaxFeePerGas: fromWei(suggestedMaxFeePerGas, GWEI),\n };\n}\n\n/**\n * Calculates a set of estimates suitable for different priority levels based on the data returned\n * by `eth_feeHistory`.\n *\n * @param blocks - A set of blocks populated with data for priority fee percentiles 10, 20, and 30,\n * obtained via {@link BlockFeeHistoryDatasetFetcher}.\n * @returns The estimates.\n */\nexport default function calculateGasFeeEstimatesForPriorityLevels(\n blocks: FeeHistoryBlock<Percentile>[],\n): Pick<GasFeeEstimates, PriorityLevel> {\n return PRIORITY_LEVELS.reduce((obj, priorityLevel) => {\n const gasEstimatesForPriorityLevel = calculateEstimatesForPriorityLevel(\n priorityLevel,\n blocks,\n );\n return { ...obj, [priorityLevel]: gasEstimatesForPriorityLevel };\n }, {} as Pick<GasFeeEstimates, PriorityLevel>);\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import type EthQuery from '@metamask/eth-query';
2
+ import type { EthBlock } from './types';
3
+ /**
4
+ * Returns information about the latest completed block.
5
+ *
6
+ * @param ethQuery - An EthQuery instance
7
+ * @param includeFullTransactionData - Whether or not to include all data for transactions as
8
+ * opposed to merely hashes. False by default.
9
+ * @returns The block.
10
+ */
11
+ export default function fetchLatestBlock(ethQuery: EthQuery, includeFullTransactionData?: boolean): Promise<EthBlock>;
12
+ //# sourceMappingURL=fetchLatestBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchLatestBlock.d.ts","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;GAOG;AACH,wBAA8B,gBAAgB,CAC5C,QAAQ,EAAE,QAAQ,EAClB,0BAA0B,UAAQ,GACjC,OAAO,CAAC,QAAQ,CAAC,CAWnB"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const controller_utils_1 = require("@metamask/controller-utils");
13
+ /**
14
+ * Returns information about the latest completed block.
15
+ *
16
+ * @param ethQuery - An EthQuery instance
17
+ * @param includeFullTransactionData - Whether or not to include all data for transactions as
18
+ * opposed to merely hashes. False by default.
19
+ * @returns The block.
20
+ */
21
+ function fetchLatestBlock(ethQuery, includeFullTransactionData = false) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const blockNumber = yield (0, controller_utils_1.query)(ethQuery, 'blockNumber');
24
+ const block = yield (0, controller_utils_1.query)(ethQuery, 'getBlockByNumber', [
25
+ blockNumber,
26
+ includeFullTransactionData,
27
+ ]);
28
+ return Object.assign(Object.assign({}, block), { number: (0, controller_utils_1.fromHex)(block.number), baseFeePerGas: (0, controller_utils_1.fromHex)(block.baseFeePerGas) });
29
+ });
30
+ }
31
+ exports.default = fetchLatestBlock;
32
+ //# sourceMappingURL=fetchLatestBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchLatestBlock.js","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,iEAA4D;AAK5D;;;;;;;GAOG;AACH,SAA8B,gBAAgB,CAC5C,QAAkB,EAClB,0BAA0B,GAAG,KAAK;;QAElC,MAAM,WAAW,GAAG,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,IAAA,wBAAK,EAAC,QAAQ,EAAE,kBAAkB,EAAE;YACtD,WAAW;YACX,0BAA0B;SAC3B,CAAC,CAAC;QACH,uCACK,KAAK,KACR,MAAM,EAAE,IAAA,0BAAO,EAAC,KAAK,CAAC,MAAM,CAAC,EAC7B,aAAa,EAAE,IAAA,0BAAO,EAAC,KAAK,CAAC,aAAa,CAAC,IAC3C;IACJ,CAAC;CAAA;AAdD,mCAcC","sourcesContent":["import { query, fromHex } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\n\nimport type { EthBlock } from './types';\n\n/**\n * Returns information about the latest completed block.\n *\n * @param ethQuery - An EthQuery instance\n * @param includeFullTransactionData - Whether or not to include all data for transactions as\n * opposed to merely hashes. False by default.\n * @returns The block.\n */\nexport default async function fetchLatestBlock(\n ethQuery: EthQuery,\n includeFullTransactionData = false,\n): Promise<EthBlock> {\n const blockNumber = await query(ethQuery, 'blockNumber');\n const block = await query(ethQuery, 'getBlockByNumber', [\n blockNumber,\n includeFullTransactionData,\n ]);\n return {\n ...block,\n number: fromHex(block.number),\n baseFeePerGas: fromHex(block.baseFeePerGas),\n };\n}\n"]}
@@ -0,0 +1,11 @@
1
+ /// <reference types="bn.js" />
2
+ import type { BN } from 'ethereumjs-util';
3
+ /**
4
+ * Finds the median among a list of numbers. Note that this is different from the implementation
5
+ * in the MetaSwap API, as we want to hold to using BN as much as possible.
6
+ *
7
+ * @param numbers - A list of numbers, as BNs. Will be sorted automatically if unsorted.
8
+ * @returns The median number.
9
+ */
10
+ export default function medianOf(numbers: BN[]): BN;
11
+ //# sourceMappingURL=medianOf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"medianOf.d.ts","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/medianOf.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAKlD"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Finds the median among a list of numbers. Note that this is different from the implementation
5
+ * in the MetaSwap API, as we want to hold to using BN as much as possible.
6
+ *
7
+ * @param numbers - A list of numbers, as BNs. Will be sorted automatically if unsorted.
8
+ * @returns The median number.
9
+ */
10
+ function medianOf(numbers) {
11
+ const sortedNumbers = numbers.slice().sort((a, b) => a.cmp(b));
12
+ const len = sortedNumbers.length;
13
+ const index = Math.floor((len - 1) / 2);
14
+ return sortedNumbers[index];
15
+ }
16
+ exports.default = medianOf;
17
+ //# sourceMappingURL=medianOf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"medianOf.js","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/medianOf.ts"],"names":[],"mappings":";;AAEA;;;;;;GAMG;AACH,SAAwB,QAAQ,CAAC,OAAa;IAC5C,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AALD,2BAKC","sourcesContent":["import type { BN } from 'ethereumjs-util';\n\n/**\n * Finds the median among a list of numbers. Note that this is different from the implementation\n * in the MetaSwap API, as we want to hold to using BN as much as possible.\n *\n * @param numbers - A list of numbers, as BNs. Will be sorted automatically if unsorted.\n * @returns The median number.\n */\nexport default function medianOf(numbers: BN[]): BN {\n const sortedNumbers = numbers.slice().sort((a, b) => a.cmp(b));\n const len = sortedNumbers.length;\n const index = Math.floor((len - 1) / 2);\n return sortedNumbers[index];\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /// <reference types="bn.js" />
2
+ import type { BN } from 'ethereumjs-util';
3
+ export declare type EthBlock = {
4
+ number: BN;
5
+ baseFeePerGas: BN;
6
+ };
7
+ export declare type FeeRange = [string, string];
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/types.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAE1C,oBAAY,QAAQ,GAAG;IACrB,MAAM,EAAE,EAAE,CAAC;IACX,aAAa,EAAE,EAAE,CAAC;CACnB,CAAC;AAEF,oBAAY,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/fetchGasEstimatesViaEthFeeHistory/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { BN } from 'ethereumjs-util';\n\nexport type EthBlock = {\n number: BN;\n baseFeePerGas: BN;\n};\n\nexport type FeeRange = [string, string];\n"]}
@@ -0,0 +1,22 @@
1
+ import type EthQuery from '@metamask/eth-query';
2
+ import type { GasFeeEstimates } from './GasFeeController';
3
+ /**
4
+ * Generates gas fee estimates based on gas fees that have been used in the recent past so that
5
+ * those estimates can be displayed to users.
6
+ *
7
+ * To produce the estimates, the last 5 blocks are read from the network, and for each block, the
8
+ * priority fees for transactions at the 10th, 20th, and 30th percentiles are also read (here
9
+ * "percentile" signifies the level at which those transactions contribute to the overall gas used
10
+ * for the block, where higher percentiles correspond to higher fees). This information is used to
11
+ * calculate reasonable max priority and max fees for three different priority levels (higher
12
+ * priority = higher fee).
13
+ *
14
+ * Note that properties are returned for other data that are normally obtained via the API; however,
15
+ * to prevent extra requests to Infura, these properties are empty.
16
+ *
17
+ * @param ethQuery - An EthQuery instance.
18
+ * @returns Base and priority fee estimates, categorized by priority level, as well as an estimate
19
+ * for the next block's base fee.
20
+ */
21
+ export default function fetchGasEstimatesViaEthFeeHistory(ethQuery: EthQuery): Promise<GasFeeEstimates>;
22
+ //# sourceMappingURL=fetchGasEstimatesViaEthFeeHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchGasEstimatesViaEthFeeHistory.d.ts","sourceRoot":"","sources":["../src/fetchGasEstimatesViaEthFeeHistory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAMhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAA8B,iCAAiC,CAC7D,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,eAAe,CAAC,CAuB1B"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const controller_utils_1 = require("@metamask/controller-utils");
16
+ const ethjs_unit_1 = require("ethjs-unit");
17
+ const fetchBlockFeeHistory_1 = __importDefault(require("./fetchBlockFeeHistory"));
18
+ const calculateGasFeeEstimatesForPriorityLevels_1 = __importDefault(require("./fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels"));
19
+ const fetchLatestBlock_1 = __importDefault(require("./fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock"));
20
+ /**
21
+ * Generates gas fee estimates based on gas fees that have been used in the recent past so that
22
+ * those estimates can be displayed to users.
23
+ *
24
+ * To produce the estimates, the last 5 blocks are read from the network, and for each block, the
25
+ * priority fees for transactions at the 10th, 20th, and 30th percentiles are also read (here
26
+ * "percentile" signifies the level at which those transactions contribute to the overall gas used
27
+ * for the block, where higher percentiles correspond to higher fees). This information is used to
28
+ * calculate reasonable max priority and max fees for three different priority levels (higher
29
+ * priority = higher fee).
30
+ *
31
+ * Note that properties are returned for other data that are normally obtained via the API; however,
32
+ * to prevent extra requests to Infura, these properties are empty.
33
+ *
34
+ * @param ethQuery - An EthQuery instance.
35
+ * @returns Base and priority fee estimates, categorized by priority level, as well as an estimate
36
+ * for the next block's base fee.
37
+ */
38
+ function fetchGasEstimatesViaEthFeeHistory(ethQuery) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const latestBlock = yield (0, fetchLatestBlock_1.default)(ethQuery);
41
+ const blocks = yield (0, fetchBlockFeeHistory_1.default)({
42
+ ethQuery,
43
+ endBlock: latestBlock.number,
44
+ numberOfBlocks: 5,
45
+ percentiles: [10, 20, 30],
46
+ });
47
+ const estimatedBaseFee = (0, ethjs_unit_1.fromWei)(latestBlock.baseFeePerGas, controller_utils_1.GWEI);
48
+ const levelSpecificEstimates = (0, calculateGasFeeEstimatesForPriorityLevels_1.default)(blocks);
49
+ return Object.assign(Object.assign({}, levelSpecificEstimates), { estimatedBaseFee, historicalBaseFeeRange: null, baseFeeTrend: null, latestPriorityFeeRange: null, historicalPriorityFeeRange: null, priorityFeeTrend: null, networkCongestion: null });
50
+ });
51
+ }
52
+ exports.default = fetchGasEstimatesViaEthFeeHistory;
53
+ //# sourceMappingURL=fetchGasEstimatesViaEthFeeHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchGasEstimatesViaEthFeeHistory.js","sourceRoot":"","sources":["../src/fetchGasEstimatesViaEthFeeHistory.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,iEAAkD;AAElD,2CAAqC;AAErC,kFAA0D;AAC1D,8JAAsI;AACtI,4GAAoF;AAGpF;;;;;;;;;;;;;;;;;GAiBG;AACH,SAA8B,iCAAiC,CAC7D,QAAkB;;QAElB,MAAM,WAAW,GAAG,MAAM,IAAA,0BAAgB,EAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAoB,EAAC;YACxC,QAAQ;YACR,QAAQ,EAAE,WAAW,CAAC,MAAM;YAC5B,cAAc,EAAE,CAAC;YACjB,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;SAC1B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,IAAA,oBAAO,EAAC,WAAW,CAAC,aAAa,EAAE,uBAAI,CAAC,CAAC;QAElE,MAAM,sBAAsB,GAC1B,IAAA,mDAAyC,EAAC,MAAM,CAAC,CAAC;QAEpD,uCACK,sBAAsB,KACzB,gBAAgB,EAChB,sBAAsB,EAAE,IAAI,EAC5B,YAAY,EAAE,IAAI,EAClB,sBAAsB,EAAE,IAAI,EAC5B,0BAA0B,EAAE,IAAI,EAChC,gBAAgB,EAAE,IAAI,EACtB,iBAAiB,EAAE,IAAI,IACvB;IACJ,CAAC;CAAA;AAzBD,oDAyBC","sourcesContent":["import { GWEI } from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { fromWei } from 'ethjs-unit';\n\nimport fetchBlockFeeHistory from './fetchBlockFeeHistory';\nimport calculateGasFeeEstimatesForPriorityLevels from './fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels';\nimport fetchLatestBlock from './fetchGasEstimatesViaEthFeeHistory/fetchLatestBlock';\nimport type { GasFeeEstimates } from './GasFeeController';\n\n/**\n * Generates gas fee estimates based on gas fees that have been used in the recent past so that\n * those estimates can be displayed to users.\n *\n * To produce the estimates, the last 5 blocks are read from the network, and for each block, the\n * priority fees for transactions at the 10th, 20th, and 30th percentiles are also read (here\n * \"percentile\" signifies the level at which those transactions contribute to the overall gas used\n * for the block, where higher percentiles correspond to higher fees). This information is used to\n * calculate reasonable max priority and max fees for three different priority levels (higher\n * priority = higher fee).\n *\n * Note that properties are returned for other data that are normally obtained via the API; however,\n * to prevent extra requests to Infura, these properties are empty.\n *\n * @param ethQuery - An EthQuery instance.\n * @returns Base and priority fee estimates, categorized by priority level, as well as an estimate\n * for the next block's base fee.\n */\nexport default async function fetchGasEstimatesViaEthFeeHistory(\n ethQuery: EthQuery,\n): Promise<GasFeeEstimates> {\n const latestBlock = await fetchLatestBlock(ethQuery);\n const blocks = await fetchBlockFeeHistory({\n ethQuery,\n endBlock: latestBlock.number,\n numberOfBlocks: 5,\n percentiles: [10, 20, 30],\n });\n const estimatedBaseFee = fromWei(latestBlock.baseFeePerGas, GWEI);\n\n const levelSpecificEstimates =\n calculateGasFeeEstimatesForPriorityLevels(blocks);\n\n return {\n ...levelSpecificEstimates,\n estimatedBaseFee,\n historicalBaseFeeRange: null,\n baseFeeTrend: null,\n latestPriorityFeeRange: null,\n historicalPriorityFeeRange: null,\n priorityFeeTrend: null,\n networkCongestion: null,\n };\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import type EthQuery from '@metamask/eth-query';
2
+ import type { GasFeeEstimates, EthGasPriceEstimate, EstimatedGasFeeTimeBounds, LegacyGasPriceEstimate } from './GasFeeController';
3
+ /**
4
+ * Convert a decimal GWEI value to a decimal string rounded to the nearest WEI.
5
+ *
6
+ * @param n - The input GWEI amount, as a decimal string or a number.
7
+ * @returns The decimal string GWEI amount.
8
+ */
9
+ export declare function normalizeGWEIDecimalNumbers(n: string | number): any;
10
+ /**
11
+ * Fetch gas estimates from the given URL.
12
+ *
13
+ * @param url - The gas estimate URL.
14
+ * @param clientId - The client ID used to identify to the API who is asking for estimates.
15
+ * @returns The gas estimates.
16
+ */
17
+ export declare function fetchGasEstimates(url: string, clientId?: string): Promise<GasFeeEstimates>;
18
+ /**
19
+ * Hit the legacy MetaSwaps gasPrices estimate api and return the low, medium
20
+ * high values from that API.
21
+ *
22
+ * @param url - The URL to fetch gas price estimates from.
23
+ * @param clientId - The client ID used to identify to the API who is asking for estimates.
24
+ * @returns The gas price estimates.
25
+ */
26
+ export declare function fetchLegacyGasPriceEstimates(url: string, clientId?: string): Promise<LegacyGasPriceEstimate>;
27
+ /**
28
+ * Get a gas price estimate from the network using the `eth_gasPrice` method.
29
+ *
30
+ * @param ethQuery - The EthQuery instance to call the network with.
31
+ * @returns A gas price estimate.
32
+ */
33
+ export declare function fetchEthGasPriceEstimate(ethQuery: EthQuery): Promise<EthGasPriceEstimate>;
34
+ /**
35
+ * Estimate the time it will take for a transaction to be confirmed.
36
+ *
37
+ * @param maxPriorityFeePerGas - The max priority fee per gas.
38
+ * @param maxFeePerGas - The max fee per gas.
39
+ * @param gasFeeEstimates - The gas fee estimates.
40
+ * @returns The estimated lower and upper bounds for when this transaction will be confirmed.
41
+ */
42
+ export declare function calculateTimeEstimate(maxPriorityFeePerGas: string, maxFeePerGas: string, gasFeeEstimates: GasFeeEstimates): EstimatedGasFeeTimeBounds;
43
+ //# sourceMappingURL=gas-util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gas-util.d.ts","sourceRoot":"","sources":["../src/gas-util.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAGhD,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EAEzB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAI5B;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,OAI7D;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAyC1B;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAgBjC;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,mBAAmB,CAAC,CAK9B;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,eAAe,GAC/B,yBAAyB,CAoD3B"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.calculateTimeEstimate = exports.fetchEthGasPriceEstimate = exports.fetchLegacyGasPriceEstimates = exports.fetchGasEstimates = exports.normalizeGWEIDecimalNumbers = void 0;
13
+ const controller_utils_1 = require("@metamask/controller-utils");
14
+ const ethereumjs_util_1 = require("ethereumjs-util");
15
+ const makeClientIdHeader = (clientId) => ({ 'X-Client-Id': clientId });
16
+ /**
17
+ * Convert a decimal GWEI value to a decimal string rounded to the nearest WEI.
18
+ *
19
+ * @param n - The input GWEI amount, as a decimal string or a number.
20
+ * @returns The decimal string GWEI amount.
21
+ */
22
+ function normalizeGWEIDecimalNumbers(n) {
23
+ const numberAsWEIHex = (0, controller_utils_1.gweiDecToWEIBN)(n).toString(16);
24
+ const numberAsGWEI = (0, controller_utils_1.weiHexToGweiDec)(numberAsWEIHex).toString(10);
25
+ return numberAsGWEI;
26
+ }
27
+ exports.normalizeGWEIDecimalNumbers = normalizeGWEIDecimalNumbers;
28
+ /**
29
+ * Fetch gas estimates from the given URL.
30
+ *
31
+ * @param url - The gas estimate URL.
32
+ * @param clientId - The client ID used to identify to the API who is asking for estimates.
33
+ * @returns The gas estimates.
34
+ */
35
+ function fetchGasEstimates(url, clientId) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ const estimates = yield (0, controller_utils_1.handleFetch)(url, clientId ? { headers: makeClientIdHeader(clientId) } : undefined);
38
+ return {
39
+ low: Object.assign(Object.assign({}, estimates.low), { suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.low.suggestedMaxPriorityFeePerGas), suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.low.suggestedMaxFeePerGas) }),
40
+ medium: Object.assign(Object.assign({}, estimates.medium), { suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.medium.suggestedMaxPriorityFeePerGas), suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.medium.suggestedMaxFeePerGas) }),
41
+ high: Object.assign(Object.assign({}, estimates.high), { suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(estimates.high.suggestedMaxPriorityFeePerGas), suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(estimates.high.suggestedMaxFeePerGas) }),
42
+ estimatedBaseFee: normalizeGWEIDecimalNumbers(estimates.estimatedBaseFee),
43
+ historicalBaseFeeRange: estimates.historicalBaseFeeRange,
44
+ baseFeeTrend: estimates.baseFeeTrend,
45
+ latestPriorityFeeRange: estimates.latestPriorityFeeRange,
46
+ historicalPriorityFeeRange: estimates.historicalPriorityFeeRange,
47
+ priorityFeeTrend: estimates.priorityFeeTrend,
48
+ networkCongestion: estimates.networkCongestion,
49
+ };
50
+ });
51
+ }
52
+ exports.fetchGasEstimates = fetchGasEstimates;
53
+ /**
54
+ * Hit the legacy MetaSwaps gasPrices estimate api and return the low, medium
55
+ * high values from that API.
56
+ *
57
+ * @param url - The URL to fetch gas price estimates from.
58
+ * @param clientId - The client ID used to identify to the API who is asking for estimates.
59
+ * @returns The gas price estimates.
60
+ */
61
+ function fetchLegacyGasPriceEstimates(url, clientId) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ const result = yield (0, controller_utils_1.handleFetch)(url, {
64
+ referrer: url,
65
+ referrerPolicy: 'no-referrer-when-downgrade',
66
+ method: 'GET',
67
+ mode: 'cors',
68
+ headers: Object.assign({ 'Content-Type': 'application/json' }, (clientId && makeClientIdHeader(clientId))),
69
+ });
70
+ return {
71
+ low: result.SafeGasPrice,
72
+ medium: result.ProposeGasPrice,
73
+ high: result.FastGasPrice,
74
+ };
75
+ });
76
+ }
77
+ exports.fetchLegacyGasPriceEstimates = fetchLegacyGasPriceEstimates;
78
+ /**
79
+ * Get a gas price estimate from the network using the `eth_gasPrice` method.
80
+ *
81
+ * @param ethQuery - The EthQuery instance to call the network with.
82
+ * @returns A gas price estimate.
83
+ */
84
+ function fetchEthGasPriceEstimate(ethQuery) {
85
+ return __awaiter(this, void 0, void 0, function* () {
86
+ const gasPrice = yield (0, controller_utils_1.query)(ethQuery, 'gasPrice');
87
+ return {
88
+ gasPrice: (0, controller_utils_1.weiHexToGweiDec)(gasPrice).toString(),
89
+ };
90
+ });
91
+ }
92
+ exports.fetchEthGasPriceEstimate = fetchEthGasPriceEstimate;
93
+ /**
94
+ * Estimate the time it will take for a transaction to be confirmed.
95
+ *
96
+ * @param maxPriorityFeePerGas - The max priority fee per gas.
97
+ * @param maxFeePerGas - The max fee per gas.
98
+ * @param gasFeeEstimates - The gas fee estimates.
99
+ * @returns The estimated lower and upper bounds for when this transaction will be confirmed.
100
+ */
101
+ function calculateTimeEstimate(maxPriorityFeePerGas, maxFeePerGas, gasFeeEstimates) {
102
+ const { low, medium, high, estimatedBaseFee } = gasFeeEstimates;
103
+ const maxPriorityFeePerGasInWEI = (0, controller_utils_1.gweiDecToWEIBN)(maxPriorityFeePerGas);
104
+ const maxFeePerGasInWEI = (0, controller_utils_1.gweiDecToWEIBN)(maxFeePerGas);
105
+ const estimatedBaseFeeInWEI = (0, controller_utils_1.gweiDecToWEIBN)(estimatedBaseFee);
106
+ const effectiveMaxPriorityFee = ethereumjs_util_1.BN.min(maxPriorityFeePerGasInWEI, maxFeePerGasInWEI.sub(estimatedBaseFeeInWEI));
107
+ const lowMaxPriorityFeeInWEI = (0, controller_utils_1.gweiDecToWEIBN)(low.suggestedMaxPriorityFeePerGas);
108
+ const mediumMaxPriorityFeeInWEI = (0, controller_utils_1.gweiDecToWEIBN)(medium.suggestedMaxPriorityFeePerGas);
109
+ const highMaxPriorityFeeInWEI = (0, controller_utils_1.gweiDecToWEIBN)(high.suggestedMaxPriorityFeePerGas);
110
+ let lowerTimeBound;
111
+ let upperTimeBound;
112
+ if (effectiveMaxPriorityFee.lt(lowMaxPriorityFeeInWEI)) {
113
+ lowerTimeBound = null;
114
+ upperTimeBound = 'unknown';
115
+ }
116
+ else if (effectiveMaxPriorityFee.gte(lowMaxPriorityFeeInWEI) &&
117
+ effectiveMaxPriorityFee.lt(mediumMaxPriorityFeeInWEI)) {
118
+ lowerTimeBound = low.minWaitTimeEstimate;
119
+ upperTimeBound = low.maxWaitTimeEstimate;
120
+ }
121
+ else if (effectiveMaxPriorityFee.gte(mediumMaxPriorityFeeInWEI) &&
122
+ effectiveMaxPriorityFee.lt(highMaxPriorityFeeInWEI)) {
123
+ lowerTimeBound = medium.minWaitTimeEstimate;
124
+ upperTimeBound = medium.maxWaitTimeEstimate;
125
+ }
126
+ else if (effectiveMaxPriorityFee.eq(highMaxPriorityFeeInWEI)) {
127
+ lowerTimeBound = high.minWaitTimeEstimate;
128
+ upperTimeBound = high.maxWaitTimeEstimate;
129
+ }
130
+ else {
131
+ lowerTimeBound = 0;
132
+ upperTimeBound = high.maxWaitTimeEstimate;
133
+ }
134
+ return {
135
+ lowerTimeBound,
136
+ upperTimeBound,
137
+ };
138
+ }
139
+ exports.calculateTimeEstimate = calculateTimeEstimate;
140
+ //# sourceMappingURL=gas-util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gas-util.js","sourceRoot":"","sources":["../src/gas-util.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n query,\n handleFetch,\n gweiDecToWEIBN,\n weiHexToGweiDec,\n} from '@metamask/controller-utils';\nimport type EthQuery from '@metamask/eth-query';\nimport { BN } from 'ethereumjs-util';\n\nimport type {\n GasFeeEstimates,\n EthGasPriceEstimate,\n EstimatedGasFeeTimeBounds,\n unknownString,\n LegacyGasPriceEstimate,\n} from './GasFeeController';\n\nconst makeClientIdHeader = (clientId: string) => ({ 'X-Client-Id': clientId });\n\n/**\n * Convert a decimal GWEI value to a decimal string rounded to the nearest WEI.\n *\n * @param n - The input GWEI amount, as a decimal string or a number.\n * @returns The decimal string GWEI amount.\n */\nexport function normalizeGWEIDecimalNumbers(n: string | number) {\n const numberAsWEIHex = gweiDecToWEIBN(n).toString(16);\n const numberAsGWEI = weiHexToGweiDec(numberAsWEIHex).toString(10);\n return numberAsGWEI;\n}\n\n/**\n * Fetch gas estimates from the given URL.\n *\n * @param url - The gas estimate URL.\n * @param clientId - The client ID used to identify to the API who is asking for estimates.\n * @returns The gas estimates.\n */\nexport async function fetchGasEstimates(\n url: string,\n clientId?: string,\n): Promise<GasFeeEstimates> {\n const estimates = await handleFetch(\n url,\n clientId ? { headers: makeClientIdHeader(clientId) } : undefined,\n );\n return {\n low: {\n ...estimates.low,\n suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.low.suggestedMaxPriorityFeePerGas,\n ),\n suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.low.suggestedMaxFeePerGas,\n ),\n },\n medium: {\n ...estimates.medium,\n suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.medium.suggestedMaxPriorityFeePerGas,\n ),\n suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.medium.suggestedMaxFeePerGas,\n ),\n },\n high: {\n ...estimates.high,\n suggestedMaxPriorityFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.high.suggestedMaxPriorityFeePerGas,\n ),\n suggestedMaxFeePerGas: normalizeGWEIDecimalNumbers(\n estimates.high.suggestedMaxFeePerGas,\n ),\n },\n estimatedBaseFee: normalizeGWEIDecimalNumbers(estimates.estimatedBaseFee),\n historicalBaseFeeRange: estimates.historicalBaseFeeRange,\n baseFeeTrend: estimates.baseFeeTrend,\n latestPriorityFeeRange: estimates.latestPriorityFeeRange,\n historicalPriorityFeeRange: estimates.historicalPriorityFeeRange,\n priorityFeeTrend: estimates.priorityFeeTrend,\n networkCongestion: estimates.networkCongestion,\n };\n}\n\n/**\n * Hit the legacy MetaSwaps gasPrices estimate api and return the low, medium\n * high values from that API.\n *\n * @param url - The URL to fetch gas price estimates from.\n * @param clientId - The client ID used to identify to the API who is asking for estimates.\n * @returns The gas price estimates.\n */\nexport async function fetchLegacyGasPriceEstimates(\n url: string,\n clientId?: string,\n): Promise<LegacyGasPriceEstimate> {\n const result = await handleFetch(url, {\n referrer: url,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n headers: {\n 'Content-Type': 'application/json',\n ...(clientId && makeClientIdHeader(clientId)),\n },\n });\n return {\n low: result.SafeGasPrice,\n medium: result.ProposeGasPrice,\n high: result.FastGasPrice,\n };\n}\n\n/**\n * Get a gas price estimate from the network using the `eth_gasPrice` method.\n *\n * @param ethQuery - The EthQuery instance to call the network with.\n * @returns A gas price estimate.\n */\nexport async function fetchEthGasPriceEstimate(\n ethQuery: EthQuery,\n): Promise<EthGasPriceEstimate> {\n const gasPrice = await query(ethQuery, 'gasPrice');\n return {\n gasPrice: weiHexToGweiDec(gasPrice).toString(),\n };\n}\n\n/**\n * Estimate the time it will take for a transaction to be confirmed.\n *\n * @param maxPriorityFeePerGas - The max priority fee per gas.\n * @param maxFeePerGas - The max fee per gas.\n * @param gasFeeEstimates - The gas fee estimates.\n * @returns The estimated lower and upper bounds for when this transaction will be confirmed.\n */\nexport function calculateTimeEstimate(\n maxPriorityFeePerGas: string,\n maxFeePerGas: string,\n gasFeeEstimates: GasFeeEstimates,\n): EstimatedGasFeeTimeBounds {\n const { low, medium, high, estimatedBaseFee } = gasFeeEstimates;\n\n const maxPriorityFeePerGasInWEI = gweiDecToWEIBN(maxPriorityFeePerGas);\n const maxFeePerGasInWEI = gweiDecToWEIBN(maxFeePerGas);\n const estimatedBaseFeeInWEI = gweiDecToWEIBN(estimatedBaseFee);\n\n const effectiveMaxPriorityFee = BN.min(\n maxPriorityFeePerGasInWEI,\n maxFeePerGasInWEI.sub(estimatedBaseFeeInWEI),\n );\n\n const lowMaxPriorityFeeInWEI = gweiDecToWEIBN(\n low.suggestedMaxPriorityFeePerGas,\n );\n const mediumMaxPriorityFeeInWEI = gweiDecToWEIBN(\n medium.suggestedMaxPriorityFeePerGas,\n );\n const highMaxPriorityFeeInWEI = gweiDecToWEIBN(\n high.suggestedMaxPriorityFeePerGas,\n );\n\n let lowerTimeBound;\n let upperTimeBound;\n\n if (effectiveMaxPriorityFee.lt(lowMaxPriorityFeeInWEI)) {\n lowerTimeBound = null;\n upperTimeBound = 'unknown' as unknownString;\n } else if (\n effectiveMaxPriorityFee.gte(lowMaxPriorityFeeInWEI) &&\n effectiveMaxPriorityFee.lt(mediumMaxPriorityFeeInWEI)\n ) {\n lowerTimeBound = low.minWaitTimeEstimate;\n upperTimeBound = low.maxWaitTimeEstimate;\n } else if (\n effectiveMaxPriorityFee.gte(mediumMaxPriorityFeeInWEI) &&\n effectiveMaxPriorityFee.lt(highMaxPriorityFeeInWEI)\n ) {\n lowerTimeBound = medium.minWaitTimeEstimate;\n upperTimeBound = medium.maxWaitTimeEstimate;\n } else if (effectiveMaxPriorityFee.eq(highMaxPriorityFeeInWEI)) {\n lowerTimeBound = high.minWaitTimeEstimate;\n upperTimeBound = high.maxWaitTimeEstimate;\n } else {\n lowerTimeBound = 0;\n upperTimeBound = high.maxWaitTimeEstimate;\n }\n\n return {\n lowerTimeBound,\n upperTimeBound,\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './GasFeeController';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./GasFeeController"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC","sourcesContent":["export * from './GasFeeController';\n"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@metamask-previews/gas-fee-controller",
3
+ "version": "6.1.1-preview.d32a7cc",
4
+ "description": "Periodically calculates gas fee estimates based on various gas limits as well as other data displayed on transaction confirm screens",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Ethereum"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/core/tree/main/packages/gas-fee-controller#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/core/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/core.git"
16
+ },
17
+ "license": "MIT",
18
+ "main": "./dist/index.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist/"
22
+ ],
23
+ "scripts": {
24
+ "build:docs": "typedoc",
25
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/gas-fee-controller",
26
+ "publish:preview": "yarn npm publish --tag preview",
27
+ "test": "jest",
28
+ "test:watch": "jest --watch"
29
+ },
30
+ "dependencies": {
31
+ "@metamask-previews/base-controller": "3.2.0-preview.d32a7cc",
32
+ "@metamask-previews/controller-utils": "4.3.1-preview.d32a7cc",
33
+ "@metamask-previews/network-controller": "12.1.1-preview.d32a7cc",
34
+ "@metamask/eth-query": "^3.0.1",
35
+ "@metamask/utils": "^6.2.0",
36
+ "@types/uuid": "^8.3.0",
37
+ "ethereumjs-util": "^7.0.10",
38
+ "ethjs-unit": "^0.1.6",
39
+ "immer": "^9.0.6",
40
+ "uuid": "^8.3.2"
41
+ },
42
+ "devDependencies": {
43
+ "@metamask/auto-changelog": "^3.1.0",
44
+ "@types/jest": "^27.4.1",
45
+ "@types/jest-when": "^2.7.3",
46
+ "deepmerge": "^4.2.2",
47
+ "jest": "^27.5.1",
48
+ "jest-when": "^3.4.2",
49
+ "nock": "^13.3.1",
50
+ "sinon": "^9.2.4",
51
+ "ts-jest": "^27.1.4",
52
+ "typedoc": "^0.22.15",
53
+ "typedoc-plugin-missing-exports": "^0.22.6",
54
+ "typescript": "~4.6.3"
55
+ },
56
+ "peerDependencies": {
57
+ "@metamask-previews/network-controller": "12.1.1-preview.d32a7cc"
58
+ },
59
+ "engines": {
60
+ "node": ">=16.0.0"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public",
64
+ "registry": "https://registry.npmjs.org/"
65
+ }
66
+ }