@metamask-previews/gas-fee-controller 11.0.0-preview.3fbb6b41 → 12.0.0-preview.353ee83b
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.
- package/CHANGELOG.md +12 -1
- package/dist/GasFeeController.d.ts +2 -2
- package/dist/GasFeeController.d.ts.map +1 -1
- package/dist/GasFeeController.js +1 -1
- package/dist/GasFeeController.js.map +1 -1
- package/dist/determineGasFeeCalculations.d.ts.map +1 -1
- package/dist/determineGasFeeCalculations.js.map +1 -1
- package/dist/fetchBlockFeeHistory.d.ts.map +1 -1
- package/dist/fetchBlockFeeHistory.js.map +1 -1
- package/package.json +8 -7
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [12.0.0]
|
|
10
|
+
### Changed
|
|
11
|
+
- **BREAKING:** Bump `@metamask/network-controller` dependency and peer dependency from `^17.0.0` to `^17.1.0` ([#3695](https://github.com/MetaMask/core/pull/3695))
|
|
12
|
+
- **BREAKING:** The `GasFeeController` now detects network changes using the `NetworkController:networkDidChange` event instead of `NetworkController:stateChange` ([#3610](https://github.com/MetaMask/core/pull/3610))
|
|
13
|
+
- Additionally, the optional constructor parameter `onNetworkStateChange` has been replaced by `onNetworkDidChange`
|
|
14
|
+
- Bump `@metamask/base-controller` to `^4.0.1` ([#3695](https://github.com/MetaMask/core/pull/3695))
|
|
15
|
+
- Bump `@metamask/controller-utils` to `^8.0.1` ([#3695](https://github.com/MetaMask/core/pull/3695), [#3678](https://github.com/MetaMask/core/pull/3678), [#3667](https://github.com/MetaMask/core/pull/3667), [#3580](https://github.com/MetaMask/core/pull/3580))
|
|
16
|
+
- Bump `@metamask/polling-controller` to `^4.0.0` ([#3695](https://github.com/MetaMask/core/pull/3695), [#3667](https://github.com/MetaMask/core/pull/3667), [#3636](https://github.com/MetaMask/core/pull/3636))
|
|
17
|
+
- This update adds two new methods to each polling controller: `_startPollingByNetworkClientId` and `_stopPollingByPollingTokenSetId`. These methods are intended for internal use, and should not be called directly.
|
|
18
|
+
|
|
9
19
|
## [11.0.0]
|
|
10
20
|
### Changed
|
|
11
21
|
- **BREAKING:** Bump `@metamask/base-controller` to ^4.0.0 ([#2063](https://github.com/MetaMask/core/pull/2063))
|
|
@@ -134,7 +144,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
134
144
|
|
|
135
145
|
All changes listed after this point were applied to this package following the monorepo conversion.
|
|
136
146
|
|
|
137
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@
|
|
147
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@12.0.0...HEAD
|
|
148
|
+
[12.0.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@11.0.0...@metamask/gas-fee-controller@12.0.0
|
|
138
149
|
[11.0.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@10.0.1...@metamask/gas-fee-controller@11.0.0
|
|
139
150
|
[10.0.1]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@10.0.0...@metamask/gas-fee-controller@10.0.1
|
|
140
151
|
[10.0.0]: https://github.com/MetaMask/core/compare/@metamask/gas-fee-controller@9.0.0...@metamask/gas-fee-controller@10.0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedControllerMessenger } from '@metamask/base-controller';
|
|
2
2
|
import type { NetworkClientId, NetworkControllerGetEIP1559CompatibilityAction, NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction, NetworkControllerNetworkDidChangeEvent, NetworkState, ProviderProxy } from '@metamask/network-controller';
|
|
3
|
-
import {
|
|
3
|
+
import { StaticIntervalPollingController } from '@metamask/polling-controller';
|
|
4
4
|
import type { Hex } from '@metamask/utils';
|
|
5
5
|
export declare const LEGACY_GAS_PRICES_API_URL = "https://api.metaswap.codefi.network/gasPrices";
|
|
6
6
|
export declare type unknownString = 'unknown';
|
|
@@ -148,7 +148,7 @@ declare type GasFeeMessenger = RestrictedControllerMessenger<typeof name, GasFee
|
|
|
148
148
|
/**
|
|
149
149
|
* Controller that retrieves gas fee estimate data and polls for updated data on a set interval
|
|
150
150
|
*/
|
|
151
|
-
export declare class GasFeeController extends
|
|
151
|
+
export declare class GasFeeController extends StaticIntervalPollingController<typeof name, GasFeeState, GasFeeMessenger> {
|
|
152
152
|
#private;
|
|
153
153
|
private intervalId?;
|
|
154
154
|
private readonly intervalDelay;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeeController.d.ts","sourceRoot":"","sources":["../src/GasFeeController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC9B,MAAM,2BAA2B,CAAC;AAOnC,OAAO,KAAK,EACV,eAAe,EACf,8CAA8C,EAC9C,2CAA2C,EAC3C,+BAA+B,EAC/B,sCAAsC,EACtC,YAAY,EACZ,aAAa,EACd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"GasFeeController.d.ts","sourceRoot":"","sources":["../src/GasFeeController.ts"],"names":[],"mappings":"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"}
|
package/dist/GasFeeController.js
CHANGED
|
@@ -64,7 +64,7 @@ const defaultState = {
|
|
|
64
64
|
/**
|
|
65
65
|
* Controller that retrieves gas fee estimate data and polls for updated data on a set interval
|
|
66
66
|
*/
|
|
67
|
-
class GasFeeController extends polling_controller_1.
|
|
67
|
+
class GasFeeController extends polling_controller_1.StaticIntervalPollingController {
|
|
68
68
|
/**
|
|
69
69
|
* Creates a GasFeeController instance.
|
|
70
70
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GasFeeController.js","sourceRoot":"","sources":["../src/GasFeeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n convertHexToDecimal,\n safelyExecute,\n toHex,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetEIP1559CompatibilityAction,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkDidChangeEvent,\n NetworkState,\n ProviderProxy,\n} from '@metamask/network-controller';\nimport { PollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { v1 as random } from 'uuid';\n\nimport determineGasFeeCalculations from './determineGasFeeCalculations';\nimport fetchGasEstimatesViaEthFeeHistory from './fetchGasEstimatesViaEthFeeHistory';\nimport {\n fetchGasEstimates,\n fetchLegacyGasPriceEstimates,\n fetchEthGasPriceEstimate,\n calculateTimeEstimate,\n} from './gas-util';\n\nexport const LEGACY_GAS_PRICES_API_URL = `https://api.metaswap.codefi.network/gasPrices`;\n\nexport type unknownString = 'unknown';\n\n// Fee Market describes the way gas is set after the london hardfork, and was\n// defined by EIP-1559.\nexport type FeeMarketEstimateType = 'fee-market';\n// Legacy describes gasPrice estimates from before london hardfork, when the\n// user is connected to mainnet and are presented with fast/average/slow\n// estimate levels to choose from.\nexport type LegacyEstimateType = 'legacy';\n// EthGasPrice describes a gasPrice estimate received from eth_gasPrice. Post\n// london this value should only be used for legacy type transactions when on\n// networks that support EIP-1559. This type of estimate is the most accurate\n// to display on custom networks that don't support EIP-1559.\nexport type EthGasPriceEstimateType = 'eth_gasPrice';\n// NoEstimate describes the state of the controller before receiving its first\n// estimate.\nexport type NoEstimateType = 'none';\n\n/**\n * Indicates which type of gasEstimate the controller is currently returning.\n * This is useful as a way of asserting that the shape of gasEstimates matches\n * expectations. NONE is a special case indicating that no previous gasEstimate\n * has been fetched.\n */\nexport const GAS_ESTIMATE_TYPES = {\n FEE_MARKET: 'fee-market' as FeeMarketEstimateType,\n LEGACY: 'legacy' as LegacyEstimateType,\n ETH_GASPRICE: 'eth_gasPrice' as EthGasPriceEstimateType,\n NONE: 'none' as NoEstimateType,\n};\n\nexport type GasEstimateType =\n | FeeMarketEstimateType\n | EthGasPriceEstimateType\n | LegacyEstimateType\n | NoEstimateType;\n\nexport type EstimatedGasFeeTimeBounds = {\n lowerTimeBound: number | null;\n upperTimeBound: number | unknownString;\n};\n\n/**\n * @type EthGasPriceEstimate\n *\n * A single gas price estimate for networks and accounts that don't support EIP-1559\n * This estimate comes from eth_gasPrice but is converted to dec gwei to match other\n * return values\n * @property gasPrice - A GWEI dec string\n */\n\nexport type EthGasPriceEstimate = {\n gasPrice: string;\n};\n\n/**\n * @type LegacyGasPriceEstimate\n *\n * A set of gas price estimates for networks and accounts that don't support EIP-1559\n * These estimates include low, medium and high all as strings representing gwei in\n * decimal format.\n * @property high - gasPrice, in decimal gwei string format, suggested for fast inclusion\n * @property medium - gasPrice, in decimal gwei string format, suggested for avg inclusion\n * @property low - gasPrice, in decimal gwei string format, suggested for slow inclusion\n */\nexport type LegacyGasPriceEstimate = {\n high: string;\n medium: string;\n low: string;\n};\n\n/**\n * @type Eip1559GasFee\n *\n * Data necessary to provide an estimate of a gas fee with a specific tip\n * @property minWaitTimeEstimate - The fastest the transaction will take, in milliseconds\n * @property maxWaitTimeEstimate - The slowest the transaction will take, in milliseconds\n * @property suggestedMaxPriorityFeePerGas - A suggested \"tip\", a GWEI hex number\n * @property suggestedMaxFeePerGas - A suggested max fee, the most a user will pay. a GWEI hex number\n */\nexport type Eip1559GasFee = {\n minWaitTimeEstimate: number; // a time duration in milliseconds\n maxWaitTimeEstimate: number; // a time duration in milliseconds\n suggestedMaxPriorityFeePerGas: string; // a GWEI decimal number\n suggestedMaxFeePerGas: string; // a GWEI decimal number\n};\n\n/**\n * @type GasFeeEstimates\n *\n * Data necessary to provide multiple GasFee estimates, and supporting information, to the user\n * @property low - A GasFee for a minimum necessary combination of tip and maxFee\n * @property medium - A GasFee for a recommended combination of tip and maxFee\n * @property high - A GasFee for a high combination of tip and maxFee\n * @property estimatedBaseFee - An estimate of what the base fee will be for the pending/next block. A GWEI dec number\n * @property networkCongestion - A normalized number that can be used to gauge the congestion\n * level of the network, with 0 meaning not congested and 1 meaning extremely congested\n */\nexport type GasFeeEstimates = SourcedGasFeeEstimates | FallbackGasFeeEstimates;\n\ntype SourcedGasFeeEstimates = {\n low: Eip1559GasFee;\n medium: Eip1559GasFee;\n high: Eip1559GasFee;\n estimatedBaseFee: string;\n historicalBaseFeeRange: [string, string];\n baseFeeTrend: 'up' | 'down' | 'level';\n latestPriorityFeeRange: [string, string];\n historicalPriorityFeeRange: [string, string];\n priorityFeeTrend: 'up' | 'down' | 'level';\n networkCongestion: number;\n};\n\ntype FallbackGasFeeEstimates = {\n low: Eip1559GasFee;\n medium: Eip1559GasFee;\n high: Eip1559GasFee;\n estimatedBaseFee: string;\n historicalBaseFeeRange: null;\n baseFeeTrend: null;\n latestPriorityFeeRange: null;\n historicalPriorityFeeRange: null;\n priorityFeeTrend: null;\n networkCongestion: null;\n};\n\nconst metadata = {\n gasFeeEstimatesByChainId: {\n persist: true,\n anonymous: false,\n },\n gasFeeEstimates: { persist: true, anonymous: false },\n estimatedGasFeeTimeBounds: { persist: true, anonymous: false },\n gasEstimateType: { persist: true, anonymous: false },\n};\n\nexport type GasFeeStateEthGasPrice = {\n gasFeeEstimates: EthGasPriceEstimate;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: EthGasPriceEstimateType;\n};\n\nexport type GasFeeStateFeeMarket = {\n gasFeeEstimates: GasFeeEstimates;\n estimatedGasFeeTimeBounds: EstimatedGasFeeTimeBounds | Record<string, never>;\n gasEstimateType: FeeMarketEstimateType;\n};\n\nexport type GasFeeStateLegacy = {\n gasFeeEstimates: LegacyGasPriceEstimate;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: LegacyEstimateType;\n};\n\nexport type GasFeeStateNoEstimates = {\n gasFeeEstimates: Record<string, never>;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: NoEstimateType;\n};\n\nexport type FetchGasFeeEstimateOptions = {\n shouldUpdateState?: boolean;\n networkClientId?: NetworkClientId;\n};\n\n/**\n * @type GasFeeState\n *\n * Gas Fee controller state\n * @property gasFeeEstimates - Gas fee estimate data based on new EIP-1559 properties\n * @property estimatedGasFeeTimeBounds - Estimates representing the minimum and maximum\n */\nexport type SingleChainGasFeeState =\n | GasFeeStateEthGasPrice\n | GasFeeStateFeeMarket\n | GasFeeStateLegacy\n | GasFeeStateNoEstimates;\n\nexport type GasFeeEstimatesByChainId = {\n gasFeeEstimatesByChainId?: Record<string, SingleChainGasFeeState>;\n};\n\nexport type GasFeeState = GasFeeEstimatesByChainId & SingleChainGasFeeState;\n\nconst name = 'GasFeeController';\n\nexport type GasFeeStateChange = ControllerStateChangeEvent<\n typeof name,\n GasFeeState\n>;\n\nexport type GetGasFeeState = ControllerGetStateAction<typeof name, GasFeeState>;\n\nexport type GasFeeControllerActions = GetGasFeeState;\n\nexport type GasFeeControllerEvents = GasFeeStateChange;\n\ntype AllowedActions =\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetEIP1559CompatibilityAction;\n\ntype GasFeeMessenger = RestrictedControllerMessenger<\n typeof name,\n GasFeeControllerActions | AllowedActions,\n GasFeeControllerEvents | NetworkControllerNetworkDidChangeEvent,\n AllowedActions['type'],\n NetworkControllerNetworkDidChangeEvent['type']\n>;\n\nconst defaultState: GasFeeState = {\n gasFeeEstimatesByChainId: {},\n gasFeeEstimates: {},\n estimatedGasFeeTimeBounds: {},\n gasEstimateType: GAS_ESTIMATE_TYPES.NONE,\n};\n\n/**\n * Controller that retrieves gas fee estimate data and polls for updated data on a set interval\n */\nexport class GasFeeController extends PollingController<\n typeof name,\n GasFeeState,\n GasFeeMessenger\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay;\n\n private readonly pollTokens: Set<string>;\n\n private readonly legacyAPIEndpoint: string;\n\n private readonly EIP1559APIEndpoint: string;\n\n private readonly getCurrentNetworkEIP1559Compatibility;\n\n private readonly getCurrentNetworkLegacyGasAPICompatibility;\n\n private readonly getCurrentAccountEIP1559Compatibility;\n\n private currentChainId;\n\n private ethQuery?: EthQuery;\n\n private readonly clientId?: string;\n\n #getProvider: () => ProviderProxy;\n\n /**\n * Creates a GasFeeController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The time in milliseconds to wait between polls.\n * @param options.messenger - The controller messenger.\n * @param options.state - The initial state.\n * @param options.getCurrentNetworkEIP1559Compatibility - Determines whether or not the current\n * network is EIP-1559 compatible.\n * @param options.getCurrentNetworkLegacyGasAPICompatibility - Determines whether or not the\n * current network is compatible with the legacy gas price API.\n * @param options.getCurrentAccountEIP1559Compatibility - Determines whether or not the current\n * account is EIP-1559 compatible.\n * @param options.getChainId - Returns the current chain ID.\n * @param options.getProvider - Returns a network provider for the current network.\n * @param options.onNetworkDidChange - A function for registering an event handler for the\n * network state change event.\n * @param options.legacyAPIEndpoint - The legacy gas price API URL. This option is primarily for\n * testing purposes.\n * @param options.EIP1559APIEndpoint - The EIP-1559 gas price API URL.\n * @param options.clientId - The client ID used to identify to the gas estimation API who is\n * asking for estimates.\n */\n constructor({\n interval = 15000,\n messenger,\n state,\n getCurrentNetworkEIP1559Compatibility,\n getCurrentAccountEIP1559Compatibility,\n getChainId,\n getCurrentNetworkLegacyGasAPICompatibility,\n getProvider,\n onNetworkDidChange,\n legacyAPIEndpoint = LEGACY_GAS_PRICES_API_URL,\n EIP1559APIEndpoint,\n clientId,\n }: {\n interval?: number;\n messenger: GasFeeMessenger;\n state?: GasFeeState;\n getCurrentNetworkEIP1559Compatibility: () => Promise<boolean>;\n getCurrentNetworkLegacyGasAPICompatibility: () => boolean;\n getCurrentAccountEIP1559Compatibility?: () => boolean;\n getChainId?: () => Hex;\n getProvider: () => ProviderProxy;\n onNetworkDidChange?: (listener: (state: NetworkState) => void) => void;\n legacyAPIEndpoint?: string;\n EIP1559APIEndpoint: string;\n clientId?: string;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.intervalDelay = interval;\n this.setIntervalLength(interval);\n this.pollTokens = new Set();\n this.getCurrentNetworkEIP1559Compatibility =\n getCurrentNetworkEIP1559Compatibility;\n this.getCurrentNetworkLegacyGasAPICompatibility =\n getCurrentNetworkLegacyGasAPICompatibility;\n this.getCurrentAccountEIP1559Compatibility =\n getCurrentAccountEIP1559Compatibility;\n this.#getProvider = getProvider;\n this.EIP1559APIEndpoint = EIP1559APIEndpoint;\n this.legacyAPIEndpoint = legacyAPIEndpoint;\n this.clientId = clientId;\n\n this.ethQuery = new EthQuery(this.#getProvider());\n\n if (onNetworkDidChange && getChainId) {\n this.currentChainId = getChainId();\n onNetworkDidChange(async (networkControllerState) => {\n await this.#onNetworkControllerDidChange(networkControllerState);\n });\n } else {\n this.currentChainId = this.messagingSystem.call(\n 'NetworkController:getState',\n ).providerConfig.chainId;\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\n async (networkControllerState) => {\n await this.#onNetworkControllerDidChange(networkControllerState);\n },\n );\n }\n }\n\n async resetPolling() {\n if (this.pollTokens.size !== 0) {\n const tokens = Array.from(this.pollTokens);\n this.stopPolling();\n await this.getGasFeeEstimatesAndStartPolling(tokens[0]);\n tokens.slice(1).forEach((token) => {\n this.pollTokens.add(token);\n });\n }\n }\n\n async fetchGasFeeEstimates(options?: FetchGasFeeEstimateOptions) {\n return await this._fetchGasFeeEstimateData(options);\n }\n\n async getGasFeeEstimatesAndStartPolling(\n pollToken: string | undefined,\n ): Promise<string> {\n const _pollToken = pollToken || random();\n\n this.pollTokens.add(_pollToken);\n\n if (this.pollTokens.size === 1) {\n await this._fetchGasFeeEstimateData();\n this._poll();\n }\n\n return _pollToken;\n }\n\n /**\n * Gets and sets gasFeeEstimates in state.\n *\n * @param options - The gas fee estimate options.\n * @param options.shouldUpdateState - Determines whether the state should be updated with the\n * updated gas estimates.\n * @returns The gas fee estimates.\n */\n async _fetchGasFeeEstimateData(\n options: FetchGasFeeEstimateOptions = {},\n ): Promise<GasFeeState> {\n const { shouldUpdateState = true, networkClientId } = options;\n\n let ethQuery,\n isEIP1559Compatible,\n isLegacyGasAPICompatible,\n decimalChainId: number;\n\n if (networkClientId !== undefined) {\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n isLegacyGasAPICompatible = networkClient.configuration.chainId === '0x38';\n\n decimalChainId = convertHexToDecimal(networkClient.configuration.chainId);\n\n try {\n const result = await this.messagingSystem.call(\n 'NetworkController:getEIP1559Compatibility',\n networkClientId,\n );\n isEIP1559Compatible = result || false;\n } catch {\n isEIP1559Compatible = false;\n }\n ethQuery = new EthQuery(networkClient.provider);\n }\n\n ethQuery ??= this.ethQuery;\n\n isLegacyGasAPICompatible ??=\n this.getCurrentNetworkLegacyGasAPICompatibility();\n\n decimalChainId ??= convertHexToDecimal(this.currentChainId);\n\n try {\n isEIP1559Compatible ??= await this.getEIP1559Compatibility();\n } catch (e) {\n console.error(e);\n isEIP1559Compatible ??= false;\n }\n\n const gasFeeCalculations = await determineGasFeeCalculations({\n isEIP1559Compatible,\n isLegacyGasAPICompatible,\n fetchGasEstimates,\n fetchGasEstimatesUrl: this.EIP1559APIEndpoint.replace(\n '<chain_id>',\n `${decimalChainId}`,\n ),\n fetchGasEstimatesViaEthFeeHistory,\n fetchLegacyGasPriceEstimates,\n fetchLegacyGasPriceEstimatesUrl: this.legacyAPIEndpoint.replace(\n '<chain_id>',\n `${decimalChainId}`,\n ),\n fetchEthGasPriceEstimate,\n calculateTimeEstimate,\n clientId: this.clientId,\n ethQuery,\n });\n\n if (shouldUpdateState) {\n this.update((state) => {\n state.gasFeeEstimates = gasFeeCalculations.gasFeeEstimates;\n state.estimatedGasFeeTimeBounds =\n gasFeeCalculations.estimatedGasFeeTimeBounds;\n state.gasEstimateType = gasFeeCalculations.gasEstimateType;\n state.gasFeeEstimatesByChainId ??= {};\n state.gasFeeEstimatesByChainId[toHex(decimalChainId)] = {\n gasFeeEstimates: gasFeeCalculations.gasFeeEstimates,\n estimatedGasFeeTimeBounds:\n gasFeeCalculations.estimatedGasFeeTimeBounds,\n gasEstimateType: gasFeeCalculations.gasEstimateType,\n } as SingleChainGasFeeState;\n });\n }\n\n return gasFeeCalculations;\n }\n\n /**\n * Remove the poll token, and stop polling if the set of poll tokens is empty.\n *\n * @param pollToken - The poll token to disconnect.\n */\n disconnectPoller(pollToken: string) {\n this.pollTokens.delete(pollToken);\n if (this.pollTokens.size === 0) {\n this.stopPolling();\n }\n }\n\n stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n this.pollTokens.clear();\n this.resetState();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private _poll() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this._fetchGasFeeEstimateData());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll(networkClientId: string): Promise<void> {\n await this._fetchGasFeeEstimateData({ networkClientId });\n }\n\n private resetState() {\n this.update(() => {\n return defaultState;\n });\n }\n\n private async getEIP1559Compatibility() {\n const currentNetworkIsEIP1559Compatible =\n await this.getCurrentNetworkEIP1559Compatibility();\n const currentAccountIsEIP1559Compatible =\n this.getCurrentAccountEIP1559Compatibility?.() ?? true;\n\n return (\n currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible\n );\n }\n\n getTimeEstimate(\n maxPriorityFeePerGas: string,\n maxFeePerGas: string,\n ): EstimatedGasFeeTimeBounds | Record<string, never> {\n if (\n !this.state.gasFeeEstimates ||\n this.state.gasEstimateType !== GAS_ESTIMATE_TYPES.FEE_MARKET\n ) {\n return {};\n }\n return calculateTimeEstimate(\n maxPriorityFeePerGas,\n maxFeePerGas,\n this.state.gasFeeEstimates,\n );\n }\n\n async #onNetworkControllerDidChange(networkControllerState: NetworkState) {\n const newChainId = networkControllerState.providerConfig.chainId;\n\n if (newChainId !== this.currentChainId) {\n this.ethQuery = new EthQuery(this.#getProvider());\n await this.resetPolling();\n\n this.currentChainId = newChainId;\n }\n }\n}\n\nexport default GasFeeController;\n"]}
|
|
1
|
+
{"version":3,"file":"GasFeeController.js","sourceRoot":"","sources":["../src/GasFeeController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport {\n convertHexToDecimal,\n safelyExecute,\n toHex,\n} from '@metamask/controller-utils';\nimport EthQuery from '@metamask/eth-query';\nimport type {\n NetworkClientId,\n NetworkControllerGetEIP1559CompatibilityAction,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkDidChangeEvent,\n NetworkState,\n ProviderProxy,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type { Hex } from '@metamask/utils';\nimport { v1 as random } from 'uuid';\n\nimport determineGasFeeCalculations from './determineGasFeeCalculations';\nimport fetchGasEstimatesViaEthFeeHistory from './fetchGasEstimatesViaEthFeeHistory';\nimport {\n fetchGasEstimates,\n fetchLegacyGasPriceEstimates,\n fetchEthGasPriceEstimate,\n calculateTimeEstimate,\n} from './gas-util';\n\nexport const LEGACY_GAS_PRICES_API_URL = `https://api.metaswap.codefi.network/gasPrices`;\n\nexport type unknownString = 'unknown';\n\n// Fee Market describes the way gas is set after the london hardfork, and was\n// defined by EIP-1559.\nexport type FeeMarketEstimateType = 'fee-market';\n// Legacy describes gasPrice estimates from before london hardfork, when the\n// user is connected to mainnet and are presented with fast/average/slow\n// estimate levels to choose from.\nexport type LegacyEstimateType = 'legacy';\n// EthGasPrice describes a gasPrice estimate received from eth_gasPrice. Post\n// london this value should only be used for legacy type transactions when on\n// networks that support EIP-1559. This type of estimate is the most accurate\n// to display on custom networks that don't support EIP-1559.\nexport type EthGasPriceEstimateType = 'eth_gasPrice';\n// NoEstimate describes the state of the controller before receiving its first\n// estimate.\nexport type NoEstimateType = 'none';\n\n/**\n * Indicates which type of gasEstimate the controller is currently returning.\n * This is useful as a way of asserting that the shape of gasEstimates matches\n * expectations. NONE is a special case indicating that no previous gasEstimate\n * has been fetched.\n */\nexport const GAS_ESTIMATE_TYPES = {\n FEE_MARKET: 'fee-market' as FeeMarketEstimateType,\n LEGACY: 'legacy' as LegacyEstimateType,\n ETH_GASPRICE: 'eth_gasPrice' as EthGasPriceEstimateType,\n NONE: 'none' as NoEstimateType,\n};\n\nexport type GasEstimateType =\n | FeeMarketEstimateType\n | EthGasPriceEstimateType\n | LegacyEstimateType\n | NoEstimateType;\n\nexport type EstimatedGasFeeTimeBounds = {\n lowerTimeBound: number | null;\n upperTimeBound: number | unknownString;\n};\n\n/**\n * @type EthGasPriceEstimate\n *\n * A single gas price estimate for networks and accounts that don't support EIP-1559\n * This estimate comes from eth_gasPrice but is converted to dec gwei to match other\n * return values\n * @property gasPrice - A GWEI dec string\n */\n\nexport type EthGasPriceEstimate = {\n gasPrice: string;\n};\n\n/**\n * @type LegacyGasPriceEstimate\n *\n * A set of gas price estimates for networks and accounts that don't support EIP-1559\n * These estimates include low, medium and high all as strings representing gwei in\n * decimal format.\n * @property high - gasPrice, in decimal gwei string format, suggested for fast inclusion\n * @property medium - gasPrice, in decimal gwei string format, suggested for avg inclusion\n * @property low - gasPrice, in decimal gwei string format, suggested for slow inclusion\n */\nexport type LegacyGasPriceEstimate = {\n high: string;\n medium: string;\n low: string;\n};\n\n/**\n * @type Eip1559GasFee\n *\n * Data necessary to provide an estimate of a gas fee with a specific tip\n * @property minWaitTimeEstimate - The fastest the transaction will take, in milliseconds\n * @property maxWaitTimeEstimate - The slowest the transaction will take, in milliseconds\n * @property suggestedMaxPriorityFeePerGas - A suggested \"tip\", a GWEI hex number\n * @property suggestedMaxFeePerGas - A suggested max fee, the most a user will pay. a GWEI hex number\n */\nexport type Eip1559GasFee = {\n minWaitTimeEstimate: number; // a time duration in milliseconds\n maxWaitTimeEstimate: number; // a time duration in milliseconds\n suggestedMaxPriorityFeePerGas: string; // a GWEI decimal number\n suggestedMaxFeePerGas: string; // a GWEI decimal number\n};\n\n/**\n * @type GasFeeEstimates\n *\n * Data necessary to provide multiple GasFee estimates, and supporting information, to the user\n * @property low - A GasFee for a minimum necessary combination of tip and maxFee\n * @property medium - A GasFee for a recommended combination of tip and maxFee\n * @property high - A GasFee for a high combination of tip and maxFee\n * @property estimatedBaseFee - An estimate of what the base fee will be for the pending/next block. A GWEI dec number\n * @property networkCongestion - A normalized number that can be used to gauge the congestion\n * level of the network, with 0 meaning not congested and 1 meaning extremely congested\n */\nexport type GasFeeEstimates = SourcedGasFeeEstimates | FallbackGasFeeEstimates;\n\ntype SourcedGasFeeEstimates = {\n low: Eip1559GasFee;\n medium: Eip1559GasFee;\n high: Eip1559GasFee;\n estimatedBaseFee: string;\n historicalBaseFeeRange: [string, string];\n baseFeeTrend: 'up' | 'down' | 'level';\n latestPriorityFeeRange: [string, string];\n historicalPriorityFeeRange: [string, string];\n priorityFeeTrend: 'up' | 'down' | 'level';\n networkCongestion: number;\n};\n\ntype FallbackGasFeeEstimates = {\n low: Eip1559GasFee;\n medium: Eip1559GasFee;\n high: Eip1559GasFee;\n estimatedBaseFee: string;\n historicalBaseFeeRange: null;\n baseFeeTrend: null;\n latestPriorityFeeRange: null;\n historicalPriorityFeeRange: null;\n priorityFeeTrend: null;\n networkCongestion: null;\n};\n\nconst metadata = {\n gasFeeEstimatesByChainId: {\n persist: true,\n anonymous: false,\n },\n gasFeeEstimates: { persist: true, anonymous: false },\n estimatedGasFeeTimeBounds: { persist: true, anonymous: false },\n gasEstimateType: { persist: true, anonymous: false },\n};\n\nexport type GasFeeStateEthGasPrice = {\n gasFeeEstimates: EthGasPriceEstimate;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: EthGasPriceEstimateType;\n};\n\nexport type GasFeeStateFeeMarket = {\n gasFeeEstimates: GasFeeEstimates;\n estimatedGasFeeTimeBounds: EstimatedGasFeeTimeBounds | Record<string, never>;\n gasEstimateType: FeeMarketEstimateType;\n};\n\nexport type GasFeeStateLegacy = {\n gasFeeEstimates: LegacyGasPriceEstimate;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: LegacyEstimateType;\n};\n\nexport type GasFeeStateNoEstimates = {\n gasFeeEstimates: Record<string, never>;\n estimatedGasFeeTimeBounds: Record<string, never>;\n gasEstimateType: NoEstimateType;\n};\n\nexport type FetchGasFeeEstimateOptions = {\n shouldUpdateState?: boolean;\n networkClientId?: NetworkClientId;\n};\n\n/**\n * @type GasFeeState\n *\n * Gas Fee controller state\n * @property gasFeeEstimates - Gas fee estimate data based on new EIP-1559 properties\n * @property estimatedGasFeeTimeBounds - Estimates representing the minimum and maximum\n */\nexport type SingleChainGasFeeState =\n | GasFeeStateEthGasPrice\n | GasFeeStateFeeMarket\n | GasFeeStateLegacy\n | GasFeeStateNoEstimates;\n\nexport type GasFeeEstimatesByChainId = {\n gasFeeEstimatesByChainId?: Record<string, SingleChainGasFeeState>;\n};\n\nexport type GasFeeState = GasFeeEstimatesByChainId & SingleChainGasFeeState;\n\nconst name = 'GasFeeController';\n\nexport type GasFeeStateChange = ControllerStateChangeEvent<\n typeof name,\n GasFeeState\n>;\n\nexport type GetGasFeeState = ControllerGetStateAction<typeof name, GasFeeState>;\n\nexport type GasFeeControllerActions = GetGasFeeState;\n\nexport type GasFeeControllerEvents = GasFeeStateChange;\n\ntype AllowedActions =\n | NetworkControllerGetStateAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetEIP1559CompatibilityAction;\n\ntype GasFeeMessenger = RestrictedControllerMessenger<\n typeof name,\n GasFeeControllerActions | AllowedActions,\n GasFeeControllerEvents | NetworkControllerNetworkDidChangeEvent,\n AllowedActions['type'],\n NetworkControllerNetworkDidChangeEvent['type']\n>;\n\nconst defaultState: GasFeeState = {\n gasFeeEstimatesByChainId: {},\n gasFeeEstimates: {},\n estimatedGasFeeTimeBounds: {},\n gasEstimateType: GAS_ESTIMATE_TYPES.NONE,\n};\n\n/**\n * Controller that retrieves gas fee estimate data and polls for updated data on a set interval\n */\nexport class GasFeeController extends StaticIntervalPollingController<\n typeof name,\n GasFeeState,\n GasFeeMessenger\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay;\n\n private readonly pollTokens: Set<string>;\n\n private readonly legacyAPIEndpoint: string;\n\n private readonly EIP1559APIEndpoint: string;\n\n private readonly getCurrentNetworkEIP1559Compatibility;\n\n private readonly getCurrentNetworkLegacyGasAPICompatibility;\n\n private readonly getCurrentAccountEIP1559Compatibility;\n\n private currentChainId;\n\n private ethQuery?: EthQuery;\n\n private readonly clientId?: string;\n\n #getProvider: () => ProviderProxy;\n\n /**\n * Creates a GasFeeController instance.\n *\n * @param options - The controller options.\n * @param options.interval - The time in milliseconds to wait between polls.\n * @param options.messenger - The controller messenger.\n * @param options.state - The initial state.\n * @param options.getCurrentNetworkEIP1559Compatibility - Determines whether or not the current\n * network is EIP-1559 compatible.\n * @param options.getCurrentNetworkLegacyGasAPICompatibility - Determines whether or not the\n * current network is compatible with the legacy gas price API.\n * @param options.getCurrentAccountEIP1559Compatibility - Determines whether or not the current\n * account is EIP-1559 compatible.\n * @param options.getChainId - Returns the current chain ID.\n * @param options.getProvider - Returns a network provider for the current network.\n * @param options.onNetworkDidChange - A function for registering an event handler for the\n * network state change event.\n * @param options.legacyAPIEndpoint - The legacy gas price API URL. This option is primarily for\n * testing purposes.\n * @param options.EIP1559APIEndpoint - The EIP-1559 gas price API URL.\n * @param options.clientId - The client ID used to identify to the gas estimation API who is\n * asking for estimates.\n */\n constructor({\n interval = 15000,\n messenger,\n state,\n getCurrentNetworkEIP1559Compatibility,\n getCurrentAccountEIP1559Compatibility,\n getChainId,\n getCurrentNetworkLegacyGasAPICompatibility,\n getProvider,\n onNetworkDidChange,\n legacyAPIEndpoint = LEGACY_GAS_PRICES_API_URL,\n EIP1559APIEndpoint,\n clientId,\n }: {\n interval?: number;\n messenger: GasFeeMessenger;\n state?: GasFeeState;\n getCurrentNetworkEIP1559Compatibility: () => Promise<boolean>;\n getCurrentNetworkLegacyGasAPICompatibility: () => boolean;\n getCurrentAccountEIP1559Compatibility?: () => boolean;\n getChainId?: () => Hex;\n getProvider: () => ProviderProxy;\n onNetworkDidChange?: (listener: (state: NetworkState) => void) => void;\n legacyAPIEndpoint?: string;\n EIP1559APIEndpoint: string;\n clientId?: string;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.intervalDelay = interval;\n this.setIntervalLength(interval);\n this.pollTokens = new Set();\n this.getCurrentNetworkEIP1559Compatibility =\n getCurrentNetworkEIP1559Compatibility;\n this.getCurrentNetworkLegacyGasAPICompatibility =\n getCurrentNetworkLegacyGasAPICompatibility;\n this.getCurrentAccountEIP1559Compatibility =\n getCurrentAccountEIP1559Compatibility;\n this.#getProvider = getProvider;\n this.EIP1559APIEndpoint = EIP1559APIEndpoint;\n this.legacyAPIEndpoint = legacyAPIEndpoint;\n this.clientId = clientId;\n\n this.ethQuery = new EthQuery(this.#getProvider());\n\n if (onNetworkDidChange && getChainId) {\n this.currentChainId = getChainId();\n onNetworkDidChange(async (networkControllerState) => {\n await this.#onNetworkControllerDidChange(networkControllerState);\n });\n } else {\n this.currentChainId = this.messagingSystem.call(\n 'NetworkController:getState',\n ).providerConfig.chainId;\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\n async (networkControllerState) => {\n await this.#onNetworkControllerDidChange(networkControllerState);\n },\n );\n }\n }\n\n async resetPolling() {\n if (this.pollTokens.size !== 0) {\n const tokens = Array.from(this.pollTokens);\n this.stopPolling();\n await this.getGasFeeEstimatesAndStartPolling(tokens[0]);\n tokens.slice(1).forEach((token) => {\n this.pollTokens.add(token);\n });\n }\n }\n\n async fetchGasFeeEstimates(options?: FetchGasFeeEstimateOptions) {\n return await this._fetchGasFeeEstimateData(options);\n }\n\n async getGasFeeEstimatesAndStartPolling(\n pollToken: string | undefined,\n ): Promise<string> {\n const _pollToken = pollToken || random();\n\n this.pollTokens.add(_pollToken);\n\n if (this.pollTokens.size === 1) {\n await this._fetchGasFeeEstimateData();\n this._poll();\n }\n\n return _pollToken;\n }\n\n /**\n * Gets and sets gasFeeEstimates in state.\n *\n * @param options - The gas fee estimate options.\n * @param options.shouldUpdateState - Determines whether the state should be updated with the\n * updated gas estimates.\n * @returns The gas fee estimates.\n */\n async _fetchGasFeeEstimateData(\n options: FetchGasFeeEstimateOptions = {},\n ): Promise<GasFeeState> {\n const { shouldUpdateState = true, networkClientId } = options;\n\n let ethQuery,\n isEIP1559Compatible,\n isLegacyGasAPICompatible,\n decimalChainId: number;\n\n if (networkClientId !== undefined) {\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n isLegacyGasAPICompatible = networkClient.configuration.chainId === '0x38';\n\n decimalChainId = convertHexToDecimal(networkClient.configuration.chainId);\n\n try {\n const result = await this.messagingSystem.call(\n 'NetworkController:getEIP1559Compatibility',\n networkClientId,\n );\n isEIP1559Compatible = result || false;\n } catch {\n isEIP1559Compatible = false;\n }\n ethQuery = new EthQuery(networkClient.provider);\n }\n\n ethQuery ??= this.ethQuery;\n\n isLegacyGasAPICompatible ??=\n this.getCurrentNetworkLegacyGasAPICompatibility();\n\n decimalChainId ??= convertHexToDecimal(this.currentChainId);\n\n try {\n isEIP1559Compatible ??= await this.getEIP1559Compatibility();\n } catch (e) {\n console.error(e);\n isEIP1559Compatible ??= false;\n }\n\n const gasFeeCalculations = await determineGasFeeCalculations({\n isEIP1559Compatible,\n isLegacyGasAPICompatible,\n fetchGasEstimates,\n fetchGasEstimatesUrl: this.EIP1559APIEndpoint.replace(\n '<chain_id>',\n `${decimalChainId}`,\n ),\n fetchGasEstimatesViaEthFeeHistory,\n fetchLegacyGasPriceEstimates,\n fetchLegacyGasPriceEstimatesUrl: this.legacyAPIEndpoint.replace(\n '<chain_id>',\n `${decimalChainId}`,\n ),\n fetchEthGasPriceEstimate,\n calculateTimeEstimate,\n clientId: this.clientId,\n ethQuery,\n });\n\n if (shouldUpdateState) {\n this.update((state) => {\n state.gasFeeEstimates = gasFeeCalculations.gasFeeEstimates;\n state.estimatedGasFeeTimeBounds =\n gasFeeCalculations.estimatedGasFeeTimeBounds;\n state.gasEstimateType = gasFeeCalculations.gasEstimateType;\n state.gasFeeEstimatesByChainId ??= {};\n state.gasFeeEstimatesByChainId[toHex(decimalChainId)] = {\n gasFeeEstimates: gasFeeCalculations.gasFeeEstimates,\n estimatedGasFeeTimeBounds:\n gasFeeCalculations.estimatedGasFeeTimeBounds,\n gasEstimateType: gasFeeCalculations.gasEstimateType,\n } as SingleChainGasFeeState;\n });\n }\n\n return gasFeeCalculations;\n }\n\n /**\n * Remove the poll token, and stop polling if the set of poll tokens is empty.\n *\n * @param pollToken - The poll token to disconnect.\n */\n disconnectPoller(pollToken: string) {\n this.pollTokens.delete(pollToken);\n if (this.pollTokens.size === 0) {\n this.stopPolling();\n }\n }\n\n stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n this.pollTokens.clear();\n this.resetState();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private _poll() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this._fetchGasFeeEstimateData());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n *\n * @private\n * @param networkClientId - The ID of the network client triggering the fetch.\n * @returns A promise that resolves when this operation completes.\n */\n async _executePoll(networkClientId: string): Promise<void> {\n await this._fetchGasFeeEstimateData({ networkClientId });\n }\n\n private resetState() {\n this.update(() => {\n return defaultState;\n });\n }\n\n private async getEIP1559Compatibility() {\n const currentNetworkIsEIP1559Compatible =\n await this.getCurrentNetworkEIP1559Compatibility();\n const currentAccountIsEIP1559Compatible =\n this.getCurrentAccountEIP1559Compatibility?.() ?? true;\n\n return (\n currentNetworkIsEIP1559Compatible && currentAccountIsEIP1559Compatible\n );\n }\n\n getTimeEstimate(\n maxPriorityFeePerGas: string,\n maxFeePerGas: string,\n ): EstimatedGasFeeTimeBounds | Record<string, never> {\n if (\n !this.state.gasFeeEstimates ||\n this.state.gasEstimateType !== GAS_ESTIMATE_TYPES.FEE_MARKET\n ) {\n return {};\n }\n return calculateTimeEstimate(\n maxPriorityFeePerGas,\n maxFeePerGas,\n this.state.gasFeeEstimates,\n );\n }\n\n async #onNetworkControllerDidChange(networkControllerState: NetworkState) {\n const newChainId = networkControllerState.providerConfig.chainId;\n\n if (newChainId !== this.currentChainId) {\n this.ethQuery = new EthQuery(this.#getProvider());\n await this.resetPolling();\n\n this.currentChainId = newChainId;\n }\n }\n}\n\nexport default GasFeeController;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"determineGasFeeCalculations.d.ts","sourceRoot":"","sources":["../src/determineGasFeeCalculations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,WAAW,IAAI,kBAAkB,EACjC,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAA8B,2BAA2B,CAAC,EACxD,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,mBAAmB,EAAE,OAAO,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,iBAAiB,EAAE,CACjB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iCAAiC,EAAE,
|
|
1
|
+
{"version":3,"file":"determineGasFeeCalculations.d.ts","sourceRoot":"","sources":["../src/determineGasFeeCalculations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,eAAe,EACf,WAAW,IAAI,kBAAkB,EACjC,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAA8B,2BAA2B,CAAC,EACxD,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,mBAAmB,EAAE,OAAO,CAAC;IAC7B,wBAAwB,EAAE,OAAO,CAAC;IAClC,iBAAiB,EAAE,CACjB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,iCAAiC,EAAE,CAGjC,QAAQ,EAAE,GAAG,KACV,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9B,4BAA4B,EAAE,CAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACrC,+BAA+B,EAAE,MAAM,CAAC;IAGxC,wBAAwB,EAAE,CAAC,QAAQ,EAAE,GAAG,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC1E,qBAAqB,EAAE,CACrB,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,eAAe,KAC7B,yBAAyB,CAAC;IAC/B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAG7B,QAAQ,EAAE,GAAG,CAAC;CACf,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkD9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"determineGasFeeCalculations.js","sourceRoot":"","sources":["../src/determineGasFeeCalculations.ts"],"names":[],"mappings":";;;;;;;;;;;AAOA,yDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAA8B,2BAA2B,CAAC,EACxD,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,
|
|
1
|
+
{"version":3,"file":"determineGasFeeCalculations.js","sourceRoot":"","sources":["../src/determineGasFeeCalculations.ts"],"names":[],"mappings":";;;;;;;;;;;AAOA,yDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAA8B,2BAA2B,CAAC,EACxD,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,iCAAiC,EACjC,4BAA4B,EAC5B,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,QAAQ,EACR,QAAQ,GA+BT;;QACC,IAAI;YACF,IAAI,mBAAmB,EAAE;gBACvB,IAAI,SAA0B,CAAC;gBAC/B,IAAI;oBACF,SAAS,GAAG,MAAM,iBAAiB,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;iBACrE;gBAAC,WAAM;oBACN,SAAS,GAAG,MAAM,iCAAiC,CAAC,QAAQ,CAAC,CAAC;iBAC/D;gBACD,MAAM,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,GAC5D,SAAS,CAAC,MAAM,CAAC;gBACnB,MAAM,yBAAyB,GAAG,qBAAqB,CACrD,6BAA6B,EAC7B,qBAAqB,EACrB,SAAS,CACV,CAAC;gBACF,OAAO;oBACL,eAAe,EAAE,SAAS;oBAC1B,yBAAyB;oBACzB,eAAe,EAAE,qCAAkB,CAAC,UAAU;iBAC/C,CAAC;aACH;iBAAM,IAAI,wBAAwB,EAAE;gBACnC,MAAM,SAAS,GAAG,MAAM,4BAA4B,CAClD,+BAA+B,EAC/B,QAAQ,CACT,CAAC;gBACF,OAAO;oBACL,eAAe,EAAE,SAAS;oBAC1B,yBAAyB,EAAE,EAAE;oBAC7B,eAAe,EAAE,qCAAkB,CAAC,MAAM;iBAC3C,CAAC;aACH;YACD,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;SACvE;QAAC,WAAM;YACN,IAAI;gBACF,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,QAAQ,CAAC,CAAC;gBAC3D,OAAO;oBACL,eAAe,EAAE,SAAS;oBAC1B,yBAAyB,EAAE,EAAE;oBAC7B,eAAe,EAAE,qCAAkB,CAAC,YAAY;iBACjD,CAAC;aACH;YAAC,OAAO,KAAK,EAAE;gBACd,IAAI,KAAK,YAAY,KAAK,EAAE;oBAC1B,MAAM,IAAI,KAAK,CACb,6CAA6C,KAAK,CAAC,OAAO,EAAE,CAC7D,CAAC;iBACH;gBACD,MAAM,KAAK,CAAC;aACb;SACF;IACH,CAAC;CAAA;AA5FD,8CA4FC","sourcesContent":["import type {\n EstimatedGasFeeTimeBounds,\n EthGasPriceEstimate,\n GasFeeEstimates,\n GasFeeState as GasFeeCalculations,\n LegacyGasPriceEstimate,\n} from './GasFeeController';\nimport { GAS_ESTIMATE_TYPES } from './GasFeeController';\n\n/**\n * Obtains a set of max base and priority fee estimates along with time estimates so that we\n * can present them to users when they are sending transactions or making swaps.\n *\n * @param args - The arguments.\n * @param args.isEIP1559Compatible - Governs whether or not we can use an EIP-1559-only method to\n * produce estimates.\n * @param args.isLegacyGasAPICompatible - Governs whether or not we can use a non-EIP-1559 method to\n * produce estimates (for instance, testnets do not support estimates altogether).\n * @param args.fetchGasEstimates - A function that fetches gas estimates using an EIP-1559-specific\n * API.\n * @param args.fetchGasEstimatesUrl - The URL for the API we can use to obtain EIP-1559-specific\n * estimates.\n * @param args.fetchGasEstimatesViaEthFeeHistory - A function that fetches gas estimates using\n * `eth_feeHistory` (an EIP-1559 feature).\n * @param args.fetchLegacyGasPriceEstimates - A function that fetches gas estimates using an\n * non-EIP-1559-specific API.\n * @param args.fetchLegacyGasPriceEstimatesUrl - The URL for the API we can use to obtain\n * non-EIP-1559-specific estimates.\n * @param args.fetchEthGasPriceEstimate - A function that fetches gas estimates using\n * `eth_gasPrice`.\n * @param args.calculateTimeEstimate - A function that determine time estimate bounds.\n * @param args.clientId - An identifier that an API can use to know who is asking for estimates.\n * @param args.ethQuery - An EthQuery instance we can use to talk to Ethereum directly.\n * @returns The gas fee calculations.\n */\nexport default async function determineGasFeeCalculations({\n isEIP1559Compatible,\n isLegacyGasAPICompatible,\n fetchGasEstimates,\n fetchGasEstimatesUrl,\n fetchGasEstimatesViaEthFeeHistory,\n fetchLegacyGasPriceEstimates,\n fetchLegacyGasPriceEstimatesUrl,\n fetchEthGasPriceEstimate,\n calculateTimeEstimate,\n clientId,\n ethQuery,\n}: {\n isEIP1559Compatible: boolean;\n isLegacyGasAPICompatible: boolean;\n fetchGasEstimates: (\n url: string,\n clientId?: string,\n ) => Promise<GasFeeEstimates>;\n fetchGasEstimatesUrl: string;\n fetchGasEstimatesViaEthFeeHistory: (\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ethQuery: any,\n ) => Promise<GasFeeEstimates>;\n fetchLegacyGasPriceEstimates: (\n url: string,\n clientId?: string,\n ) => Promise<LegacyGasPriceEstimate>;\n fetchLegacyGasPriceEstimatesUrl: string;\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n fetchEthGasPriceEstimate: (ethQuery: any) => Promise<EthGasPriceEstimate>;\n calculateTimeEstimate: (\n maxPriorityFeePerGas: string,\n maxFeePerGas: string,\n gasFeeEstimates: GasFeeEstimates,\n ) => EstimatedGasFeeTimeBounds;\n clientId: string | undefined;\n // TODO: Replace `any` with type\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ethQuery: any;\n}): Promise<GasFeeCalculations> {\n try {\n if (isEIP1559Compatible) {\n let estimates: GasFeeEstimates;\n try {\n estimates = await fetchGasEstimates(fetchGasEstimatesUrl, clientId);\n } catch {\n estimates = await fetchGasEstimatesViaEthFeeHistory(ethQuery);\n }\n const { suggestedMaxPriorityFeePerGas, suggestedMaxFeePerGas } =\n estimates.medium;\n const estimatedGasFeeTimeBounds = calculateTimeEstimate(\n suggestedMaxPriorityFeePerGas,\n suggestedMaxFeePerGas,\n estimates,\n );\n return {\n gasFeeEstimates: estimates,\n estimatedGasFeeTimeBounds,\n gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,\n };\n } else if (isLegacyGasAPICompatible) {\n const estimates = await fetchLegacyGasPriceEstimates(\n fetchLegacyGasPriceEstimatesUrl,\n clientId,\n );\n return {\n gasFeeEstimates: estimates,\n estimatedGasFeeTimeBounds: {},\n gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY,\n };\n }\n throw new Error('Main gas fee/price estimation failed. Use fallback');\n } catch {\n try {\n const estimates = await fetchEthGasPriceEstimate(ethQuery);\n return {\n gasFeeEstimates: estimates,\n estimatedGasFeeTimeBounds: {},\n gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE,\n };\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Gas fee/price estimation failed. Message: ${error.message}`,\n );\n }\n throw error;\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchBlockFeeHistory.d.ts","sourceRoot":"","sources":["../src/fetchBlockFeeHistory.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetchBlockFeeHistory.d.ts","sourceRoot":"","sources":["../src/fetchBlockFeeHistory.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAIrC,aAAK,QAAQ,GAAG,GAAG,CAAC;AAcpB;;;;;;;;;;;;;GAaG;AAEH,oBAAY,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,aAAK,uBAAuB,CAAC,UAAU,SAAS,MAAM,IAAI;IACxD,MAAM,EAAE,EAAE,CAAC;IACX,aAAa,EAAE,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;CAClD,CAAC;AAEF;;;;;;GAMG;AACH,aAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,EAAE,CAAC;IACX,aAAa,EAAE,EAAE,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,oBAAY,eAAe,CAAC,UAAU,SAAS,MAAM,IACjD,uBAAuB,CAAC,UAAU,CAAC,GACnC,mBAAmB,CAAC;AAExB;;;;;GAKG;AACH,oBAAY,qBAAqB,CAAC,CAAC,IAAI,CAAC,SAAS,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,GACvE,CAAC,GACD,KAAK,CAAC;AAIV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAA8B,oBAAoB,CAAC,UAAU,SAAS,MAAM,EAAE,EAC5E,QAAQ,EACR,cAAc,EAAE,mBAAmB,EACnC,QAAQ,EAAE,aAAwB,EAClC,WAAW,EAAE,gBAAqB,EAClC,gBAAwB,GACzB,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,QAAQ,GAAG,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACpC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,CAAC,CAwCzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchBlockFeeHistory.js","sourceRoot":"","sources":["../src/fetchBlockFeeHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import { query, fromHex, toHex } from '@metamask/controller-utils';\nimport { BN } from 'ethereumjs-util';\n\ntype EthQuery = any;\n\n/**\n * @type RequestChunkSpecifier\n *\n * Arguments to `eth_feeHistory` that can be used to fetch a set of historical data.\n * @property blockCount - The number of blocks requested.\n * @property endBlockNumber - The number of the block at the end of the requested range.\n */\ntype RequestChunkSpecifier = {\n numberOfBlocks: number;\n endBlockNumber: BN;\n};\n\n/**\n * @type EthFeeHistoryResponse\n *\n * Response data for `eth_feeHistory`.\n * @property oldestBlock - The id of the oldest block (in hex format) in the range of blocks\n * requested.\n * @property baseFeePerGas - Base fee per gas for each block in the range of blocks requested.\n * For go-ethereum based chains baseFeePerGas will not returned in case of empty results\n * <github.com/ethereum/go-ethereum/blob/v1.10.16/internal/ethapi/api.go#L87>\n * @property gasUsedRatio - A number between 0 and 1 that represents the gas used vs. gas limit for\n * each block in the range of blocks requested.\n * @property reward - The priority fee at the percentiles requested for each block in the range of\n * blocks requested.\n */\n\nexport type EthFeeHistoryResponse = {\n oldestBlock: string;\n baseFeePerGas?: string[];\n gasUsedRatio: number[];\n reward?: string[][];\n};\n\n/**\n * @type ExistingFeeHistoryBlock\n *\n * Historical data for a particular block that exists on the blockchain.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The base fee per gas for the block in WEI, as a BN.\n * @property gasUsedRatio - A number between 0 and 1 that represents the ratio between the gas paid\n * for the block and its set gas limit.\n * @property priorityFeesByPercentile - The priority fees paid for the transactions in the block\n * that occurred at particular levels at which those transactions contributed to the overall gas\n * used for the block, indexed by those percentiles. (See docs for {@link fetchBlockFeeHistory} for more\n * on how this works.)\n */\ntype ExistingFeeHistoryBlock<Percentile extends number> = {\n number: BN;\n baseFeePerGas: BN;\n gasUsedRatio: number;\n priorityFeesByPercentile: Record<Percentile, BN>;\n};\n\n/**\n * @type NextFeeHistoryBlock\n *\n * Historical data for a theoretical block that could exist in the future.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The estimated base fee per gas for the block in WEI, as a BN.\n */\ntype NextFeeHistoryBlock = {\n number: BN;\n baseFeePerGas: BN;\n};\n\n/**\n * @type FeeHistoryBlock\n *\n * Historical data for a particular block.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The base fee per gas for the block in WEI, as a BN.\n * @property gasUsedRatio - A number between 0 and 1 that represents the ratio between the gas paid\n * for the block and its set gas limit.\n * @property priorityFeesByPercentile - The priority fees paid for the transactions in the block\n * that occurred at particular levels at which those transactions contributed to the overall gas\n * used for the block, indexed by those percentiles. (See docs for {@link fetchBlockFeeHistory} for more\n * on how this works.)\n */\nexport type FeeHistoryBlock<Percentile extends number> =\n | ExistingFeeHistoryBlock<Percentile>\n | NextFeeHistoryBlock;\n\n/**\n * @type ExtractPercentileFrom\n *\n * Extracts the percentiles that the type assigned to an array of FeeHistoryBlock has been created\n * with. This makes use of the `infer` keyword to read the type argument.\n */\nexport type ExtractPercentileFrom<T> = T extends FeeHistoryBlock<infer P>[]\n ? P\n : never;\n\nconst MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL = 1024;\n\n/**\n * Uses `eth_feeHistory` (an EIP-1559 feature) to obtain information about gas fees from a range of\n * blocks that have occurred recently on a network.\n *\n * To learn more, see these resources:\n *\n * - <https://infura.io/docs/ethereum#operation/eth_feeHistory>\n * - <https://github.com/zsfelfoldi/feehistory/blob/main/docs/feeHistory.md>\n * - <https://github.com/ethereum/go-ethereum/blob/57a3fab8a75eeb9c2f4fab770b73b51b9fe672c5/eth/gasprice/feehistory.go#L180>\n * - <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md>\n * - <https://gas-api.metaswap.codefi.network/testFeeHistory>\n *\n * @param args - The arguments to this function.\n * @param args.ethQuery - An EthQuery instance that wraps a provider for the network in question.\n * @param args.endBlock - The desired end of the requested block range. Can be \"latest\" if you want\n * to start from the latest successful block or the number of a known past block.\n * @param args.numberOfBlocks - How many total blocks to fetch. Note that if this is more than 1024,\n * multiple calls to `eth_feeHistory` will be made.\n * @param args.percentiles - A set of numbers between 1 and 100 which will dictate how\n * `priorityFeesByPercentile` in each returned block will be formed. When Ethereum runs the\n * `eth_feeHistory` method, for each block it is considering, it will first sort all transactions by\n * the priority fee. It will then go through each transaction and add the total amount of gas paid\n * for that transaction to a bucket which maxes out at the total gas used for the whole block. As\n * the bucket fills, it will cross percentages which correspond to the percentiles specified here,\n * and the priority fees of the first transactions which cause it to reach those percentages will be\n * recorded. Hence, `priorityFeesByPercentile` represents the priority fees of transactions at key\n * gas used contribution levels, where earlier levels have smaller contributions and later levels\n * have higher contributions.\n * @param args.includeNextBlock - Whether to include an extra block that represents the next\n * block after the latest one. Only the `baseFeePerGas` will be filled in for this block (which is\n * estimated).\n * @returns The list of blocks and their fee data, sorted from oldest to newest.\n */\nexport default async function fetchBlockFeeHistory<Percentile extends number>({\n ethQuery,\n numberOfBlocks: totalNumberOfBlocks,\n endBlock: givenEndBlock = 'latest',\n percentiles: givenPercentiles = [],\n includeNextBlock = false,\n}: {\n ethQuery: EthQuery;\n numberOfBlocks: number;\n endBlock?: 'latest' | BN;\n percentiles?: readonly Percentile[];\n includeNextBlock?: boolean;\n}): Promise<FeeHistoryBlock<Percentile>[]> {\n const percentiles =\n givenPercentiles.length > 0\n ? Array.from(new Set(givenPercentiles)).sort((a, b) => a - b)\n : [];\n\n const finalEndBlockNumber =\n givenEndBlock === 'latest'\n ? fromHex(await query(ethQuery, 'blockNumber'))\n : givenEndBlock;\n\n const requestChunkSpecifiers = determineRequestChunkSpecifiers(\n finalEndBlockNumber,\n totalNumberOfBlocks,\n );\n\n const blockChunks = await Promise.all(\n requestChunkSpecifiers.map(({ numberOfBlocks, endBlockNumber }, i) => {\n return i === requestChunkSpecifiers.length - 1\n ? makeRequestForChunk({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock,\n })\n : makeRequestForChunk({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock: false,\n });\n }),\n );\n\n return blockChunks.reduce(\n (array, blocks) => [...array, ...blocks],\n [] as FeeHistoryBlock<Percentile>[],\n );\n}\n\n/**\n * Builds an ExistingFeeHistoryBlock.\n *\n * @param args - The args to this function.\n * @param args.number - The number of the block.\n * @param args.baseFeePerGas - The base fee per gas of the block.\n * @param args.blockIndex - The index of the block in the source chunk.\n * @param args.gasUsedRatios - The gas used ratios for the block.\n * @param args.priorityFeePercentileGroups - The priority fee percentile groups for the block.\n * @param args.percentiles - The percentiles used to fetch the source chunk.\n * @returns The ExistingFeeHistoryBlock.\n */\nfunction buildExistingFeeHistoryBlock<Percentile extends number>({\n baseFeePerGas,\n number,\n blockIndex,\n gasUsedRatios,\n priorityFeePercentileGroups,\n percentiles,\n}: {\n baseFeePerGas: BN;\n number: BN;\n blockIndex: number;\n gasUsedRatios: number[];\n priorityFeePercentileGroups: string[][];\n percentiles: readonly Percentile[];\n}): ExistingFeeHistoryBlock<Percentile> {\n const gasUsedRatio = gasUsedRatios[blockIndex];\n const priorityFeesForEachPercentile = priorityFeePercentileGroups[blockIndex];\n const priorityFeesByPercentile = percentiles.reduce(\n (obj, percentile, percentileIndex) => {\n const priorityFee = priorityFeesForEachPercentile[percentileIndex];\n return { ...obj, [percentile]: fromHex(priorityFee) };\n },\n {} as Record<Percentile, BN>,\n );\n\n return {\n number,\n baseFeePerGas,\n gasUsedRatio,\n priorityFeesByPercentile,\n };\n}\n\n/**\n * Builds a NextFeeHistoryBlock.\n *\n * @param args - The args to this function.\n * @param args.baseFeePerGas - The base fee per gas of the block.\n * @param args.number - The number of the block.\n * @returns The NextFeeHistoryBlock.\n */\nfunction buildNextFeeHistoryBlock({\n baseFeePerGas,\n number,\n}: {\n baseFeePerGas: BN;\n number: BN;\n}) {\n return {\n number,\n baseFeePerGas,\n gasUsedRatio: null,\n priorityFeesByPercentile: null,\n };\n}\n\n/**\n * Uses eth_feeHistory to request historical data about a group of blocks (max size 1024).\n *\n * @param args - The arguments\n * @param args.ethQuery - An EthQuery instance.\n * @param args.numberOfBlocks - The number of blocks in the chunk. Must be at most 1024, as this is\n * the maximum that `eth_feeHistory` can return in one call.\n * @param args.endBlockNumber - The end of the requested block range.\n * @param args.percentiles - A set of numbers between 1 and 100 that will be used to pull priority\n * fees for each block.\n * @param args.includeNextBlock - Whether to include an extra block that represents the next\n * block after the latest one. Only the `baseFeePerGas` will be filled in for this block (which is\n * estimated).\n * @returns A list of block data.\n */\nasync function makeRequestForChunk<Percentile extends number>({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock,\n}: {\n ethQuery: EthQuery;\n numberOfBlocks: number;\n endBlockNumber: BN;\n percentiles: readonly Percentile[];\n includeNextBlock: boolean;\n}): Promise<FeeHistoryBlock<Percentile>[]> {\n const response: EthFeeHistoryResponse = await query(\n ethQuery,\n 'eth_feeHistory',\n [toHex(numberOfBlocks), toHex(endBlockNumber), percentiles],\n );\n\n const startBlockNumber = fromHex(response.oldestBlock);\n\n if (\n response.baseFeePerGas !== undefined &&\n response.baseFeePerGas.length > 0 &&\n response.gasUsedRatio.length > 0 &&\n (response.reward === undefined || response.reward.length > 0)\n ) {\n // Per\n // <https://github.com/ethereum/go-ethereum/blob/57a3fab8a75eeb9c2f4fab770b73b51b9fe672c5/eth/gasprice/feehistory.go#L191-L192>,\n // baseFeePerGas will always include an extra item which is the calculated base fee for the\n // next (future) block. We may or may not care about this; if we don't, chop it off.\n const baseFeesPerGasAsHex = includeNextBlock\n ? response.baseFeePerGas\n : response.baseFeePerGas.slice(0, numberOfBlocks);\n const gasUsedRatios = response.gasUsedRatio;\n const priorityFeePercentileGroups = response.reward ?? [];\n // Chain is allowed to return fewer number of block results\n const numberOfExistingResults = gasUsedRatios.length;\n\n return baseFeesPerGasAsHex.map((baseFeePerGasAsHex, blockIndex) => {\n const baseFeePerGas = fromHex(baseFeePerGasAsHex);\n const number = startBlockNumber.addn(blockIndex);\n\n return blockIndex >= numberOfExistingResults\n ? buildNextFeeHistoryBlock({ baseFeePerGas, number })\n : buildExistingFeeHistoryBlock({\n baseFeePerGas,\n number,\n blockIndex,\n gasUsedRatios,\n priorityFeePercentileGroups,\n percentiles,\n });\n });\n }\n\n return [];\n}\n\n/**\n * Divides a block range (specified by a range size and the end of the range) into chunks based on\n * the maximum number of blocks that `eth_feeHistory` can return in a single call.\n *\n * If the requested totalNumberOfBlocks exceed endBlockNumber, totalNumberOfBlocks is\n * truncated to avoid requesting chunks with negative endBlockNumber.\n *\n * @param endBlockNumber - The final block in the complete desired block range after all\n * `eth_feeHistory` requests have been made.\n * @param totalNumberOfBlocks - The total number of desired blocks after all `eth_feeHistory`\n * requests have been made.\n * @returns A set of arguments that can be used to make requests to `eth_feeHistory` in order to\n * retrieve all of the requested blocks, sorted from oldest block to newest block.\n */\nfunction determineRequestChunkSpecifiers(\n endBlockNumber: BN,\n totalNumberOfBlocks: number,\n): RequestChunkSpecifier[] {\n if (endBlockNumber.lt(new BN(totalNumberOfBlocks))) {\n totalNumberOfBlocks = endBlockNumber.toNumber();\n }\n\n const specifiers = [];\n for (\n let chunkStartBlockNumber = endBlockNumber.subn(totalNumberOfBlocks);\n chunkStartBlockNumber.lt(endBlockNumber);\n chunkStartBlockNumber = chunkStartBlockNumber.addn(\n MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL,\n )\n ) {\n const distanceToEnd = endBlockNumber.sub(chunkStartBlockNumber).toNumber();\n const numberOfBlocks =\n distanceToEnd < MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL\n ? distanceToEnd\n : MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL;\n const chunkEndBlockNumber = chunkStartBlockNumber.addn(numberOfBlocks);\n specifiers.push({ numberOfBlocks, endBlockNumber: chunkEndBlockNumber });\n }\n return specifiers;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetchBlockFeeHistory.js","sourceRoot":"","sources":["../src/fetchBlockFeeHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import { query, fromHex, toHex } from '@metamask/controller-utils';\nimport { BN } from 'ethereumjs-util';\n\n// TODO: Replace `any` with type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype EthQuery = any;\n\n/**\n * @type RequestChunkSpecifier\n *\n * Arguments to `eth_feeHistory` that can be used to fetch a set of historical data.\n * @property blockCount - The number of blocks requested.\n * @property endBlockNumber - The number of the block at the end of the requested range.\n */\ntype RequestChunkSpecifier = {\n numberOfBlocks: number;\n endBlockNumber: BN;\n};\n\n/**\n * @type EthFeeHistoryResponse\n *\n * Response data for `eth_feeHistory`.\n * @property oldestBlock - The id of the oldest block (in hex format) in the range of blocks\n * requested.\n * @property baseFeePerGas - Base fee per gas for each block in the range of blocks requested.\n * For go-ethereum based chains baseFeePerGas will not returned in case of empty results\n * <github.com/ethereum/go-ethereum/blob/v1.10.16/internal/ethapi/api.go#L87>\n * @property gasUsedRatio - A number between 0 and 1 that represents the gas used vs. gas limit for\n * each block in the range of blocks requested.\n * @property reward - The priority fee at the percentiles requested for each block in the range of\n * blocks requested.\n */\n\nexport type EthFeeHistoryResponse = {\n oldestBlock: string;\n baseFeePerGas?: string[];\n gasUsedRatio: number[];\n reward?: string[][];\n};\n\n/**\n * @type ExistingFeeHistoryBlock\n *\n * Historical data for a particular block that exists on the blockchain.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The base fee per gas for the block in WEI, as a BN.\n * @property gasUsedRatio - A number between 0 and 1 that represents the ratio between the gas paid\n * for the block and its set gas limit.\n * @property priorityFeesByPercentile - The priority fees paid for the transactions in the block\n * that occurred at particular levels at which those transactions contributed to the overall gas\n * used for the block, indexed by those percentiles. (See docs for {@link fetchBlockFeeHistory} for more\n * on how this works.)\n */\ntype ExistingFeeHistoryBlock<Percentile extends number> = {\n number: BN;\n baseFeePerGas: BN;\n gasUsedRatio: number;\n priorityFeesByPercentile: Record<Percentile, BN>;\n};\n\n/**\n * @type NextFeeHistoryBlock\n *\n * Historical data for a theoretical block that could exist in the future.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The estimated base fee per gas for the block in WEI, as a BN.\n */\ntype NextFeeHistoryBlock = {\n number: BN;\n baseFeePerGas: BN;\n};\n\n/**\n * @type FeeHistoryBlock\n *\n * Historical data for a particular block.\n * @property number - The number of the block, as a BN.\n * @property baseFeePerGas - The base fee per gas for the block in WEI, as a BN.\n * @property gasUsedRatio - A number between 0 and 1 that represents the ratio between the gas paid\n * for the block and its set gas limit.\n * @property priorityFeesByPercentile - The priority fees paid for the transactions in the block\n * that occurred at particular levels at which those transactions contributed to the overall gas\n * used for the block, indexed by those percentiles. (See docs for {@link fetchBlockFeeHistory} for more\n * on how this works.)\n */\nexport type FeeHistoryBlock<Percentile extends number> =\n | ExistingFeeHistoryBlock<Percentile>\n | NextFeeHistoryBlock;\n\n/**\n * @type ExtractPercentileFrom\n *\n * Extracts the percentiles that the type assigned to an array of FeeHistoryBlock has been created\n * with. This makes use of the `infer` keyword to read the type argument.\n */\nexport type ExtractPercentileFrom<T> = T extends FeeHistoryBlock<infer P>[]\n ? P\n : never;\n\nconst MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL = 1024;\n\n/**\n * Uses `eth_feeHistory` (an EIP-1559 feature) to obtain information about gas fees from a range of\n * blocks that have occurred recently on a network.\n *\n * To learn more, see these resources:\n *\n * - <https://infura.io/docs/ethereum#operation/eth_feeHistory>\n * - <https://github.com/zsfelfoldi/feehistory/blob/main/docs/feeHistory.md>\n * - <https://github.com/ethereum/go-ethereum/blob/57a3fab8a75eeb9c2f4fab770b73b51b9fe672c5/eth/gasprice/feehistory.go#L180>\n * - <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md>\n * - <https://gas-api.metaswap.codefi.network/testFeeHistory>\n *\n * @param args - The arguments to this function.\n * @param args.ethQuery - An EthQuery instance that wraps a provider for the network in question.\n * @param args.endBlock - The desired end of the requested block range. Can be \"latest\" if you want\n * to start from the latest successful block or the number of a known past block.\n * @param args.numberOfBlocks - How many total blocks to fetch. Note that if this is more than 1024,\n * multiple calls to `eth_feeHistory` will be made.\n * @param args.percentiles - A set of numbers between 1 and 100 which will dictate how\n * `priorityFeesByPercentile` in each returned block will be formed. When Ethereum runs the\n * `eth_feeHistory` method, for each block it is considering, it will first sort all transactions by\n * the priority fee. It will then go through each transaction and add the total amount of gas paid\n * for that transaction to a bucket which maxes out at the total gas used for the whole block. As\n * the bucket fills, it will cross percentages which correspond to the percentiles specified here,\n * and the priority fees of the first transactions which cause it to reach those percentages will be\n * recorded. Hence, `priorityFeesByPercentile` represents the priority fees of transactions at key\n * gas used contribution levels, where earlier levels have smaller contributions and later levels\n * have higher contributions.\n * @param args.includeNextBlock - Whether to include an extra block that represents the next\n * block after the latest one. Only the `baseFeePerGas` will be filled in for this block (which is\n * estimated).\n * @returns The list of blocks and their fee data, sorted from oldest to newest.\n */\nexport default async function fetchBlockFeeHistory<Percentile extends number>({\n ethQuery,\n numberOfBlocks: totalNumberOfBlocks,\n endBlock: givenEndBlock = 'latest',\n percentiles: givenPercentiles = [],\n includeNextBlock = false,\n}: {\n ethQuery: EthQuery;\n numberOfBlocks: number;\n endBlock?: 'latest' | BN;\n percentiles?: readonly Percentile[];\n includeNextBlock?: boolean;\n}): Promise<FeeHistoryBlock<Percentile>[]> {\n const percentiles =\n givenPercentiles.length > 0\n ? Array.from(new Set(givenPercentiles)).sort((a, b) => a - b)\n : [];\n\n const finalEndBlockNumber =\n givenEndBlock === 'latest'\n ? fromHex(await query(ethQuery, 'blockNumber'))\n : givenEndBlock;\n\n const requestChunkSpecifiers = determineRequestChunkSpecifiers(\n finalEndBlockNumber,\n totalNumberOfBlocks,\n );\n\n const blockChunks = await Promise.all(\n requestChunkSpecifiers.map(({ numberOfBlocks, endBlockNumber }, i) => {\n return i === requestChunkSpecifiers.length - 1\n ? makeRequestForChunk({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock,\n })\n : makeRequestForChunk({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock: false,\n });\n }),\n );\n\n return blockChunks.reduce(\n (array, blocks) => [...array, ...blocks],\n [] as FeeHistoryBlock<Percentile>[],\n );\n}\n\n/**\n * Builds an ExistingFeeHistoryBlock.\n *\n * @param args - The args to this function.\n * @param args.number - The number of the block.\n * @param args.baseFeePerGas - The base fee per gas of the block.\n * @param args.blockIndex - The index of the block in the source chunk.\n * @param args.gasUsedRatios - The gas used ratios for the block.\n * @param args.priorityFeePercentileGroups - The priority fee percentile groups for the block.\n * @param args.percentiles - The percentiles used to fetch the source chunk.\n * @returns The ExistingFeeHistoryBlock.\n */\nfunction buildExistingFeeHistoryBlock<Percentile extends number>({\n baseFeePerGas,\n number,\n blockIndex,\n gasUsedRatios,\n priorityFeePercentileGroups,\n percentiles,\n}: {\n baseFeePerGas: BN;\n number: BN;\n blockIndex: number;\n gasUsedRatios: number[];\n priorityFeePercentileGroups: string[][];\n percentiles: readonly Percentile[];\n}): ExistingFeeHistoryBlock<Percentile> {\n const gasUsedRatio = gasUsedRatios[blockIndex];\n const priorityFeesForEachPercentile = priorityFeePercentileGroups[blockIndex];\n const priorityFeesByPercentile = percentiles.reduce(\n (obj, percentile, percentileIndex) => {\n const priorityFee = priorityFeesForEachPercentile[percentileIndex];\n return { ...obj, [percentile]: fromHex(priorityFee) };\n },\n {} as Record<Percentile, BN>,\n );\n\n return {\n number,\n baseFeePerGas,\n gasUsedRatio,\n priorityFeesByPercentile,\n };\n}\n\n/**\n * Builds a NextFeeHistoryBlock.\n *\n * @param args - The args to this function.\n * @param args.baseFeePerGas - The base fee per gas of the block.\n * @param args.number - The number of the block.\n * @returns The NextFeeHistoryBlock.\n */\nfunction buildNextFeeHistoryBlock({\n baseFeePerGas,\n number,\n}: {\n baseFeePerGas: BN;\n number: BN;\n}) {\n return {\n number,\n baseFeePerGas,\n gasUsedRatio: null,\n priorityFeesByPercentile: null,\n };\n}\n\n/**\n * Uses eth_feeHistory to request historical data about a group of blocks (max size 1024).\n *\n * @param args - The arguments\n * @param args.ethQuery - An EthQuery instance.\n * @param args.numberOfBlocks - The number of blocks in the chunk. Must be at most 1024, as this is\n * the maximum that `eth_feeHistory` can return in one call.\n * @param args.endBlockNumber - The end of the requested block range.\n * @param args.percentiles - A set of numbers between 1 and 100 that will be used to pull priority\n * fees for each block.\n * @param args.includeNextBlock - Whether to include an extra block that represents the next\n * block after the latest one. Only the `baseFeePerGas` will be filled in for this block (which is\n * estimated).\n * @returns A list of block data.\n */\nasync function makeRequestForChunk<Percentile extends number>({\n ethQuery,\n numberOfBlocks,\n endBlockNumber,\n percentiles,\n includeNextBlock,\n}: {\n ethQuery: EthQuery;\n numberOfBlocks: number;\n endBlockNumber: BN;\n percentiles: readonly Percentile[];\n includeNextBlock: boolean;\n}): Promise<FeeHistoryBlock<Percentile>[]> {\n const response: EthFeeHistoryResponse = await query(\n ethQuery,\n 'eth_feeHistory',\n [toHex(numberOfBlocks), toHex(endBlockNumber), percentiles],\n );\n\n const startBlockNumber = fromHex(response.oldestBlock);\n\n if (\n response.baseFeePerGas !== undefined &&\n response.baseFeePerGas.length > 0 &&\n response.gasUsedRatio.length > 0 &&\n (response.reward === undefined || response.reward.length > 0)\n ) {\n // Per\n // <https://github.com/ethereum/go-ethereum/blob/57a3fab8a75eeb9c2f4fab770b73b51b9fe672c5/eth/gasprice/feehistory.go#L191-L192>,\n // baseFeePerGas will always include an extra item which is the calculated base fee for the\n // next (future) block. We may or may not care about this; if we don't, chop it off.\n const baseFeesPerGasAsHex = includeNextBlock\n ? response.baseFeePerGas\n : response.baseFeePerGas.slice(0, numberOfBlocks);\n const gasUsedRatios = response.gasUsedRatio;\n const priorityFeePercentileGroups = response.reward ?? [];\n // Chain is allowed to return fewer number of block results\n const numberOfExistingResults = gasUsedRatios.length;\n\n return baseFeesPerGasAsHex.map((baseFeePerGasAsHex, blockIndex) => {\n const baseFeePerGas = fromHex(baseFeePerGasAsHex);\n const number = startBlockNumber.addn(blockIndex);\n\n return blockIndex >= numberOfExistingResults\n ? buildNextFeeHistoryBlock({ baseFeePerGas, number })\n : buildExistingFeeHistoryBlock({\n baseFeePerGas,\n number,\n blockIndex,\n gasUsedRatios,\n priorityFeePercentileGroups,\n percentiles,\n });\n });\n }\n\n return [];\n}\n\n/**\n * Divides a block range (specified by a range size and the end of the range) into chunks based on\n * the maximum number of blocks that `eth_feeHistory` can return in a single call.\n *\n * If the requested totalNumberOfBlocks exceed endBlockNumber, totalNumberOfBlocks is\n * truncated to avoid requesting chunks with negative endBlockNumber.\n *\n * @param endBlockNumber - The final block in the complete desired block range after all\n * `eth_feeHistory` requests have been made.\n * @param totalNumberOfBlocks - The total number of desired blocks after all `eth_feeHistory`\n * requests have been made.\n * @returns A set of arguments that can be used to make requests to `eth_feeHistory` in order to\n * retrieve all of the requested blocks, sorted from oldest block to newest block.\n */\nfunction determineRequestChunkSpecifiers(\n endBlockNumber: BN,\n totalNumberOfBlocks: number,\n): RequestChunkSpecifier[] {\n if (endBlockNumber.lt(new BN(totalNumberOfBlocks))) {\n totalNumberOfBlocks = endBlockNumber.toNumber();\n }\n\n const specifiers = [];\n for (\n let chunkStartBlockNumber = endBlockNumber.subn(totalNumberOfBlocks);\n chunkStartBlockNumber.lt(endBlockNumber);\n chunkStartBlockNumber = chunkStartBlockNumber.addn(\n MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL,\n )\n ) {\n const distanceToEnd = endBlockNumber.sub(chunkStartBlockNumber).toNumber();\n const numberOfBlocks =\n distanceToEnd < MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL\n ? distanceToEnd\n : MAX_NUMBER_OF_BLOCKS_PER_ETH_FEE_HISTORY_CALL;\n const chunkEndBlockNumber = chunkStartBlockNumber.addn(numberOfBlocks);\n specifiers.push({ numberOfBlocks, endBlockNumber: chunkEndBlockNumber });\n }\n return specifiers;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/gas-fee-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "12.0.0-preview.353ee83b",
|
|
4
4
|
"description": "Periodically calculates gas fee estimates based on various gas limits as well as other data displayed on transaction confirm screens",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build:docs": "typedoc",
|
|
25
|
+
"changelog:update": "../../scripts/update-changelog.sh @metamask/gas-fee-controller",
|
|
25
26
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/gas-fee-controller",
|
|
26
27
|
"publish:preview": "yarn npm publish --tag preview",
|
|
27
28
|
"test": "jest --reporters=jest-silent-reporter",
|
|
@@ -30,19 +31,19 @@
|
|
|
30
31
|
"test:watch": "jest --watch"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
|
-
"@metamask/base-controller": "^4.0.
|
|
34
|
-
"@metamask/controller-utils": "^
|
|
34
|
+
"@metamask/base-controller": "^4.0.1",
|
|
35
|
+
"@metamask/controller-utils": "^8.0.1",
|
|
35
36
|
"@metamask/eth-query": "^4.0.0",
|
|
36
37
|
"@metamask/ethjs-unit": "^0.2.1",
|
|
37
|
-
"@metamask/network-controller": "^17.
|
|
38
|
-
"@metamask/polling-controller": "^
|
|
38
|
+
"@metamask/network-controller": "^17.1.0",
|
|
39
|
+
"@metamask/polling-controller": "^4.0.0",
|
|
39
40
|
"@metamask/utils": "^8.2.0",
|
|
40
41
|
"@types/uuid": "^8.3.0",
|
|
41
42
|
"ethereumjs-util": "^7.0.10",
|
|
42
43
|
"uuid": "^8.3.2"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@metamask/auto-changelog": "^3.4.
|
|
46
|
+
"@metamask/auto-changelog": "^3.4.4",
|
|
46
47
|
"@types/jest": "^27.4.1",
|
|
47
48
|
"@types/jest-when": "^2.7.3",
|
|
48
49
|
"deepmerge": "^4.2.2",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"typescript": "~4.8.4"
|
|
57
58
|
},
|
|
58
59
|
"peerDependencies": {
|
|
59
|
-
"@metamask/network-controller": "^17.
|
|
60
|
+
"@metamask/network-controller": "^17.1.0"
|
|
60
61
|
},
|
|
61
62
|
"engines": {
|
|
62
63
|
"node": ">=16.0.0"
|