diff --git a/.changeset/three-schools-peel.md b/.changeset/three-schools-peel.md new file mode 100644 index 000000000..ff5df3667 --- /dev/null +++ b/.changeset/three-schools-peel.md @@ -0,0 +1,6 @@ +--- +'@typechain/ethers-v5': minor +'typechain': minor +--- + +fix tuples in event signatures and also arrays of tuples in functions diff --git a/contracts/v0.6.4/DataTypesInput.sol b/contracts/v0.6.4/DataTypesInput.sol index 8165c8786..c011605df 100644 --- a/contracts/v0.6.4/DataTypesInput.sol +++ b/contracts/v0.6.4/DataTypesInput.sol @@ -101,6 +101,10 @@ contract DataTypesInput { info2.a = address(info1.a); info2.b = address(info1.b); } + + event event_struct(Struct1 input); + + event event_struct_2(uint256 input, Struct1 input2); } library StructsLib1 { diff --git a/contracts/v0.6.4/Events.sol b/contracts/v0.6.4/Events.sol index 7be2489b4..d9f22afdf 100644 --- a/contracts/v0.6.4/Events.sol +++ b/contracts/v0.6.4/Events.sol @@ -45,5 +45,11 @@ contract Events { emit Event4(EventData(2, "test")); } + event Event5(EventData[2] data); + + function emit_event5() public { + emit Event5([EventData(2, "test"), EventData(3, "test2")]); + } + event NoArgsEvent(); } diff --git a/packages/target-ethers-v5-test/test/DataTypesInput.test.ts b/packages/target-ethers-v5-test/test/DataTypesInput.test.ts index a3d229559..e110552d4 100644 --- a/packages/target-ethers-v5-test/test/DataTypesInput.test.ts +++ b/packages/target-ethers-v5-test/test/DataTypesInput.test.ts @@ -1,4 +1,4 @@ -import type { FunctionFragment } from '@ethersproject/abi' +import type { EventFragment, FunctionFragment } from '@ethersproject/abi' import { expect } from 'earljs' import type { BigNumberish } from 'ethers' import { BigNumber, ethers } from 'ethers' @@ -79,12 +79,37 @@ describe('DataTypesInput', () => { typedAssert(await chain.contract.input_enum(1), 1) }) - it('generates correct signature for tuples', () => { + it('generates correct function signature for tuples', () => { const fragment: FunctionFragment = chain.contract.interface.functions['input_struct((uint256,uint256))'] // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition expect(fragment !== undefined).toEqual(true) }) + it('generates correct function signature for tuples arrays', () => { + const fragment: FunctionFragment = chain.contract.interface.functions['input_struct3_array((uint256[])[])'] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + expect(fragment !== undefined).toEqual(true) + }) + + it('generates correct function signature for tuples with fixed length', () => { + const fragment: FunctionFragment = + chain.contract.interface.functions['input_struct2_tuple((uint256,(uint256,uint256))[3])'] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + expect(fragment !== undefined).toEqual(true) + }) + + it('generate correct event signature for tuples', () => { + const fragment: EventFragment = chain.contract.interface.events['event_struct((uint256,uint256))'] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + expect(fragment !== undefined).toEqual(true) + }) + + it('generate correct event signature for mix of arguments and tuples', () => { + const fragment: EventFragment = chain.contract.interface.events['event_struct_2(uint256,(uint256,uint256))'] + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + expect(fragment !== undefined).toEqual(true) + }) + // tests: https://github.com/ethereum-ts/TypeChain/issues/232 // NOTE: typesAssert is too simple to tests type compatibility here so we can't use it it('generates correct types for tuples', () => { diff --git a/packages/target-ethers-v5-test/test/Events.test.ts b/packages/target-ethers-v5-test/test/Events.test.ts index 80a2419a8..00582b71f 100644 --- a/packages/target-ethers-v5-test/test/Events.test.ts +++ b/packages/target-ethers-v5-test/test/Events.test.ts @@ -33,6 +33,8 @@ describe('Events', () => { const filter = contract.filters.Event1(null, null) const results = await contract.queryFilter(filter) + + typedAssert(results.length, 1) results.map((r) => { typedAssert(r.args.value1, BigNumber.from(1)) typedAssert(r.args.value2, BigNumber.from(2)) @@ -41,6 +43,20 @@ describe('Events', () => { }) }) + it('queryFilter with tuples and arrays', async () => { + await contract.emit_event5() + + const filter = contract.filters.Event5(null) + const results = await contract.queryFilter(filter) + typedAssert(results.length, 1) + results.map((r) => { + typedAssert(r.args[0][0][0], BigNumber.from(2)) + typedAssert(r.args[0][0][1], 'test') + typedAssert(r.args[0][1][0], BigNumber.from(3)) + typedAssert(r.args[0][1][1], 'test2') + }) + }) + it('queryFilter without params', async () => { await contract.emit_event1() diff --git a/packages/target-ethers-v5-test/types/factories/v0.6.4/DataTypesInput__factory.ts b/packages/target-ethers-v5-test/types/factories/v0.6.4/DataTypesInput__factory.ts index 275ce186d..abf17e8ba 100644 --- a/packages/target-ethers-v5-test/types/factories/v0.6.4/DataTypesInput__factory.ts +++ b/packages/target-ethers-v5-test/types/factories/v0.6.4/DataTypesInput__factory.ts @@ -10,6 +10,62 @@ import type { } from "../../v0.6.4/DataTypesInput"; const _abi = [ + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "uint256_0", + type: "uint256", + }, + { + internalType: "uint256", + name: "uint256_1", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct DataTypesInput.Struct1", + name: "input", + type: "tuple", + }, + ], + name: "event_struct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "input", + type: "uint256", + }, + { + components: [ + { + internalType: "uint256", + name: "uint256_0", + type: "uint256", + }, + { + internalType: "uint256", + name: "uint256_1", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct DataTypesInput.Struct1", + name: "input2", + type: "tuple", + }, + ], + name: "event_struct_2", + type: "event", + }, { inputs: [ { diff --git a/packages/target-ethers-v5-test/types/factories/v0.6.4/Events__factory.ts b/packages/target-ethers-v5-test/types/factories/v0.6.4/Events__factory.ts index 14d9a8cb1..d1114640e 100644 --- a/packages/target-ethers-v5-test/types/factories/v0.6.4/Events__factory.ts +++ b/packages/target-ethers-v5-test/types/factories/v0.6.4/Events__factory.ts @@ -109,6 +109,31 @@ const _abi = [ name: "Event4", type: "event", }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + ], + indexed: false, + internalType: "struct Events.EventData[2]", + name: "data", + type: "tuple[2]", + }, + ], + name: "Event5", + type: "event", + }, { anonymous: false, inputs: [], @@ -176,6 +201,13 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "emit_event5", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, ] as const; export class Events__factory { diff --git a/packages/target-ethers-v5-test/types/v0.6.4/DataTypesInput.ts b/packages/target-ethers-v5-test/types/v0.6.4/DataTypesInput.ts index a14041bcd..f21c51a93 100644 --- a/packages/target-ethers-v5-test/types/v0.6.4/DataTypesInput.ts +++ b/packages/target-ethers-v5-test/types/v0.6.4/DataTypesInput.ts @@ -11,7 +11,11 @@ import type { Signer, utils, } from "ethers"; -import type { FunctionFragment, Result } from "@ethersproject/abi"; +import type { + FunctionFragment, + Result, + EventFragment, +} from "@ethersproject/abi"; import type { Listener, Provider } from "@ethersproject/providers"; import type { TypedEventFilter, @@ -20,21 +24,6 @@ import type { OnEvent, } from "../common"; -export declare namespace StructsLib1 { - export type InfoStruct = { a: BigNumberish; b: BigNumberish }; - - export type InfoStructOutput = [BigNumber, BigNumber] & { - a: BigNumber; - b: BigNumber; - }; -} - -export declare namespace StructsLib2 { - export type InfoStruct = { a: string; b: string }; - - export type InfoStructOutput = [string, string] & { a: string; b: string }; -} - export declare namespace DataTypesInput { export type Struct1Struct = { uint256_0: BigNumberish; @@ -61,6 +50,21 @@ export declare namespace DataTypesInput { export type Struct3StructOutput = [BigNumber[]] & { input1: BigNumber[] }; } +export declare namespace StructsLib1 { + export type InfoStruct = { a: BigNumberish; b: BigNumberish }; + + export type InfoStructOutput = [BigNumber, BigNumber] & { + a: BigNumber; + b: BigNumber; + }; +} + +export declare namespace StructsLib2 { + export type InfoStruct = { a: string; b: string }; + + export type InfoStructOutput = [string, string] & { a: string; b: string }; +} + export interface DataTypesInputInterface extends utils.Interface { functions: { "input_address(address)": FunctionFragment; @@ -77,16 +81,16 @@ export interface DataTypesInputInterface extends utils.Interface { "input_struct((uint256,uint256))": FunctionFragment; "input_struct2((uint256,(uint256,uint256)))": FunctionFragment; "input_struct2_array((uint256,(uint256,uint256))[])": FunctionFragment; - "input_struct2_tuple(tuple[3])": FunctionFragment; + "input_struct2_tuple((uint256,(uint256,uint256))[3])": FunctionFragment; "input_struct3_array((uint256[])[])": FunctionFragment; "input_struct_array((uint256,uint256)[])": FunctionFragment; - "input_struct_array_array(tuple[][])": FunctionFragment; - "input_struct_array_array_array(tuple[][][])": FunctionFragment; - "input_struct_array_fixedarray(tuple[][2])": FunctionFragment; - "input_struct_fixedarray_array(tuple[2][])": FunctionFragment; - "input_struct_fixedarray_array_fixedarray(tuple[2][][3])": FunctionFragment; - "input_struct_fixedarray_array_fixedarray_array_fixedarray(tuple[2][][3][][4])": FunctionFragment; - "input_struct_fixedarray_fixedarray(tuple[2][3])": FunctionFragment; + "input_struct_array_array((uint256,uint256)[][])": FunctionFragment; + "input_struct_array_array_array((uint256,uint256)[][][])": FunctionFragment; + "input_struct_array_fixedarray((uint256,uint256)[][2])": FunctionFragment; + "input_struct_fixedarray_array((uint256,uint256)[2][])": FunctionFragment; + "input_struct_fixedarray_array_fixedarray((uint256,uint256)[2][][3])": FunctionFragment; + "input_struct_fixedarray_array_fixedarray_array_fixedarray((uint256,uint256)[2][][3][][4])": FunctionFragment; + "input_struct_fixedarray_fixedarray((uint256,uint256)[2][3])": FunctionFragment; "input_tuple(uint256,uint256)": FunctionFragment; "input_uint256(uint256)": FunctionFragment; "input_uint8(uint8)": FunctionFragment; @@ -387,8 +391,35 @@ export interface DataTypesInputInterface extends utils.Interface { data: BytesLike ): Result; - events: {}; + events: { + "event_struct((uint256,uint256))": EventFragment; + "event_struct_2(uint256,(uint256,uint256))": EventFragment; + }; + + getEvent(nameOrSignatureOrTopic: "event_struct"): EventFragment; + getEvent(nameOrSignatureOrTopic: "event_struct_2"): EventFragment; +} + +export interface event_structEventObject { + input: DataTypesInput.Struct1StructOutput; +} +export type event_structEvent = TypedEvent< + [DataTypesInput.Struct1StructOutput], + event_structEventObject +>; + +export type event_structEventFilter = TypedEventFilter; + +export interface event_struct_2EventObject { + input: BigNumber; + input2: DataTypesInput.Struct1StructOutput; } +export type event_struct_2Event = TypedEvent< + [BigNumber, DataTypesInput.Struct1StructOutput], + event_struct_2EventObject +>; + +export type event_struct_2EventFilter = TypedEventFilter; export interface DataTypesInput extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; @@ -1237,7 +1268,16 @@ export interface DataTypesInput extends BaseContract { ): Promise; }; - filters: {}; + filters: { + "event_struct((uint256,uint256))"(input?: null): event_structEventFilter; + event_struct(input?: null): event_structEventFilter; + + "event_struct_2(uint256,(uint256,uint256))"( + input?: null, + input2?: null + ): event_struct_2EventFilter; + event_struct_2(input?: null, input2?: null): event_struct_2EventFilter; + }; estimateGas: { input_address( diff --git a/packages/target-ethers-v5-test/types/v0.6.4/Events.ts b/packages/target-ethers-v5-test/types/v0.6.4/Events.ts index 379a5140e..1ae178025 100644 --- a/packages/target-ethers-v5-test/types/v0.6.4/Events.ts +++ b/packages/target-ethers-v5-test/types/v0.6.4/Events.ts @@ -43,6 +43,7 @@ export interface EventsInterface extends utils.Interface { "emit_event3()": FunctionFragment; "emit_event3_overloaded()": FunctionFragment; "emit_event4()": FunctionFragment; + "emit_event5()": FunctionFragment; }; getFunction( @@ -53,6 +54,7 @@ export interface EventsInterface extends utils.Interface { | "emit_event3" | "emit_event3_overloaded" | "emit_event4" + | "emit_event5" ): FunctionFragment; encodeFunctionData( @@ -79,6 +81,10 @@ export interface EventsInterface extends utils.Interface { functionFragment: "emit_event4", values?: undefined ): string; + encodeFunctionData( + functionFragment: "emit_event5", + values?: undefined + ): string; decodeFunctionResult(functionFragment: "emit_anon1", data: BytesLike): Result; decodeFunctionResult( @@ -101,6 +107,10 @@ export interface EventsInterface extends utils.Interface { functionFragment: "emit_event4", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "emit_event5", + data: BytesLike + ): Result; events: { "AnonEvent1(uint256)": EventFragment; @@ -108,7 +118,8 @@ export interface EventsInterface extends utils.Interface { "Event2(uint256)": EventFragment; "Event3(bool,uint256)": EventFragment; "Event3(uint256)": EventFragment; - "Event4(tuple)": EventFragment; + "Event4((uint256,string))": EventFragment; + "Event5((uint256,string)[2])": EventFragment; "NoArgsEvent()": EventFragment; "UpdateFrequencySet(address[],uint256[])": EventFragment; }; @@ -119,6 +130,7 @@ export interface EventsInterface extends utils.Interface { getEvent(nameOrSignatureOrTopic: "Event3(bool,uint256)"): EventFragment; getEvent(nameOrSignatureOrTopic: "Event3(uint256)"): EventFragment; getEvent(nameOrSignatureOrTopic: "Event4"): EventFragment; + getEvent(nameOrSignatureOrTopic: "Event5"): EventFragment; getEvent(nameOrSignatureOrTopic: "NoArgsEvent"): EventFragment; getEvent(nameOrSignatureOrTopic: "UpdateFrequencySet"): EventFragment; } @@ -177,6 +189,16 @@ export type Event4Event = TypedEvent< export type Event4EventFilter = TypedEventFilter; +export interface Event5EventObject { + data: [Events.EventDataStructOutput, Events.EventDataStructOutput]; +} +export type Event5Event = TypedEvent< + [[Events.EventDataStructOutput, Events.EventDataStructOutput]], + Event5EventObject +>; + +export type Event5EventFilter = TypedEventFilter; + export interface NoArgsEventEventObject {} export type NoArgsEventEvent = TypedEvent<[], NoArgsEventEventObject>; @@ -244,6 +266,10 @@ export interface Events extends BaseContract { emit_event4( overrides?: Overrides & { from?: string } ): Promise; + + emit_event5( + overrides?: Overrides & { from?: string } + ): Promise; }; emit_anon1( @@ -270,6 +296,10 @@ export interface Events extends BaseContract { overrides?: Overrides & { from?: string } ): Promise; + emit_event5( + overrides?: Overrides & { from?: string } + ): Promise; + callStatic: { emit_anon1(overrides?: CallOverrides): Promise; @@ -282,6 +312,8 @@ export interface Events extends BaseContract { emit_event3_overloaded(overrides?: CallOverrides): Promise; emit_event4(overrides?: CallOverrides): Promise; + + emit_event5(overrides?: CallOverrides): Promise; }; filters: { @@ -303,9 +335,12 @@ export interface Events extends BaseContract { ): Event3_bool_uint256_EventFilter; "Event3(uint256)"(value1?: BigNumberish | null): Event3_uint256_EventFilter; - "Event4(tuple)"(data?: null): Event4EventFilter; + "Event4((uint256,string))"(data?: null): Event4EventFilter; Event4(data?: null): Event4EventFilter; + "Event5((uint256,string)[2])"(data?: null): Event5EventFilter; + Event5(data?: null): Event5EventFilter; + "NoArgsEvent()"(): NoArgsEventEventFilter; NoArgsEvent(): NoArgsEventEventFilter; @@ -330,6 +365,8 @@ export interface Events extends BaseContract { ): Promise; emit_event4(overrides?: Overrides & { from?: string }): Promise; + + emit_event5(overrides?: Overrides & { from?: string }): Promise; }; populateTransaction: { @@ -356,5 +393,9 @@ export interface Events extends BaseContract { emit_event4( overrides?: Overrides & { from?: string } ): Promise; + + emit_event5( + overrides?: Overrides & { from?: string } + ): Promise; }; } diff --git a/packages/target-ethers-v5-test/types/v0.8.9/KingOfTheHill/KingOfTheHill.ts b/packages/target-ethers-v5-test/types/v0.8.9/KingOfTheHill/KingOfTheHill.ts index bd75bf6fe..fea251c5e 100644 --- a/packages/target-ethers-v5-test/types/v0.8.9/KingOfTheHill/KingOfTheHill.ts +++ b/packages/target-ethers-v5-test/types/v0.8.9/KingOfTheHill/KingOfTheHill.ts @@ -59,7 +59,7 @@ export interface KingOfTheHillInterface extends utils.Interface { decodeFunctionResult(functionFragment: "withdraw", data: BytesLike): Result; events: { - "HighestBidIncreased(tuple)": EventFragment; + "HighestBidIncreased((address,uint256))": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HighestBidIncreased"): EventFragment; @@ -139,7 +139,9 @@ export interface KingOfTheHill extends BaseContract { }; filters: { - "HighestBidIncreased(tuple)"(bid?: null): HighestBidIncreasedEventFilter; + "HighestBidIncreased((address,uint256))"( + bid?: null + ): HighestBidIncreasedEventFilter; HighestBidIncreased(bid?: null): HighestBidIncreasedEventFilter; }; diff --git a/packages/target-ethers-v5/src/codegen/events.ts b/packages/target-ethers-v5/src/codegen/events.ts index d7ba01ac7..3751d7416 100644 --- a/packages/target-ethers-v5/src/codegen/events.ts +++ b/packages/target-ethers-v5/src/codegen/events.ts @@ -3,6 +3,7 @@ import { EventArgDeclaration, EventDeclaration, getFullSignatureAsSymbolForEvent, + getFullSignatureForEvent, } from 'typechain' import { generateInputType, generateOutputComplexTypeAsArray, generateOutputComplexTypesAsObject } from './types' @@ -55,7 +56,7 @@ export function generateInterfaceEventDescription(event: EventDeclaration): stri } export function generateEventSignature(event: EventDeclaration): string { - return `${event.name}(${event.inputs.map((input: any) => input.type.originalType).join(',')})` + return getFullSignatureForEvent(event) } export function generateEventInputs(eventArgs: EventArgDeclaration[]) { diff --git a/packages/target-ethers-v6-test/test/Events.test.ts b/packages/target-ethers-v6-test/test/Events.test.ts index 4340e4028..1ee7a1c13 100644 --- a/packages/target-ethers-v6-test/test/Events.test.ts +++ b/packages/target-ethers-v6-test/test/Events.test.ts @@ -49,6 +49,20 @@ describe('Events', () => { }) }) + it('queryFilter ith tuples and arrays', async () => { + await contract.emit_event5() + + const filter = contract.filters.Event5() + const results = await contract.queryFilter(filter) + typedAssert(results.length, 1) + results.map((r) => { + typedAssert(r.args[0][0][0], BigInt(2)) + typedAssert(r.args[0][0][1], 'test') + typedAssert(r.args[0][1][0], BigInt(3)) + typedAssert(r.args[0][1][1], 'test2') + }) + }) + it('contract.on', async () => { const filter = contract.filters.Event1(undefined, undefined) await contract.queryFilter(filter) diff --git a/packages/target-ethers-v6-test/types/factories/v0.6.4/DataTypesInput__factory.ts b/packages/target-ethers-v6-test/types/factories/v0.6.4/DataTypesInput__factory.ts index 5a0caa8d9..ad9809204 100644 --- a/packages/target-ethers-v6-test/types/factories/v0.6.4/DataTypesInput__factory.ts +++ b/packages/target-ethers-v6-test/types/factories/v0.6.4/DataTypesInput__factory.ts @@ -9,6 +9,62 @@ import type { } from "../../v0.6.4/DataTypesInput"; const _abi = [ + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "uint256_0", + type: "uint256", + }, + { + internalType: "uint256", + name: "uint256_1", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct DataTypesInput.Struct1", + name: "input", + type: "tuple", + }, + ], + name: "event_struct", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "input", + type: "uint256", + }, + { + components: [ + { + internalType: "uint256", + name: "uint256_0", + type: "uint256", + }, + { + internalType: "uint256", + name: "uint256_1", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct DataTypesInput.Struct1", + name: "input2", + type: "tuple", + }, + ], + name: "event_struct_2", + type: "event", + }, { inputs: [ { diff --git a/packages/target-ethers-v6-test/types/factories/v0.6.4/Events__factory.ts b/packages/target-ethers-v6-test/types/factories/v0.6.4/Events__factory.ts index 3906f8657..049499b28 100644 --- a/packages/target-ethers-v6-test/types/factories/v0.6.4/Events__factory.ts +++ b/packages/target-ethers-v6-test/types/factories/v0.6.4/Events__factory.ts @@ -108,6 +108,31 @@ const _abi = [ name: "Event4", type: "event", }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "string", + name: "name", + type: "string", + }, + ], + indexed: false, + internalType: "struct Events.EventData[2]", + name: "data", + type: "tuple[2]", + }, + ], + name: "Event5", + type: "event", + }, { anonymous: false, inputs: [], @@ -175,6 +200,13 @@ const _abi = [ stateMutability: "nonpayable", type: "function", }, + { + inputs: [], + name: "emit_event5", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, ] as const; export class Events__factory { diff --git a/packages/target-ethers-v6-test/types/v0.6.4/DataTypesInput.ts b/packages/target-ethers-v6-test/types/v0.6.4/DataTypesInput.ts index d3bc78f1d..28a3dfec1 100644 --- a/packages/target-ethers-v6-test/types/v0.6.4/DataTypesInput.ts +++ b/packages/target-ethers-v6-test/types/v0.6.4/DataTypesInput.ts @@ -8,6 +8,7 @@ import type { FunctionFragment, Result, Interface, + EventFragment, AddressLike, ContractRunner, ContractMethod, @@ -17,28 +18,11 @@ import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, + TypedLogDescription, TypedListener, TypedContractMethod, } from "../common"; -export declare namespace StructsLib1 { - export type InfoStruct = { a: BigNumberish; b: BigNumberish }; - - export type InfoStructOutput = [a: bigint, b: bigint] & { - a: bigint; - b: bigint; - }; -} - -export declare namespace StructsLib2 { - export type InfoStruct = { a: AddressLike; b: AddressLike }; - - export type InfoStructOutput = [a: string, b: string] & { - a: string; - b: string; - }; -} - export declare namespace DataTypesInput { export type Struct1Struct = { uint256_0: BigNumberish; @@ -65,6 +49,24 @@ export declare namespace DataTypesInput { export type Struct3StructOutput = [input1: bigint[]] & { input1: bigint[] }; } +export declare namespace StructsLib1 { + export type InfoStruct = { a: BigNumberish; b: BigNumberish }; + + export type InfoStructOutput = [a: bigint, b: bigint] & { + a: bigint; + b: bigint; + }; +} + +export declare namespace StructsLib2 { + export type InfoStruct = { a: AddressLike; b: AddressLike }; + + export type InfoStructOutput = [a: string, b: string] & { + a: string; + b: string; + }; +} + export interface DataTypesInputInterface extends Interface { getFunction( nameOrSignature: @@ -98,6 +100,10 @@ export interface DataTypesInputInterface extends Interface { | "input_uint_array" ): FunctionFragment; + getEvent( + nameOrSignatureOrTopic: "event_struct" | "event_struct_2" + ): EventFragment; + encodeFunctionData( functionFragment: "input_address", values: [AddressLike] @@ -361,6 +367,37 @@ export interface DataTypesInputInterface extends Interface { ): Result; } +export namespace event_structEvent { + export type InputTuple = [input: DataTypesInput.Struct1Struct]; + export type OutputTuple = [input: DataTypesInput.Struct1StructOutput]; + export interface OutputObject { + input: DataTypesInput.Struct1StructOutput; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace event_struct_2Event { + export type InputTuple = [ + input: BigNumberish, + input2: DataTypesInput.Struct1Struct + ]; + export type OutputTuple = [ + input: bigint, + input2: DataTypesInput.Struct1StructOutput + ]; + export interface OutputObject { + input: bigint; + input2: DataTypesInput.Struct1StructOutput; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + export interface DataTypesInput extends BaseContract { connect(runner?: ContractRunner | null): DataTypesInput; waitForDeployment(): Promise; @@ -997,5 +1034,42 @@ export interface DataTypesInput extends BaseContract { nameOrSignature: "input_uint_array" ): TypedContractMethod<[input1: BigNumberish[]], [bigint[]], "view">; - filters: {}; + getEvent( + key: "event_struct" + ): TypedContractEvent< + event_structEvent.InputTuple, + event_structEvent.OutputTuple, + event_structEvent.OutputObject + >; + getEvent( + key: "event_struct_2" + ): TypedContractEvent< + event_struct_2Event.InputTuple, + event_struct_2Event.OutputTuple, + event_struct_2Event.OutputObject + >; + + filters: { + "event_struct(tuple)": TypedContractEvent< + event_structEvent.InputTuple, + event_structEvent.OutputTuple, + event_structEvent.OutputObject + >; + event_struct: TypedContractEvent< + event_structEvent.InputTuple, + event_structEvent.OutputTuple, + event_structEvent.OutputObject + >; + + "event_struct_2(uint256,tuple)": TypedContractEvent< + event_struct_2Event.InputTuple, + event_struct_2Event.OutputTuple, + event_struct_2Event.OutputObject + >; + event_struct_2: TypedContractEvent< + event_struct_2Event.InputTuple, + event_struct_2Event.OutputTuple, + event_struct_2Event.OutputObject + >; + }; } diff --git a/packages/target-ethers-v6-test/types/v0.6.4/Events.ts b/packages/target-ethers-v6-test/types/v0.6.4/Events.ts index 5191061b7..13505d614 100644 --- a/packages/target-ethers-v6-test/types/v0.6.4/Events.ts +++ b/packages/target-ethers-v6-test/types/v0.6.4/Events.ts @@ -41,6 +41,7 @@ export interface EventsInterface extends Interface { | "emit_event3" | "emit_event3_overloaded" | "emit_event4" + | "emit_event5" ): FunctionFragment; getEvent( @@ -51,6 +52,7 @@ export interface EventsInterface extends Interface { | "Event3(bool,uint256)" | "Event3(uint256)" | "Event4" + | "Event5" | "NoArgsEvent" | "UpdateFrequencySet" ): EventFragment; @@ -79,6 +81,10 @@ export interface EventsInterface extends Interface { functionFragment: "emit_event4", values?: undefined ): string; + encodeFunctionData( + functionFragment: "emit_event5", + values?: undefined + ): string; decodeFunctionResult(functionFragment: "emit_anon1", data: BytesLike): Result; decodeFunctionResult( @@ -101,6 +107,10 @@ export interface EventsInterface extends Interface { functionFragment: "emit_event4", data: BytesLike ): Result; + decodeFunctionResult( + functionFragment: "emit_event5", + data: BytesLike + ): Result; } export namespace AnonEvent1Event { @@ -177,6 +187,22 @@ export namespace Event4Event { export type LogDescription = TypedLogDescription; } +export namespace Event5Event { + export type InputTuple = [ + data: [Events.EventDataStruct, Events.EventDataStruct] + ]; + export type OutputTuple = [ + data: [Events.EventDataStructOutput, Events.EventDataStructOutput] + ]; + export interface OutputObject { + data: [Events.EventDataStructOutput, Events.EventDataStructOutput]; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + export namespace NoArgsEventEvent { export type InputTuple = []; export type OutputTuple = []; @@ -255,6 +281,8 @@ export interface Events extends BaseContract { emit_event4: TypedContractMethod<[], [void], "nonpayable">; + emit_event5: TypedContractMethod<[], [void], "nonpayable">; + getFunction( key: string | FunctionFragment ): T; @@ -277,6 +305,9 @@ export interface Events extends BaseContract { getFunction( nameOrSignature: "emit_event4" ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "emit_event5" + ): TypedContractMethod<[], [void], "nonpayable">; getEvent( key: "AnonEvent1" @@ -320,6 +351,13 @@ export interface Events extends BaseContract { Event4Event.OutputTuple, Event4Event.OutputObject >; + getEvent( + key: "Event5" + ): TypedContractEvent< + Event5Event.InputTuple, + Event5Event.OutputTuple, + Event5Event.OutputObject + >; getEvent( key: "NoArgsEvent" ): TypedContractEvent< @@ -391,6 +429,17 @@ export interface Events extends BaseContract { Event4Event.OutputObject >; + "Event5(tuple[2])": TypedContractEvent< + Event5Event.InputTuple, + Event5Event.OutputTuple, + Event5Event.OutputObject + >; + Event5: TypedContractEvent< + Event5Event.InputTuple, + Event5Event.OutputTuple, + Event5Event.OutputObject + >; + "NoArgsEvent()": TypedContractEvent< NoArgsEventEvent.InputTuple, NoArgsEventEvent.OutputTuple, diff --git a/packages/target-truffle-v5-test/types/truffle-contracts/DataTypesInput.d.ts b/packages/target-truffle-v5-test/types/truffle-contracts/DataTypesInput.d.ts index f99a7ead4..9f75cb563 100644 --- a/packages/target-truffle-v5-test/types/truffle-contracts/DataTypesInput.d.ts +++ b/packages/target-truffle-v5-test/types/truffle-contracts/DataTypesInput.d.ts @@ -10,7 +10,25 @@ export interface DataTypesInputContract "new"(meta?: Truffle.TransactionDetails): Promise; } -type AllEvents = never; +export interface event_struct { + name: "event_struct"; + args: { + input: { uint256_0: BN; uint256_1: BN }; + 0: { uint256_0: BN; uint256_1: BN }; + }; +} + +export interface event_struct_2 { + name: "event_struct_2"; + args: { + input: BN; + input2: { uint256_0: BN; uint256_1: BN }; + 0: BN; + 1: { uint256_0: BN; uint256_1: BN }; + }; +} + +type AllEvents = event_struct | event_struct_2; export interface DataTypesInputInstance extends Truffle.ContractInstance { input_uint8( diff --git a/packages/target-truffle-v5-test/types/truffle-contracts/Events.d.ts b/packages/target-truffle-v5-test/types/truffle-contracts/Events.d.ts index 336a93c5d..9ac47719f 100644 --- a/packages/target-truffle-v5-test/types/truffle-contracts/Events.d.ts +++ b/packages/target-truffle-v5-test/types/truffle-contracts/Events.d.ts @@ -62,6 +62,14 @@ export interface Event4 { }; } +export interface Event5 { + name: "Event5"; + args: { + data: { index: BN; name: string }[]; + 0: { index: BN; name: string }[]; + }; +} + export interface NoArgsEvent { name: "NoArgsEvent"; args: {}; @@ -80,6 +88,7 @@ type AllEvents = | Event2 | Event3 | Event4 + | Event5 | NoArgsEvent | UpdateFrequencySet; @@ -138,6 +147,15 @@ export interface EventsInstance extends Truffle.ContractInstance { estimateGas(txDetails?: Truffle.TransactionDetails): Promise; }; + emit_event5: { + (txDetails?: Truffle.TransactionDetails): Promise< + Truffle.TransactionResponse + >; + call(txDetails?: Truffle.TransactionDetails): Promise; + sendTransaction(txDetails?: Truffle.TransactionDetails): Promise; + estimateGas(txDetails?: Truffle.TransactionDetails): Promise; + }; + methods: { emit_event1: { (txDetails?: Truffle.TransactionDetails): Promise< @@ -192,6 +210,15 @@ export interface EventsInstance extends Truffle.ContractInstance { sendTransaction(txDetails?: Truffle.TransactionDetails): Promise; estimateGas(txDetails?: Truffle.TransactionDetails): Promise; }; + + emit_event5: { + (txDetails?: Truffle.TransactionDetails): Promise< + Truffle.TransactionResponse + >; + call(txDetails?: Truffle.TransactionDetails): Promise; + sendTransaction(txDetails?: Truffle.TransactionDetails): Promise; + estimateGas(txDetails?: Truffle.TransactionDetails): Promise; + }; }; getPastEvents(event: string): Promise; diff --git a/packages/target-web3-v1-test/types/v0.6.4/DataTypesInput.ts b/packages/target-web3-v1-test/types/v0.6.4/DataTypesInput.ts index 19388318b..4ed94abe4 100644 --- a/packages/target-web3-v1-test/types/v0.6.4/DataTypesInput.ts +++ b/packages/target-web3-v1-test/types/v0.6.4/DataTypesInput.ts @@ -21,6 +21,17 @@ export interface EventOptions { topics?: string[]; } +export type event_struct = ContractEventLog<{ + input: [string, string]; + 0: [string, string]; +}>; +export type event_struct_2 = ContractEventLog<{ + input: string; + input2: [string, string]; + 0: string; + 1: [string, string]; +}>; + export interface DataTypesInput extends BaseContract { constructor( jsonInterface: any[], @@ -147,6 +158,32 @@ export interface DataTypesInput extends BaseContract { ): NonPayableTransactionObject; }; events: { + event_struct(cb?: Callback): EventEmitter; + event_struct( + options?: EventOptions, + cb?: Callback + ): EventEmitter; + + event_struct_2(cb?: Callback): EventEmitter; + event_struct_2( + options?: EventOptions, + cb?: Callback + ): EventEmitter; + allEvents(options?: EventOptions, cb?: Callback): EventEmitter; }; + + once(event: "event_struct", cb: Callback): void; + once( + event: "event_struct", + options: EventOptions, + cb: Callback + ): void; + + once(event: "event_struct_2", cb: Callback): void; + once( + event: "event_struct_2", + options: EventOptions, + cb: Callback + ): void; } diff --git a/packages/target-web3-v1-test/types/v0.6.4/Events.ts b/packages/target-web3-v1-test/types/v0.6.4/Events.ts index df8955d9d..103eaafce 100644 --- a/packages/target-web3-v1-test/types/v0.6.4/Events.ts +++ b/packages/target-web3-v1-test/types/v0.6.4/Events.ts @@ -48,6 +48,10 @@ export type Event4 = ContractEventLog<{ data: [string, string]; 0: [string, string]; }>; +export type Event5 = ContractEventLog<{ + data: [string, string][]; + 0: [string, string][]; +}>; export type NoArgsEvent = ContractEventLog<{}>; export type UpdateFrequencySet = ContractEventLog<{ 0: string[]; @@ -73,6 +77,8 @@ export interface Events extends BaseContract { emit_event3_overloaded(): NonPayableTransactionObject; emit_event4(): NonPayableTransactionObject; + + emit_event5(): NonPayableTransactionObject; }; events: { Event1(cb?: Callback): EventEmitter; @@ -96,6 +102,9 @@ export interface Events extends BaseContract { Event4(cb?: Callback): EventEmitter; Event4(options?: EventOptions, cb?: Callback): EventEmitter; + Event5(cb?: Callback): EventEmitter; + Event5(options?: EventOptions, cb?: Callback): EventEmitter; + NoArgsEvent(cb?: Callback): EventEmitter; NoArgsEvent( options?: EventOptions, @@ -120,6 +129,9 @@ export interface Events extends BaseContract { once(event: "Event4", cb: Callback): void; once(event: "Event4", options: EventOptions, cb: Callback): void; + once(event: "Event5", cb: Callback): void; + once(event: "Event5", options: EventOptions, cb: Callback): void; + once(event: "NoArgsEvent", cb: Callback): void; once( event: "NoArgsEvent", diff --git a/packages/typechain/src/utils/signatures.ts b/packages/typechain/src/utils/signatures.ts index e9717398d..dc387b5ff 100644 --- a/packages/typechain/src/utils/signatures.ts +++ b/packages/typechain/src/utils/signatures.ts @@ -1,4 +1,4 @@ -import { AbiParameter, EventDeclaration, FunctionDeclaration } from '../parser/abiParser' +import { AbiParameter, EventArgDeclaration, EventDeclaration, FunctionDeclaration } from '../parser/abiParser' import { ArrayType, TupleType } from '../parser/parseEvmType' export function getFullSignatureAsSymbolForEvent(event: EventDeclaration): string { @@ -14,19 +14,20 @@ export function getFullSignatureAsSymbolForEvent(event: EventDeclaration): strin } export function getFullSignatureForEvent(event: EventDeclaration): string { - return `${event.name}(${event.inputs.map((e) => e.type.originalType).join(',')})` + return `${event.name}(${event.inputs.map((e) => getArgumentForSignature(e)).join(',')})` } export function getIndexedSignatureForEvent(event: EventDeclaration): string { const indexedType = event.inputs.filter((e) => e.isIndexed) - return `${event.name}(${indexedType.map((e) => e.type.originalType).join(',')})` + return `${event.name}(${indexedType.map((e) => getArgumentForSignature(e)).join(',')})` } -export function getArgumentForSignature(argument: AbiParameter): string { +export function getArgumentForSignature(argument: EventArgDeclaration | AbiParameter): string { if (argument.type.originalType === 'tuple') { return `(${(argument.type as TupleType).components.map((i) => getArgumentForSignature(i)).join(',')})` - } else if (argument.type.originalType === 'tuple[]') { - return getArgumentForSignature({ name: '', type: (argument.type as ArrayType).itemType }) + '[]' + } else if (argument.type.originalType.startsWith('tuple')) { + const arr = argument.type as ArrayType + return `${getArgumentForSignature({ name: '', type: arr.itemType })}[${arr.size?.toString() || ''}]` } else { return argument.type.originalType }