@obolnetwork/obol-sdk 2.12.0 → 2.12.1

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 (39) hide show
  1. package/dist/browser/src/index.js +315 -136
  2. package/dist/browser/src/index.js.map +1 -1
  3. package/dist/cjs/src/blsUtils.js +19 -2
  4. package/dist/cjs/src/blsUtils.js.map +1 -1
  5. package/dist/cjs/src/index.js +321 -136
  6. package/dist/cjs/src/index.js.map +1 -1
  7. package/dist/cjs/src/verification/clusterLockValidationWorker.js +14696 -0
  8. package/dist/cjs/src/verification/clusterLockValidationWorker.js.map +1 -0
  9. package/dist/cjs/src/verification/lockWorker.js +13 -1
  10. package/dist/cjs/src/verification/lockWorker.js.map +1 -1
  11. package/dist/cjs/src/verification/parallelPool.js +228 -35
  12. package/dist/cjs/src/verification/parallelPool.js.map +1 -1
  13. package/dist/esm/src/blsUtils.js +7 -3
  14. package/dist/esm/src/chunk-5ASVONSJ.js +10242 -0
  15. package/dist/esm/src/chunk-5ASVONSJ.js.map +1 -0
  16. package/dist/esm/src/{chunk-267HIPEB.js → chunk-LOSYOJC3.js} +16 -1
  17. package/dist/esm/src/{chunk-267HIPEB.js.map → chunk-LOSYOJC3.js.map} +1 -1
  18. package/dist/esm/src/chunk-RYTIXFRX.js +382 -0
  19. package/dist/esm/src/chunk-RYTIXFRX.js.map +1 -0
  20. package/dist/esm/src/index.js +213 -10340
  21. package/dist/esm/src/index.js.map +1 -1
  22. package/dist/esm/src/verification/clusterLockValidationWorker.js +18 -0
  23. package/dist/esm/src/verification/clusterLockValidationWorker.js.map +1 -0
  24. package/dist/esm/src/verification/lockWorker.js +7 -2
  25. package/dist/esm/src/verification/lockWorker.js.map +1 -1
  26. package/dist/esm/src/verification/parallelPool.js +8 -2
  27. package/dist/types/src/blsUtils.d.ts +3 -0
  28. package/dist/types/src/errors.d.ts +13 -0
  29. package/dist/types/src/index.d.ts +1 -1
  30. package/dist/types/src/services.d.ts +4 -1
  31. package/dist/types/src/types.d.ts +6 -0
  32. package/dist/types/src/verification/clusterLockValidationWorker.d.ts +1 -0
  33. package/dist/types/src/verification/common.d.ts +17 -7
  34. package/dist/types/src/verification/lockWorker.d.ts +7 -2
  35. package/dist/types/src/verification/parallelPool.d.ts +9 -0
  36. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  37. package/package.json +1 -1
  38. package/dist/esm/src/chunk-OYZHSNKR.js +0 -186
  39. package/dist/esm/src/chunk-OYZHSNKR.js.map +0 -1
@@ -114,6 +114,7 @@ __export(index_exports, {
114
114
  CONFIG_VERSION: () => CONFIG_VERSION,
115
115
  CONFLICT_ERROR_MSG: () => CONFLICT_ERROR_MSG,
116
116
  Client: () => Client,
117
+ ClusterLockValidationTimeoutError: () => ClusterLockValidationTimeoutError,
117
118
  ConflictError: () => ConflictError,
118
119
  CreatorConfigHashSigningTypes: () => CreatorConfigHashSigningTypes,
119
120
  CreatorTypedMessage: () => CreatorTypedMessage,
@@ -154,8 +155,12 @@ __export(index_exports, {
154
155
  TermsAndConditionsSigningTypes: () => TermsAndConditionsSigningTypes,
155
156
  UnsupportedChainError: () => UnsupportedChainError,
156
157
  blsVerify: () => blsVerify,
158
+ builderBlsCheck: () => builderBlsCheck,
159
+ builderDomainForFork: () => builderDomainForFork,
157
160
  clusterConfigOrDefinitionHash: () => clusterConfigOrDefinitionHash,
158
161
  clusterLockHash: () => clusterLockHash,
162
+ depositBlsCheck: () => depositBlsCheck,
163
+ depositDomainForFork: () => depositDomainForFork,
159
164
  hasUniqueDistributedKeys: () => hasUniqueDistributedKeys,
160
165
  isChainSupportedForSplitters: () => isChainSupportedForSplitters,
161
166
  isValidClusterLock: () => isValidClusterLock,
@@ -165,6 +170,7 @@ __export(index_exports, {
165
170
  signingRoot: () => signingRoot,
166
171
  validateAddressSignature: () => validateAddressSignature,
167
172
  validateClusterLock: () => validateClusterLock,
173
+ validateDepositDataStructure: () => validateDepositDataStructure,
168
174
  validateEOASignature: () => validateEOASignature,
169
175
  validateSmartContractSignature: () => validateSmartContractSignature,
170
176
  verifyBuilderRegistration: () => verifyBuilderRegistration,
@@ -177,7 +183,7 @@ var import_uuid = require("uuid");
177
183
  // package.json
178
184
  var package_default = {
179
185
  name: "@obolnetwork/obol-sdk",
180
- version: "2.12.0",
186
+ version: "2.12.1",
181
187
  description: "A package for creating Distributed Validators using the Obol API.",
182
188
  bugs: {
183
189
  url: "https://github.com/obolnetwork/obol-sdk/issues"
@@ -661,6 +667,19 @@ var UnsupportedChainError = class _UnsupportedChainError extends Error {
661
667
  Object.setPrototypeOf(this, _UnsupportedChainError.prototype);
662
668
  }
663
669
  };
670
+ var ClusterLockValidationTimeoutError = class _ClusterLockValidationTimeoutError extends Error {
671
+ /**
672
+ * @param timeoutMs - Same value as SDK whole-lock validation worker timeout.
673
+ */
674
+ constructor(timeoutMs) {
675
+ super(
676
+ `Cluster lock validation exceeded worker time limit (${timeoutMs} ms). Retry later; this does not imply invalid lock data.`
677
+ );
678
+ this.timeoutMs = timeoutMs;
679
+ this.name = "ClusterLockValidationTimeoutError";
680
+ Object.setPrototypeOf(this, _ClusterLockValidationTimeoutError.prototype);
681
+ }
682
+ };
664
683
 
665
684
  // src/verification/common.ts
666
685
  var import_ssz7 = require("@chainsafe/ssz");
@@ -780,6 +799,9 @@ var signingRootType = new import_ssz.ContainerType({
780
799
  // src/verification/v1.6.0.ts
781
800
  var import_ssz3 = require("@chainsafe/ssz");
782
801
 
802
+ // src/verification/parallelPool.ts
803
+ var import_ssz2 = require("@chainsafe/ssz");
804
+
783
805
  // node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
784
806
  function isBytes(a) {
785
807
  return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
@@ -4934,6 +4956,12 @@ function blsVerify(pubkey, message2, signature) {
4934
4956
  return false;
4935
4957
  }
4936
4958
  }
4959
+ function blsAggregatePublicKeys(pubkeys) {
4960
+ if (pubkeys.length === 0) {
4961
+ throw new Error("cannot aggregate empty pubkey set");
4962
+ }
4963
+ return ls.aggregatePublicKeys(pubkeys).toBytes();
4964
+ }
4937
4965
  function blsVerifyAggregate(pubkeys, message2, signature) {
4938
4966
  try {
4939
4967
  return ls.verify(
@@ -4945,6 +4973,13 @@ function blsVerifyAggregate(pubkeys, message2, signature) {
4945
4973
  return false;
4946
4974
  }
4947
4975
  }
4976
+ function blsVerifyWithAggregatedPubkey(aggregatedPubkey, message2, signature) {
4977
+ try {
4978
+ return ls.verify(signature, ls.hash(message2, ETH2_DST), aggregatedPubkey);
4979
+ } catch (e) {
4980
+ return false;
4981
+ }
4982
+ }
4948
4983
  function blsVerifyMultiple(pubkeys, messages, signature) {
4949
4984
  try {
4950
4985
  if (pubkeys.length !== messages.length) return false;
@@ -5010,16 +5045,23 @@ function blsVerifyExtraShares(pubshares, threshold, distributedPubkey) {
5010
5045
  }
5011
5046
 
5012
5047
  // src/verification/parallelPool.ts
5013
- var import_ssz2 = require("@chainsafe/ssz");
5014
5048
  var MIN_PARALLEL_VALIDATORS = 50;
5015
5049
  var MIN_PARALLEL_BATCH_PAIRS = 100;
5016
5050
  var MAX_WORKERS = 8;
5017
5051
  var MIN_VALIDATORS_PER_WORKER = 25;
5018
5052
  var MIN_PAIRS_PER_WORKER = 50;
5053
+ var MIN_PARALLEL_AGGREGATE_KEYS = 400;
5054
+ var MIN_KEYS_PER_WORKER_AGG = 100;
5055
+ var MIN_VALIDATORS_FOR_VALIDATION_WORKER = 50;
5056
+ var VALIDATION_WORKER_TIMEOUT_MS = 12e4;
5019
5057
  var WORKER_TIMEOUT_MS = 6e4;
5058
+ var MAX_CONCURRENT_WORKERS_CAP = 8;
5059
+ function maxConcurrentWorkers(numWorkers) {
5060
+ return Math.min(numWorkers, MAX_CONCURRENT_WORKERS_CAP);
5061
+ }
5020
5062
  var workerThreadsCache;
5021
5063
  var osCache;
5022
- var workerPathCache;
5064
+ var workerPathByFile = /* @__PURE__ */ new Map();
5023
5065
  function loadWorkerThreads() {
5024
5066
  if (workerThreadsCache !== void 0) return workerThreadsCache;
5025
5067
  try {
@@ -5038,18 +5080,47 @@ function loadOs() {
5038
5080
  }
5039
5081
  return osCache;
5040
5082
  }
5041
- function getWorkerPath() {
5042
- if (workerPathCache !== void 0) return workerPathCache;
5043
- if (typeof __dirname === "undefined") return workerPathCache = null;
5083
+ function getWorkerPath(filename) {
5084
+ const cached = workerPathByFile.get(filename);
5085
+ if (cached !== void 0) return cached;
5086
+ if (typeof __dirname === "undefined") {
5087
+ workerPathByFile.set(filename, null);
5088
+ return null;
5089
+ }
5044
5090
  const path = require("path");
5045
- const candidate = path.join(__dirname, "lockWorker.js");
5091
+ const fs = require("fs");
5092
+ const candidates = [
5093
+ path.join(__dirname, filename),
5094
+ path.join(__dirname, "verification", filename)
5095
+ ];
5046
5096
  try {
5047
- const fs = require("fs");
5048
- if (!fs.existsSync(candidate)) return workerPathCache = null;
5097
+ for (const candidate of candidates) {
5098
+ if (fs.existsSync(candidate)) {
5099
+ workerPathByFile.set(filename, candidate);
5100
+ return candidate;
5101
+ }
5102
+ }
5049
5103
  } catch (e) {
5050
- return workerPathCache = null;
5051
5104
  }
5052
- return workerPathCache = candidate;
5105
+ workerPathByFile.set(filename, null);
5106
+ return null;
5107
+ }
5108
+ function mapWithConcurrency(items, concurrency, fn) {
5109
+ return __async(this, null, function* () {
5110
+ const results = new Array(items.length);
5111
+ let next = 0;
5112
+ const runners = Array.from(
5113
+ { length: Math.min(concurrency, items.length) },
5114
+ () => __async(null, null, function* () {
5115
+ while (next < items.length) {
5116
+ const i = next++;
5117
+ results[i] = yield fn(items[i], i);
5118
+ }
5119
+ })
5120
+ );
5121
+ yield Promise.all(runners);
5122
+ return results;
5123
+ });
5053
5124
  }
5054
5125
  function chunkArrays(arr, n) {
5055
5126
  const size = Math.ceil(arr.length / n);
@@ -5078,6 +5149,33 @@ function verifySharesSync(shares, distributedKeys, threshold) {
5078
5149
  }
5079
5150
  return true;
5080
5151
  }
5152
+ function runWorkerAggregatePubkeys(wt, workerFile, data) {
5153
+ return __async(this, null, function* () {
5154
+ return yield new Promise((resolve) => {
5155
+ let settled = false;
5156
+ const worker = new wt.Worker(workerFile, { workerData: data });
5157
+ const finish = (result) => {
5158
+ if (settled) return;
5159
+ settled = true;
5160
+ clearTimeout(timer);
5161
+ worker.terminate();
5162
+ resolve(result);
5163
+ };
5164
+ const timer = setTimeout(() => {
5165
+ finish(null);
5166
+ }, WORKER_TIMEOUT_MS);
5167
+ worker.once("message", (msg) => {
5168
+ finish(msg instanceof Uint8Array ? msg : null);
5169
+ });
5170
+ worker.once("error", () => {
5171
+ finish(null);
5172
+ });
5173
+ worker.once("exit", (code2) => {
5174
+ if (code2 !== 0) finish(null);
5175
+ });
5176
+ });
5177
+ });
5178
+ }
5081
5179
  function runWorker(wt, workerFile, data) {
5082
5180
  return __async(this, null, function* () {
5083
5181
  return yield new Promise((resolve) => {
@@ -5108,8 +5206,8 @@ function runWorker(wt, workerFile, data) {
5108
5206
  function poolSize(itemCount, minPerWorker) {
5109
5207
  const wt = loadWorkerThreads();
5110
5208
  const os = loadOs();
5111
- const workerFile = getWorkerPath();
5112
- const numCpus = os ? os.cpus().length : 1;
5209
+ const workerFile = getWorkerPath("lockWorker.js");
5210
+ const numCpus = os ? Math.max(1, os.cpus().length) : 1;
5113
5211
  const numWorkers = Math.min(
5114
5212
  MAX_WORKERS,
5115
5213
  Math.max(1, Math.floor(itemCount / minPerWorker)),
@@ -5117,6 +5215,18 @@ function poolSize(itemCount, minPerWorker) {
5117
5215
  );
5118
5216
  return { numWorkers, wt, workerFile };
5119
5217
  }
5218
+ function runWorkerChunks(wt, workerFile, chunks) {
5219
+ return __async(this, null, function* () {
5220
+ const results = yield mapWithConcurrency(
5221
+ chunks,
5222
+ maxConcurrentWorkers(chunks.length),
5223
+ (data) => __async(null, null, function* () {
5224
+ return yield runWorker(wt, workerFile, data);
5225
+ })
5226
+ );
5227
+ return results.every(Boolean);
5228
+ });
5229
+ }
5120
5230
  function verifySharesBinding(shares, distributedKeys, threshold) {
5121
5231
  return __async(this, null, function* () {
5122
5232
  if (shares.length !== distributedKeys.length) return false;
@@ -5130,19 +5240,26 @@ function verifySharesBinding(shares, distributedKeys, threshold) {
5130
5240
  }
5131
5241
  const shareChunks = chunkArrays(shares, numWorkers);
5132
5242
  const keyChunks = chunkArrays(distributedKeys, numWorkers);
5133
- const results = yield Promise.all(
5134
- shareChunks.map(
5135
- (chunk, i) => __async(null, null, function* () {
5136
- return yield runWorker(wt, workerFile, {
5137
- mode: "shareBinding",
5138
- shares: chunk,
5139
- distributedKeys: keyChunks[i],
5140
- threshold
5141
- });
5142
- })
5143
- )
5243
+ return yield runWorkerChunks(
5244
+ wt,
5245
+ workerFile,
5246
+ shareChunks.map((chunk, i) => ({
5247
+ mode: "shareBinding",
5248
+ shares: chunk,
5249
+ distributedKeys: keyChunks[i],
5250
+ threshold
5251
+ }))
5252
+ );
5253
+ });
5254
+ }
5255
+ function verifyBlsChecksParallel(checks) {
5256
+ return __async(this, null, function* () {
5257
+ if (checks.length === 0) return true;
5258
+ return yield verifyBatchParallel(
5259
+ checks.map((c) => c.pubkey),
5260
+ checks.map((c) => c.message),
5261
+ checks.map((c) => c.signature)
5144
5262
  );
5145
- return results.every(Boolean);
5146
5263
  });
5147
5264
  }
5148
5265
  function verifyBatchParallel(pubkeys, messages, signatures) {
@@ -5165,19 +5282,84 @@ function verifyBatchParallel(pubkeys, messages, signatures) {
5165
5282
  const pkChunks = chunkArrays(pubkeys, numWorkers);
5166
5283
  const msgChunks = chunkArrays(messages, numWorkers);
5167
5284
  const sigChunks = chunkArrays(signatures, numWorkers);
5168
- const results = yield Promise.all(
5169
- pkChunks.map(
5170
- (pks, i) => __async(null, null, function* () {
5171
- return yield runWorker(wt, workerFile, {
5172
- mode: "verifyBatch",
5173
- pubkeys: pks,
5174
- messages: msgChunks[i],
5175
- aggregateSignature: blsAggregateSignatures(sigChunks[i])
5176
- });
5177
- })
5178
- )
5285
+ return yield runWorkerChunks(
5286
+ wt,
5287
+ workerFile,
5288
+ pkChunks.map((pks, i) => ({
5289
+ mode: "verifyBatch",
5290
+ pubkeys: pks,
5291
+ messages: msgChunks[i],
5292
+ signatures: sigChunks[i]
5293
+ }))
5179
5294
  );
5180
- return results.every(Boolean);
5295
+ });
5296
+ }
5297
+ function verifyAggregateParallel(pubkeys, message2, signature) {
5298
+ return __async(this, null, function* () {
5299
+ if (pubkeys.length === 0) return false;
5300
+ const { numWorkers, wt, workerFile } = poolSize(
5301
+ pubkeys.length,
5302
+ MIN_KEYS_PER_WORKER_AGG
5303
+ );
5304
+ if (wt === null || workerFile === null || pubkeys.length < MIN_PARALLEL_AGGREGATE_KEYS || numWorkers < 2) {
5305
+ return blsVerifyAggregate(pubkeys, message2, signature);
5306
+ }
5307
+ const pkChunks = chunkArrays(pubkeys, numWorkers);
5308
+ const partials = yield mapWithConcurrency(
5309
+ pkChunks,
5310
+ maxConcurrentWorkers(pkChunks.length),
5311
+ (chunk) => __async(null, null, function* () {
5312
+ return yield runWorkerAggregatePubkeys(wt, workerFile, {
5313
+ mode: "aggregatePubkeys",
5314
+ pubkeys: chunk
5315
+ });
5316
+ })
5317
+ );
5318
+ if (partials.some((p) => p === null)) return false;
5319
+ const aggregated = blsAggregatePublicKeys(partials);
5320
+ return blsVerifyWithAggregatedPubkey(aggregated, message2, signature);
5321
+ });
5322
+ }
5323
+ function validateClusterLockInWorker(lock, safeRpcUrl) {
5324
+ return __async(this, null, function* () {
5325
+ var _a6, _b2;
5326
+ const n = (_b2 = (_a6 = lock.distributed_validators) == null ? void 0 : _a6.length) != null ? _b2 : 0;
5327
+ if (n < MIN_VALIDATORS_FOR_VALIDATION_WORKER) return null;
5328
+ const wt = loadWorkerThreads();
5329
+ const workerFile = getWorkerPath("clusterLockValidationWorker.js");
5330
+ if (wt === null || workerFile === null) return null;
5331
+ return yield new Promise((resolve, reject) => {
5332
+ let settled = false;
5333
+ const worker = new wt.Worker(workerFile, {
5334
+ workerData: { lock, safeRpcUrl }
5335
+ });
5336
+ let timer;
5337
+ const finish = (result) => {
5338
+ if (settled) return;
5339
+ settled = true;
5340
+ clearTimeout(timer);
5341
+ worker.terminate();
5342
+ resolve(result);
5343
+ };
5344
+ timer = setTimeout(() => {
5345
+ if (settled) return;
5346
+ settled = true;
5347
+ clearTimeout(timer);
5348
+ void worker.terminate();
5349
+ reject(
5350
+ new ClusterLockValidationTimeoutError(VALIDATION_WORKER_TIMEOUT_MS)
5351
+ );
5352
+ }, VALIDATION_WORKER_TIMEOUT_MS);
5353
+ worker.once("message", (msg) => {
5354
+ finish(msg === true);
5355
+ });
5356
+ worker.once("error", () => {
5357
+ finish(null);
5358
+ });
5359
+ worker.once("exit", (code2) => {
5360
+ if (code2 !== 0) finish(null);
5361
+ });
5362
+ });
5181
5363
  });
5182
5364
  }
5183
5365
 
@@ -5282,7 +5464,6 @@ var hashClusterLockV1X6 = (cluster) => {
5282
5464
  return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
5283
5465
  };
5284
5466
  var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5285
- var _a6;
5286
5467
  const validators = clusterLock.distributed_validators;
5287
5468
  const operatorCount = clusterLock.cluster_definition.operators.length;
5288
5469
  const threshold = clusterLock.cluster_definition.threshold;
@@ -5301,9 +5482,7 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5301
5482
  return false;
5302
5483
  }
5303
5484
  const pubShares = [];
5304
- const pubKeys = [];
5305
- const builderRegistrationAndDepositDataMessages = [];
5306
- const blsSignatures = [];
5485
+ const blsChecks = [];
5307
5486
  for (let i = 0; i < validators.length; i++) {
5308
5487
  const validator = validators[i];
5309
5488
  const validatorPublicShares = validator.public_shares;
@@ -5321,33 +5500,23 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5321
5500
  for (const share of validatorPublicSharesBytes) {
5322
5501
  pubShares.push(share);
5323
5502
  }
5324
- const { isValidDepositData, depositDataMsg } = verifyDepositData(
5503
+ const depositCheck = depositBlsCheck(
5325
5504
  distributedPublicKey,
5326
5505
  validator.deposit_data,
5327
5506
  clusterLock.cluster_definition.validators[i].withdrawal_address,
5328
5507
  clusterLock.cluster_definition.fork_version
5329
5508
  );
5330
- if (!isValidDepositData) {
5331
- return false;
5332
- }
5333
- pubKeys.push((0, import_ssz3.fromHexString)(validator.distributed_public_key));
5334
- builderRegistrationAndDepositDataMessages.push(depositDataMsg);
5335
- blsSignatures.push(
5336
- (0, import_ssz3.fromHexString)((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5337
- );
5509
+ if (!depositCheck) return false;
5510
+ blsChecks.push(depositCheck);
5338
5511
  }
5339
- if (!(yield verifyBatchParallel(
5340
- pubKeys,
5341
- builderRegistrationAndDepositDataMessages,
5342
- blsSignatures
5343
- ))) {
5512
+ if (!(yield verifyBlsChecksParallel(blsChecks))) {
5344
5513
  return false;
5345
5514
  }
5346
- if (!blsVerifyAggregate(
5515
+ if (!(yield verifyAggregateParallel(
5347
5516
  pubShares,
5348
5517
  (0, import_ssz3.fromHexString)(clusterLock.lock_hash),
5349
5518
  (0, import_ssz3.fromHexString)(clusterLock.signature_aggregate)
5350
- )) {
5519
+ ))) {
5351
5520
  return false;
5352
5521
  }
5353
5522
  return true;
@@ -5473,7 +5642,6 @@ var hashClusterLockV1X7 = (cluster) => {
5473
5642
  return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
5474
5643
  };
5475
5644
  var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5476
- var _a6, _b2;
5477
5645
  const validators = clusterLock.distributed_validators;
5478
5646
  const operatorCount = clusterLock.cluster_definition.operators.length;
5479
5647
  const threshold = clusterLock.cluster_definition.threshold;
@@ -5492,9 +5660,7 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5492
5660
  return false;
5493
5661
  }
5494
5662
  const pubShares = [];
5495
- const pubKeys = [];
5496
- const builderRegistrationAndDepositDataMessages = [];
5497
- const blsSignatures = [];
5663
+ const blsChecks = [];
5498
5664
  for (let i = 0; i < validators.length; i++) {
5499
5665
  const validator = validators[i];
5500
5666
  const validatorPublicShares = validator.public_shares;
@@ -5512,49 +5678,33 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5512
5678
  for (const share of validatorPublicSharesBytes) {
5513
5679
  pubShares.push(share);
5514
5680
  }
5515
- const { isValidDepositData, depositDataMsg } = verifyDepositData(
5681
+ const depositCheck = depositBlsCheck(
5516
5682
  distributedPublicKey,
5517
5683
  validator.deposit_data,
5518
5684
  clusterLock.cluster_definition.validators[i].withdrawal_address,
5519
5685
  clusterLock.cluster_definition.fork_version
5520
5686
  );
5521
- if (!isValidDepositData) {
5522
- return false;
5523
- }
5524
- pubKeys.push((0, import_ssz4.fromHexString)(distributedPublicKey));
5525
- builderRegistrationAndDepositDataMessages.push(depositDataMsg);
5526
- blsSignatures.push(
5527
- (0, import_ssz4.fromHexString)((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5528
- );
5529
- const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
5687
+ if (!depositCheck) return false;
5688
+ blsChecks.push(depositCheck);
5689
+ const builderCheck = builderBlsCheck(
5530
5690
  validator,
5531
5691
  clusterLock.cluster_definition.validators[i].fee_recipient_address,
5532
5692
  clusterLock.cluster_definition.fork_version
5533
5693
  );
5534
- if (!isValidBuilderRegistration) {
5535
- return false;
5536
- }
5537
- pubKeys.push((0, import_ssz4.fromHexString)(distributedPublicKey));
5538
- builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
5539
- blsSignatures.push(
5540
- (0, import_ssz4.fromHexString)((_b2 = validator.builder_registration) == null ? void 0 : _b2.signature)
5541
- );
5694
+ if (!builderCheck) return false;
5695
+ blsChecks.push(builderCheck);
5542
5696
  }
5543
- if (!(yield verifyBatchParallel(
5544
- pubKeys,
5545
- builderRegistrationAndDepositDataMessages,
5546
- blsSignatures
5547
- ))) {
5697
+ if (!(yield verifyBlsChecksParallel(blsChecks))) {
5548
5698
  return false;
5549
5699
  }
5550
5700
  if (!verifyNodeSignatures(clusterLock)) {
5551
5701
  return false;
5552
5702
  }
5553
- if (!blsVerifyAggregate(
5703
+ if (!(yield verifyAggregateParallel(
5554
5704
  pubShares,
5555
5705
  (0, import_ssz4.fromHexString)(clusterLock.lock_hash),
5556
5706
  (0, import_ssz4.fromHexString)(clusterLock.signature_aggregate)
5557
- )) {
5707
+ ))) {
5558
5708
  return false;
5559
5709
  }
5560
5710
  return true;
@@ -14107,7 +14257,6 @@ var hashClusterLockV1X8 = (cluster) => {
14107
14257
  return "0x" + Buffer.from(lockType.hashTreeRoot(val).buffer).toString("hex");
14108
14258
  };
14109
14259
  var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
14110
- var _a6;
14111
14260
  const validators = clusterLock.distributed_validators;
14112
14261
  const operatorCount = clusterLock.cluster_definition.operators.length;
14113
14262
  const threshold = clusterLock.cluster_definition.threshold;
@@ -14126,9 +14275,10 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
14126
14275
  return false;
14127
14276
  }
14128
14277
  const pubShares = [];
14129
- const pubKeys = [];
14130
- const builderRegistrationAndDepositDataMessages = [];
14131
- const blsSignatures = [];
14278
+ const blsChecks = [];
14279
+ const forkVersion = clusterLock.cluster_definition.fork_version;
14280
+ const depositDomain = depositDomainForFork(forkVersion);
14281
+ const builderDomain = builderDomainForFork(forkVersion);
14132
14282
  for (let i = 0; i < validators.length; i++) {
14133
14283
  const validator = validators[i];
14134
14284
  const validatorPublicShares = validator.public_shares;
@@ -14155,51 +14305,38 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
14155
14305
  return false;
14156
14306
  }
14157
14307
  }
14158
- for (const element of validator.partial_deposit_data) {
14159
- const depositData = element;
14160
- const { isValidDepositData, depositDataMsg } = verifyDepositData(
14308
+ for (const depositData of validator.partial_deposit_data) {
14309
+ const check = depositBlsCheck(
14161
14310
  distributedPublicKey,
14162
14311
  depositData,
14163
14312
  clusterLock.cluster_definition.validators[i].withdrawal_address,
14164
- clusterLock.cluster_definition.fork_version,
14165
- clusterLock.cluster_definition.compounding
14313
+ forkVersion,
14314
+ clusterLock.cluster_definition.compounding,
14315
+ depositDomain
14166
14316
  );
14167
- if (!isValidDepositData) {
14168
- return false;
14169
- }
14170
- pubKeys.push((0, import_ssz5.fromHexString)(distributedPublicKey));
14171
- builderRegistrationAndDepositDataMessages.push(depositDataMsg);
14172
- blsSignatures.push((0, import_ssz5.fromHexString)(depositData == null ? void 0 : depositData.signature));
14317
+ if (!check) return false;
14318
+ blsChecks.push(check);
14173
14319
  }
14174
- const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
14320
+ const builderCheck = builderBlsCheck(
14175
14321
  validator,
14176
14322
  clusterLock.cluster_definition.validators[i].fee_recipient_address,
14177
- clusterLock.cluster_definition.fork_version
14178
- );
14179
- if (!isValidBuilderRegistration) {
14180
- return false;
14181
- }
14182
- pubKeys.push((0, import_ssz5.fromHexString)(distributedPublicKey));
14183
- builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
14184
- blsSignatures.push(
14185
- (0, import_ssz5.fromHexString)((_a6 = validator.builder_registration) == null ? void 0 : _a6.signature)
14323
+ forkVersion,
14324
+ builderDomain
14186
14325
  );
14326
+ if (!builderCheck) return false;
14327
+ blsChecks.push(builderCheck);
14187
14328
  }
14188
- if (!(yield verifyBatchParallel(
14189
- pubKeys,
14190
- builderRegistrationAndDepositDataMessages,
14191
- blsSignatures
14192
- ))) {
14329
+ if (!(yield verifyBlsChecksParallel(blsChecks))) {
14193
14330
  return false;
14194
14331
  }
14195
14332
  if (!verifyNodeSignatures(clusterLock)) {
14196
14333
  return false;
14197
14334
  }
14198
- if (!blsVerifyAggregate(
14335
+ if (!(yield verifyAggregateParallel(
14199
14336
  pubShares,
14200
14337
  (0, import_ssz5.fromHexString)(clusterLock.lock_hash),
14201
14338
  (0, import_ssz5.fromHexString)(clusterLock.signature_aggregate)
14202
- )) {
14339
+ ))) {
14203
14340
  return false;
14204
14341
  }
14205
14342
  return true;
@@ -14601,37 +14738,62 @@ var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = (0, im
14601
14738
  domain.set(forkDataRoot.subarray(0, 28), 4);
14602
14739
  return domain;
14603
14740
  };
14604
- var verifyDepositData = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding) => {
14605
- const depositDomain = computeDomain(
14606
- (0, import_ssz7.fromHexString)(DOMAIN_DEPOSIT),
14607
- forkVersion
14608
- );
14741
+ var depositDomainForFork = (forkVersion) => computeDomain((0, import_ssz7.fromHexString)(DOMAIN_DEPOSIT), forkVersion);
14742
+ var builderDomainForFork = (forkVersion) => computeDomain((0, import_ssz7.fromHexString)(DOMAIN_APPLICATION_BUILDER), forkVersion);
14743
+ var validateDepositDataStructure = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding, precomputedDepositDomain) => {
14744
+ const depositDomain = precomputedDepositDomain != null ? precomputedDepositDomain : computeDomain((0, import_ssz7.fromHexString)(DOMAIN_DEPOSIT), forkVersion);
14609
14745
  const withdrawalPrefix = compounding ? "0x02" : "0x01";
14610
14746
  const expectedWithdrawalCredentials = withdrawalPrefix + "0".repeat(22) + withdrawalAddress.toLowerCase().slice(2);
14611
14747
  if (expectedWithdrawalCredentials !== depositData.withdrawal_credentials) {
14612
- return { isValidDepositData: false, depositDataMsg: new Uint8Array(0) };
14748
+ return { valid: false, message: new Uint8Array(0) };
14613
14749
  }
14614
14750
  if (distributedPublicKey !== depositData.pubkey) {
14615
- return { isValidDepositData: false, depositDataMsg: new Uint8Array(0) };
14751
+ return { valid: false, message: new Uint8Array(0) };
14616
14752
  }
14617
14753
  const depositMessageBuffer = computeDepositMsgRoot(depositData);
14618
- const depositDataRoot = signingRoot(depositDomain, depositMessageBuffer);
14754
+ const message2 = signingRoot(depositDomain, depositMessageBuffer);
14619
14755
  if (!depositData.signature) {
14620
- return { isValidDepositData: false, depositDataMsg: depositDataRoot };
14756
+ return { valid: false, message: message2 };
14757
+ }
14758
+ return { valid: true, message: message2 };
14759
+ };
14760
+ var depositBlsCheck = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding, precomputedDepositDomain) => {
14761
+ const { valid, message: message2 } = validateDepositDataStructure(
14762
+ distributedPublicKey,
14763
+ depositData,
14764
+ withdrawalAddress,
14765
+ forkVersion,
14766
+ compounding,
14767
+ precomputedDepositDomain
14768
+ );
14769
+ if (!valid || !depositData.signature || !depositData.pubkey) return null;
14770
+ return {
14771
+ pubkey: (0, import_ssz7.fromHexString)(depositData.pubkey),
14772
+ message: message2,
14773
+ signature: (0, import_ssz7.fromHexString)(depositData.signature)
14774
+ };
14775
+ };
14776
+ var verifyDepositData = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding) => {
14777
+ const { valid, message: message2 } = validateDepositDataStructure(
14778
+ distributedPublicKey,
14779
+ depositData,
14780
+ withdrawalAddress,
14781
+ forkVersion,
14782
+ compounding
14783
+ );
14784
+ if (!valid || !depositData.signature || !depositData.pubkey) {
14785
+ return { isValidDepositData: false, depositDataMsg: message2 };
14621
14786
  }
14622
14787
  const isValidDepositData = blsVerify(
14623
14788
  (0, import_ssz7.fromHexString)(depositData.pubkey),
14624
- depositDataRoot,
14789
+ message2,
14625
14790
  (0, import_ssz7.fromHexString)(depositData.signature)
14626
14791
  );
14627
- return { isValidDepositData, depositDataMsg: depositDataRoot };
14792
+ return { isValidDepositData, depositDataMsg: message2 };
14628
14793
  };
14629
- var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) => {
14794
+ var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion, precomputedBuilderDomain) => {
14630
14795
  var _a6;
14631
- const builderDomain = computeDomain(
14632
- (0, import_ssz7.fromHexString)(DOMAIN_APPLICATION_BUILDER),
14633
- forkVersion
14634
- );
14796
+ const builderDomain = precomputedBuilderDomain != null ? precomputedBuilderDomain : computeDomain((0, import_ssz7.fromHexString)(DOMAIN_APPLICATION_BUILDER), forkVersion);
14635
14797
  if (validator.distributed_public_key !== ((_a6 = validator.builder_registration) == null ? void 0 : _a6.message.pubkey)) {
14636
14798
  return {
14637
14799
  isValidBuilderRegistration: false,
@@ -14656,6 +14818,22 @@ var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) =>
14656
14818
  builderRegistrationMsg: builderRegistrationMessage
14657
14819
  };
14658
14820
  };
14821
+ var builderBlsCheck = (validator, feeRecipientAddress, forkVersion, precomputedBuilderDomain) => {
14822
+ var _a6;
14823
+ const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
14824
+ validator,
14825
+ feeRecipientAddress,
14826
+ forkVersion,
14827
+ precomputedBuilderDomain
14828
+ );
14829
+ const sig = (_a6 = validator.builder_registration) == null ? void 0 : _a6.signature;
14830
+ if (!isValidBuilderRegistration || !sig) return null;
14831
+ return {
14832
+ pubkey: (0, import_ssz7.fromHexString)(validator.distributed_public_key),
14833
+ message: builderRegistrationMsg,
14834
+ signature: (0, import_ssz7.fromHexString)(sig)
14835
+ };
14836
+ };
14659
14837
  var verifyNodeSignatures = (clusterLock) => {
14660
14838
  const ec2 = new import_elliptic.default.ec("secp256k1");
14661
14839
  const nodeSignatures = clusterLock.node_signatures;
@@ -19663,8 +19841,9 @@ var EOA = class {
19663
19841
  // src/services.ts
19664
19842
  var validateClusterLock = (lock, safeRpcUrl) => __async(null, null, function* () {
19665
19843
  try {
19666
- const isLockValid = yield isValidClusterLock(lock, safeRpcUrl);
19667
- return isLockValid;
19844
+ const inWorker = yield validateClusterLockInWorker(lock, safeRpcUrl);
19845
+ if (inWorker !== null) return inWorker;
19846
+ return yield isValidClusterLock(lock, safeRpcUrl);
19668
19847
  } catch (err) {
19669
19848
  throw err;
19670
19849
  }
@@ -20264,6 +20443,7 @@ var Client = class extends Base {
20264
20443
  CONFIG_VERSION,
20265
20444
  CONFLICT_ERROR_MSG,
20266
20445
  Client,
20446
+ ClusterLockValidationTimeoutError,
20267
20447
  ConflictError,
20268
20448
  CreatorConfigHashSigningTypes,
20269
20449
  CreatorTypedMessage,
@@ -20304,8 +20484,12 @@ var Client = class extends Base {
20304
20484
  TermsAndConditionsSigningTypes,
20305
20485
  UnsupportedChainError,
20306
20486
  blsVerify,
20487
+ builderBlsCheck,
20488
+ builderDomainForFork,
20307
20489
  clusterConfigOrDefinitionHash,
20308
20490
  clusterLockHash,
20491
+ depositBlsCheck,
20492
+ depositDomainForFork,
20309
20493
  hasUniqueDistributedKeys,
20310
20494
  isChainSupportedForSplitters,
20311
20495
  isValidClusterLock,
@@ -20315,6 +20499,7 @@ var Client = class extends Base {
20315
20499
  signingRoot,
20316
20500
  validateAddressSignature,
20317
20501
  validateClusterLock,
20502
+ validateDepositDataStructure,
20318
20503
  validateEOASignature,
20319
20504
  validateSmartContractSignature,
20320
20505
  verifyBuilderRegistration,