Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

newPendingTransactionFilter #7353

Merged
merged 18 commits into from
Nov 5, 2024
171 changes: 171 additions & 0 deletions packages/web3-eth/src/filtering_rpc_method_wrappers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
This file is part of web3.js.

web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

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 { ethRpcMethods } from 'web3-rpc-methods';
import { DataFormat, EthExecutionAPI, Numbers, Log, FilterParams } from 'web3-types';
import { format, numberToHex } from 'web3-utils';
import { isNullish } from 'web3-validator';
import { logSchema } from './schemas.js';

/**
* View additional documentations here: {@link Web3Eth.createNewPendingTransactionFilter}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param returnFormat ({@link DataFormat}) Return format
*/
export async function createNewPendingTransactionFilter<ReturnFormat extends DataFormat>(
web3Context: Web3Context<EthExecutionAPI>,
returnFormat: ReturnFormat,
danforbes marked this conversation as resolved.
Show resolved Hide resolved
) {
const response = await ethRpcMethods.newPendingTransactionFilter(web3Context.requestManager);

return format(
{ format: 'uint' },
response as Numbers,
returnFormat ?? web3Context.defaultReturnFormat,
);
}

/**
* View additional documentations here: {@link Web3Eth.createNewFilter}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param filter ({@link FilterParam}) Filter param optional having from-block to-block address or params
* @param returnFormat ({@link DataFormat}) Return format
*/
export async function createNewFilter<ReturnFormat extends DataFormat>(
web3Context: Web3Context<EthExecutionAPI>,
filter: FilterParams,
returnFormat: ReturnFormat,
) {
// format type bigint or number toBlock and fromBlock to hexstring.
let { toBlock, fromBlock } = filter;
if (!isNullish(toBlock)) {
if (typeof toBlock === 'number' || typeof toBlock === 'bigint') {
toBlock = numberToHex(toBlock);
}
}
if (!isNullish(fromBlock)) {
if (typeof fromBlock === 'number' || typeof fromBlock === 'bigint') {
fromBlock = numberToHex(fromBlock);
}
}

const formattedFilter = { ...filter, fromBlock, toBlock };

const response = await ethRpcMethods.newFilter(web3Context.requestManager, formattedFilter);

return format(
{ format: 'uint' },
response as Numbers,
returnFormat ?? web3Context.defaultReturnFormat,
);
}

/**
* View additional documentations here: {@link Web3Eth.createNewBlockFilter}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param returnFormat ({@link DataFormat}) Return format
*/
export async function createNewBlockFilter<ReturnFormat extends DataFormat>(
web3Context: Web3Context<EthExecutionAPI>,
returnFormat: ReturnFormat,
) {
const response = await ethRpcMethods.newBlockFilter(web3Context.requestManager);

return format(
{ format: 'uint' },
response as Numbers,
returnFormat ?? web3Context.defaultReturnFormat,
);
}

/**
* View additional documentations here: {@link Web3Eth.uninstallFilter}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param filterIdentifier ({@link Numbers}) filter id
*/
export async function uninstallFilter(
web3Context: Web3Context<EthExecutionAPI>,
filterIdentifier: Numbers,
) {
const response = await ethRpcMethods.uninstallFilter(
web3Context.requestManager,
numberToHex(filterIdentifier),
);

return response;
}

/**
* View additional documentations here: {@link Web3Eth.getFilterChanges}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param filterIdentifier ({@link Numbers}) filter id
*/
export async function getFilterChanges<ReturnFormat extends DataFormat>(
web3Context: Web3Context<EthExecutionAPI>,
filterIdentifier: Numbers,
returnFormat: ReturnFormat,
) {
const response = await ethRpcMethods.getFilterChanges(
web3Context.requestManager,
numberToHex(filterIdentifier),
);

const result = response.map(res => {
if (typeof res === 'string') {
return res;

Check warning on line 130 in packages/web3-eth/src/filtering_rpc_method_wrappers.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/filtering_rpc_method_wrappers.ts#L130

Added line #L130 was not covered by tests
}

return format(
logSchema,
res as unknown as Log,
returnFormat ?? web3Context.defaultReturnFormat,
);
});

return result;
}

/**
* View additional documentations here: {@link Web3Eth.getFilterLogs}
* @param web3Context ({@link Web3Context}) Web3 configuration object that contains things such as the provider, request manager, wallet, etc.
* @param filterIdentifier ({@link Numbers}) filter id
*/
export async function getFilterLogs<ReturnFormat extends DataFormat>(
web3Context: Web3Context<EthExecutionAPI>,
filterIdentifier: Numbers,
returnFormat: ReturnFormat,
) {
const response = await ethRpcMethods.getFilterLogs(
web3Context.requestManager,
numberToHex(filterIdentifier),
);

const result = response.map(res => {
if (typeof res === 'string') {
return res;

Check warning on line 160 in packages/web3-eth/src/filtering_rpc_method_wrappers.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/filtering_rpc_method_wrappers.ts#L160

Added line #L160 was not covered by tests
}

return format(
logSchema,
res as unknown as Log,
returnFormat ?? web3Context.defaultReturnFormat,
);
});

return result;
}
141 changes: 141 additions & 0 deletions packages/web3-eth/src/web3_eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@
Eip712TypedData,
FMT_BYTES,
FMT_NUMBER,
FilterParams,
} from 'web3-types';
import { isSupportedProvider, Web3Context, Web3ContextInitOptions } from 'web3-core';
import { TransactionNotFound } from 'web3-errors';
import { toChecksumAddress, isNullish, ethUnitMap } from 'web3-utils';
import { ethRpcMethods } from 'web3-rpc-methods';

import * as rpcMethodsWrappers from './rpc_method_wrappers.js';
import * as filteringRpcMethodsWrappers from './filtering_rpc_method_wrappers.js';
import { SendTransactionOptions, TransactionMiddleware } from './types.js';
import {
LogsSubscription,
Expand Down Expand Up @@ -1894,4 +1896,143 @@
notClearSyncing ? Web3Eth.shouldClearSubscription : undefined,
);
}

/**
* Creates a filter in the node, to notify when new pending transactions arrive. To check if the state has changed.

Check warning on line 1901 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L1900-L1901

Added lines #L1900 - L1901 were not covered by tests
*
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) Specifies how the return data should be formatted.
* @returns A filter id.
*
* ```ts
* web3.eth.createNewPendingTransactionFilter().then(console.log);
* > 1n
*
* web3.eth.createNewPendingTransactionFilter({ number: FMT_NUMBER.HEX , bytes: FMT_BYTES.HEX }).then(console.log);
* > "0x1"
* ```
*/
public async createNewPendingTransactionFilter<
ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT,
>(returnFormat: ReturnFormat = this.defaultReturnFormat as ReturnFormat) {
return filteringRpcMethodsWrappers.createNewPendingTransactionFilter(this, returnFormat);
}

/**
* Creates a filter object, based on filter options, to notify when the state changes (logs)
*
* @param filter A {@link FilterParams} object containing the filter properties.
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) Specifies how the return data should be formatted.
* @returns A filter id.
*
* ```ts
* web3.eth.createNewFilter(filterParams).then(console.log);
* > 1n
*
* web3.eth.createNewFilter(filterParams, { number: FMT_NUMBER.HEX , bytes: FMT_BYTES.HEX }).then(console.log);
* > "0x1"
* ```
*/
public async createNewFilter<ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT>(
filter: FilterParams,
returnFormat: ReturnFormat = this.defaultReturnFormat as ReturnFormat,
) {
return filteringRpcMethodsWrappers.createNewFilter(this, filter, returnFormat);
}

/**
* Creates a filter in the node, to notify when a new block arrives.
*
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) Specifies how the return data should be formatted.
* @returns A filter id.
*
* ```ts
* web3.eth.createNewBlockFilter().then(console.log);
* > 1n
*
* web3.eth.createNewBlockFilter({ number: FMT_NUMBER.HEX , bytes: FMT_BYTES.HEX }).then(console.log);
* > "0x1"
* ```
*/
public async createNewBlockFilter<
ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT,
>(returnFormat: ReturnFormat = this.defaultReturnFormat as ReturnFormat) {
return filteringRpcMethodsWrappers.createNewBlockFilter(this, returnFormat);

Check warning on line 1959 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L1959

Added line #L1959 was not covered by tests
}

Check warning on line 1961 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L1961

Added line #L1961 was not covered by tests
/**
* Uninstalls a filter with given id. Should always be called when watch is no longer needed.
*
* @param filterIdentifier ({@link Numbers} filter id
* @returns true if the filter was successfully uninstalled, otherwise false.
*
* ```ts
* web3.eth.uninstallFilter(123).then(console.log);
* > true
*
* web3.eth.uninstallFilter('0x123').then(console.log);
* > true
*
* web3.eth.uninstallFilter(12n).then(console.log);
* > true
* ```
*/
public async uninstallFilter(filterIdentifier: Numbers) {
return filteringRpcMethodsWrappers.uninstallFilter(this, filterIdentifier);
}

Check warning on line 1981 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L1980-L1981

Added lines #L1980 - L1981 were not covered by tests

/**
* Polling method for a filter, which returns an array of logs which occurred since last poll.
*
* @param filterIdentifier ({@link Numbers} filter id
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) - Specifies how the return data from the call should be formatted.
* @returns {@link FilterResultsAPI}, an array of {@link Log} objects.
*
* ```ts
* web3.eth.getFilterChanges(123).then(console.log);
* > [{
* data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
* topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
* logIndex: 0n,
* transactionIndex: 0n,
* transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
* blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
* blockNumber: 1234n,
* address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
* },
* {...}]

Check warning on line 2002 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L2001-L2002

Added lines #L2001 - L2002 were not covered by tests
*/
public async getFilterChanges<ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT>(
filterIdentifier: Numbers,
returnFormat: ReturnFormat = this.defaultReturnFormat as ReturnFormat,
) {
return filteringRpcMethodsWrappers.getFilterChanges(this, filterIdentifier, returnFormat);
}

/**
* Returns an array of all logs matching filter with given id.
*
* @param filterIdentifier ({@link Numbers} filter id
* @param returnFormat ({@link DataFormat} defaults to {@link DEFAULT_RETURN_FORMAT}) - Specifies how the return data from the call should be formatted.
* @returns {@link FilterResultsAPI}, an array of {@link Log} objects.
*
* ```ts
* web3.eth.getFilterLogs(123).then(console.log);
* > [{
* data: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
* topics: ['0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7', '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385']
* logIndex: 0n,
* transactionIndex: 0n,
* transactionHash: '0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385',
* blockHash: '0xfd43ade1c09fade1c0d57a7af66ab4ead7c2c2eb7b11a91ffdd57a7af66ab4ead7',
* blockNumber: 1234n,
* address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'

Check warning on line 2028 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L2028

Added line #L2028 was not covered by tests
* },
* {...}]

Check warning on line 2030 in packages/web3-eth/src/web3_eth.ts

View check run for this annotation

Codecov / codecov/patch

packages/web3-eth/src/web3_eth.ts#L2030

Added line #L2030 was not covered by tests
*/
public async getFilterLogs<ReturnFormat extends DataFormat = typeof DEFAULT_RETURN_FORMAT>(
filterIdentifier: Numbers,
returnFormat: ReturnFormat = this.defaultReturnFormat as ReturnFormat,
) {
return filteringRpcMethodsWrappers.getFilterLogs(this, filterIdentifier, returnFormat);
}
}
7 changes: 7 additions & 0 deletions packages/web3-eth/test/integration/format.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,12 @@ describe('format', () => {
expect(typeof res).toBe(mapFormatToType[format as string]);
expect(Number(res)).toBeGreaterThan(0);
});

it.each(Object.values(FMT_NUMBER))('createNewPendingTransactionFilter', async format => {
web3Eth.defaultReturnFormat = { number: format as FMT_NUMBER, bytes: FMT_BYTES.HEX };
const res = await web3Eth.createNewPendingTransactionFilter();
expect(typeof res).toBe(mapFormatToType[format as string]);
expect(parseInt(String(res), 16)).toBeGreaterThan(0);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
This file is part of web3.js.

web3.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

web3.js is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

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, Web3EthExecutionAPI } from 'web3-types';
import { ethRpcMethods } from 'web3-rpc-methods';
import { createNewBlockFilter } from '../../../src/filtering_rpc_method_wrappers';

jest.mock('web3-rpc-methods');

describe('createNewBlockFilter', () => {
let web3Context: Web3Context<Web3EthExecutionAPI>;

beforeAll(() => {
web3Context = new Web3Context('http://127.0.0.1:8545');
});

it('should call rpcMethods.newBlockFilter with expected parameters', async () => {
await createNewBlockFilter(web3Context, DEFAULT_RETURN_FORMAT);
expect(ethRpcMethods.newBlockFilter).toHaveBeenCalledWith(web3Context.requestManager);
});
});
Loading
Loading