@subsquid/evm-typegen 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/main.js CHANGED
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.run = void 0;
7
+ const abi_1 = require("@ethersproject/abi");
8
+ const util_internal_code_printer_1 = require("@subsquid/util-internal-code-printer");
7
9
  const commander_1 = require("commander");
8
- const process_1 = __importDefault(require("process"));
9
- const path_1 = __importDefault(require("path"));
10
10
  const fs_1 = __importDefault(require("fs"));
11
- const util_internal_code_printer_1 = require("@subsquid/util-internal-code-printer");
12
- const abi_1 = require("@ethersproject/abi");
11
+ const path_1 = __importDefault(require("path"));
12
+ const process_1 = __importDefault(require("process"));
13
13
  function run() {
14
14
  commander_1.program.description(`
15
15
  Generates TypeScript definitions for evm log events
@@ -42,6 +42,7 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
42
42
  const rawABI = JSON.parse(fs_1.default.readFileSync(inputPathRaw, { encoding: "utf-8" }));
43
43
  const output = new util_internal_code_printer_1.Output();
44
44
  output.line("import * as ethers from \"ethers\";");
45
+ output.line("import assert from \"assert\";");
45
46
  output.line();
46
47
  output.line("export const abi = new ethers.utils.Interface(getJsonAbi());");
47
48
  output.line();
@@ -49,7 +50,6 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
49
50
  const abi = new abi_1.Interface(rawABI);
50
51
  const typeNames = {};
51
52
  const abiEvents = Object.values(abi.events).map((event) => {
52
- let signature = `${event.name}(`;
53
53
  let eventTypeName = `${event.name}`;
54
54
  if (typeNames[event.name]) {
55
55
  eventTypeName += typeNames[event.name].toString();
@@ -59,6 +59,8 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
59
59
  eventTypeName += "0";
60
60
  typeNames[event.name] = 1;
61
61
  }
62
+ eventTypeName += 'Event';
63
+ let signature = `${event.name}(`;
62
64
  if (event.inputs.length > 0) {
63
65
  signature += event.inputs[0].type;
64
66
  }
@@ -74,11 +76,7 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
74
76
  };
75
77
  });
76
78
  for (const decl of abiEvents) {
77
- output.block(`export interface ${decl.eventTypeName}Event`, () => {
78
- for (const input of decl.inputs) {
79
- output.line(`${input.name}: ${getType(input)};`);
80
- }
81
- });
79
+ output.line(`export type ${decl.eventTypeName} = ${getTupleType(decl.inputs)}`);
82
80
  output.line("");
83
81
  }
84
82
  output.block("export interface EvmEvent", () => {
@@ -86,30 +84,116 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
86
84
  output.line("topics: string[];");
87
85
  });
88
86
  output.line();
87
+ output.block(`function decodeEvent(signature: string, data: EvmEvent): any`, () => {
88
+ output.line(`return abi.decodeEventLog(`);
89
+ output.indentation(() => {
90
+ output.line(`abi.getEvent(signature),`);
91
+ output.line(`data.data || "",`);
92
+ output.line("data.topics");
93
+ });
94
+ output.line(");");
95
+ });
96
+ output.line();
89
97
  output.block("export const events =", () => {
90
98
  for (const decl of abiEvents) {
91
- output.block(`"${decl.signature}": `, () => {
99
+ output.block(`"${decl.signature}":`, () => {
92
100
  output.line(`topic: abi.getEventTopic("${decl.signature}"),`);
93
- output.block(`decode(data: EvmEvent): ${decl.eventTypeName}Event`, () => {
94
- output.line(`const result = abi.decodeEventLog(`);
95
- output.indentation(() => {
96
- output.line(`abi.getEvent("${decl.signature}"),`);
97
- output.line(`data.data || "",`);
98
- output.line("data.topics");
99
- });
100
- output.line(");");
101
- output.block("return ", () => {
102
- for (let i = 0; i < decl.inputs.length; ++i) {
103
- const input = decl.inputs[i];
104
- output.line(`${input.name}: ${`result[${i}]`},`);
105
- }
106
- });
101
+ output.block(`decode(data: EvmEvent): ${decl.eventTypeName}`, () => {
102
+ output.line(`return decodeEvent("${decl.signature}", data)`);
107
103
  });
108
104
  });
109
105
  output.line(",");
110
106
  }
111
107
  });
112
108
  output.line();
109
+ let abiFunctions = new Map();
110
+ for (let func of Object.values(abi.functions)) {
111
+ if (!func.constant || func.outputs == null)
112
+ continue;
113
+ let abiFunction = abiFunctions.get(func.name);
114
+ if (abiFunction == null) {
115
+ abiFunction = {
116
+ name: func.name,
117
+ overloads: []
118
+ };
119
+ abiFunctions.set(func.name, abiFunction);
120
+ }
121
+ let returnTypeName = func.outputs.length == 1 ? getType(func.outputs[0]) : getTupleType(func.outputs);
122
+ abiFunction.overloads.push({
123
+ inputs: func.inputs,
124
+ outputs: func.outputs || [],
125
+ returnTypeName
126
+ });
127
+ }
128
+ output.block("interface ChainContext ", () => {
129
+ output.line(`_chain: Chain`);
130
+ });
131
+ output.line();
132
+ output.block("interface BlockContext ", () => {
133
+ output.line(`_chain: Chain`);
134
+ output.line(`block: Block`);
135
+ });
136
+ output.line();
137
+ output.block("interface Block ", () => {
138
+ output.line(`height: number`);
139
+ });
140
+ output.line();
141
+ output.block("interface Chain ", () => {
142
+ output.block("client: ", () => {
143
+ output.line(`call: <T=any>(method: string, params?: unknown[]) => Promise<T>`);
144
+ });
145
+ });
146
+ output.line();
147
+ output.block("export class Contract ", () => {
148
+ output.line(`private readonly _chain: Chain`);
149
+ output.line(`private readonly blockHeight: number`);
150
+ output.line(`readonly address: string`);
151
+ output.line();
152
+ output.line(`constructor(ctx: BlockContext, address: string)`);
153
+ output.line(`constructor(ctx: ChainContext, block: Block, address: string)`);
154
+ output.block(`constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string)`, () => {
155
+ output.line(`this._chain = ctx._chain`);
156
+ output.block(`if (typeof blockOrAddress === 'string') `, () => {
157
+ output.line(`this.blockHeight = ctx.block.height`);
158
+ output.line(`this.address = ethers.utils.getAddress(blockOrAddress)`);
159
+ });
160
+ output.block(`else `, () => {
161
+ output.line(`assert(address != null)`);
162
+ output.line(`this.blockHeight = blockOrAddress.height`);
163
+ output.line(`this.address = ethers.utils.getAddress(address)`);
164
+ });
165
+ });
166
+ output.line();
167
+ for (const decl of abiFunctions.values()) {
168
+ if (decl.overloads.length > 1) {
169
+ for (let overload of decl.overloads) {
170
+ const args = overload.inputs.map((i, n) => `${i.name || `arg${n}`}: ${getType(i)}`);
171
+ const returnType = overload.returnTypeName;
172
+ output.line(`async ${decl.name}(${args}): Promise<${returnType}>`);
173
+ }
174
+ output.block(`async ${decl.name}(...args: any[])`, () => {
175
+ output.line(`return this.call("${decl.name}", args)`);
176
+ });
177
+ }
178
+ else {
179
+ const overload = decl.overloads[0];
180
+ const params = overload.inputs.map((i, n) => `${i.name || `arg${n}`}: ${getType(i)}`);
181
+ const returnType = overload.returnTypeName;
182
+ output.block(`async ${decl.name}(${params.join(`, `)}): Promise<${returnType}>`, () => {
183
+ output.line(`return this.call("${decl.name}", [${overload.inputs.map((i, n) => `${i.name || `arg${n}`}`).join(`, `)}])`);
184
+ });
185
+ }
186
+ output.line();
187
+ }
188
+ output.block(`private async call(name: string, args: any[]) : Promise<any>`, () => {
189
+ output.line(`const fragment = abi.getFunction(name)`);
190
+ output.line(`const data = abi.encodeFunctionData(fragment, args)`);
191
+ output.line(`const result = await this._chain.client.call('eth_call', [{to: this.address, data}, this.blockHeight])`);
192
+ output.line(`const decoded = abi.decodeFunctionResult(fragment, result)`);
193
+ output.line(`return decoded.length > 1 ? decoded : decoded[0]`);
194
+ });
195
+ });
196
+ output.line();
113
197
  output.block("function getJsonAbi(): any", () => {
114
198
  `return ${JSON.stringify(rawABI, null, 2)}`.split('\n').forEach(line => {
115
199
  output.line(line);
@@ -118,7 +202,7 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
118
202
  fs_1.default.writeFileSync(outputPathRaw, output.toString());
119
203
  }
120
204
  // taken from: https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/cli/src.ts/typescript.ts#L10
121
- function getType(param, flexible) {
205
+ function getType(param) {
122
206
  if (param.type === "address" || param.type === "string") {
123
207
  return "string";
124
208
  }
@@ -126,28 +210,39 @@ function getType(param, flexible) {
126
210
  return "boolean";
127
211
  }
128
212
  if (param.type.substring(0, 5) === "bytes") {
129
- if (flexible) {
130
- return "string | ethers.utils.BytesLike";
131
- }
132
213
  return "string";
133
214
  }
134
215
  let match = param.type.match(/^(u?int)([0-9]+)$/);
135
216
  if (match) {
136
- if (flexible) {
137
- return "ethers.BigNumberish";
138
- }
139
- if (parseInt(match[2]) < 53) {
140
- return 'number';
141
- }
142
- return 'ethers.BigNumber';
217
+ return parseInt(match[2]) < 53 ? 'number' : 'ethers.BigNumber';
143
218
  }
144
219
  if (param.baseType === "array") {
145
220
  return "Array<" + getType(param.arrayChildren) + ">";
146
221
  }
147
222
  if (param.baseType === "tuple") {
148
- let struct = param.components.map((p, i) => `${p.name || "p_" + i}: ${getType(p, flexible)}`);
149
- return "{ " + struct.join(", ") + " }";
223
+ return getTupleType(param.components);
150
224
  }
151
225
  throw new Error("unknown type");
152
226
  }
227
+ function getTupleType(params) {
228
+ let tuple = '[' + params.map(p => {
229
+ return p.name ? `${p.name}: ${getType(p)}` : getType(p);
230
+ }).join(', ') + ']';
231
+ let fields = getStructFields(params);
232
+ if (fields.length == 0)
233
+ return tuple;
234
+ let struct = '{' + fields.map(f => `${f.name}: ${getType(f)}`).join(', ') + '}';
235
+ return `(${tuple} & ${struct})`;
236
+ }
237
+ // https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/abi/src.ts/coders/tuple.ts#L29
238
+ function getStructFields(params) {
239
+ let array = [];
240
+ let counts = {};
241
+ for (let p of params) {
242
+ if (p.name && array[p.name] == null) {
243
+ counts[p.name] = (counts[p.name] || 0) + 1;
244
+ }
245
+ }
246
+ return params.filter(p => counts[p.name] == 1);
247
+ }
153
248
  //# sourceMappingURL=main.js.map
package/lib/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subsquid/evm-typegen",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "CLI for generating typescript types and decode implementations for evm logs",
5
5
  "license": "GPL-3.0-or-later",
6
6
  "repository": "git@github.com:subsquid/squid.git",
@@ -18,7 +18,7 @@
18
18
  "dependencies": {
19
19
  "commander": "^9.3.0",
20
20
  "@ethersproject/abi": "^5.6.4",
21
- "@subsquid/util-internal-code-printer": "^0.0.1"
21
+ "@subsquid/util-internal-code-printer": "^0.0.2"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^16.11.41",
package/src/main.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { program } from "commander";
2
- import process from "process";
3
- import path from "path";
4
- import fs from "fs";
5
- import { Output } from "@subsquid/util-internal-code-printer";
6
- import { EventFragment, Interface, ParamType } from "@ethersproject/abi";
1
+ import {EventFragment, Interface, ParamType} from "@ethersproject/abi"
2
+ import {Output} from "@subsquid/util-internal-code-printer"
3
+ import {program} from "commander"
4
+ import fs from "fs"
5
+ import path from "path"
6
+ import process from "process"
7
7
 
8
8
  export function run(): void {
9
9
  program.description(`
@@ -21,7 +21,7 @@ for use within substrate-processor mapping handlers.
21
21
 
22
22
  try {
23
23
  generateTsFromAbi(inputPath, outputPath);
24
- } catch(err: any) {
24
+ } catch (err: any) {
25
25
  console.error(`evm-typegen error: ${err.toString()}`);
26
26
  process.exit(1);
27
27
  }
@@ -39,11 +39,12 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
39
39
  throw new Error("invalid output file extension");
40
40
  }
41
41
 
42
- const rawABI = JSON.parse(fs.readFileSync(inputPathRaw, { encoding: "utf-8" }));
42
+ const rawABI = JSON.parse(fs.readFileSync(inputPathRaw, {encoding: "utf-8"}));
43
43
 
44
44
  const output = new Output();
45
45
 
46
46
  output.line("import * as ethers from \"ethers\";");
47
+ output.line("import assert from \"assert\";");
47
48
  output.line();
48
49
  output.line("export const abi = new ethers.utils.Interface(getJsonAbi());");
49
50
  output.line();
@@ -51,29 +52,27 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
51
52
  // validate the abi
52
53
  const abi = new Interface(rawABI);
53
54
 
54
- const typeNames: { [key: string]: number } = {};
55
+ const typeNames: {[key: string]: number} = {};
55
56
 
56
57
  const abiEvents: Array<AbiEvent> = Object.values(abi.events).map((event: EventFragment): AbiEvent => {
57
- let signature = `${event.name}(`;
58
58
  let eventTypeName = `${event.name}`;
59
-
60
- if(typeNames[event.name]) {
59
+ if (typeNames[event.name]) {
61
60
  eventTypeName += typeNames[event.name].toString();
62
61
  typeNames[event.name]++;
63
62
  } else {
64
63
  eventTypeName += "0";
65
64
  typeNames[event.name] = 1;
66
65
  }
66
+ eventTypeName += 'Event'
67
67
 
68
- if(event.inputs.length > 0) {
68
+ let signature = `${event.name}(`;
69
+ if (event.inputs.length > 0) {
69
70
  signature += event.inputs[0].type;
70
71
  }
71
-
72
- for (let i=1; i<event.inputs.length; ++i) {
72
+ for (let i = 1; i < event.inputs.length; ++i) {
73
73
  const input = event.inputs[i];
74
74
  signature += `,${input.type}`;
75
75
  }
76
-
77
76
  signature += ")";
78
77
 
79
78
  return {
@@ -83,12 +82,8 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
83
82
  };
84
83
  });
85
84
 
86
- for(const decl of abiEvents) {
87
- output.block(`export interface ${decl.eventTypeName}Event`, () => {
88
- for (const input of decl.inputs) {
89
- output.line(`${input.name}: ${getType(input)};`);
90
- }
91
- });
85
+ for (const decl of abiEvents) {
86
+ output.line(`export type ${decl.eventTypeName} = ${getTupleType(decl.inputs)}`)
92
87
  output.line("");
93
88
  }
94
89
 
@@ -99,24 +94,24 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
99
94
 
100
95
  output.line();
101
96
 
97
+ output.block(`function decodeEvent(signature: string, data: EvmEvent): any`, () => {
98
+ output.line(`return abi.decodeEventLog(`);
99
+ output.indentation(() => {
100
+ output.line(`abi.getEvent(signature),`);
101
+ output.line(`data.data || "",`);
102
+ output.line("data.topics");
103
+ });
104
+ output.line(");");
105
+ });
106
+
107
+ output.line();
108
+
102
109
  output.block("export const events =", () => {
103
- for(const decl of abiEvents) {
104
- output.block(`"${decl.signature}": `, () => {
110
+ for (const decl of abiEvents) {
111
+ output.block(`"${decl.signature}":`, () => {
105
112
  output.line(`topic: abi.getEventTopic("${decl.signature}"),`);
106
- output.block(`decode(data: EvmEvent): ${decl.eventTypeName}Event`, () => {
107
- output.line(`const result = abi.decodeEventLog(`);
108
- output.indentation(() => {
109
- output.line(`abi.getEvent("${decl.signature}"),`);
110
- output.line(`data.data || "",`);
111
- output.line("data.topics");
112
- });
113
- output.line(");");
114
- output.block("return ", () => {
115
- for (let i=0; i<decl.inputs.length; ++i) {
116
- const input = decl.inputs[i];
117
- output.line(`${input.name}: ${`result[${i}]`},`);
118
- }
119
- });
113
+ output.block(`decode(data: EvmEvent): ${decl.eventTypeName}`, () => {
114
+ output.line(`return decodeEvent("${decl.signature}", data)`);
120
115
  });
121
116
  });
122
117
  output.line(",");
@@ -125,6 +120,98 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
125
120
 
126
121
  output.line();
127
122
 
123
+ let abiFunctions: Map<string, AbiFunction> = new Map()
124
+ for (let func of Object.values(abi.functions)) {
125
+ if (!func.constant || func.outputs == null) continue
126
+
127
+ let abiFunction = abiFunctions.get(func.name)
128
+ if (abiFunction == null) {
129
+ abiFunction = {
130
+ name: func.name,
131
+ overloads: []
132
+ }
133
+ abiFunctions.set(func.name, abiFunction)
134
+ }
135
+
136
+ let returnTypeName = func.outputs.length == 1 ? getType(func.outputs[0]) : getTupleType(func.outputs)
137
+
138
+ abiFunction.overloads.push({
139
+ inputs: func.inputs,
140
+ outputs: func.outputs || [],
141
+ returnTypeName
142
+ })
143
+ }
144
+
145
+ output.block("interface ChainContext ", () => {
146
+ output.line(`_chain: Chain`);
147
+ })
148
+ output.line();
149
+ output.block("interface BlockContext ", () => {
150
+ output.line(`_chain: Chain`);
151
+ output.line(`block: Block`);
152
+ })
153
+ output.line();
154
+ output.block("interface Block ", () => {
155
+ output.line(`height: number`);
156
+ })
157
+ output.line();
158
+ output.block("interface Chain ", () => {
159
+ output.block("client: ", () => {
160
+ output.line(`call: <T=any>(method: string, params?: unknown[]) => Promise<T>`);
161
+ })
162
+ })
163
+ output.line();
164
+ output.block("export class Contract ", () => {
165
+ output.line(`private readonly _chain: Chain`);
166
+ output.line(`private readonly blockHeight: number`);
167
+ output.line(`readonly address: string`);
168
+ output.line();
169
+ output.line(`constructor(ctx: BlockContext, address: string)`);
170
+ output.line(`constructor(ctx: ChainContext, block: Block, address: string)`);
171
+ output.block(`constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string)`, () => {
172
+ output.line(`this._chain = ctx._chain`);
173
+ output.block(`if (typeof blockOrAddress === 'string') `, () => {
174
+ output.line(`this.blockHeight = ctx.block.height`)
175
+ output.line(`this.address = ethers.utils.getAddress(blockOrAddress)`)
176
+ })
177
+ output.block(`else `, () => {
178
+ output.line(`assert(address != null)`)
179
+ output.line(`this.blockHeight = blockOrAddress.height`)
180
+ output.line(`this.address = ethers.utils.getAddress(address)`)
181
+ })
182
+ })
183
+ output.line();
184
+ for (const decl of abiFunctions.values()) {
185
+ if (decl.overloads.length > 1) {
186
+ for (let overload of decl.overloads) {
187
+ const args = overload.inputs.map((i, n) => `${i.name || `arg${n}`}: ${getType(i)}`)
188
+ const returnType = overload.returnTypeName
189
+ output.line(`async ${decl.name}(${args}): Promise<${returnType}>`)
190
+ }
191
+ output.block(`async ${decl.name}(...args: any[])`, () => {
192
+ output.line(`return this.call("${decl.name}", args)`);
193
+ });
194
+ } else {
195
+ const overload = decl.overloads[0]
196
+ const params = overload.inputs.map((i, n) => `${i.name || `arg${n}`}: ${getType(i)}`)
197
+ const returnType = overload.returnTypeName
198
+ output.block(`async ${decl.name}(${params.join(`, `)}): Promise<${returnType}>`, () => {
199
+ output.line(`return this.call("${decl.name}", [${overload.inputs.map((i, n) => `${i.name || `arg${n}`}`).join(`, `)}])`);
200
+ });
201
+ }
202
+ output.line();
203
+ }
204
+ output.block(`private async call(name: string, args: any[]) : Promise<any>`, () => {
205
+ output.line(`const fragment = abi.getFunction(name)`);
206
+ output.line(`const data = abi.encodeFunctionData(fragment, args)`);
207
+ output.line(`const result = await this._chain.client.call('eth_call', [{to: this.address, data}, this.blockHeight])`);
208
+ output.line(`const decoded = abi.decodeFunctionResult(fragment, result)`);
209
+ output.line(`return decoded.length > 1 ? decoded : decoded[0]`);
210
+ })
211
+ })
212
+
213
+ output.line();
214
+
128
215
  output.block("function getJsonAbi(): any", () => {
129
216
  `return ${JSON.stringify(rawABI, null, 2)}`.split('\n').forEach(line => {
130
217
  output.line(line)
@@ -135,25 +222,22 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
135
222
  }
136
223
 
137
224
  // taken from: https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/cli/src.ts/typescript.ts#L10
138
- function getType(param: ParamType, flexible?: boolean): string {
139
- if (param.type === "address" || param.type === "string") { return "string"; }
225
+ function getType(param: ParamType): string {
226
+ if (param.type === "address" || param.type === "string") {
227
+ return "string"
228
+ }
140
229
 
141
- if (param.type === "bool") { return "boolean" }
230
+ if (param.type === "bool") {
231
+ return "boolean"
232
+ }
142
233
 
143
234
  if (param.type.substring(0, 5) === "bytes") {
144
- if (flexible) {
145
- return "string | ethers.utils.BytesLike";
146
- }
147
235
  return "string"
148
236
  }
149
237
 
150
238
  let match = param.type.match(/^(u?int)([0-9]+)$/)
151
239
  if (match) {
152
- if (flexible) {
153
- return "ethers.BigNumberish";
154
- }
155
- if (parseInt(match[2]) < 53) { return 'number'; }
156
- return 'ethers.BigNumber';
240
+ return parseInt(match[2]) < 53 ? 'number' : 'ethers.BigNumber'
157
241
  }
158
242
 
159
243
  if (param.baseType === "array") {
@@ -161,15 +245,48 @@ function getType(param: ParamType, flexible?: boolean): string {
161
245
  }
162
246
 
163
247
  if (param.baseType === "tuple") {
164
- let struct = param.components.map((p, i) => `${p.name || "p_" + i}: ${getType(p, flexible)}`);
165
- return "{ " + struct.join(", ") + " }";
248
+ return getTupleType(param.components);
166
249
  }
167
250
 
168
251
  throw new Error("unknown type");
169
252
  }
170
253
 
254
+ function getTupleType(params: ParamType[]) {
255
+ let tuple = '[' + params.map(p => {
256
+ return p.name ? `${p.name}: ${getType(p)}` : getType(p)
257
+ }).join(', ') + ']'
258
+
259
+ let fields = getStructFields(params)
260
+ if (fields.length == 0) return tuple
261
+
262
+ let struct = '{' + fields.map(f => `${f.name}: ${getType(f)}`).join(', ') + '}'
263
+
264
+ return `(${tuple} & ${struct})`
265
+ }
266
+
267
+ // https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/abi/src.ts/coders/tuple.ts#L29
268
+ function getStructFields(params: ParamType[]): ParamType[] {
269
+ let array: any = []
270
+ let counts: Record<string, number> = {}
271
+ for (let p of params) {
272
+ if (p.name && array[p.name] == null) {
273
+ counts[p.name] = (counts[p.name] || 0) + 1
274
+ }
275
+ }
276
+ return params.filter(p => counts[p.name] == 1)
277
+ }
278
+
171
279
  interface AbiEvent {
172
280
  signature: string;
173
281
  eventTypeName: string;
174
282
  inputs: ParamType[];
175
283
  }
284
+
285
+ interface AbiFunction {
286
+ name: string;
287
+ overloads: {
288
+ inputs: ParamType[];
289
+ outputs: ParamType[];
290
+ returnTypeName?: string;
291
+ }[]
292
+ }