@0xbow/privacy-pools-core-sdk 1.0.4 → 1.1.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.
Files changed (32) hide show
  1. package/dist/esm/{fetchArtifacts.esm-C_DNv-_D.js → fetchArtifacts.esm-B6qveiM8.js} +2 -2
  2. package/dist/esm/{fetchArtifacts.esm-C_DNv-_D.js.map → fetchArtifacts.esm-B6qveiM8.js.map} +1 -1
  3. package/dist/esm/{fetchArtifacts.node-BBPNjgiT.js → fetchArtifacts.node-BPQQPsnb.js} +2 -2
  4. package/dist/esm/{fetchArtifacts.node-BBPNjgiT.js.map → fetchArtifacts.node-BPQQPsnb.js.map} +1 -1
  5. package/dist/esm/{index-BxzIe_IR.js → index-CRtEyHEf.js} +2884 -107
  6. package/dist/esm/index-CRtEyHEf.js.map +1 -0
  7. package/dist/esm/index.mjs +1 -1
  8. package/dist/index.d.mts +87 -14
  9. package/dist/node/{fetchArtifacts.esm-l-EDo53-.js → fetchArtifacts.esm-z-KXbilc.js} +2 -2
  10. package/dist/node/{fetchArtifacts.esm-l-EDo53-.js.map → fetchArtifacts.esm-z-KXbilc.js.map} +1 -1
  11. package/dist/node/{fetchArtifacts.node-DYwQHSF4.js → fetchArtifacts.node-DvqhqpW9.js} +2 -2
  12. package/dist/node/{fetchArtifacts.node-DYwQHSF4.js.map → fetchArtifacts.node-DvqhqpW9.js.map} +1 -1
  13. package/dist/node/{index-DGsIfUGw.js → index-BsmEKESv.js} +2884 -107
  14. package/dist/node/index-BsmEKESv.js.map +1 -0
  15. package/dist/node/index.mjs +1 -1
  16. package/dist/types/core/account.service.d.ts +8 -6
  17. package/dist/types/core/data.service.d.ts +28 -8
  18. package/dist/types/{fetchArtifacts.esm-IMTIZwq7.js → fetchArtifacts.esm-DF01Zpo3.js} +1 -1
  19. package/dist/types/{fetchArtifacts.node-BcXsBNCT.js → fetchArtifacts.node-BO6FBCAw.js} +1 -1
  20. package/dist/types/{index-DbuAhDci.js → index-CH7gk4sK.js} +2883 -106
  21. package/dist/types/index.js +1 -1
  22. package/dist/types/types/index.d.ts +1 -0
  23. package/dist/types/types/rateLimit.d.ts +51 -0
  24. package/package.json +4 -2
  25. package/src/core/account.service.ts +52 -39
  26. package/src/core/data.service.ts +324 -95
  27. package/src/types/index.ts +1 -0
  28. package/src/types/rateLimit.ts +66 -0
  29. package/dist/esm/index-BxzIe_IR.js.map +0 -1
  30. package/dist/node/index-DGsIfUGw.js.map +0 -1
  31. package/dist/types/utils/concurrency.d.ts +0 -15
  32. package/src/utils/concurrency.ts +0 -32
@@ -1,4 +1,4 @@
1
- export { n as AccountError, A as AccountService, B as BlockchainProvider, o as CircuitName, j as Circuits, C as CommitmentService, m as ContractError, k as ContractInteractionsService, D as DataService, E as ErrorCode, I as InvalidRpcUrl, P as PrivacyPoolSDK, l as ProofError, S as SDKError, W as WithdrawalService, e as bigintToHash, f as bigintToHex, i as calculateContext, a as generateDepositSecrets, g as generateMasterKeys, d as generateMerkleProof, b as generateWithdrawalSecrets, c as getCommitment, h as hashPrecommitment } from './index-DbuAhDci.js';
1
+ export { o as AccountError, A as AccountService, B as BlockchainProvider, p as CircuitName, k as Circuits, C as CommitmentService, n as ContractError, l as ContractInteractionsService, a as DEFAULT_LOG_FETCH_CONFIG, D as DataService, E as ErrorCode, I as InvalidRpcUrl, P as PrivacyPoolSDK, m as ProofError, S as SDKError, W as WithdrawalService, f as bigintToHash, i as bigintToHex, j as calculateContext, b as generateDepositSecrets, g as generateMasterKeys, e as generateMerkleProof, c as generateWithdrawalSecrets, d as getCommitment, h as hashPrecommitment } from './index-CH7gk4sK.js';
2
2
  import 'viem/accounts';
3
3
  import 'buffer';
4
4
  import 'http';
@@ -1,3 +1,4 @@
1
1
  export * from "./commitment.js";
2
2
  export * from "./withdrawal.js";
3
3
  export * from "./keys.js";
4
+ export * from "./rateLimit.js";
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Configuration options for rate-limited log fetching
3
+ */
4
+ export interface LogFetchConfig {
5
+ /**
6
+ * Maximum number of blocks to fetch in a single RPC call.
7
+ * Default: 10000 (typical limit for most RPC providers)
8
+ */
9
+ blockChunkSize: number;
10
+ /**
11
+ * Maximum number of concurrent log fetch operations.
12
+ * Default: 3
13
+ */
14
+ concurrency: number;
15
+ /**
16
+ * Delay in milliseconds between chunk requests (for additional throttling).
17
+ * Default: 0 (no delay)
18
+ */
19
+ chunkDelayMs: number;
20
+ /**
21
+ * Whether to retry failed chunk fetches.
22
+ * Default: true
23
+ */
24
+ retryOnFailure: boolean;
25
+ /**
26
+ * Maximum number of retries for a failed chunk.
27
+ * Default: 3
28
+ */
29
+ maxRetries: number;
30
+ /**
31
+ * Base delay for exponential backoff on retries (ms).
32
+ * Default: 1000
33
+ */
34
+ retryBaseDelayMs: number;
35
+ }
36
+ /**
37
+ * Default log fetch configuration
38
+ */
39
+ export declare const DEFAULT_LOG_FETCH_CONFIG: LogFetchConfig;
40
+ /**
41
+ * Per-chain log fetch configuration map
42
+ * Maps chainId to its specific LogFetchConfig
43
+ */
44
+ export type ChainLogFetchConfig = Map<number, Partial<LogFetchConfig>>;
45
+ /**
46
+ * Block range for chunked fetching
47
+ */
48
+ export interface BlockRange {
49
+ fromBlock: bigint;
50
+ toBlock: bigint;
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xbow/privacy-pools-core-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Typescript SDK for the Privacy Pool protocol",
5
5
  "repository": "https://github.com/0xbow-io/privacy-pools-core",
6
6
  "license": "Apache-2.0",
@@ -50,6 +50,8 @@
50
50
  "dependencies": {
51
51
  "@types/snarkjs": "0.7.9",
52
52
  "@zk-kit/lean-imt": "2.2.4",
53
+ "async": "3.2.6",
54
+ "dotenv": "17.3.1",
53
55
  "maci-crypto": "2.5.0",
54
56
  "snarkjs": "0.7.5",
55
57
  "typescript": "^5.7.3",
@@ -66,10 +68,10 @@
66
68
  "@rollup/plugin-node-resolve": "16.0.0",
67
69
  "@rollup/plugin-typescript": "12.1.2",
68
70
  "@rollup/plugin-wasm": "6.2.2",
71
+ "@types/async": "3.2.24",
69
72
  "@types/node": "20.3.1",
70
73
  "@types/snarkjs": "0.7.9",
71
74
  "commitlint": "19.4.1",
72
- "dotenv": "^17.3.1",
73
75
  "globals": "15.14.0",
74
76
  "husky": "9.1.5",
75
77
  "lint-staged": "15.2.10",
@@ -2,6 +2,7 @@ import { poseidon } from "maci-crypto/build/ts/hashing.js";
2
2
  import { Hash, Secret } from "../types/commitment.js";
3
3
  import { Hex, bytesToNumber } from "viem";
4
4
  import { mnemonicToAccount } from "viem/accounts";
5
+ import { mapLimit } from "async";
5
6
  import { DataService } from "./data.service.js";
6
7
  import {
7
8
  AccountCommitment,
@@ -18,7 +19,6 @@ import {
18
19
  } from "../types/events.js";
19
20
 
20
21
  import { Logger } from "../utils/logger.js";
21
- import { batchWithConcurrency } from "../utils/concurrency.js";
22
22
  import { AccountError } from "../errors/account.error.js";
23
23
  import { ErrorCode } from "../errors/base.error.js";
24
24
  import { EventError } from "../errors/events.error.js";
@@ -26,9 +26,11 @@ import { EventError } from "../errors/events.error.js";
26
26
  type AccountServiceConfig =
27
27
  | {
28
28
  mnemonic: string;
29
+ poolConcurrency?: number;
29
30
  }
30
31
  | {
31
32
  account: PrivacyPoolAccount;
33
+ poolConcurrency?: number;
32
34
  };
33
35
 
34
36
  /**
@@ -42,6 +44,7 @@ type AccountServiceConfig =
42
44
  export class AccountService {
43
45
  account: PrivacyPoolAccount;
44
46
  private readonly logger: Logger;
47
+ private readonly poolConcurrency: number;
45
48
 
46
49
  /**
47
50
  * Creates a new AccountService instance.
@@ -50,6 +53,7 @@ export class AccountService {
50
53
  * @param config - Configuration for the account service (either mnemonic or existing account)
51
54
  * @param config.mnemonic - Optional mnemonic for deterministic key generation
52
55
  * @param config.account - Optional existing account to initialize with
56
+ * @param config.poolConcurrency - Optional maximum number of pools to fetch events for concurrently (default: 2)
53
57
  *
54
58
  * @throws {AccountError} If account initialization fails
55
59
  */
@@ -58,6 +62,7 @@ export class AccountService {
58
62
  config: AccountServiceConfig
59
63
  ) {
60
64
  this.logger = new Logger({ prefix: "Account" });
65
+ this.poolConcurrency = config.poolConcurrency ?? 2;
61
66
  if ("mnemonic" in config) {
62
67
  this.account = this._initializeAccount(config.mnemonic);
63
68
  } else {
@@ -562,44 +567,51 @@ export class AccountService {
562
567
  }
563
568
 
564
569
  /**
565
- * Fetches events for a given set of pools with concurrency control
570
+ * Fetches events for a given set of pools
566
571
  *
567
572
  * @param pools - The pools to fetch events for
568
- * @param maxConcurrency - Maximum number of concurrent pool fetches (default: 5)
569
573
  *
570
574
  * @returns A map of pool scopes to their events
571
575
  */
572
- public async getEvents(
573
- pools: PoolInfo[],
574
- maxConcurrency: number = 5
575
- ): Promise<PoolEventsResult> {
576
+ public async getEvents(pools: PoolInfo[]): Promise<PoolEventsResult> {
576
577
  const events: PoolEventsResult = new Map();
577
578
 
578
- // Create tasks for batched execution
579
- const tasks = pools.map((pool) => async () => {
580
- this.logger.info(`Fetching events for pool`, {
581
- poolAddress: pool.address,
582
- poolChainId: pool.chainId,
583
- poolDeploymentBlock: pool.deploymentBlock,
584
- });
585
-
586
- const [depositEvents, withdrawalEvents, ragequitEvents] =
587
- await Promise.all([
588
- this.getDepositEvents(pool),
589
- this.getWithdrawalEvents(pool),
590
- this.getRagequitEvents(pool),
591
- ]);
592
-
593
- return {
594
- scope: pool.scope,
595
- depositEvents,
596
- withdrawalEvents,
597
- ragequitEvents,
598
- };
599
- });
600
-
601
- // Execute with concurrency control
602
- const poolEventResults = await batchWithConcurrency(tasks, maxConcurrency);
579
+ // Use mapLimit to control concurrency at pool level
580
+ const poolEventResults = await mapLimit(
581
+ pools,
582
+ this.poolConcurrency,
583
+ async (pool: PoolInfo) => {
584
+ try {
585
+ this.logger.info(`Fetching events for pool`, {
586
+ poolAddress: pool.address,
587
+ poolChainId: pool.chainId,
588
+ poolDeploymentBlock: pool.deploymentBlock,
589
+ });
590
+
591
+ const [depositEvents, withdrawalEvents, ragequitEvents] =
592
+ await Promise.all([
593
+ this.getDepositEvents(pool),
594
+ this.getWithdrawalEvents(pool),
595
+ this.getRagequitEvents(pool),
596
+ ]);
597
+
598
+ return {
599
+ status: "fulfilled" as const,
600
+ value: {
601
+ scope: pool.scope,
602
+ depositEvents,
603
+ withdrawalEvents,
604
+ ragequitEvents,
605
+ },
606
+ };
607
+ } catch (error) {
608
+ return {
609
+ status: "rejected" as const,
610
+ reason: error as Error,
611
+ };
612
+ }
613
+ }
614
+ );
603
615
 
604
616
  for (const result of poolEventResults) {
605
617
  if (result.status === "fulfilled") {
@@ -611,9 +623,12 @@ export class AccountService {
611
623
  ragequitEvents,
612
624
  });
613
625
  } else {
614
- events.set(result.reason.details?.scope as Hash, {
626
+ const errorWithDetails = result.reason as Error & { details?: { scope?: Hash } };
627
+ const scope = errorWithDetails.details?.scope as Hash;
628
+
629
+ events.set(scope, {
615
630
  reason: result.reason.message,
616
- scope: result.reason.details?.scope as Hash,
631
+ scope: scope,
617
632
  });
618
633
  }
619
634
  }
@@ -790,11 +805,10 @@ export class AccountService {
790
805
  * @param dataService - The data service to use for fetching events
791
806
  * @param source - The source to use for initializing the account. Either a mnemonic or an existing account service instance
792
807
  * @param pools - The pools to fetch events for
793
- * @param maxConcurrency - Maximum number of concurrent pool fetches (default: 5)
794
808
  *
795
809
  * @remarks
796
810
  * This method performs the following steps for each pool:
797
- * 1. Fetches deposit, withdrawal, and ragequit events for each pool (with concurrency control)
811
+ * 1. Fetches deposit, withdrawal, and ragequit events for each pool
798
812
  * 2. Processes deposit events and creates pool accounts
799
813
  * 3. Processes withdrawal events and adds commitments to pool accounts
800
814
  * 4. Processes ragequit events and adds ragequit to pool accounts
@@ -815,8 +829,7 @@ export class AccountService {
815
829
  | {
816
830
  service: AccountService;
817
831
  },
818
- pools: PoolInfo[],
819
- maxConcurrency: number = 5
832
+ pools: PoolInfo[]
820
833
  ): Promise<{ account: AccountService; errors: PoolEventsError[] }> {
821
834
  // Log the start of the history retrieval process
822
835
  const logger = new Logger({ prefix: "Account" });
@@ -839,7 +852,7 @@ export class AccountService {
839
852
  : { account: source.service.account }
840
853
  );
841
854
 
842
- const events = await account.getEvents(pools, maxConcurrency);
855
+ const events = await account.getEvents(pools);
843
856
 
844
857
  for (const [scope, result] of events.entries()) {
845
858
  if ("reason" in result) {