@subsquid/evm-typegen 1.3.0 → 2.0.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/README.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @subsquid/evm-typegen
2
2
 
3
- This package provides `squid-evm-typegen(1)` command
4
- which can generate TypeScript definitions for evm logs
5
- to be used within [substrate-processor](../substrate-processor) mapping handlers.
3
+ Generates TypeScript facades for EVM transactions, logs and `eth_call` queries.
4
+
5
+ The generated facade classes are assumed to be used by [squids](https://docs.Subsquid.io/overview) indexing EVM data.
6
+ The generated classes depend on [ethers](https://www.npmjs.com/package/ethers).
7
+
8
+ ## Usage
9
+
10
+ ```
11
+ npm i -g @subsquid/evm-typegen
12
+ ```
13
+
14
+ ```
15
+ Arguments:
16
+ output-dir output directory for generated definitions
17
+ abi ABI file
18
+
19
+ Options:
20
+ --multicall generate facade for MakerDAO multicall contract
21
+ --etherscan-api <url> etherscan API to fetch contract ABI by a known address
22
+ --clean delete output directory before run
23
+ -h, --help display help for command
24
+
25
+ ABI file can be specified in three ways:
26
+
27
+ 1. as a plain JSON file:
28
+
29
+ squid-evm-typegen src/abi erc20.json
30
+
31
+ 2. as a contract address (to fetch ABI from etherscan)
32
+
33
+ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413
34
+
35
+ 3. as an arbitrary http url
36
+
37
+ squid-evm-typegen src/abi https://example.com/erc721.json
38
+
39
+ In all cases typegen will use ABI's basename as a basename of generated files.
40
+ You can overwrite basename of generated files using fragment (#) suffix.
41
+
42
+ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract
43
+ ```
package/bin/run.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('../lib/main').run()
3
+ require('../lib/main')
@@ -0,0 +1,49 @@
1
+ import * as ethers from 'ethers';
2
+ export interface LogRecord {
3
+ topics: string[];
4
+ data: string;
5
+ }
6
+ export declare class LogEvent<Args> {
7
+ private abi;
8
+ readonly topic: string;
9
+ private fragment;
10
+ constructor(abi: ethers.utils.Interface, topic: string);
11
+ decode(rec: LogRecord): Args;
12
+ }
13
+ export declare class Func<Args extends any[], FieldArgs, Result> {
14
+ private abi;
15
+ readonly sighash: string;
16
+ private fragment;
17
+ constructor(abi: ethers.utils.Interface, sighash: string);
18
+ decode(input: ethers.utils.BytesLike): Args & FieldArgs;
19
+ encode(args: Args): string;
20
+ decodeResult(output: ethers.utils.BytesLike): Result;
21
+ tryDecodeResult(output: ethers.utils.BytesLike): Result | undefined;
22
+ }
23
+ export declare function isFunctionResultDecodingError(val: unknown): val is Error & {
24
+ data: string;
25
+ };
26
+ export interface ChainContext {
27
+ _chain: Chain;
28
+ }
29
+ export interface BlockContext {
30
+ _chain: Chain;
31
+ block: Block;
32
+ }
33
+ export interface Block {
34
+ height: number;
35
+ }
36
+ export interface Chain {
37
+ client: {
38
+ call: <T = any>(method: string, params?: unknown[]) => Promise<T>;
39
+ };
40
+ }
41
+ export declare class ContractBase {
42
+ private readonly _chain;
43
+ private readonly blockHeight;
44
+ readonly address: string;
45
+ constructor(ctx: BlockContext, address: string);
46
+ constructor(ctx: ChainContext, block: Block, address: string);
47
+ eth_call<Args extends any[], FieldArgs, Result>(func: Func<Args, FieldArgs, Result>, args: Args): Promise<Result>;
48
+ }
49
+ //# sourceMappingURL=abi.support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.support.d.ts","sourceRoot":"","sources":["../src/abi.support.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAGhC,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACf;AAGD,qBAAa,QAAQ,CAAC,IAAI;IAGV,OAAO,CAAC,GAAG;aAA0C,KAAK,EAAE,MAAM;IAF9E,OAAO,CAAC,QAAQ,CAA4B;gBAExB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAkB,KAAK,EAAE,MAAM;IAI9E,MAAM,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI;CAG/B;AAGD,qBAAa,IAAI,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM;IAGvC,OAAO,CAAC,GAAG;aAA0C,OAAO,EAAE,MAAM;IAFhF,OAAO,CAAC,QAAQ,CAA+B;gBAE3B,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAkB,OAAO,EAAE,MAAM;IAIhF,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,SAAS;IAIvD,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAI1B,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM;IAKpD,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,GAAG,SAAS;CAOtE;AAGD,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,KAAK,GAAG;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAOzF;AAGD,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,KAAK,CAAA;CAChB;AAGD,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,KAAK,CAAA;IACb,KAAK,EAAE,KAAK,CAAA;CACf;AAGD,MAAM,WAAW,KAAK;IAClB,MAAM,EAAE,MAAM,CAAA;CACjB;AAGD,MAAM,WAAW,KAAK;IAClB,MAAM,EAAG;QACL,IAAI,EAAE,CAAC,CAAC,GAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;KAClE,CAAA;CACJ;AAGD,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAO;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBAEZ,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM;gBAClC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM;IAetD,QAAQ,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CAQ1H"}
@@ -0,0 +1,100 @@
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
+ 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.ContractBase = exports.isFunctionResultDecodingError = exports.Func = exports.LogEvent = void 0;
27
+ const ethers = __importStar(require("ethers"));
28
+ class LogEvent {
29
+ constructor(abi, topic) {
30
+ this.abi = abi;
31
+ this.topic = topic;
32
+ this.fragment = abi.getEvent(topic);
33
+ }
34
+ decode(rec) {
35
+ return this.abi.decodeEventLog(this.fragment, rec.data, rec.topics);
36
+ }
37
+ }
38
+ exports.LogEvent = LogEvent;
39
+ class Func {
40
+ constructor(abi, sighash) {
41
+ this.abi = abi;
42
+ this.sighash = sighash;
43
+ this.fragment = abi.getFunction(sighash);
44
+ }
45
+ decode(input) {
46
+ return this.abi.decodeFunctionData(this.fragment, input);
47
+ }
48
+ encode(args) {
49
+ return this.abi.encodeFunctionData(this.fragment, args);
50
+ }
51
+ decodeResult(output) {
52
+ const decoded = this.abi.decodeFunctionResult(this.fragment, output);
53
+ return decoded.length > 1 ? decoded : decoded[0];
54
+ }
55
+ tryDecodeResult(output) {
56
+ try {
57
+ return this.decodeResult(output);
58
+ }
59
+ catch (err) {
60
+ return undefined;
61
+ }
62
+ }
63
+ }
64
+ exports.Func = Func;
65
+ function isFunctionResultDecodingError(val) {
66
+ if (!(val instanceof Error))
67
+ return false;
68
+ let err = val;
69
+ return err.code == 'CALL_EXCEPTION'
70
+ && typeof err.data == 'string'
71
+ && !err.errorArgs
72
+ && !err.errorName;
73
+ }
74
+ exports.isFunctionResultDecodingError = isFunctionResultDecodingError;
75
+ class ContractBase {
76
+ constructor(ctx, blockOrAddress, address) {
77
+ this._chain = ctx._chain;
78
+ if (typeof blockOrAddress === 'string') {
79
+ this.blockHeight = ctx.block.height;
80
+ this.address = ethers.utils.getAddress(blockOrAddress);
81
+ }
82
+ else {
83
+ if (address == null) {
84
+ throw new Error('missing contract address');
85
+ }
86
+ this.blockHeight = blockOrAddress.height;
87
+ this.address = ethers.utils.getAddress(address);
88
+ }
89
+ }
90
+ async eth_call(func, args) {
91
+ let data = func.encode(args);
92
+ let result = await this._chain.client.call('eth_call', [
93
+ { to: this.address, data },
94
+ '0x' + this.blockHeight.toString(16)
95
+ ]);
96
+ return func.decodeResult(result);
97
+ }
98
+ }
99
+ exports.ContractBase = ContractBase;
100
+ //# sourceMappingURL=abi.support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.support.js","sourceRoot":"","sources":["../src/abi.support.ts"],"names":[],"mappings":"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"}
package/lib/main.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare function run(): void;
1
+ export {};
2
2
  //# sourceMappingURL=main.d.ts.map
package/lib/main.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAKA,wBAAgB,GAAG,IAAI,IAAI,CA4B1B"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/lib/main.js CHANGED
@@ -1,37 +1,191 @@
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
+ 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
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.run = void 0;
29
+ const abi_1 = require("@ethersproject/abi");
30
+ const address_1 = require("@ethersproject/address");
31
+ const logger_1 = require("@subsquid/logger");
32
+ const util_internal_1 = require("@subsquid/util-internal");
33
+ const util_internal_code_printer_1 = require("@subsquid/util-internal-code-printer");
34
+ const validator = __importStar(require("@subsquid/util-internal-commander"));
7
35
  const commander_1 = require("commander");
36
+ const fs = __importStar(require("fs"));
8
37
  const path_1 = __importDefault(require("path"));
9
- const process_1 = __importDefault(require("process"));
10
38
  const typegen_1 = require("./typegen");
11
- function run() {
12
- commander_1.program.description(`
13
- Generates TypeScript definitions for evm log events
14
- for use within substrate-processor mapping handlers.
39
+ const fetch_1 = require("./util/fetch");
40
+ const LOG = (0, logger_1.createLogger)('sqd:evm-typegen');
41
+ (0, util_internal_1.runProgram)(async function () {
42
+ commander_1.program
43
+ .description(`
44
+ Generates TypeScript facades for EVM transactions, logs and eth_call queries.
45
+
46
+ The generated facades are assumed to be used by "squids" indexing EVM data.
15
47
  `.trim())
16
- .requiredOption('--abi <path>', 'path to a JSON abi file')
17
- .requiredOption('--output <path>', 'path for output typescript file');
48
+ .name('squid-evm-typegen')
49
+ .argument('<output-dir>', 'output directory for generated definitions')
50
+ .argument('[abi...]', 'ABI file', specArgument)
51
+ .option('--multicall', 'generate facade for MakerDAO multicall contract')
52
+ .option('--etherscan-api <url>', 'etherscan API to fetch contract ABI by a known address', validator.Url(['http:', 'https:']))
53
+ .option('--clean', 'delete output directory before run')
54
+ .addHelpText('afterAll', `
55
+ ABI file can be specified in three ways:
56
+
57
+ 1. as a plain JSON file:
58
+
59
+ squid-evm-typegen src/abi erc20.json
60
+
61
+ 2. as a contract address (to fetch ABI from etherscan)
62
+
63
+ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413
64
+
65
+ 3. as an arbitrary http url
66
+
67
+ squid-evm-typegen src/abi https://example.com/erc721.json
68
+
69
+ In all cases typegen will use ABI's basename as a basename of generated files.
70
+ You can overwrite basename of generated files using fragment (#) suffix.
71
+
72
+ squid-evm-typegen src/abi 0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413#contract
73
+ `);
18
74
  commander_1.program.parse();
19
- const options = commander_1.program.opts();
20
- const inputPath = options.abi;
21
- const outputPath = options.output;
22
- if (path_1.default.parse(inputPath).ext !== ".json") {
23
- throw new Error("invalid abi file extension");
75
+ let opts = commander_1.program.opts();
76
+ let dest = new util_internal_code_printer_1.OutDir(commander_1.program.processedArgs[0]);
77
+ let specs = commander_1.program.processedArgs[1];
78
+ if (opts.clean && dest.exists()) {
79
+ LOG.info(`deleting ${dest.path()}`);
80
+ dest.del();
81
+ }
82
+ if (specs.length == 0 && !opts.multicall) {
83
+ LOG.warn('no ABI files given, nothing to generate');
84
+ return;
85
+ }
86
+ dest.add('abi.support.ts', [__dirname, '../src/abi.support.ts']);
87
+ LOG.info(`saved ${dest.path('abi.support.ts')}`);
88
+ if (opts.multicall) {
89
+ dest.add('multicall.ts', [__dirname, '../src/multicall.ts']);
90
+ LOG.info(`saved ${dest.path('multicall.ts')}`);
91
+ }
92
+ for (let spec of specs) {
93
+ LOG.info(`processing ${spec.src}`);
94
+ let abi_json = await read(spec, opts);
95
+ let abi = new abi_1.Interface(abi_json);
96
+ new typegen_1.Typegen(dest, abi, spec.name, LOG).generate();
97
+ }
98
+ }, err => LOG.fatal(err));
99
+ async function read(spec, options) {
100
+ if (spec.kind == 'address') {
101
+ return fetchFromEtherscan(spec.src, options?.etherscanApi);
24
102
  }
25
- if (path_1.default.parse(outputPath).ext !== ".ts") {
26
- throw new Error("invalid output file extension");
103
+ let abi;
104
+ if (spec.kind == 'url') {
105
+ abi = await (0, fetch_1.GET)(spec.src);
27
106
  }
28
- try {
29
- new typegen_1.Typegen(inputPath, outputPath).generate();
107
+ else {
108
+ abi = JSON.parse(fs.readFileSync(spec.src, 'utf-8'));
109
+ }
110
+ if (Array.isArray(abi)) {
111
+ return abi;
112
+ }
113
+ else if (Array.isArray(abi?.abi)) {
114
+ return abi.abi;
115
+ }
116
+ else {
117
+ throw new Error('Unrecognized ABI format');
118
+ }
119
+ }
120
+ async function fetchFromEtherscan(address, api) {
121
+ api = api || 'https://api.etherscan.io/';
122
+ let url = new URL('api?module=contract&action=getabi', api);
123
+ url.searchParams.set('address', address);
124
+ let response;
125
+ let attempts = 2;
126
+ while (true) {
127
+ response = await (0, fetch_1.GET)(url.toString());
128
+ if (response.status == '0' && response.result.includes('rate limit') && --attempts) {
129
+ LOG.warn('faced rate limit error while trying to fetch contract ABI. Trying again in 2 seconds.');
130
+ await (0, util_internal_1.wait)(2000);
131
+ }
132
+ else {
133
+ break;
134
+ }
30
135
  }
31
- catch (err) {
32
- console.error(`evm-typegen error: ${err.toString()}`);
33
- process_1.default.exit(1);
136
+ if (response.status == '1') {
137
+ return JSON.parse(response.result);
34
138
  }
139
+ else {
140
+ throw new Error(`Failed to fetch contract ABI from ${api}: ${response.result}`);
141
+ }
142
+ }
143
+ function specArgument(value, prev) {
144
+ let spec = parseSpec(value);
145
+ prev.push(spec);
146
+ return prev;
147
+ }
148
+ function parseSpec(spec) {
149
+ let [src, fragment] = splitFragment(spec);
150
+ if (src.startsWith('0x')) {
151
+ if (!(0, address_1.isAddress)(src))
152
+ throw new commander_1.InvalidArgumentError('Invalid contract address');
153
+ return {
154
+ kind: 'address',
155
+ src,
156
+ name: fragment || src
157
+ };
158
+ }
159
+ else if (src.includes('://')) {
160
+ let u = new URL(validator.Url(['http:', 'https:'])(src));
161
+ return {
162
+ kind: 'url',
163
+ src,
164
+ name: fragment || basename(u.pathname)
165
+ };
166
+ }
167
+ else {
168
+ return {
169
+ kind: 'file',
170
+ src,
171
+ name: fragment || basename(src)
172
+ };
173
+ }
174
+ }
175
+ function splitFragment(spec) {
176
+ let parts = spec.split('#');
177
+ if (parts.length > 1) {
178
+ let fragment = parts.pop();
179
+ return [parts.join('#'), fragment];
180
+ }
181
+ else {
182
+ return [spec, ''];
183
+ }
184
+ }
185
+ function basename(file) {
186
+ let name = path_1.default.parse(file).name;
187
+ if (name)
188
+ return name;
189
+ throw new commander_1.InvalidArgumentError(`Can't derive target basename for output files. Use url fragment to specify it, e.g. #erc20`);
35
190
  }
36
- exports.run = run;
37
191
  //# 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":";;;;;;AAAA,yCAAiC;AACjC,gDAAuB;AACvB,sDAA6B;AAC7B,uCAAiC;AAEjC,SAAgB,GAAG;IACf,mBAAO,CAAC,WAAW,CAAC;;;KAGnB,CAAC,IAAI,EAAE,CAAC;SACJ,cAAc,CAAC,cAAc,EAAE,yBAAyB,CAAC;SACzD,cAAc,CAAC,iBAAiB,EAAE,iCAAiC,CAAC,CAAC;IAE1E,mBAAO,CAAC,KAAK,EAAE,CAAC;IAEhB,MAAM,OAAO,GAAG,mBAAO,CAAC,IAAI,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAElC,IAAI,cAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;KACjD;IAED,IAAI,cAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,KAAK,KAAK,EAAE;QACtC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;KACpD;IAED,IAAI;QACA,IAAI,iBAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;KACjD;IAAC,OAAO,GAAQ,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtD,iBAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACnB;AACL,CAAC;AA5BD,kBA4BC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import * as ethers from 'ethers';
2
+ import { ContractBase, Func } from './abi.support';
3
+ declare type AnyFunc = Func<any, {}, any>;
4
+ declare type Call = [address: string, bytes: string];
5
+ export declare type MulticallResult<T> = {
6
+ success: true;
7
+ value: T;
8
+ } | {
9
+ success: false;
10
+ returnData?: string;
11
+ value?: undefined;
12
+ };
13
+ export declare class Multicall extends ContractBase {
14
+ static aggregate: Func<[calls: Call[]], {}, {
15
+ blockNumber: ethers.ethers.BigNumber;
16
+ returnData: string[];
17
+ }>;
18
+ static try_aggregate: Func<[requireSuccess: boolean, calls: [target: string, callData: string][]], {}, {
19
+ success: boolean;
20
+ returnData: string;
21
+ }[]>;
22
+ aggregate<Args extends any[], R>(func: Func<Args, {}, R>, address: string, calls: Args[], paging?: number): Promise<R[]>;
23
+ aggregate<Args extends any[], R>(func: Func<Args, {}, R>, calls: [address: string, args: Args][], paging?: number): Promise<R[]>;
24
+ aggregate(calls: [func: AnyFunc, address: string, args: any[]][], paging?: number): Promise<any[]>;
25
+ tryAggregate<Args extends any[], R>(func: Func<Args, {}, R>, address: string, calls: Args[], paging?: number): Promise<MulticallResult<R>[]>;
26
+ tryAggregate<Args extends any[], R>(func: Func<Args, {}, R>, calls: [address: string, args: Args][], paging?: number): Promise<MulticallResult<R>[]>;
27
+ tryAggregate(calls: [func: AnyFunc, address: string, args: any[]][], paging?: number): Promise<MulticallResult<any>[]>;
28
+ private makeCalls;
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=multicall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multicall.d.ts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAC,YAAY,EAAE,IAAI,EAAC,MAAM,eAAe,CAAA;AAoDhD,aAAK,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;AACjC,aAAK,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAa5C,oBAAY,eAAe,CAAC,CAAC,IAAI;IAC7B,OAAO,EAAE,IAAI,CAAA;IACb,KAAK,EAAE,CAAC,CAAA;CACX,GAAG;IACA,OAAO,EAAE,KAAK,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,SAAS,CAAA;CACpB,CAAA;AAGD,qBAAa,SAAU,SAAQ,YAAY;IACvC,MAAM,CAAC,SAAS;;;OAAY;IAC5B,MAAM,CAAC,aAAa;;;SAAgB;IAEpC,SAAS,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC,EAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,EAAE,CAAC;IAEf,SAAS,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC,EAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EACtC,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,EAAE,CAAC;IAEf,SAAS,CACL,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,EACtD,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,EAAE,CAAC;IAgBjB,YAAY,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC,EAC9B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhC,YAAY,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC,EAC9B,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EACvB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EACtC,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhC,YAAY,CACR,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,EACtD,MAAM,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;IA2BlC,OAAO,CAAC,SAAS;CA2CpB"}
@@ -0,0 +1,175 @@
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
+ 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");
29
+ const abi = new ethers.utils.Interface([
30
+ {
31
+ type: 'function',
32
+ name: 'aggregate',
33
+ stateMutability: 'nonpayable',
34
+ inputs: [
35
+ {
36
+ name: 'calls',
37
+ type: 'tuple[]',
38
+ components: [
39
+ { name: 'target', type: 'address' },
40
+ { name: 'callData', type: 'bytes' },
41
+ ]
42
+ }
43
+ ],
44
+ outputs: [
45
+ { name: 'blockNumber', type: 'uint256' },
46
+ { name: 'returnData', type: 'bytes[]' },
47
+ ]
48
+ },
49
+ {
50
+ name: 'tryAggregate',
51
+ type: 'function',
52
+ stateMutability: 'nonpayable',
53
+ inputs: [
54
+ { name: 'requireSuccess', type: 'bool' },
55
+ {
56
+ name: 'calls',
57
+ type: 'tuple[]',
58
+ components: [
59
+ { name: 'target', type: 'address' },
60
+ { name: 'callData', type: 'bytes' },
61
+ ]
62
+ }
63
+ ],
64
+ outputs: [
65
+ {
66
+ name: 'returnData',
67
+ type: 'tuple[]',
68
+ components: [
69
+ { name: 'success', type: 'bool' },
70
+ { name: 'returnData', type: 'bytes' },
71
+ ]
72
+ },
73
+ ]
74
+ }
75
+ ]);
76
+ const aggregate = new abi_support_1.Func(abi, abi.getSighash('aggregate'));
77
+ const try_aggregate = new abi_support_1.Func(abi, abi.getSighash('tryAggregate'));
78
+ class Multicall extends abi_support_1.ContractBase {
79
+ async aggregate(...args) {
80
+ let [calls, funcs, page] = this.makeCalls(args);
81
+ let size = calls.length;
82
+ let results = new Array(size);
83
+ for (let [from, to] of splitIntoPages(size, page)) {
84
+ let { returnData } = await this.eth_call(aggregate, [calls.slice(from, to)]);
85
+ for (let i = from; i < to; i++) {
86
+ let data = returnData[i - from];
87
+ results[i] = funcs[i].decodeResult(data);
88
+ }
89
+ }
90
+ return results;
91
+ }
92
+ async tryAggregate(...args) {
93
+ let [calls, funcs, page] = this.makeCalls(args);
94
+ let size = calls.length;
95
+ let results = new Array(size);
96
+ for (let [from, to] of splitIntoPages(size, page)) {
97
+ let response = await this.eth_call(try_aggregate, [false, calls.slice(from, to)]);
98
+ for (let i = from; i < to; i++) {
99
+ let res = response[i - from];
100
+ if (res.success) {
101
+ try {
102
+ results[i] = {
103
+ success: true,
104
+ value: funcs[i].decodeResult(res.returnData)
105
+ };
106
+ }
107
+ catch (err) {
108
+ results[i] = { success: false, returnData: res.returnData };
109
+ }
110
+ }
111
+ else {
112
+ results[i] = { success: false };
113
+ }
114
+ }
115
+ }
116
+ return results;
117
+ }
118
+ makeCalls(args) {
119
+ let page = typeof args[args.length - 1] == 'number' ? args.pop() : Number.MAX_SAFE_INTEGER;
120
+ switch (args.length) {
121
+ case 1: {
122
+ let list = args[0];
123
+ let calls = new Array(list.length);
124
+ let funcs = new Array(list.length);
125
+ 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;
129
+ }
130
+ return [calls, funcs, page];
131
+ }
132
+ 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);
137
+ 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;
141
+ }
142
+ return [calls, funcs, page];
143
+ }
144
+ 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);
150
+ for (let i = 0; i < list.length; i++) {
151
+ let args = list[i];
152
+ calls[i] = [address, func.encode(args)];
153
+ funcs[i] = func;
154
+ }
155
+ return [calls, funcs, page];
156
+ }
157
+ default:
158
+ throw new Error('unexpected number of arguments');
159
+ }
160
+ }
161
+ }
162
+ exports.Multicall = Multicall;
163
+ Multicall.aggregate = aggregate;
164
+ Multicall.try_aggregate = try_aggregate;
165
+ function* splitIntoPages(size, page) {
166
+ let from = 0;
167
+ while (size) {
168
+ let step = Math.min(page, size);
169
+ let to = from + step;
170
+ yield [from, to];
171
+ size -= step;
172
+ from = to;
173
+ }
174
+ }
175
+ //# sourceMappingURL=multicall.js.map