dequanto 0.1.99 → 0.2.6

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 (50) hide show
  1. package/lib/cjs/clients/ClientEventsStream.js +1 -2
  2. package/lib/cjs/clients/ClientEventsStream.js.map +1 -1
  3. package/lib/cjs/clients/handlers/RateLimitGuard.js +2 -0
  4. package/lib/cjs/clients/handlers/RateLimitGuard.js.map +1 -1
  5. package/lib/cjs/contracts/ContractBase.js +1 -1
  6. package/lib/cjs/contracts/ContractBase.js.map +1 -1
  7. package/lib/cjs/contracts/TxContract.js +2 -3
  8. package/lib/cjs/contracts/TxContract.js.map +1 -1
  9. package/lib/cjs/explorer/BlockchainExplorer.js +8 -5
  10. package/lib/cjs/explorer/BlockchainExplorer.js.map +1 -1
  11. package/lib/cjs/explorer/BlockchainExplorerFactory.js +1 -1
  12. package/lib/cjs/explorer/BlockchainExplorerFactory.js.map +1 -1
  13. package/lib/cjs/explorer/ContractVerifier.js +14 -5
  14. package/lib/cjs/explorer/ContractVerifier.js.map +1 -1
  15. package/lib/cjs/explorer/Etherscan.js +62 -4
  16. package/lib/cjs/explorer/Etherscan.js.map +1 -1
  17. package/lib/cjs/explorer/Evmscan.js +1 -4
  18. package/lib/cjs/explorer/Evmscan.js.map +1 -1
  19. package/lib/esm/clients/ClientEventsStream.js.map +1 -1
  20. package/lib/esm/clients/ClientEventsStream.mjs +1 -2
  21. package/lib/esm/clients/handlers/RateLimitGuard.js.map +1 -1
  22. package/lib/esm/clients/handlers/RateLimitGuard.mjs +2 -0
  23. package/lib/esm/contracts/ContractBase.js.map +1 -1
  24. package/lib/esm/contracts/ContractBase.mjs +1 -1
  25. package/lib/esm/contracts/TxContract.js.map +1 -1
  26. package/lib/esm/contracts/TxContract.mjs +2 -3
  27. package/lib/esm/explorer/BlockchainExplorer.js.map +1 -1
  28. package/lib/esm/explorer/BlockchainExplorer.mjs +8 -5
  29. package/lib/esm/explorer/BlockchainExplorerFactory.js.map +1 -1
  30. package/lib/esm/explorer/BlockchainExplorerFactory.mjs +1 -1
  31. package/lib/esm/explorer/ContractVerifier.js.map +1 -1
  32. package/lib/esm/explorer/ContractVerifier.mjs +14 -5
  33. package/lib/esm/explorer/Etherscan.js.map +1 -1
  34. package/lib/esm/explorer/Etherscan.mjs +62 -4
  35. package/lib/esm/explorer/Evmscan.js.map +1 -1
  36. package/lib/esm/explorer/Evmscan.mjs +1 -3
  37. package/lib/types/contracts/TxContract.d.ts +1 -1
  38. package/lib/types/explorer/BlockchainExplorerFactory.d.ts +4 -4
  39. package/lib/types/explorer/Etherscan.d.ts +46 -3
  40. package/lib/types/explorer/Evmscan.d.ts +1 -4
  41. package/package.json +2 -2
  42. package/src/clients/ClientEventsStream.ts +1 -2
  43. package/src/clients/handlers/RateLimitGuard.ts +2 -0
  44. package/src/contracts/ContractBase.ts +1 -1
  45. package/src/contracts/TxContract.ts +2 -3
  46. package/src/explorer/BlockchainExplorer.ts +8 -5
  47. package/src/explorer/BlockchainExplorerFactory.ts +6 -6
  48. package/src/explorer/ContractVerifier.ts +16 -5
  49. package/src/explorer/Etherscan.ts +64 -4
  50. package/src/explorer/Evmscan.ts +1 -3
@@ -41,9 +41,8 @@ export class ClientEventsStream<T extends TClientEventsStreamData<unknown[]> = a
41
41
  // this.subscriptions.connection = null;
42
42
  // }
43
43
  this.innerStream = web3Subscription;
44
- web3Subscription.on('data', this.onDataInner);
44
+ web3Subscription.subscribe(this.onDataInner, this.onErrorInner);
45
45
  web3Subscription.on('connected', this.onConnectedInner);
46
- web3Subscription.on('error', this.onErrorInner);
47
46
  }
48
47
 
49
48
  subscribe (cb: (x: T) => void, onError?: (x: Error | any) => void) {
@@ -12,6 +12,8 @@ let rateLimitRgx = {
12
12
  /exceed.+request/i,
13
13
  /try.+later/i,
14
14
  /request.+rate/i,
15
+ /max.+rate/i,
16
+ /max.+calls/i,
15
17
  /\b429\b/i,
16
18
  [/\bCUPS\b/i, /(\b(maximum|limit)\b)i/]
17
19
  ],
@@ -308,7 +308,7 @@ export abstract class ContractBase {
308
308
  let stream = this.getContractStream();
309
309
  let events = stream.on(event);
310
310
  if (cb) {
311
- events.onData(cb);
311
+ events.subscribe(cb);
312
312
  }
313
313
  return events;
314
314
  }
@@ -1,6 +1,5 @@
1
1
  import di from 'a-di';
2
2
  import alot from 'alot';
3
- import { Etherscan } from '@dequanto/explorer/Etherscan';
4
3
  import { IBlockchainExplorer } from '@dequanto/explorer/IBlockchainExplorer';
5
4
  import { ITransactionDetails } from '@dequanto/models/ITransactionDetails';
6
5
  import { ContractProvider } from './ContractProvider';
@@ -11,8 +10,8 @@ export class TxContract {
11
10
 
12
11
  private provider: ContractProvider;
13
12
 
14
- constructor (private explorer: IBlockchainExplorer = di.resolve(Etherscan)) {
15
- this.provider = di.resolve(ContractProvider, this.explorer);
13
+ constructor (private explorer: IBlockchainExplorer) {
14
+ this.provider = di.resolve(ContractProvider, explorer);
16
15
  }
17
16
 
18
17
  async parseTransaction (tx: TEth.TxLike) {
@@ -19,6 +19,7 @@ import { $http } from '@dequanto/utils/$http';
19
19
  import { IVerifier } from './verifiers/IVerifier';
20
20
  import { FsHtmlVerifier } from './verifiers/FsHtmlVerifier';
21
21
  import { TExplorer, TExplorerDefinition } from '@dequanto/models/TExplorer';
22
+ import { RateLimitGuard } from '@dequanto/clients/handlers/RateLimitGuard';
22
23
 
23
24
 
24
25
  /** @deprecated use TExplorerDefinition instead */
@@ -627,18 +628,20 @@ class HttpClient {
627
628
  let data = resp.data;
628
629
  if (data.message === 'NOTOK') {
629
630
  let str = data.result;
630
- if (/Max rate/i.test(str)) {
631
- let count = opts?.retryCount ?? 3;
631
+ let error = new Error(str);
632
+ if (RateLimitGuard.isRateLimited(error)) {
633
+ const MAX = 3;
634
+ let count = opts?.retryCount ?? MAX;
632
635
  if (--count === 0) {
633
- throw new Error(str);
636
+ throw error;
634
637
  }
635
- await $promise.wait(200);
638
+ await $promise.wait(300 * (MAX - count + 1));
636
639
  return this.getInner(url, {
637
640
  ...(opts ?? {}),
638
641
  retryCount: count
639
642
  });
640
643
  }
641
- throw new Error(str);
644
+ throw error;
642
645
  }
643
646
  if (data.result == null) {
644
647
  $logger.warn(`Blockchain "${url}" explorer returned empty result`, data);
@@ -22,11 +22,11 @@ export namespace BlockchainExplorerFactory {
22
22
  registry[platform] = explorer;
23
23
  }
24
24
 
25
- export function get (platform: TPlatform | number)
26
- export function get (config: TExplorerDefinition)
25
+ export function get (platform: TPlatform | number): IBlockchainExplorer
26
+ export function get (config: TExplorerDefinition): IBlockchainExplorer
27
27
  /** @obsolete */
28
- export function get (platform: TPlatform | number, opts: IBlockchainExplorerFactoryParams)
29
- export function get (mix: TPlatform | number | TExplorerDefinition, opts?: IBlockchainExplorerFactoryParams) {
28
+ export function get (platform: TPlatform | number, opts: IBlockchainExplorerFactoryParams): IBlockchainExplorer
29
+ export function get (mix: TPlatform | number | TExplorerDefinition, opts?: IBlockchainExplorerFactoryParams): IBlockchainExplorer {
30
30
 
31
31
  $require.notNull(mix, `ArgumentException: no platform in BlockchainExplorerFactory`);
32
32
 
@@ -35,8 +35,8 @@ export namespace BlockchainExplorerFactory {
35
35
 
36
36
  let cfg = $config.getExplorerOptions(platform);
37
37
  let params = {
38
- ...(opts ?? {}),
39
38
  ...(cfg ?? {}),
39
+ ...(opts ?? {}),
40
40
  } as any;
41
41
 
42
42
  let Ctor = registry[platform];
@@ -51,7 +51,7 @@ export namespace BlockchainExplorerFactory {
51
51
  }
52
52
 
53
53
  /** Same as sync variation, but ensures the config is being fetched */
54
- export async function getAsync (platform: TPlatform, opts?: IBlockchainExplorerFactoryParams) {
54
+ export async function getAsync (platform: TPlatform, opts?: IBlockchainExplorerFactoryParams): Promise<IBlockchainExplorer> {
55
55
  await Config.get();
56
56
  return get(platform, opts);
57
57
  }
@@ -87,12 +87,17 @@ export class ContractVerifier {
87
87
  address?: TEth.Address
88
88
  proxyFor?: TEth.Address
89
89
  constructorParams?: any[]
90
+ tx?: TEth.Hex
90
91
  }): Promise<TSubmissionStatus> {
91
92
  let client = this.deployments.client;
92
93
  let contractName = typeof Ctor === 'string' ? Ctor : Ctor.name;
93
- let deployment = await this.deployments.store.getDeploymentInfo(Ctor, opts);
94
- $require.notNull(deployment, `Deployment not found for ${opts?.id ?? contractName}`);
95
- let address = opts?.address ?? deployment.implementation ?? deployment.address;
94
+ let address = opts?.address;
95
+
96
+ if ($is.Address(address) === false) {
97
+ let deployment = await this.deployments.store.getDeploymentInfo(Ctor, opts);
98
+ $require.notNull(deployment, `Deployment not found for ${opts?.id ?? contractName}`);
99
+ address = deployment.implementation ?? deployment.address;
100
+ }
96
101
 
97
102
  try {
98
103
  this.logger.log(`Checking if already verified ${address}`);
@@ -119,8 +124,14 @@ export class ContractVerifier {
119
124
  let ctorAbi = abi.find(x => x.type === 'constructor');
120
125
  if (ctorAbi?.inputs?.length > 0) {
121
126
  if (opts?.constructorParams == null) {
122
- let tx = await this.deployments.client.getTransaction(deployment.tx);
123
- $require.notNull(tx, `Tx ${deployment.tx} not found in ${this.deployments.client.network}`);
127
+ let txHash = opts.tx;
128
+ if (txHash == null) {
129
+ let deployment = await this.deployments.store.getDeploymentInfo(Ctor, opts);
130
+ $require.notNull(deployment, `Deployment not found for ${opts?.id ?? contractName}`);
131
+ txHash = deployment.tx;
132
+ }
133
+ let tx = await this.deployments.client.getTransaction(txHash);
134
+ $require.notNull(tx, `Tx ${txHash} not found in ${this.deployments.client.network}`);
124
135
  let parsedArguments = $contract.decodeDeploymentArguments(tx.input, ctorAbi);
125
136
  constructorArguments = parsedArguments.encoded;
126
137
  } else {
@@ -1,14 +1,74 @@
1
1
  import di from 'a-di';
2
+ import memd from 'memd';
2
3
  import { $config } from '@dequanto/utils/$config';
3
4
  import { EthWeb3Client } from '@dequanto/clients/EthWeb3Client';
4
5
  import { TPlatform } from '@dequanto/models/TPlatform';
6
+ import { IBlockchainExplorer, IBlockchainTransferEvent } from './IBlockchainExplorer';
5
7
  import { BlockchainExplorer } from './BlockchainExplorer';
8
+ import { IContractDetails } from '@dequanto/models/IContractDetails';
9
+ import { TAddress } from '@dequanto/models/TAddress';
10
+ import { TEth } from '@dequanto/models/TEth';
6
11
 
7
12
  const contracts = $config.get('contracts.eth', [])
8
- export class Etherscan extends BlockchainExplorer {
9
13
 
10
- constructor () {
11
- super({
14
+
15
+ export class Etherscan implements IBlockchainExplorer {
16
+ inMemoryDb: IContractDetails[];
17
+ getContractMeta(q: string) {
18
+ return this.getExplorer().getContractMeta(q);
19
+ }
20
+ getContractCreation(address: TEth.Address) {
21
+ return this.getExplorer().getContractCreation(address);
22
+ }
23
+ getContractAbi(address: TEth.Address, opts?) {
24
+ return this.getExplorer().getContractAbi(address, opts);
25
+ }
26
+ getContractSource(address: TEth.Address) {
27
+ return this.getExplorer().getContractSource(address);
28
+ }
29
+ submitContractVerification(contractData) {
30
+ return this.getExplorer().submitContractVerification(contractData);
31
+ }
32
+ checkContractVerificationSubmission(submission) {
33
+ return this.getExplorer().checkContractVerificationSubmission(submission);
34
+ }
35
+ submitContractProxyVerification(contractData) {
36
+ return this.getExplorer().submitContractProxyVerification(contractData);
37
+ }
38
+ checkContractProxyVerificationSubmission(submission: { guid: any; }): Promise<string> {
39
+ return this.getExplorer().checkContractProxyVerificationSubmission(submission);
40
+ }
41
+ getTransactions(address: TEth.Address, params?) {
42
+ return this.getExplorer().getTransactions(address, params);
43
+ }
44
+ getTransactionsAll(address: TEth.Address) {
45
+ return this.getExplorer().getTransactionsAll(address);
46
+ }
47
+ getInternalTransactions(address: TEth.Address, params) {
48
+ return this.getExplorer().getInternalTransactions(address, params);
49
+ }
50
+ getInternalTransactionsAll(address: TEth.Address): Promise<TEth.TxLike[]> {
51
+ return this.getExplorer().getInternalTransactionsAll(address);
52
+ }
53
+ getErc20Transfers(address: TEth.Address, fromBlockNumber?: number): Promise<IBlockchainTransferEvent[]> {
54
+ return this.getExplorer().getErc20Transfers(address);
55
+ }
56
+ getErc20TransfersAll(address: TEth.Address, fromBlockNumber?: number): Promise<IBlockchainTransferEvent[]> {
57
+ return this.getExplorer().getErc20TransfersAll(address);
58
+ }
59
+ registerAbi(abis: { name: any; address: any; abi: any; }[]) {
60
+ return this.getExplorer().registerAbi(abis);
61
+ }
62
+
63
+
64
+
65
+ @memd.deco.memoize()
66
+ private getExplorer () {
67
+ return new BlockchainExplorer(this.getConfig());
68
+ }
69
+
70
+ private getConfig () {
71
+ return {
12
72
  platform: 'eth',
13
73
  ABI_CACHE: `./cache/eth/abis.json`,
14
74
  CONTRACTS: contracts,
@@ -34,7 +94,7 @@ export class Etherscan extends BlockchainExplorer {
34
94
  www: config?.www,
35
95
  };
36
96
  }
37
- })
97
+ }
38
98
  }
39
99
  }
40
100
 
@@ -5,6 +5,4 @@ import { BlockchainExplorer } from './BlockchainExplorer';
5
5
  /**
6
6
  * @obsolete Use BlockchainExplorer class instead.
7
7
  */
8
- export function Evmscan (options: { platform: TPlatform }) {
9
- return new BlockchainExplorer(options);
10
- }
8
+ export const Evmscan = BlockchainExplorer;