VYPR
Low severityNVD Advisory· Published Sep 24, 2025· Updated Sep 29, 2025

CVE-2025-57330

CVE-2025-57330

Description

The web3-core-subscriptions is a package designed to manages web3 subscriptions. A Prototype Pollution vulnerability in the attachToObject function of web3-core-subscriptions version 1.10.4 and before allows attackers to inject properties on Object.prototype via supplying a crafted payload, causing denial of service (DoS) as the minimum consequence.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Prototype Pollution in web3-core-subscriptions ≤1.10.4 allows attackers to inject properties on Object.prototype, leading to DoS or potentially arbitrary code execution.

Vulnerability

The attachToObject function in web3-core-subscriptions versions 1.10.4 and earlier is vulnerable to Prototype Pollution (CWE-1321). The function does not properly restrict the modification of object prototypes, allowing an attacker to inject arbitrary properties onto Object.prototype via a crafted payload [1][2].

Exploitation

An attacker can exploit this by supplying a specially crafted input during object instantiation, such as a nested key path like __proto__.pollution in the subscription options. The vulnerability requires no authentication or specific network position, as it is triggered during the package's normal processing of subscription data [4].

Impact

At a minimum, this results in denial of service (DoS) due to unexpected application behavior or crashes. However, as noted in proof-of-concept analyses, the same flaw can potentially be leveraged for arbitrary code execution if the polluted property is used in sensitive operations [2][4].

Mitigation

The issue has been fixed in a commit that improves nullish value handling [1]. Users should upgrade to a patched version of the package (e.g., by updating web3.js) to mitigate the risk. No workarounds are available.

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
web3-core-subscriptionsnpm
<= 2.0.0-alpha.1

Affected products

2

Patches

1
d9660426c122

:art: Improve the nullish value usage around the codebase (#5095)

https://github.com/web3/web3.jsNazar HussainJun 7, 2022via ghsa
107 files changed · +1371 412
  • packages/web3-common/src/deferred_promise.ts+1 1 modified
    @@ -71,7 +71,7 @@ export class DeferredPromise<T> implements Promise<T> {
     		return this._promise.catch(onrejected);
     	}
     
    -	public async finally(onfinally?: (() => void) | null): Promise<T> {
    +	public async finally(onfinally?: (() => void) | undefined): Promise<T> {
     		return this._promise.finally(onfinally);
     	}
     
    
  • packages/web3-common/src/eth_execution_api.ts+19 19 modified
    @@ -55,7 +55,7 @@ export interface TransactionCall {
     }
     
     export interface BaseTransaction {
    -	readonly to?: Address | null;
    +	readonly to?: Address;
     	readonly type: HexStringSingleByte;
     	readonly nonce: Uint;
     	readonly gas: Uint;
    @@ -113,11 +113,11 @@ export type TransactionSigned =
     
     // https://github.com/ethereum/execution-apis/blob/main/src/schemas/transaction.json#L269
     export type TransactionInfo = TransactionSigned & {
    -	readonly blockHash: HexString32Bytes | null;
    -	readonly blockNumber: Uint | null;
    +	readonly blockHash?: HexString32Bytes;
    +	readonly blockNumber?: Uint;
     	readonly from: Address;
     	readonly hash: HexString32Bytes;
    -	readonly transactionIndex: Uint | null;
    +	readonly transactionIndex?: Uint;
     };
     
     // https://github.com/ethereum/execution-apis/blob/main/src/schemas/transaction.json#L24
    @@ -131,34 +131,34 @@ export interface Block {
     	readonly stateRoot: HexString32Bytes;
     	readonly transactionsRoot: HexString32Bytes;
     	readonly receiptsRoot: HexString32Bytes;
    -	readonly logsBloom: HexString256Bytes | null;
    +	readonly logsBloom?: HexString256Bytes;
     	readonly difficulty?: Uint;
    -	readonly number: Uint | null;
    +	readonly number?: Uint;
     	readonly gasLimit: Uint;
     	readonly gasUsed: Uint;
     	readonly timestamp: Uint;
     	readonly extraData: HexStringBytes;
     	readonly mixHash: HexString32Bytes;
    -	readonly nonce: Uint | null;
    +	readonly nonce?: Uint;
     	readonly totalDifficulty: Uint;
     	readonly baseFeePerGas?: Uint;
     	readonly size: Uint;
     	readonly transactions: TransactionHash[] | TransactionInfo[];
     	readonly uncles: Uncles;
    -	readonly hash: HexString32Bytes | null;
    +	readonly hash?: HexString32Bytes;
     }
     
     // https://github.com/ethereum/execution-apis/blob/main/src/schemas/receipt.json#L2
     export interface Log {
     	readonly removed?: boolean;
    -	readonly logIndex?: Uint | null;
    -	readonly transactionIndex?: Uint | null;
    -	readonly transactionHash?: HexString32Bytes | null;
    -	readonly blockHash?: HexString32Bytes | null;
    -	readonly blockNumber?: Uint | null;
    +	readonly logIndex?: Uint;
    +	readonly transactionIndex?: Uint;
    +	readonly transactionHash?: HexString32Bytes;
    +	readonly blockHash?: HexString32Bytes;
    +	readonly blockNumber?: Uint;
     	readonly address?: Address;
     	readonly data?: HexStringBytes;
    -	readonly topics?: null | Topic | Topic[];
    +	readonly topics?: Topic | Topic[];
     }
     
     // https://github.com/ethereum/execution-apis/blob/main/src/schemas/receipt.json#L44
    @@ -171,7 +171,7 @@ export interface ReceiptInfo {
     	readonly to: Address;
     	readonly cumulativeGasUsed: Uint;
     	readonly gasUsed: Uint;
    -	readonly contractAddress: Address | null;
    +	readonly contractAddress?: Address;
     	readonly logs: Log[];
     	readonly logsBloom: HexString256Bytes;
     	readonly root: HexString32Bytes;
    @@ -224,16 +224,16 @@ export type EthExecutionAPI = {
     	eth_getUncleByBlockNumberAndIndex: (blockNumber: BlockNumberOrTag, uncleIndex: Uint) => Block;
     
     	// https://github.com/ethereum/execution-apis/blob/main/src/eth/transaction.json
    -	eth_getTransactionByHash: (transactionHash: HexString32Bytes) => TransactionInfo | null;
    +	eth_getTransactionByHash: (transactionHash: HexString32Bytes) => TransactionInfo | undefined;
     	eth_getTransactionByBlockHashAndIndex: (
     		blockHash: HexString32Bytes,
     		transactionIndex: Uint,
    -	) => TransactionInfo | null;
    +	) => TransactionInfo | undefined;
     	eth_getTransactionByBlockNumberAndIndex: (
     		blockNumber: BlockNumberOrTag,
     		transactionIndex: Uint,
    -	) => TransactionInfo | null;
    -	eth_getTransactionReceipt: (transactionHash: HexString32Bytes) => ReceiptInfo | null;
    +	) => TransactionInfo | undefined;
    +	eth_getTransactionReceipt: (transactionHash: HexString32Bytes) => ReceiptInfo | undefined;
     
     	// https://github.com/ethereum/execution-apis/blob/main/src/eth/client.json
     	eth_protocolVersion: () => string;
    
  • packages/web3-common/src/formatters.ts+51 20 modified
    @@ -35,7 +35,7 @@ import {
     	toUtf8,
     	utf8ToHex,
     } from 'web3-utils';
    -import { isBlockTag, isHex } from 'web3-validator';
    +import { isBlockTag, isHex, isNullish } from 'web3-validator';
     import {
     	BlockInput,
     	BlockOutput,
    @@ -55,11 +55,15 @@ import {
     
     /**
      * Will format the given storage key array values to hex strings.
    + *
    + * @param keys
      */
     export const inputStorageKeysFormatter = (keys: Array<string>) => keys.map(numberToHex);
     
     /**
      * Will format the given proof response from the node.
    + *
    + * @param proof
      */
     export const outputProofFormatter = (proof: Proof): Proof => ({
     	address: toChecksumAddress(proof.address),
    @@ -69,14 +73,18 @@ export const outputProofFormatter = (proof: Proof): Proof => ({
     
     /**
      * Should the format output to a big number
    + *
    + * @param number
      */
     export const outputBigIntegerFormatter = (number: Numbers) => toNumber(number);
     
     /**
      * Returns the given block number as hex string or the predefined block number 'latest', 'pending', 'earliest', 'genesis'
    + *
    + * @param blockNumber
      */
     export const inputBlockNumberFormatter = (blockNumber: Numbers | undefined) => {
    -	if (blockNumber === undefined) {
    +	if (isNullish(blockNumber)) {
     		return undefined;
     	}
     
    @@ -97,6 +105,9 @@ export const inputBlockNumberFormatter = (blockNumber: Numbers | undefined) => {
     
     /**
      * Returns the given block number as hex string or does return the defaultBlock property of the current module
    + *
    + * @param blockNumber
    + * @param defaultBlock
      */
     export const inputDefaultBlockNumberFormatter = (
     	blockNumber: Numbers | undefined,
    @@ -127,6 +138,8 @@ export const inputAddressFormatter = (address: string): string | never => {
     
     /**
      * Formats the input of a transaction and converts all values to HEX
    + *
    + * @param options
      */
     export const txInputOptionsFormatter = (options: TransactionInput): Mutable<TransactionOutput> => {
     	const modifiedOptions = { ...options } as unknown as Mutable<TransactionOutput>;
    @@ -165,7 +178,7 @@ export const txInputOptionsFormatter = (options: TransactionInput): Mutable<Tran
     	}
     
     	['gasPrice', 'gas', 'value', 'maxPriorityFeePerGas', 'maxFeePerGas', 'nonce', 'chainId']
    -		.filter(key => modifiedOptions[key] !== undefined)
    +		.filter(key => !isNullish(modifiedOptions[key]))
     		.forEach(key => {
     			modifiedOptions[key] = numberToHex(modifiedOptions[key] as Numbers);
     		});
    @@ -175,6 +188,9 @@ export const txInputOptionsFormatter = (options: TransactionInput): Mutable<Tran
     
     /**
      * Formats the input of a transaction and converts all values to HEX
    + *
    + * @param options
    + * @param defaultAccount
      */
     export const inputCallFormatter = (options: TransactionInput, defaultAccount?: string) => {
     	const opts = txInputOptionsFormatter(options);
    @@ -190,6 +206,9 @@ export const inputCallFormatter = (options: TransactionInput, defaultAccount?: s
     
     /**
      * Formats the input of a transaction and converts all values to HEX
    + *
    + * @param options
    + * @param defaultAccount
      */
     export const inputTransactionFormatter = (options: TransactionInput, defaultAccount?: string) => {
     	const opts = txInputOptionsFormatter(options);
    @@ -210,15 +229,17 @@ export const inputTransactionFormatter = (options: TransactionInput, defaultAcco
     
     /**
      * Hex encodes the data passed to eth_sign and personal_sign
    + *
    + * @param data
      */
     export const inputSignFormatter = (data: string) => (isHexStrict(data) ? data : utf8ToHex(data));
     
     /**
      * Formats the output of a transaction to its proper values
      *
    - * @method outputTransactionFormatter
    - * @param {Object} tx
    - * @returns {Object}
    + * @function outputTransactionFormatter
    + * @param {object} tx
    + * @returns {object}
      */
     export const outputTransactionFormatter = (tx: TransactionInput): TransactionOutput => {
     	const modifiedTx = { ...tx } as unknown as Mutable<TransactionOutput>;
    @@ -266,26 +287,31 @@ export const outputTransactionFormatter = (tx: TransactionInput): TransactionOut
     	return modifiedTx;
     };
     
    +// To align with specification we use the type "null" here
    +// eslint-disable-next-line @typescript-eslint/ban-types
     export const inputTopicFormatter = (topic: Topic): Topic | null => {
    -	if (topic === null || typeof topic === 'undefined') return null;
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
    +	if (isNullish(topic)) return null;
     
     	const value = String(topic);
     
     	return isHex(value) ? value : fromUtf8(value);
     };
     
     export const inputLogFormatter = (filter: Filter) => {
    -	const val: Mutable<Filter> =
    -		filter === undefined ? {} : mergeDeep({}, filter as Record<string, unknown>);
    +	const val: Mutable<Filter> = isNullish(filter)
    +		? {}
    +		: mergeDeep({}, filter as Record<string, unknown>);
     
     	// If options !== undefined, don't blow out existing data
    -	if (val.fromBlock === undefined) {
    +	if (isNullish(val.fromBlock)) {
     		val.fromBlock = BlockTags.LATEST;
     	}
     
     	val.fromBlock = inputBlockNumberFormatter(val.fromBlock);
     
    -	if (val.toBlock !== undefined) {
    +	if (!isNullish(val.toBlock)) {
     		val.toBlock = inputBlockNumberFormatter(val.toBlock);
     	}
     
    @@ -309,9 +335,9 @@ export const inputLogFormatter = (filter: Filter) => {
     /**
      * Formats the output of a log
      *
    - * @method outputLogFormatter
    - * @param {Object} log object
    - * @returns {Object} log
    + * @function outputLogFormatter
    + * @param {object} log object
    + * @returns {object} log
      */
     export const outputLogFormatter = (log: Partial<LogsInput>): LogsOutput => {
     	const modifiedLog = { ...log } as unknown as Mutable<LogsOutput>;
    @@ -353,6 +379,8 @@ export const outputLogFormatter = (log: Partial<LogsInput>): LogsOutput => {
     
     /**
      * Formats the output of a transaction receipt to its proper values
    + *
    + * @param receipt
      */
     export const outputTransactionReceiptFormatter = (receipt: ReceiptInput): ReceiptOutput => {
     	if (typeof receipt !== 'object') {
    @@ -393,9 +421,9 @@ export const outputTransactionReceiptFormatter = (receipt: ReceiptInput): Receip
     /**
      * Formats the output of a block to its proper values
      *
    - * @method outputBlockFormatter
    - * @param {Object} block
    - * @returns {Object}
    + * @function outputBlockFormatter
    + * @param {object} block
    + * @returns {object}
      */
     export const outputBlockFormatter = (block: BlockInput): BlockOutput => {
     	const modifiedBlock = { ...block } as unknown as Mutable<BlockOutput>;
    @@ -435,6 +463,8 @@ export const outputBlockFormatter = (block: BlockInput): BlockOutput => {
     
     /**
      * Formats the input of a whisper post and converts all values to HEX
    + *
    + * @param post
      */
     export const inputPostFormatter = (post: PostOutput): PostInput => {
     	const modifiedPost = { ...post } as unknown as Mutable<PostInput>;
    @@ -467,9 +497,10 @@ export const inputPostFormatter = (post: PostOutput): PostInput => {
     /**
      * Formats the output of a received post message
      *
    - * @method outputPostFormatter
    - * @param {Object}
    - * @returns {Object}
    + * @function outputPostFormatter
    + * @param post
    + * @param {object}
    + * @returns {object}
      */
     export const outputPostFormatter = (post: PostInput): PostOutput => {
     	const modifiedPost = { ...post } as unknown as Mutable<PostOutput>;
    
  • packages/web3-common/src/formatter.ts+4 4 modified
    @@ -25,7 +25,7 @@ import {
     	numberToHex,
     	toBigInt,
     } from 'web3-utils';
    -import { isObject, JsonSchema, utils, ValidationSchemaInput } from 'web3-validator';
    +import { isNullish, isObject, JsonSchema, utils, ValidationSchemaInput } from 'web3-validator';
     
     const { parseBaseType } = utils;
     
    @@ -159,7 +159,7 @@ export const convert = (
     		const schemaProp = findSchemaByDataPath(schema, dataPath);
     
     		// If value is a scaler value
    -		if (schemaProp === undefined) {
    +		if (isNullish(schemaProp)) {
     			delete object[key];
     			dataPath.pop();
     
    @@ -175,7 +175,7 @@ export const convert = (
     
     		// If value is an array
     		if (Array.isArray(value)) {
    -			if (schemaProp?.items === undefined) {
    +			if (isNullish(schemaProp?.items)) {
     				// Can not find schema for array item, delete that item
     				delete object[key];
     				dataPath.pop();
    @@ -184,7 +184,7 @@ export const convert = (
     			}
     
     			// If schema for array items is a single type
    -			if (isObject(schemaProp.items) && schemaProp.items.eth !== undefined) {
    +			if (isObject(schemaProp.items) && !isNullish(schemaProp.items.eth)) {
     				for (let i = 0; i < value.length; i += 1) {
     					(object[key] as unknown[])[i] = convertScalarValue(
     						value[i],
    
  • packages/web3-common/src/json_rpc.ts+12 8 modified
    @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    +import { isNullish } from 'web3-validator';
     import {
     	JsonRpcPayload,
     	JsonRpcResponse,
    @@ -36,8 +37,9 @@ export const isResponseWithResult = <Result = unknown, Error = unknown>(
     	!Array.isArray(response) &&
     	!!response &&
     	response.jsonrpc === '2.0' &&
    -	response.result !== undefined &&
    -	!response.error &&
    +	// JSON RPC consider "null" as valid response
    +	'result' in response &&
    +	isNullish(response.error) &&
     	(typeof response.id === 'number' || typeof response.id === 'string');
     
     export const isResponseWithError = <Error = unknown, Result = unknown>(
    @@ -46,8 +48,9 @@ export const isResponseWithError = <Error = unknown, Result = unknown>(
     	!Array.isArray(response) &&
     	response.jsonrpc === '2.0' &&
     	!!response &&
    -	response.result === undefined &&
    -	response.error !== undefined &&
    +	isNullish(response.result) &&
    +	// JSON RPC consider "null" as valid response
    +	'error' in response &&
     	(typeof response.id === 'number' || typeof response.id === 'string');
     
     export const isResponseWithNotification = <Result>(
    @@ -56,17 +59,18 @@ export const isResponseWithNotification = <Result>(
     	!Array.isArray(response) &&
     	!!response &&
     	response.jsonrpc === '2.0' &&
    -	response.params !== undefined &&
    -	response.method !== undefined;
    +	!isNullish(response.params) &&
    +	!isNullish(response.method);
     
     export const isSubscriptionResult = <Result>(
     	response: JsonRpcNotification<Result> | JsonRpcSubscriptionResult,
     ): response is JsonRpcSubscriptionResult =>
     	!Array.isArray(response) &&
     	!!response &&
     	response.jsonrpc === '2.0' &&
    -	response.id !== undefined &&
    -	response.result !== undefined;
    +	'id' in response &&
    +	// JSON RPC consider "null" as valid response
    +	'result' in response;
     
     export const validateResponse = <Result = unknown, Error = unknown>(
     	response: JsonRpcResponse<Result, Error>,
    
  • packages/web3-common/src/promi_event.ts+4 4 modified
    @@ -37,19 +37,19 @@ export class PromiEvent<ResolveType, EventMap extends Web3EventMap>
     	public [Symbol.toStringTag]: 'Promise';
     
     	public async then<TResult1 = ResolveType, TResult2 = never>(
    -		onfulfilled?: ((value: ResolveType) => TResult1 | PromiseLike<TResult1>) | null,
    -		onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
    +		onfulfilled?: ((value: ResolveType) => TResult1 | PromiseLike<TResult1>) | undefined,
    +		onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | undefined,
     	): Promise<TResult1 | TResult2> {
     		return this._promise.then(onfulfilled, onrejected);
     	}
     
     	public async catch<TResult = never>(
    -		onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
    +		onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined,
     	): Promise<ResolveType | TResult> {
     		return this._promise.catch(onrejected);
     	}
     
    -	public async finally(onfinally?: (() => void) | null): Promise<ResolveType> {
    +	public async finally(onfinally?: (() => void) | undefined): Promise<ResolveType> {
     		return this._promise.finally(onfinally);
     	}
     }
    
  • packages/web3-common/src/types.ts+6 6 modified
    @@ -17,7 +17,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     
     import { HexString, HexString32Bytes } from 'web3-utils';
     
    -export type JsonRpcId = string | number | null;
    +export type JsonRpcId = string | number | undefined;
     export type JsonRpcResult = string | number | boolean | Record<string, unknown>;
     export type JsonRpcIdentifier = string & ('2.0' | '1.0');
     
    @@ -146,11 +146,11 @@ export interface LogsInput {
     export interface LogsOutput {
     	readonly id?: string;
     	readonly removed: boolean;
    -	readonly logIndex: bigint | number | null;
    +	readonly logIndex?: bigint | number;
     	readonly transactionIndex?: bigint | number;
    -	readonly transactionHash: HexString32Bytes | null;
    -	readonly blockHash: HexString32Bytes | null;
    -	readonly blockNumber: bigint | number | null;
    +	readonly transactionHash?: HexString32Bytes;
    +	readonly blockHash?: HexString32Bytes;
    +	readonly blockNumber?: bigint | number;
     	readonly address: string;
     	readonly topics: HexString[];
     	readonly data: HexString;
    @@ -276,6 +276,6 @@ export type Receipt = Record<string, unknown>;
     // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#connectivity
     export type Web3BaseProviderStatus = 'connecting' | 'connected' | 'disconnected';
     export type Web3BaseProviderCallback<T = JsonRpcResult> = (
    -	error: Error | null,
    +	error: Error | undefined,
     	result?: JsonRpcSubscriptionResult | JsonRpcNotification<T>,
     ) => void;
    
  • packages/web3-common/test/unit/formatter.test.ts+28 28 modified
    @@ -25,11 +25,11 @@ import {
     } from '../../src/formatter';
     
     type TestTransactionInfoType = {
    -	readonly blockHash: Bytes | null;
    -	readonly blockNumber: Numbers | null;
    +	readonly blockHash?: Bytes;
    +	readonly blockNumber?: Numbers;
     	readonly from: Address;
     	readonly hash: Bytes;
    -	readonly transactionIndex: Numbers | null;
    +	readonly transactionIndex?: Numbers;
     };
     
     type TestBlockType = {
    @@ -39,21 +39,21 @@ type TestBlockType = {
     	readonly stateRoot: Bytes;
     	readonly transactionsRoot: Bytes;
     	readonly receiptsRoot: Bytes;
    -	readonly logsBloom: Bytes | null;
    +	readonly logsBloom?: Bytes;
     	readonly difficulty?: Numbers;
    -	readonly number: Numbers | null;
    +	readonly number?: Numbers;
     	readonly gasLimit: Numbers;
     	readonly gasUsed: Numbers;
     	readonly timestamp: Numbers;
     	readonly extraData: Bytes;
     	readonly mixHash: Bytes;
    -	readonly nonce: Numbers | null;
    +	readonly nonce?: Numbers;
     	readonly totalDifficulty: Numbers;
     	readonly baseFeePerGas?: Numbers;
     	readonly size: Numbers;
     	readonly transactions: Bytes[] | TestTransactionInfoType[];
     	readonly uncles: Bytes[];
    -	readonly hash: Bytes | null;
    +	readonly hash?: Bytes;
     };
     
     describe('formatter', () => {
    @@ -298,29 +298,29 @@ describe('formatter', () => {
     					readonly stateRoot: string;
     					readonly transactionsRoot: string;
     					readonly receiptsRoot: string;
    -					readonly logsBloom: string | null;
    +					readonly logsBloom?: string;
     					readonly difficulty?: string;
    -					readonly number: string | null;
    +					readonly number?: string;
     					readonly gasLimit: string;
     					readonly gasUsed: string;
     					readonly timestamp: string;
     					readonly extraData: string;
     					readonly mixHash: string;
    -					readonly nonce: string | null;
    +					readonly nonce?: string;
     					readonly totalDifficulty: string;
     					readonly baseFeePerGas?: string;
     					readonly size: string;
     					readonly transactions:
     						| string[]
     						| {
    -								readonly blockHash: string | null;
    -								readonly blockNumber: string | null;
    +								readonly blockHash?: string;
    +								readonly blockNumber?: string;
     								readonly from: Address;
     								readonly hash: string;
    -								readonly transactionIndex: string | null;
    +								readonly transactionIndex?: string;
     						  }[];
     					readonly uncles: string[];
    -					readonly hash: string | null;
    +					readonly hash?: string;
     				}>();
     			});
     
    @@ -337,29 +337,29 @@ describe('formatter', () => {
     					readonly stateRoot: Buffer;
     					readonly transactionsRoot: Buffer;
     					readonly receiptsRoot: Buffer;
    -					readonly logsBloom: Buffer | null;
    +					readonly logsBloom?: Buffer;
     					readonly difficulty?: bigint;
    -					readonly number: bigint | null;
    +					readonly number?: bigint;
     					readonly gasLimit: bigint;
     					readonly gasUsed: bigint;
     					readonly timestamp: bigint;
     					readonly extraData: Buffer;
     					readonly mixHash: Buffer;
    -					readonly nonce: bigint | null;
    +					readonly nonce?: bigint;
     					readonly totalDifficulty: bigint;
     					readonly baseFeePerGas?: bigint;
     					readonly size: bigint;
     					readonly transactions:
     						| Buffer[]
     						| {
    -								readonly blockHash: Buffer | null;
    -								readonly blockNumber: bigint | null;
    +								readonly blockHash?: Buffer;
    +								readonly blockNumber?: bigint;
     								readonly from: Address;
     								readonly hash: Buffer;
    -								readonly transactionIndex: bigint | null;
    +								readonly transactionIndex?: bigint;
     						  }[];
     					readonly uncles: Buffer[];
    -					readonly hash: Buffer | null;
    +					readonly hash?: Buffer;
     				}>();
     			});
     
    @@ -378,29 +378,29 @@ describe('formatter', () => {
     						readonly stateRoot: Uint8Array;
     						readonly transactionsRoot: Uint8Array;
     						readonly receiptsRoot: Uint8Array;
    -						readonly logsBloom: Uint8Array | null;
    +						readonly logsBloom?: Uint8Array;
     						readonly difficulty?: number;
    -						readonly number: number | null;
    +						readonly number?: number;
     						readonly gasLimit: number;
     						readonly gasUsed: number;
     						readonly timestamp: number;
     						readonly extraData: Uint8Array;
     						readonly mixHash: Uint8Array;
    -						readonly nonce: number | null;
    +						readonly nonce?: number;
     						readonly totalDifficulty: number;
     						readonly baseFeePerGas?: number;
     						readonly size: number;
     						readonly transactions:
     							| Uint8Array[]
     							| {
    -									readonly blockHash: Uint8Array | null;
    -									readonly blockNumber: number | null;
    +									readonly blockHash?: Uint8Array;
    +									readonly blockNumber?: number;
     									readonly from: Address;
     									readonly hash: Uint8Array;
    -									readonly transactionIndex: number | null;
    +									readonly transactionIndex?: number;
     							  }[];
     						readonly uncles: Uint8Array[];
    -						readonly hash: Uint8Array | null;
    +						readonly hash?: Uint8Array;
     					}>();
     				},
     			);
    
  • packages/web3-common/test/unit/promi_event.test.ts+2 2 modified
    @@ -42,7 +42,7 @@ describe('PromiEvent', () => {
     
     			p.on('data', data => {
     				expect(data).toBe('resolved value');
    -				done(null);
    +				done(undefined);
     			});
     
     			p.then(data => {
    @@ -71,7 +71,7 @@ describe('PromiEvent', () => {
     
     			p.on('data', data => {
     				expect(data).toBe('emitted data');
    -				done(null);
    +				done(undefined);
     			});
     		});
     	});
    
  • packages/web3-core/src/types.ts+4 2 modified
    @@ -28,14 +28,16 @@ import { HexString } from 'web3-utils';
     export type LegacyRequestProvider = {
     	request: <R = JsonRpcResult, P = unknown>(
     		payload: JsonRpcPayload<P>,
    -		cb: (err: Error | null, response: JsonRpcResponse<R>) => void,
    +		cb: (err: Error | undefined, response: JsonRpcResponse<R>) => void,
     	) => void;
     };
     
     export type LegacySendProvider = {
     	send: <R = JsonRpcResult, P = unknown>(
     		payload: JsonRpcPayload<P>,
    -		cb: (err: Error | null, response: JsonRpcResponse<R>) => void,
    +		// Used "null" value to match the legacy version
    +		// eslint-disable-next-line @typescript-eslint/ban-types
    +		cb: (err?: Error | null, response?: JsonRpcResponse<R>) => void,
     	) => void;
     };
     
    
  • packages/web3-core/src/web3_context.ts+9 1 modified
    @@ -186,6 +186,9 @@ export class Web3Context<
     	 * Use to create new object of any type extended by `Web3Context`
     	 * and link it to current context. This can be used to initiate a global context object
     	 * and then use it to create new objects of any type extended by `Web3Context`.
    +	 *
    +	 * @param ContextRef
    +	 * @param {...any} args
     	 */
     	// eslint-disable-next-line @typescript-eslint/no-explicit-any
     	public use<T extends Web3Context<any>, T2 extends unknown[]>(
    @@ -206,6 +209,8 @@ export class Web3Context<
     
     	/**
     	 * Link current context to another context.
    +	 *
    +	 * @param parentContext
     	 */
     	public link<T extends Web3Context<API, RegisteredSubs>>(parentContext: T) {
     		this.setConfig(parentContext.getConfig());
    @@ -247,7 +252,10 @@ export class Web3Context<
     	}
     
     	public get BatchRequest(): new () => Web3BatchRequest {
    -		return Web3BatchRequest.bind(null, this._requestManager as unknown as Web3RequestManager);
    +		return Web3BatchRequest.bind(
    +			undefined,
    +			this._requestManager as unknown as Web3RequestManager,
    +		);
     	}
     }
     
    
  • packages/web3-core/src/web3_request_manager.ts+9 1 modified
    @@ -37,6 +37,7 @@ import {
     import HttpProvider from 'web3-providers-http';
     import WSProvider from 'web3-providers-ws';
     import IpcProvider from 'web3-providers-ipc';
    +import { isNullish } from 'web3-utils';
     import { SupportedProviders, Web3BaseProviderConstructor } from './types';
     import {
     	isLegacyRequestProvider,
    @@ -110,7 +111,7 @@ export class Web3RequestManager<
     		}
     
     		this.emit(Web3RequestManagerEvent.BEFORE_PROVIDER_CHANGE, this._provider);
    -		this._provider = newProvider ?? provider ?? null;
    +		this._provider = newProvider ?? provider;
     		this.emit(Web3RequestManagerEvent.PROVIDER_CHANGED, this._provider);
     	}
     
    @@ -181,6 +182,13 @@ export class Web3RequestManager<
     						throw err;
     					}
     
    +					if (isNullish(response)) {
    +						throw new ResponseError(
    +							'' as never,
    +							'Got a "nullish" response from provider.',
    +						);
    +					}
    +
     					return resolve(this._processJsonRpcResponse(payload, response));
     				});
     			});
    
  • packages/web3-core/src/web3_subscription_manager.ts+7 4 modified
    @@ -17,6 +17,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     
     import { Web3APISpec } from 'web3-common';
     import { ProviderError, SubscriptionError } from 'web3-errors';
    +import { isNullish } from 'web3-utils';
     import { isSupportSubscriptions } from './utils';
     import { Web3RequestManager, Web3RequestManagerEvent } from './web3_request_manager';
     import { Web3SubscriptionConstructor } from './web3_subscriptions';
    @@ -63,7 +64,7 @@ export class Web3SubscriptionManager<
     			throw new SubscriptionError('Invalid subscription type');
     		}
     
    -		const subscription = new Klass(args ?? null, {
    +		const subscription = new Klass(args ?? undefined, {
     			requestManager: this.requestManager,
     		}) as InstanceType<RegisteredSubs[T]>;
     
    @@ -87,20 +88,22 @@ export class Web3SubscriptionManager<
     
     		await sub.subscribe();
     
    -		if (sub.id === undefined) {
    +		if (isNullish(sub.id)) {
     			throw new SubscriptionError('Subscription is not subscribed yet.');
     		}
     
     		this._subscriptions.set(sub.id, sub);
     	}
     
     	public async removeSubscription(sub: InstanceType<RegisteredSubs[keyof RegisteredSubs]>) {
    -		if (sub.id === undefined) {
    +		if (isNullish(sub.id)) {
     			throw new SubscriptionError('Subscription is not subscribed yet.');
     		}
     
     		if (!this._subscriptions.has(sub.id)) {
    -			throw new SubscriptionError(`Subscription with id "${sub.id}" does not exists`);
    +			throw new SubscriptionError(
    +				`Subscription with id "${sub.id.toString()}" does not exists`,
    +			);
     		}
     		const { id } = sub;
     		await sub.unsubscribe();
    
  • packages/web3-core/src/web3_subscriptions.ts+2 2 modified
    @@ -41,7 +41,7 @@ export abstract class Web3Subscription<
     	private readonly _requestManager: Web3RequestManager<API>;
     	private readonly _lastBlock?: BlockOutput;
     	private _id?: HexString;
    -	private _messageListener?: (e: Error | null, data?: JsonRpcNotification<Log>) => void;
    +	private _messageListener?: (e: Error | undefined, data?: JsonRpcNotification<Log>) => void;
     
     	public constructor(
     		public readonly args: ArgsType,
    @@ -66,7 +66,7 @@ export abstract class Web3Subscription<
     		});
     
     		const messageListener = (
    -			err: Error | null,
    +			err: Error | undefined,
     			data?: JsonRpcSubscriptionResult | JsonRpcNotification<Log>,
     		) => {
     			if (data && jsonRpc.isResponseWithNotification(data)) {
    
  • packages/web3-core/test/unit/web3_request_manager.test.ts+4 4 modified
    @@ -354,7 +354,7 @@ describe('Web3RequestManager', () => {
     					request: jest
     						.fn()
     						.mockImplementation((_, cb: (error?: any, data?: any) => void) => {
    -							cb(null, errorResponse);
    +							cb(undefined, errorResponse);
     						}),
     				} as any;
     
    @@ -416,7 +416,7 @@ describe('Web3RequestManager', () => {
     					send: jest
     						.fn()
     						.mockImplementation((_, cb: (error?: any, data?: any) => void) => {
    -							cb(null, errorResponse);
    +							cb(undefined, errorResponse);
     						}),
     				} as any;
     
    @@ -618,7 +618,7 @@ describe('Web3RequestManager', () => {
     					request: jest
     						.fn()
     						.mockImplementation((_, cb: (error?: any, data?: any) => void) => {
    -							cb(null, errorResponse);
    +							cb(undefined, errorResponse);
     						}),
     				} as any;
     
    @@ -678,7 +678,7 @@ describe('Web3RequestManager', () => {
     					send: jest
     						.fn()
     						.mockImplementation((_, cb: (error?: any, data?: any) => void) => {
    -							cb(null, errorResponse);
    +							cb(undefined, errorResponse);
     						}),
     				} as any;
     
    
  • packages/web3-errors/src/errors/transaction_errors.ts+5 3 modified
    @@ -58,7 +58,9 @@ export class TransactionRevertError extends Web3Error {
     	public code = ERR_TX_REVERT_TRANSACTION;
     
     	public constructor(public reason: string, public signature: string, public receipt: Receipt) {
    -		super(`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, null, 2)}`);
    +		super(
    +			`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
    +		);
     	}
     
     	public toJSON() {
    @@ -92,7 +94,7 @@ export class ContractCodeNotStoredError extends TransactionError {
     export class TransactionRevertedWithoutReasonError extends TransactionError {
     	public constructor(receipt: Receipt) {
     		super(
    -			`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, null, 2)}`,
    +			`Transaction has been reverted by the EVM:\n ${JSON.stringify(receipt, undefined, 2)}`,
     			receipt,
     		);
     		this.code = ERR_TX_REVERT_WITHOUT_REASON;
    @@ -104,7 +106,7 @@ export class TransactionOutOfGasError extends TransactionError {
     		super(
     			`Transaction ran out of gas. Please provide more gas:\n ${JSON.stringify(
     				receipt,
    -				null,
    +				undefined,
     				2,
     			)}`,
     			receipt,
    
  • packages/web3-errors/src/web3_error_base.ts+3 1 modified
    @@ -34,7 +34,9 @@ export abstract class Web3Error extends Error {
     	}
     
     	public static convertToString(value: unknown, unquotValue = false) {
    -		if (value === undefined) return 'undefined';
    +		// Using "null" value intentionally for validation
    +		// eslint-disable-next-line no-null/no-null
    +		if (value === null || value === undefined ) return 'undefined';
     
     		const result = JSON.stringify(
     			value,
    
  • packages/web3-eth-abi/src/api/events_api.ts+2 0 modified
    @@ -22,6 +22,8 @@ import { jsonInterfaceMethodToString, isAbiEventFragment } from '../utils';
     
     /**
      * Encodes the event name to its ABI signature, which are the sha3 hash of the event name including input types..
    + *
    + * @param functionName
      */
     export const encodeEventSignature = (functionName: string | AbiEventFragment): string => {
     	if (typeof functionName !== 'string' && !isAbiEventFragment(functionName)) {
    
  • packages/web3-eth-abi/src/api/functions_api.ts+5 0 modified
    @@ -23,6 +23,8 @@ import { encodeParameters } from './parameters_api';
     
     /**
      * Encodes the function name to its ABI representation, which are the first 4 bytes of the sha3 of the function name including  types.
    + *
    + * @param functionName
      */
     export const encodeFunctionSignature = (functionName: string | AbiFunctionFragment): string => {
     	if (typeof functionName !== 'string' && !isAbiFunctionFragment(functionName)) {
    @@ -42,6 +44,9 @@ export const encodeFunctionSignature = (functionName: string | AbiFunctionFragme
     
     /**
      * Encodes a function call from its json interface and parameters.
    + *
    + * @param jsonInterface
    + * @param params
      */
     export const encodeFunctionCall = (
     	jsonInterface: AbiFunctionFragment,
    
  • packages/web3-eth-abi/src/api/logs_api.ts+5 1 modified
    @@ -23,6 +23,10 @@ const STATIC_TYPES = ['bool', 'string', 'int', 'uint', 'address', 'fixed', 'ufix
     
     /**
      * Decodes ABI-encoded log data and indexed topic data
    + *
    + * @param inputs
    + * @param data
    + * @param topics
      */
     export const decodeLog = <ReturnType extends Record<string, unknown>>(
     	inputs: Array<AbiParameter>,
    @@ -62,7 +66,7 @@ export const decodeLog = <ReturnType extends Record<string, unknown>>(
     	let nonIndexedCounter = 0;
     
     	for (const [i, res] of inputs.entries()) {
    -		returnValue[i] = res.type === 'string' ? '' : null;
    +		returnValue[i] = res.type === 'string' ? '' : undefined;
     
     		if (indexedInputs[i]) {
     			returnValue[i] = decodedIndexedInputs[indexedCounter];
    
  • packages/web3-eth-abi/src/api/parameters_api.ts+18 0 modified
    @@ -47,6 +47,9 @@ const formatDecodedObject = (
     
     /**
      * Should be used to encode list of params
    + *
    + * @param abi
    + * @param params
      */
     export const encodeParameters = (abi: ReadonlyArray<AbiInput>, params: unknown[]): string => {
     	try {
    @@ -85,12 +88,19 @@ export const encodeParameters = (abi: ReadonlyArray<AbiInput>, params: unknown[]
     
     /**
      * Should be used to encode plain param
    + *
    + * @param abi
    + * @param param
      */
     export const encodeParameter = (abi: AbiInput, param: unknown): string =>
     	encodeParameters([abi], [param]);
     
     /**
      * Should be used to decode list of params
    + *
    + * @param abis
    + * @param bytes
    + * @param loose
      */
     export const decodeParametersWith = (
     	abis: AbiInput[],
    @@ -124,6 +134,8 @@ export const decodeParametersWith = (
     			// only convert `0x` to null if it's not string value
     			// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
     			decodedValue =
    +				// Using "null" value to match with legacy behavior
    +				// eslint-disable-next-line no-null/no-null
     				decodedValue === '0x' && !isStringObject && !isStringType ? null : decodedValue;
     
     			if (!!abi && typeof abi === 'object' && !abi.name && !Array.isArray(abi)) {
    @@ -149,11 +161,17 @@ export const decodeParametersWith = (
     
     /**
      * Should be used to decode list of params
    + *
    + * @param abi
    + * @param bytes
      */
     export const decodeParameters = (abi: AbiInput[], bytes: HexString) =>
     	decodeParametersWith(abi, bytes, false);
     
     /**
      * Should be used to decode bytes to plain param
    + *
    + * @param abi
    + * @param bytes
      */
     export const decodeParameter = (abi: AbiInput, bytes: HexString) => decodeParameters([abi], bytes);
    
  • packages/web3-eth-abi/src/utils.ts+26 13 modified
    @@ -17,7 +17,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     
     import { AbiError } from 'web3-errors';
     import { AbiCoder, ParamType } from '@ethersproject/abi';
    -import { leftPad, rightPad, toHex } from 'web3-utils';
    +import { isNullish, leftPad, rightPad, toHex } from 'web3-utils';
     import ethersAbiCoder from './ethers_abi_coder';
     import {
     	AbiInput,
    @@ -31,35 +31,33 @@ import {
     } from './types';
     
     export const isAbiFragment = (item: unknown): item is AbiFragment =>
    -	item !== undefined &&
    -	item !== null &&
    +	!isNullish(item) &&
     	typeof item === 'object' &&
    -	(item as { type: string }).type !== undefined &&
    +	!isNullish((item as { type: string }).type) &&
     	['function', 'event', 'constructor'].includes((item as { type: string }).type);
     
     export const isAbiEventFragment = (item: unknown): item is AbiEventFragment =>
    -	item !== undefined &&
    -	item !== null &&
    +	!isNullish(item) &&
     	typeof item === 'object' &&
    -	(item as { type: string }).type !== undefined &&
    +	!isNullish((item as { type: string }).type) &&
     	(item as { type: string }).type === 'event';
     
     export const isAbiFunctionFragment = (item: unknown): item is AbiFunctionFragment =>
    -	item !== undefined &&
    -	item !== null &&
    +	!isNullish(item) &&
     	typeof item === 'object' &&
    -	(item as { type: string }).type !== undefined &&
    +	!isNullish((item as { type: string }).type) &&
     	(item as { type: string }).type === 'function';
     
     export const isAbiConstructorFragment = (item: unknown): item is AbiConstructorFragment =>
    -	item !== undefined &&
    -	item !== null &&
    +	!isNullish(item) &&
     	typeof item === 'object' &&
    -	(item as { type: string }).type !== undefined &&
    +	!isNullish((item as { type: string }).type) &&
     	(item as { type: string }).type === 'constructor';
     
     /**
      * Check if type is simplified struct format
    + *
    + * @param type
      */
     export const isSimplifiedStructFormat = (
     	type: string | Partial<AbiParameter>,
    @@ -70,6 +68,8 @@ export const isSimplifiedStructFormat = (
     
     /**
      * Maps the correct tuple type and name when the simplified format in encode/decodeParameter is used
    + *
    + * @param structName
      */
     export const mapStructNameAndType = (structName: string): AbiStruct =>
     	structName.includes('[]')
    @@ -78,6 +78,8 @@ export const mapStructNameAndType = (structName: string): AbiStruct =>
     
     /**
      * Maps the simplified format in to the expected format of the ABICoder
    + *
    + * @param struct
      */
     export const mapStructToCoderFormat = (struct: AbiStruct): Array<AbiCoderStruct> => {
     	const components: Array<AbiCoderStruct> = [];
    @@ -102,6 +104,8 @@ export const mapStructToCoderFormat = (struct: AbiStruct): Array<AbiCoderStruct>
     
     /**
      * Map types if simplified format is used
    + *
    + * @param types
      */
     export const mapTypes = (
     	types: AbiInput[],
    @@ -142,18 +146,25 @@ export const mapTypes = (
     
     /**
      * returns true if input is a hexstring and is odd-lengthed
    + *
    + * @param param
      */
     export const isOddHexstring = (param: unknown): boolean =>
     	typeof param === 'string' && /^(-)?0x[0-9a-f]*$/i.test(param) && param.length % 2 === 1;
     
     /**
      * format odd-length bytes to even-length
    + *
    + * @param param
      */
     export const formatOddHexstrings = (param: string): string =>
     	isOddHexstring(param) ? `0x0${param.substring(2)}` : param;
     
     /**
      * Handle some formatting of params for backwards compatibility with Ethers V4
    + *
    + * @param type
    + * @param _param
      */
     export const formatParam = (type: string, _param: unknown): unknown => {
     	// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    @@ -280,6 +291,8 @@ export const flattenTypes = (
     /**
      * Should be used to create full function/event name from json abi
      * returns a string
    + *
    + * @param json
      */
     export const jsonInterfaceMethodToString = (json: AbiFragment): string => {
     	if (isAbiEventFragment(json) || isAbiFunctionFragment(json)) {
    
  • packages/web3-eth-abi/test/fixtures/data.ts+10 0 modified
    @@ -207,6 +207,8 @@ export const inValidFunctionsSignatures: { input: any; output: string }[] = [
     	{ input: 345, output: 'Invalid parameter value in encodeFunctionSignature' },
     	{ input: {}, output: 'Invalid parameter value in encodeFunctionSignature' },
     	{ input: ['mystring'], output: 'Invalid parameter value in encodeFunctionSignature' },
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	{ input: null, output: 'Invalid parameter value in encodeFunctionSignature' },
     	{ input: undefined, output: 'Invalid parameter value in encodeFunctionSignature' },
     ];
    @@ -238,6 +240,8 @@ export const inValidFunctionsCalls: { input: any; output: string }[] = [
     	{ input: 345, output: 'Invalid parameter value in encodeFunctionCall' },
     	{ input: {}, output: 'Invalid parameter value in encodeFunctionCall' },
     	{ input: ['mystring'], output: 'Invalid parameter value in encodeFunctionCall' },
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	{ input: null, output: 'Invalid parameter value in encodeFunctionCall' },
     	{ input: undefined, output: 'Invalid parameter value in encodeFunctionCall' },
     ];
    @@ -270,6 +274,8 @@ export const invalidEventsSignatures: { input: any; output: string }[] = [
     	{ input: 345, output: 'Invalid parameter value in encodeEventSignature' },
     	{ input: {}, output: 'Invalid parameter value in encodeEventSignature' },
     	{ input: ['mystring'], output: 'Invalid parameter value in encodeEventSignature' },
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	{ input: null, output: 'Invalid parameter value in encodeEventSignature' },
     	{ input: undefined, output: 'Invalid parameter value in encodeEventSignature' },
     ];
    @@ -556,6 +562,8 @@ export const inValidEncodeParametersData: {
     		output: 'Parameter encoding error',
     	},
     	{
    +		// Using "null" value intentionally for validation
    +		// eslint-disable-next-line no-null/no-null
     		input: [null, ['2345675643', 'Hello!%']],
     		output: 'Parameter encoding error',
     	},
    @@ -634,6 +642,8 @@ export const inValidDecodeParametersData: {
     		output: 'Parameter decoding error',
     	},
     	{
    +		// Using "null" value intentionally for validation
    +		// eslint-disable-next-line no-null/no-null
     		input: [null, '0x000000000010'],
     		output: 'Parameter decoding error',
     	},
    
  • packages/web3-eth-accounts/src/account.ts+26 5 modified
    @@ -51,7 +51,7 @@ import {
     	isHexStrict,
     	utf8ToHex,
     } from 'web3-utils';
    -import { validator, isBuffer, isHexString32Bytes, isString } from 'web3-validator';
    +import { validator, isBuffer, isHexString32Bytes, isString, isNullish } from 'web3-validator';
     import {
     	signatureObject,
     	signResult,
    @@ -82,6 +82,9 @@ export const hashMessage = (message: string): string => {
     
     /**
      * Signs arbitrary data. The value passed as the data parameter will be UTF-8 HEX decoded and wrapped as follows: "\x19Ethereum Signed Message:\n" + message.length + message
    + *
    + * @param data
    + * @param privateKey
      */
     export const sign = (data: string, privateKey: HexString): signResult => {
     	const privateKeyParam = privateKey.startsWith('0x') ? privateKey.substring(2) : privateKey;
    @@ -113,6 +116,9 @@ export const sign = (data: string, privateKey: HexString): signResult => {
     
     /**
      *  Signs an Ethereum transaction with a given private key.
    + *
    + * @param transaction
    + * @param privateKey
      */
     export const signTransaction = (
     	transaction: TxData | AccessListEIP2930TxData | FeeMarketEIP1559TxData,
    @@ -123,7 +129,7 @@ export const signTransaction = (
     
     	const tx = TransactionFactory.fromTxData(transaction);
     	const signedTx = tx.sign(Buffer.from(privateKey.substring(2), 'hex'));
    -	if (signedTx.v === undefined || signedTx.r === undefined || signedTx.s === undefined)
    +	if (isNullish(signedTx.v) || isNullish(signedTx.r) || isNullish(signedTx.s))
     		throw new SignerError('Signer Error');
     
     	const validationErrors = signedTx.validate(true);
    @@ -152,9 +158,11 @@ export const signTransaction = (
     
     /**
      * Recovers the Ethereum address which was used to sign the given RLP encoded transaction.
    + *
    + * @param rawTransaction
      */
     export const recoverTransaction = (rawTransaction: HexString): Address => {
    -	if (rawTransaction === undefined) throw new UndefinedRawTransactionError();
    +	if (isNullish(rawTransaction)) throw new UndefinedRawTransactionError();
     
     	const tx = TransactionFactory.fromSerializedData(Buffer.from(rawTransaction.slice(2), 'hex'));
     
    @@ -163,6 +171,10 @@ export const recoverTransaction = (rawTransaction: HexString): Address => {
     
     /**
      * Recovers the Ethereum address which was used to sign the given data
    + *
    + * @param data
    + * @param signature
    + * @param hashed
      */
     export const recover = (
     	data: string | signatureObject,
    @@ -174,7 +186,7 @@ export const recover = (
     		return recover(data.messageHash, signatureStr, true);
     	}
     
    -	if (signature === undefined) throw new InvalidSignatureError('signature string undefined');
    +	if (isNullish(signature)) throw new InvalidSignatureError('signature string undefined');
     
     	const V_INDEX = 130; // r = first 32 bytes, s = second 32 bytes, v = last byte of signature
     	const hashedMessage = hashed ? data : hashMessage(data);
    @@ -253,6 +265,10 @@ export const privateKeyToAddress = (privateKey: string | Buffer): string => {
     /**
      * encrypt a private key given a password, returns a V3 JSON Keystore
      * https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
    + *
    + * @param privateKey
    + * @param password
    + * @param options
      */
     export const encrypt = async (
     	privateKey: HexString,
    @@ -373,6 +389,8 @@ export const encrypt = async (
     
     /**
      * Get account from private key
    + *
    + * @param privateKey
      */
     export const privateKeyToAccount = (privateKey: string | Buffer): Web3Account => {
     	const pKey = Buffer.isBuffer(privateKey) ? Buffer.from(privateKey).toString('hex') : privateKey;
    @@ -403,7 +421,10 @@ export const create = (): Web3Account => {
     /**
      *  Decrypts a v3 keystore JSON, and creates the account.
      *
    - * */
    + * @param keystore
    + * @param password
    + * @param nonStrict
    + */
     export const decrypt = async (
     	keystore: KeyStore | string,
     	password: string | Buffer,
    
  • packages/web3-eth-accounts/src/wallet.ts+2 1 modified
    @@ -21,6 +21,7 @@ import {
     	Web3AccountProvider,
     	Web3EncryptedWallet,
     } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     type BrowserError = { code: number; name: string };
     
    @@ -57,7 +58,7 @@ export class Wallet<
     					// Firefox
     					(e as BrowserError).name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
     				// acknowledge QuotaExceededError only if there's something already stored
    -				storage !== undefined &&
    +				!isNullish(storage) &&
     				storage.length !== 0
     				? storage
     				: undefined;
    
  • packages/web3-eth-contract/src/contract.ts+5 5 modified
    @@ -142,7 +142,7 @@ export class Contract<Abi extends ContractAbi>
     	public static handleRevert?: boolean;
     
     	private _jsonInterface!: Abi;
    -	private _address?: Address | null;
    +	private _address?: Address;
     	private _functions: Record<
     		string,
     		{
    @@ -189,8 +189,8 @@ export class Contract<Abi extends ContractAbi>
     		this.options = {
     			address: undefined,
     			jsonInterface: [],
    -			gas: options?.gas ?? options?.gasLimit ?? null,
    -			gasPrice: options?.gasPrice ?? null,
    +			gas: options?.gas ?? options?.gasLimit,
    +			gasPrice: options?.gasPrice,
     			gasLimit: options?.gasLimit,
     			from: options?.from,
     			data: options?.data,
    @@ -436,7 +436,7 @@ export class Contract<Abi extends ContractAbi>
     	}
     
     	private _parseAndSetAddress(value?: Address) {
    -		this._address = value ? toChecksumAddress(inputAddressFormatter(value)) : null;
    +		this._address = value ? toChecksumAddress(inputAddressFormatter(value)) : value;
     	}
     
     	private _parseAndSetJsonInterface(abis: ContractAbi) {
    @@ -626,7 +626,7 @@ export class Contract<Abi extends ContractAbi>
     				const newContract = this.clone();
     
     				// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
    -				newContract.options.address = receipt.contractAddress as HexString;
    +				newContract.options.address = receipt.contractAddress;
     
     				return newContract;
     			},
    
  • packages/web3-eth-contract/src/encoding.ts+6 2 modified
    @@ -40,7 +40,9 @@ export const encodeEventABI = (
     		fromBlock?: BlockNumberOrTag;
     		toBlock?: BlockNumberOrTag;
     		filter?: Filter;
    -		topics?: (Topic | Topic[] | null)[];
    +		// Using "null" type intentionally to match specifications
    +		// eslint-disable-next-line @typescript-eslint/ban-types
    +		topics?: (null | Topic | Topic[])[];
     	},
     ) => {
     	const opts: {
    @@ -146,7 +148,7 @@ export const decodeEventABI = (
     		...result,
     		returnValue: decodeLog([...event.inputs], data.data, argTopics),
     		event: event.name,
    -		signature: event.anonymous || !data.topics[0] ? null : data.topics[0],
    +		signature: event.anonymous || !data.topics[0] ? undefined : data.topics[0],
     		raw: {
     			data: data.data,
     			topics: data.topics,
    @@ -195,6 +197,8 @@ export const decodeMethodReturn = (abi: AbiFunctionFragment, returnValues?: HexS
     	}
     
     	if (!returnValues) {
    +		// Using "null" value intentionally to match legacy behavior
    +		// eslint-disable-next-line no-null/no-null
     		return null;
     	}
     
    
  • packages/web3-eth-contract/src/types.ts+4 4 modified
    @@ -46,8 +46,8 @@ export interface ContractEventOptions {
     }
     
     export interface ContractOptions {
    -	readonly gas: Uint | null;
    -	readonly gasPrice: Uint | null;
    +	readonly gas?: Uint;
    +	readonly gasPrice?: Uint;
     	readonly gasLimit?: Uint;
     	readonly from?: Address;
     	readonly data?: Bytes;
    @@ -56,8 +56,8 @@ export interface ContractOptions {
     }
     
     export interface ContractInitOptions {
    -	readonly gas?: Uint | null;
    -	readonly gasPrice?: Uint | null;
    +	readonly gas?: Uint;
    +	readonly gasPrice?: Uint;
     	readonly from?: Address;
     	readonly data?: Bytes;
     	readonly gasLimit?: Uint;
    
  • packages/web3-eth-contract/test/fixtures/encoding.ts+2 2 modified
    @@ -118,7 +118,7 @@ export const decodeEventABIData: [AbiEventFragment & { signature: string }, Logs
     				c: '192',
     			},
     			event: '',
    -			signature: null,
    +			signature: undefined,
     			raw: {
     				data: '0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000002307800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000000',
     				topics: [],
    @@ -157,7 +157,7 @@ export const decodeEventABIData: [AbiEventFragment & { signature: string }, Logs
     				c: '192',
     			},
     			event: '',
    -			signature: null,
    +			signature: undefined,
     			raw: {
     				data: '0x0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000002307800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016200000000000000000000000000000000000000000000000000000000000000',
     				topics: [],
    
  • packages/web3-eth-contract/test/integration/contract_defaults.test.ts+4 12 modified
    @@ -101,7 +101,7 @@ describe('contract', () => {
     				// Forcefully delete this property from the contract instance
     				// eslint-disable-next-line @typescript-eslint/ban-ts-comment
     				// @ts-expect-error
    -				contract.defaultBlock = null;
    +				contract.defaultBlock = undefined;
     
     				await contract.methods.greet().call();
     
    @@ -120,11 +120,7 @@ describe('contract', () => {
     					'request',
     				);
     				contract.defaultBlock = 'pending';
    -
    -				// Forcefully delete this property from the contract instance
    -				// eslint-disable-next-line @typescript-eslint/ban-ts-comment
    -				// @ts-expect-error
    -				Contract.defaultBlock = null;
    +				Contract.defaultBlock = undefined;
     
     				await contract.methods.greet().call();
     
    @@ -146,12 +142,8 @@ describe('contract', () => {
     				// Forcefully delete this property from the contract instance
     				// eslint-disable-next-line @typescript-eslint/ban-ts-comment
     				// @ts-expect-error
    -				contract.defaultBlock = null;
    -
    -				// Forcefully delete this property from the contract instance
    -				// eslint-disable-next-line @typescript-eslint/ban-ts-comment
    -				// @ts-expect-error
    -				Contract.defaultBlock = null;
    +				contract.defaultBlock = undefined;
    +				Contract.defaultBlock = undefined;
     
     				await contract.methods.greet().call(undefined, 'pending');
     
    
  • packages/web3-eth-contract/test/integration/contract_deploy.test.ts+37 21 modified
    @@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Contract } from '../../src';
    -import { sleep, processAsync } from '../shared_fixtures/utils';
    +import { sleep } from '../shared_fixtures/utils';
     import { GreeterBytecode, GreeterAbi } from '../shared_fixtures/build/Greeter';
     import { DeployRevertAbi, DeployRevertBytecode } from '../shared_fixtures/build/DeployRevert';
     import { getSystemTestProvider, getSystemTestAccounts } from '../fixtures/system_test_utils';
    @@ -95,35 +95,51 @@ describe('contract', () => {
     		});
     
     		it('should emit the "transactionHash" event', async () => {
    -			await expect(
    -				processAsync(resolve => {
    -					contract.deploy(deployOptions).send(sendOptions).on('transactionHash', resolve);
    -				}),
    -			).resolves.toBeDefined();
    +			const handler = jest.fn();
    +
    +			const promiEvent = contract.deploy(deployOptions).send(sendOptions);
    +
    +			promiEvent.on('transactionHash', handler);
    +			// Deploy the contract
    +			await promiEvent;
    +
    +			expect(handler).toHaveBeenCalled();
     		});
     
     		it('should emit the "sending" event', async () => {
    -			await expect(
    -				processAsync(resolve => {
    -					contract.deploy(deployOptions).send(sendOptions).on('sending', resolve);
    -				}),
    -			).resolves.toBeDefined();
    +			const handler = jest.fn();
    +
    +			const promiEvent = contract.deploy(deployOptions).send(sendOptions);
    +
    +			promiEvent.on('sending', handler);
    +			// Deploy the contract
    +			await promiEvent;
    +
    +			expect(handler).toHaveBeenCalled();
     		});
     
     		it('should emit the "sent" event', async () => {
    -			await expect(
    -				processAsync(resolve => {
    -					contract.deploy(deployOptions).send(sendOptions).on('sent', resolve);
    -				}),
    -			).resolves.toBeDefined();
    +			const handler = jest.fn();
    +
    +			const promiEvent = contract.deploy(deployOptions).send(sendOptions);
    +
    +			promiEvent.on('sent', handler);
    +			// Deploy the contract
    +			await promiEvent;
    +
    +			expect(handler).toHaveBeenCalled();
     		});
     
     		it('should emit the "receipt" event', async () => {
    -			await expect(
    -				processAsync(resolve => {
    -					contract.deploy(deployOptions).send(sendOptions).on('receipt', resolve);
    -				}),
    -			).resolves.toBeDefined();
    +			const handler = jest.fn();
    +
    +			const promiEvent = contract.deploy(deployOptions).send(sendOptions);
    +
    +			promiEvent.on('receipt', handler);
    +			// Deploy the contract
    +			await promiEvent;
    +
    +			expect(handler).toHaveBeenCalled();
     		});
     
     		it('should fail with errors on "intrinsic gas too low" OOG', async () => {
    
  • packages/web3-eth-ens/src/ens.ts+47 4 modified
    @@ -35,8 +35,8 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     	public registryAddress: string;
     	private readonly _registry: Registry;
     	private readonly _resolver: Resolver;
    -	private _detectedAddress: string | null;
    -	private _lastSyncCheck: number | null;
    +	private _detectedAddress?: string;
    +	private _lastSyncCheck?: number;
     
     	public constructor(
     		registryAddr?: string,
    @@ -48,19 +48,23 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     		this.registryAddress = registryAddr ?? registryAddresses.main; // will default to main registry address
     		this._registry = new Registry(registryAddr);
     		this._resolver = new Resolver(this._registry);
    -		this._lastSyncCheck = null;
    -		this._detectedAddress = null;
     	}
     
     	/**
     	 * Returns the Resolver by the given address
    +	 *
    +	 * @param name
     	 */
     	public async getResolver(name: string): Promise<Contract<typeof RESOLVER>> {
     		return this._registry.getResolver(name);
     	}
     
     	/**
     	 * set the resolver of the given name
    +	 *
    +	 * @param name
    +	 * @param address
    +	 * @param txConfig
     	 */
     	public async setResolver(
     		name: string,
    @@ -72,6 +76,13 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Sets the owner, resolver and TTL for a subdomain, creating it if necessary.
    +	 *
    +	 * @param name
    +	 * @param label
    +	 * @param owner
    +	 * @param resolver
    +	 * @param ttl
    +	 * @param txConfig
     	 */
     	public async setSubnodeRecord(
     		name: string,
    @@ -86,6 +97,10 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Sets or clears an approval by the given operator.
    +	 *
    +	 * @param operator
    +	 * @param approved
    +	 * @param txConfig
     	 */
     	public async setApprovalForAll(
     		operator: Address,
    @@ -97,20 +112,30 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Returns true if the operator is approved
    +	 *
    +	 * @param owner
    +	 * @param operator
     	 */
     	public async isApprovedForAll(owner: Address, operator: Address): Promise<unknown> {
     		return this._registry.isApprovedForAll(owner, operator);
     	}
     
     	/**
     	 * Returns true if the record exists
    +	 *
    +	 * @param name
     	 */
     	public async recordExists(name: string): Promise<unknown> {
     		return this._registry.recordExists(name);
     	}
     
     	/**
     	 * Returns the address of the owner of an ENS name.
    +	 *
    +	 * @param name
    +	 * @param label
    +	 * @param address
    +	 * @param txConfig
     	 */
     	public async setSubnodeOwner(
     		name: string,
    @@ -123,13 +148,19 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Returns the address of the owner of an ENS name.
    +	 *
    +	 * @param name
     	 */
     	public async getTTL(name: string): Promise<unknown> {
     		return this._registry.getTTL(name);
     	}
     
     	/**
     	 * Returns the address of the owner of an ENS name.
    +	 *
    +	 * @param name
    +	 * @param ttl
    +	 * @param txConfig
     	 */
     	public async setTTL(
     		name: string,
    @@ -141,13 +172,19 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Returns the owner by the given name and current configured or detected Registry
    +	 *
    +	 * @param name
     	 */
     	public async getOwner(name: string): Promise<unknown> {
     		return this._registry.getOwner(name);
     	}
     
     	/**
     	 * Returns the address of the owner of an ENS name.
    +	 *
    +	 * @param name
    +	 * @param address
    +	 * @param txConfig
     	 */
     	public async setOwner(
     		name: string,
    @@ -159,6 +196,12 @@ export class ENS extends Web3Context<EthExecutionAPI & Web3NetAPI> {
     
     	/**
     	 * Returns the address of the owner of an ENS name.
    +	 *
    +	 * @param name
    +	 * @param owner
    +	 * @param resolver
    +	 * @param ttl
    +	 * @param txConfig
     	 */
     	public async setRecord(
     		name: string,
    
  • packages/web3-eth-ens/src/resolver.ts+2 2 modified
    @@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    -import { Address, sha3, isHexStrict } from 'web3-utils';
    +import { Address, sha3, isHexStrict, isNullish } from 'web3-utils';
     import { Contract, NonPayableCallOptions } from 'web3-eth-contract';
     import { inputAddressFormatter } from 'web3-common';
     import { ResolverMethodMissingError } from 'web3-errors';
    @@ -45,7 +45,7 @@ export class Resolver {
     		resolverContract: Contract<typeof RESOLVER>,
     		methodName: string,
     	) {
    -		if (interfaceIds[methodName] === undefined)
    +		if (isNullish(interfaceIds[methodName]))
     			throw new ResolverMethodMissingError(
     				resolverContract.options.address ?? '',
     				methodName,
    
  • packages/web3-eth-iban/src/index.ts+21 0 modified
    @@ -32,6 +32,8 @@ export class Iban {
     
     	/**
     	 * Construct a direct or indirect IBAN
    +	 *
    +	 * @param iban
     	 */
     	public constructor(iban: string) {
     		if (Iban.isIndirect(iban) || Iban.isDirect(iban)) {
    @@ -44,6 +46,8 @@ export class Iban {
     	/**
     	 * Prepare an IBAN for mod 97 computation by moving the first 4 chars to the end and transforming the letters to
     	 * numbers (A = 10, B = 11, ..., Z = 35), as specified in ISO13616.
    +	 *
    +	 * @param iban
     	 */
     	private static readonly _iso13616Prepare = (iban: string): string => {
     		const A = 'A'.charCodeAt(0);
    @@ -67,6 +71,9 @@ export class Iban {
     
     	/**
     	 * return the bigint of the given string with the specified base
    +	 *
    +	 * @param str
    +	 * @param base
     	 */
     	private static readonly _parseInt = (str: string, base: number): bigint =>
     		[...str].reduce(
    @@ -76,6 +83,8 @@ export class Iban {
     
     	/**
     	 * Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064.
    +	 *
    +	 * @param iban
     	 */
     	private static readonly _mod9710 = (iban: string): number => {
     		let remainder = iban;
    @@ -115,6 +124,8 @@ export class Iban {
     	};
     	/**
     	 * This method should be used to create an ethereum address from a direct iban address
    +	 *
    +	 * @param iban
     	 */
     	public static toAddress = (iban: string): HexString => {
     		const ibanObject = new Iban(iban);
    @@ -125,6 +136,8 @@ export class Iban {
     	 * Convert the passed BBAN to an IBAN for this country specification.
     	 * Please note that <i>"generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account"</i>.
     	 * This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits
    +	 *
    +	 * @param bban
     	 */
     	public static fromBban(bban: string): Iban {
     		const countryCode = 'XE';
    @@ -137,6 +150,8 @@ export class Iban {
     
     	/**
     	 * This method should be used to create iban object from an ethereum address
    +	 *
    +	 * @param address
     	 */
     	public static fromAddress(address: HexString): Iban {
     		if (!isAddress(address)) {
    @@ -151,13 +166,17 @@ export class Iban {
     
     	/**
     	 * This method should be used to create iban address from an ethereum address
    +	 *
    +	 * @param address
     	 */
     	public static toIban(address: HexString): string {
     		return Iban.fromAddress(address).toString();
     	}
     
     	/**
     	 * Should be used to create IBAN object for given institution and identifier
    +	 *
    +	 * @param options
     	 */
     	public static createIndirect(options: IbanOptions): Iban {
     		return Iban.fromBban(`ETH${options.institution}${options.identifier}`);
    @@ -193,6 +212,8 @@ export class Iban {
     
     	/**
     	 * This method should be used to check if given string is valid iban object
    +	 *
    +	 * @param iban
     	 */
     	public static isValid(iban: string) {
     		return Iban._isValid(iban);
    
  • packages/web3-eth/src/rpc_methods.ts+255 0 modified
    @@ -29,62 +29,100 @@ import {
     import { BlockNumberOrTag, validator } from 'web3-validator';
     import { Web3EthExecutionAPI } from './web3_eth_execution_api';
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getProtocolVersion(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_protocolVersion',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getSyncing(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_syncing',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getCoinbase(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_coinbase',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getMining(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_mining',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getHashRate(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_hashrate',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getGasPrice(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_gasPrice',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getAccounts(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_accounts',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getBlockNumber(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_blockNumber',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param blockNumber
    + */
     export async function getBalance(
     	requestManager: Web3RequestManager,
     	address: Address,
    @@ -98,6 +136,13 @@ export async function getBalance(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param storageSlot
    + * @param blockNumber
    + */
     export async function getStorageAt(
     	requestManager: Web3RequestManager,
     	address: Address,
    @@ -112,6 +157,12 @@ export async function getStorageAt(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param blockNumber
    + */
     export async function getTransactionCount(
     	requestManager: Web3RequestManager,
     	address: Address,
    @@ -125,6 +176,11 @@ export async function getTransactionCount(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockHash
    + */
     export async function getBlockTransactionCountByHash(
     	requestManager: Web3RequestManager,
     	blockHash: HexString32Bytes,
    @@ -137,6 +193,11 @@ export async function getBlockTransactionCountByHash(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockNumber
    + */
     export async function getBlockTransactionCountByNumber(
     	requestManager: Web3RequestManager,
     	blockNumber: BlockNumberOrTag,
    @@ -149,6 +210,11 @@ export async function getBlockTransactionCountByNumber(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockHash
    + */
     export async function getUncleCountByBlockHash(
     	requestManager: Web3RequestManager,
     	blockHash: HexString32Bytes,
    @@ -161,6 +227,11 @@ export async function getUncleCountByBlockHash(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockNumber
    + */
     export async function getUncleCountByBlockNumber(
     	requestManager: Web3RequestManager,
     	blockNumber: BlockNumberOrTag,
    @@ -173,6 +244,12 @@ export async function getUncleCountByBlockNumber(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param blockNumber
    + */
     export async function getCode(
     	requestManager: Web3RequestManager,
     	address: Address,
    @@ -186,6 +263,12 @@ export async function getCode(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param message
    + */
     export async function sign(
     	requestManager: Web3RequestManager,
     	address: Address,
    @@ -203,6 +286,11 @@ export async function sign(
     // isTransactionWithSender(transaction)
     // ? validateTransactionWithSender(transaction)
     // : validateTransactionWithSender(transaction, true) with true being a isPartial flag
    +/**
    + *
    + * @param requestManager
    + * @param transaction
    + */
     export async function signTransaction(
     	requestManager: Web3RequestManager,
     	transaction: TransactionWithSender | Partial<TransactionWithSender>,
    @@ -217,6 +305,11 @@ export async function signTransaction(
     // isTransactionWithSender(transaction)
     // ? validateTransactionWithSender(transaction)
     // : validateTransactionWithSender(transaction, true) with true being a isPartial flag
    +/**
    + *
    + * @param requestManager
    + * @param transaction
    + */
     export async function sendTransaction(
     	requestManager: Web3RequestManager,
     	transaction: TransactionWithSender | Partial<TransactionWithSender>,
    @@ -227,6 +320,11 @@ export async function sendTransaction(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param transaction
    + */
     export async function sendRawTransaction(
     	requestManager: Web3RequestManager,
     	transaction: HexStringBytes,
    @@ -240,6 +338,12 @@ export async function sendRawTransaction(
     }
     
     // TODO - validate transaction
    +/**
    + *
    + * @param requestManager
    + * @param transaction
    + * @param blockNumber
    + */
     export async function call(
     	requestManager: Web3RequestManager,
     	transaction: TransactionCall,
    @@ -255,6 +359,12 @@ export async function call(
     }
     
     // TODO Not sure how to best validate Partial<TransactionWithSender>
    +/**
    + *
    + * @param requestManager
    + * @param transaction
    + * @param blockNumber
    + */
     export async function estimateGas(
     	requestManager: Web3RequestManager,
     	transaction: Partial<TransactionWithSender>,
    @@ -268,6 +378,12 @@ export async function estimateGas(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockHash
    + * @param hydrated
    + */
     export async function getBlockByHash(
     	requestManager: Web3RequestManager,
     	blockHash: HexString32Bytes,
    @@ -281,6 +397,12 @@ export async function getBlockByHash(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockNumber
    + * @param hydrated
    + */
     export async function getBlockByNumber(
     	requestManager: Web3RequestManager,
     	blockNumber: BlockNumberOrTag,
    @@ -294,6 +416,11 @@ export async function getBlockByNumber(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param transactionHash
    + */
     export async function getTransactionByHash(
     	requestManager: Web3RequestManager,
     	transactionHash: HexString32Bytes,
    @@ -306,6 +433,12 @@ export async function getTransactionByHash(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockHash
    + * @param transactionIndex
    + */
     export async function getTransactionByBlockHashAndIndex(
     	requestManager: Web3RequestManager,
     	blockHash: HexString32Bytes,
    @@ -319,6 +452,12 @@ export async function getTransactionByBlockHashAndIndex(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockNumber
    + * @param transactionIndex
    + */
     export async function getTransactionByBlockNumberAndIndex(
     	requestManager: Web3RequestManager,
     	blockNumber: BlockNumberOrTag,
    @@ -332,6 +471,11 @@ export async function getTransactionByBlockNumberAndIndex(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param transactionHash
    + */
     export async function getTransactionReceipt(
     	requestManager: Web3RequestManager,
     	transactionHash: HexString32Bytes,
    @@ -344,6 +488,12 @@ export async function getTransactionReceipt(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockHash
    + * @param uncleIndex
    + */
     export async function getUncleByBlockHashAndIndex(
     	requestManager: Web3RequestManager,
     	blockHash: HexString32Bytes,
    @@ -357,6 +507,12 @@ export async function getUncleByBlockHashAndIndex(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockNumber
    + * @param uncleIndex
    + */
     export async function getUncleByBlockNumberAndIndex(
     	requestManager: Web3RequestManager,
     	blockNumber: BlockNumberOrTag,
    @@ -370,13 +526,22 @@ export async function getUncleByBlockNumberAndIndex(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getCompilers(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_getCompilers',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param code
    + */
     export async function compileSolidity(requestManager: Web3RequestManager, code: string) {
     	validator.validate(['string'], [code]);
     
    @@ -386,6 +551,11 @@ export async function compileSolidity(requestManager: Web3RequestManager, code:
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param code
    + */
     export async function compileLLL(requestManager: Web3RequestManager, code: string) {
     	validator.validate(['string'], [code]);
     
    @@ -395,6 +565,11 @@ export async function compileLLL(requestManager: Web3RequestManager, code: strin
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param code
    + */
     export async function compileSerpent(requestManager: Web3RequestManager, code: string) {
     	validator.validate(['string'], [code]);
     
    @@ -404,6 +579,11 @@ export async function compileSerpent(requestManager: Web3RequestManager, code: s
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param filter
    + */
     export async function newFilter(requestManager: Web3RequestManager, filter: Filter) {
     	validator.validate(['filter'], [filter]);
     
    @@ -413,20 +593,33 @@ export async function newFilter(requestManager: Web3RequestManager, filter: Filt
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function newBlockFilter(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_newBlockFilter',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function newPendingTransactionFilter(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_newPendingTransactionFilter',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param filterIdentifier
    + */
     export async function uninstallFilter(requestManager: Web3RequestManager, filterIdentifier: Uint) {
     	validator.validate(['hex'], [filterIdentifier]);
     
    @@ -436,6 +629,11 @@ export async function uninstallFilter(requestManager: Web3RequestManager, filter
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param filterIdentifier
    + */
     export async function getFilterChanges(requestManager: Web3RequestManager, filterIdentifier: Uint) {
     	validator.validate(['hex'], [filterIdentifier]);
     
    @@ -445,6 +643,11 @@ export async function getFilterChanges(requestManager: Web3RequestManager, filte
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param filterIdentifier
    + */
     export async function getFilterLogs(requestManager: Web3RequestManager, filterIdentifier: Uint) {
     	validator.validate(['hex'], [filterIdentifier]);
     
    @@ -454,6 +657,11 @@ export async function getFilterLogs(requestManager: Web3RequestManager, filterId
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param filter
    + */
     export async function getLogs(requestManager: Web3RequestManager, filter: Filter) {
     	validator.validate(['filter'], [filter]);
     
    @@ -463,13 +671,24 @@ export async function getLogs(requestManager: Web3RequestManager, filter: Filter
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getWork(requestManager: Web3RequestManager) {
     	return requestManager.send({
     		method: 'eth_getWork',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param nonce
    + * @param hash
    + * @param digest
    + */
     export async function submitWork(
     	requestManager: Web3RequestManager,
     	nonce: HexString8Bytes,
    @@ -484,6 +703,12 @@ export async function submitWork(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param hashRate
    + * @param id
    + */
     export async function submitHashrate(
     	requestManager: Web3RequestManager,
     	hashRate: HexString32Bytes,
    @@ -497,6 +722,13 @@ export async function submitHashrate(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param blockCount
    + * @param newestBlock
    + * @param rewardPercentiles
    + */
     export async function getFeeHistory(
     	requestManager: Web3RequestManager,
     	blockCount: Uint,
    @@ -515,6 +747,10 @@ export async function getFeeHistory(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getPendingTransactions(
     	requestManager: Web3RequestManager<Web3EthExecutionAPI>,
     ) {
    @@ -524,20 +760,35 @@ export async function getPendingTransactions(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function requestAccounts(requestManager: Web3RequestManager<Web3EthExecutionAPI>) {
     	return requestManager.send({
     		method: 'eth_requestAccounts',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getChainId(requestManager: Web3RequestManager<Web3EthExecutionAPI>) {
     	return requestManager.send({
     		method: 'eth_chainId',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + * @param address
    + * @param storageKeys
    + * @param blockNumber
    + */
     export async function getProof(
     	requestManager: Web3RequestManager<Web3EthExecutionAPI>,
     	address: Address,
    @@ -555,6 +806,10 @@ export async function getProof(
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getNodeInfo(requestManager: Web3RequestManager<Web3EthExecutionAPI>) {
     	return requestManager.send({
     		method: 'web3_clientVersion',
    
  • packages/web3-eth/src/rpc_method_wrappers.ts+170 9 modified
    @@ -31,7 +31,7 @@ import {
     } from 'web3-common';
     import { Web3Context } from 'web3-core';
     import { Address, BlockTag, BlockNumberOrTag, Bytes, Filter, HexString, Numbers } from 'web3-utils';
    -import { isBlockTag, isBytes } from 'web3-validator';
    +import { isBlockTag, isBytes, isNullish } from 'web3-validator';
     import { SignatureError } from './errors';
     import * as rpcMethods from './rpc_methods';
     import {
    @@ -76,6 +76,11 @@ export const getCoinbase = async (web3Context: Web3Context<EthExecutionAPI>) =>
     export const isMining = async (web3Context: Web3Context<EthExecutionAPI>) =>
     	rpcMethods.getMining(web3Context.requestManager);
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getHashRate<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
    @@ -85,6 +90,11 @@ export async function getHashRate<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getGasPrice<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
    @@ -94,6 +104,11 @@ export async function getGasPrice<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getBlockNumber<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
    @@ -103,6 +118,13 @@ export async function getBlockNumber<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param address
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function getBalance<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	address: Address,
    @@ -120,6 +142,14 @@ export async function getBalance<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param address
    + * @param storageSlot
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function getStorageAt<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	address: Address,
    @@ -140,6 +170,13 @@ export async function getStorageAt<ReturnFormat extends DataFormat>(
     	return format({ eth: 'bytes' }, response, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param address
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function getCode<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	address: Address,
    @@ -157,6 +194,13 @@ export async function getCode<ReturnFormat extends DataFormat>(
     	return format({ eth: 'bytes' }, response, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param block
    + * @param hydrated
    + * @param returnFormat
    + */
     export async function getBlock<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	block: Bytes | BlockNumberOrTag = web3Context.defaultBlock,
    @@ -185,6 +229,12 @@ export async function getBlock<ReturnFormat extends DataFormat>(
     	return format(blockSchema, response as unknown as Block, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param block
    + * @param returnFormat
    + */
     export async function getBlockTransactionCount<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	block: Bytes | BlockNumberOrTag = web3Context.defaultBlock,
    @@ -210,6 +260,12 @@ export async function getBlockTransactionCount<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param block
    + * @param returnFormat
    + */
     export async function getBlockUncleCount<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	block: Bytes | BlockNumberOrTag = web3Context.defaultBlock,
    @@ -235,6 +291,13 @@ export async function getBlockUncleCount<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param block
    + * @param uncleIndex
    + * @param returnFormat
    + */
     export async function getUncle<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	block: Bytes | BlockNumberOrTag = web3Context.defaultBlock,
    @@ -265,6 +328,12 @@ export async function getUncle<ReturnFormat extends DataFormat>(
     	return format(blockSchema, response as unknown as Block, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param transactionHash
    + * @param returnFormat
    + */
     export async function getTransaction<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transactionHash: Bytes,
    @@ -280,11 +349,16 @@ export async function getTransaction<ReturnFormat extends DataFormat>(
     		transactionHashFormatted,
     	);
     
    -	return response === null
    +	return isNullish(response)
     		? response
     		: format(transactionInfoSchema, response as unknown as TransactionInfo, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getPendingTransactions<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
    @@ -296,6 +370,13 @@ export async function getPendingTransactions<ReturnFormat extends DataFormat>(
     	);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param block
    + * @param transactionIndex
    + * @param returnFormat
    + */
     export async function getTransactionFromBlock<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	block: Bytes | BlockNumberOrTag = web3Context.defaultBlock,
    @@ -327,11 +408,17 @@ export async function getTransactionFromBlock<ReturnFormat extends DataFormat>(
     		);
     	}
     
    -	return response === null
    +	return isNullish(response)
     		? response
     		: format(transactionInfoSchema, response as unknown as TransactionInfo, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param transactionHash
    + * @param returnFormat
    + */
     export async function getTransactionReceipt<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transactionHash: Bytes,
    @@ -347,7 +434,7 @@ export async function getTransactionReceipt<ReturnFormat extends DataFormat>(
     		transactionHashFormatted,
     	);
     
    -	return response === null
    +	return isNullish(response)
     		? response
     		: (format(
     				receiptInfoSchema,
    @@ -356,6 +443,13 @@ export async function getTransactionReceipt<ReturnFormat extends DataFormat>(
     		  ) as ReceiptInfo);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param address
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function getTransactionCount<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	address: Address,
    @@ -374,6 +468,13 @@ export async function getTransactionCount<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as Numbers, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param transaction
    + * @param returnFormat
    + * @param options
    + */
     export function sendTransaction<
     	ReturnFormat extends DataFormat,
     	ResolveType = FormatType<ReceiptInfo, ReturnFormat>,
    @@ -396,9 +497,9 @@ export function sendTransaction<
     				try {
     					if (
     						!options?.ignoreGasPricing &&
    -						transaction.gasPrice === undefined &&
    -						(transaction.maxPriorityFeePerGas === undefined ||
    -							transaction.maxFeePerGas === undefined)
    +						isNullish(transactionFormatted.gasPrice) &&
    +						(isNullish(transaction.maxPriorityFeePerGas) ||
    +							isNullish(transaction.maxFeePerGas))
     					) {
     						transactionFormatted = {
     							...transactionFormatted,
    @@ -461,7 +562,7 @@ export function sendTransaction<
     					);
     
     					// Transaction hasn't been included in a block yet
    -					if (transactionReceipt === null)
    +					if (isNullish(transactionReceipt))
     						transactionReceipt = await waitForTransactionReceipt(
     							web3Context,
     							transactionHash,
    @@ -513,6 +614,12 @@ export function sendTransaction<
     	return promiEvent;
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param signedTransaction
    + * @param returnFormat
    + */
     export function sendSignedTransaction<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	signedTransaction: Bytes,
    @@ -563,7 +670,7 @@ export function sendSignedTransaction<ReturnFormat extends DataFormat>(
     				);
     
     				// Transaction hasn't been included in a block yet
    -				if (transactionReceipt === null)
    +				if (isNullish(transactionReceipt))
     					transactionReceipt = await waitForTransactionReceipt(
     						web3Context,
     						transactionHash,
    @@ -596,6 +703,13 @@ export function sendSignedTransaction<ReturnFormat extends DataFormat>(
     	return promiEvent;
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param message
    + * @param addressOrIndex
    + * @param returnFormat
    + */
     export async function sign<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	message: Bytes,
    @@ -625,6 +739,12 @@ export async function sign<ReturnFormat extends DataFormat>(
     	return format({ eth: 'bytes' }, response, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param transaction
    + * @param returnFormat
    + */
     export async function signTransaction<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transaction: Transaction,
    @@ -642,6 +762,13 @@ export async function signTransaction<ReturnFormat extends DataFormat>(
     
     // TODO Decide what to do with transaction.to
     // https://github.com/ChainSafe/web3.js/pull/4525#issuecomment-982330076
    +/**
    + *
    + * @param web3Context
    + * @param transaction
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function call<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transaction: TransactionCall,
    @@ -660,6 +787,13 @@ export async function call<ReturnFormat extends DataFormat>(
     }
     
     // TODO - Investigate whether response is padded as 1.x docs suggest
    +/**
    + *
    + * @param web3Context
    + * @param transaction
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function estimateGas<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transaction: Transaction,
    @@ -680,6 +814,12 @@ export async function estimateGas<ReturnFormat extends DataFormat>(
     }
     
     // TODO - Add input formatting to filter
    +/**
    + *
    + * @param web3Context
    + * @param filter
    + * @param returnFormat
    + */
     export async function getLogs<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<Web3EthExecutionAPI>,
     	filter: Filter,
    @@ -698,6 +838,11 @@ export async function getLogs<ReturnFormat extends DataFormat>(
     	return result;
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getChainId<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
    @@ -712,6 +857,14 @@ export async function getChainId<ReturnFormat extends DataFormat>(
     	);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param address
    + * @param storageKeys
    + * @param blockNumber
    + * @param returnFormat
    + */
     export async function getProof<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<Web3EthExecutionAPI>,
     	address: Address,
    @@ -736,6 +889,14 @@ export async function getProof<ReturnFormat extends DataFormat>(
     	return format(accountSchema, response as unknown as AccountObject, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param blockCount
    + * @param newestBlock
    + * @param rewardPercentiles
    + * @param returnFormat
    + */
     export async function getFeeHistory<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	blockCount: Numbers,
    
  • packages/web3-eth/src/types.ts+9 9 modified
    @@ -47,8 +47,8 @@ export interface Log {
     	readonly removed?: boolean;
     	readonly logIndex?: Numbers;
     	readonly transactionIndex?: Numbers;
    -	readonly transactionHash?: Bytes | null;
    -	readonly blockHash?: Bytes | null;
    +	readonly transactionHash?: Bytes;
    +	readonly blockHash?: Bytes;
     	readonly blockNumber?: Numbers;
     	readonly address?: Address;
     	readonly data?: Bytes;
    @@ -65,7 +65,7 @@ export interface ReceiptInfo {
     	readonly cumulativeGasUsed: Numbers;
     	readonly gasUsed: Numbers;
     	readonly effectiveGasPrice?: Numbers;
    -	readonly contractAddress: Address | null;
    +	readonly contractAddress?: Address;
     	readonly logs: Log[];
     	readonly logsBloom: Bytes;
     	readonly root: Bytes;
    @@ -89,7 +89,7 @@ export interface Transaction {
     	accessList?: AccessList;
     	common?: Common;
     	from?: Address;
    -	to?: Address | null;
    +	to?: Address;
     	gas?: Numbers;
     	gasPrice?: Numbers;
     	type?: Numbers;
    @@ -109,11 +109,11 @@ export interface Transaction {
     }
     
     export interface TransactionInfo extends Transaction {
    -	readonly blockHash: Bytes | null;
    -	readonly blockNumber: Numbers | null;
    +	readonly blockHash?: Bytes;
    +	readonly blockNumber?: Numbers;
     	readonly from: Address;
     	readonly hash: Bytes;
    -	readonly transactionIndex: Numbers | null;
    +	readonly transactionIndex?: Numbers;
     }
     
     export type InternalTransaction = FormatType<
    @@ -163,7 +163,7 @@ export interface Block {
     	readonly stateRoot: Bytes;
     	readonly transactionsRoot: Bytes;
     	readonly receiptsRoot: Bytes;
    -	readonly logsBloom: Bytes | null;
    +	readonly logsBloom?: Bytes;
     	readonly difficulty?: Numbers;
     	readonly number: Numbers;
     	readonly gasLimit: Numbers;
    @@ -177,7 +177,7 @@ export interface Block {
     	readonly size: Numbers;
     	readonly transactions: TransactionHash[] | TransactionInfo[];
     	readonly uncles: Uncles;
    -	readonly hash: Bytes | null;
    +	readonly hash?: Bytes;
     }
     
     export type SendTransactionEvents = {
    
  • packages/web3-eth/src/utils/detect_transaction_type.ts+5 4 modified
    @@ -17,22 +17,23 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     
     import { EthExecutionAPI, DEFAULT_RETURN_FORMAT, format } from 'web3-common';
     import { TransactionTypeParser, Web3Context } from 'web3-core';
    +import { isNullish } from 'web3-validator';
     import { InternalTransaction, Transaction } from '../types';
     
     export const defaultTransactionTypeParser: TransactionTypeParser = transaction => {
     	const tx = transaction as unknown as Transaction;
     
    -	if (tx.type !== undefined) return format({ eth: 'uint' }, tx.type, DEFAULT_RETURN_FORMAT);
    +	if (!isNullish(tx.type)) return format({ eth: 'uint' }, tx.type, DEFAULT_RETURN_FORMAT);
     
     	if (
    -		tx.maxFeePerGas !== undefined ||
    -		tx.maxPriorityFeePerGas !== undefined ||
    +		!isNullish(tx.maxFeePerGas) ||
    +		!isNullish(tx.maxPriorityFeePerGas) ||
     		tx.hardfork === 'london' ||
     		tx.common?.hardfork === 'london'
     	)
     		return '0x2';
     
    -	if (tx.accessList !== undefined || tx.hardfork === 'berlin' || tx.common?.hardfork === 'berlin')
    +	if (!isNullish(tx.accessList) || tx.hardfork === 'berlin' || tx.common?.hardfork === 'berlin')
     		return '0x1';
     
     	return undefined;
    
  • packages/web3-eth/src/utils/format_transaction.ts+10 4 modified
    @@ -17,10 +17,16 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     
     import { DataFormat, DEFAULT_RETURN_FORMAT, format, FormatType } from 'web3-common';
     import { bytesToBuffer, mergeDeep } from 'web3-utils';
    +import { isNullish } from 'web3-validator';
     import { TransactionDataAndInputError } from '../errors';
     import { transactionSchema } from '../schemas';
     import { Transaction } from '../types';
     
    +/**
    + *
    + * @param transaction
    + * @param returnFormat
    + */
     export function formatTransaction<
     	ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT,
     	TransactionType extends Transaction = Transaction,
    @@ -29,20 +35,20 @@ export function formatTransaction<
     	returnFormat: ReturnFormat = DEFAULT_RETURN_FORMAT as ReturnFormat,
     ): FormatType<TransactionType, ReturnFormat> {
     	let formattedTransaction = mergeDeep({}, transaction as Record<string, unknown>) as Transaction;
    -	if (transaction?.common !== undefined) {
    +	if (!isNullish(transaction?.common)) {
     		formattedTransaction.common = { ...transaction.common };
    -		if (transaction.common?.customChain !== undefined)
    +		if (!isNullish(transaction.common?.customChain))
     			formattedTransaction.common.customChain = { ...transaction.common.customChain };
     	}
     
     	formattedTransaction = format(transactionSchema, formattedTransaction, returnFormat);
     
    -	if (formattedTransaction.data !== undefined && formattedTransaction.input !== undefined)
    +	if (!isNullish(formattedTransaction.data) && !isNullish(formattedTransaction.input))
     		throw new TransactionDataAndInputError({
     			data: bytesToBuffer(formattedTransaction.data).toString('hex'),
     			input: bytesToBuffer(formattedTransaction.input).toString('hex'),
     		});
    -	else if (formattedTransaction.input !== undefined) {
    +	else if (!isNullish(formattedTransaction.input)) {
     		formattedTransaction.data = formattedTransaction.input;
     		delete formattedTransaction.input;
     	}
    
  • packages/web3-eth/src/utils/get_transaction_gas_pricing.ts+17 4 modified
    @@ -24,23 +24,30 @@ import {
     } from 'web3-common';
     import { Web3Context } from 'web3-core';
     import { Numbers } from 'web3-utils';
    +import { isNullish } from 'web3-validator';
     import { Eip1559NotSupportedError, UnsupportedTransactionTypeError } from '../errors';
     // eslint-disable-next-line import/no-cycle
     import { getBlock, getGasPrice } from '../rpc_method_wrappers';
     import { InternalTransaction, Transaction } from '../types';
     // eslint-disable-next-line import/no-cycle
     import { getTransactionType } from './transaction_builder';
     
    +/**
    + *
    + * @param transaction
    + * @param web3Context
    + * @param returnFormat
    + */
     async function getEip1559GasPricing<ReturnFormat extends DataFormat>(
     	transaction: FormatType<Transaction, typeof DEFAULT_RETURN_FORMAT>,
     	web3Context: Web3Context<EthExecutionAPI>,
     	returnFormat: ReturnFormat,
     ): Promise<FormatType<{ maxPriorityFeePerGas?: Numbers; maxFeePerGas?: Numbers }, ReturnFormat>> {
     	const block = await getBlock(web3Context, web3Context.defaultBlock, false, returnFormat);
     
    -	if (block.baseFeePerGas === undefined) throw new Eip1559NotSupportedError();
    +	if (isNullish(block.baseFeePerGas)) throw new Eip1559NotSupportedError();
     
    -	if (transaction.gasPrice !== undefined) {
    +	if (!isNullish(transaction.gasPrice)) {
     		const convertedTransactionGasPrice = format(
     			{ eth: 'uint' },
     			transaction.gasPrice as Numbers,
    @@ -70,6 +77,12 @@ async function getEip1559GasPricing<ReturnFormat extends DataFormat>(
     	};
     }
     
    +/**
    + *
    + * @param transaction
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getTransactionGasPricing<ReturnFormat extends DataFormat>(
     	transaction: InternalTransaction,
     	web3Context: Web3Context<EthExecutionAPI>,
    @@ -82,7 +95,7 @@ export async function getTransactionGasPricing<ReturnFormat extends DataFormat>(
     	| undefined
     > {
     	const transactionType = getTransactionType(transaction, web3Context);
    -	if (transactionType !== undefined) {
    +	if (!isNullish(transactionType)) {
     		if (transactionType.startsWith('-'))
     			throw new UnsupportedTransactionTypeError(transactionType);
     
    @@ -91,7 +104,7 @@ export async function getTransactionGasPricing<ReturnFormat extends DataFormat>(
     			throw new UnsupportedTransactionTypeError(transactionType);
     
     		if (
    -			transaction.gasPrice === undefined &&
    +			isNullish(transaction.gasPrice) &&
     			(transactionType === '0x0' || transactionType === '0x1')
     		)
     			return {
    
  • packages/web3-eth/src/utils/prepare_transaction_for_signing.ts+6 6 modified
    @@ -20,6 +20,7 @@ import { TransactionFactory, TxOptions } from '@ethereumjs/tx';
     import { EthExecutionAPI, FMT_BYTES, FMT_NUMBER, FormatType } from 'web3-common';
     import { Web3Context } from 'web3-core';
     import { HexString, toNumber } from 'web3-utils';
    +import { isNullish } from 'web3-validator';
     import {
     	PopulatedUnsignedEip1559Transaction,
     	PopulatedUnsignedEip2930Transaction,
    @@ -72,19 +73,18 @@ const getEthereumjsTransactionOptions = (
     	web3Context: Web3Context<EthExecutionAPI>,
     ) => {
     	const hasTransactionSigningOptions =
    -		(transaction.chain !== undefined && transaction.hardfork !== undefined) ||
    -		transaction.common !== undefined;
    +		(!isNullish(transaction.chain) && !isNullish(transaction.hardfork)) ||
    +		!isNullish(transaction.common);
     
     	let common;
     	if (!hasTransactionSigningOptions) {
     		common = Common.custom(
     			{
     				name: 'custom-network',
     				chainId: toNumber(transaction.chainId) as number,
    -				networkId:
    -					transaction.networkId !== undefined
    -						? (toNumber(transaction.networkId) as number)
    -						: undefined,
    +				networkId: !isNullish(transaction.networkId)
    +					? (toNumber(transaction.networkId) as number)
    +					: undefined,
     				defaultHardfork: transaction.hardfork ?? web3Context.defaultHardfork,
     			},
     			{
    
  • packages/web3-eth/src/utils/transaction_builder.ts+27 26 modified
    @@ -20,6 +20,7 @@ import { Web3Context } from 'web3-core';
     import { privateKeyToAddress } from 'web3-eth-accounts';
     import { getId, Web3NetAPI } from 'web3-net';
     import { Address, HexString } from 'web3-utils';
    +import { isNullish } from 'web3-validator';
     import { TransactionDataAndInputError, UnableToPopulateNonceError } from '../errors';
     // eslint-disable-next-line import/no-cycle
     import { getChainId, getTransactionCount } from '../rpc_method_wrappers';
    @@ -32,8 +33,8 @@ export const getTransactionFromAttr = (
     	web3Context: Web3Context<EthExecutionAPI>,
     	privateKey?: HexString | Buffer,
     ) => {
    -	if (privateKey !== undefined) return privateKeyToAddress(privateKey);
    -	if (web3Context.defaultAccount !== null) return web3Context.defaultAccount;
    +	if (!isNullish(privateKey)) return privateKeyToAddress(privateKey);
    +	if (!isNullish(web3Context.defaultAccount)) return web3Context.defaultAccount;
     	// TODO if (web3.eth.accounts.wallet) Try to fill using local wallet
     
     	return undefined;
    @@ -43,7 +44,7 @@ export const getTransactionNonce = async (
     	web3Context: Web3Context<EthExecutionAPI>,
     	address?: Address,
     ) => {
    -	if (address === undefined) {
    +	if (isNullish(address)) {
     		// TODO if (web3.eth.accounts.wallet) use address from local wallet
     		throw new UnableToPopulateNonceError();
     	}
    @@ -62,91 +63,91 @@ export const getTransactionType = (
     ) => {
     	const inferredType = detectTransactionType(transaction, web3Context);
     
    -	if (inferredType !== undefined) return inferredType;
    -	if (
    -		web3Context.defaultTransactionType !== null ||
    -		web3Context.defaultTransactionType !== undefined
    -	)
    +	if (!isNullish(inferredType)) return inferredType;
    +	if (!isNullish(web3Context.defaultTransactionType))
     		return format({ eth: 'uint' }, web3Context.defaultTransactionType, DEFAULT_RETURN_FORMAT);
     
     	return undefined;
     };
     
     // Keep in mind that the order the properties of populateTransaction get populated matters
     // as some of the properties are dependent on others
    +/**
    + *
    + * @param options
    + * @param options.transaction
    + * @param options.web3Context
    + * @param options.privateKey
    + */
     export async function defaultTransactionBuilder<ReturnType = Record<string, unknown>>(options: {
     	transaction: Record<string, unknown>;
     	web3Context: Web3Context<EthExecutionAPI & Web3NetAPI>;
     	privateKey?: HexString | Buffer;
     }): Promise<ReturnType> {
     	let populatedTransaction = { ...options.transaction } as unknown as InternalTransaction;
     
    -	if (populatedTransaction.from === undefined) {
    +	if (isNullish(populatedTransaction.from)) {
     		populatedTransaction.from = getTransactionFromAttr(options.web3Context, options.privateKey);
     	}
     
     	// TODO: Debug why need to typecase getTransactionNonce
    -	if (populatedTransaction.nonce === undefined) {
    +	if (isNullish(populatedTransaction.nonce)) {
     		populatedTransaction.nonce = (await getTransactionNonce(
     			options.web3Context,
     			populatedTransaction.from,
     		)) as unknown as string;
     	}
     
    -	if (populatedTransaction.value === undefined) {
    +	if (isNullish(populatedTransaction.value)) {
     		populatedTransaction.value = '0x';
     	}
     
    -	if (populatedTransaction.data !== undefined && populatedTransaction.input !== undefined) {
    +	if (!isNullish(populatedTransaction.data) && !isNullish(populatedTransaction.input)) {
     		throw new TransactionDataAndInputError({
     			data: populatedTransaction.data,
     			input: populatedTransaction.input,
     		});
    -	} else if (populatedTransaction.input !== undefined) {
    +	} else if (!isNullish(populatedTransaction.input)) {
     		populatedTransaction.data = populatedTransaction.input;
     		delete populatedTransaction.input;
     	}
     
    -	if (
    -		populatedTransaction.data === undefined ||
    -		populatedTransaction.data === null ||
    -		populatedTransaction.data === ''
    -	) {
    +	if (isNullish(populatedTransaction.data) || populatedTransaction.data === '') {
     		populatedTransaction.data = '0x';
     	} else if (!populatedTransaction.data.startsWith('0x')) {
     		populatedTransaction.data = `0x${populatedTransaction.data}`;
     	}
     
    -	if (populatedTransaction.common === undefined) {
    -		if (populatedTransaction.chain === undefined) {
    +	if (isNullish(populatedTransaction.common)) {
    +		if (isNullish(populatedTransaction.chain)) {
     			populatedTransaction.chain = options.web3Context.defaultChain as ValidChains;
     		}
    -		if (populatedTransaction.hardfork === undefined) {
    +		if (isNullish(populatedTransaction.hardfork)) {
     			populatedTransaction.hardfork = options.web3Context.defaultHardfork as Hardfork;
     		}
     	}
     
     	if (
    -		populatedTransaction.chainId === undefined &&
    -		populatedTransaction.common?.customChain.chainId === undefined
    +		isNullish(populatedTransaction.chainId) &&
    +		isNullish(populatedTransaction.common?.customChain.chainId)
     	) {
     		populatedTransaction.chainId = await getChainId(options.web3Context, DEFAULT_RETURN_FORMAT);
     	}
     
    -	if (populatedTransaction.networkId === undefined) {
    +	if (isNullish(populatedTransaction.networkId)) {
     		populatedTransaction.networkId =
     			(options.web3Context.defaultNetworkId as string) ??
     			(await getId(options.web3Context, DEFAULT_RETURN_FORMAT));
     	}
     
    -	if (populatedTransaction.gasLimit === undefined && populatedTransaction.gas !== undefined) {
    +	if (isNullish(populatedTransaction.gasLimit) && !isNullish(populatedTransaction.gas)) {
     		populatedTransaction.gasLimit = populatedTransaction.gas;
     	}
     
     	populatedTransaction.type = getTransactionType(populatedTransaction, options.web3Context);
     
     	if (
    -		populatedTransaction.accessList === undefined &&
    +		isNullish(populatedTransaction.accessList) &&
     		(populatedTransaction.type === '0x1' || populatedTransaction.type === '0x2')
     	) {
     		populatedTransaction.accessList = [];
    
  • packages/web3-eth/src/utils/wait_for_transaction_receipt.ts+8 2 modified
    @@ -16,13 +16,19 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { DataFormat, EthExecutionAPI } from 'web3-common';
     import { Web3Context } from 'web3-core';
    -import { Bytes } from 'web3-utils';
    +import { Bytes, isNullish } from 'web3-utils';
     
     import { ReceiptInfo } from '../types';
     // eslint-disable-next-line import/no-cycle
     import { getTransactionReceipt } from '../rpc_method_wrappers';
     import { TransactionPollingTimeoutError } from '../errors';
     
    +/**
    + *
    + * @param web3Context
    + * @param transactionHash
    + * @param returnFormat
    + */
     export async function waitForTransactionReceipt<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<EthExecutionAPI>,
     	transactionHash: Bytes,
    @@ -50,7 +56,7 @@ export async function waitForTransactionReceipt<ReturnFormat extends DataFormat>
     					returnFormat,
     				);
     
    -				if (response !== null) {
    +				if (!isNullish(response)) {
     					clearInterval(intervalId);
     					resolve(response);
     				}
    
  • packages/web3-eth/src/utils/watch_transaction_for_confirmations.ts+10 6 modified
    @@ -25,6 +25,7 @@ import {
     import { SubscriptionError } from 'web3-errors';
     import { Web3Context } from 'web3-core';
     import { Bytes, HexString32Bytes, numberToHex } from 'web3-utils';
    +import { isNullish } from 'web3-validator';
     
     import {
     	TransactionMissingReceiptOrBlockHashError,
    @@ -128,6 +129,14 @@ const watchBySubscription = <ResolveType = ReceiptInfo>({
     	});
     };
     
    +/**
    + *
    + * @param web3Context
    + * @param transactionPromiEvent
    + * @param transactionReceipt
    + * @param transactionHash
    + * @param returnFormat
    + */
     export function watchTransactionForConfirmations<
     	PromiEventEventType extends PromiEventEventTypeBase,
     	ReturnFormat extends DataFormat,
    @@ -139,12 +148,7 @@ export function watchTransactionForConfirmations<
     	transactionHash: Bytes,
     	returnFormat: ReturnFormat,
     ) {
    -	if (
    -		transactionReceipt === undefined ||
    -		transactionReceipt === null ||
    -		transactionReceipt.blockHash === undefined ||
    -		transactionReceipt.blockHash === null
    -	)
    +	if (isNullish(transactionReceipt) || isNullish(transactionReceipt.blockHash))
     		throw new TransactionMissingReceiptOrBlockHashError({
     			receipt: transactionReceipt,
     			blockHash: format({ eth: 'bytes32' }, transactionReceipt.blockHash, returnFormat),
    
  • packages/web3-eth/src/validation.ts+77 36 modified
    @@ -27,7 +27,7 @@ import {
     	TransactionLegacyUnsigned,
     	TransactionWithSender,
     } from 'web3-common';
    -import { isAddress, isHexStrict, isHexString32Bytes, isUInt } from 'web3-validator';
    +import { isAddress, isHexStrict, isHexString32Bytes, isNullish, isUInt } from 'web3-validator';
     import {
     	ChainIdMismatchError,
     	CommonOrChainAndHardforkError,
    @@ -48,10 +48,13 @@ import {
     import { formatTransaction } from './utils/format_transaction';
     import { InternalTransaction, Transaction } from './types';
     
    +/**
    + *
    + * @param value
    + */
     export function isBaseTransaction(value: BaseTransaction): boolean {
    -	if (value.to !== undefined && value?.to !== null && !isAddress(value.to)) return false;
    -	if (!isHexStrict(value.type) && value.type !== undefined && value.type.length !== 2)
    -		return false;
    +	if (!isNullish(value.to) && !isAddress(value.to)) return false;
    +	if (!isHexStrict(value.type) && !isNullish(value.type) && value.type.length !== 2) return false;
     	if (!isHexStrict(value.nonce)) return false;
     	if (!isHexStrict(value.gas)) return false;
     	if (!isHexStrict(value.value)) return false;
    @@ -61,17 +64,25 @@ export function isBaseTransaction(value: BaseTransaction): boolean {
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isAccessListEntry(value: AccessListEntry): boolean {
    -	if (value.address !== undefined && !isAddress(value.address)) return false;
    +	if (!isNullish(value.address) && !isAddress(value.address)) return false;
     	if (
    -		value.storageKeys !== undefined &&
    +		!isNullish(value.storageKeys) &&
     		!value.storageKeys.every(storageKey => isHexString32Bytes(storageKey))
     	)
     		return false;
     
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isAccessList(value: AccessList): boolean {
     	if (
     		!Array.isArray(value) ||
    @@ -82,6 +93,10 @@ export function isAccessList(value: AccessList): boolean {
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isTransaction1559Unsigned(value: Transaction1559Unsigned): boolean {
     	if (!isBaseTransaction(value)) return false;
     	if (!isHexStrict(value.maxFeePerGas)) return false;
    @@ -91,6 +106,10 @@ export function isTransaction1559Unsigned(value: Transaction1559Unsigned): boole
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isTransaction2930Unsigned(value: Transaction2930Unsigned): boolean {
     	if (!isBaseTransaction(value)) return false;
     	if (!isHexStrict(value.gasPrice)) return false;
    @@ -99,13 +118,21 @@ export function isTransaction2930Unsigned(value: Transaction2930Unsigned): boole
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isTransactionLegacyUnsigned(value: TransactionLegacyUnsigned): boolean {
     	if (!isBaseTransaction(value)) return false;
     	if (!isHexStrict(value.gasPrice)) return false;
     
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isTransactionWithSender(value: TransactionWithSender): boolean {
     	if (!isAddress(value.from)) return false;
     	if (!isBaseTransaction(value)) return false;
    @@ -119,35 +146,47 @@ export function isTransactionWithSender(value: TransactionWithSender): boolean {
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function validateTransactionWithSender(value: TransactionWithSender) {
     	if (!isTransactionWithSender(value)) throw new InvalidTransactionWithSender(value);
     }
     
    +/**
    + *
    + * @param value
    + */
     export function isTransactionCall(value: TransactionCall): boolean {
    -	if (value.from !== undefined && !isAddress(value.from)) return false;
    +	if (!isNullish(value.from) && !isAddress(value.from)) return false;
     	if (!isAddress(value.to)) return false;
    -	if (value.gas !== undefined && !isHexStrict(value.gas)) return false;
    -	if (value.gasPrice !== undefined && !isHexStrict(value.gasPrice)) return false;
    -	if (value.value !== undefined && !isHexStrict(value.value)) return false;
    -	if (value.data !== undefined && !isHexStrict(value.data)) return false;
    -	if (value.type !== undefined) return false;
    +	if (!isNullish(value.gas) && !isHexStrict(value.gas)) return false;
    +	if (!isNullish(value.gasPrice) && !isHexStrict(value.gasPrice)) return false;
    +	if (!isNullish(value.value) && !isHexStrict(value.value)) return false;
    +	if (!isNullish(value.data) && !isHexStrict(value.data)) return false;
    +	if (!isNullish(value.type)) return false;
     	if (isTransaction1559Unsigned(value as Transaction1559Unsigned)) return false;
     	if (isTransaction2930Unsigned(value as Transaction2930Unsigned)) return false;
     
     	return true;
     }
     
    +/**
    + *
    + * @param value
    + */
     export function validateTransactionCall(value: TransactionCall) {
     	if (!isTransactionCall(value)) throw new InvalidTransactionCall(value);
     }
     
     export const validateCustomChainInfo = (transaction: InternalTransaction) => {
    -	if (transaction.common !== undefined) {
    -		if (transaction.common.customChain === undefined) throw new MissingCustomChainError();
    -		if (transaction.common.customChain.chainId === undefined)
    +	if (!isNullish(transaction.common)) {
    +		if (isNullish(transaction.common.customChain)) throw new MissingCustomChainError();
    +		if (isNullish(transaction.common.customChain.chainId))
     			throw new MissingCustomChainIdError();
     		if (
    -			transaction.chainId !== undefined &&
    +			!isNullish(transaction.chainId) &&
     			transaction.chainId !== transaction.common.customChain.chainId
     		)
     			throw new ChainIdMismatchError({
    @@ -159,15 +198,15 @@ export const validateCustomChainInfo = (transaction: InternalTransaction) => {
     
     export const validateChainInfo = (transaction: InternalTransaction) => {
     	if (
    -		transaction.common !== undefined &&
    -		transaction.chain !== undefined &&
    -		transaction.hardfork !== undefined
    +		!isNullish(transaction.common) &&
    +		!isNullish(transaction.chain) &&
    +		!isNullish(transaction.hardfork)
     	) {
     		throw new CommonOrChainAndHardforkError();
     	}
     	if (
    -		(transaction.chain !== undefined && transaction.hardfork === undefined) ||
    -		(transaction.hardfork !== undefined && transaction.chain === undefined)
    +		(!isNullish(transaction.chain) && isNullish(transaction.hardfork)) ||
    +		(!isNullish(transaction.hardfork) && isNullish(transaction.chain))
     	)
     		throw new MissingChainOrHardforkError({
     			chain: transaction.chain,
    @@ -178,16 +217,16 @@ export const validateChainInfo = (transaction: InternalTransaction) => {
     export const validateLegacyGas = (transaction: InternalTransaction) => {
     	if (
     		// This check is verifying gas and gasPrice aren't less than 0.
    -		transaction.gas === undefined ||
    +		isNullish(transaction.gas) ||
     		!isUInt(transaction.gas) ||
    -		transaction.gasPrice === undefined ||
    +		isNullish(transaction.gasPrice) ||
     		!isUInt(transaction.gasPrice)
     	)
     		throw new InvalidGasOrGasPrice({
     			gas: transaction.gas,
     			gasPrice: transaction.gasPrice,
     		});
    -	if (transaction.maxFeePerGas !== undefined || transaction.maxPriorityFeePerGas !== undefined)
    +	if (!isNullish(transaction.maxFeePerGas) || !isNullish(transaction.maxPriorityFeePerGas))
     		throw new UnsupportedFeeMarketError({
     			maxFeePerGas: transaction.maxFeePerGas,
     			maxPriorityFeePerGas: transaction.maxPriorityFeePerGas,
    @@ -198,7 +237,7 @@ export const validateFeeMarketGas = (transaction: InternalTransaction) => {
     	// These errors come from 1.x, so they must be checked before
     	// InvalidMaxPriorityFeePerGasOrMaxFeePerGas to throw the same error
     	// for the same code executing in 1.x
    -	if (transaction.gasPrice !== undefined && transaction.type === '0x2')
    +	if (!isNullish(transaction.gasPrice) && transaction.type === '0x2')
     		throw new Eip1559GasPriceError(transaction.gasPrice);
     	if (transaction.type === '0x0' || transaction.type === '0x1')
     		throw new UnsupportedFeeMarketError({
    @@ -207,9 +246,9 @@ export const validateFeeMarketGas = (transaction: InternalTransaction) => {
     		});
     
     	if (
    -		transaction.maxFeePerGas === undefined ||
    +		isNullish(transaction.maxFeePerGas) ||
     		!isUInt(transaction.maxFeePerGas) ||
    -		transaction.maxPriorityFeePerGas === undefined ||
    +		isNullish(transaction.maxPriorityFeePerGas) ||
     		!isUInt(transaction.maxPriorityFeePerGas)
     	)
     		throw new InvalidMaxPriorityFeePerGasOrMaxFeePerGas({
    @@ -221,14 +260,16 @@ export const validateFeeMarketGas = (transaction: InternalTransaction) => {
     /**
      * This method checks if all required gas properties are present for either
      * legacy gas (type 0x0 and 0x1) OR fee market transactions (0x2)
    + *
    + * @param transaction
      */
     export const validateGas = (transaction: InternalTransaction) => {
    -	const gasPresent = transaction.gas !== undefined || transaction.gasLimit !== undefined;
    -	const legacyGasPresent = gasPresent && transaction.gasPrice !== undefined;
    +	const gasPresent = !isNullish(transaction.gas) || !isNullish(transaction.gasLimit);
    +	const legacyGasPresent = gasPresent && !isNullish(transaction.gasPrice);
     	const feeMarketGasPresent =
     		gasPresent &&
    -		transaction.maxPriorityFeePerGas !== undefined &&
    -		transaction.maxFeePerGas !== undefined;
    +		!isNullish(transaction.maxPriorityFeePerGas) &&
    +		!isNullish(transaction.maxFeePerGas);
     
     	if (!legacyGasPresent && !feeMarketGasPresent)
     		throw new MissingGasError({
    @@ -249,7 +290,7 @@ export const validateGas = (transaction: InternalTransaction) => {
     		});
     
     	(legacyGasPresent ? validateLegacyGas : validateFeeMarketGas)(transaction);
    -	(transaction.type !== undefined && transaction.type > '0x1'
    +	(!isNullish(transaction.type) && transaction.type > '0x1'
     		? validateFeeMarketGas
     		: validateLegacyGas)(transaction);
     };
    @@ -258,12 +299,12 @@ export const validateTransactionForSigning = (
     	transaction: InternalTransaction,
     	overrideMethod?: (transaction: InternalTransaction) => void,
     ) => {
    -	if (overrideMethod !== undefined) {
    +	if (!isNullish(overrideMethod)) {
     		overrideMethod(transaction);
     		return;
     	}
     
    -	if (typeof transaction !== 'object' || transaction === null)
    +	if (typeof transaction !== 'object' || isNullish(transaction))
     		throw new InvalidTransactionObjectError(transaction);
     
     	validateCustomChainInfo(transaction);
    @@ -276,8 +317,8 @@ export const validateTransactionForSigning = (
     	validateGas(formattedTransaction);
     
     	if (
    -		formattedTransaction.nonce === undefined ||
    -		formattedTransaction.chainId === undefined ||
    +		isNullish(formattedTransaction.nonce) ||
    +		isNullish(formattedTransaction.chainId) ||
     		formattedTransaction.nonce.startsWith('-') ||
     		formattedTransaction.chainId.startsWith('-')
     	)
    
  • packages/web3-eth/src/web3_subscriptions.ts+1 1 modified
    @@ -32,7 +32,7 @@ export class LogsSubscription extends Web3Subscription<
     	{
     		readonly fromBlock?: BlockNumberOrTag;
     		readonly address?: Address | Address[];
    -		readonly topics?: (Topic | null)[];
    +		readonly topics?: Topic[];
     	}
     > {
     	protected _buildSubscriptionParams() {
    
  • packages/web3-eth/test/fixtures/web3_eth_methods_with_parameters.ts+4 0 modified
    @@ -1454,6 +1454,8 @@ export const getPastLogsValidData: [Filter, Filter][] = [
     			address: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
     			topics: [
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +				// Using "null" value intentionally for validation
    +				// eslint-disable-next-line no-null/no-null
     				null,
     				[
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -1467,6 +1469,8 @@ export const getPastLogsValidData: [Filter, Filter][] = [
     			address: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
     			topics: [
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +				// Using "null" value intentionally for validation
    +				// eslint-disable-next-line no-null/no-null
     				null,
     				[
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    
  • packages/web3-eth/test/unit/default_transaction_builder.test.ts+2 1 modified
    @@ -18,6 +18,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     import { EthExecutionAPI } from 'web3-common';
     import { Web3Context } from 'web3-core';
     import HttpProvider from 'web3-providers-http';
    +import { isNullish } from 'web3-validator';
     import {
     	Eip1559NotSupportedError,
     	UnableToPopulateNonceError,
    @@ -344,7 +345,7 @@ describe('defaultTransactionBuilder', () => {
     			delete input.type;
     
     			input.hardfork = 'istanbul';
    -			if (input.common !== undefined) input.common.hardfork = 'istanbul';
    +			if (!isNullish(input.common)) input.common.hardfork = 'istanbul';
     
     			const result = await defaultTransactionBuilder({
     				transaction: input,
    
  • packages/web3-eth/test/unit/prepare_transaction_for_signing.test.ts+10 12 modified
    @@ -18,6 +18,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     import { EthExecutionAPI } from 'web3-common';
     import { Web3Context } from 'web3-core';
     import HttpProvider from 'web3-providers-http';
    +import { isNullish } from 'web3-validator';
     import {
     	AccessListEIP2930Transaction,
     	FeeMarketEIP1559Transaction,
    @@ -88,18 +89,15 @@ describe('prepareTransactionForSigning', () => {
     				expect(messageToSign).toBe(expectedMessageToSign);
     
     				// should have expected v, r, and s
    -				const v =
    -					signedTransaction.v !== undefined
    -						? `0x${signedTransaction.v.toString('hex')}`
    -						: '';
    -				const r =
    -					signedTransaction.r !== undefined
    -						? `0x${signedTransaction.r.toString('hex')}`
    -						: '';
    -				const s =
    -					signedTransaction.s !== undefined
    -						? `0x${signedTransaction.s.toString('hex')}`
    -						: '';
    +				const v = !isNullish(signedTransaction.v)
    +					? `0x${signedTransaction.v.toString('hex')}`
    +					: '';
    +				const r = !isNullish(signedTransaction.r)
    +					? `0x${signedTransaction.r.toString('hex')}`
    +					: '';
    +				const s = !isNullish(signedTransaction.s)
    +					? `0x${signedTransaction.s.toString('hex')}`
    +					: '';
     				expect(v).toBe(expectedV);
     				expect(r).toBe(expectedR);
     				expect(s).toBe(expectedS);
    
  • packages/web3-eth/test/unit/rpc_methods/fixtures/get_logs.ts+4 0 modified
    @@ -66,6 +66,8 @@ export const testData: TestData[] = [
     			{
     				topics: [
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +					// Using "null" value intentionally for validation
    +					// eslint-disable-next-line no-null/no-null
     					null,
     					[
     						'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -87,6 +89,8 @@ export const testData: TestData[] = [
     				],
     				topics: [
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +					// Using "null" value intentionally for validation
    +					// eslint-disable-next-line no-null/no-null
     					null,
     					[
     						'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    
  • packages/web3-eth/test/unit/rpc_methods/fixtures/new_filter.ts+4 0 modified
    @@ -66,6 +66,8 @@ export const testData: TestData[] = [
     			{
     				topics: [
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +					// Using "null" value intentionally for validation
    +					// eslint-disable-next-line no-null/no-null
     					null,
     					[
     						'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -87,6 +89,8 @@ export const testData: TestData[] = [
     				],
     				topics: [
     					'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +					// Using "null" value intentionally for validation
    +					// eslint-disable-next-line no-null/no-null
     					null,
     					[
     						'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/call.test.ts+2 1 modified
    @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
    +import { isNullish } from 'web3-validator';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
     
     import { call as rpcMethodsCall } from '../../../src/rpc_methods';
    @@ -43,7 +44,7 @@ describe('call', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/estimate_gas.test.ts+2 1 modified
    @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
    +import { isNullish } from 'web3-validator';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
     
     import { estimateGas as rpcMethodsEstimateGas } from '../../../src/rpc_methods';
    @@ -43,7 +44,7 @@ describe('call', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/fixtures/get_logs.ts+2 0 modified
    @@ -34,6 +34,8 @@ const filter: Filter = {
     	address: '0x407d73d8a49eeb85d32cf465507dd71d507100c1',
     	topics: [
     		'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +		// Using "null" value intentionally for validation
    +		// eslint-disable-next-line no-null/no-null
     		null,
     		[
     			'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_balance.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getBalance as rpcMethodsGetBalance } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -38,7 +39,7 @@ describe('getBalance', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_block.test.ts+2 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    -import { isBytes } from 'web3-validator';
    +import { isBytes, isNullish } from 'web3-validator';
     import { Bytes } from 'web3-utils';
     
     import { getBlockByHash, getBlockByNumber } from '../../../src/rpc_methods';
    @@ -44,7 +44,7 @@ describe('getBlock', () => {
     
     			if (inputBlockIsBytes) {
     				inputBlockFormatted = format({ eth: 'bytes32' }, inputBlock, DEFAULT_RETURN_FORMAT);
    -			} else if (inputBlock === undefined) {
    +			} else if (isNullish(inputBlock)) {
     				inputBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockFormatted = format({ eth: 'uint' }, inputBlock, DEFAULT_RETURN_FORMAT);
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_block_transaction_count.test.ts+2 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    -import { isBytes } from 'web3-validator';
    +import { isBytes, isNullish } from 'web3-validator';
     import { Bytes } from 'web3-utils';
     
     import {
    @@ -46,7 +46,7 @@ describe('getBlockTransactionCount', () => {
     
     			if (inputBlockIsBytes) {
     				inputBlockFormatted = format({ eth: 'bytes32' }, inputBlock, DEFAULT_RETURN_FORMAT);
    -			} else if (inputBlock === undefined) {
    +			} else if (isNullish(inputBlock)) {
     				inputBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockFormatted = format({ eth: 'uint' }, inputBlock, DEFAULT_RETURN_FORMAT);
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_block_uncle_count.test.ts+2 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    -import { isBytes } from 'web3-validator';
    +import { isBytes, isNullish } from 'web3-validator';
     import { Bytes } from 'web3-utils';
     
     import { getUncleCountByBlockHash, getUncleCountByBlockNumber } from '../../../src/rpc_methods';
    @@ -43,7 +43,7 @@ describe('getBlockUncleCount', () => {
     
     			if (inputBlockIsBytes) {
     				inputBlockFormatted = format({ eth: 'bytes32' }, inputBlock, DEFAULT_RETURN_FORMAT);
    -			} else if (inputBlock === undefined) {
    +			} else if (isNullish(inputBlock)) {
     				inputBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockFormatted = format({ eth: 'uint' }, inputBlock, DEFAULT_RETURN_FORMAT);
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_code.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getCode as rpcMethodsGetCode } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -38,7 +39,7 @@ describe('getCode', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_fee_history.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getFeeHistory as rpcMethodsGetFeeHistory } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -57,7 +58,7 @@ describe('getFeeHistory', () => {
     
     			let inputNewestBlockFormatted;
     
    -			if (inputNewestBlock === undefined) {
    +			if (isNullish(inputNewestBlock)) {
     				inputNewestBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputNewestBlockFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_proof.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getProof as rpcMethodsGetProof } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -42,7 +43,7 @@ describe('getProof', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_storage_at.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getStorageAt as rpcMethodsGetStorageAt } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -43,7 +44,7 @@ describe('getStorageAt', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_count.test.ts+2 1 modified
    @@ -16,6 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
     
     import { getTransactionCount as rpcMethodsGetTransactionCount } from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
    @@ -38,7 +39,7 @@ describe('getTransactionCount', () => {
     
     			let inputBlockNumberFormatted;
     
    -			if (inputBlockNumber === undefined) {
    +			if (isNullish(inputBlockNumber)) {
     				inputBlockNumberFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockNumberFormatted = format(
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_transaction_from_block.test.ts+2 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    -import { isBytes } from 'web3-validator';
    +import { isBytes, isNullish } from 'web3-validator';
     import { Bytes } from 'web3-utils';
     
     import {
    @@ -52,7 +52,7 @@ describe('getTransactionFromBlock', () => {
     
     			if (inputBlockIsBytes) {
     				inputBlockFormatted = format({ eth: 'bytes32' }, inputBlock, DEFAULT_RETURN_FORMAT);
    -			} else if (inputBlock === undefined) {
    +			} else if (isNullish(inputBlock)) {
     				inputBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockFormatted = format({ eth: 'uint' }, inputBlock, DEFAULT_RETURN_FORMAT);
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/get_uncle.test.ts+2 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
     import { DEFAULT_RETURN_FORMAT, FMT_BYTES, FMT_NUMBER, format } from 'web3-common';
    -import { isBytes } from 'web3-validator';
    +import { isBytes, isNullish } from 'web3-validator';
     import { Bytes } from 'web3-utils';
     
     import {
    @@ -52,7 +52,7 @@ describe('getUncle', () => {
     
     			if (inputBlockIsBytes) {
     				inputBlockFormatted = format({ eth: 'bytes32' }, inputBlock, DEFAULT_RETURN_FORMAT);
    -			} else if (inputBlock === undefined) {
    +			} else if (isNullish(inputBlock)) {
     				inputBlockFormatted = web3Context.defaultBlock;
     			} else {
     				inputBlockFormatted = format({ eth: 'uint' }, inputBlock, DEFAULT_RETURN_FORMAT);
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/send_signed_transaction.test.ts+5 5 modified
    @@ -61,7 +61,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('sending', signedTransaction => {
     					expect(signedTransaction).toStrictEqual(inputSignedTransactionFormatted);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -99,7 +99,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('sent', signedTransaction => {
     					expect(signedTransaction).toStrictEqual(inputSignedTransactionFormatted);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -120,7 +120,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('transactionHash', transactionHash => {
     					expect(transactionHash).toStrictEqual(expectedTransactionHash);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -152,7 +152,7 @@ describe('sendTransaction', () => {
     			(rpcMethods.sendRawTransaction as jest.Mock).mockResolvedValueOnce(
     				expectedTransactionHash,
     			);
    -			(rpcMethods.getTransactionReceipt as jest.Mock).mockResolvedValueOnce(null);
    +			(rpcMethods.getTransactionReceipt as jest.Mock).mockResolvedValueOnce(undefined);
     
     			await sendSignedTransaction(web3Context, inputSignedTransaction, DEFAULT_RETURN_FORMAT);
     
    @@ -189,7 +189,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('receipt', receiptInfo => {
     					expect(receiptInfo).toStrictEqual(formattedReceiptInfo);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    
  • packages/web3-eth/test/unit/rpc_method_wrappers/send_transaction.test.ts+10 9 modified
    @@ -15,8 +15,9 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     import { Web3Context } from 'web3-core';
    -
     import { DEFAULT_RETURN_FORMAT, format } from 'web3-common';
    +import { isNullish } from 'web3-validator';
    +
     import * as rpcMethods from '../../../src/rpc_methods';
     import { Web3EthExecutionAPI } from '../../../src/web3_eth_execution_api';
     import { sendTransaction } from '../../../src/rpc_method_wrappers';
    @@ -64,9 +65,9 @@ describe('sendTransaction', () => {
     
     			if (
     				sendTransactionOptions?.ignoreGasPricing ||
    -				inputTransaction.gasPrice !== undefined ||
    -				(inputTransaction.maxPriorityFeePerGas !== undefined &&
    -					inputTransaction.maxFeePerGas !== undefined)
    +				!isNullish(inputTransaction.gasPrice) ||
    +				(!isNullish(inputTransaction.maxPriorityFeePerGas) &&
    +					!isNullish(inputTransaction.maxFeePerGas))
     			)
     				// eslint-disable-next-line jest/no-conditional-expect
     				expect(getTransactionGasPricingSpy).not.toHaveBeenCalled();
    @@ -94,7 +95,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('sending', transaction => {
     					expect(transaction).toStrictEqual(formattedTransaction);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -137,7 +138,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('sent', transaction => {
     					expect(transaction).toStrictEqual(formattedTransaction);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -162,7 +163,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('transactionHash', transactionHash => {
     					expect(transactionHash).toStrictEqual(expectedTransactionHash);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    @@ -200,7 +201,7 @@ describe('sendTransaction', () => {
     				expectedTransactionHash,
     			);
     			(rpcMethods.getTransactionReceipt as jest.Mock)
    -				.mockResolvedValueOnce(null)
    +				.mockResolvedValueOnce(undefined)
     				.mockResolvedValue(expectedReceiptInfo);
     
     			await sendTransaction(
    @@ -242,7 +243,7 @@ describe('sendTransaction', () => {
     				);
     				promiEvent.on('receipt', receiptInfo => {
     					expect(receiptInfo).toStrictEqual(formattedReceiptInfo);
    -					done(null);
    +					done(undefined);
     				});
     			});
     		},
    
  • packages/web3-net/src/rpc_methods.ts+12 0 modified
    @@ -18,20 +18,32 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     import { Web3RequestManager } from 'web3-core';
     import { Web3NetAPI } from './web3_net_api';
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getId(requestManager: Web3RequestManager<Web3NetAPI>) {
     	return requestManager.send({
     		method: 'net_version',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function getPeerCount(requestManager: Web3RequestManager<Web3NetAPI>) {
     	return requestManager.send({
     		method: 'net_peerCount',
     		params: [],
     	});
     }
     
    +/**
    + *
    + * @param requestManager
    + */
     export async function isListening(requestManager: Web3RequestManager<Web3NetAPI>) {
     	return requestManager.send({
     		method: 'net_listening',
    
  • packages/web3-net/src/rpc_method_wrappers.ts+10 0 modified
    @@ -20,6 +20,11 @@ import { Web3Context } from 'web3-core';
     import * as rpcMethods from './rpc_methods';
     import { Web3NetAPI } from './web3_net_api';
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getId<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<Web3NetAPI>,
     	returnFormat: ReturnFormat,
    @@ -29,6 +34,11 @@ export async function getId<ReturnFormat extends DataFormat>(
     	return format({ eth: 'uint' }, response as unknown as number, returnFormat);
     }
     
    +/**
    + *
    + * @param web3Context
    + * @param returnFormat
    + */
     export async function getPeerCount<ReturnFormat extends DataFormat>(
     	web3Context: Web3Context<Web3NetAPI>,
     	returnFormat: ReturnFormat,
    
  • packages/web3-providers-http/test/fixtures/test_data.ts+5 3 modified
    @@ -30,6 +30,8 @@ export const invalidClients = [
     	'http//localhost:8545',
     	'ws://localhost:8545',
     	'',
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	null,
     	undefined,
     	/* eslint-disable @typescript-eslint/no-magic-numbers */
    @@ -38,7 +40,7 @@ export const invalidClients = [
     
     export const httpProviderOptions = {
     	providerOptions: {
    -		body: null,
    +		body: undefined,
     		cache: 'force-cache',
     		credentials: 'same-origin',
     		headers: {
    @@ -51,8 +53,8 @@ export const httpProviderOptions = {
     		redirect: 'error',
     		referrer: 'foo',
     		referrerPolicy: 'same-origin',
    -		signal: null,
    -		window: null,
    +		signal: undefined,
    +		window: undefined,
     	} as RequestInit,
     };
     
    
  • packages/web3-providers-ipc/package.json+2 1 modified
    @@ -40,6 +40,7 @@
     	},
     	"dependencies": {
     		"web3-errors": "1.0.0-alpha.0",
    -		"web3-common": "1.0.0-alpha.0"
    +		"web3-common": "1.0.0-alpha.0",
    +		"web3-utils": "4.0.0-alpha.1"
     	}
     }
    
  • packages/web3-providers-ipc/src/index.ts+8 7 modified
    @@ -36,6 +36,7 @@ import {
     	Web3BaseProviderStatus,
     } from 'web3-common';
     import { ConnectionNotOpenError, InvalidClientError, InvalidConnectionError } from 'web3-errors';
    +import { isNullish } from 'web3-utils';
     
     export default class IpcProvider<
     	API extends Web3APISpec = EthExecutionAPI,
    @@ -115,9 +116,9 @@ export default class IpcProvider<
     		Method extends Web3APIMethod<API>,
     		ResponseType = Web3APIReturnType<API, Method>,
     	>(request: Web3APIPayload<API, Method>): Promise<JsonRpcResponse<ResponseType>> {
    -		if (this._socket === undefined) throw new Error('IPC connection is undefined');
    +		if (isNullish(this._socket)) throw new Error('IPC connection is undefined');
     
    -		if (request.id === undefined) throw new Error('Request Id not defined');
    +		if (isNullish(request.id)) throw new Error('Request Id not defined');
     
     		if (this.getStatus() !== 'connected') {
     			throw new ConnectionNotOpenError();
    @@ -148,18 +149,18 @@ export default class IpcProvider<
     			| JsonRpcNotification;
     
     		if ('method' in response && response.method.endsWith('_subscription')) {
    -			this._emitter.emit('message', null, response);
    +			this._emitter.emit('message', undefined, response);
     			return;
     		}
     
     		if (response.id && this._requestQueue.has(response.id)) {
     			const requestItem = this._requestQueue.get(response.id);
     
    -			if ('result' in response && response.result !== undefined) {
    -				this._emitter.emit('message', null, response);
    +			if ('result' in response && !isNullish(response.result)) {
    +				this._emitter.emit('message', undefined, response);
     				requestItem?.resolve(response);
    -			} else if ('error' in response && response.error !== undefined) {
    -				this._emitter.emit('message', response, null);
    +			} else if ('error' in response && !isNullish(response.error)) {
    +				this._emitter.emit('message', response, undefined);
     				requestItem?.reject(response);
     			}
     
    
  • packages/web3-providers-ws/package.json+1 0 modified
    @@ -48,6 +48,7 @@
     		"isomorphic-ws": "^4.0.1",
     		"web3-common": "1.0.0-alpha.0",
     		"web3-errors": "1.0.0-alpha.0",
    +		"web3-utils": "4.0.0-alpha.1",
     		"ws": "^8.2.3"
     	}
     }
    
  • packages/web3-providers-ws/src/index.ts+6 5 modified
    @@ -43,6 +43,7 @@ import {
     	Web3WSProviderError,
     	RequestAlreadySentError,
     } from 'web3-errors';
    +import { isNullish } from 'web3-utils';
     import { EventEmittedCallback, OnCloseEvent, ReconnectOptions, WSRequestItem } from './types';
     
     export default class WebSocketProvider<
    @@ -107,7 +108,7 @@ export default class WebSocketProvider<
     	}
     
     	public getStatus(): Web3BaseProviderStatus {
    -		if (this._webSocketConnection === undefined) return 'disconnected';
    +		if (isNullish(this._webSocketConnection)) return 'disconnected';
     
     		switch (this._webSocketConnection.readyState) {
     			case this._webSocketConnection.CONNECTING: {
    @@ -276,7 +277,7 @@ export default class WebSocketProvider<
     			jsonRpc.isResponseWithNotification(response as JsonRpcNotification) &&
     			(response as JsonRpcNotification).method.endsWith('_subscription')
     		) {
    -			this._wsEventEmitter.emit('message', null, response);
    +			this._wsEventEmitter.emit('message', undefined, response);
     			return;
     		}
     
    @@ -288,10 +289,10 @@ export default class WebSocketProvider<
     		}
     
     		if (jsonRpc.isBatchResponse(response) || jsonRpc.isResponseWithResult(response)) {
    -			this._wsEventEmitter.emit('message', null, response);
    +			this._wsEventEmitter.emit('message', undefined, response);
     			requestItem.deferredPromise.resolve(response);
     		} else {
    -			this._wsEventEmitter.emit('message', response, null);
    +			this._wsEventEmitter.emit('message', response, undefined);
     			requestItem?.deferredPromise.reject(new ResponseError(response));
     		}
     
    @@ -355,7 +356,7 @@ export default class WebSocketProvider<
     	}
     
     	private _emitCloseEvent(code?: number, reason?: string): void {
    -		this._wsEventEmitter.emit('close', null, {
    +		this._wsEventEmitter.emit('close', undefined, {
     			code,
     			reason,
     		} as OnCloseEvent);
    
  • packages/web3-providers-ws/src/types.ts+4 1 modified
    @@ -37,4 +37,7 @@ export type OnCloseEvent = {
     	reason: string;
     };
     
    -export type EventEmittedCallback = (error: Error | null, event?: OnCloseEvent | null) => void;
    +export type EventEmittedCallback = (
    +	error: Error | undefined,
    +	event?: OnCloseEvent | undefined,
    +) => void;
    
  • packages/web3-providers-ws/test/fixtures/test_data.ts+2 0 modified
    @@ -30,6 +30,8 @@ export const invalidConnectionStrings = [
     	'http//localhost:8545',
     	'ipc://localhost:8545',
     	'',
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	null,
     	undefined,
     	42,
    
  • packages/web3-providers-ws/test/integration/web_socket_provider_integration.test.ts+10 13 modified
    @@ -89,7 +89,7 @@ describeIf(getSystemTestProvider().includes('ws'))(
     					webSocketProvider.on(
     						'message',
     						(
    -							error: Error | null,
    +							error: Error | undefined,
     							result?: JsonRpcSubscriptionResult | JsonRpcNotification<any>,
     						) => {
     							if (error) {
    @@ -134,16 +134,13 @@ describeIf(getSystemTestProvider().includes('ws'))(
     				const code = 1000;
     
     				const closePromise = new Promise((resolve: Resolve) => {
    -					webSocketProvider.on(
    -						'close',
    -						(err: Error | null, event: OnCloseEvent | null | undefined) => {
    -							if (err) {
    -								throw new Error(err.message);
    -							}
    -							expect(event!.code).toEqual(code);
    -							resolve();
    -						},
    -					);
    +					webSocketProvider.on('close', (err?: Error, event?: OnCloseEvent) => {
    +						if (err) {
    +							throw new Error(err.message);
    +						}
    +						expect(event?.code).toEqual(code);
    +						resolve();
    +					});
     				});
     				currentAttempt = 0;
     				await waitForOpenConnection(webSocketProvider, currentAttempt);
    @@ -197,10 +194,10 @@ describeIf(getSystemTestProvider().includes('ws'))(
     					deferredPromise: defPromise,
     				};
     
    -				testResetProvider.setPendingRequest(jsonRpcPayload.id as JsonRpcId, reqItem);
    +				testResetProvider.setPendingRequest(jsonRpcPayload.id, reqItem);
     				expect(testResetProvider.pendigRequestsSize()).toBe(1);
     
    -				testResetProvider.setSentRequest(jsonRpcPayload.id as JsonRpcId, reqItem);
    +				testResetProvider.setSentRequest(jsonRpcPayload.id, reqItem);
     				expect(testResetProvider.sentRequestsSize()).toBe(1);
     
     				testResetProvider.reset();
    
  • packages/web3-providers-ws/test/unit/web_socket_provider.test.ts+2 2 modified
    @@ -104,7 +104,7 @@ describe('WebSocketProvider', () => {
     
     				await wsProvider.request(jsonRpcPayload);
     
    -				expect(messageSpy).toHaveBeenCalledWith(null, jsonRpcResponse);
    +				expect(messageSpy).toHaveBeenCalledWith(undefined, jsonRpcResponse);
     			});
     		});
     
    @@ -127,7 +127,7 @@ describe('WebSocketProvider', () => {
     
     				await expect(wsProvider.request(payload)).rejects.toThrow();
     
    -				expect(messageSpy).toHaveBeenCalledWith(payload, null);
    +				expect(messageSpy).toHaveBeenCalledWith(payload, undefined);
     			});
     		});
     	});
    
  • packages/web3-utils/src/converters.ts+48 3 modified
    @@ -15,7 +15,13 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    -import { validator, isAddress, isHexStrict, utils as validatorUtils } from 'web3-validator';
    +import {
    +	validator,
    +	isAddress,
    +	isHexStrict,
    +	utils as validatorUtils,
    +	isNullish,
    +} from 'web3-validator';
     import { keccak256 } from 'ethereum-cryptography/keccak';
     
     import {
    @@ -99,21 +105,30 @@ export const bytesToBuffer = (data: Bytes): Buffer | never => {
     	throw new InvalidBytesError(data);
     };
     
    -/** @internal */
    +/**
    + * @param data
    + * @internal
    + */
     const bufferToHexString = (data: Buffer) => `0x${data.toString('hex')}`;
     
     /**
      * Convert a byte array to a hex string
    + *
    + * @param bytes
      */
     export const bytesToHex = (bytes: Bytes): HexString => bufferToHexString(bytesToBuffer(bytes));
     
     /**
      * Convert a hex string to a byte array
    + *
    + * @param bytes
      */
     export const hexToBytes = (bytes: HexString): Buffer => bytesToBuffer(bytes);
     
     /**
      * Converts value to it's number representation
    + *
    + * @param value
      */
     export const hexToNumber = (value: HexString): bigint | number => {
     	validator.validate(['hex'], [value]);
    @@ -130,6 +145,8 @@ export const toDecimal = hexToNumber;
     
     /**
      * Converts value to it's hex representation
    + *
    + * @param value
      */
     export const numberToHex = (value: Numbers): HexString => {
     	validator.validate(['int'], [value]);
    @@ -145,11 +162,15 @@ export const fromDecimal = numberToHex;
     
     /**
      * Converts value to it's decimal representation in string
    + *
    + * @param data
      */
     export const hexToNumberString = (data: HexString): string => hexToNumber(data).toString();
     
     /**
      * Should be called to get hex representation (prefixed by 0x) of utf8 string
    + *
    + * @param str
      */
     export const utf8ToHex = (str: string): HexString => {
     	validator.validate(['string'], [str]);
    @@ -175,6 +196,8 @@ export const stringToHex = utf8ToHex;
     
     /**
      * Should be called to get utf8 from it's hex representation
    + *
    + * @param str
      */
     export const hexToUtf8 = (str: HexString): string => bytesToBuffer(str).toString('utf8');
     
    @@ -190,6 +213,8 @@ export const hexToString = hexToUtf8;
     
     /**
      * Should be called to get hex representation (prefixed by 0x) of ascii string
    + *
    + * @param str
      */
     export const asciiToHex = (str: string): HexString => {
     	validator.validate(['string'], [str]);
    @@ -204,6 +229,8 @@ export const fromAscii = asciiToHex;
     
     /**
      * Should be called to get ascii from it's hex representation
    + *
    + * @param str
      */
     export const hexToAscii = (str: HexString): string => bytesToBuffer(str).toString('ascii');
     
    @@ -214,6 +241,9 @@ export const toAscii = hexToAscii;
     
     /**
      * Auto converts any given value into it's hex representation.
    + *
    + * @param value
    + * @param returnType
      */
     export const toHex = (
     	value: Numbers | Bytes | Address | boolean,
    @@ -257,6 +287,8 @@ export const toHex = (
     /**
      * Auto converts any given value into it's hex representation,
      * then converts hex to number.
    + *
    + * @param value
      */
     export const toNumber = (value: Numbers): number | bigint => {
     	if (typeof value === 'number') {
    @@ -274,6 +306,8 @@ export const toNumber = (value: Numbers): number | bigint => {
     
     /**
      * Auto converts any given value into it's bigint representation
    + *
    + * @param value
      */
     export const toBigInt = (value: unknown): bigint => {
     	if (typeof value === 'number') {
    @@ -297,6 +331,9 @@ export const toBigInt = (value: unknown): bigint => {
     
     /**
      * Takes a number of wei and converts it to any other ether unit.
    + *
    + * @param number
    + * @param unit
      */
     export const fromWei = (number: Numbers, unit: EtherUnits): string => {
     	const denomination = ethUnitMap[unit];
    @@ -344,6 +381,9 @@ export const fromWei = (number: Numbers, unit: EtherUnits): string => {
     
     /**
      * Takes a number of a unit and converts it to wei.
    + *
    + * @param number
    + * @param unit
      */
     export const toWei = (number: Numbers, unit: EtherUnits): string => {
     	validator.validate(['number'], [number]);
    @@ -395,7 +435,7 @@ export const toChecksumAddress = (address: Address): string => {
     	const hash = bytesToHex(keccak256(Buffer.from(lowerCaseAddress)));
     
     	if (
    -		hash === null ||
    +		isNullish(hash) ||
     		hash === 'c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
     	)
     		return ''; // // EIP-1052 if hash is equal to c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, keccak was given empty data
    @@ -417,6 +457,9 @@ export const toChecksumAddress = (address: Address): string => {
     
     /**
      *  used to flatten json abi inputs/outputs into an array of type-representing-strings
    + *
    + * @param includeTuple
    + * @param puts
      */
     export const flattenTypes = (includeTuple: boolean, puts: Components[]): string[] => {
     	const types: string[] = [];
    @@ -448,6 +491,8 @@ export const flattenTypes = (includeTuple: boolean, puts: Components[]): string[
     /**
      * Should be used to create full function/event name from json abi
      * returns a string
    + *
    + * @param json
      */
     export const jsonInterfaceMethodToString = (
     	json: JsonFunctionInterface | JsonEventInterface,
    
  • packages/web3-utils/src/hash.ts+31 6 modified
    @@ -26,7 +26,7 @@ import {
     	InvalidBytesError,
     } from 'web3-errors';
     import { keccak256 } from 'ethereum-cryptography/keccak';
    -import { isAddress, isHexStrict } from 'web3-validator';
    +import { isAddress, isHexStrict, isNullish } from 'web3-validator';
     import { Numbers, TypedObject, TypedObjectAbbreviated, EncodingTypes, Bytes } from './types';
     import { leftPad, rightPad, toTwosComplement } from './string_manipulation';
     import { utf8ToHex, hexToBytes, toNumber, bytesToHex } from './converters';
    @@ -36,22 +36,26 @@ const SHA3_EMPTY_BYTES = '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfa
     /**
      *
      * computes the Keccak-256 hash of the input and returns a hexstring
    + *
    + * @param data
      */
    -export const sha3 = (data: Bytes): string | null => {
    +export const sha3 = (data: Bytes): string | undefined => {
     	const updatedData = typeof data === 'string' && isHexStrict(data) ? hexToBytes(data) : data;
     
     	const hash = bytesToHex(keccak256(Buffer.from(updatedData as Buffer)));
     
     	// EIP-1052 if hash is equal to c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, keccak was given empty data
    -	return hash === SHA3_EMPTY_BYTES ? null : hash;
    +	return hash === SHA3_EMPTY_BYTES ? undefined : hash;
     };
     
     /**
      *Will calculate the sha3 of the input but does return the hash value instead of null if for example a empty string is passed.
    + *
    + * @param data
      */
     export const sha3Raw = (data: Bytes): string => {
     	const hash = sha3(data);
    -	if (hash === null) {
    +	if (isNullish(hash)) {
     		return SHA3_EMPTY_BYTES;
     	}
     
    @@ -62,6 +66,8 @@ export { keccak256 };
     
     /**
      * returns type and value
    + *
    + * @param arg
      */
     const getType = (arg: TypedObject | TypedObjectAbbreviated | Numbers): [string, EncodingTypes] => {
     	if (
    @@ -78,6 +84,8 @@ const getType = (arg: TypedObject | TypedObjectAbbreviated | Numbers): [string,
     
     /**
      * returns the type with size if uint or int
    + *
    + * @param name
      */
     const elementaryName = (name: string): string => {
     	if (name.startsWith('int[')) {
    @@ -97,6 +105,9 @@ const elementaryName = (name: string): string => {
     
     /**
      * returns the size of the value of type 'byte'
    + *
    + * @param value
    + * @param typeLength
      */
     const parseTypeN = (value: string, typeLength: number): number => {
     	const typesize = /^(\d+).*$/.exec(value.slice(typeLength));
    @@ -105,6 +116,8 @@ const parseTypeN = (value: string, typeLength: number): number => {
     
     /**
      * returns the bit length of the value
    + *
    + * @param value
      */
     const bitLength = (value: BigInt | number): number => {
     	const updatedVal = value.toString(2);
    @@ -114,6 +127,9 @@ const bitLength = (value: BigInt | number): number => {
     /**
      * Pads the value based on size and type
      * returns a string of the padded value
    + *
    + * @param type
    + * @param val
      */
     const solidityPack = (type: string, val: EncodingTypes): string => {
     	const value = val.toString();
    @@ -191,6 +207,8 @@ const solidityPack = (type: string, val: EncodingTypes): string => {
     
     /**
      * returns a string of the tightly packed value given based on the type
    + *
    + * @param arg
      */
     export const processSolidityEncodePackedArgs = (
     	arg: TypedObject | TypedObjectAbbreviated | Numbers,
    @@ -210,6 +228,8 @@ export const processSolidityEncodePackedArgs = (
     
     /**
      * Encode packed arguments to a hexstring
    + *
    + * @param {...any} values
      */
     export const encodePacked = (...values: TypedObject[] | TypedObjectAbbreviated[]): string => {
     	const args = Array.prototype.slice.call(values);
    @@ -222,13 +242,18 @@ export const encodePacked = (...values: TypedObject[] | TypedObjectAbbreviated[]
     /**
      * Will tightly pack values given in the same way solidity would then hash.
      * returns a hash string, or null if input is empty
    + *
    + * @param {...any} values
      */
    -export const soliditySha3 = (...values: TypedObject[] | TypedObjectAbbreviated[]): string | null =>
    -	sha3(encodePacked(...values));
    +export const soliditySha3 = (
    +	...values: TypedObject[] | TypedObjectAbbreviated[]
    +): string | undefined => sha3(encodePacked(...values));
     
     /**
      * Will tightly pack values given in the same way solidity would then hash.
      * returns a hash string, if input is empty will return `0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`
    + *
    + * @param {...any} values
      */
     export const soliditySha3Raw = (...values: TypedObject[] | TypedObjectAbbreviated[]): string =>
     	sha3Raw(encodePacked(...values));
    
  • packages/web3-utils/src/objects.ts+4 2 modified
    @@ -15,12 +15,14 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    +import { isNullish } from 'web3-validator';
    +
     // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
     export const TypedArray = Object.getPrototypeOf(Uint8Array);
     
     const isIterable = (item: unknown): item is Record<string, unknown> =>
     	typeof item === 'object' &&
    -	item !== null &&
    +	!isNullish(item) &&
     	!Array.isArray(item) &&
     	!Buffer.isBuffer(item) &&
     	!(item instanceof TypedArray);
    @@ -46,7 +48,7 @@ export const mergeDeep = (
     					result[key] as Record<string, unknown>,
     					src[key] as Record<string, unknown>,
     				);
    -			} else if (src[key] !== undefined && src[key] !== null) {
    +			} else if (!isNullish(src[key]) && Object.hasOwnProperty.call(src, key)) {
     				if (Array.isArray(src[key]) || src[key] instanceof TypedArray) {
     					result[key] = (src[key] as unknown[]).slice(0);
     				} else {
    
  • packages/web3-utils/src/random.ts+4 2 modified
    @@ -20,7 +20,8 @@ import { randomBytes as cryptoRandomBytes } from 'crypto';
     /**
      * Returns a random byte array by the given bytes size
      *
    - * @param {Number} size
    + * @param {number} size
    + * @param byteSize
      * @returns {Buffer}
      */
     export const randomBytes = (byteSize: number): Buffer => {
    @@ -34,7 +35,8 @@ export const randomBytes = (byteSize: number): Buffer => {
     /**
      * Returns a random hex string by the given bytes size
      *
    - * @param {Number} size
    + * @param {number} size
    + * @param byteSize
      * @returns {string}
      */
     export const randomHex = (byteSize: number): string => `0x${randomBytes(byteSize).toString('hex')}`;
    
  • packages/web3-utils/src/string_manipulation.ts+14 0 modified
    @@ -22,6 +22,10 @@ import { Numbers } from './types';
     
     /**
      * Adds a padding on the left of a string, if value is a integer or bigInt will be converted to a hex string.
    + *
    + * @param value
    + * @param characterAmount
    + * @param sign
      */
     export const padLeft = (value: Numbers, characterAmount: number, sign = '0'): string => {
     	// To avoid duplicate code and circular dependency we will
    @@ -38,6 +42,10 @@ export const padLeft = (value: Numbers, characterAmount: number, sign = '0'): st
     
     /**
      * Adds a padding on the right of a string, if value is a integer or bigInt will be converted to a hex string.
    + *
    + * @param value
    + * @param characterAmount
    + * @param sign
      */
     export const padRight = (value: Numbers, characterAmount: number, sign = '0'): string => {
     	if (typeof value === 'string' && !isHexStrict(value)) {
    @@ -64,6 +72,9 @@ export const leftPad = padLeft;
     
     /**
      * Converts a negative number into the two’s complement and return a hexstring of 64 nibbles.
    + *
    + * @param value
    + * @param nibbleWidth
      */
     export const toTwosComplement = (value: Numbers, nibbleWidth = 64): string => {
     	validator.validate(['int'], [value]);
    @@ -85,6 +96,9 @@ export const toTwosComplement = (value: Numbers, nibbleWidth = 64): string => {
     
     /**
      * Converts the twos complement into a decimal number or big int.
    + *
    + * @param value
    + * @param nibbleWidth
      */
     export const fromTwosComplement = (value: Numbers, nibbleWidth = 64): number | bigint => {
     	validator.validate(['int'], [value]);
    
  • packages/web3-utils/src/types.ts+4 1 modified
    @@ -114,5 +114,8 @@ export interface Filter {
     	readonly fromBlock?: BlockNumberOrTag;
     	readonly toBlock?: BlockNumberOrTag;
     	readonly address?: Address | Address[];
    -	readonly topics?: (Topic | Topic[] | null)[];
    +
    +	// Using "null" type intentionally to match specifications
    +	// eslint-disable-next-line @typescript-eslint/ban-types
    +	readonly topics?: (null | Topic | Topic[])[];
     }
    
  • packages/web3-utils/src/validation.ts+6 0 modified
    @@ -27,6 +27,7 @@ import {
     	isTopic as isTopicValidator,
     	isTopicInBloom as isTopicInBloomValidator,
     	isUserEthereumAddressInBloom as isUserEthereumAddressInBloomValidator,
    +	isNullish as isNullishValidator,
     } from 'web3-validator';
     import { Numbers } from './types';
     
    @@ -105,6 +106,9 @@ export const isTopicInBloom = isTopicInBloomValidator;
     /**
      * Compares between block A and block B
      * Returns -1 if a < b, returns 1 if a > b and returns 0 if a == b
    + *
    + * @param blockA
    + * @param blockB
      */
     export const compareBlockNumbers = (blockA: Numbers, blockB: Numbers) => {
     	// string validation
    @@ -171,3 +175,5 @@ export const compareBlockNumbers = (blockA: Numbers, blockB: Numbers) => {
     	}
     	return 1;
     };
    +
    +export const isNullish = isNullishValidator;
    
  • packages/web3-utils/test/fixtures/converters.ts+14 0 modified
    @@ -36,6 +36,8 @@ export const bytesToHexInvalidData: [any, string][] = [
     	['data', 'value "data" at "/0" must pass "bytes" validation'],
     	[12, 'value "12" at "/0" must pass "bytes" validation'],
     	[['string'], 'value "string" at "/0" must pass "bytes" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[null, 'value at "/0" must pass "bytes" validation'],
     	[undefined, 'value at "/0" must pass "bytes" validation'],
     	[{}, 'value "[object Object]" at "/0" must pass "bytes" validation'],
    @@ -62,6 +64,8 @@ export const hexToBytesInvalidData: [any, string][] = [
     	['data', 'value "data" at "/0" must pass "bytes" validation'],
     	[12, 'value "12" at "/0" must pass "bytes" validation'],
     	[['string'], 'value "string" at "/0" must pass "bytes" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[null, 'value at "/0" must pass "bytes" validation'],
     	[undefined, 'value at "/0" must pass "bytes" validation'],
     	[{}, 'value "[object Object]" at "/0" must pass "bytes" validation'],
    @@ -87,6 +91,8 @@ export const numberToHexInvalidData: [any, string][] = [
     	[12.2, 'value "12.2" at "/0" must pass "int" validation'],
     	['0xag', 'value "0xag" at "/0" must pass "int" validation'],
     	['122g', 'value "122g" at "/0" must pass "int" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[null, 'value at "/0" must pass "int" validation'],
     	[undefined, 'value at "/0" must pass "int" validation'],
     	[{}, 'value "[object Object]" at "/0" must pass "int" validation'],
    @@ -131,6 +137,8 @@ export const utf8ToHexInvalidData: [any, string][] = [
     	[12, 'value "12" at "/0" must pass "string" validation'],
     	[BigInt(12), 'value "12" at "/0" must pass "string" validation'],
     	[12n, 'value "12" at "/0" must pass "string" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[null, 'value at "/0" must pass "string" validation'],
     	[undefined, 'value at "/0" must pass "string" validation'],
     	[{}, 'value "[object Object]" at "/0" must pass "string" validation'],
    @@ -154,6 +162,8 @@ export const hexToUtf8InvalidData: [any, string][] = [
     		'value "0x4920686176652031303g0c2a3" at "/0" must pass "bytes" validation',
     	],
     	['afde', 'value "afde" at "/0" must pass "bytes" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[null, 'value at "/0" must pass "bytes" validation'],
     	[undefined, 'value at "/0" must pass "bytes" validation'],
     	[{}, 'value "[object Object]" at "/0" must pass "bytes" validation'],
    @@ -250,6 +260,8 @@ export const toWeiValidData: [[Numbers, EtherUnits], string][] = [
     
     export const fromWeiInvalidData: [[any, any], string][] = [
     	[['123.34', 'kwei'], 'value "123.34" at "/0" must pass "int" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[[null, 'kwei'], 'value at "/0" must pass "int" validation'],
     	[[undefined, 'kwei'], 'value at "/0" must pass "int" validation'],
     	[[{}, 'kwei'], 'value "[object Object]" at "/0" must pass "int" validation'],
    @@ -258,6 +270,8 @@ export const fromWeiInvalidData: [[any, any], string][] = [
     ];
     
     export const toWeiInvalidData: [[any, any], string][] = [
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[[null, 'kwei'], 'value at "/0" must pass "number" validation'],
     	[[undefined, 'kwei'], 'value at "/0" must pass "number" validation'],
     	[[{}, 'kwei'], 'value "[object Object]" at "/0" must pass "number" validation'],
    
  • packages/web3-utils/test/fixtures/hash.ts+19 17 modified
    @@ -18,7 +18,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     import { hexToBytes } from '../../src/converters';
     import { TypedObject, TypedObjectAbbreviated } from '../../src/types';
     
    -export const sha3Data: [string, string | null][] = [
    +export const sha3Data: [string, string | undefined][] = [
     	['test123', '0xf81b517a242b218999ec8eec0ea6e2ddbef2a367a14e93f4a32a39e260f686ad'],
     	[
     		'0x265385c7f4132228a0d54eb1a9e7460b91c0cc68:2382:image',
    @@ -28,9 +28,9 @@ export const sha3Data: [string, string | null][] = [
     	['helloworld', '0xfa26db7ca85ead399216e7c6316bc50ed24393c3122b582735e7f3b0f91b93f0'],
     ];
     
    -export const sha3ValidData: [string, string | null][] = [
    +export const sha3ValidData: [string, string | undefined][] = [
     	...sha3Data,
    -	['', null],
    +	['', undefined],
     	[
     		'0x265385c7f4132228a0d54eb1a9e7460b91c0cc68',
     		'0xb549c60e309fa734059e547a595c28b5ebada949c16229fbf2192650807694f5',
    @@ -43,7 +43,7 @@ export const sha3ValidData: [string, string | null][] = [
     	['0x1234', '0x56570de287d73cd1cb6092bb8fdee6173974955fdef345ae579ee9f475ea7432'],
     ];
     
    -export const compareSha3JSValidData: [string, any | null][] = [
    +export const compareSha3JSValidData: [string, any | undefined][] = [
     	// cases that include buffer data
     	['0x80', Buffer.from(hexToBytes('0x80'))],
     	[
    @@ -59,14 +59,14 @@ export const sha3InvalidData: [any, string][] = [
     	[undefined, 'Invalid value given "undefined". Error: not a valid string.'],
     ];
     
    -export const sha3RawValidData: [string, string | null][] = [
    +export const sha3RawValidData: [string, string | undefined][] = [
     	...sha3Data,
     	['', '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'],
     ];
     
     export const compareSha3JSRawValidData: [string, string][] = [...compareSha3JSValidData];
     
    -export const soliditySha3Data: [TypedObject[] | TypedObjectAbbreviated[], string | null][] = [
    +export const soliditySha3Data: [TypedObject[] | TypedObjectAbbreviated[], string | undefined][] = [
     	[
     		[{ type: 'string', value: '31323334' }],
     		'0xf15f8da2ad27e486d632dc37d24912f634398918d6f9913a0a0ff84e388be62b',
    @@ -146,19 +146,21 @@ export const soliditySha3Data: [TypedObject[] | TypedObjectAbbreviated[], string
     	],
     ];
     
    -export const soliditySha3ValidData: [TypedObject[] | TypedObjectAbbreviated[], string | null][] = [
    -	...soliditySha3Data,
    -	[[{ t: 'string', v: '' }], null],
    -];
    +export const soliditySha3ValidData: [
    +	TypedObject[] | TypedObjectAbbreviated[],
    +	string | undefined,
    +][] = [...soliditySha3Data, [[{ t: 'string', v: '' }], undefined]];
     
    -export const soliditySha3RawValidData: [TypedObject[] | TypedObjectAbbreviated[], string | null][] =
    +export const soliditySha3RawValidData: [
    +	TypedObject[] | TypedObjectAbbreviated[],
    +	string | undefined,
    +][] = [
    +	...soliditySha3Data,
     	[
    -		...soliditySha3Data,
    -		[
    -			[{ t: 'string', v: '' }],
    -			'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470',
    -		],
    -	];
    +		[{ t: 'string', v: '' }],
    +		'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470',
    +	],
    +];
     
     export const soliditySha3InvalidData: [any, string][] = [
     	[1, 'Invalid value given "1". Error: invalid type, type not supported.'],
    
  • packages/web3-utils/test/fixtures/string_manipulation.ts+2 0 modified
    @@ -35,6 +35,8 @@ export const padLeftData: [[Numbers, number, string], HexString][] = [
     
     export const padInvalidData: [[any, number, string], string][] = [
     	[[9.5, 64, 'f'], 'value "9.5" at "/0" must pass "int" validation'],
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
     	[[null, 8, '0'], 'value at "/0" must pass "int" validation'],
     	[[undefined, 8, '0'], 'value at "/0" must pass "int" validation'],
     	[[{}, 3, 'f'], 'value "[object Object]" at "/0" must pass "int" validation'],
    
  • packages/web3-validator/src/errors.ts+2 1 modified
    @@ -16,9 +16,10 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
     import { Web3ValidationErrorObject } from './types';
    +import { isNullish } from './validation';
     
     const errorFormatter = (error: Web3ValidationErrorObject): string => {
    -	if (error.message && error.instancePath && error.params && error.params.value != null) {
    +	if (error.message && error.instancePath && error.params && !isNullish(error.params.value)) {
     		// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
     		return `value "${(error.params as { value: unknown }).value}" at "${error.instancePath}" ${
     			error.message
    
  • packages/web3-validator/src/types.ts+3 1 modified
    @@ -78,7 +78,9 @@ export interface Filter {
     	readonly fromBlock?: BlockNumberOrTag;
     	readonly toBlock?: BlockNumberOrTag;
     	readonly address?: string | string[];
    -	readonly topics?: (string | string[] | null)[];
    +	// Using "null" type intentionally to match specifications
    +	// eslint-disable-next-line @typescript-eslint/ban-types
    +	readonly topics?: (null | string | string[])[];
     }
     
     // To avoid circular dependency to avoid breaking changes in "web3-utils" package.
    
  • packages/web3-validator/src/utils.ts+8 0 modified
    @@ -205,6 +205,8 @@ export const codePointToInt = (codePoint: number): number => {
     
     /**
      * Converts value to it's number representation
    + *
    + * @param value
      */
     export const hexToNumber = (value: string): bigint | number => {
     	if (!isHexStrict(value)) {
    @@ -223,6 +225,8 @@ export const hexToNumber = (value: string): bigint | number => {
     
     /**
      * Converts value to it's hex representation
    + *
    + * @param value
      */
     export const numberToHex = (value: ValidInputTypes): string => {
     	if ((typeof value === 'number' || typeof value === 'bigint') && value < 0) {
    @@ -246,6 +250,10 @@ export const numberToHex = (value: ValidInputTypes): string => {
     
     /**
      * Adds a padding on the left of a string, if value is a integer or bigInt will be converted to a hex string.
    + *
    + * @param value
    + * @param characterAmount
    + * @param sign
      */
     export const padLeft = (value: ValidInputTypes, characterAmount: number, sign = '0'): string => {
     	if (typeof value === 'string' && !isHexStrict(value)) {
    
  • packages/web3-validator/src/validation/address.ts+5 0 modified
    @@ -21,6 +21,8 @@ import { isHexStrict } from './string';
     
     /**
      * Checks the checksum of a given address. Will also return false on non-checksum addresses.
    + *
    + * @param data
      */
     export const checkAddressCheckSum = (data: string): boolean => {
     	if (!/^(0x)?[0-9a-f]{40}$/i.test(data)) return false;
    @@ -45,6 +47,9 @@ export const checkAddressCheckSum = (data: string): boolean => {
     
     /**
      * Checks if a given string is a valid Ethereum address. It will also check the checksum, if the address has upper and lowercase letters.
    + *
    + * @param value
    + * @param checkChecksum
      */
     export const isAddress = (value: ValidInputTypes, checkChecksum = true) => {
     	if (typeof value !== 'string' && !Buffer.isBuffer(value)) {
    
  • packages/web3-validator/src/validation/block.ts+4 0 modified
    @@ -23,12 +23,16 @@ export const isBlockNumber = (value: string): boolean =>
     
     /**
      * Returns true if the given blockNumber is 'latest', 'pending', or 'earliest.
    + *
    + * @param value
      */
     export const isBlockTag = (value: string) =>
     	BlockTags.LATEST === value || BlockTags.PENDING === value || BlockTags.EARLIEST === value;
     
     /**
      * Returns true if given value is valid hex string and not negative, or is a valid BlockTag
    + *
    + * @param value
      */
     export const isBlockNumberOrTag = (value: string) =>
     	(isHexStrict(value) && !value.startsWith('-')) || isBlockTag(value);
    
  • packages/web3-validator/src/validation/bloom.ts+11 0 modified
    @@ -24,6 +24,8 @@ import { isHexStrict } from './string';
     /**
      * Returns true if the bloom is a valid bloom
      * https://github.com/joshstevens19/ethereum-bloom-filters/blob/fbeb47b70b46243c3963fe1c2988d7461ef17236/src/index.ts#L7
    + *
    + * @param bloom
      */
     export const isBloom = (bloom: ValidInputTypes): boolean => {
     	if (typeof bloom !== 'string') {
    @@ -44,6 +46,9 @@ export const isBloom = (bloom: ValidInputTypes): boolean => {
     /**
      * Returns true if the value is part of the given bloom
      * note: false positives are possible.
    + *
    + * @param bloom
    + * @param value
      */
     export const isInBloom = (bloom: string, value: string | Uint8Array): boolean => {
     	if (typeof value === 'string' && !isHexStrict(value)) {
    @@ -84,6 +89,9 @@ export const isInBloom = (bloom: string, value: string | Uint8Array): boolean =>
     
     /**
      * Returns true if the ethereum users address is part of the given bloom note: false positives are possible.
    + *
    + * @param bloom
    + * @param ethereumAddress
      */
     export const isUserEthereumAddressInBloom = (bloom: string, ethereumAddress: string): boolean => {
     	if (!isBloom(bloom)) {
    @@ -109,6 +117,9 @@ export const isUserEthereumAddressInBloom = (bloom: string, ethereumAddress: str
     /**
      * Returns true if the contract address is part of the given bloom.
      * note: false positives are possible.
    + *
    + * @param bloom
    + * @param contractAddress
      */
     export const isContractAddressInBloom = (bloom: string, contractAddress: string): boolean => {
     	if (!isBloom(bloom)) {
    
  • packages/web3-validator/src/validation/bytes.ts+2 0 modified
    @@ -21,6 +21,8 @@ import { isHexStrict } from './string';
     
     /**
      * checks input if typeof data is valid buffer input
    + *
    + * @param data
      */
     export const isBuffer = (data: ValidInputTypes) => Buffer.isBuffer(data);
     
    
  • packages/web3-validator/src/validation/filter.ts+9 6 modified
    @@ -18,13 +18,16 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     import { Filter } from '../types';
     import { isAddress } from './address';
     import { isBlockNumberOrTag } from './block';
    +import { isNullish } from './object';
     import { isTopic } from './topic';
     
     /**
      * First we check if all properties in the provided value are expected,
      * then because all Filter properties are optional, we check if the expected properties
      * are defined. If defined and they're not the expected type, we immediately return false,
      * otherwise we return true after all checks pass.
    + *
    + * @param value
      */
     export const isFilterObject = (value: Filter) => {
     	const expectedFilterProperties: (keyof Filter)[] = [
    @@ -33,7 +36,7 @@ export const isFilterObject = (value: Filter) => {
     		'address',
     		'topics',
     	];
    -	if (value === null || typeof value !== 'object') return false;
    +	if (isNullish(value) || typeof value !== 'object') return false;
     
     	if (
     		!Object.keys(value).every(property =>
    @@ -43,21 +46,21 @@ export const isFilterObject = (value: Filter) => {
     		return false;
     
     	if (
    -		(value.fromBlock !== undefined && !isBlockNumberOrTag(value.fromBlock)) ||
    -		(value.toBlock !== undefined && !isBlockNumberOrTag(value.toBlock))
    +		(!isNullish(value.fromBlock) && !isBlockNumberOrTag(value.fromBlock)) ||
    +		(!isNullish(value.toBlock) && !isBlockNumberOrTag(value.toBlock))
     	)
     		return false;
     
    -	if (value.address !== undefined) {
    +	if (!isNullish(value.address)) {
     		if (Array.isArray(value.address)) {
     			if (!value.address.every(address => isAddress(address))) return false;
     		} else if (!isAddress(value.address)) return false;
     	}
     
    -	if (value.topics !== undefined) {
    +	if (!isNullish(value.topics)) {
     		if (
     			!value.topics.every(topic => {
    -				if (topic === null) return true;
    +				if (isNullish(topic)) return true;
     
     				if (Array.isArray(topic)) {
     					return topic.every(nestedTopic => isTopic(nestedTopic));
    
  • packages/web3-validator/src/validation/numbers.ts+2 0 modified
    @@ -21,6 +21,8 @@ import { isHexStrict } from './string';
     
     /**
      * Checks if a given value is a valid big int
    + *
    + * @param value
      */
     export const isBigInt = (value: ValidInputTypes): boolean => typeof value === 'bigint';
     
    
  • packages/web3-validator/src/validation/object.ts+8 1 modified
    @@ -18,9 +18,16 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
     export const TypedArray = Object.getPrototypeOf(Uint8Array);
     
    +// Explicitly check for the
    +// eslint-disable-next-line @typescript-eslint/ban-types
    +export const isNullish = (item: unknown): item is undefined | null =>
    +	// Using "null" value intentionally for validation
    +	// eslint-disable-next-line no-null/no-null
    +	item === undefined || item === null;
    +
     export const isObject = (item: unknown): item is Record<string, unknown> =>
     	typeof item === 'object' &&
    -	item !== null &&
    +	!isNullish(item) &&
     	!Array.isArray(item) &&
     	!Buffer.isBuffer(item) &&
     	!(item instanceof TypedArray);
    
  • packages/web3-validator/src/validation/string.ts+2 0 modified
    @@ -19,6 +19,8 @@ import { ValidInputTypes } from '../types';
     
     /**
      * checks input if typeof data is valid string input
    + *
    + * @param value
      */
     export const isString = (value: ValidInputTypes) => typeof value === 'string';
     
    
  • packages/web3-validator/src/validation/topic.ts+5 0 modified
    @@ -19,6 +19,8 @@ import { isBloom, isInBloom } from './bloom';
     
     /**
      * Checks if its a valid topic
    + *
    + * @param topic
      */
     export const isTopic = (topic: string): boolean => {
     	if (typeof topic !== 'string') {
    @@ -39,6 +41,9 @@ export const isTopic = (topic: string): boolean => {
     /**
      * Returns true if the topic is part of the given bloom.
      * note: false positives are possible.
    + *
    + * @param bloom
    + * @param topic
      */
     export const isTopicInBloom = (bloom: string, topic: string): boolean => {
     	if (!isBloom(bloom)) {
    
  • packages/web3-validator/test/fixtures/validation.ts+17 1 modified
    @@ -15,6 +15,8 @@ You should have received a copy of the GNU Lesser General Public License
     along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     
    +import { Filter } from '../../src/types';
    +
     export const validUintData: any[] = [
     	'0x48',
     	'0x123c',
    @@ -24,6 +26,8 @@ export const validUintData: any[] = [
     	BigInt(12),
     ];
     
    +// Using "null" value intentionally for validation
    +// eslint-disable-next-line no-null/no-null
     export const invalidUintData: any[] = ['-0x48', '-12', -1, true, undefined, null];
     
     export const validUintDataWithSize: [any, number][] = [
    @@ -65,6 +69,8 @@ export const validIntData: any[] = [
     	BigInt(-12),
     ];
     
    +// Using "null" value intentionally for validation
    +// eslint-disable-next-line no-null/no-null
     export const invalidIntData: any[] = [true, undefined, null];
     
     export const validIntDataWithSize: [any, number][] = [
    @@ -348,7 +354,7 @@ export const invalidBooleanData = invalidHexStrictData.filter(
     	data => data !== 1 && data !== 0 && data !== '0' && data !== '1' && typeof data !== 'boolean',
     );
     
    -export const validFilterObjectData: Record<string, unknown>[] = [
    +export const validFilterObjectData: Filter[] = [
     	{
     		fromBlock: '0xc0ff3',
     	},
    @@ -367,6 +373,8 @@ export const validFilterObjectData: Record<string, unknown>[] = [
     	{
     		topics: [
     			'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +			// Using "null" value intentionally for validation
    +			// eslint-disable-next-line no-null/no-null
     			null,
     			[
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -383,6 +391,8 @@ export const validFilterObjectData: Record<string, unknown>[] = [
     		],
     		topics: [
     			'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +			// Using "null" value intentionally for validation
    +			// eslint-disable-next-line no-null/no-null
     			null,
     			[
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -406,12 +416,16 @@ export const invalidFilterObjectData: any[] = [
     		address: [
     			'0x98afe7a8d28bbc88dcf41f8e06d97c74958a47dc',
     			'0xdfd5293d8e347dfe59e90efd55b2956a1343963d',
    +			// Using "null" value intentionally for validation
    +			// eslint-disable-next-line no-null/no-null
     			null,
     		],
     	},
     	{
     		topics: [
     			'0x00000000000000000000000',
    +			// Using "null" value intentionally for validation
    +			// eslint-disable-next-line no-null/no-null
     			null,
     			[
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    @@ -429,6 +443,8 @@ export const invalidFilterObjectData: any[] = [
     		],
     		topics: [
     			'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    +			// Using "null" value intentionally for validation
    +			// eslint-disable-next-line no-null/no-null
     			null,
     			[
     				'0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b',
    
  • scripts/system_tests_utils.ts+2 0 modified
    @@ -31,6 +31,8 @@ let _accounts: string[] = [];
     
     /**
      * Get the env variable from Cypress if it exists or node process
    + *
    + * @param name
      */
     export const getEnvVar = (name: string): string | undefined =>
     	// eslint-disable-next-line @typescript-eslint/ban-ts-comment
    
  • tools/eslint-config-web3-base/package.json+2 1 modified
    @@ -41,7 +41,8 @@
     		"eslint-config-prettier": "^8.3.0",
     		"eslint-plugin-jest": "^25.2.4",
     		"eslint-plugin-tsdoc": "^0.2.16",
    -		"eslint-plugin-jsdoc": "^39.3.2"
    +		"eslint-plugin-jsdoc": "^39.3.2",
    +		"eslint-plugin-no-null": "^1.0.2"
     	},
     	"devDependencies": {
     		"eslint-plugin-deprecation": "^1.3.2",
    
  • tools/eslint-config-web3-base/ts-jest.js+10 2 modified
    @@ -16,7 +16,7 @@ along with web3.js.  If not, see <http://www.gnu.org/licenses/>.
     */
     module.exports = {
     	parser: '@typescript-eslint/parser',
    -	plugins: ['@typescript-eslint', 'jest'],
    +	plugins: ['@typescript-eslint', 'jest', 'header', 'no-null'],
     	extends: ['./ts', 'plugin:jest/recommended', 'plugin:jest/style'],
     	env: {
     		'jest/globals': true,
    @@ -37,12 +37,20 @@ module.exports = {
     		'@typescript-eslint/no-unsafe-call': ['error'],
     		'@typescript-eslint/no-unsafe-return': ['error'],
     		'@typescript-eslint/no-empty-function': ['error'],
    -		'@typescript-eslint/ban-types': 'warn',
    +		'@typescript-eslint/ban-types': [
    +			'error',
    +			{
    +				types: {
    +					null: "Use 'undefined' instead of 'null'",
    +				},
    +			},
    +		],
     		'@typescript-eslint/require-await': ['warn'],
     		'@typescript-eslint/restrict-template-expressions': ['warn'],
     		'dot-notation': 'off',
     		'lines-between-class-members': 'off',
     		'arrow-body-style': 'off',
     		'no-underscore-dangle': 'off',
    +		'no-null/no-null': ['error'],
     	},
     };
    
  • tools/eslint-config-web3-base/ts.js+10 1 modified
    @@ -42,6 +42,7 @@ module.exports = {
     		'deprecation',
     		'eslint-plugin-tsdoc',
     		'eslint-plugin-jsdoc',
    +		'no-null',
     	],
     	extends: [
     		'airbnb-base',
    @@ -97,7 +98,14 @@ module.exports = {
     		'@typescript-eslint/no-unused-expressions': ['error'],
     		'@typescript-eslint/no-useless-constructor': ['error'],
     		'@typescript-eslint/explicit-module-boundary-types': 'off',
    -		'@typescript-eslint/ban-types': 'warn',
    +		'@typescript-eslint/ban-types': [
    +			'error',
    +			{
    +				types: {
    +					null: "Use 'undefined' instead of 'null'",
    +				},
    +			},
    +		],
     		'@typescript-eslint/no-unused-vars': 'warn',
     		'import/extensions': [
     			'error',
    @@ -128,6 +136,7 @@ module.exports = {
     					'`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
     			},
     		],
    +		'no-null/no-null': ['error'],
     	},
     	globals: {
     		BigInt: true,
    
  • tsconfig.json+2 1 modified
    @@ -15,6 +15,7 @@
     		"removeComments": true,
     		"sourceMap": true,
     		"declarationMap": true,
    -		"strict": true
    +		"strict": true,
    +		"strictNullChecks": true
     	}
     }
    
  • yarn.lock+5 0 modified
    @@ -4671,6 +4671,11 @@ eslint-plugin-jsdoc@^39.3.2:
         semver "^7.3.7"
         spdx-expression-parse "^3.0.1"
     
    +eslint-plugin-no-null@^1.0.2:
    +  version "1.0.2"
    +  resolved "https://registry.yarnpkg.com/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz#1236a812391390a1877ad4007c26e745341c951f"
    +  integrity sha512-uRDiz88zCO/2rzGfgG15DBjNsgwWtWiSo4Ezy7zzajUgpnFIqd1TjepKeRmJZHEfBGu58o2a8S0D7vglvvhkVA==
    +
     eslint-plugin-tsdoc@^0.2.16:
       version "0.2.16"
       resolved "https://registry.yarnpkg.com/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.16.tgz#a3d31fb9c7955faa3c66a43dd43da7635f1c5e0d"
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.