@subsquid/evm-typegen 3.3.0 → 4.0.1
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 +13 -12
- package/lib/main.js.map +1 -1
- package/lib/multicall.d.ts +212 -26
- package/lib/multicall.d.ts.map +1 -1
- package/lib/multicall.js +142 -100
- package/lib/multicall.js.map +1 -1
- package/lib/typegen.d.ts +15 -7
- package/lib/typegen.d.ts.map +1 -1
- package/lib/typegen.js +117 -68
- package/lib/typegen.js.map +1 -1
- package/lib/util/fetch.d.ts.map +1 -1
- package/lib/util/fetch.js +1 -1
- package/lib/util/fetch.js.map +1 -1
- package/lib/util/types.d.ts +2 -6
- package/lib/util/types.d.ts.map +1 -1
- package/lib/util/types.js +39 -60
- package/lib/util/types.js.map +1 -1
- package/package.json +8 -8
- package/src/main.ts +148 -135
- package/src/multicall.ts +3 -0
- package/src/typegen.ts +228 -111
- package/src/util/fetch.ts +6 -8
- package/src/util/types.ts +44 -62
- package/lib/abi.support.d.ts +0 -57
- package/lib/abi.support.d.ts.map +0 -1
- package/lib/abi.support.js +0 -116
- package/lib/abi.support.js.map +0 -1
- package/src/abi.support.ts +0 -135
package/lib/multicall.js
CHANGED
|
@@ -1,31 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.Multicall = void 0;
|
|
27
|
-
const ethers = __importStar(require("ethers"));
|
|
28
|
-
const abi_support_1 = require("./abi.support");
|
|
2
|
+
/**
|
|
3
|
+
* TODO migrate multicall
|
|
4
|
+
import * as ethers from 'ethers'
|
|
5
|
+
import {ContractBase, Func} from './abi.support'
|
|
6
|
+
|
|
7
|
+
|
|
29
8
|
const abi = new ethers.Interface([
|
|
30
9
|
{
|
|
31
10
|
type: 'function',
|
|
@@ -36,14 +15,14 @@ const abi = new ethers.Interface([
|
|
|
36
15
|
name: 'calls',
|
|
37
16
|
type: 'tuple[]',
|
|
38
17
|
components: [
|
|
39
|
-
{
|
|
40
|
-
{
|
|
18
|
+
{name: 'target', type: 'address'},
|
|
19
|
+
{name: 'callData', type: 'bytes'},
|
|
41
20
|
]
|
|
42
21
|
}
|
|
43
22
|
],
|
|
44
23
|
outputs: [
|
|
45
|
-
{
|
|
46
|
-
{
|
|
24
|
+
{name: 'blockNumber', type: 'uint256'},
|
|
25
|
+
{name: 'returnData', type: 'bytes[]'},
|
|
47
26
|
]
|
|
48
27
|
},
|
|
49
28
|
{
|
|
@@ -51,13 +30,13 @@ const abi = new ethers.Interface([
|
|
|
51
30
|
type: 'function',
|
|
52
31
|
stateMutability: 'nonpayable',
|
|
53
32
|
inputs: [
|
|
54
|
-
{
|
|
33
|
+
{name: 'requireSuccess', type: 'bool'},
|
|
55
34
|
{
|
|
56
35
|
name: 'calls',
|
|
57
36
|
type: 'tuple[]',
|
|
58
37
|
components: [
|
|
59
|
-
{
|
|
60
|
-
{
|
|
38
|
+
{name: 'target', type: 'address'},
|
|
39
|
+
{name: 'callData', type: 'bytes'},
|
|
61
40
|
]
|
|
62
41
|
}
|
|
63
42
|
],
|
|
@@ -66,110 +45,173 @@ const abi = new ethers.Interface([
|
|
|
66
45
|
name: 'returnData',
|
|
67
46
|
type: 'tuple[]',
|
|
68
47
|
components: [
|
|
69
|
-
{
|
|
70
|
-
{
|
|
48
|
+
{name: 'success', type: 'bool'},
|
|
49
|
+
{name: 'returnData', type: 'bytes'},
|
|
71
50
|
]
|
|
72
51
|
},
|
|
73
52
|
]
|
|
74
53
|
}
|
|
75
|
-
])
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
type AnyFunc = Func<any, {}, any>
|
|
58
|
+
type Call = [address: string, bytes: string]
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
const aggregate = new Func<[calls: Call[]], {}, {blockNumber: bigint, returnData: string[]}>(
|
|
62
|
+
abi, abi.getFunction('aggregate')!.selector
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
const try_aggregate = new Func<[requireSuccess: boolean, calls: Array<[target: string, callData: string]>], {}, Array<{success: boolean, returnData: string}>>(
|
|
67
|
+
abi, abi.getFunction('tryAggregate')!.selector
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
export type MulticallResult<T> = {
|
|
72
|
+
success: true
|
|
73
|
+
value: T
|
|
74
|
+
} | {
|
|
75
|
+
success: false
|
|
76
|
+
returnData?: string
|
|
77
|
+
value?: undefined
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
export class Multicall extends ContractBase {
|
|
82
|
+
static aggregate = aggregate
|
|
83
|
+
static try_aggregate = try_aggregate
|
|
84
|
+
|
|
85
|
+
aggregate<Args extends any[], R>(
|
|
86
|
+
func: Func<Args, {}, R>,
|
|
87
|
+
address: string,
|
|
88
|
+
calls: Args[],
|
|
89
|
+
paging?: number
|
|
90
|
+
): Promise<R[]>
|
|
91
|
+
|
|
92
|
+
aggregate<Args extends any[], R>(
|
|
93
|
+
func: Func<Args, {}, R>,
|
|
94
|
+
calls: [address: string, args: Args][],
|
|
95
|
+
paging?: number
|
|
96
|
+
): Promise<R[]>
|
|
97
|
+
|
|
98
|
+
aggregate(
|
|
99
|
+
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
100
|
+
paging?: number
|
|
101
|
+
): Promise<any[]>
|
|
102
|
+
|
|
103
|
+
async aggregate(...args: any[]): Promise<any[]> {
|
|
104
|
+
let [calls, funcs, page] = this.makeCalls(args)
|
|
105
|
+
let size = calls.length
|
|
106
|
+
let results = new Array(size)
|
|
83
107
|
for (let [from, to] of splitIntoPages(size, page)) {
|
|
84
|
-
let {
|
|
108
|
+
let {returnData} = await this.eth_call(aggregate, [calls.slice(from, to)])
|
|
85
109
|
for (let i = from; i < to; i++) {
|
|
86
|
-
let data = returnData[i - from]
|
|
87
|
-
results[i] = funcs[i].decodeResult(data)
|
|
110
|
+
let data = returnData[i - from]
|
|
111
|
+
results[i] = funcs[i].decodeResult(data)
|
|
88
112
|
}
|
|
89
113
|
}
|
|
90
|
-
return results
|
|
114
|
+
return results
|
|
91
115
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
116
|
+
|
|
117
|
+
tryAggregate<Args extends any[], R>(
|
|
118
|
+
func: Func<Args, {}, R>,
|
|
119
|
+
address: string,
|
|
120
|
+
calls: Args[],
|
|
121
|
+
paging?: number
|
|
122
|
+
): Promise<MulticallResult<R>[]>
|
|
123
|
+
|
|
124
|
+
tryAggregate<Args extends any[], R>(
|
|
125
|
+
func: Func<Args, {}, R>,
|
|
126
|
+
calls: [address: string, args: Args][],
|
|
127
|
+
paging?: number
|
|
128
|
+
): Promise<MulticallResult<R>[]>
|
|
129
|
+
|
|
130
|
+
tryAggregate(
|
|
131
|
+
calls: [func: AnyFunc, address: string, args: any[]][],
|
|
132
|
+
paging?: number
|
|
133
|
+
): Promise<MulticallResult<any>[]>
|
|
134
|
+
|
|
135
|
+
async tryAggregate(...args: any[]): Promise<any[]> {
|
|
136
|
+
let [calls, funcs, page] = this.makeCalls(args)
|
|
137
|
+
let size = calls.length
|
|
138
|
+
let results = new Array(size)
|
|
96
139
|
for (let [from, to] of splitIntoPages(size, page)) {
|
|
97
|
-
let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)])
|
|
140
|
+
let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)])
|
|
98
141
|
for (let i = from; i < to; i++) {
|
|
99
|
-
let res = response[i - from]
|
|
142
|
+
let res = response[i - from]
|
|
100
143
|
if (res.success) {
|
|
101
144
|
try {
|
|
102
145
|
results[i] = {
|
|
103
146
|
success: true,
|
|
104
147
|
value: funcs[i].decodeResult(res.returnData)
|
|
105
|
-
}
|
|
148
|
+
}
|
|
149
|
+
} catch(err: any) {
|
|
150
|
+
results[i] = {success: false, returnData: res.returnData}
|
|
106
151
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
results[i] = { success: false };
|
|
152
|
+
} else {
|
|
153
|
+
results[i] = {success: false}
|
|
113
154
|
}
|
|
114
155
|
}
|
|
115
156
|
}
|
|
116
|
-
return results
|
|
157
|
+
return results
|
|
117
158
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
159
|
+
|
|
160
|
+
private makeCalls(args: any[]): [calls: Call[], funcs: AnyFunc[], page: number] {
|
|
161
|
+
let page = typeof args[args.length-1] == 'number' ? args.pop()! : Number.MAX_SAFE_INTEGER
|
|
162
|
+
switch(args.length) {
|
|
121
163
|
case 1: {
|
|
122
|
-
let list = args[0]
|
|
123
|
-
let calls = new Array(list.length)
|
|
124
|
-
let funcs = new Array(list.length)
|
|
164
|
+
let list: [func: AnyFunc, address: string, args: any[]][] = args[0]
|
|
165
|
+
let calls = new Array(list.length)
|
|
166
|
+
let funcs = new Array(list.length)
|
|
125
167
|
for (let i = 0; i < list.length; i++) {
|
|
126
|
-
let [func, address, args] = list[i]
|
|
127
|
-
calls[i] = [address, func.encode(args)]
|
|
128
|
-
funcs[i] = func
|
|
168
|
+
let [func, address, args] = list[i]
|
|
169
|
+
calls[i] = [address, func.encode(args)]
|
|
170
|
+
funcs[i] = func
|
|
129
171
|
}
|
|
130
|
-
return [calls, funcs, page]
|
|
172
|
+
return [calls, funcs, page]
|
|
131
173
|
}
|
|
132
174
|
case 2: {
|
|
133
|
-
let func = args[0]
|
|
134
|
-
let list = args[1]
|
|
135
|
-
let calls = new Array(list.length)
|
|
136
|
-
let funcs = new Array(list.length)
|
|
175
|
+
let func: AnyFunc = args[0]
|
|
176
|
+
let list: [address: string, args: any[]][] = args[1]
|
|
177
|
+
let calls = new Array(list.length)
|
|
178
|
+
let funcs = new Array(list.length)
|
|
137
179
|
for (let i = 0; i < list.length; i++) {
|
|
138
|
-
let [address, args] = list[i]
|
|
139
|
-
calls[i] = [address, func.encode(args)]
|
|
140
|
-
funcs[i] = func
|
|
180
|
+
let [address, args] = list[i]
|
|
181
|
+
calls[i] = [address, func.encode(args)]
|
|
182
|
+
funcs[i] = func
|
|
141
183
|
}
|
|
142
|
-
return [calls, funcs, page]
|
|
184
|
+
return [calls, funcs, page]
|
|
143
185
|
}
|
|
144
186
|
case 3: {
|
|
145
|
-
let func = args[0]
|
|
146
|
-
let address = args[1]
|
|
147
|
-
let list = args[2]
|
|
148
|
-
let calls = new Array(list.length)
|
|
149
|
-
let funcs = new Array(list.length)
|
|
187
|
+
let func: AnyFunc = args[0]
|
|
188
|
+
let address: string = args[1]
|
|
189
|
+
let list: any[][] = args[2]
|
|
190
|
+
let calls = new Array(list.length)
|
|
191
|
+
let funcs = new Array(list.length)
|
|
150
192
|
for (let i = 0; i < list.length; i++) {
|
|
151
|
-
let args = list[i]
|
|
152
|
-
calls[i] = [address, func.encode(args)]
|
|
153
|
-
funcs[i] = func
|
|
193
|
+
let args = list[i]
|
|
194
|
+
calls[i] = [address, func.encode(args)]
|
|
195
|
+
funcs[i] = func
|
|
154
196
|
}
|
|
155
|
-
return [calls, funcs, page]
|
|
197
|
+
return [calls, funcs, page]
|
|
156
198
|
}
|
|
157
199
|
default:
|
|
158
|
-
throw new Error('unexpected number of arguments')
|
|
200
|
+
throw new Error('unexpected number of arguments')
|
|
159
201
|
}
|
|
160
202
|
}
|
|
161
203
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
let from = 0;
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
function* splitIntoPages(size: number, page: number): Iterable<[from: number, to: number]> {
|
|
207
|
+
let from = 0
|
|
167
208
|
while (size) {
|
|
168
|
-
let step = Math.min(page, size)
|
|
169
|
-
let to = from + step
|
|
170
|
-
yield [from, to]
|
|
171
|
-
size -= step
|
|
172
|
-
from = to
|
|
209
|
+
let step = Math.min(page, size)
|
|
210
|
+
let to = from + step
|
|
211
|
+
yield [from, to]
|
|
212
|
+
size -= step
|
|
213
|
+
from = to
|
|
173
214
|
}
|
|
174
215
|
}
|
|
216
|
+
*/
|
|
175
217
|
//# sourceMappingURL=multicall.js.map
|
package/lib/multicall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.js","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"multicall.js","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsNE"}
|
package/lib/typegen.d.ts
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
import * as ethers from 'ethers';
|
|
2
1
|
import { Logger } from '@subsquid/logger';
|
|
2
|
+
import type { Abi } from 'abitype';
|
|
3
3
|
import { OutDir } from '@subsquid/util-internal-code-printer';
|
|
4
4
|
export declare class Typegen {
|
|
5
|
-
private dest;
|
|
6
5
|
private abi;
|
|
7
|
-
private basename;
|
|
8
6
|
private log;
|
|
9
7
|
private out;
|
|
10
|
-
constructor(dest: OutDir, abi:
|
|
11
|
-
generate(): void
|
|
12
|
-
private writeAbi;
|
|
8
|
+
constructor(dest: OutDir, abi: Abi, basename: string, log: Logger);
|
|
9
|
+
generate(): Promise<void>;
|
|
13
10
|
private generateEvents;
|
|
11
|
+
private topic0;
|
|
12
|
+
private toTypes;
|
|
14
13
|
private generateFunctions;
|
|
14
|
+
private functionSelector;
|
|
15
15
|
private generateContract;
|
|
16
|
-
private
|
|
16
|
+
private cannonicalType;
|
|
17
|
+
private sighash;
|
|
17
18
|
private getPropName;
|
|
19
|
+
private getPropNameGetter;
|
|
18
20
|
private getOverloads;
|
|
21
|
+
private capitalize;
|
|
22
|
+
private getOverloadIndex;
|
|
23
|
+
private toEventType;
|
|
24
|
+
private generateEventTypes;
|
|
25
|
+
private toFunctionTypes;
|
|
26
|
+
private generateFunctionTypes;
|
|
19
27
|
private functionOverloads;
|
|
20
28
|
private eventOverloads;
|
|
21
29
|
private getFunctions;
|
package/lib/typegen.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../src/typegen.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"typegen.d.ts","sourceRoot":"","sources":["../src/typegen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAIzC,OAAO,KAAK,EAAE,GAAG,EAAuC,MAAM,SAAS,CAAA;AACvE,OAAO,EAAc,MAAM,EAAE,MAAM,sCAAsC,CAAA;AAYzE,qBAAa,OAAO;IAKhB,OAAO,CAAC,GAAG;IAEX,OAAO,CAAC,GAAG;IANb,OAAO,CAAC,GAAG,CAAY;gBAGrB,IAAI,EAAE,MAAM,EACJ,GAAG,EAAE,GAAG,EAChB,QAAQ,EAAE,MAAM,EACR,GAAG,EAAE,MAAM;IAKf,QAAQ;IAmBd,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,iBAAiB;IAyBzB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,gBAAgB;IA4BxB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,SAAS;CAGlB"}
|
package/lib/typegen.js
CHANGED
|
@@ -1,70 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
2
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
3
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
4
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
5
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
7
|
};
|
|
24
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
-
if (mod && mod.__esModule) return mod;
|
|
26
|
-
var result = {};
|
|
27
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
-
__setModuleDefault(result, mod);
|
|
29
|
-
return result;
|
|
30
|
-
};
|
|
31
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
32
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
10
|
};
|
|
34
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
12
|
exports.Typegen = void 0;
|
|
36
|
-
const ethers = __importStar(require("ethers"));
|
|
37
13
|
const util_internal_1 = require("@subsquid/util-internal");
|
|
14
|
+
const evm_abi_1 = require("@subsquid/evm-abi");
|
|
38
15
|
const types_1 = require("./util/types");
|
|
16
|
+
function areItemEqual(item1, item2) {
|
|
17
|
+
if (item1.name !== item2.name || item1.inputs.length !== item2.inputs.length || item1.type !== item2.type) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return item1.inputs.every((input, idx) => {
|
|
21
|
+
const input2 = item2.inputs[idx];
|
|
22
|
+
return input.name === input2.name && input.type === input2.type;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
39
25
|
class Typegen {
|
|
40
26
|
constructor(dest, abi, basename, log) {
|
|
41
|
-
this.dest = dest;
|
|
42
27
|
this.abi = abi;
|
|
43
|
-
this.basename = basename;
|
|
44
28
|
this.log = log;
|
|
45
29
|
this.out = dest.file(basename + '.ts');
|
|
46
30
|
}
|
|
47
|
-
generate() {
|
|
48
|
-
this.out.line(
|
|
49
|
-
this.out.line(
|
|
50
|
-
this.out.line(`import {
|
|
51
|
-
this.out.line();
|
|
52
|
-
this.out.line("export const abi = new ethers.Interface(ABI_JSON);");
|
|
31
|
+
async generate() {
|
|
32
|
+
this.out.line(`import * as p from '@subsquid/evm-codec'`);
|
|
33
|
+
this.out.line(`import { event, fun, indexed, ContractBase } from '@subsquid/evm-abi'`);
|
|
34
|
+
this.out.line(`import type { EventParams as EParams, FunctionArguments, FunctionReturn } from '@subsquid/evm-abi'`);
|
|
53
35
|
this.generateEvents();
|
|
54
36
|
this.generateFunctions();
|
|
55
37
|
this.generateContract();
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
38
|
+
this.generateEventTypes();
|
|
39
|
+
this.generateFunctionTypes();
|
|
40
|
+
await this.out.write();
|
|
58
41
|
this.log.info(`saved ${this.out.file}`);
|
|
59
42
|
}
|
|
60
|
-
writeAbi() {
|
|
61
|
-
let out = this.dest.file(this.basename + '.abi.ts');
|
|
62
|
-
let json = this.abi.formatJson();
|
|
63
|
-
json = JSON.stringify(JSON.parse(json), null, 4);
|
|
64
|
-
out.line(`export const ABI_JSON = ${json}`);
|
|
65
|
-
out.write();
|
|
66
|
-
this.log.info(`saved ${out.file}`);
|
|
67
|
-
}
|
|
68
43
|
generateEvents() {
|
|
69
44
|
let events = this.getEvents();
|
|
70
45
|
if (events.length == 0) {
|
|
@@ -73,12 +48,16 @@ class Typegen {
|
|
|
73
48
|
this.out.line();
|
|
74
49
|
this.out.block(`export const events =`, () => {
|
|
75
50
|
for (let e of events) {
|
|
76
|
-
this.out.line(`${this.getPropName(e)}:
|
|
77
|
-
this.out.indentation(() => this.out.line(`abi, '${e.topicHash}'`));
|
|
78
|
-
this.out.line('),');
|
|
51
|
+
this.out.line(`${this.getPropName(e)}: event("${this.topic0(e)}", {${this.toTypes(e.inputs)}}),`);
|
|
79
52
|
}
|
|
80
53
|
});
|
|
81
54
|
}
|
|
55
|
+
topic0(e) {
|
|
56
|
+
return `0x${(0, evm_abi_1.keccak256)(this.sighash(e)).toString('hex')}`;
|
|
57
|
+
}
|
|
58
|
+
toTypes(inputs) {
|
|
59
|
+
return inputs.map((input, idx) => (0, types_1.getType)(input, idx)).join(', ');
|
|
60
|
+
}
|
|
82
61
|
generateFunctions() {
|
|
83
62
|
let functions = this.getFunctions();
|
|
84
63
|
if (functions.length == 0) {
|
|
@@ -87,57 +66,127 @@ class Typegen {
|
|
|
87
66
|
this.out.line();
|
|
88
67
|
this.out.block(`export const functions =`, () => {
|
|
89
68
|
for (let f of functions) {
|
|
90
|
-
let
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
69
|
+
let returnType = '';
|
|
70
|
+
if (f.outputs?.length === 1) {
|
|
71
|
+
returnType = (0, types_1.getType)({ ...f.outputs[0], name: undefined });
|
|
72
|
+
}
|
|
73
|
+
if (f.outputs?.length > 1) {
|
|
74
|
+
returnType = `{${this.toTypes(f.outputs)}}`;
|
|
75
|
+
}
|
|
76
|
+
this.out.line(`${this.getPropName(f)}: fun("${this.functionSelector(f)}", {${this.toTypes(f.inputs)}}, ${returnType}),`);
|
|
97
77
|
}
|
|
98
78
|
});
|
|
99
79
|
}
|
|
80
|
+
functionSelector(f) {
|
|
81
|
+
const sighash = this.sighash(f);
|
|
82
|
+
return `0x${(0, evm_abi_1.keccak256)(sighash).slice(0, 4).toString('hex')}`;
|
|
83
|
+
}
|
|
100
84
|
generateContract() {
|
|
101
85
|
this.out.line();
|
|
102
86
|
this.out.block(`export class Contract extends ContractBase`, () => {
|
|
103
87
|
let functions = this.getFunctions();
|
|
104
88
|
for (let f of functions) {
|
|
105
|
-
if (f.
|
|
89
|
+
if ((f.stateMutability === 'pure' || f.stateMutability === 'view') &&
|
|
90
|
+
f.outputs?.length) {
|
|
106
91
|
this.out.line();
|
|
107
|
-
let argNames = f.inputs.map((a, idx) => a.name || `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
92
|
+
let argNames = f.inputs.map((a, idx) => a.name || `_${idx}`);
|
|
93
|
+
const ref = this.getPropNameGetter(f);
|
|
94
|
+
const [argsType] = this.toFunctionTypes(f);
|
|
95
|
+
let args = f.inputs
|
|
96
|
+
.map((a, idx) => `${argNames[idx]}: ${argsType}["${argNames[idx]}"]`)
|
|
97
|
+
.join(', ');
|
|
98
|
+
this.out.block(`${this.getPropName(f)}(${args})`, () => {
|
|
99
|
+
this.out.line(`return this.eth_call(functions${ref}, {${argNames.join(', ')}})`);
|
|
111
100
|
});
|
|
112
101
|
}
|
|
113
102
|
}
|
|
114
103
|
});
|
|
115
104
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return `[${key}]`;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
return '.' + key;
|
|
105
|
+
cannonicalType(param) {
|
|
106
|
+
if (!param.type.startsWith('tuple')) {
|
|
107
|
+
return param.type;
|
|
123
108
|
}
|
|
109
|
+
const arrayBrackets = param.type.slice(5);
|
|
110
|
+
return `(${param.components.map((param) => this.cannonicalType(param))})${arrayBrackets}`;
|
|
111
|
+
}
|
|
112
|
+
sighash(item) {
|
|
113
|
+
return `${item.name}(${item.inputs
|
|
114
|
+
.map((param) => this.cannonicalType(param))
|
|
115
|
+
.join(',')})`;
|
|
124
116
|
}
|
|
125
117
|
getPropName(item) {
|
|
126
118
|
if (this.getOverloads(item) == 1) {
|
|
127
119
|
return item.name;
|
|
128
120
|
}
|
|
129
121
|
else {
|
|
130
|
-
return `
|
|
122
|
+
return `"${this.sighash(item)}"`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
getPropNameGetter(item) {
|
|
126
|
+
if (this.getOverloads(item) == 1) {
|
|
127
|
+
return '.' + item.name;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
return `["${this.sighash(item)}"]`;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
getOverloads(item) {
|
|
134
|
-
if (item
|
|
134
|
+
if (item.type === 'event') {
|
|
135
135
|
return this.eventOverloads()[item.name];
|
|
136
136
|
}
|
|
137
137
|
else {
|
|
138
138
|
return this.functionOverloads()[item.name];
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
|
+
capitalize(s) {
|
|
142
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
143
|
+
}
|
|
144
|
+
getOverloadIndex(item) {
|
|
145
|
+
const abi = [...this.getEvents(), ...this.getFunctions()];
|
|
146
|
+
const overloads = abi.filter((x) => x.name === item.name);
|
|
147
|
+
return overloads.findIndex((x) => areItemEqual(x, item));
|
|
148
|
+
}
|
|
149
|
+
toEventType(e) {
|
|
150
|
+
if (this.getOverloads(e) === 1) {
|
|
151
|
+
return `${this.capitalize(e.name)}EventArgs`;
|
|
152
|
+
}
|
|
153
|
+
const index = this.getOverloadIndex(e);
|
|
154
|
+
return `${this.capitalize(e.name)}EventArgs_${index}`;
|
|
155
|
+
}
|
|
156
|
+
generateEventTypes() {
|
|
157
|
+
const events = this.getEvents();
|
|
158
|
+
if (events.length == 0) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.out.line();
|
|
162
|
+
this.out.line(`/// Event types`);
|
|
163
|
+
for (let e of events) {
|
|
164
|
+
const propName = this.getPropNameGetter(e);
|
|
165
|
+
this.out.line(`export type ${this.toEventType(e)} = EParams<typeof events${propName}>`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
toFunctionTypes(f) {
|
|
169
|
+
if (this.getOverloads(f) === 1) {
|
|
170
|
+
return [`${this.capitalize(f.name)}Params`, `${this.capitalize(f.name)}Return`];
|
|
171
|
+
}
|
|
172
|
+
const index = this.getOverloadIndex(f);
|
|
173
|
+
return [`${this.capitalize(f.name)}Params_${index}`, `${this.capitalize(f.name)}Return_${index}`];
|
|
174
|
+
}
|
|
175
|
+
generateFunctionTypes() {
|
|
176
|
+
let functions = this.getFunctions();
|
|
177
|
+
if (functions.length == 0) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.out.line();
|
|
181
|
+
this.out.line(`/// Function types`);
|
|
182
|
+
for (let f of functions) {
|
|
183
|
+
const propName = this.getPropNameGetter(f);
|
|
184
|
+
const [args, ret] = this.toFunctionTypes(f);
|
|
185
|
+
this.out.line(`export type ${args} = FunctionArguments<typeof functions${propName}>`);
|
|
186
|
+
this.out.line(`export type ${ret} = FunctionReturn<typeof functions${propName}>`);
|
|
187
|
+
this.out.line();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
141
190
|
functionOverloads() {
|
|
142
191
|
let overloads = {};
|
|
143
192
|
for (let item of this.getFunctions()) {
|
|
@@ -153,10 +202,10 @@ class Typegen {
|
|
|
153
202
|
return overloads;
|
|
154
203
|
}
|
|
155
204
|
getFunctions() {
|
|
156
|
-
return this.abi.
|
|
205
|
+
return this.abi.filter((f) => f.type === 'function');
|
|
157
206
|
}
|
|
158
207
|
getEvents() {
|
|
159
|
-
return this.abi.
|
|
208
|
+
return this.abi.filter((f) => f.type === 'event');
|
|
160
209
|
}
|
|
161
210
|
}
|
|
162
211
|
exports.Typegen = Typegen;
|