@0xbow/privacy-pools-core-sdk 0.1.21 → 1.0.2

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 (43) hide show
  1. package/README.md +4 -4
  2. package/dist/esm/{fetchArtifacts.esm-CXLPgzhJ.js → fetchArtifacts.esm-D0mKkSYH.js} +2 -2
  3. package/dist/esm/{fetchArtifacts.esm-CXLPgzhJ.js.map → fetchArtifacts.esm-D0mKkSYH.js.map} +1 -1
  4. package/dist/esm/{fetchArtifacts.node-B3pPMuWd.js → fetchArtifacts.node-D2RwI1ei.js} +2 -2
  5. package/dist/esm/{fetchArtifacts.node-B3pPMuWd.js.map → fetchArtifacts.node-D2RwI1ei.js.map} +1 -1
  6. package/dist/esm/{index-C_oO7cOn.js → index-CysEkDfm.js} +416 -67
  7. package/dist/esm/index-CysEkDfm.js.map +1 -0
  8. package/dist/esm/index.mjs +1 -1
  9. package/dist/index.d.mts +185 -46
  10. package/dist/node/{fetchArtifacts.esm-DoJiimN3.js → fetchArtifacts.esm-GuREmUVE.js} +2 -2
  11. package/dist/node/{fetchArtifacts.esm-DoJiimN3.js.map → fetchArtifacts.esm-GuREmUVE.js.map} +1 -1
  12. package/dist/node/{fetchArtifacts.node-B4Ey9DOV.js → fetchArtifacts.node-80qrImLq.js} +2 -2
  13. package/dist/node/{fetchArtifacts.node-B4Ey9DOV.js.map → fetchArtifacts.node-80qrImLq.js.map} +1 -1
  14. package/dist/node/{index-CwopFzOC.js → index-bIu80opN.js} +416 -67
  15. package/dist/node/index-bIu80opN.js.map +1 -0
  16. package/dist/node/index.mjs +1 -1
  17. package/dist/types/core/account.service.d.ts +116 -4
  18. package/dist/types/core/contracts.service.d.ts +9 -1
  19. package/dist/types/core/sdk.d.ts +2 -1
  20. package/dist/types/core/withdrawal.service.d.ts +2 -2
  21. package/dist/types/errors/account.error.d.ts +2 -0
  22. package/dist/types/errors/base.error.d.ts +1 -0
  23. package/dist/types/errors/events.error.d.ts +9 -0
  24. package/dist/types/{fetchArtifacts.esm-CxFhH8oR.js → fetchArtifacts.esm-Ok2Ropox.js} +1 -1
  25. package/dist/types/{fetchArtifacts.node-Cqk_Z-mS.js → fetchArtifacts.node-DpNFJc75.js} +1 -1
  26. package/dist/types/{index-CIvuCHHq.js → index-xpjDqElC.js} +415 -66
  27. package/dist/types/index.js +1 -1
  28. package/dist/types/interfaces/contracts.interface.d.ts +7 -0
  29. package/dist/types/types/events.d.ts +11 -1
  30. package/package.json +2 -2
  31. package/src/core/account.service.ts +479 -61
  32. package/src/core/contracts.service.ts +35 -0
  33. package/src/core/data.service.ts +2 -3
  34. package/src/core/sdk.ts +2 -1
  35. package/src/core/withdrawal.service.ts +25 -9
  36. package/src/crypto.ts +11 -2
  37. package/src/errors/account.error.ts +14 -0
  38. package/src/errors/base.error.ts +5 -0
  39. package/src/errors/events.error.ts +38 -0
  40. package/src/interfaces/contracts.interface.ts +8 -0
  41. package/src/types/events.ts +15 -1
  42. package/dist/esm/index-C_oO7cOn.js.map +0 -1
  43. package/dist/node/index-CwopFzOC.js.map +0 -1
@@ -15082,19 +15082,10 @@ var __setModuleDefault = Object.create ? (function(o, v) {
15082
15082
  o["default"] = v;
15083
15083
  };
15084
15084
 
15085
- var ownKeys = function(o) {
15086
- ownKeys = Object.getOwnPropertyNames || function (o) {
15087
- var ar = [];
15088
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
15089
- return ar;
15090
- };
15091
- return ownKeys(o);
15092
- };
15093
-
15094
15085
  function __importStar(mod) {
15095
15086
  if (mod && mod.__esModule) return mod;
15096
15087
  var result = {};
15097
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
15088
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
15098
15089
  __setModuleDefault(result, mod);
15099
15090
  return result;
15100
15091
  }
@@ -15176,25 +15167,12 @@ function __disposeResources(env) {
15176
15167
  return next();
15177
15168
  }
15178
15169
 
15179
- function __rewriteRelativeImportExtension(path, preserveJsx) {
15180
- if (typeof path === "string" && /^\.\.?\//.test(path)) {
15181
- return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
15182
- return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
15183
- });
15184
- }
15185
- return path;
15186
- }
15187
-
15188
15170
  var tslib_es6 = {
15189
15171
  __extends: __extends,
15190
15172
  __assign: __assign,
15191
15173
  __rest: __rest,
15192
15174
  __decorate: __decorate,
15193
15175
  __param: __param,
15194
- __esDecorate: __esDecorate,
15195
- __runInitializers: __runInitializers,
15196
- __propKey: __propKey,
15197
- __setFunctionName: __setFunctionName,
15198
15176
  __metadata: __metadata,
15199
15177
  __awaiter: __awaiter,
15200
15178
  __generator: __generator,
@@ -15217,7 +15195,6 @@ var tslib_es6 = {
15217
15195
  __classPrivateFieldIn: __classPrivateFieldIn,
15218
15196
  __addDisposableResource: __addDisposableResource,
15219
15197
  __disposeResources: __disposeResources,
15220
- __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,
15221
15198
  };
15222
15199
 
15223
15200
  var tslib_es6$1 = /*#__PURE__*/Object.freeze({
@@ -15247,7 +15224,6 @@ var tslib_es6$1 = /*#__PURE__*/Object.freeze({
15247
15224
  __propKey: __propKey,
15248
15225
  __read: __read,
15249
15226
  __rest: __rest,
15250
- __rewriteRelativeImportExtension: __rewriteRelativeImportExtension,
15251
15227
  __runInitializers: __runInitializers,
15252
15228
  __setFunctionName: __setFunctionName,
15253
15229
  __spread: __spread,
@@ -50363,9 +50339,9 @@ var hashingExports = requireHashing();
50363
50339
 
50364
50340
  /**
50365
50341
  * @module @zk-kit/utils
50366
- * @version 1.2.1
50342
+ * @version 1.4.1
50367
50343
  * @file Essential zero-knowledge utility library for JavaScript developers.
50368
- * @copyright Ethereum Foundation 2024
50344
+ * @copyright Ethereum Foundation 2025
50369
50345
  * @license MIT
50370
50346
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
50371
50347
  */
@@ -50415,9 +50391,9 @@ function isArray(value) {
50415
50391
 
50416
50392
  /**
50417
50393
  * @module @zk-kit/utils
50418
- * @version 1.2.1
50394
+ * @version 1.4.1
50419
50395
  * @file Essential zero-knowledge utility library for JavaScript developers.
50420
- * @copyright Ethereum Foundation 2024
50396
+ * @copyright Ethereum Foundation 2025
50421
50397
  * @license MIT
50422
50398
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/utils}
50423
50399
  */
@@ -50484,9 +50460,9 @@ function requireArray(parameterValue, parameterName) {
50484
50460
 
50485
50461
  /**
50486
50462
  * @module @zk-kit/lean-imt
50487
- * @version 2.2.2
50463
+ * @version 2.2.4
50488
50464
  * @file Lean Incremental Merkle tree implementation in TypeScript.
50489
- * @copyright Ethereum Foundation 2024
50465
+ * @copyright Ethereum Foundation 2025
50490
50466
  * @license MIT
50491
50467
  * @see [Github]{@link https://github.com/privacy-scaling-explorations/zk-kit/tree/main/packages/lean-imt}
50492
50468
  */
@@ -50617,7 +50593,7 @@ class LeanIMT {
50617
50593
  throw new Error("There are no leaves to add");
50618
50594
  }
50619
50595
  let startIndex = this.size >> 1;
50620
- this._nodes[0].push(...leaves);
50596
+ this._nodes[0] = this._nodes[0].concat(leaves);
50621
50597
  // Calculate how many tree levels will need to be added
50622
50598
  // using the number of leaves.
50623
50599
  const numberOfNewLevels = Math.ceil(Math.log2(this.size)) - this.depth;
@@ -50748,7 +50724,12 @@ class LeanIMT {
50748
50724
  }
50749
50725
  // The index might be different from the original index of the leaf, since
50750
50726
  // in some cases some siblings are not included (as explained above).
50751
- return { root: this.root, leaf, index: Number.parseInt(path.reverse().join(""), 2), siblings };
50727
+ return {
50728
+ root: this.root,
50729
+ leaf,
50730
+ index: path.length === 0 ? 0 : Number.parseInt(path.reverse().join(""), 2),
50731
+ siblings
50732
+ };
50752
50733
  }
50753
50734
  /**
50754
50735
  * It verifies a {@link LeanIMTMerkleProof} to confirm that a leaf indeed
@@ -50956,7 +50937,14 @@ function generateMerkleProof(leaves, leaf) {
50956
50937
  if (leafIndex === -1) {
50957
50938
  throw new PrivacyPoolError(ErrorCode$1.MERKLE_ERROR, "Leaf not found in the leaves array.");
50958
50939
  }
50959
- return tree.generateProof(leafIndex);
50940
+ const proof = tree.generateProof(leafIndex);
50941
+ if (proof.siblings.length < 32) {
50942
+ proof.siblings = [
50943
+ ...proof.siblings,
50944
+ ...Array(32 - proof.siblings.length).fill(BigInt(0)),
50945
+ ];
50946
+ }
50947
+ return proof;
50960
50948
  }
50961
50949
  function bigintToHash(value) {
50962
50950
  return `0x${value.toString(16).padStart(64, "0")}`;
@@ -51082,10 +51070,10 @@ const circuitToAsset = {
51082
51070
 
51083
51071
  async function importFetchVersionedArtifact(isBrowser) {
51084
51072
  if (isBrowser) {
51085
- return import('./fetchArtifacts.esm-CxFhH8oR.js');
51073
+ return import('./fetchArtifacts.esm-Ok2Ropox.js');
51086
51074
  }
51087
51075
  else {
51088
- return import('./fetchArtifacts.node-Cqk_Z-mS.js');
51076
+ return import('./fetchArtifacts.node-DpNFJc75.js');
51089
51077
  }
51090
51078
  }
51091
51079
 
@@ -53222,6 +53210,9 @@ class ContractError extends SDKError {
53222
53210
  static scopeNotFound(scope) {
53223
53211
  return new ContractError(`No pool found for scope ${scope.toString()}`, ErrorCode.CONTRACT_ERROR);
53224
53212
  }
53213
+ static assetNotFound(address) {
53214
+ return new ContractError(`Asset ${address} has no pool`, ErrorCode.CONTRACT_ERROR);
53215
+ }
53225
53216
  }
53226
53217
 
53227
53218
  class ContractInteractionsService {
@@ -53430,6 +53421,34 @@ class ContractInteractionsService {
53430
53421
  });
53431
53422
  return BigInt(stateSize);
53432
53423
  }
53424
+ /**
53425
+ * Retrieves data from the corresponding asset
53426
+ *
53427
+ * @param assetAddress - The asset contract address.
53428
+ * @returns AssetConfig - An object containing the privacy pool address, minimum deposit amount, vetting fee and maximum relaying fee.
53429
+ * @throws ContractError if the asset does not exist in the pool.
53430
+ */
53431
+ async getAssetConfig(assetAddress) {
53432
+ const assetConfig = await this.publicClient.readContract({
53433
+ address: this.entrypointAddress,
53434
+ abi: IEntrypointABI,
53435
+ account: this.account,
53436
+ args: [assetAddress],
53437
+ functionName: "assetConfig",
53438
+ });
53439
+ const [pool, minimumDepositAmount, vettingFeeBPS, maxRelayFeeBPS] = assetConfig;
53440
+ // if no pool throw error
53441
+ if (!pool ||
53442
+ pool === "0x0000000000000000000000000000000000000000") {
53443
+ throw ContractError.assetNotFound(assetAddress);
53444
+ }
53445
+ return {
53446
+ pool: getAddress(pool),
53447
+ minimumDepositAmount,
53448
+ vettingFeeBPS,
53449
+ maxRelayFeeBPS
53450
+ };
53451
+ }
53433
53452
  /**
53434
53453
  * Retrieves data about a specific scope, including the associated privacy pool
53435
53454
  * and the asset used in that pool.
@@ -76209,6 +76228,22 @@ class WithdrawalService {
76209
76228
  * Prepares input signals for the withdrawal circuit.
76210
76229
  */
76211
76230
  prepareInputSignals(commitment, input) {
76231
+ let existingValue;
76232
+ let existingNullifier;
76233
+ let existingSecret;
76234
+ let label;
76235
+ if ("preimage" in commitment) {
76236
+ existingValue = commitment.preimage.value;
76237
+ existingNullifier = commitment.preimage.precommitment.nullifier;
76238
+ existingSecret = commitment.preimage.precommitment.secret;
76239
+ label = commitment.preimage.label;
76240
+ }
76241
+ else {
76242
+ existingValue = commitment.value;
76243
+ existingNullifier = commitment.nullifier;
76244
+ existingSecret = commitment.secret;
76245
+ label = commitment.label;
76246
+ }
76212
76247
  return {
76213
76248
  // Public signals
76214
76249
  withdrawnValue: input.withdrawalAmount,
@@ -76218,10 +76253,10 @@ class WithdrawalService {
76218
76253
  ASPTreeDepth: input.aspTreeDepth,
76219
76254
  context: input.context,
76220
76255
  // Private signals
76221
- label: commitment.preimage.label,
76222
- existingValue: commitment.preimage.value,
76223
- existingNullifier: commitment.preimage.precommitment.nullifier,
76224
- existingSecret: commitment.preimage.precommitment.secret,
76256
+ label,
76257
+ existingValue,
76258
+ existingNullifier,
76259
+ existingSecret,
76225
76260
  newNullifier: input.newNullifier,
76226
76261
  newSecret: input.newSecret,
76227
76262
  // Merkle Proofs
@@ -76301,6 +76336,12 @@ class AccountError extends SDKError {
76301
76336
  static accountInitializationFailed(reason) {
76302
76337
  return new AccountError(`Failed to initialize account: ${reason}`, ErrorCode.OPERATION_FAILED);
76303
76338
  }
76339
+ static duplicatePools(scope) {
76340
+ return new AccountError(`Duplicate pools found for scope: ${scope.toString()}`, ErrorCode.INVALID_INPUT);
76341
+ }
76342
+ static invalidIndex(index) {
76343
+ return new AccountError(`Invalid index: ${index.toString()}`, ErrorCode.INVALID_INPUT);
76344
+ }
76304
76345
  }
76305
76346
 
76306
76347
  var LogLevel;
@@ -76344,6 +76385,38 @@ class Logger {
76344
76385
  }
76345
76386
  }
76346
76387
 
76388
+ class DataError extends SDKError {
76389
+ constructor(message, code = ErrorCode.NETWORK_ERROR, details) {
76390
+ super(message, code, details);
76391
+ this.name = "DataError";
76392
+ }
76393
+ static invalidLog(type, reason) {
76394
+ return new DataError(`Invalid ${type} log: ${reason}`, ErrorCode.INVALID_INPUT);
76395
+ }
76396
+ static chainNotConfigured(chainId) {
76397
+ return new DataError(`No configuration found for chain ID ${chainId}`, ErrorCode.INVALID_INPUT);
76398
+ }
76399
+ static networkError(chainId, error) {
76400
+ return new DataError(`Network error on chain ${chainId}: ${error.message}`, ErrorCode.NETWORK_ERROR, { originalError: error });
76401
+ }
76402
+ }
76403
+
76404
+ class EventError extends DataError {
76405
+ constructor(message, code = ErrorCode.NETWORK_ERROR, details) {
76406
+ super(message, code, details);
76407
+ this.name = "EventError";
76408
+ }
76409
+ static depositEventError(chainId, scope, error) {
76410
+ return new EventError(`Error fetching deposit events for chain ${chainId}: ${error.message}`, ErrorCode.NETWORK_ERROR, { originalError: error, scope });
76411
+ }
76412
+ static withdrawalEventError(chainId, scope, error) {
76413
+ return new EventError(`Error fetching withdrawal events for chain ${chainId}: ${error.message}`, ErrorCode.NETWORK_ERROR, { originalError: error, scope });
76414
+ }
76415
+ static ragequitEventError(chainId, scope, error) {
76416
+ return new EventError(`Error fetching ragequit events for chain ${chainId}: ${error.message}`, ErrorCode.NETWORK_ERROR, { originalError: error, scope });
76417
+ }
76418
+ }
76419
+
76347
76420
  /**
76348
76421
  * Service responsible for managing privacy pool accounts and their associated commitments.
76349
76422
  * Handles account initialization, deposit/withdrawal tracking, and history synchronization.
@@ -76360,15 +76433,21 @@ class AccountService {
76360
76433
  * Creates a new AccountService instance.
76361
76434
  *
76362
76435
  * @param dataService - Service for fetching on-chain events
76363
- * @param account - Optional existing account to initialize with
76364
- * @param mnemonic - Optional mnemonic for deterministic key generation
76436
+ * @param config - Configuration for the account service (either mnemonic or existing account)
76437
+ * @param config.mnemonic - Optional mnemonic for deterministic key generation
76438
+ * @param config.account - Optional existing account to initialize with
76365
76439
  *
76366
76440
  * @throws {AccountError} If account initialization fails
76367
76441
  */
76368
- constructor(dataService, mnemonic, account) {
76442
+ constructor(dataService, config) {
76369
76443
  this.dataService = dataService;
76370
76444
  this.logger = new Logger({ prefix: "Account" });
76371
- this.account = account || this._initializeAccount(mnemonic);
76445
+ if ("mnemonic" in config) {
76446
+ this.account = this._initializeAccount(config.mnemonic);
76447
+ }
76448
+ else {
76449
+ this.account = config.account;
76450
+ }
76372
76451
  }
76373
76452
  /**
76374
76453
  * Initializes a new account from a mnemonic phrase.
@@ -76396,7 +76475,7 @@ class AccountService {
76396
76475
  masterKeys: [masterNullifier, masterSecret],
76397
76476
  poolAccounts: new Map(),
76398
76477
  creationTimestamp: 0n,
76399
- lastUpdateTimestamp: 0n
76478
+ lastUpdateTimestamp: 0n,
76400
76479
  };
76401
76480
  }
76402
76481
  catch (error) {
@@ -76518,8 +76597,11 @@ class AccountService {
76518
76597
  * The precommitment is a hash of the nullifier and secret, used in the deposit process.
76519
76598
  */
76520
76599
  createDepositSecrets(scope, index) {
76600
+ if (index && index < 0n) {
76601
+ throw AccountError.invalidIndex(index);
76602
+ }
76521
76603
  const accounts = this.account.poolAccounts.get(scope);
76522
- index = index || BigInt(accounts?.length || 0);
76604
+ index = index ?? BigInt(accounts?.length || 0);
76523
76605
  const nullifier = this._genDepositNullifier(scope, index);
76524
76606
  const secret = this._genDepositSecret(scope, index);
76525
76607
  const precommitment = this._hashPrecommitment(nullifier, secret);
@@ -76677,6 +76759,288 @@ class AccountService {
76677
76759
  return foundAccount;
76678
76760
  }
76679
76761
  /**
76762
+ * Fetches deposit events for a given pool and returns a map of precommitments to their events for efficient lookup
76763
+ *
76764
+ * @param pool - The pool to fetch deposit events for
76765
+ *
76766
+ * @returns A map of precommitments to their events
76767
+ */
76768
+ async getDepositEvents(pool) {
76769
+ try {
76770
+ const depositEvents = await this.dataService.getDeposits(pool);
76771
+ this.logger.info(`Found deposits for pool`, {
76772
+ poolAddress: pool.address,
76773
+ poolChainId: pool.chainId,
76774
+ depositCount: depositEvents.length,
76775
+ });
76776
+ const depositMap = new Map();
76777
+ for (const event of depositEvents) {
76778
+ const existingEvent = depositMap.get(event.precommitment);
76779
+ // If no existing event, or current event is older (earlier block), use current event
76780
+ if (!existingEvent || event.blockNumber < existingEvent.blockNumber) {
76781
+ depositMap.set(event.precommitment, event);
76782
+ }
76783
+ }
76784
+ return depositMap;
76785
+ }
76786
+ catch (error) {
76787
+ throw EventError.depositEventError(pool.chainId, pool.scope, error);
76788
+ }
76789
+ }
76790
+ /**
76791
+ * Fetches withdrawal events for a given pool and returns a map of spent nullifiers to their events for efficient lookup
76792
+ *
76793
+ * @param pool - The pool to fetch withdrawal events for
76794
+ *
76795
+ * @returns A map of spent nullifiers to their events
76796
+ */
76797
+ async getWithdrawalEvents(pool) {
76798
+ try {
76799
+ const withdrawalEvents = await this.dataService.getWithdrawals(pool);
76800
+ const withdrawalMap = new Map();
76801
+ for (const event of withdrawalEvents) {
76802
+ withdrawalMap.set(event.spentNullifier, event);
76803
+ }
76804
+ return withdrawalMap;
76805
+ }
76806
+ catch (error) {
76807
+ throw EventError.withdrawalEventError(pool.chainId, pool.scope, error);
76808
+ }
76809
+ }
76810
+ /**
76811
+ * Fetches ragequit events for a given pool and returns a map of ragequit labels to their events for efficient lookup
76812
+ *
76813
+ * @param pool - The pool to fetch ragequit events for
76814
+ *
76815
+ * @returns A map of ragequit labels to their events
76816
+ */
76817
+ async getRagequitEvents(pool) {
76818
+ try {
76819
+ const ragequitEvents = await this.dataService.getRagequits(pool);
76820
+ const ragequitMap = new Map();
76821
+ for (const event of ragequitEvents) {
76822
+ ragequitMap.set(event.label, event);
76823
+ }
76824
+ return ragequitMap;
76825
+ }
76826
+ catch (error) {
76827
+ throw EventError.ragequitEventError(pool.chainId, pool.scope, error);
76828
+ }
76829
+ }
76830
+ /**
76831
+ * Fetches events for a given set of pools
76832
+ *
76833
+ * @param pools - The pools to fetch events for
76834
+ *
76835
+ * @returns A map of pool scopes to their events
76836
+ */
76837
+ async getEvents(pools) {
76838
+ const events = new Map();
76839
+ const poolEventResults = await Promise.allSettled(pools.map(async (pool) => {
76840
+ this.logger.info(`Fetching events for pool`, {
76841
+ poolAddress: pool.address,
76842
+ poolChainId: pool.chainId,
76843
+ poolDeploymentBlock: pool.deploymentBlock,
76844
+ });
76845
+ const [depositEvents, withdrawalEvents, ragequitEvents] = await Promise.all([
76846
+ this.getDepositEvents(pool),
76847
+ this.getWithdrawalEvents(pool),
76848
+ this.getRagequitEvents(pool),
76849
+ ]);
76850
+ return {
76851
+ scope: pool.scope,
76852
+ depositEvents,
76853
+ withdrawalEvents,
76854
+ ragequitEvents,
76855
+ };
76856
+ }));
76857
+ for (const result of poolEventResults) {
76858
+ if (result.status === "fulfilled") {
76859
+ const { scope, depositEvents, withdrawalEvents, ragequitEvents } = result.value;
76860
+ events.set(scope, {
76861
+ depositEvents,
76862
+ withdrawalEvents,
76863
+ ragequitEvents,
76864
+ });
76865
+ }
76866
+ else {
76867
+ events.set(result.reason.details?.scope, {
76868
+ reason: result.reason.message,
76869
+ scope: result.reason.details?.scope,
76870
+ });
76871
+ }
76872
+ }
76873
+ return events;
76874
+ }
76875
+ /**
76876
+ * Processes deposit events for a given scope and adds them to the account
76877
+ * Deterministically generate deposit secrets and check if they match on-chain deposits
76878
+ *
76879
+ * @param scope - The scope of the pool
76880
+ * @param depositEvents - The map of deposit events
76881
+ *
76882
+ */
76883
+ _processDepositEvents(scope, depositEvents) {
76884
+ const MAX_CONSECUTIVE_MISSES = 10; // Large enough to avoid tx failures
76885
+ const foundIndices = new Set();
76886
+ let consecutiveMisses = 0;
76887
+ for (let index = BigInt(0);; index++) {
76888
+ // Generate nullifier, secret, and precommitment for this index
76889
+ const { nullifier, secret, precommitment } = this.createDepositSecrets(scope, index);
76890
+ // Look for a deposit with this precommitment
76891
+ const event = depositEvents.get(precommitment);
76892
+ if (!event) {
76893
+ consecutiveMisses++;
76894
+ if (consecutiveMisses >= MAX_CONSECUTIVE_MISSES) {
76895
+ break;
76896
+ }
76897
+ continue;
76898
+ }
76899
+ // Can reset counter in case if user had any tx failures for
76900
+ // newer deposits
76901
+ consecutiveMisses = 0;
76902
+ foundIndices.add(index);
76903
+ // Create a new pool account for this deposit
76904
+ this.addPoolAccount(scope, event.value, nullifier, secret, event.label, event.blockNumber, event.transactionHash);
76905
+ this.logger.debug(`Found deposit at index ${index} for scope ${scope}`);
76906
+ }
76907
+ }
76908
+ /**
76909
+ * Processes withdrawal events for a given scope and adds them to the account
76910
+ *
76911
+ * @param scope - The scope of the pool
76912
+ * @param withdrawalEvents - The map of withdrawal events
76913
+ *
76914
+ * @remarks
76915
+ * This method performs the following steps for each pool:
76916
+ * 1. Identifies the earliest deposit block for each scope
76917
+ * 2. For each account, reconstructs the withdrawal history by:
76918
+ * - Generating nullifiers sequentially
76919
+ * - Matching them against on-chain events
76920
+ * - Adding matched withdrawals to the account state
76921
+ *
76922
+ * @throws {DataError} If event fetching fails
76923
+ * @private
76924
+ *
76925
+ */
76926
+ _processWithdrawalEvents(scope, withdrawalEvents) {
76927
+ const accounts = this.account.poolAccounts.get(scope);
76928
+ // Skip if no accounts for this scope
76929
+ if (!accounts || accounts.length === 0) {
76930
+ this.logger.info(`No accounts found for pool with this scope`, {
76931
+ scope,
76932
+ });
76933
+ return;
76934
+ }
76935
+ // Process each account in parallel for better performance
76936
+ for (const account of accounts) {
76937
+ let currentCommitment = account.deposit;
76938
+ let index = BigInt(0);
76939
+ // Continue processing withdrawals until no more are found secuentially
76940
+ while (true) {
76941
+ // Generate nullifier for this withdrawal
76942
+ const nullifierHash = hashingExports.poseidon([currentCommitment.nullifier]);
76943
+ // Look for a withdrawal event with this nullifier
76944
+ const withdrawal = withdrawalEvents.get(nullifierHash);
76945
+ if (!withdrawal) {
76946
+ break;
76947
+ }
76948
+ // Generate secret for this withdrawal
76949
+ const nullifier = this._genWithdrawalNullifier(account.label, index);
76950
+ const secret = this._genWithdrawalSecret(account.label, index);
76951
+ // Add the withdrawal commitment to the account
76952
+ const newCommitment = this.addWithdrawalCommitment(currentCommitment, currentCommitment.value - withdrawal.withdrawn, nullifier, secret, withdrawal.blockNumber, withdrawal.transactionHash);
76953
+ // Update current commitment to the newly created one
76954
+ currentCommitment = newCommitment;
76955
+ // Increment index for next potential withdrawal
76956
+ index++;
76957
+ }
76958
+ }
76959
+ }
76960
+ /**
76961
+ * Processes ragequit events for a given scope and adds them to the account
76962
+ *
76963
+ * @param scope - The scope of the pool
76964
+ * @param ragequitEvents - The map of ragequit events
76965
+ *
76966
+ * @remarks
76967
+ * This method performs the following steps for each pool:
76968
+ * 1. Adds ragequit events to accounts if found
76969
+ *
76970
+ * @throws {DataError} If event fetching fails
76971
+ * @private
76972
+ *
76973
+ */
76974
+ _processRagequitEvents(scope, ragequitEvents) {
76975
+ const accounts = this.account.poolAccounts.get(scope);
76976
+ if (!accounts || accounts.length === 0) {
76977
+ this.logger.info(`No accounts found for pool with this scope`, {
76978
+ scope,
76979
+ });
76980
+ return;
76981
+ }
76982
+ for (const account of accounts) {
76983
+ const ragequit = ragequitEvents.get(account.label);
76984
+ if (ragequit) {
76985
+ this.addRagequitToAccount(account.label, ragequit);
76986
+ }
76987
+ }
76988
+ }
76989
+ /**
76990
+ * Initializes an AccountService instance with events for a given set of pools
76991
+ *
76992
+ * @param dataService - The data service to use for fetching events
76993
+ * @param source - The source to use for initializing the account. Either a mnemonic or an existing account service instance
76994
+ * @param pools - The pools to fetch events for
76995
+ *
76996
+ * @remarks
76997
+ * This method performs the following steps for each pool:
76998
+ * 1. Fetches deposit, withdrawal, and ragequit events for each pool
76999
+ * 2. Processes deposit events and creates pool accounts
77000
+ * 3. Processes withdrawal events and adds commitments to pool accounts
77001
+ * 4. Processes ragequit events and adds ragequit to pool accounts
77002
+ *
77003
+ * @returns The initialized AccountService instance and array of errors if any pool events fetching fails
77004
+ *
77005
+ * if any pool events fetching fails, the account will be initialized without the events for that pool
77006
+ * user can then call to this method again with the same account and missing pools to fetch the missing events
77007
+ *
77008
+ * @throws {AccountError} If account state reconstruction fails or if duplicate pools are found
77009
+ */
77010
+ static async initializeWithEvents(dataService, source, pools) {
77011
+ // Log the start of the history retrieval process
77012
+ const logger = new Logger({ prefix: "Account" });
77013
+ logger.info(`Fetching events for pools`, { poolLength: pools.length });
77014
+ // verify that pools don't contain duplicates based on scope
77015
+ const uniqueScopes = new Set();
77016
+ for (const pool of pools) {
77017
+ if (uniqueScopes.has(pool.scope)) {
77018
+ throw AccountError.duplicatePools(pool.scope);
77019
+ }
77020
+ uniqueScopes.add(pool.scope);
77021
+ }
77022
+ const errors = [];
77023
+ const account = new AccountService(dataService, "mnemonic" in source
77024
+ ? { mnemonic: source.mnemonic }
77025
+ : { account: source.service.account });
77026
+ const events = await account.getEvents(pools);
77027
+ for (const [scope, result] of events.entries()) {
77028
+ if ("reason" in result) {
77029
+ errors.push(result);
77030
+ }
77031
+ else {
77032
+ // Process deposit events an create pool accounts
77033
+ account._processDepositEvents(scope, result.depositEvents);
77034
+ // Process withdrawal events and add commitments to pool accounts
77035
+ account._processWithdrawalEvents(scope, result.withdrawalEvents);
77036
+ // Process ragequit events and add ragequit to pool accounts
77037
+ account._processRagequitEvents(scope, result.ragequitEvents);
77038
+ }
77039
+ }
77040
+ return { account, errors };
77041
+ }
77042
+ /**
77043
+ * @deprecated Use `initializeWithEvents` for instantiating an account with history reconstruction
76680
77044
  * Retrieves the history of deposits and withdrawals for the given pools.
76681
77045
  *
76682
77046
  * @param pools - Array of pool configurations to sync history for
@@ -76811,7 +77175,9 @@ class AccountService {
76811
77175
  // Continue processing withdrawals until no more are found
76812
77176
  while (true) {
76813
77177
  // Generate nullifier for this withdrawal
76814
- const nullifierHash = hashingExports.poseidon([currentCommitment.nullifier]);
77178
+ const nullifierHash = hashingExports.poseidon([
77179
+ currentCommitment.nullifier,
77180
+ ]);
76815
77181
  // Look for a withdrawal event with this nullifier
76816
77182
  const withdrawal = withdrawalMap.get(nullifierHash);
76817
77183
  if (!withdrawal) {
@@ -76836,22 +77202,6 @@ class AccountService {
76836
77202
  }
76837
77203
  }
76838
77204
 
76839
- class DataError extends SDKError {
76840
- constructor(message, code = ErrorCode.NETWORK_ERROR, details) {
76841
- super(message, code, details);
76842
- this.name = "DataError";
76843
- }
76844
- static invalidLog(type, reason) {
76845
- return new DataError(`Invalid ${type} log: ${reason}`, ErrorCode.INVALID_INPUT);
76846
- }
76847
- static chainNotConfigured(chainId) {
76848
- return new DataError(`No configuration found for chain ID ${chainId}`, ErrorCode.INVALID_INPUT);
76849
- }
76850
- static networkError(chainId, error) {
76851
- return new DataError(`Network error on chain ${chainId}: ${error.message}`, ErrorCode.NETWORK_ERROR, { originalError: error });
76852
- }
76853
- }
76854
-
76855
77205
  // Event signatures from the contract
76856
77206
  const DEPOSIT_EVENT = parseAbiItem('event Deposited(address indexed _depositor, uint256 _commitment, uint256 _label, uint256 _value, uint256 _merkleRoot)');
76857
77207
  const WITHDRAWAL_EVENT = parseAbiItem('event Withdrawn(address indexed _processooor, uint256 _value, uint256 _spentNullifier, uint256 _newCommitment)');
@@ -76880,12 +77230,11 @@ class DataService {
76880
77230
  this.logger = new Logger({ prefix: "Data" });
76881
77231
  try {
76882
77232
  for (const config of chainConfigs) {
76883
- if (!config.rpcUrl || !config.apiKey) {
76884
- throw new Error(`Missing RPC URL or API key for chain ${config.chainId}`);
77233
+ if (!config.rpcUrl) {
77234
+ throw new Error(`Missing RPC URL for chain ${config.chainId}`);
76885
77235
  }
76886
77236
  const client = createPublicClient({
76887
77237
  transport: http(config.rpcUrl),
76888
- key: config.apiKey,
76889
77238
  });
76890
77239
  this.clients.set(config.chainId, client);
76891
77240
  }
@@ -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-CIvuCHHq.js';
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-xpjDqElC.js';
2
2
  import 'viem/accounts';
3
3
  import 'buffer';
4
4
  import 'http';