Skip to content

Commit

Permalink
getPastEvents doesn't support filter (#6010)
Browse files Browse the repository at this point in the history
* filter past events

* refactor

* fix

* remove filter for ALL EVNETS. add tests for Basic contract

* filter all events in a lib

* add unit tests

* add topics unit tests

* add change logs

* fix changelogs

---------

Co-authored-by: Junaid <[email protected]>
  • Loading branch information
avkos and jdevcs authored Apr 20, 2023
1 parent 3d80e63 commit 55bed46
Show file tree
Hide file tree
Showing 9 changed files with 453 additions and 35 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1461,3 +1461,13 @@ should use 4.0.1-alpha.0 for testing.
- Bug fix of `checkNetwork` in ENS (#5988)

## [Unreleased]

### Added

#### web3-eth-contract

- Added support for `getPastEvents` method to filter `allEvents` and specific event (#6010)

#### web3-types

- Added `filters` param to the `Filter` type (#6010)
4 changes: 4 additions & 0 deletions packages/web3-eth-contract/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,7 @@ const transactionHash = receipt.transactionHash;
- `data` was removed as a property of `ContractOptions` type (#5915)

## [Unreleased]

### Added

- Added support for `getPastEvents` method to filter `allEvents` and specific event (#6010)
28 changes: 23 additions & 5 deletions packages/web3-eth-contract/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
PayableCallOptions,
DataFormat,
DEFAULT_RETURN_FORMAT,
Numbers,
} from 'web3-types';
import { format, isDataFormat, toChecksumAddress } from 'web3-utils';
import {
Expand Down Expand Up @@ -702,7 +703,7 @@ export class Contract<Abi extends ContractAbi>
): Promise<(string | EventLog)[]> {
const eventName = typeof param1 === 'string' ? param1 : 'allEvents';

const filter =
const options =
// eslint-disable-next-line no-nested-ternary
typeof param1 !== 'string' && !isDataFormat(param1)
? param1
Expand All @@ -727,19 +728,36 @@ export class Contract<Abi extends ContractAbi>
if (!abi) {
throw new Web3ContractError(`Event ${eventName} not found.`);
}

const { fromBlock, toBlock, topics, address } = encodeEventABI(
this.options,
abi,
filter ?? {},
options ?? {},
);

const logs = await getLogs(this, { fromBlock, toBlock, topics, address }, returnFormat);
return logs.map(log =>
const decodedLogs = logs.map(log =>
typeof log === 'string'
? log
: decodeEventABI(abi, log as LogsInput, this._jsonInterface, returnFormat),
);

const filter = options?.filter ?? {};
const filterKeys = Object.keys(filter);
return eventName === 'allEvents' && filterKeys.length > 0
? decodedLogs.filter(log =>
typeof log === 'string'
? true
: filterKeys.every((k: string) =>
Array.isArray(filter[k])
? (filter[k] as Numbers[]).some(
(v: Numbers) =>
String(log.returnValues[k]).toUpperCase() ===
String(v).toUpperCase(),
)
: String(log.returnValues[k]).toUpperCase() ===
String(filter[k]).toUpperCase(),
),
)
: decodedLogs;
}

private _parseAndSetAddress(value?: Address, returnFormat: DataFormat = DEFAULT_RETURN_FORMAT) {
Expand Down
40 changes: 13 additions & 27 deletions packages/web3-eth-contract/src/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ import {
AbiEventFragment,
AbiFunctionFragment,
LogsInput,
BlockNumberOrTag,
Filter,
HexString,
Topic,
Numbers,
FMT_NUMBER,
FMT_BYTES,
DataFormat,
Expand All @@ -51,27 +49,15 @@ import { Web3ContractError } from 'web3-errors';
// eslint-disable-next-line import/no-cycle
import { ContractOptions, ContractAbiWithSignature, EventLog } from './types';

type Writeable<T> = { -readonly [P in keyof T]: T[P] };
export const encodeEventABI = (
{ address }: ContractOptions,
event: AbiEventFragment & { signature: string },
options?: {
fromBlock?: BlockNumberOrTag;
toBlock?: BlockNumberOrTag;
filter?: Filter;
// Using "null" type intentionally to match specifications
// eslint-disable-next-line @typescript-eslint/ban-types
topics?: (null | Topic | Topic[])[];
},
options?: Filter,
) => {
const opts: {
filter: Filter;
fromBlock?: Numbers;
toBlock?: Numbers;
topics?: (Topic | Topic[])[];
address?: HexString;
} = {
filter: options?.filter ?? {},
};
const topics = options?.topics;
const filter = options?.filter ?? {};
const opts: Writeable<Filter> = {};

if (!isNullish(options?.fromBlock)) {
opts.fromBlock = format(blockSchema.properties.number, options?.fromBlock, {
Expand All @@ -86,11 +72,10 @@ export const encodeEventABI = (
});
}

if (options?.topics && Array.isArray(options.topics)) {
opts.topics = [...options.topics].filter(Boolean) as Topic[];
if (topics && Array.isArray(topics)) {
opts.topics = [...topics] as Topic[];
} else {
opts.topics = [];

// add event signature
if (event && !event.anonymous && event.name !== 'ALLEVENTS') {
opts.topics.push(
Expand All @@ -105,19 +90,20 @@ export const encodeEventABI = (
continue;
}

const value = opts.filter[input.name as keyof Filter];

const value = filter[input.name];
if (!value) {
// eslint-disable-next-line no-null/no-null
opts.topics.push(null);
continue;
}

// TODO: https://github.com/ethereum/web3.js/issues/344
// TODO: deal properly with components
if (Array.isArray(value)) {
opts.topics.push(...value.map(v => encodeParameter(input.type, v)));
opts.topics.push(value.map(v => encodeParameter(input.type, v)));
} else {
opts.topics.push(encodeParameter(input.type, value));
}

opts.topics.push(encodeParameter(input.type, value));
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions packages/web3-eth-contract/src/log_subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ export class LogsSubscription extends Web3Subscription<
data: EventLog;
changed: EventLog & { removed: true };
},
{ address?: HexString; topics?: (Topic | Topic[])[]; abi: AbiEventFragment }
// eslint-disable-next-line @typescript-eslint/ban-types
{ address?: HexString; topics?: (Topic | Topic[] | null)[]; abi: AbiEventFragment }
> {
/**
* Address of tye contract
Expand All @@ -93,7 +94,8 @@ export class LogsSubscription extends Web3Subscription<
/**
* The list of topics subscribed
*/
public readonly topics?: (Topic | Topic[])[];
// eslint-disable-next-line @typescript-eslint/ban-types
public readonly topics?: (Topic | Topic[] | null)[];

/**
* The {@doclink glossary/json_interface | JSON Interface} of the event.
Expand All @@ -105,7 +107,8 @@ export class LogsSubscription extends Web3Subscription<
public constructor(
args: {
address?: HexString;
topics?: (Topic | Topic[])[];
// eslint-disable-next-line @typescript-eslint/ban-types
topics?: (Topic | Topic[] | null)[];
abi: AbiEventFragment & { signature: HexString };
jsonInterface: ContractAbiWithSignature;
},
Expand Down
Loading

0 comments on commit 55bed46

Please sign in to comment.