UNPKG

@vechain/sdk-network

Version:

This module serves as the standard interface connecting decentralized applications (dApps) and users to the VeChainThor blockchain

200 lines (184 loc) 6.77 kB
import { type FeesPriorityResponse, type FeeHistoryResponse, type FeeHistoryOptions, type EstimateGasOptions, type EstimateGasResult } from './types'; import { InvalidDataType } from '@vechain/sdk-errors'; import { HttpMethod, type HttpClient } from '../../http'; import { HexUInt, Revision } from '@vechain/sdk-core'; import { thorest } from '../../utils'; import { type SimulateTransactionClause } from '../transactions/types'; interface TransactionModuleInterface { estimateGas: ( clauses: SimulateTransactionClause[], caller?: string, options?: EstimateGasOptions ) => Promise<EstimateGasResult>; } /** * The `GasModule` handles gas related operations and provides * convenient methods for estimating the gas cost of a transaction. */ class GasModule { readonly httpClient: HttpClient; protected transactionsModule: TransactionModuleInterface | null; constructor(httpClient: HttpClient) { this.httpClient = httpClient; this.transactionsModule = null; } /** * Sets the transactions module. * * @param transactionsModule - The transactions module to set. */ public setTransactionsModule( transactionsModule: TransactionModuleInterface ): void { this.transactionsModule = transactionsModule; } /** * Simulates a transaction and returns an object containing information regarding the gas used and whether the transaction reverted. * * @note The caller option is suggested as estimation without this parameter may not be accurate. * * @param clauses - The clauses of the transaction to simulate. * @param caller - The address of the account sending the transaction. * @param options - Optional parameters for the request. Includes all options of the `simulateTransaction` method excluding the `caller` option. * @see {@link TransactionsClient#simulateTransaction} * Also, includes the `gasPadding` option which is a percentage of gas to add on top of the estimated gas. The value must be between (0, 1]. * @returns An object containing information regarding the gas used and whether the transaction reverted, together with the decoded revert reason and VM errors. * @throws{InvalidDataType} */ public async estimateGas( clauses: SimulateTransactionClause[], caller?: string, options?: EstimateGasOptions ): Promise<EstimateGasResult> { if (this.transactionsModule == null) { throw new InvalidDataType( 'estimateGas()', 'Transactions module not set', {} ); } return await this.transactionsModule.estimateGas( clauses, caller, options ); } /** * Returns the suggested priority fee per gas in wei. * This is calculated based on the current base fee and network conditions. * * @returns Suggested priority fee per gas in wei (hex string) * @throws {InvalidDataType} */ public async getMaxPriorityFeePerGas(): Promise<string> { const response = (await this.httpClient.get( '/fees/priority' )) as FeesPriorityResponse; // Validate response if ( response === null || response === undefined || typeof response !== 'object' ) { throw new InvalidDataType( 'getMaxPriorityFeePerGas()', 'Invalid response format from /fees/priority endpoint', { response } ); } if ( response.maxPriorityFeePerGas === undefined || response.maxPriorityFeePerGas === null || response.maxPriorityFeePerGas === '' || typeof response.maxPriorityFeePerGas !== 'string' ) { throw new InvalidDataType( 'getMaxPriorityFeePerGas()', 'Missing or invalid maxPriorityFeePerGas in response', { response } ); } return response.maxPriorityFeePerGas; } /** * Returns fee history for the returned block range. * * @param options - The options for the fee history request * @returns Fee history for the returned block range * @throws {InvalidDataType} */ public async getFeeHistory( options: FeeHistoryOptions ): Promise<FeeHistoryResponse> { if ( options === null || options === undefined || typeof options.blockCount !== 'number' || !Number.isFinite(options.blockCount) || options.blockCount <= 0 ) { throw new InvalidDataType( 'getFeeHistory()', 'Invalid blockCount parameter', { options } ); } if ( options.newestBlock !== null && options.newestBlock !== undefined && !Revision.isValid(options.newestBlock) ) { throw new InvalidDataType( 'getFeeHistory()', 'Invalid revision. The revision must be a string representing a block number or block id (also "best" is accepted which represents the best block & "finalized" for the finalized block).', { options } ); } const response = await this.httpClient.http( HttpMethod.GET, thorest.fees.get.FEES_HISTORY( options.blockCount, options.newestBlock, options.rewardPercentiles ) ); if ( response === null || response === undefined || typeof response !== 'object' ) { throw new InvalidDataType( 'getFeeHistory()', 'Invalid response format from /fees/history endpoint', { response } ); } return response as FeeHistoryResponse; } /** * Returns the base fee per gas of the next block. * @returns The base fee per gas of the next block. */ public async getNextBlockBaseFeePerGas(): Promise<bigint | null> { const options: FeeHistoryOptions = { blockCount: 1, newestBlock: 'next' }; const feeHistory = await this.getFeeHistory(options); if ( feeHistory.baseFeePerGas === null || feeHistory.baseFeePerGas === undefined || feeHistory.baseFeePerGas.length === 0 ) { return null; } return HexUInt.of(feeHistory.baseFeePerGas[0]).bi; } } export { GasModule };