UNPKG

@vechain/sdk-network

Version:

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

204 lines (185 loc) 6.53 kB
import { JSONRPCInternalError, JSONRPCTransactionRevertError, stringifyData, VechainSDKError } from '@vechain/sdk-errors'; import { VeChainSDKLogger } from '@vechain/sdk-logging'; import { SimpleHttpClient } from '../../../http'; import { ThorClient } from '../../../thor-client'; import type { EIP1193RequestArguments } from '../../eip1193'; import { type ProviderInternalWallet } from '../../helpers'; import { VeChainProvider } from '../vechain-provider/vechain-provider'; import { type BuildHardhatErrorFunction, type JsonRpcRequest, type JsonRpcResponse } from './types'; /** * This class is a wrapper for the VeChainProvider that Hardhat uses. * * It exposes the interface that Hardhat expects, and uses the VeChainProvider as wrapped provider. */ class HardhatVeChainProvider extends VeChainProvider { /** * Debug mode. */ debug: boolean; /** * The function to use to build Hardhat errors. */ buildHardhatErrorFunctionCallback: BuildHardhatErrorFunction; /** * RPC configuration. */ rpcConfiguration: { ethGetTransactionCountMustReturn0: boolean; }; /** * Constructor with the network configuration. * * @param walletToUse - The wallet to use. * @param nodeUrl - The node url to use * @param buildHardhatErrorFunctionCallback - The function to use to build Hardhat errors. * @param debug - Debug mode. * @param enableDelegation - Enable fee delegation or not. */ constructor( walletToUse: ProviderInternalWallet, nodeUrl: string, buildHardhatErrorFunctionCallback: BuildHardhatErrorFunction, debug: boolean = false, enableDelegation: boolean = false, rpcConfiguration = { // By default, the eth_getTransactionCount method returns a random number. ethGetTransactionCountMustReturn0: false } ) { // Initialize the provider with the network configuration. super( new ThorClient(new SimpleHttpClient(nodeUrl)), walletToUse, enableDelegation ); // Save the debug mode. this.debug = debug; // Save the RPC configuration. this.rpcConfiguration = rpcConfiguration; // Save the buildHardhatErrorFunction. this.buildHardhatErrorFunctionCallback = buildHardhatErrorFunctionCallback; } /** * Overload of the send method * * @param method - The method to call. * @param params - The parameters to pass to the method. */ async send(method: string, params?: unknown[]): Promise<unknown> { return await this.request({ method, params }); } /** * Overload of the sendAsync method. * It is the same of the send method, but with a callback. * Instead of returning the result, it calls the callback with the result. * * @param payload - The request payload (it contains method and params as 'send' method). * @param callback - The callback to call with the result. */ async sendAsync( payload: JsonRpcRequest, callback: (error: unknown, response: JsonRpcResponse) => void ): Promise<void> { try { const result = await this.request({ method: payload.method, params: payload.params }); // Execute the callback with the result callback(null, { id: payload.id, jsonrpc: '2.0', result }); } catch (e) { // Execute the callback with the error callback(e, { id: payload.id, jsonrpc: '2.0' }); } } /** * It sends the request through the VeChainProvider. * * @param args - The request arguments. */ async request(args: EIP1193RequestArguments): Promise<unknown> { // Must return 0 with the eth_getTransactionCount method const mustReturn0 = this.rpcConfiguration.ethGetTransactionCountMustReturn0 && args.method === 'eth_getTransactionCount'; try { // Debug mode - get the request and the accounts if (this.debug) { const accounts = await ( this.wallet as ProviderInternalWallet ).getAddresses(); const gasPayer = await ( this.wallet as ProviderInternalWallet ).getGasPayer(); VeChainSDKLogger('log').log({ title: `Sending request - ${args.method}`, messages: [ `params: ${stringifyData(args.params)}`, `accounts: ${stringifyData(accounts)}`, `gasPayer: ${stringifyData(gasPayer)}`, `url: ${this.thorClient.httpClient.baseURL}` ] }); } // Send the request const result = mustReturn0 ? '0x0' : await super.request({ method: args.method, params: args.params as never }); // Debug mode - get the result if (this.debug) { VeChainSDKLogger('log').log({ title: `Get request - ${args.method} result`, messages: [`result: ${stringifyData(result)}`] }); } return result; } catch (error) { // Debug the error if (this.debug) { VeChainSDKLogger('error').log( new JSONRPCInternalError( args.method, `Error on request - ${args.method}`, { args } ) ); } // eth_call transaction revert error already in correct format if (error instanceof JSONRPCTransactionRevertError) { throw error; } if (error instanceof VechainSDKError) { throw this.buildHardhatErrorFunctionCallback( `Error on request ${args.method}: ${error.innerError}`, error ); } } } } export { HardhatVeChainProvider };