@subsquid/evm-typegen 1.0.2 → 1.1.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 +78 -0
- package/lib/main.js.map +1 -1
- package/package.json +1 -1
- package/src/main.ts +101 -15
package/lib/main.js
CHANGED
|
@@ -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();
|
|
@@ -110,6 +111,83 @@ function generateTsFromAbi(inputPathRaw, outputPathRaw) {
|
|
|
110
111
|
}
|
|
111
112
|
});
|
|
112
113
|
output.line();
|
|
114
|
+
const abiFunctions = Object.values(abi.functions)
|
|
115
|
+
.filter((func) => func.constant && func.outputs != null)
|
|
116
|
+
.map((func) => {
|
|
117
|
+
return {
|
|
118
|
+
name: func.name,
|
|
119
|
+
inputs: func.inputs,
|
|
120
|
+
outputs: func.outputs || []
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
output.block("interface ChainContext ", () => {
|
|
124
|
+
output.line(`_chain: Chain`);
|
|
125
|
+
});
|
|
126
|
+
output.line();
|
|
127
|
+
output.block("interface BlockContext ", () => {
|
|
128
|
+
output.line(`_chain: Chain`);
|
|
129
|
+
output.line(`block: Block`);
|
|
130
|
+
});
|
|
131
|
+
output.line();
|
|
132
|
+
output.block("interface Block ", () => {
|
|
133
|
+
output.line(`height: number`);
|
|
134
|
+
});
|
|
135
|
+
output.line();
|
|
136
|
+
output.block("interface Chain ", () => {
|
|
137
|
+
output.block("client: ", () => {
|
|
138
|
+
output.line(`call: <T=any>(method: string, params?: unknown[]) => Promise<T>`);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
output.line();
|
|
142
|
+
output.block("export class Contract ", () => {
|
|
143
|
+
output.line(`private readonly _chain: Chain`);
|
|
144
|
+
output.line(`private readonly blockHeight: number`);
|
|
145
|
+
output.line(`readonly address: string`);
|
|
146
|
+
output.line();
|
|
147
|
+
output.line(`constructor(ctx: BlockContext, address: string)`);
|
|
148
|
+
output.line(`constructor(ctx: ChainContext, block: Block, address: string)`);
|
|
149
|
+
output.block(`constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string)`, () => {
|
|
150
|
+
output.line(`this._chain = ctx._chain`);
|
|
151
|
+
output.block(`if (typeof blockOrAddress === 'string') `, () => {
|
|
152
|
+
output.line(`this.blockHeight = ctx.block.height`);
|
|
153
|
+
output.line(`this.address = ethers.utils.getAddress(blockOrAddress)`);
|
|
154
|
+
});
|
|
155
|
+
output.block(`else `, () => {
|
|
156
|
+
output.line(`assert(address != null)`);
|
|
157
|
+
output.line(`this.blockHeight = blockOrAddress.height`);
|
|
158
|
+
output.line(`this.address = ethers.utils.getAddress(address)`);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
output.line();
|
|
162
|
+
output.block(`private async call(name: string, args: any[]) : Promise<ReadonlyArray<any>>`, () => {
|
|
163
|
+
output.line(`const fragment = abi.getFunction(name)`);
|
|
164
|
+
output.line(`const data = abi.encodeFunctionData(fragment, args)`);
|
|
165
|
+
output.line(`const result = await this._chain.client.call('eth_call', [{to: this.address, data}, this.blockHeight])`);
|
|
166
|
+
output.line(`return abi.decodeFunctionResult(fragment, result)`);
|
|
167
|
+
});
|
|
168
|
+
for (const decl of abiFunctions) {
|
|
169
|
+
const params = decl.inputs.map((i) => `${i.name}: ${getType(i)}`);
|
|
170
|
+
const returnType = decl.outputs.length > 1
|
|
171
|
+
? `{${decl.outputs.map((i) => `${i.name}: ${getType(i)}`)}}`
|
|
172
|
+
: getType(decl.outputs[0]);
|
|
173
|
+
output.line();
|
|
174
|
+
output.block(`async ${decl.name}(${params.join(`, `)}): Promise<${returnType}>`, () => {
|
|
175
|
+
output.line(`const result = await this.call("${decl.name}", [${decl.inputs.map((i) => `${i.name}`).join(`, `)}])`);
|
|
176
|
+
if (decl.outputs.length > 1) {
|
|
177
|
+
output.block("return ", () => {
|
|
178
|
+
for (let i = 0; i < decl.outputs.length; ++i) {
|
|
179
|
+
const out = decl.outputs[i];
|
|
180
|
+
output.line(`${out.name}: ${`result[${i}]`},`);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
output.line(`return result[0]`);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
output.line();
|
|
113
191
|
output.block("function getJsonAbi(): any", () => {
|
|
114
192
|
`return ${JSON.stringify(rawABI, null, 2)}`.split('\n').forEach(line => {
|
|
115
193
|
output.line(line);
|
package/lib/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {program} from "commander";
|
|
2
2
|
import process from "process";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import {Output} from "@subsquid/util-internal-code-printer";
|
|
6
|
+
import {EventFragment, FunctionFragment, Interface, ParamType} from "@ethersproject/abi";
|
|
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, {
|
|
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,13 +52,13 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
51
52
|
// validate the abi
|
|
52
53
|
const abi = new Interface(rawABI);
|
|
53
54
|
|
|
54
|
-
const typeNames: {
|
|
55
|
+
const typeNames: {[key: string]: number} = {};
|
|
55
56
|
|
|
56
57
|
const abiEvents: Array<AbiEvent> = Object.values(abi.events).map((event: EventFragment): AbiEvent => {
|
|
57
58
|
let signature = `${event.name}(`;
|
|
58
59
|
let eventTypeName = `${event.name}`;
|
|
59
60
|
|
|
60
|
-
if(typeNames[event.name]) {
|
|
61
|
+
if (typeNames[event.name]) {
|
|
61
62
|
eventTypeName += typeNames[event.name].toString();
|
|
62
63
|
typeNames[event.name]++;
|
|
63
64
|
} else {
|
|
@@ -65,11 +66,11 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
65
66
|
typeNames[event.name] = 1;
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
if(event.inputs.length > 0) {
|
|
69
|
+
if (event.inputs.length > 0) {
|
|
69
70
|
signature += event.inputs[0].type;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
for (let i=1; i<event.inputs.length; ++i) {
|
|
73
|
+
for (let i = 1; i < event.inputs.length; ++i) {
|
|
73
74
|
const input = event.inputs[i];
|
|
74
75
|
signature += `,${input.type}`;
|
|
75
76
|
}
|
|
@@ -83,7 +84,7 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
83
84
|
};
|
|
84
85
|
});
|
|
85
86
|
|
|
86
|
-
for(const decl of abiEvents) {
|
|
87
|
+
for (const decl of abiEvents) {
|
|
87
88
|
output.block(`export interface ${decl.eventTypeName}Event`, () => {
|
|
88
89
|
for (const input of decl.inputs) {
|
|
89
90
|
output.line(`${input.name}: ${getType(input)};`);
|
|
@@ -100,7 +101,7 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
100
101
|
output.line();
|
|
101
102
|
|
|
102
103
|
output.block("export const events =", () => {
|
|
103
|
-
for(const decl of abiEvents) {
|
|
104
|
+
for (const decl of abiEvents) {
|
|
104
105
|
output.block(`"${decl.signature}": `, () => {
|
|
105
106
|
output.line(`topic: abi.getEventTopic("${decl.signature}"),`);
|
|
106
107
|
output.block(`decode(data: EvmEvent): ${decl.eventTypeName}Event`, () => {
|
|
@@ -112,7 +113,7 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
112
113
|
});
|
|
113
114
|
output.line(");");
|
|
114
115
|
output.block("return ", () => {
|
|
115
|
-
for (let i=0; i<decl.inputs.length; ++i) {
|
|
116
|
+
for (let i = 0; i < decl.inputs.length; ++i) {
|
|
116
117
|
const input = decl.inputs[i];
|
|
117
118
|
output.line(`${input.name}: ${`result[${i}]`},`);
|
|
118
119
|
}
|
|
@@ -125,6 +126,85 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
125
126
|
|
|
126
127
|
output.line();
|
|
127
128
|
|
|
129
|
+
const abiFunctions: Array<AbiFunction> = Object.values(abi.functions)
|
|
130
|
+
.filter((func: FunctionFragment) => func.constant && func.outputs != null)
|
|
131
|
+
.map((func): AbiFunction => {
|
|
132
|
+
return {
|
|
133
|
+
name: func.name,
|
|
134
|
+
inputs: func.inputs,
|
|
135
|
+
outputs: func.outputs || []
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
output.block("interface ChainContext ", () => {
|
|
140
|
+
output.line(`_chain: Chain`);
|
|
141
|
+
})
|
|
142
|
+
output.line();
|
|
143
|
+
output.block("interface BlockContext ", () => {
|
|
144
|
+
output.line(`_chain: Chain`);
|
|
145
|
+
output.line(`block: Block`);
|
|
146
|
+
})
|
|
147
|
+
output.line();
|
|
148
|
+
output.block("interface Block ", () => {
|
|
149
|
+
output.line(`height: number`);
|
|
150
|
+
})
|
|
151
|
+
output.line();
|
|
152
|
+
output.block("interface Chain ", () => {
|
|
153
|
+
output.block("client: ", () => {
|
|
154
|
+
output.line(`call: <T=any>(method: string, params?: unknown[]) => Promise<T>`);
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
output.line();
|
|
158
|
+
output.block("export class Contract ", () => {
|
|
159
|
+
output.line(`private readonly _chain: Chain`);
|
|
160
|
+
output.line(`private readonly blockHeight: number`);
|
|
161
|
+
output.line(`readonly address: string`);
|
|
162
|
+
output.line();
|
|
163
|
+
output.line(`constructor(ctx: BlockContext, address: string)`);
|
|
164
|
+
output.line(`constructor(ctx: ChainContext, block: Block, address: string)`);
|
|
165
|
+
output.block(`constructor(ctx: BlockContext, blockOrAddress: Block | string, address?: string)`, () => {
|
|
166
|
+
output.line(`this._chain = ctx._chain`);
|
|
167
|
+
output.block(`if (typeof blockOrAddress === 'string') `, () => {
|
|
168
|
+
output.line(`this.blockHeight = ctx.block.height`)
|
|
169
|
+
output.line(`this.address = ethers.utils.getAddress(blockOrAddress)`)
|
|
170
|
+
})
|
|
171
|
+
output.block(`else `, () => {
|
|
172
|
+
output.line(`assert(address != null)`)
|
|
173
|
+
output.line(`this.blockHeight = blockOrAddress.height`)
|
|
174
|
+
output.line(`this.address = ethers.utils.getAddress(address)`)
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
output.line();
|
|
178
|
+
output.block(`private async call(name: string, args: any[]) : Promise<ReadonlyArray<any>>`, () => {
|
|
179
|
+
output.line(`const fragment = abi.getFunction(name)`);
|
|
180
|
+
output.line(`const data = abi.encodeFunctionData(fragment, args)`);
|
|
181
|
+
output.line(`const result = await this._chain.client.call('eth_call', [{to: this.address, data}, this.blockHeight])`);
|
|
182
|
+
output.line(`return abi.decodeFunctionResult(fragment, result)`);
|
|
183
|
+
})
|
|
184
|
+
for (const decl of abiFunctions) {
|
|
185
|
+
const params = decl.inputs.map((i) => `${i.name}: ${getType(i)}`)
|
|
186
|
+
const returnType = decl.outputs.length > 1
|
|
187
|
+
? `{${decl.outputs.map((i) => `${i.name}: ${getType(i)}`)}}`
|
|
188
|
+
: getType(decl.outputs[0])
|
|
189
|
+
output.line();
|
|
190
|
+
output.block(`async ${decl.name}(${params.join(`, `)}): Promise<${returnType}>`, () => {
|
|
191
|
+
output.line(`const result = await this.call("${decl.name}", [${decl.inputs.map((i) => `${i.name}`).join(`, `)}])`);
|
|
192
|
+
if (decl.outputs.length > 1) {
|
|
193
|
+
output.block("return ", () => {
|
|
194
|
+
for (let i = 0; i < decl.outputs.length; ++i) {
|
|
195
|
+
const out = decl.outputs[i];
|
|
196
|
+
output.line(`${out.name}: ${`result[${i}]`},`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
} else {
|
|
200
|
+
output.line(`return result[0]`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
output.line();
|
|
207
|
+
|
|
128
208
|
output.block("function getJsonAbi(): any", () => {
|
|
129
209
|
`return ${JSON.stringify(rawABI, null, 2)}`.split('\n').forEach(line => {
|
|
130
210
|
output.line(line)
|
|
@@ -136,9 +216,9 @@ function generateTsFromAbi(inputPathRaw: string, outputPathRaw: string): void {
|
|
|
136
216
|
|
|
137
217
|
// taken from: https://github.com/ethers-io/ethers.js/blob/948f77050dae884fe88932fd88af75560aac9d78/packages/cli/src.ts/typescript.ts#L10
|
|
138
218
|
function getType(param: ParamType, flexible?: boolean): string {
|
|
139
|
-
if (param.type === "address" || param.type === "string") {
|
|
219
|
+
if (param.type === "address" || param.type === "string") {return "string";}
|
|
140
220
|
|
|
141
|
-
if (param.type === "bool") {
|
|
221
|
+
if (param.type === "bool") {return "boolean"}
|
|
142
222
|
|
|
143
223
|
if (param.type.substring(0, 5) === "bytes") {
|
|
144
224
|
if (flexible) {
|
|
@@ -152,7 +232,7 @@ function getType(param: ParamType, flexible?: boolean): string {
|
|
|
152
232
|
if (flexible) {
|
|
153
233
|
return "ethers.BigNumberish";
|
|
154
234
|
}
|
|
155
|
-
if (parseInt(match[2]) < 53) {
|
|
235
|
+
if (parseInt(match[2]) < 53) {return 'number';}
|
|
156
236
|
return 'ethers.BigNumber';
|
|
157
237
|
}
|
|
158
238
|
|
|
@@ -173,3 +253,9 @@ interface AbiEvent {
|
|
|
173
253
|
eventTypeName: string;
|
|
174
254
|
inputs: ParamType[];
|
|
175
255
|
}
|
|
256
|
+
|
|
257
|
+
interface AbiFunction {
|
|
258
|
+
name: string;
|
|
259
|
+
inputs: ParamType[];
|
|
260
|
+
outputs: ParamType[];
|
|
261
|
+
}
|