More flexible Contract for events and allow listening to multiple events in a single filter.
This commit is contained in:
parent
8fe938e69b
commit
d2271617a6
@ -3,11 +3,11 @@ import { resolveAddress } from "../address/index.js";
|
|||||||
import { copyRequest, Log, TransactionResponse } from "../providers/index.js";
|
import { copyRequest, Log, TransactionResponse } from "../providers/index.js";
|
||||||
import {
|
import {
|
||||||
defineProperties, isCallException, isHexString, resolveProperties,
|
defineProperties, isCallException, isHexString, resolveProperties,
|
||||||
makeError, assertArgument, throwError
|
makeError, assert, assertArgument
|
||||||
} from "../utils/index.js";
|
} from "../utils/index.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContractEventPayload,
|
ContractEventPayload, ContractUnknownEventPayload,
|
||||||
ContractTransactionResponse,
|
ContractTransactionResponse,
|
||||||
EventLog
|
EventLog
|
||||||
} from "./wrappers.js";
|
} from "./wrappers.js";
|
||||||
@ -63,12 +63,6 @@ function canSend(value: any): value is ContractRunnerSender {
|
|||||||
return (value && typeof(value.sendTransaction) === "function");
|
return (value && typeof(value.sendTransaction) === "function");
|
||||||
}
|
}
|
||||||
|
|
||||||
function concisify(items: Array<string>): Array<string> {
|
|
||||||
items = Array.from((new Set(items)).values())
|
|
||||||
items.sort();
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PreparedTopicFilter implements DeferredTopicFilter {
|
class PreparedTopicFilter implements DeferredTopicFilter {
|
||||||
#filter: Promise<TopicFilter>;
|
#filter: Promise<TopicFilter>;
|
||||||
readonly fragment!: EventFragment;
|
readonly fragment!: EventFragment;
|
||||||
@ -223,11 +217,9 @@ class WrappedMethod<A extends Array<any> = Array<any>, R = any, D extends R | Co
|
|||||||
|
|
||||||
async send(...args: ContractMethodArgs<A>): Promise<ContractTransactionResponse> {
|
async send(...args: ContractMethodArgs<A>): Promise<ContractTransactionResponse> {
|
||||||
const runner = this._contract.runner;
|
const runner = this._contract.runner;
|
||||||
if (!canSend(runner)) {
|
assert(canSend(runner), "contract runner does not support sending transactions",
|
||||||
return throwError("contract runner does not support sending transactions", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "sendTransaction" });
|
||||||
operation: "sendTransaction"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const tx = await runner.sendTransaction(await this.populateTransaction(...args));
|
const tx = await runner.sendTransaction(await this.populateTransaction(...args));
|
||||||
const provider = getProvider(this._contract.runner);
|
const provider = getProvider(this._contract.runner);
|
||||||
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
// @TODO: the provider can be null; make a custom dummy provider that will throw a
|
||||||
@ -237,21 +229,16 @@ class WrappedMethod<A extends Array<any> = Array<any>, R = any, D extends R | Co
|
|||||||
|
|
||||||
async estimateGas(...args: ContractMethodArgs<A>): Promise<bigint> {
|
async estimateGas(...args: ContractMethodArgs<A>): Promise<bigint> {
|
||||||
const runner = getRunner(this._contract.runner, "estimateGas");
|
const runner = getRunner(this._contract.runner, "estimateGas");
|
||||||
if (!canEstimate(runner)) {
|
assert(canEstimate(runner), "contract runner does not support gas estimation",
|
||||||
return throwError("contract runner does not support gas estimation", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "estimateGas" });
|
||||||
operation: "estimateGas"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return await runner.estimateGas(await this.populateTransaction(...args));
|
return await runner.estimateGas(await this.populateTransaction(...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
async staticCallResult(...args: ContractMethodArgs<A>): Promise<Result> {
|
async staticCallResult(...args: ContractMethodArgs<A>): Promise<Result> {
|
||||||
const runner = getRunner(this._contract.runner, "call");
|
const runner = getRunner(this._contract.runner, "call");
|
||||||
if (!canCall(runner)) {
|
assert(canCall(runner), "contract runner does not support calling",
|
||||||
return throwError("contract runner does not support calling", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "call" });
|
||||||
operation: "call"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const tx = await this.populateTransaction(...args);
|
const tx = await this.populateTransaction(...args);
|
||||||
|
|
||||||
@ -290,7 +277,7 @@ class WrappedEvent<A extends Array<any> = Array<any>> extends _WrappedEventBase(
|
|||||||
|
|
||||||
return new Proxy(this, {
|
return new Proxy(this, {
|
||||||
// Perform the default operation for this fragment type
|
// Perform the default operation for this fragment type
|
||||||
apply: async (target, thisArg, args: ContractEventArgs<A>) => {
|
apply: (target, thisArg, args: ContractEventArgs<A>) => {
|
||||||
return new PreparedTopicFilter(contract, target.getFragment(...args), args);
|
return new PreparedTopicFilter(contract, target.getFragment(...args), args);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -344,23 +331,41 @@ function isDeferred(value: any): value is DeferredTopicFilter {
|
|||||||
(typeof(value.getTopicFilter) === "function") && value.fragment);
|
(typeof(value.getTopicFilter) === "function") && value.fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSubTag(contract: BaseContract, event: ContractEventName): Promise<{ tag: string, fragment: EventFragment, topics: TopicFilter }> {
|
async function getSubInfo(contract: BaseContract, event: ContractEventName): Promise<{ fragment: null | EventFragment, tag: string, topics: TopicFilter }> {
|
||||||
let fragment: EventFragment;
|
|
||||||
let topics: Array<null | string | Array<string>>;
|
let topics: Array<null | string | Array<string>>;
|
||||||
|
let fragment: null | EventFragment = null;
|
||||||
|
|
||||||
|
// Convert named events to topicHash and get the fragment for
|
||||||
|
// events which need deconstructing.
|
||||||
|
|
||||||
if (Array.isArray(event)) {
|
if (Array.isArray(event)) {
|
||||||
// Topics; e.g. `[ "0x1234...89ab" ]`
|
const topicHashify = function(name: string): string {
|
||||||
fragment = contract.interface.getEvent(event[0] as string);
|
if (isHexString(name, 32)) { return name; }
|
||||||
topics = event;
|
return contract.interface.getEvent(name).topicHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array of Topics and Names; e.g. `[ "0x1234...89ab", "Transfer(address)" ]`
|
||||||
|
topics = event.map((e) => {
|
||||||
|
if (e == null) { return null; }
|
||||||
|
if (Array.isArray(e)) { return e.map(topicHashify); }
|
||||||
|
return topicHashify(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (event === "*") {
|
||||||
|
topics = [ null ];
|
||||||
|
|
||||||
} else if (typeof(event) === "string") {
|
} else if (typeof(event) === "string") {
|
||||||
// Event name (name or signature); `"Transfer"`
|
if (isHexString(event, 32)) {
|
||||||
|
// Topic Hash
|
||||||
|
topics = [ event ];
|
||||||
|
} else {
|
||||||
|
// Name or Signature; e.g. `"Transfer", `"Transfer(address)"`
|
||||||
fragment = contract.interface.getEvent(event);
|
fragment = contract.interface.getEvent(event);
|
||||||
topics = [ fragment.topicHash ];
|
topics = [ fragment.topicHash ];
|
||||||
|
}
|
||||||
|
|
||||||
} else if (isDeferred(event)) {
|
} else if (isDeferred(event)) {
|
||||||
// Deferred Topic Filter; e.g. `contract.filter.Transfer(from)`
|
// Deferred Topic Filter; e.g. `contract.filter.Transfer(from)`
|
||||||
fragment = event.fragment;
|
|
||||||
topics = await event.getTopicFilter();
|
topics = await event.getTopicFilter();
|
||||||
|
|
||||||
} else if ("fragment" in event) {
|
} else if ("fragment" in event) {
|
||||||
@ -369,15 +374,17 @@ async function getSubTag(contract: BaseContract, event: ContractEventName): Prom
|
|||||||
topics = [ fragment.topicHash ];
|
topics = [ fragment.topicHash ];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log(event);
|
assertArgument(false, "unknown event name", "event", event);
|
||||||
throw new Error("TODO");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize topics and sort TopicSets
|
// Normalize topics and sort TopicSets
|
||||||
topics = topics.map((t) => {
|
topics = topics.map((t) => {
|
||||||
if (t == null) { return null; }
|
if (t == null) { return null; }
|
||||||
if (Array.isArray(t)) {
|
if (Array.isArray(t)) {
|
||||||
return concisify(t.map((t) => t.toLowerCase()));
|
const items = Array.from(new Set(t.map((t) => t.toLowerCase())).values());
|
||||||
|
if (items.length === 1) { return items[0]; }
|
||||||
|
items.sort();
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
return t.toLowerCase();
|
return t.toLowerCase();
|
||||||
});
|
});
|
||||||
@ -393,19 +400,16 @@ async function getSubTag(contract: BaseContract, event: ContractEventName): Prom
|
|||||||
|
|
||||||
async function hasSub(contract: BaseContract, event: ContractEventName): Promise<null | Sub> {
|
async function hasSub(contract: BaseContract, event: ContractEventName): Promise<null | Sub> {
|
||||||
const { subs } = getInternal(contract);
|
const { subs } = getInternal(contract);
|
||||||
return subs.get((await getSubTag(contract, event)).tag) || null;
|
return subs.get((await getSubInfo(contract, event)).tag) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSub(contract: BaseContract, event: ContractEventName): Promise<Sub> {
|
async function getSub(contract: BaseContract, operation: string, event: ContractEventName): Promise<Sub> {
|
||||||
// Make sure our runner can actually subscribe to events
|
// Make sure our runner can actually subscribe to events
|
||||||
const provider = getProvider(contract.runner);
|
const provider = getProvider(contract.runner);
|
||||||
if (!provider) {
|
assert(provider, "contract runner does not support subscribing",
|
||||||
return throwError("contract runner does not support subscribing", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation });
|
||||||
operation: "on"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const { fragment, tag, topics } = await getSubTag(contract, event);
|
const { fragment, tag, topics } = await getSubInfo(contract, event);
|
||||||
|
|
||||||
const { addr, subs } = getInternal(contract);
|
const { addr, subs } = getInternal(contract);
|
||||||
|
|
||||||
@ -414,8 +418,26 @@ async function getSub(contract: BaseContract, event: ContractEventName): Promise
|
|||||||
const address: string | Addressable = (addr ? addr: contract);
|
const address: string | Addressable = (addr ? addr: contract);
|
||||||
const filter = { address, topics };
|
const filter = { address, topics };
|
||||||
const listener = (log: Log) => {
|
const listener = (log: Log) => {
|
||||||
const payload = new ContractEventPayload(contract, null, event, fragment, log);
|
let foundFragment = fragment;
|
||||||
emit(contract, event, payload.args, payload);
|
if (foundFragment == null) {
|
||||||
|
try {
|
||||||
|
foundFragment = contract.interface.getEvent(log.topics[0]);
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
// If fragment is null, we do not deconstruct the args to emit
|
||||||
|
|
||||||
|
if (foundFragment) {
|
||||||
|
const _foundFragment = foundFragment;
|
||||||
|
const args = fragment ? contract.interface.decodeEventLog(fragment, log.data, log.topics): [ ];
|
||||||
|
emit(contract, event, args, (listener: null | Listener) => {
|
||||||
|
return new ContractEventPayload(contract, listener, event, _foundFragment, log);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
emit(contract, event, [ ], (listener: null | Listener) => {
|
||||||
|
return new ContractUnknownEventPayload(contract, listener, event, log);
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let started = false;
|
let started = false;
|
||||||
@ -440,7 +462,9 @@ async function getSub(contract: BaseContract, event: ContractEventName): Promise
|
|||||||
// notice to the event queu using setTimeout).
|
// notice to the event queu using setTimeout).
|
||||||
let lastEmit: Promise<any> = Promise.resolve();
|
let lastEmit: Promise<any> = Promise.resolve();
|
||||||
|
|
||||||
async function _emit(contract: BaseContract, event: ContractEventName, args: Array<any>, payload: null | ContractEventPayload): Promise<boolean> {
|
type PayloadFunc = (listener: null | Listener) => ContractUnknownEventPayload;
|
||||||
|
|
||||||
|
async function _emit(contract: BaseContract, event: ContractEventName, args: Array<any>, payloadFunc: null | PayloadFunc): Promise<boolean> {
|
||||||
await lastEmit;
|
await lastEmit;
|
||||||
|
|
||||||
const sub = await hasSub(contract, event);
|
const sub = await hasSub(contract, event);
|
||||||
@ -449,9 +473,8 @@ async function _emit(contract: BaseContract, event: ContractEventName, args: Arr
|
|||||||
const count = sub.listeners.length;
|
const count = sub.listeners.length;
|
||||||
sub.listeners = sub.listeners.filter(({ listener, once }) => {
|
sub.listeners = sub.listeners.filter(({ listener, once }) => {
|
||||||
const passArgs = args.slice();
|
const passArgs = args.slice();
|
||||||
if (payload) {
|
if (payloadFunc) {
|
||||||
passArgs.push(new ContractEventPayload(contract, (once ? null: listener),
|
passArgs.push(payloadFunc(once ? null: listener));
|
||||||
event, payload.fragment, payload.log));
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
listener.call(contract, ...passArgs);
|
listener.call(contract, ...passArgs);
|
||||||
@ -461,12 +484,12 @@ async function _emit(contract: BaseContract, event: ContractEventName, args: Arr
|
|||||||
return (count > 0);
|
return (count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function emit(contract: BaseContract, event: ContractEventName, args: Array<any>, payload: null | ContractEventPayload): Promise<boolean> {
|
async function emit(contract: BaseContract, event: ContractEventName, args: Array<any>, payloadFunc: null | PayloadFunc): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await lastEmit;
|
await lastEmit;
|
||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
|
|
||||||
const resultPromise = _emit(contract, event, args, payload);
|
const resultPromise = _emit(contract, event, args, payloadFunc);
|
||||||
lastEmit = resultPromise;
|
lastEmit = resultPromise;
|
||||||
return await resultPromise;
|
return await resultPromise;
|
||||||
}
|
}
|
||||||
@ -564,17 +587,19 @@ export class BaseContract implements Addressable, EventEmitterable<ContractEvent
|
|||||||
throw new Error(`unknown contract method: ${ prop }`);
|
throw new Error(`unknown contract method: ${ prop }`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(runner: null | ContractRunner): BaseContract {
|
||||||
|
return new BaseContract(this.target, this.interface, runner);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAddress(): Promise<string> { return await getInternal(this).addrPromise; }
|
async getAddress(): Promise<string> { return await getInternal(this).addrPromise; }
|
||||||
|
|
||||||
async getDeployedCode(): Promise<null | string> {
|
async getDeployedCode(): Promise<null | string> {
|
||||||
const provider = getProvider(this.runner);
|
const provider = getProvider(this.runner);
|
||||||
if (!provider) {
|
assert(provider, "runner does not support .provider",
|
||||||
return throwError("runner does not support .provider", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "getDeployedCode" });
|
||||||
operation: "getDeployedCode"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const code = await provider.getCode(await this.getAddress());
|
const code = await provider.getCode(await this.getAddress());
|
||||||
if (code === "0x") { return null; }
|
if (code === "0x") { return null; }
|
||||||
@ -595,11 +620,8 @@ export class BaseContract implements Addressable, EventEmitterable<ContractEvent
|
|||||||
|
|
||||||
// Make sure we can subscribe to a provider event
|
// Make sure we can subscribe to a provider event
|
||||||
const provider = getProvider(this.runner);
|
const provider = getProvider(this.runner);
|
||||||
if (provider == null) {
|
assert(provider != null, "contract runner does not support .provider",
|
||||||
return throwError("contract runner does not support .provider", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "waitForDeployment" });
|
||||||
operation: "waitForDeployment"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const checkCode = async () => {
|
const checkCode = async () => {
|
||||||
@ -634,33 +656,41 @@ export class BaseContract implements Addressable, EventEmitterable<ContractEvent
|
|||||||
throw new Error("@TODO");
|
throw new Error("@TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
async queryFilter(event: ContractEventName, fromBlock: BlockTag = 0, toBlock: BlockTag = "latest"): Promise<Array<EventLog>> {
|
async queryFilter(event: ContractEventName, fromBlock: BlockTag = 0, toBlock: BlockTag = "latest"): Promise<Array<EventLog | Log>> {
|
||||||
const { addr, addrPromise } = getInternal(this);
|
const { addr, addrPromise } = getInternal(this);
|
||||||
const address = (addr ? addr: (await addrPromise));
|
const address = (addr ? addr: (await addrPromise));
|
||||||
const { fragment, topics } = await getSubTag(this, event);
|
const { fragment, topics } = await getSubInfo(this, event);
|
||||||
const filter = { address, topics, fromBlock, toBlock };
|
const filter = { address, topics, fromBlock, toBlock };
|
||||||
|
|
||||||
const provider = getProvider(this.runner);
|
const provider = getProvider(this.runner);
|
||||||
if (!provider) {
|
assert(provider, "contract runner does not have a provider",
|
||||||
return throwError("contract runner does not have a provider", "UNSUPPORTED_OPERATION", {
|
"UNSUPPORTED_OPERATION", { operation: "queryFilter" });
|
||||||
operation: "queryFilter"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return (await provider.getLogs(filter)).map((log) => {
|
return (await provider.getLogs(filter)).map((log) => {
|
||||||
return new EventLog(log, this.interface, fragment);
|
let foundFragment = fragment;
|
||||||
|
if (foundFragment == null) {
|
||||||
|
try {
|
||||||
|
foundFragment = this.interface.getEvent(log.topics[0]);
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundFragment) {
|
||||||
|
return new EventLog(log, this.interface, foundFragment);
|
||||||
|
} else {
|
||||||
|
return new Log(log, provider);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async on(event: ContractEventName, listener: Listener): Promise<this> {
|
async on(event: ContractEventName, listener: Listener): Promise<this> {
|
||||||
const sub = await getSub(this, event);
|
const sub = await getSub(this, "on", event);
|
||||||
sub.listeners.push({ listener, once: false });
|
sub.listeners.push({ listener, once: false });
|
||||||
sub.start();
|
sub.start();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
async once(event: ContractEventName, listener: Listener): Promise<this> {
|
async once(event: ContractEventName, listener: Listener): Promise<this> {
|
||||||
const sub = await getSub(this, event);
|
const sub = await getSub(this, "once", event);
|
||||||
sub.listeners.push({ listener, once: true });
|
sub.listeners.push({ listener, once: true });
|
||||||
sub.start();
|
sub.start();
|
||||||
return this;
|
return this;
|
||||||
|
@ -9,7 +9,7 @@ import type { ContractTransactionResponse } from "./wrappers.js";
|
|||||||
|
|
||||||
|
|
||||||
// The types of events a Contract can listen for
|
// The types of events a Contract can listen for
|
||||||
export type ContractEventName = string | ContractEvent | TopicFilter;
|
export type ContractEventName = string | ContractEvent | TopicFilter | DeferredTopicFilter;
|
||||||
|
|
||||||
export interface ContractInterface {
|
export interface ContractInterface {
|
||||||
[ name: string ]: BaseContractMethod;
|
[ name: string ]: BaseContractMethod;
|
||||||
|
@ -64,25 +64,12 @@ export class ContractTransactionResponse extends TransactionResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ContractEventPayload extends EventPayload<ContractEventName> {
|
export class ContractUnknownEventPayload extends EventPayload<ContractEventName> {
|
||||||
|
readonly log!: Log;
|
||||||
|
|
||||||
readonly fragment!: EventFragment;
|
constructor(contract: BaseContract, listener: null | Listener, filter: ContractEventName, log: Log) {
|
||||||
readonly log!: EventLog;
|
|
||||||
readonly args!: Result;
|
|
||||||
|
|
||||||
constructor(contract: BaseContract, listener: null | Listener, filter: ContractEventName, fragment: EventFragment, _log: Log) {
|
|
||||||
super(contract, listener, filter);
|
super(contract, listener, filter);
|
||||||
const log = new EventLog(_log, contract.interface, fragment);
|
defineProperties<ContractUnknownEventPayload>(this, { log });
|
||||||
const args = contract.interface.decodeEventLog(fragment, log.data, log.topics);
|
|
||||||
defineProperties<ContractEventPayload>(this, { args, fragment, log });
|
|
||||||
}
|
|
||||||
|
|
||||||
get eventName(): string {
|
|
||||||
return this.fragment.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
get eventSignature(): string {
|
|
||||||
return this.fragment.format();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlock(): Promise<Block<string>> {
|
async getBlock(): Promise<Block<string>> {
|
||||||
@ -97,3 +84,24 @@ export class ContractEventPayload extends EventPayload<ContractEventName> {
|
|||||||
return await this.log.getTransactionReceipt();
|
return await this.log.getTransactionReceipt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ContractEventPayload extends ContractUnknownEventPayload {
|
||||||
|
|
||||||
|
declare readonly fragment: EventFragment;
|
||||||
|
declare readonly log: EventLog;
|
||||||
|
declare readonly args: Result;
|
||||||
|
|
||||||
|
constructor(contract: BaseContract, listener: null | Listener, filter: ContractEventName, fragment: EventFragment, _log: Log) {
|
||||||
|
super(contract, listener, filter, new EventLog(_log, contract.interface, fragment));
|
||||||
|
const args = contract.interface.decodeEventLog(fragment, this.log.data, this.log.topics);
|
||||||
|
defineProperties<ContractEventPayload>(this, { args, fragment });
|
||||||
|
}
|
||||||
|
|
||||||
|
get eventName(): string {
|
||||||
|
return this.fragment.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
get eventSignature(): string {
|
||||||
|
return this.fragment.format();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user