dequanto 0.1.15 → 0.1.21
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/cjs/config/Config.js.map +1 -1
- package/lib/cjs/gen/Generator.d.ts +2 -0
- package/lib/cjs/gen/Generator.js +2 -0
- package/lib/cjs/gen/Generator.js.map +1 -1
- package/lib/cjs/gen/GeneratorFromAbi.d.ts +30 -7
- package/lib/cjs/gen/GeneratorFromAbi.js +193 -110
- package/lib/cjs/gen/GeneratorFromAbi.js.map +1 -1
- package/lib/cjs/gen/GeneratorStorageReader.d.ts +1 -0
- package/lib/cjs/gen/GeneratorStorageReader.js +25 -9
- package/lib/cjs/gen/GeneratorStorageReader.js.map +1 -1
- package/lib/cjs/utils/$config.js +4 -0
- package/lib/cjs/utils/$config.js.map +1 -1
- package/lib/esm/config/Config.js.map +1 -1
- package/lib/esm/gen/Generator.d.ts +2 -0
- package/lib/esm/gen/Generator.js.map +1 -1
- package/lib/esm/gen/Generator.mjs +2 -0
- package/lib/esm/gen/GeneratorFromAbi.d.ts +30 -7
- package/lib/esm/gen/GeneratorFromAbi.js.map +1 -1
- package/lib/esm/gen/GeneratorFromAbi.mjs +193 -110
- package/lib/esm/gen/GeneratorStorageReader.d.ts +1 -0
- package/lib/esm/gen/GeneratorStorageReader.js.map +1 -1
- package/lib/esm/gen/GeneratorStorageReader.mjs +25 -9
- package/lib/esm/utils/$config.js.map +1 -1
- package/lib/esm/utils/$config.mjs +4 -0
- package/package.json +1 -1
- package/src/config/Config.ts +2 -1
- package/src/gen/ContractStorageReaderTemplate.js +17 -0
- package/src/gen/ContractTemplate.js +77 -0
- package/src/gen/Generator.ts +6 -0
- package/src/gen/GeneratorFromAbi.ts +204 -121
- package/src/gen/GeneratorStorageReader.ts +29 -11
- package/src/utils/$config.ts +4 -0
|
@@ -14,7 +14,7 @@ import { GeneratorStorageReader } from './GeneratorStorageReader';
|
|
|
14
14
|
import { Web3Client } from '@dequanto/clients/Web3Client';
|
|
15
15
|
import { Str } from './utils/Str';
|
|
16
16
|
import { $gen } from './utils/$gen';
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
export class GeneratorFromAbi {
|
|
@@ -24,11 +24,13 @@ export class GeneratorFromAbi {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async generate(abiJson: TAbiItem[], opts: {
|
|
27
|
+
target?: 'js' | 'ts'
|
|
27
28
|
network: TPlatform
|
|
28
29
|
name: string
|
|
29
30
|
contractName: string
|
|
30
31
|
address: TAddress
|
|
31
32
|
output: string
|
|
33
|
+
outputFileExt?: string
|
|
32
34
|
implementation: TAddress
|
|
33
35
|
saveAbi?: boolean
|
|
34
36
|
saveSources?: boolean
|
|
@@ -41,6 +43,7 @@ export class GeneratorFromAbi {
|
|
|
41
43
|
client?: Web3Client
|
|
42
44
|
}) {
|
|
43
45
|
|
|
46
|
+
let targetType = opts.target ?? 'ts';
|
|
44
47
|
let methodsArr = alot(abiJson)
|
|
45
48
|
.filter(x => x.type === 'function' || x.type === 'constructor')
|
|
46
49
|
.groupBy(x => x.name)
|
|
@@ -56,23 +59,11 @@ export class GeneratorFromAbi {
|
|
|
56
59
|
return null;
|
|
57
60
|
})
|
|
58
61
|
.filter(Boolean)
|
|
62
|
+
.map(x => x[ opts?.target ?? 'ts' ])
|
|
59
63
|
.map(Str.formatMethod)
|
|
60
64
|
.toArray();
|
|
61
65
|
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
// let methodInterfacesArr = alot(abiJson)
|
|
65
|
-
// .filter(x => x.type === 'function')
|
|
66
|
-
// .groupBy(x => x.name)
|
|
67
|
-
// .map(group => {
|
|
68
|
-
// let item = group.values[0];
|
|
69
|
-
// return Gen.serializeMethodInterfacesTs(item.name, group.values);
|
|
70
|
-
// })
|
|
71
|
-
// .filter(Boolean)
|
|
72
|
-
// .toArray();
|
|
73
|
-
|
|
74
|
-
//let methodInterfacesAll = Gen.serializeMethodInterfacesAllTs(methodInterfacesArr);
|
|
75
|
-
|
|
76
67
|
let methodTypes = alot(abiJson)
|
|
77
68
|
.filter(x => x.type === 'function')
|
|
78
69
|
.groupBy(x => x.name)
|
|
@@ -87,6 +78,7 @@ export class GeneratorFromAbi {
|
|
|
87
78
|
.filter(x => x.type === 'event')
|
|
88
79
|
.map(x => Gen.serializeEvent(x))
|
|
89
80
|
.filter(Boolean)
|
|
81
|
+
.map(x => x[ opts?.target ?? 'ts' ])
|
|
90
82
|
.map(Str.formatMethod);
|
|
91
83
|
|
|
92
84
|
let eventTypes = alot(abiJson)
|
|
@@ -106,12 +98,14 @@ export class GeneratorFromAbi {
|
|
|
106
98
|
.filter(x => x.type === 'event')
|
|
107
99
|
.map(x => Gen.serializeEventExtractor(x))
|
|
108
100
|
.filter(Boolean)
|
|
101
|
+
.map(x => x[ opts?.target ?? 'ts' ])
|
|
109
102
|
.map(Str.formatMethod);
|
|
110
103
|
|
|
111
104
|
let eventsFetchersArr = abiJson
|
|
112
105
|
.filter(x => x.type === 'event')
|
|
113
106
|
.map(x => Gen.serializeEventFetcher(x))
|
|
114
107
|
.filter(Boolean)
|
|
108
|
+
.map(x => x[ opts?.target ?? 'ts' ])
|
|
115
109
|
.map(Str.formatMethod);
|
|
116
110
|
|
|
117
111
|
// let eventInterfaces = abiJson
|
|
@@ -126,7 +120,7 @@ export class GeneratorFromAbi {
|
|
|
126
120
|
let eventsFetchers = eventsFetchersArr.join('\n\n');
|
|
127
121
|
|
|
128
122
|
let name = opts.name;
|
|
129
|
-
let templatePath = $path.resolve(`/src/gen/ContractTemplate
|
|
123
|
+
let templatePath = $path.resolve(`/src/gen/ContractTemplate.${ targetType }`);
|
|
130
124
|
let template = await File.readAsync<string>(templatePath, { skipHooks: true });
|
|
131
125
|
|
|
132
126
|
|
|
@@ -136,13 +130,14 @@ export class GeneratorFromAbi {
|
|
|
136
130
|
let sourceUri: string;
|
|
137
131
|
let Web3ClientOptions = '';
|
|
138
132
|
let EvmScanOptions = '';
|
|
133
|
+
let importPfx = targetType === 'js' ? 'dequanto' : '@dequanto';
|
|
139
134
|
switch (opts.network) {
|
|
140
135
|
case 'bsc':
|
|
141
136
|
EtherscanStr = 'Bscscan';
|
|
142
137
|
EthWeb3ClientStr = 'BscWeb3Client';
|
|
143
138
|
imports = [
|
|
144
|
-
`import { Bscscan } from '
|
|
145
|
-
`import { BscWeb3Client } from '
|
|
139
|
+
`import { Bscscan } from '${importPfx}/explorer/Bscscan'`,
|
|
140
|
+
`import { BscWeb3Client } from '${importPfx}/clients/BscWeb3Client'`,
|
|
146
141
|
];
|
|
147
142
|
sourceUri = `https://bscscan.com/address/${opts.address}#code`;
|
|
148
143
|
break;
|
|
@@ -150,8 +145,8 @@ export class GeneratorFromAbi {
|
|
|
150
145
|
EtherscanStr = 'Polyscan';
|
|
151
146
|
EthWeb3ClientStr = 'PolyWeb3Client';
|
|
152
147
|
imports = [
|
|
153
|
-
`import { Polyscan } from '
|
|
154
|
-
`import { PolyWeb3Client } from '
|
|
148
|
+
`import { Polyscan } from '${importPfx}/explorer/Polyscan'`,
|
|
149
|
+
`import { PolyWeb3Client } from '${importPfx}/clients/PolyWeb3Client'`,
|
|
155
150
|
];
|
|
156
151
|
sourceUri = `https://polygonscan.com/address/${opts.address}#code`;
|
|
157
152
|
break;
|
|
@@ -159,8 +154,8 @@ export class GeneratorFromAbi {
|
|
|
159
154
|
EtherscanStr = 'XDaiscan';
|
|
160
155
|
EthWeb3ClientStr = 'XDaiWeb3Client';
|
|
161
156
|
imports = [
|
|
162
|
-
`import { XDaiscan } from '
|
|
163
|
-
`import { XDaiWeb3Client } from '
|
|
157
|
+
`import { XDaiscan } from '${importPfx}/chains/xdai/XDaiscan'`,
|
|
158
|
+
`import { XDaiWeb3Client } from '${importPfx}/chains/xdai/XDaiWeb3Client'`,
|
|
164
159
|
];
|
|
165
160
|
sourceUri = `https://blockscout.com/xdai/mainnet/address/${opts.address}/contracts`;
|
|
166
161
|
break;
|
|
@@ -168,8 +163,8 @@ export class GeneratorFromAbi {
|
|
|
168
163
|
EtherscanStr = 'Etherscan';
|
|
169
164
|
EthWeb3ClientStr = 'EthWeb3Client';
|
|
170
165
|
imports = [
|
|
171
|
-
`import { Etherscan } from '
|
|
172
|
-
`import { EthWeb3Client } from '
|
|
166
|
+
`import { Etherscan } from '${importPfx}/explorer/Etherscan'`,
|
|
167
|
+
`import { EthWeb3Client } from '${importPfx}/clients/EthWeb3Client'`,
|
|
173
168
|
];
|
|
174
169
|
sourceUri = `https://etherscan.io/address/${opts.address}#code`;
|
|
175
170
|
break;
|
|
@@ -177,8 +172,8 @@ export class GeneratorFromAbi {
|
|
|
177
172
|
EtherscanStr = 'Etherscan';
|
|
178
173
|
EthWeb3ClientStr = 'HardhatWeb3Client';
|
|
179
174
|
imports = [
|
|
180
|
-
`import { Etherscan } from '
|
|
181
|
-
`import { HardhatWeb3Client } from '
|
|
175
|
+
`import { Etherscan } from '${importPfx}/explorer/Etherscan'`,
|
|
176
|
+
`import { HardhatWeb3Client } from '${importPfx}/hardhat/HardhatWeb3Client'`,
|
|
182
177
|
];
|
|
183
178
|
sourceUri = ``;
|
|
184
179
|
break;
|
|
@@ -188,8 +183,8 @@ export class GeneratorFromAbi {
|
|
|
188
183
|
EtherscanStr = 'Evmscan';
|
|
189
184
|
EthWeb3ClientStr = 'EvmWeb3Client';
|
|
190
185
|
imports = [
|
|
191
|
-
`import { Evmscan } from '
|
|
192
|
-
`import { EvmWeb3Client } from '
|
|
186
|
+
`import { Evmscan } from '${importPfx}/explorer/Evmscan'`,
|
|
187
|
+
`import { EvmWeb3Client } from '${importPfx}/clients/EvmWeb3Client'`,
|
|
193
188
|
];
|
|
194
189
|
Web3ClientOptions = `{ platform: '${opts.network}' }`;
|
|
195
190
|
EvmScanOptions = `{ platform: '${opts.network}' }`;
|
|
@@ -210,7 +205,7 @@ export class GeneratorFromAbi {
|
|
|
210
205
|
let outputFilename = /[^\\/]+$/.exec(name)[0];
|
|
211
206
|
let outputPath = /\.(ts|js)$/.test(opts.output)
|
|
212
207
|
? opts.output
|
|
213
|
-
: class_Uri.combine(opts.output, outputDirectory, `${outputFilename}.
|
|
208
|
+
: class_Uri.combine(opts.output, outputDirectory, `${outputFilename}.${opts.outputFileExt ?? targetType}`);
|
|
214
209
|
|
|
215
210
|
let meta = {
|
|
216
211
|
artifact: opts.artifact
|
|
@@ -229,14 +224,14 @@ export class GeneratorFromAbi {
|
|
|
229
224
|
let storageReaderClass = '';
|
|
230
225
|
try {
|
|
231
226
|
let storageReaderGenerator = new GeneratorStorageReader();
|
|
232
|
-
let reader = await storageReaderGenerator.generate({ ...opts });
|
|
227
|
+
let reader = await storageReaderGenerator.generate({ ...opts, target: targetType });
|
|
233
228
|
|
|
234
229
|
if (reader.sourcePath != null && opts.address == null) {
|
|
235
230
|
sourceUri = this.getRelativePath(reader.sourcePath);
|
|
236
231
|
}
|
|
237
232
|
if (reader.className) {
|
|
238
233
|
storageReaderClass = reader.code;
|
|
239
|
-
storageReaderProperty = `declare storage: ${reader.className}
|
|
234
|
+
storageReaderProperty = targetType === 'ts' ? `declare storage: ${reader.className}` : '';
|
|
240
235
|
storageReaderInitializer = `this.storage = new ${reader.className}(this.address, this.client, this.explorer);`;
|
|
241
236
|
$logger.log(`green<StorageReader> was generated`);
|
|
242
237
|
} else {
|
|
@@ -270,8 +265,8 @@ export class GeneratorFromAbi {
|
|
|
270
265
|
.replace(`/* STORAGE_READER_INITIALIZER */`, storageReaderInitializer)
|
|
271
266
|
.replace(`/* STORAGE_READER_PROPERTY */`, storageReaderProperty)
|
|
272
267
|
.replace(`/* STORAGE_READER_CLASS */`, () => storageReaderClass)
|
|
273
|
-
.replace(`/* TX_CALLER_METHODS */`, () => Gen.serializeTxCallerMethods(className, abiJson))
|
|
274
|
-
.replace(`/* TX_DATA_METHODS */`, () => Gen.serializeTxDataMethods(className, abiJson))
|
|
268
|
+
.replace(`/* TX_CALLER_METHODS */`, () => Gen.serializeTxCallerMethods(className, abiJson)[targetType])
|
|
269
|
+
.replace(`/* TX_DATA_METHODS */`, () => Gen.serializeTxDataMethods(className, abiJson)[targetType])
|
|
275
270
|
|
|
276
271
|
|
|
277
272
|
.replace(`/* $EVENT_TYPES$ */`, () => Str.indent(eventTypes.map(x => x.code).join('\n'), ' '))
|
|
@@ -359,8 +354,8 @@ namespace Gen {
|
|
|
359
354
|
// abi.length > 1 if has method overloads
|
|
360
355
|
export function serializeMethodInterfacesTs(name: string, abis: TAbiItem[]) {
|
|
361
356
|
let args = abis.map(abi => {
|
|
362
|
-
let {
|
|
363
|
-
return `[ ${
|
|
357
|
+
let { fnInputArgumentsTargets } = serializeArgumentsTs(abi);
|
|
358
|
+
return `[ ${fnInputArgumentsTargets.ts} ]`;
|
|
364
359
|
}).join(' | ');
|
|
365
360
|
|
|
366
361
|
let iface = `IMethod${name[0].toUpperCase()}${name.substring(1)}`;
|
|
@@ -379,8 +374,8 @@ namespace Gen {
|
|
|
379
374
|
|
|
380
375
|
export function serializeMethodTypeTs(name: string, abis: TAbiItem[]) {
|
|
381
376
|
let args = abis.map(abi => {
|
|
382
|
-
let {
|
|
383
|
-
return `[ ${
|
|
377
|
+
let { fnInputArgumentsTargets } = serializeArgumentsTs(abi);
|
|
378
|
+
return `[ ${fnInputArgumentsTargets.ts} ]`;
|
|
384
379
|
}).join(' | ');
|
|
385
380
|
|
|
386
381
|
let iface = `IMethod${name[0].toUpperCase()}${name.substring(1)}`;
|
|
@@ -426,9 +421,9 @@ namespace Gen {
|
|
|
426
421
|
};
|
|
427
422
|
}
|
|
428
423
|
export function serializeEventType(event: TAbiItem) {
|
|
429
|
-
let {
|
|
430
|
-
let outputParams = `{ ${
|
|
431
|
-
let outputArgs = `[ ${
|
|
424
|
+
let { fnInputArgumentsTargets, callInputArguments, fnResult } = serializeArgumentsTs(event);
|
|
425
|
+
let outputParams = `{ ${fnInputArgumentsTargets.ts} }`;
|
|
426
|
+
let outputArgs = `[ ${fnInputArgumentsTargets.ts.replace('\n', '')} ]`;
|
|
432
427
|
let code = [
|
|
433
428
|
`${event.name}: {`,
|
|
434
429
|
` outputParams: ${outputParams},`,
|
|
@@ -441,34 +436,56 @@ namespace Gen {
|
|
|
441
436
|
}
|
|
442
437
|
|
|
443
438
|
export function serializeEvent(abi: TAbiItem) {
|
|
444
|
-
let {
|
|
445
|
-
return
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
439
|
+
let { fnInputArgumentsTargets, callInputArguments, fnResult } = serializeArgumentsTs(abi);
|
|
440
|
+
return {
|
|
441
|
+
ts: `
|
|
442
|
+
on${abi.name} (fn?: (event: TClientEventsStreamData<TEventArguments<'${abi.name}'>>) => void): ClientEventsStream<TClientEventsStreamData<TEventArguments<'${abi.name}'>>> {
|
|
443
|
+
return this.$onLog('${abi.name}', fn);
|
|
444
|
+
}
|
|
445
|
+
`,
|
|
446
|
+
js: `
|
|
447
|
+
on${abi.name} (fn) {
|
|
448
|
+
return this.$onLog('${abi.name}', fn);
|
|
449
|
+
}
|
|
450
|
+
`
|
|
451
|
+
};
|
|
450
452
|
}
|
|
451
453
|
export function serializeEventExtractor(abi: TAbiItem) {
|
|
452
|
-
return
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
454
|
+
return {
|
|
455
|
+
ts: `
|
|
456
|
+
extractLogs${abi.name} (tx: TEth.TxReceipt): ITxLogItem<TEventParams<'${abi.name}'>>[] {
|
|
457
|
+
let abi = this.$getAbiItem('event', '${abi.name}');
|
|
458
|
+
return this.$extractLogs(tx, abi) as any as ITxLogItem<TEventParams<'${abi.name}'>>[];
|
|
459
|
+
}
|
|
460
|
+
`,
|
|
461
|
+
js: `
|
|
462
|
+
extractLogs${abi.name} (tx) {
|
|
463
|
+
let abi = this.$getAbiItem('event', '${abi.name}');
|
|
464
|
+
return this.$extractLogs(tx, abi);
|
|
465
|
+
}
|
|
466
|
+
`
|
|
467
|
+
};
|
|
458
468
|
}
|
|
459
469
|
export function serializeEventFetcher(abi: TAbiItem) {
|
|
460
470
|
let inputs = abi.inputs;
|
|
461
471
|
let indexed = alot(inputs).takeWhile(x => x.indexed).toArray();
|
|
462
472
|
let indexedParams = indexed.map(param => `${param.name}?: ${$abiType.getTsType(param.type, param)}`)
|
|
463
|
-
return
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
473
|
+
return {
|
|
474
|
+
ts: `
|
|
475
|
+
async getPastLogs${abi.name} (options?: {
|
|
476
|
+
fromBlock?: number | Date
|
|
477
|
+
toBlock?: number | Date
|
|
478
|
+
params?: { ${indexedParams} }
|
|
479
|
+
}): Promise<ITxLogItem<TEventParams<'${abi.name}'>>[]> {
|
|
480
|
+
return await this.$getPastLogsParsed('${abi.name}', options) as any;
|
|
481
|
+
}
|
|
482
|
+
`,
|
|
483
|
+
js: `
|
|
484
|
+
async getPastLogs${abi.name} (options) {
|
|
485
|
+
return await this.$getPastLogsParsed('${abi.name}', options);
|
|
486
|
+
}
|
|
487
|
+
`
|
|
488
|
+
}
|
|
472
489
|
}
|
|
473
490
|
// export function serializeEventInterface (abi: TAbiItem) {
|
|
474
491
|
// let { fnInputArguments, callInputArguments, fnResult } = serializeArgumentsTs(abi);
|
|
@@ -497,80 +514,119 @@ namespace Gen {
|
|
|
497
514
|
}
|
|
498
515
|
|
|
499
516
|
function serializeReadMethodTs(abi: TAbiItem) {
|
|
500
|
-
let {
|
|
517
|
+
let { fnInputArgumentsTargets, callInputArguments, fnResult } = serializeArgumentsTs(abi);
|
|
501
518
|
if (callInputArguments) {
|
|
502
519
|
callInputArguments = `, ${callInputArguments}`;
|
|
503
520
|
}
|
|
504
|
-
return
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
521
|
+
return {
|
|
522
|
+
ts: `
|
|
523
|
+
// ${$abiUtils.getMethodSignature(abi)}
|
|
524
|
+
async ${abi.name} (${fnInputArgumentsTargets.ts}): ${fnResult} {
|
|
525
|
+
return this.$read(this.$getAbiItem('function', '${abi.name}')${callInputArguments});
|
|
526
|
+
}
|
|
527
|
+
`,
|
|
528
|
+
js: `
|
|
529
|
+
// ${$abiUtils.getMethodSignature(abi)}
|
|
530
|
+
async ${abi.name} (${fnInputArgumentsTargets.js}) {
|
|
531
|
+
return this.$read(this.$getAbiItem('function', '${abi.name}')${callInputArguments});
|
|
532
|
+
}
|
|
533
|
+
`
|
|
534
|
+
};
|
|
510
535
|
}
|
|
511
536
|
function serializeReadMethodTsOverloads(abis: TAbiItem[]) {
|
|
512
537
|
let overrides = abis.map(abi => {
|
|
513
|
-
let {
|
|
538
|
+
let { fnInputArgumentsTargets, fnResult } = serializeArgumentsTs(abi);
|
|
514
539
|
return `
|
|
515
540
|
// ${$abiUtils.getMethodSignature(abi)}
|
|
516
|
-
async ${abi.name} (${
|
|
541
|
+
async ${abi.name} (${fnInputArgumentsTargets.ts}): ${fnResult}
|
|
517
542
|
`;
|
|
518
543
|
}).join('\n');
|
|
519
544
|
|
|
520
545
|
let abi = abis[0];
|
|
521
546
|
let { fnResult } = serializeArgumentsTs(abi);
|
|
522
547
|
let sigs = abis.map(abi => serializeMethodAbi(abi)).map(x => `'${x}'`).join(', ');
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
548
|
+
return {
|
|
549
|
+
ts: `
|
|
550
|
+
${overrides}
|
|
551
|
+
async ${abi.name} (...args): ${fnResult} {
|
|
552
|
+
let abi = this.$getAbiItemOverload([ ${sigs} ], args);
|
|
553
|
+
return this.$read(abi, ...args);
|
|
554
|
+
}
|
|
555
|
+
`,
|
|
556
|
+
js: `
|
|
557
|
+
async ${abi.name} (...args) {
|
|
558
|
+
let abi = this.$getAbiItemOverload([ ${sigs} ], args);
|
|
559
|
+
return this.$read(abi, ...args);
|
|
560
|
+
}
|
|
561
|
+
`
|
|
562
|
+
};
|
|
530
563
|
}
|
|
531
564
|
|
|
532
565
|
function serializeWriteMethodTs(abi: TAbiItem) {
|
|
533
|
-
let {
|
|
566
|
+
let { fnInputArgumentsTargets, callInputArguments } = serializeArgumentsTs(abi);
|
|
534
567
|
if (callInputArguments) {
|
|
535
568
|
callInputArguments = `, ${callInputArguments}`;
|
|
536
569
|
}
|
|
537
570
|
|
|
538
|
-
return
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
571
|
+
return {
|
|
572
|
+
ts: `
|
|
573
|
+
// ${$abiUtils.getMethodSignature(abi)}
|
|
574
|
+
async ${abi.name} (sender: TSender, ${fnInputArgumentsTargets.ts}): Promise<TxWriter> {
|
|
575
|
+
return this.$write(this.$getAbiItem('function', '${abi.name}'), sender${callInputArguments});
|
|
576
|
+
}
|
|
577
|
+
`,
|
|
578
|
+
js: `
|
|
579
|
+
// ${$abiUtils.getMethodSignature(abi)}
|
|
580
|
+
async ${abi.name} (sender, ${fnInputArgumentsTargets.js}) {
|
|
581
|
+
return this.$write(this.$getAbiItem('function', '${abi.name}'), sender${callInputArguments});
|
|
582
|
+
}
|
|
583
|
+
`
|
|
584
|
+
};
|
|
544
585
|
}
|
|
545
586
|
function serializeConstructorMethodTs(abi: TAbiItem) {
|
|
546
|
-
let {
|
|
587
|
+
let { fnInputArgumentsTargets, callInputArguments } = serializeArgumentsTs(abi);
|
|
547
588
|
if (callInputArguments) {
|
|
548
589
|
callInputArguments = `, ${callInputArguments}`;
|
|
549
590
|
}
|
|
550
|
-
return
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
591
|
+
return {
|
|
592
|
+
ts: `
|
|
593
|
+
async $constructor (deployer: TSender, ${fnInputArgumentsTargets.ts}): Promise<TxWriter> {
|
|
594
|
+
throw new Error('Not implemented. Typing purpose. Use the ContractDeployer class to deploy the contract');
|
|
595
|
+
}
|
|
596
|
+
`,
|
|
597
|
+
js: `
|
|
598
|
+
async $constructor (deployer, ${fnInputArgumentsTargets.js}) {
|
|
599
|
+
throw new Error('Not implemented. Typing purpose. Use the ContractDeployer class to deploy the contract');
|
|
600
|
+
}
|
|
601
|
+
`
|
|
602
|
+
};
|
|
555
603
|
}
|
|
556
604
|
function serializeWriteMethodTsOverloads(abis: TAbiItem[]) {
|
|
557
605
|
let overrides = abis.map(abi => {
|
|
558
|
-
let {
|
|
606
|
+
let { fnInputArgumentsTargets, fnResult } = serializeArgumentsTs(abi);
|
|
559
607
|
return `
|
|
560
608
|
// ${$abiUtils.getMethodSignature(abi)}
|
|
561
|
-
async ${abi.name} (sender: TSender, ${
|
|
609
|
+
async ${abi.name} (sender: TSender, ${fnInputArgumentsTargets.ts}): Promise<TxWriter>
|
|
562
610
|
`;
|
|
563
611
|
}).join('\n');
|
|
564
612
|
|
|
565
613
|
let abi = abis[0];
|
|
566
614
|
let sigs = abis.map(abi => serializeMethodAbi(abi)).map(x => `'${x}'`).join(', ');
|
|
567
|
-
return
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
615
|
+
return {
|
|
616
|
+
ts: `
|
|
617
|
+
${overrides}
|
|
618
|
+
async ${abi.name} (sender: TSender, ...args): Promise<TxWriter> {
|
|
619
|
+
let abi = this.$getAbiItemOverload([ ${sigs} ], args);
|
|
620
|
+
return this.$write(abi, sender, ...args);
|
|
621
|
+
}
|
|
622
|
+
`,
|
|
623
|
+
js: `
|
|
624
|
+
async ${abi.name} (sender, ...args) {
|
|
625
|
+
let abi = this.$getAbiItemOverload([ ${sigs} ], args);
|
|
626
|
+
return this.$write(abi, sender, ...args);
|
|
627
|
+
}
|
|
628
|
+
`
|
|
629
|
+
};
|
|
574
630
|
}
|
|
575
631
|
|
|
576
632
|
function serializeArgumentsTs(abi: TAbiItem) {
|
|
@@ -585,16 +641,26 @@ namespace Gen {
|
|
|
585
641
|
return result;
|
|
586
642
|
});
|
|
587
643
|
|
|
588
|
-
let
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
644
|
+
let fnInputArgumentsArr = inputs
|
|
645
|
+
?.map((input) => {
|
|
646
|
+
let tsType = $abiType.getTsType(input.type, input);
|
|
647
|
+
if (tsType == null) {
|
|
648
|
+
throw new Error(`Unknown abi type in arguments: ${input.type}`);
|
|
649
|
+
}
|
|
650
|
+
return { name: input.name, type: tsType };
|
|
651
|
+
}) ?? [];
|
|
594
652
|
|
|
595
|
-
|
|
653
|
+
let fnInputArgumentsTs = fnInputArgumentsArr
|
|
654
|
+
.map((input) => {
|
|
655
|
+
return `${input.name}: ${input.type}`;
|
|
596
656
|
})
|
|
597
|
-
|
|
657
|
+
.join(', ');
|
|
658
|
+
|
|
659
|
+
let fnInputArgumentsJs = fnInputArgumentsArr
|
|
660
|
+
.map((input) => {
|
|
661
|
+
return `${input.name}`;
|
|
662
|
+
})
|
|
663
|
+
.join(', ');
|
|
598
664
|
|
|
599
665
|
let callInputArguments = inputs
|
|
600
666
|
?.map(input => {
|
|
@@ -604,7 +670,14 @@ namespace Gen {
|
|
|
604
670
|
|
|
605
671
|
|
|
606
672
|
let fnResult = serializeMethodTsReturns(abi.outputs);
|
|
607
|
-
return {
|
|
673
|
+
return {
|
|
674
|
+
fnInputArgumentsTargets: {
|
|
675
|
+
ts: fnInputArgumentsTs,
|
|
676
|
+
js: fnInputArgumentsJs,
|
|
677
|
+
},
|
|
678
|
+
callInputArguments,
|
|
679
|
+
fnResult
|
|
680
|
+
};
|
|
608
681
|
}
|
|
609
682
|
|
|
610
683
|
function isObjectParams(params: { name?, type }[]) {
|
|
@@ -688,43 +761,53 @@ namespace Gen {
|
|
|
688
761
|
return lines.join('\n');
|
|
689
762
|
}
|
|
690
763
|
|
|
691
|
-
export function serializeTxCallerMethods(className: string, abiJson: TAbiItem[])
|
|
764
|
+
export function serializeTxCallerMethods(className: string, abiJson: TAbiItem[]) {
|
|
692
765
|
let methods = abiJson.filter(x => x.type === 'function');
|
|
693
766
|
let writeMethods = methods.filter(abi => $abiUtils.isReadMethod(abi) === false);
|
|
694
|
-
let lines =
|
|
695
|
-
|
|
696
|
-
lines.push(serializeMethodTs(method));
|
|
767
|
+
let lines = writeMethods.map(method => {
|
|
768
|
+
return serializeMethodTs(method);
|
|
697
769
|
});
|
|
698
770
|
|
|
699
|
-
return
|
|
771
|
+
return {
|
|
772
|
+
ts: lines.map(x => x.ts).join('\n'),
|
|
773
|
+
js: lines.map(x => x.js).join('\n'),
|
|
774
|
+
};
|
|
700
775
|
|
|
701
776
|
|
|
702
777
|
function serializeMethodTs(abi: TAbiItem) {
|
|
703
|
-
let {
|
|
778
|
+
let { fnInputArgumentsTargets, callInputArguments, fnResult } = serializeArgumentsTs(abi);
|
|
704
779
|
if (callInputArguments) {
|
|
705
780
|
callInputArguments = `, ${callInputArguments}`;
|
|
706
781
|
}
|
|
707
|
-
return
|
|
782
|
+
return {
|
|
783
|
+
ts: ` ${abi.name} (sender: TSender, ${fnInputArgumentsTargets.ts}): Promise<{ error?: Error & { data?: { type: string, params } }, result? }>`,
|
|
784
|
+
js: ` ${abi.name} (sender, ${fnInputArgumentsTargets.js})`,
|
|
785
|
+
};
|
|
708
786
|
}
|
|
709
787
|
}
|
|
710
788
|
|
|
711
|
-
export function serializeTxDataMethods(className: string, abiJson: TAbiItem[])
|
|
789
|
+
export function serializeTxDataMethods(className: string, abiJson: TAbiItem[]) {
|
|
712
790
|
let methods = abiJson.filter(x => x.type === 'function');
|
|
713
791
|
let writeMethods = methods.filter(abi => $abiUtils.isReadMethod(abi) === false);
|
|
714
|
-
let lines =
|
|
715
|
-
|
|
716
|
-
lines.push(serializeInterfaceMethodTs(method));
|
|
792
|
+
let lines = writeMethods.map(method => {
|
|
793
|
+
return serializeInterfaceMethodTs(method);
|
|
717
794
|
});
|
|
718
795
|
|
|
719
|
-
return
|
|
796
|
+
return {
|
|
797
|
+
ts: lines.map(x => x.ts).join('\n'),
|
|
798
|
+
js: lines.map(x => x.js).join('\n'),
|
|
799
|
+
}
|
|
720
800
|
|
|
721
801
|
|
|
722
802
|
function serializeInterfaceMethodTs(abi: TAbiItem) {
|
|
723
|
-
let {
|
|
803
|
+
let { fnInputArgumentsTargets, callInputArguments, fnResult } = serializeArgumentsTs(abi);
|
|
724
804
|
if (callInputArguments) {
|
|
725
805
|
callInputArguments = `, ${callInputArguments}`;
|
|
726
806
|
}
|
|
727
|
-
return
|
|
807
|
+
return {
|
|
808
|
+
ts: ` ${abi.name} (sender: TSender, ${fnInputArgumentsTargets.ts}): Promise<TEth.TxLike>`,
|
|
809
|
+
js: ` ${abi.name} (sender, ${fnInputArgumentsTargets.js})`,
|
|
810
|
+
}
|
|
728
811
|
}
|
|
729
812
|
}
|
|
730
813
|
}
|
|
@@ -14,6 +14,8 @@ import { ISlotVarDefinition } from '@dequanto/solidity/SlotsParser/models'
|
|
|
14
14
|
export class GeneratorStorageReader {
|
|
15
15
|
|
|
16
16
|
async generate(opts: {
|
|
17
|
+
target?: 'js' | 'ts'
|
|
18
|
+
|
|
17
19
|
network: TPlatform
|
|
18
20
|
name: string
|
|
19
21
|
contractName: string
|
|
@@ -24,6 +26,7 @@ export class GeneratorStorageReader {
|
|
|
24
26
|
client?: Web3Client
|
|
25
27
|
}): Promise<{ code?: string, className?: string, sourcePath?: string, error?: Error }> {
|
|
26
28
|
|
|
29
|
+
let targetType = opts.target ?? 'ts';
|
|
27
30
|
let { client, sources, contractName, address } = opts;
|
|
28
31
|
let files = alot.fromObject(sources ?? {}).map(x => {
|
|
29
32
|
return {
|
|
@@ -56,9 +59,9 @@ export class GeneratorStorageReader {
|
|
|
56
59
|
let slots = await SlotsParser.slots({ code: file.content, path: file.path }, contractName, { files })
|
|
57
60
|
|
|
58
61
|
let methods = this.serializeSlots(slots);
|
|
59
|
-
let codeMethods = methods.join('\n\n');
|
|
62
|
+
let codeMethods = methods.map(x => x[targetType]).join('\n\n');
|
|
60
63
|
|
|
61
|
-
let templatePath = $path.resolve(`/src/gen/ContractStorageReaderTemplate
|
|
64
|
+
let templatePath = $path.resolve(`/src/gen/ContractStorageReaderTemplate.${targetType}`);
|
|
62
65
|
let template = await File.readAsync<string>(templatePath, { skipHooks: true });
|
|
63
66
|
let className = $gen.toClassName(opts.name + 'StorageReader');
|
|
64
67
|
let code = template
|
|
@@ -77,22 +80,34 @@ export class GeneratorStorageReader {
|
|
|
77
80
|
private serializeSlots (slots: ISlotVarDefinition[]) {
|
|
78
81
|
return slots
|
|
79
82
|
.map(slot => this.serializeSlot(slot))
|
|
80
|
-
.map(
|
|
83
|
+
.map(entry => {
|
|
84
|
+
return {
|
|
85
|
+
ts: Str.formatMethod(entry.ts),
|
|
86
|
+
js: Str.formatMethod(entry.js),
|
|
87
|
+
}
|
|
88
|
+
});
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
private serializeSlot (slot: ISlotVarDefinition) {
|
|
84
92
|
let name = slot.name;
|
|
85
93
|
let type = slot.type;
|
|
86
94
|
let { parametersTypes, parametersCall, returnType } = this.getParameters(type);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
95
|
+
return {
|
|
96
|
+
ts: `
|
|
97
|
+
async ${name}(${parametersTypes?.ts ?? ''}): Promise<${returnType}> {
|
|
98
|
+
return this.$storage.get(['${name}', ${ parametersCall ?? '' }]);
|
|
99
|
+
}
|
|
100
|
+
`,
|
|
101
|
+
js: `
|
|
102
|
+
async ${name}(${parametersTypes?.js ?? ''}) {
|
|
103
|
+
return this.$storage.get(['${name}', ${ parametersCall ?? '' }]);
|
|
104
|
+
}
|
|
105
|
+
`
|
|
106
|
+
};
|
|
93
107
|
}
|
|
94
108
|
|
|
95
|
-
private getParameters (type: string): { parametersTypes
|
|
109
|
+
private getParameters (type: string): { parametersTypes?: { ts, js}, parametersCall?, returnType } {
|
|
110
|
+
|
|
96
111
|
if (type.startsWith('mapping')) {
|
|
97
112
|
let valueType = $abiType.mapping.getValueType(type);
|
|
98
113
|
let keyType = $abiType.mapping.getKeyType(type);
|
|
@@ -100,7 +115,10 @@ export class GeneratorStorageReader {
|
|
|
100
115
|
let keyTsType = $abiType.getTsTypeFromDefinition(keyType);
|
|
101
116
|
let valueTsType = $abiType.getTsTypeFromDefinition(valueType);
|
|
102
117
|
return {
|
|
103
|
-
parametersTypes:
|
|
118
|
+
parametersTypes: {
|
|
119
|
+
ts: `key: ${keyTsType}`,
|
|
120
|
+
js: `key`
|
|
121
|
+
},
|
|
104
122
|
returnType: `${valueTsType}`,
|
|
105
123
|
parametersCall: 'key',
|
|
106
124
|
}
|