@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.
- package/README.md +4 -4
- package/dist/esm/{fetchArtifacts.esm-CXLPgzhJ.js → fetchArtifacts.esm-D0mKkSYH.js} +2 -2
- package/dist/esm/{fetchArtifacts.esm-CXLPgzhJ.js.map → fetchArtifacts.esm-D0mKkSYH.js.map} +1 -1
- package/dist/esm/{fetchArtifacts.node-B3pPMuWd.js → fetchArtifacts.node-D2RwI1ei.js} +2 -2
- package/dist/esm/{fetchArtifacts.node-B3pPMuWd.js.map → fetchArtifacts.node-D2RwI1ei.js.map} +1 -1
- package/dist/esm/{index-C_oO7cOn.js → index-CysEkDfm.js} +416 -67
- package/dist/esm/index-CysEkDfm.js.map +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/index.d.mts +185 -46
- package/dist/node/{fetchArtifacts.esm-DoJiimN3.js → fetchArtifacts.esm-GuREmUVE.js} +2 -2
- package/dist/node/{fetchArtifacts.esm-DoJiimN3.js.map → fetchArtifacts.esm-GuREmUVE.js.map} +1 -1
- package/dist/node/{fetchArtifacts.node-B4Ey9DOV.js → fetchArtifacts.node-80qrImLq.js} +2 -2
- package/dist/node/{fetchArtifacts.node-B4Ey9DOV.js.map → fetchArtifacts.node-80qrImLq.js.map} +1 -1
- package/dist/node/{index-CwopFzOC.js → index-bIu80opN.js} +416 -67
- package/dist/node/index-bIu80opN.js.map +1 -0
- package/dist/node/index.mjs +1 -1
- package/dist/types/core/account.service.d.ts +116 -4
- package/dist/types/core/contracts.service.d.ts +9 -1
- package/dist/types/core/sdk.d.ts +2 -1
- package/dist/types/core/withdrawal.service.d.ts +2 -2
- package/dist/types/errors/account.error.d.ts +2 -0
- package/dist/types/errors/base.error.d.ts +1 -0
- package/dist/types/errors/events.error.d.ts +9 -0
- package/dist/types/{fetchArtifacts.esm-CxFhH8oR.js → fetchArtifacts.esm-Ok2Ropox.js} +1 -1
- package/dist/types/{fetchArtifacts.node-Cqk_Z-mS.js → fetchArtifacts.node-DpNFJc75.js} +1 -1
- package/dist/types/{index-CIvuCHHq.js → index-xpjDqElC.js} +415 -66
- package/dist/types/index.js +1 -1
- package/dist/types/interfaces/contracts.interface.d.ts +7 -0
- package/dist/types/types/events.d.ts +11 -1
- package/package.json +2 -2
- package/src/core/account.service.ts +479 -61
- package/src/core/contracts.service.ts +35 -0
- package/src/core/data.service.ts +2 -3
- package/src/core/sdk.ts +2 -1
- package/src/core/withdrawal.service.ts +25 -9
- package/src/crypto.ts +11 -2
- package/src/errors/account.error.ts +14 -0
- package/src/errors/base.error.ts +5 -0
- package/src/errors/events.error.ts +38 -0
- package/src/interfaces/contracts.interface.ts +8 -0
- package/src/types/events.ts +15 -1
- package/dist/esm/index-C_oO7cOn.js.map +0 -1
- 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
|
|
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.
|
|
50342
|
+
* @version 1.4.1
|
|
50367
50343
|
* @file Essential zero-knowledge utility library for JavaScript developers.
|
|
50368
|
-
* @copyright Ethereum Foundation
|
|
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.
|
|
50394
|
+
* @version 1.4.1
|
|
50419
50395
|
* @file Essential zero-knowledge utility library for JavaScript developers.
|
|
50420
|
-
* @copyright Ethereum Foundation
|
|
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.
|
|
50463
|
+
* @version 2.2.4
|
|
50488
50464
|
* @file Lean Incremental Merkle tree implementation in TypeScript.
|
|
50489
|
-
* @copyright Ethereum Foundation
|
|
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].
|
|
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 {
|
|
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
|
-
|
|
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-
|
|
51073
|
+
return import('./fetchArtifacts.esm-Ok2Ropox.js');
|
|
51086
51074
|
}
|
|
51087
51075
|
else {
|
|
51088
|
-
return import('./fetchArtifacts.node-
|
|
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
|
|
76222
|
-
existingValue
|
|
76223
|
-
existingNullifier
|
|
76224
|
-
existingSecret
|
|
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
|
|
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,
|
|
76442
|
+
constructor(dataService, config) {
|
|
76369
76443
|
this.dataService = dataService;
|
|
76370
76444
|
this.logger = new Logger({ prefix: "Account" });
|
|
76371
|
-
|
|
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
|
|
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([
|
|
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
|
|
76884
|
-
throw new Error(`Missing RPC URL
|
|
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
|
}
|
package/dist/types/index.js
CHANGED
|
@@ -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-
|
|
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';
|