dequanto 0.1.21 → 0.1.22

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.
Files changed (123) hide show
  1. package/lib/cjs/abi/coders/array.js +1 -1
  2. package/lib/cjs/abi/coders/array.js.map +1 -1
  3. package/lib/cjs/chains/arbitrum/Arbiscan.d.ts +1 -1
  4. package/lib/cjs/chains/boba/Bobascan.d.ts +1 -1
  5. package/lib/cjs/chains/xdai/XDaiscan.d.ts +1 -1
  6. package/lib/cjs/contracts/ContractBase.d.ts +1 -0
  7. package/lib/cjs/contracts/ContractBase.js.map +1 -1
  8. package/lib/cjs/contracts/ContractClassFactory.d.ts +2 -1
  9. package/lib/cjs/contracts/ContractClassFactory.js +5 -1
  10. package/lib/cjs/contracts/ContractClassFactory.js.map +1 -1
  11. package/lib/cjs/contracts/deploy/ContractDeployer.d.ts +1 -1
  12. package/lib/cjs/contracts/deploy/Deployments.d.ts +1 -1
  13. package/lib/cjs/contracts/deploy/proxy/ProxyDeployment.d.ts +1 -1
  14. package/lib/cjs/contracts/deploy/storage/DeploymentsStorage.d.ts +1 -1
  15. package/lib/cjs/contracts/deploy/storage/DeploymentsStorage.js +3 -3
  16. package/lib/cjs/contracts/deploy/storage/DeploymentsStorage.js.map +1 -1
  17. package/lib/cjs/explorer/BlockChainExplorerFactory.d.ts +1 -1
  18. package/lib/cjs/explorer/BlockChainExplorerProvider.d.ts +1 -1
  19. package/lib/cjs/explorer/Bscscan.d.ts +1 -1
  20. package/lib/cjs/explorer/ContractVerifier.d.ts +1 -1
  21. package/lib/cjs/explorer/ContractVerifier.js.map +1 -1
  22. package/lib/cjs/explorer/Etherscan.d.ts +1 -1
  23. package/lib/cjs/explorer/Polyscan.d.ts +1 -1
  24. package/lib/cjs/gen/GeneratorFromAbi.d.ts +3 -0
  25. package/lib/cjs/gen/GeneratorFromAbi.js +29 -1
  26. package/lib/cjs/gen/GeneratorFromAbi.js.map +1 -1
  27. package/lib/cjs/hardhat/HardhatProvider.d.ts +24 -2
  28. package/lib/cjs/hardhat/HardhatProvider.js +155 -92
  29. package/lib/cjs/hardhat/HardhatProvider.js.map +1 -1
  30. package/lib/cjs/json/JsonArrayMultiStore.js +4 -2
  31. package/lib/cjs/json/JsonArrayMultiStore.js.map +1 -1
  32. package/lib/cjs/json/JsonArrayStore.d.ts +2 -2
  33. package/lib/cjs/models/TEth.d.ts +2 -2
  34. package/lib/cjs/solidity/SlotsStorage.js.map +1 -1
  35. package/lib/cjs/utils/$abiParser.js +8 -1
  36. package/lib/cjs/utils/$abiParser.js.map +1 -1
  37. package/lib/cjs/utils/$bigint.d.ts +4 -0
  38. package/lib/cjs/utils/$bigint.js +40 -0
  39. package/lib/cjs/utils/$bigint.js.map +1 -1
  40. package/lib/cjs/utils/$contract.js +6 -0
  41. package/lib/cjs/utils/$contract.js.map +1 -1
  42. package/lib/cjs/utils/$path.d.ts +6 -0
  43. package/lib/cjs/utils/$path.js +19 -0
  44. package/lib/cjs/utils/$path.js.map +1 -1
  45. package/lib/cjs/utils/$sig.d.ts +3 -0
  46. package/lib/cjs/utils/$sig.js +2 -2
  47. package/lib/cjs/utils/$sig.js.map +1 -1
  48. package/lib/cjs/utils/types.d.ts +3 -0
  49. package/lib/esm/abi/coders/array.js.map +1 -1
  50. package/lib/esm/abi/coders/array.mjs +1 -1
  51. package/lib/esm/chains/arbitrum/Arbiscan.d.ts +1 -1
  52. package/lib/esm/chains/boba/Bobascan.d.ts +1 -1
  53. package/lib/esm/chains/xdai/XDaiscan.d.ts +1 -1
  54. package/lib/esm/contracts/ContractBase.d.ts +1 -0
  55. package/lib/esm/contracts/ContractBase.js.map +1 -1
  56. package/lib/esm/contracts/ContractClassFactory.d.ts +2 -1
  57. package/lib/esm/contracts/ContractClassFactory.js.map +1 -1
  58. package/lib/esm/contracts/ContractClassFactory.mjs +5 -1
  59. package/lib/esm/contracts/deploy/ContractDeployer.d.ts +1 -1
  60. package/lib/esm/contracts/deploy/Deployments.d.ts +1 -1
  61. package/lib/esm/contracts/deploy/proxy/ProxyDeployment.d.ts +1 -1
  62. package/lib/esm/contracts/deploy/storage/DeploymentsStorage.d.ts +1 -1
  63. package/lib/esm/contracts/deploy/storage/DeploymentsStorage.js.map +1 -1
  64. package/lib/esm/contracts/deploy/storage/DeploymentsStorage.mjs +3 -3
  65. package/lib/esm/explorer/BlockChainExplorerFactory.d.ts +1 -1
  66. package/lib/esm/explorer/BlockChainExplorerProvider.d.ts +1 -1
  67. package/lib/esm/explorer/Bscscan.d.ts +1 -1
  68. package/lib/esm/explorer/ContractVerifier.d.ts +1 -1
  69. package/lib/esm/explorer/ContractVerifier.js.map +1 -1
  70. package/lib/esm/explorer/Etherscan.d.ts +1 -1
  71. package/lib/esm/explorer/Polyscan.d.ts +1 -1
  72. package/lib/esm/gen/GeneratorFromAbi.d.ts +3 -0
  73. package/lib/esm/gen/GeneratorFromAbi.js.map +1 -1
  74. package/lib/esm/gen/GeneratorFromAbi.mjs +29 -1
  75. package/lib/esm/hardhat/HardhatProvider.d.ts +24 -2
  76. package/lib/esm/hardhat/HardhatProvider.js.map +1 -1
  77. package/lib/esm/hardhat/HardhatProvider.mjs +155 -92
  78. package/lib/esm/json/JsonArrayMultiStore.js.map +1 -1
  79. package/lib/esm/json/JsonArrayMultiStore.mjs +4 -2
  80. package/lib/esm/json/JsonArrayStore.d.ts +2 -2
  81. package/lib/esm/models/TEth.d.ts +2 -2
  82. package/lib/esm/solidity/SlotsStorage.js.map +1 -1
  83. package/lib/esm/utils/$abiParser.js.map +1 -1
  84. package/lib/esm/utils/$abiParser.mjs +8 -1
  85. package/lib/esm/utils/$bigint.d.ts +4 -0
  86. package/lib/esm/utils/$bigint.js.map +1 -1
  87. package/lib/esm/utils/$bigint.mjs +40 -0
  88. package/lib/esm/utils/$contract.js.map +1 -1
  89. package/lib/esm/utils/$contract.mjs +6 -0
  90. package/lib/esm/utils/$path.d.ts +6 -0
  91. package/lib/esm/utils/$path.js.map +1 -1
  92. package/lib/esm/utils/$path.mjs +19 -0
  93. package/lib/esm/utils/$sig.d.ts +3 -0
  94. package/lib/esm/utils/$sig.js.map +1 -1
  95. package/lib/esm/utils/$sig.mjs +1 -1
  96. package/lib/esm/utils/types.d.ts +3 -0
  97. package/package.json +1 -1
  98. package/src/abi/coders/array.ts +1 -1
  99. package/src/contracts/ContractBase.ts +2 -0
  100. package/src/contracts/ContractClassFactory.ts +8 -2
  101. package/src/contracts/deploy/ContractDeployer.ts +1 -1
  102. package/src/contracts/deploy/Deployments.ts +1 -1
  103. package/src/contracts/deploy/proxy/ProxyDeployment.ts +1 -1
  104. package/src/contracts/deploy/storage/DeploymentsStorage.ts +5 -5
  105. package/src/contracts/wrappers/FnSignedWrapper.ts +1 -1
  106. package/src/explorer/BlockChainExplorerFactory.ts +1 -1
  107. package/src/explorer/BlockChainExplorerProvider.ts +1 -1
  108. package/src/explorer/ContractVerifier.ts +2 -1
  109. package/src/gen/ContractStorageReaderTemplate.d.ts.template +14 -0
  110. package/src/gen/ContractTemplate.d.ts.template +111 -0
  111. package/src/gen/GeneratorFromAbi.ts +29 -1
  112. package/src/hardhat/HardhatProvider.ts +228 -106
  113. package/src/json/JsonArrayMultiStore.ts +4 -2
  114. package/src/json/JsonArrayStore.ts +1 -1
  115. package/src/models/TEth.ts +2 -2
  116. package/src/solidity/SlotsStorage.ts +2 -1
  117. package/src/types/TAbi.ts +2 -2
  118. package/src/utils/$abiParser.ts +8 -1
  119. package/src/utils/$bigint.ts +41 -0
  120. package/src/utils/$contract.ts +6 -1
  121. package/src/utils/$path.ts +18 -0
  122. package/src/utils/$sig.ts +1 -1
  123. package/src/utils/types.ts +3 -0
@@ -4,11 +4,11 @@ import { class_Uri } from 'atma-utils';
4
4
  import { File, env, Directory } from 'atma-io';
5
5
 
6
6
  import type { ContractBase } from '@dequanto/contracts/ContractBase';
7
- import type { Constructor } from 'atma-utils/mixin';
7
+
8
8
  import type { TAbiItem } from '@dequanto/types/TAbi';
9
9
  import type { TEth } from '@dequanto/models/TEth';
10
10
 
11
- import { EoAccount } from "@dequanto/models/TAccount";
11
+ import { EoAccount } from '@dequanto/models/TAccount';
12
12
  import { HardhatWeb3Client } from '@dequanto/hardhat/HardhatWeb3Client';
13
13
  import { Web3Client } from '@dequanto/clients/Web3Client';
14
14
 
@@ -34,6 +34,7 @@ import { TAddress } from '@dequanto/models/TAddress';
34
34
  import { $contract } from '@dequanto/utils/$contract';
35
35
  import { $dependency } from '@dequanto/utils/$dependency';
36
36
  import { TTransport } from '@dequanto/rpc/transports/ITransport';
37
+ import { Constructor } from '@dequanto/utils/types';
37
38
 
38
39
  type THardhatLib = typeof import('hardhat');
39
40
 
@@ -263,12 +264,14 @@ export class HardhatProvider {
263
264
  };
264
265
  }
265
266
 
266
- async compileSol<T extends ContractBase = IContractWrapped> (solContractPath: string, options?: {
267
+ async compileSolDirectory (dir: string, options?: {
267
268
  paths?: {
268
269
  root?: string
269
270
  artifacts?: string
270
271
  },
271
272
  contractName?: string
273
+ tsgen?: boolean
274
+ install?: string
272
275
  }): Promise<{
273
276
  abi: TAbiItem[]
274
277
  bytecode: TEth.Hex
@@ -276,123 +279,79 @@ export class HardhatProvider {
276
279
  // renamed output
277
280
  artifact: string
278
281
  source: IGeneratorSources
279
- ContractCtor: Constructor<T>
282
+ ContractCtor: Constructor<IContractWrapped>
280
283
  linkReferences?: Record<string /* path */, Record<string /* name */, any>>
281
- }> {
282
-
283
- solContractPath = $path.normalize(solContractPath);
284
-
285
- const dir = solContractPath.replace(/[^\/]+$/, '');
286
- const filename = /(?<filename>[^\/]+)\.\w+$/.exec(solContractPath)?.groups.filename;
287
- // Filename could contain have random number, extract main-name
288
- const filenameRndSuffix = filename.replace(/_\d+$/, '');
289
-
290
- let root = options?.paths?.root;
291
- let artifacts = options?.paths?.artifacts;
284
+ }[]> {
292
285
 
293
- if (filename == null) {
294
- throw new Error(`Filename not extracted from ${solContractPath}`);
286
+ dir = $path.normalize(dir);
287
+ if (await Directory.existsAsync(dir) === false) {
288
+ throw new Error(`Directory "${dir}" does not exist.`);
295
289
  }
296
-
297
- let hhOptions = {
290
+ const paths = {
298
291
  sources: dir,
299
- root,
300
- artifacts,
301
- tsgen: false,
292
+ root: options?.paths?.root,
293
+ artifacts: options?.paths?.artifacts,
294
+ };
295
+ const hhOptions = {
296
+ ...paths,
297
+ tsgen: options?.tsgen ?? false,
298
+ install: options?.install ?? null
302
299
  };
303
300
  const hh = await this.getHardhat();
304
301
  await hh.run('compile', hhOptions);
305
302
 
306
- if (root == null) {
307
- root = 'file://' + $path.normalize(process.cwd());
308
- }
309
- if (artifacts == null && root != null) {
310
- artifacts = class_Uri.combine(root, 'artifacts/');
311
- }
312
-
313
- if (solContractPath.toLowerCase().includes(root.toLowerCase())) {
314
- let i = solContractPath.toLowerCase().indexOf(root.toLowerCase());
315
- solContractPath = solContractPath.substring(i + root.length);
316
- }
303
+ const files = await Directory.readFilesAsync(paths.sources, '*.sol');
317
304
 
318
- let outputDir = class_Uri.combine(artifacts, solContractPath);
319
- let output = class_Uri.combine(outputDir, `${filename}.json`);
320
- if (await File.existsAsync(output) === false) {
321
- let path = `${outputDir}/`;
322
- if (await Directory.existsAsync(path) === false) {
323
- throw new Error(`No JSONs found in ${outputDir}, nor ${output}`);
324
- }
325
- let files = await Directory.readFilesAsync(path);
326
- let jsons = files.filter(x => /(?<!dbg)\.json$/.test(x.uri.file));
327
- if (jsons.length === 0) {
328
- throw new Error(`No JSONs output found in "${outputDir}/"`);
329
- }
330
- if (jsons.length === 1) {
331
- output = jsons[0].uri.toString();
332
- } else {
333
- let jsonFile = getJsonFile(jsons, filename);
334
- if (jsonFile == null) {
335
- jsonFile = getJsonFile(jsons, filenameRndSuffix);
336
- }
337
- if (jsonFile == null) {
338
- let contractName = options?.contractName;
339
- if (contractName == null) {
340
- let source = await File.readAsync<string>(solContractPath);
341
- let rgx = /contract \s*(?<contractName>[\w_]+)/ig;
342
- let matches = Array.from(source.matchAll(rgx));
343
- contractName = matches[matches.length - 1]?.groups?.contractName;
344
- options.contractName = contractName;
345
- }
346
- jsonFile = getJsonFile(jsons, contractName);
347
- }
348
-
349
- if (jsonFile == null) {
350
- $logger.log(`Files: ${ files.map(file => file.uri.file ).join(', ')}`);
351
- throw new Error(`Compiled JSON data not found for "${filename}" in "${outputDir}/"`);
352
- }
353
- output = jsonFile.uri.toString();
354
- }
355
- }
356
- function getJsonFile (files: InstanceType<typeof File>[], filename: string) {
357
- return files.find(file => {
358
- return file.uri.file === `${filename}.json`;
305
+ return await alot(files).mapAsync(async file => {
306
+ let solContractPath = file.uri.toLocalFile();
307
+ return await this.getContractFromSolPath(solContractPath, {
308
+ paths
359
309
  });
360
- }
310
+ }).toArrayAsync();
311
+ }
361
312
 
362
- let { abi, bytecode, contractName, linkReferences } = await File.readAsync<{
363
- abi,
364
- bytecode,
365
- contractName,
366
- linkReferences: Record<string /* path */, Record<string /* name */, any>>
367
- }> (output);
368
- let files = await Directory.readFilesAsync(dir, '*.sol');
369
- let { contract, ContractCtor } = ContractClassFactory.fromAbi<T>(null, abi, null, null, {
370
- $meta: {
371
- artifact: output
372
- }
373
- })
313
+ async compileSol<T extends ContractBase = IContractWrapped> (solContractPath: string, options?: {
314
+ paths?: {
315
+ root?: string
316
+ artifacts?: string
317
+ },
318
+ contractName?: string
319
+ tsgen?: boolean
320
+ install?: string
321
+ }): Promise<{
322
+ abi: TAbiItem[]
323
+ bytecode: TEth.Hex
324
+ output: string
325
+ // renamed output
326
+ artifact: string
327
+ source: IGeneratorSources
328
+ ContractCtor: Constructor<T>
329
+ linkReferences?: Record<string /* path */, Record<string /* name */, any>>
330
+ }> {
374
331
 
375
- let fileMap = await alot(files)
376
- .mapAsync(async file => {
377
- return {
378
- key: file.uri.toString(),
379
- content: await file.readAsync<string>()
380
- };
381
- })
382
- .toDictionaryAsync(x => x.key, x => ({ content: x.content }));
332
+ solContractPath = $path.normalize(solContractPath);
383
333
 
384
- return {
385
- abi,
386
- bytecode,
387
- output,
388
- artifact: output,
389
- source: {
390
- contractName: contractName ?? options?.contractName,
391
- files: fileMap
392
- },
393
- linkReferences,
394
- ContractCtor
334
+ const dir = $path.getDirectory(solContractPath);
335
+ const paths = {
336
+ sources: dir,
337
+ root: options?.paths?.root,
338
+ artifacts: options?.paths?.artifacts,
395
339
  };
340
+
341
+ let hhOptions = {
342
+ ...paths,
343
+
344
+ tsgen: options?.tsgen ?? false,
345
+ install: options?.install ?? null
346
+ };
347
+ const hh = await this.getHardhat();
348
+ await hh.run('compile', hhOptions);
349
+
350
+
351
+ return await this.getContractFromSolPath<T> (solContractPath, {
352
+ contractName: options?.contractName,
353
+ paths
354
+ });
396
355
  }
397
356
 
398
357
  async deployCode <TReturn extends ContractBase = IContractWrapped> (
@@ -507,4 +466,167 @@ export class HardhatProvider {
507
466
  return hh.network.provider as any as TTransport.Transport;
508
467
  }
509
468
 
469
+
470
+ private async getArtifactJsonPath (solContractPath: string, options: {
471
+ contractName?: string
472
+ paths: {
473
+ root: string
474
+ artifacts: string
475
+ }
476
+ }) {
477
+ let outputDir = class_Uri.combine(options.paths.artifacts, solContractPath, '/');
478
+ if (await Directory.existsAsync(outputDir) === false) {
479
+ throw new Error(`No JSONs found in ${outputDir} for ${solContractPath}`);
480
+ }
481
+
482
+ if (options.contractName != null) {
483
+ let artifactJsonPath = class_Uri.combine(outputDir, `${options.contractName}.json`);
484
+ if (await File.existsAsync(artifactJsonPath)) {
485
+ return artifactJsonPath;
486
+ }
487
+ }
488
+ const { filename } = $path.getFilename(solContractPath);
489
+
490
+ if (filename != null) {
491
+ let artifactJsonPath = class_Uri.combine(outputDir, `${filename}.json`);
492
+ if (await File.existsAsync(artifactJsonPath)) {
493
+ return artifactJsonPath;
494
+ }
495
+ }
496
+ if (filename == null) {
497
+ throw new Error(`Filename not extracted from ${solContractPath}`);
498
+ }
499
+
500
+
501
+ // Filename could contain random number, extract main-name
502
+
503
+
504
+ let files = await Directory.readFilesAsync(outputDir);
505
+ let jsons = files.filter(x => /(?<!dbg)\.json$/.test(x.uri.file));
506
+ if (jsons.length === 0) {
507
+ throw new Error(`No JSONs output found in "${outputDir}/"`);
508
+ }
509
+ if (jsons.length === 1) {
510
+ // Only one JSON artifact found, assume it's the main contract
511
+ let artifactJsonPath = jsons[0].uri.toString();
512
+ return artifactJsonPath;
513
+ }
514
+
515
+
516
+ let jsonFile = getJsonFile(jsons, filename);
517
+ if (jsonFile == null) {
518
+ const filenameRndSuffix = filename.replace(/_\d+$/, '');
519
+ if (filenameRndSuffix != null) {
520
+ jsonFile = getJsonFile(jsons, filenameRndSuffix);
521
+ }
522
+ }
523
+ if (jsonFile == null) {
524
+ let sourceFile = solContractPath;
525
+ if (await File.existsAsync(sourceFile) === false) {
526
+ sourceFile = class_Uri.combine(options.paths.root, sourceFile);
527
+ }
528
+ if (await File.existsAsync(sourceFile) === false) {
529
+ throw new Error(`Source file "${solContractPath}" not found in ${options.paths.root}`);
530
+ }
531
+
532
+
533
+ let source = await File.readAsync<string>(sourceFile);
534
+ let rgx = /contract \s*(?<contractName>[\w_]+)/ig;
535
+ let matches = Array.from(source.matchAll(rgx));
536
+ let contractName = matches[matches.length - 1]?.groups?.contractName;
537
+ options.contractName = contractName;
538
+ jsonFile = getJsonFile(jsons, contractName);
539
+ }
540
+
541
+ if (jsonFile == null) {
542
+ $logger.log(`Files: ${ files.map(file => file.uri.file ).join(', ')}`);
543
+ throw new Error(`Compiled JSON data not found for "${filename}" in "${outputDir}/"`);
544
+ }
545
+ let artifactJsonPath = jsonFile.uri.toString();
546
+ return artifactJsonPath;
547
+
548
+
549
+ function getJsonFile (files: InstanceType<typeof File>[], filename: string) {
550
+ return files.find(file => {
551
+ return file.uri.file === `${filename}.json`;
552
+ });
553
+ }
554
+ }
555
+
556
+ private async getPaths (paths?: { root?: string, artifacts?: string }) {
557
+ let root = paths?.root;
558
+ let artifacts = paths?.artifacts;
559
+
560
+ if (root == null) {
561
+ root = 'file://' + $path.normalize(process.cwd());
562
+ }
563
+ if (artifacts == null) {
564
+ artifacts = class_Uri.combine(root, 'artifacts/');
565
+ }
566
+
567
+ return { root, artifacts };
568
+ }
569
+
570
+
571
+ private async getContractFromSolPath <T extends ContractBase = IContractWrapped> (solContractPath, options: {
572
+ contractName?: string
573
+ paths: {
574
+ sources: string
575
+ root?: string;
576
+ artifacts?: string;
577
+ };
578
+ }) {
579
+
580
+ let { root, artifacts } = await this.getPaths (options?.paths);
581
+ let solContractPathRootRelative = $path.getRelativePath(solContractPath, root);
582
+
583
+ let artifactJsonPath = await this.getArtifactJsonPath(solContractPathRootRelative, {
584
+ contractName: options?.contractName,
585
+ paths: {
586
+ root,
587
+ artifacts,
588
+ },
589
+ })
590
+
591
+ let { abi, bytecode, contractName, linkReferences } = await File.readAsync<IJsonArtifact> (artifactJsonPath);
592
+ let { contract, ContractCtor } = ContractClassFactory.fromAbi<T>(null, abi, null, null, {
593
+ contractName,
594
+ $meta: {
595
+ name: contractName,
596
+ source: solContractPathRootRelative,
597
+ artifact: artifactJsonPath
598
+ }
599
+ })
600
+
601
+ let files = await Directory.readFilesAsync(options.paths.sources, '*.sol');
602
+ let fileMap = await alot(files)
603
+ .mapAsync(async file => {
604
+ return {
605
+ key: file.uri.toString(),
606
+ content: await file.readAsync<string>()
607
+ };
608
+ })
609
+ .toDictionaryAsync(x => x.key, x => ({ content: x.content }));
610
+
611
+ return {
612
+ abi,
613
+ bytecode,
614
+ output: artifactJsonPath,
615
+ artifact: artifactJsonPath,
616
+ source: {
617
+ contractName: contractName ?? options?.contractName,
618
+ files: fileMap
619
+ },
620
+ linkReferences,
621
+ ContractCtor
622
+ };
623
+ }
624
+ }
625
+
626
+
627
+ interface IJsonArtifact {
628
+ abi: TEth.Abi.Item[]
629
+ bytecode: TEth.Hex
630
+ contractName: string
631
+ linkReferences: Record<string /* path */, Record<string /* name */, any>>
510
632
  }
@@ -89,14 +89,16 @@ export class JsonArrayMultiStore<T> {
89
89
  private async getGroupedFiles () {
90
90
  try {
91
91
  let files = await Directory.readFilesAsync(this.options.path, '*.json');
92
- let rangeFiles = files
92
+ let rangeFiles = alot(files)
93
93
  .map(file => {
94
94
  return {
95
95
  file,
96
96
  range: this.parseRangeFilename(file.uri.file)
97
97
  };
98
98
  })
99
- .filter(x => x.range != null);
99
+ .filter(x => x.range != null)
100
+ .sortBy(x => x.range.start, 'asc')
101
+ .toArray();
100
102
  return rangeFiles;
101
103
  } catch (e) {
102
104
  return [];
@@ -2,7 +2,7 @@ import alot from 'alot'
2
2
  import { JsonConvert } from 'class-json'
3
3
  import { Alot } from 'alot/alot'
4
4
  import { JsonStoreFs } from './JsonStoreFs'
5
- import type { Constructor } from 'atma-utils'
5
+ import { Constructor } from '@dequanto/utils/types'
6
6
 
7
7
  export interface IStoreOptions<T, TStorage = T> {
8
8
  path: string
@@ -201,7 +201,7 @@ export namespace TEth {
201
201
  }
202
202
 
203
203
  export interface Input {
204
- name: string;
204
+ name?: string;
205
205
  type: string;
206
206
  indexed?: boolean;
207
207
  components?: Input[];
@@ -209,7 +209,7 @@ export namespace TEth {
209
209
  }
210
210
 
211
211
  export interface Output {
212
- name: string;
212
+ name?: string;
213
213
  type: string;
214
214
  components?: Output[];
215
215
  internalType?: string;
@@ -7,7 +7,8 @@ import { SlotDynamicArrayHandler } from './storage/handlers/SlotDynamicArrayHand
7
7
  import { SlotsStorageTransport, ISlotsStorageTransport, SlotsCursorTransport } from './storage/SlotsStorageTransport';
8
8
  import { TAddress } from '@dequanto/models/TAddress';
9
9
  import { ASlotsStorageHandler } from './storage/SlotsStorageHandler';
10
- import { Constructor, is_Object } from 'atma-utils';
10
+ import { Constructor } from '@dequanto/utils/types';
11
+ import { is_Object } from 'atma-utils';
11
12
  import { SlotMappingHandler } from './storage/handlers/SlotMappingHandler';
12
13
  import { SlotStringHandler } from './storage/handlers/SlotStringHandler';
13
14
  import { Accessor, IAccessorItem } from './storage/Accessor';
package/src/types/TAbi.ts CHANGED
@@ -20,13 +20,13 @@ export interface TAbiInput {
20
20
  name?: string;
21
21
  type: string;
22
22
  indexed?: boolean;
23
- components?: TAbiInput[];
23
+ components?: TAbiInput[];
24
24
  internalType?: string;
25
25
  }
26
26
 
27
27
  export interface TAbiOutput {
28
28
  name?: string;
29
29
  type: string;
30
- components?: TAbiOutput[];
30
+ components?: TAbiOutput[];
31
31
  internalType?: string;
32
32
  }
@@ -124,10 +124,17 @@ export namespace $abiParser {
124
124
  }
125
125
  let tupleName = line.substring(end + 1, delimiter).trim();
126
126
  if (tupleName) {
127
+ let type = 'tuple';
128
+ // e.g. tupleName "[] users" from (uint256 foo, uint256 bar)[] users
129
+ let arrMatch = /\[(\d+)?\]/.exec(tupleName);
130
+ if (arrMatch != null) {
131
+ type = type + arrMatch[0];
132
+ tupleName = tupleName.substring(arrMatch[0].length).trim();
133
+ }
127
134
  return [
128
135
  {
129
136
  name: tupleName,
130
- type: `tuple`,
137
+ type,
131
138
  components: params
132
139
  }
133
140
  ];
@@ -1,6 +1,7 @@
1
1
  import { TEth } from '@dequanto/models/TEth';
2
2
  import { $buffer } from './$buffer';
3
3
  import { $require } from './$require';
4
+ import { $is } from '@dequanto/utils/$is';
4
5
 
5
6
  export namespace $bigint {
6
7
 
@@ -48,6 +49,46 @@ export namespace $bigint {
48
49
  return BigInt(Math.round(amount));
49
50
  }
50
51
 
52
+ /**
53
+ * @param amount e.g "2.4 ether", "10 gwei", "1.7^18", "123456"
54
+ */
55
+ export function parse (amount: string): bigint {
56
+ if (/^\d+$/.test(amount) || $is.Hex(amount) ) {
57
+ return BigInt(amount);
58
+ }
59
+ let rgxName = /^(?<number>[\d.]+)\s*(?<name>ether|gwei|wei)$/i;
60
+ let rgxMatch = rgxName.exec(amount);
61
+ if (rgxMatch != null) {
62
+ let number = Number(rgxMatch.groups.number);
63
+ if (isNaN(number)) {
64
+ throw new Error(`Invalid format: ${amount}`);
65
+ }
66
+ let name = rgxMatch.groups.name;
67
+ if (name === 'ether') {
68
+ return toWei(number, ETHER_DECIMALS);
69
+ }
70
+ if (name === 'gwei') {
71
+ return toWei(number, GWEI_DECIMALS);
72
+ }
73
+ if (name === 'wei') {
74
+ return BigInt(number);
75
+ }
76
+ }
77
+
78
+ // 2.5^18
79
+ let rgxMantissa = /^(?<number>[\d.]+)\s*\^\s*(?<decimals>\d+)$/;
80
+ let rgxMantissaMatch = rgxMantissa.exec(amount);
81
+ if (rgxMantissaMatch != null) {
82
+ let number = Number(rgxMantissaMatch.groups.number);
83
+ let decimals = Number(rgxMantissaMatch.groups.decimals);
84
+ if (isNaN(number) || isNaN(decimals)) {
85
+ throw new Error(`Invalid format: ${amount}`);
86
+ }
87
+ return toWei(number, decimals);
88
+ }
89
+ throw new Error(`Unsupported format: ${amount}`);
90
+ }
91
+
51
92
  export function ensureWei (amount: number | bigint, decimals: number) {
52
93
  if (typeof amount === 'number') {
53
94
  return toWei(amount, decimals);
@@ -124,12 +124,17 @@ export namespace $contract {
124
124
  let evm = new EvmBytecode(input, { withConstructorCode: true });
125
125
  let opcodes = evm.getOpcodes();
126
126
  let codeSize = opcodes.findIndex(x => x.name === 'CODESIZE');
127
+ if (codeSize === -1) {
128
+ return {
129
+ bytecode: input,
130
+ arguments: '0x',
131
+ };
132
+ }
127
133
  let prev = opcodes[codeSize - 1];
128
134
  $require.True(/PUSH/.test(prev.name), `PUSH expected but got ${prev.name}`);
129
135
 
130
136
  let codeSizeValue = $buffer.toBigInt(prev.pushData) * 2n;
131
137
  let inputCursor = 2 /*0x*/ + Number(codeSizeValue);
132
-
133
138
  return {
134
139
  bytecode: input.substring(0, inputCursor),
135
140
  arguments: '0x' + input.substring(inputCursor),
@@ -45,6 +45,24 @@ export namespace $path {
45
45
  }
46
46
  return path;
47
47
  }
48
+ export function getDirectory (path: string) {
49
+ const dir = path.replace(/[^\/\\]+$/, '');
50
+ return dir;
51
+ }
52
+
53
+ export function getFilename (path: string) {
54
+ const match = /(?<filename>[^\/\\]+)\.(?<extension>\w+)$/.exec(path);
55
+ const { filename, extension } = match?.groups ?? { filename: null, extension: null };
56
+ return { filename, extension };
57
+ }
58
+
59
+ export function getRelativePath (path: string, base: string) {
60
+ let i = path.toLowerCase().indexOf(base.toLowerCase());
61
+ if (i > -1) {
62
+ return path.substring(i + base.length);
63
+ }
64
+ return path;
65
+ }
48
66
 
49
67
  function getRoot () {
50
68
  let base = $config.get('settings.base');
package/src/utils/$sig.ts CHANGED
@@ -681,7 +681,7 @@ export namespace $sig {
681
681
 
682
682
  type TKey = TEth.Hex | `p1:0x${string}`;
683
683
 
684
- namespace KeyUtils {
684
+ export namespace KeyUtils {
685
685
  const rgx = /^p1:/
686
686
 
687
687
  export async function withKey <TReturn> (account: TEth.EoAccount, fn: (account: TEth.EoAccount) => TReturn): Promise<TReturn> {
@@ -17,6 +17,9 @@ export type DeepPartial<T> = {
17
17
  DeepPartial<T[P]> | T[P]
18
18
  };
19
19
 
20
+ export type Constructor<T = {}> = {
21
+ new (...args: any[]): T;
22
+ };
20
23
 
21
24
 
22
25
  export type IntersectionTypeWithArrays<T1, T2, arrayKeys extends (keyof T1 & keyof T2)> = (