@obolnetwork/obol-sdk 2.11.12 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/browser/src/index.js +446 -134
  2. package/dist/browser/src/index.js.map +1 -1
  3. package/dist/cjs/src/blsUtils.js +3826 -0
  4. package/dist/cjs/src/blsUtils.js.map +1 -0
  5. package/dist/cjs/src/index.js +530 -222
  6. package/dist/cjs/src/index.js.map +1 -1
  7. package/dist/cjs/src/verification/lockWorker.js +3828 -0
  8. package/dist/cjs/src/verification/lockWorker.js.map +1 -0
  9. package/dist/cjs/src/verification/parallelPool.js +3992 -0
  10. package/dist/cjs/src/verification/parallelPool.js.map +1 -0
  11. package/dist/esm/src/blsUtils.js +17 -0
  12. package/dist/esm/src/blsUtils.js.map +1 -0
  13. package/dist/esm/src/chunk-267HIPEB.js +4355 -0
  14. package/dist/esm/src/chunk-267HIPEB.js.map +1 -0
  15. package/dist/esm/src/chunk-OYZHSNKR.js +186 -0
  16. package/dist/esm/src/chunk-OYZHSNKR.js.map +1 -0
  17. package/dist/esm/src/index.js +835 -5000
  18. package/dist/esm/src/index.js.map +1 -1
  19. package/dist/esm/src/verification/lockWorker.js +50 -0
  20. package/dist/esm/src/verification/lockWorker.js.map +1 -0
  21. package/dist/esm/src/verification/parallelPool.js +10 -0
  22. package/dist/esm/src/verification/parallelPool.js.map +1 -0
  23. package/dist/types/src/blsUtils.d.ts +2 -0
  24. package/dist/types/src/index.d.ts +1 -0
  25. package/dist/types/src/verification/common.d.ts +9 -0
  26. package/dist/types/src/verification/lockWorker.d.ts +13 -0
  27. package/dist/types/src/verification/parallelPool.d.ts +2 -0
  28. package/dist/types/test/verification/parallelPool.spec.d.ts +1 -0
  29. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  30. package/package.json +1 -1
@@ -21,6 +21,12 @@ var __spreadValues = (a, b) => {
21
21
  return a;
22
22
  };
23
23
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
25
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
26
+ }) : x)(function(x) {
27
+ if (typeof require !== "undefined") return require.apply(this, arguments);
28
+ throw Error('Dynamic require of "' + x + '" is not supported');
29
+ });
24
30
  var __export = (target, all) => {
25
31
  for (var name2 in all)
26
32
  __defProp(target, name2, { get: all[name2], enumerable: true });
@@ -92,7 +98,7 @@ import { v4 as uuidv4 } from "uuid";
92
98
  // package.json
93
99
  var package_default = {
94
100
  name: "@obolnetwork/obol-sdk",
95
- version: "2.11.12",
101
+ version: "2.12.0",
96
102
  description: "A package for creating Distributed Validators using the Obol API.",
97
103
  bugs: {
98
104
  url: "https://github.com/obolnetwork/obol-sdk/issues"
@@ -578,7 +584,7 @@ var UnsupportedChainError = class _UnsupportedChainError extends Error {
578
584
  };
579
585
 
580
586
  // src/verification/common.ts
581
- import { fromHexString as fromHexString5 } from "@chainsafe/ssz";
587
+ import { fromHexString as fromHexString6 } from "@chainsafe/ssz";
582
588
  import elliptic from "elliptic";
583
589
  import * as semver from "semver";
584
590
 
@@ -705,7 +711,7 @@ import {
705
711
  ByteVectorType as ByteVectorType2,
706
712
  ContainerType as ContainerType2,
707
713
  ListCompositeType,
708
- fromHexString
714
+ fromHexString as fromHexString2
709
715
  } from "@chainsafe/ssz";
710
716
 
711
717
  // node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
@@ -5159,6 +5165,226 @@ function blsVerifyMultiple(pubkeys, messages, signature) {
5159
5165
  function blsAggregateSignatures(signatures) {
5160
5166
  return ls.Signature.toBytes(ls.aggregateSignatures(signatures));
5161
5167
  }
5168
+ function lagrangeCoeffAtZero(shareIndex, indices) {
5169
+ const { Fr } = bls12_381.fields;
5170
+ let num = BigInt(1);
5171
+ let den = BigInt(1);
5172
+ for (const j of indices) {
5173
+ if (j === shareIndex) continue;
5174
+ num = Fr.mul(num, Fr.neg(j));
5175
+ den = Fr.mul(den, Fr.sub(shareIndex, j));
5176
+ }
5177
+ return Fr.mul(num, Fr.inv(den));
5178
+ }
5179
+ function blsRecoverWithIndices(shares, indices) {
5180
+ try {
5181
+ let recovered = bls12_381.G1.Point.ZERO;
5182
+ for (let i = 0; i < shares.length; i++) {
5183
+ const point = bls12_381.G1.Point.fromBytes(shares[i]);
5184
+ const coeff = lagrangeCoeffAtZero(indices[i], indices);
5185
+ recovered = recovered.add(point.multiply(coeff));
5186
+ }
5187
+ return recovered.toBytes();
5188
+ } catch (e) {
5189
+ return null;
5190
+ }
5191
+ }
5192
+ function blsRecoverDistributedPubkeyFromShares(pubshares, threshold) {
5193
+ if (threshold <= 0 || pubshares.length < threshold) return null;
5194
+ const selected = pubshares.slice(0, threshold);
5195
+ const indices = selected.map((_, i) => BigInt(i + 1));
5196
+ return blsRecoverWithIndices(selected, indices);
5197
+ }
5198
+ function blsVerifyExtraShares(pubshares, threshold, distributedPubkey) {
5199
+ if (threshold <= 0 || pubshares.length < threshold) return false;
5200
+ try {
5201
+ const baseShares = pubshares.slice(0, threshold - 1);
5202
+ const baseIndices = baseShares.map((_, i) => BigInt(i + 1));
5203
+ for (let i = threshold; i < pubshares.length; i++) {
5204
+ const shares = [...baseShares, pubshares[i]];
5205
+ const indices = [...baseIndices, BigInt(i + 1)];
5206
+ const recovered = blsRecoverWithIndices(shares, indices);
5207
+ if (!recovered || recovered.length !== distributedPubkey.length || !recovered.every((b, j) => b === distributedPubkey[j])) {
5208
+ return false;
5209
+ }
5210
+ }
5211
+ return true;
5212
+ } catch (e) {
5213
+ return false;
5214
+ }
5215
+ }
5216
+
5217
+ // src/verification/parallelPool.ts
5218
+ import { fromHexString } from "@chainsafe/ssz";
5219
+ var MIN_PARALLEL_VALIDATORS = 50;
5220
+ var MIN_PARALLEL_BATCH_PAIRS = 100;
5221
+ var MAX_WORKERS = 8;
5222
+ var MIN_VALIDATORS_PER_WORKER = 25;
5223
+ var MIN_PAIRS_PER_WORKER = 50;
5224
+ var WORKER_TIMEOUT_MS = 6e4;
5225
+ var workerThreadsCache;
5226
+ var osCache;
5227
+ var workerPathCache;
5228
+ function loadWorkerThreads() {
5229
+ if (workerThreadsCache !== void 0) return workerThreadsCache;
5230
+ try {
5231
+ workerThreadsCache = __require("worker_threads");
5232
+ } catch (e) {
5233
+ workerThreadsCache = null;
5234
+ }
5235
+ return workerThreadsCache;
5236
+ }
5237
+ function loadOs() {
5238
+ if (osCache !== void 0) return osCache;
5239
+ try {
5240
+ osCache = __require("os");
5241
+ } catch (e) {
5242
+ osCache = null;
5243
+ }
5244
+ return osCache;
5245
+ }
5246
+ function getWorkerPath() {
5247
+ if (workerPathCache !== void 0) return workerPathCache;
5248
+ if (typeof __dirname === "undefined") return workerPathCache = null;
5249
+ const path = __require("path");
5250
+ const candidate = path.join(__dirname, "lockWorker.js");
5251
+ try {
5252
+ const fs = __require("fs");
5253
+ if (!fs.existsSync(candidate)) return workerPathCache = null;
5254
+ } catch (e) {
5255
+ return workerPathCache = null;
5256
+ }
5257
+ return workerPathCache = candidate;
5258
+ }
5259
+ function chunkArrays(arr, n) {
5260
+ const size = Math.ceil(arr.length / n);
5261
+ const out = [];
5262
+ for (let i = 0; i < arr.length; i += size) {
5263
+ out.push(arr.slice(i, i + size));
5264
+ }
5265
+ return out;
5266
+ }
5267
+ function verifySharesSync(shares, distributedKeys, threshold) {
5268
+ for (let i = 0; i < shares.length; i++) {
5269
+ const sharesBytes = shares[i].map((s) => fromHexString(s));
5270
+ const dkBytes = fromHexString(distributedKeys[i]);
5271
+ const recovered = blsRecoverDistributedPubkeyFromShares(
5272
+ sharesBytes,
5273
+ threshold
5274
+ );
5275
+ if (!recovered) return false;
5276
+ if (recovered.length !== dkBytes.length) return false;
5277
+ for (let j = 0; j < recovered.length; j++) {
5278
+ if (recovered[j] !== dkBytes[j]) return false;
5279
+ }
5280
+ if (!blsVerifyExtraShares(sharesBytes, threshold, dkBytes)) {
5281
+ return false;
5282
+ }
5283
+ }
5284
+ return true;
5285
+ }
5286
+ function runWorker(wt, workerFile, data) {
5287
+ return __async(this, null, function* () {
5288
+ return yield new Promise((resolve) => {
5289
+ let settled = false;
5290
+ const worker = new wt.Worker(workerFile, { workerData: data });
5291
+ const finish = (result) => {
5292
+ if (settled) return;
5293
+ settled = true;
5294
+ clearTimeout(timer);
5295
+ worker.terminate();
5296
+ resolve(result);
5297
+ };
5298
+ const timer = setTimeout(() => {
5299
+ finish(false);
5300
+ }, WORKER_TIMEOUT_MS);
5301
+ worker.once("message", (msg) => {
5302
+ finish(msg === true);
5303
+ });
5304
+ worker.once("error", () => {
5305
+ finish(false);
5306
+ });
5307
+ worker.once("exit", (code2) => {
5308
+ if (code2 !== 0) finish(false);
5309
+ });
5310
+ });
5311
+ });
5312
+ }
5313
+ function poolSize(itemCount, minPerWorker) {
5314
+ const wt = loadWorkerThreads();
5315
+ const os = loadOs();
5316
+ const workerFile = getWorkerPath();
5317
+ const numCpus = os ? os.cpus().length : 1;
5318
+ const numWorkers = Math.min(
5319
+ MAX_WORKERS,
5320
+ Math.max(1, Math.floor(itemCount / minPerWorker)),
5321
+ numCpus
5322
+ );
5323
+ return { numWorkers, wt, workerFile };
5324
+ }
5325
+ function verifySharesBinding(shares, distributedKeys, threshold) {
5326
+ return __async(this, null, function* () {
5327
+ if (shares.length !== distributedKeys.length) return false;
5328
+ if (shares.length === 0) return true;
5329
+ const { numWorkers, wt, workerFile } = poolSize(
5330
+ shares.length,
5331
+ MIN_VALIDATORS_PER_WORKER
5332
+ );
5333
+ if (wt === null || workerFile === null || shares.length < MIN_PARALLEL_VALIDATORS || numWorkers < 2) {
5334
+ return verifySharesSync(shares, distributedKeys, threshold);
5335
+ }
5336
+ const shareChunks = chunkArrays(shares, numWorkers);
5337
+ const keyChunks = chunkArrays(distributedKeys, numWorkers);
5338
+ const results = yield Promise.all(
5339
+ shareChunks.map(
5340
+ (chunk, i) => __async(null, null, function* () {
5341
+ return yield runWorker(wt, workerFile, {
5342
+ mode: "shareBinding",
5343
+ shares: chunk,
5344
+ distributedKeys: keyChunks[i],
5345
+ threshold
5346
+ });
5347
+ })
5348
+ )
5349
+ );
5350
+ return results.every(Boolean);
5351
+ });
5352
+ }
5353
+ function verifyBatchParallel(pubkeys, messages, signatures) {
5354
+ return __async(this, null, function* () {
5355
+ if (pubkeys.length !== messages.length || pubkeys.length !== signatures.length) {
5356
+ return false;
5357
+ }
5358
+ if (pubkeys.length === 0) return true;
5359
+ const { numWorkers, wt, workerFile } = poolSize(
5360
+ pubkeys.length,
5361
+ MIN_PAIRS_PER_WORKER
5362
+ );
5363
+ if (wt === null || workerFile === null || pubkeys.length < MIN_PARALLEL_BATCH_PAIRS || numWorkers < 2) {
5364
+ return blsVerifyMultiple(
5365
+ pubkeys,
5366
+ messages,
5367
+ blsAggregateSignatures(signatures)
5368
+ );
5369
+ }
5370
+ const pkChunks = chunkArrays(pubkeys, numWorkers);
5371
+ const msgChunks = chunkArrays(messages, numWorkers);
5372
+ const sigChunks = chunkArrays(signatures, numWorkers);
5373
+ const results = yield Promise.all(
5374
+ pkChunks.map(
5375
+ (pks, i) => __async(null, null, function* () {
5376
+ return yield runWorker(wt, workerFile, {
5377
+ mode: "verifyBatch",
5378
+ pubkeys: pks,
5379
+ messages: msgChunks[i],
5380
+ aggregateSignature: blsAggregateSignatures(sigChunks[i])
5381
+ });
5382
+ })
5383
+ )
5384
+ );
5385
+ return results.every(Boolean);
5386
+ });
5387
+ }
5162
5388
 
5163
5389
  // src/verification/v1.6.0.ts
5164
5390
  var clusterDefinitionContainerTypeV1X6 = (configOnly) => {
@@ -5192,29 +5418,29 @@ var hashClusterDefinitionV1X6 = (cluster, configOnly) => {
5192
5418
  val.num_validators = cluster.num_validators;
5193
5419
  val.threshold = cluster.threshold;
5194
5420
  val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
5195
- val.fork_version = fromHexString(cluster.fork_version);
5421
+ val.fork_version = fromHexString2(cluster.fork_version);
5196
5422
  val.operators = cluster.operators.map((operator) => {
5197
- return configOnly ? { address: fromHexString(operator.address) } : {
5198
- address: fromHexString(operator.address),
5423
+ return configOnly ? { address: fromHexString2(operator.address) } : {
5424
+ address: fromHexString2(operator.address),
5199
5425
  enr: strToUint8Array(operator.enr),
5200
- config_signature: fromHexString(operator.config_signature),
5201
- enr_signature: fromHexString(operator.enr_signature)
5426
+ config_signature: fromHexString2(operator.config_signature),
5427
+ enr_signature: fromHexString2(operator.enr_signature)
5202
5428
  };
5203
5429
  });
5204
- val.creator = configOnly ? { address: fromHexString(cluster.creator.address) } : {
5205
- address: fromHexString(cluster.creator.address),
5206
- config_signature: fromHexString(
5430
+ val.creator = configOnly ? { address: fromHexString2(cluster.creator.address) } : {
5431
+ address: fromHexString2(cluster.creator.address),
5432
+ config_signature: fromHexString2(
5207
5433
  cluster.creator.config_signature
5208
5434
  )
5209
5435
  };
5210
5436
  val.validators = cluster.validators.map((validator) => {
5211
5437
  return {
5212
- fee_recipient_address: fromHexString(validator.fee_recipient_address),
5213
- withdrawal_address: fromHexString(validator.withdrawal_address)
5438
+ fee_recipient_address: fromHexString2(validator.fee_recipient_address),
5439
+ withdrawal_address: fromHexString2(validator.withdrawal_address)
5214
5440
  };
5215
5441
  });
5216
5442
  if (!configOnly) {
5217
- val.config_hash = fromHexString(cluster.config_hash);
5443
+ val.config_hash = fromHexString2(cluster.config_hash);
5218
5444
  }
5219
5445
  return val;
5220
5446
  };
@@ -5243,18 +5469,18 @@ var hashClusterLockV1X6 = (cluster) => {
5243
5469
  (dValidator) => {
5244
5470
  var _a6, _b2, _c, _d;
5245
5471
  return {
5246
- distributed_public_key: fromHexString(
5472
+ distributed_public_key: fromHexString2(
5247
5473
  dValidator.distributed_public_key
5248
5474
  ),
5249
5475
  public_shares: dValidator.public_shares.map(
5250
- (publicShare) => fromHexString(publicShare)
5476
+ (publicShare) => fromHexString2(publicShare)
5251
5477
  ),
5252
- pubkey: fromHexString((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
5253
- withdrawal_credentials: fromHexString(
5478
+ pubkey: fromHexString2((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
5479
+ withdrawal_credentials: fromHexString2(
5254
5480
  (_b2 = dValidator.deposit_data) == null ? void 0 : _b2.withdrawal_credentials
5255
5481
  ),
5256
5482
  amount: parseInt((_c = dValidator.deposit_data) == null ? void 0 : _c.amount),
5257
- signature: fromHexString((_d = dValidator.deposit_data) == null ? void 0 : _d.signature)
5483
+ signature: fromHexString2((_d = dValidator.deposit_data) == null ? void 0 : _d.signature)
5258
5484
  };
5259
5485
  }
5260
5486
  );
@@ -5263,6 +5489,22 @@ var hashClusterLockV1X6 = (cluster) => {
5263
5489
  var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5264
5490
  var _a6;
5265
5491
  const validators = clusterLock.distributed_validators;
5492
+ const operatorCount = clusterLock.cluster_definition.operators.length;
5493
+ const threshold = clusterLock.cluster_definition.threshold;
5494
+ for (const validator of validators) {
5495
+ if (validator.public_shares.length !== operatorCount) {
5496
+ return false;
5497
+ }
5498
+ const uniqueShareCount = new Set(validator.public_shares).size;
5499
+ if (uniqueShareCount !== validator.public_shares.length) {
5500
+ return false;
5501
+ }
5502
+ }
5503
+ const allShares = validators.map((v) => v.public_shares);
5504
+ const allDKs = validators.map((v) => v.distributed_public_key);
5505
+ if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
5506
+ return false;
5507
+ }
5266
5508
  const pubShares = [];
5267
5509
  const pubKeys = [];
5268
5510
  const builderRegistrationAndDepositDataMessages = [];
@@ -5271,8 +5513,18 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5271
5513
  const validator = validators[i];
5272
5514
  const validatorPublicShares = validator.public_shares;
5273
5515
  const distributedPublicKey = validator.distributed_public_key;
5274
- for (const element of validatorPublicShares) {
5275
- pubShares.push(fromHexString(element));
5516
+ if (validatorPublicShares.length !== operatorCount) {
5517
+ return false;
5518
+ }
5519
+ const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
5520
+ if (new Set(normalizedShares).size !== normalizedShares.length) {
5521
+ return false;
5522
+ }
5523
+ const validatorPublicSharesBytes = validatorPublicShares.map(
5524
+ (share) => fromHexString2(share)
5525
+ );
5526
+ for (const share of validatorPublicSharesBytes) {
5527
+ pubShares.push(share);
5276
5528
  }
5277
5529
  const { isValidDepositData, depositDataMsg } = verifyDepositData(
5278
5530
  distributedPublicKey,
@@ -5283,24 +5535,23 @@ var verifyDVV1X6 = (clusterLock) => __async(null, null, function* () {
5283
5535
  if (!isValidDepositData) {
5284
5536
  return false;
5285
5537
  }
5286
- pubKeys.push(fromHexString(validator.distributed_public_key));
5538
+ pubKeys.push(fromHexString2(validator.distributed_public_key));
5287
5539
  builderRegistrationAndDepositDataMessages.push(depositDataMsg);
5288
5540
  blsSignatures.push(
5289
- fromHexString((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5541
+ fromHexString2((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5290
5542
  );
5291
5543
  }
5292
- const aggregateBLSSignature = blsAggregateSignatures(blsSignatures);
5293
- if (!blsVerifyMultiple(
5544
+ if (!(yield verifyBatchParallel(
5294
5545
  pubKeys,
5295
5546
  builderRegistrationAndDepositDataMessages,
5296
- aggregateBLSSignature
5297
- )) {
5547
+ blsSignatures
5548
+ ))) {
5298
5549
  return false;
5299
5550
  }
5300
5551
  if (!blsVerifyAggregate(
5301
5552
  pubShares,
5302
- fromHexString(clusterLock.lock_hash),
5303
- fromHexString(clusterLock.signature_aggregate)
5553
+ fromHexString2(clusterLock.lock_hash),
5554
+ fromHexString2(clusterLock.signature_aggregate)
5304
5555
  )) {
5305
5556
  return false;
5306
5557
  }
@@ -5316,7 +5567,7 @@ import {
5316
5567
  ByteVectorType as ByteVectorType3,
5317
5568
  ContainerType as ContainerType3,
5318
5569
  ListCompositeType as ListCompositeType2,
5319
- fromHexString as fromHexString2
5570
+ fromHexString as fromHexString3
5320
5571
  } from "@chainsafe/ssz";
5321
5572
  var clusterDefinitionContainerTypeV1X7 = (configOnly) => {
5322
5573
  let returnedContainerType = {
@@ -5349,29 +5600,29 @@ var hashClusterDefinitionV1X7 = (cluster, configOnly) => {
5349
5600
  val.num_validators = cluster.num_validators;
5350
5601
  val.threshold = cluster.threshold;
5351
5602
  val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
5352
- val.fork_version = fromHexString2(cluster.fork_version);
5603
+ val.fork_version = fromHexString3(cluster.fork_version);
5353
5604
  val.operators = cluster.operators.map((operator) => {
5354
- return configOnly ? { address: fromHexString2(operator.address) } : {
5355
- address: fromHexString2(operator.address),
5605
+ return configOnly ? { address: fromHexString3(operator.address) } : {
5606
+ address: fromHexString3(operator.address),
5356
5607
  enr: strToUint8Array(operator.enr),
5357
- config_signature: fromHexString2(operator.config_signature),
5358
- enr_signature: fromHexString2(operator.enr_signature)
5608
+ config_signature: fromHexString3(operator.config_signature),
5609
+ enr_signature: fromHexString3(operator.enr_signature)
5359
5610
  };
5360
5611
  });
5361
- val.creator = configOnly ? { address: fromHexString2(cluster.creator.address) } : {
5362
- address: fromHexString2(cluster.creator.address),
5363
- config_signature: fromHexString2(
5612
+ val.creator = configOnly ? { address: fromHexString3(cluster.creator.address) } : {
5613
+ address: fromHexString3(cluster.creator.address),
5614
+ config_signature: fromHexString3(
5364
5615
  cluster.creator.config_signature
5365
5616
  )
5366
5617
  };
5367
5618
  val.validators = cluster.validators.map((validator) => {
5368
5619
  return {
5369
- fee_recipient_address: fromHexString2(validator.fee_recipient_address),
5370
- withdrawal_address: fromHexString2(validator.withdrawal_address)
5620
+ fee_recipient_address: fromHexString3(validator.fee_recipient_address),
5621
+ withdrawal_address: fromHexString3(validator.withdrawal_address)
5371
5622
  };
5372
5623
  });
5373
5624
  if (!configOnly) {
5374
- val.config_hash = fromHexString2(cluster.config_hash);
5625
+ val.config_hash = fromHexString3(cluster.config_hash);
5375
5626
  }
5376
5627
  return val;
5377
5628
  };
@@ -5398,34 +5649,34 @@ var hashClusterLockV1X7 = (cluster) => {
5398
5649
  (dValidator) => {
5399
5650
  var _a6, _b2, _c, _d, _e, _f, _g, _h, _i;
5400
5651
  return {
5401
- distributed_public_key: fromHexString2(
5652
+ distributed_public_key: fromHexString3(
5402
5653
  dValidator.distributed_public_key
5403
5654
  ),
5404
5655
  public_shares: dValidator.public_shares.map(
5405
- (publicShare) => fromHexString2(publicShare)
5656
+ (publicShare) => fromHexString3(publicShare)
5406
5657
  ),
5407
5658
  deposit_data: {
5408
- pubkey: fromHexString2((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
5409
- withdrawal_credentials: fromHexString2(
5659
+ pubkey: fromHexString3((_a6 = dValidator.deposit_data) == null ? void 0 : _a6.pubkey),
5660
+ withdrawal_credentials: fromHexString3(
5410
5661
  (_b2 = dValidator.deposit_data) == null ? void 0 : _b2.withdrawal_credentials
5411
5662
  ),
5412
5663
  amount: parseInt((_c = dValidator.deposit_data) == null ? void 0 : _c.amount),
5413
- signature: fromHexString2(
5664
+ signature: fromHexString3(
5414
5665
  (_d = dValidator.deposit_data) == null ? void 0 : _d.signature
5415
5666
  )
5416
5667
  },
5417
5668
  builder_registration: {
5418
5669
  message: {
5419
- fee_recipient: fromHexString2(
5670
+ fee_recipient: fromHexString3(
5420
5671
  (_e = dValidator.builder_registration) == null ? void 0 : _e.message.fee_recipient
5421
5672
  ),
5422
5673
  gas_limit: (_f = dValidator.builder_registration) == null ? void 0 : _f.message.gas_limit,
5423
5674
  timestamp: (_g = dValidator.builder_registration) == null ? void 0 : _g.message.timestamp,
5424
- pubkey: fromHexString2(
5675
+ pubkey: fromHexString3(
5425
5676
  (_h = dValidator.builder_registration) == null ? void 0 : _h.message.pubkey
5426
5677
  )
5427
5678
  },
5428
- signature: fromHexString2(
5679
+ signature: fromHexString3(
5429
5680
  (_i = dValidator.builder_registration) == null ? void 0 : _i.signature
5430
5681
  )
5431
5682
  }
@@ -5437,6 +5688,22 @@ var hashClusterLockV1X7 = (cluster) => {
5437
5688
  var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5438
5689
  var _a6, _b2;
5439
5690
  const validators = clusterLock.distributed_validators;
5691
+ const operatorCount = clusterLock.cluster_definition.operators.length;
5692
+ const threshold = clusterLock.cluster_definition.threshold;
5693
+ for (const validator of validators) {
5694
+ if (validator.public_shares.length !== operatorCount) {
5695
+ return false;
5696
+ }
5697
+ const uniqueShareCount = new Set(validator.public_shares).size;
5698
+ if (uniqueShareCount !== validator.public_shares.length) {
5699
+ return false;
5700
+ }
5701
+ }
5702
+ const allShares = validators.map((v) => v.public_shares);
5703
+ const allDKs = validators.map((v) => v.distributed_public_key);
5704
+ if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
5705
+ return false;
5706
+ }
5440
5707
  const pubShares = [];
5441
5708
  const pubKeys = [];
5442
5709
  const builderRegistrationAndDepositDataMessages = [];
@@ -5445,8 +5712,18 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5445
5712
  const validator = validators[i];
5446
5713
  const validatorPublicShares = validator.public_shares;
5447
5714
  const distributedPublicKey = validator.distributed_public_key;
5448
- for (const element of validatorPublicShares) {
5449
- pubShares.push(fromHexString2(element));
5715
+ if (validatorPublicShares.length !== operatorCount) {
5716
+ return false;
5717
+ }
5718
+ const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
5719
+ if (new Set(normalizedShares).size !== normalizedShares.length) {
5720
+ return false;
5721
+ }
5722
+ const validatorPublicSharesBytes = validatorPublicShares.map(
5723
+ (share) => fromHexString3(share)
5724
+ );
5725
+ for (const share of validatorPublicSharesBytes) {
5726
+ pubShares.push(share);
5450
5727
  }
5451
5728
  const { isValidDepositData, depositDataMsg } = verifyDepositData(
5452
5729
  distributedPublicKey,
@@ -5457,10 +5734,10 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5457
5734
  if (!isValidDepositData) {
5458
5735
  return false;
5459
5736
  }
5460
- pubKeys.push(fromHexString2(distributedPublicKey));
5737
+ pubKeys.push(fromHexString3(distributedPublicKey));
5461
5738
  builderRegistrationAndDepositDataMessages.push(depositDataMsg);
5462
5739
  blsSignatures.push(
5463
- fromHexString2((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5740
+ fromHexString3((_a6 = validator.deposit_data) == null ? void 0 : _a6.signature)
5464
5741
  );
5465
5742
  const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
5466
5743
  validator,
@@ -5470,18 +5747,17 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5470
5747
  if (!isValidBuilderRegistration) {
5471
5748
  return false;
5472
5749
  }
5473
- pubKeys.push(fromHexString2(distributedPublicKey));
5750
+ pubKeys.push(fromHexString3(distributedPublicKey));
5474
5751
  builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
5475
5752
  blsSignatures.push(
5476
- fromHexString2((_b2 = validator.builder_registration) == null ? void 0 : _b2.signature)
5753
+ fromHexString3((_b2 = validator.builder_registration) == null ? void 0 : _b2.signature)
5477
5754
  );
5478
5755
  }
5479
- const aggregateBLSSignature = blsAggregateSignatures(blsSignatures);
5480
- if (!blsVerifyMultiple(
5756
+ if (!(yield verifyBatchParallel(
5481
5757
  pubKeys,
5482
5758
  builderRegistrationAndDepositDataMessages,
5483
- aggregateBLSSignature
5484
- )) {
5759
+ blsSignatures
5760
+ ))) {
5485
5761
  return false;
5486
5762
  }
5487
5763
  if (!verifyNodeSignatures(clusterLock)) {
@@ -5489,8 +5765,8 @@ var verifyDVV1X7 = (clusterLock) => __async(null, null, function* () {
5489
5765
  }
5490
5766
  if (!blsVerifyAggregate(
5491
5767
  pubShares,
5492
- fromHexString2(clusterLock.lock_hash),
5493
- fromHexString2(clusterLock.signature_aggregate)
5768
+ fromHexString3(clusterLock.lock_hash),
5769
+ fromHexString3(clusterLock.signature_aggregate)
5494
5770
  )) {
5495
5771
  return false;
5496
5772
  }
@@ -14959,7 +15235,7 @@ import {
14959
15235
  ContainerType as ContainerType4,
14960
15236
  ListBasicType,
14961
15237
  ListCompositeType as ListCompositeType3,
14962
- fromHexString as fromHexString3
15238
+ fromHexString as fromHexString4
14963
15239
  } from "@chainsafe/ssz";
14964
15240
  var clusterDefinitionContainerTypeV1X8 = (configOnly) => {
14965
15241
  let returnedContainerType = {
@@ -14996,25 +15272,25 @@ var hashClusterDefinitionV1X8 = (cluster, configOnly) => {
14996
15272
  val.num_validators = cluster.num_validators;
14997
15273
  val.threshold = cluster.threshold;
14998
15274
  val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
14999
- val.fork_version = fromHexString3(cluster.fork_version);
15275
+ val.fork_version = fromHexString4(cluster.fork_version);
15000
15276
  val.operators = cluster.operators.map((operator) => {
15001
- return configOnly ? { address: fromHexString3(operator.address) } : {
15002
- address: fromHexString3(operator.address),
15277
+ return configOnly ? { address: fromHexString4(operator.address) } : {
15278
+ address: fromHexString4(operator.address),
15003
15279
  enr: strToUint8Array(operator.enr),
15004
- config_signature: fromHexString3(operator.config_signature),
15005
- enr_signature: fromHexString3(operator.enr_signature)
15280
+ config_signature: fromHexString4(operator.config_signature),
15281
+ enr_signature: fromHexString4(operator.enr_signature)
15006
15282
  };
15007
15283
  });
15008
- val.creator = configOnly ? { address: fromHexString3(cluster.creator.address) } : {
15009
- address: fromHexString3(cluster.creator.address),
15010
- config_signature: fromHexString3(
15284
+ val.creator = configOnly ? { address: fromHexString4(cluster.creator.address) } : {
15285
+ address: fromHexString4(cluster.creator.address),
15286
+ config_signature: fromHexString4(
15011
15287
  cluster.creator.config_signature
15012
15288
  )
15013
15289
  };
15014
15290
  val.validators = cluster.validators.map((validator) => {
15015
15291
  return {
15016
- fee_recipient_address: fromHexString3(validator.fee_recipient_address),
15017
- withdrawal_address: fromHexString3(validator.withdrawal_address)
15292
+ fee_recipient_address: fromHexString4(validator.fee_recipient_address),
15293
+ withdrawal_address: fromHexString4(validator.withdrawal_address)
15018
15294
  };
15019
15295
  });
15020
15296
  if (cluster.deposit_amounts) {
@@ -15023,7 +15299,7 @@ var hashClusterDefinitionV1X8 = (cluster, configOnly) => {
15023
15299
  });
15024
15300
  }
15025
15301
  if (!configOnly) {
15026
- val.config_hash = fromHexString3(cluster.config_hash);
15302
+ val.config_hash = fromHexString4(cluster.config_hash);
15027
15303
  }
15028
15304
  return val;
15029
15305
  };
@@ -15050,35 +15326,35 @@ var hashClusterLockV1X8 = (cluster) => {
15050
15326
  (dValidator) => {
15051
15327
  var _a6, _b2, _c, _d, _e;
15052
15328
  return {
15053
- distributed_public_key: fromHexString3(
15329
+ distributed_public_key: fromHexString4(
15054
15330
  dValidator.distributed_public_key
15055
15331
  ),
15056
15332
  public_shares: dValidator.public_shares.map(
15057
- (publicShare) => fromHexString3(publicShare)
15333
+ (publicShare) => fromHexString4(publicShare)
15058
15334
  ),
15059
15335
  // should be fixed
15060
15336
  partial_deposit_data: dValidator.partial_deposit_data.map((depositData) => {
15061
15337
  return {
15062
- pubkey: fromHexString3(depositData.pubkey),
15063
- withdrawal_credentials: fromHexString3(
15338
+ pubkey: fromHexString4(depositData.pubkey),
15339
+ withdrawal_credentials: fromHexString4(
15064
15340
  depositData.withdrawal_credentials
15065
15341
  ),
15066
15342
  amount: parseInt(depositData.amount),
15067
- signature: fromHexString3(depositData.signature)
15343
+ signature: fromHexString4(depositData.signature)
15068
15344
  };
15069
15345
  }),
15070
15346
  builder_registration: {
15071
15347
  message: {
15072
- fee_recipient: fromHexString3(
15348
+ fee_recipient: fromHexString4(
15073
15349
  (_a6 = dValidator.builder_registration) == null ? void 0 : _a6.message.fee_recipient
15074
15350
  ),
15075
15351
  gas_limit: (_b2 = dValidator.builder_registration) == null ? void 0 : _b2.message.gas_limit,
15076
15352
  timestamp: (_c = dValidator.builder_registration) == null ? void 0 : _c.message.timestamp,
15077
- pubkey: fromHexString3(
15353
+ pubkey: fromHexString4(
15078
15354
  (_d = dValidator.builder_registration) == null ? void 0 : _d.message.pubkey
15079
15355
  )
15080
15356
  },
15081
- signature: fromHexString3(
15357
+ signature: fromHexString4(
15082
15358
  (_e = dValidator.builder_registration) == null ? void 0 : _e.signature
15083
15359
  )
15084
15360
  }
@@ -15090,6 +15366,22 @@ var hashClusterLockV1X8 = (cluster) => {
15090
15366
  var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
15091
15367
  var _a6;
15092
15368
  const validators = clusterLock.distributed_validators;
15369
+ const operatorCount = clusterLock.cluster_definition.operators.length;
15370
+ const threshold = clusterLock.cluster_definition.threshold;
15371
+ for (const validator of validators) {
15372
+ if (validator.public_shares.length !== operatorCount) {
15373
+ return false;
15374
+ }
15375
+ const uniqueShareCount = new Set(validator.public_shares).size;
15376
+ if (uniqueShareCount !== validator.public_shares.length) {
15377
+ return false;
15378
+ }
15379
+ }
15380
+ const allShares = validators.map((v) => v.public_shares);
15381
+ const allDKs = validators.map((v) => v.distributed_public_key);
15382
+ if (!(yield verifySharesBinding(allShares, allDKs, threshold))) {
15383
+ return false;
15384
+ }
15093
15385
  const pubShares = [];
15094
15386
  const pubKeys = [];
15095
15387
  const builderRegistrationAndDepositDataMessages = [];
@@ -15098,8 +15390,18 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
15098
15390
  const validator = validators[i];
15099
15391
  const validatorPublicShares = validator.public_shares;
15100
15392
  const distributedPublicKey = validator.distributed_public_key;
15101
- for (const element of validatorPublicShares) {
15102
- pubShares.push(fromHexString3(element));
15393
+ if (validatorPublicShares.length !== operatorCount) {
15394
+ return false;
15395
+ }
15396
+ const normalizedShares = validatorPublicShares.map((s) => s.toLowerCase());
15397
+ if (new Set(normalizedShares).size !== normalizedShares.length) {
15398
+ return false;
15399
+ }
15400
+ const validatorPublicSharesBytes = validatorPublicShares.map(
15401
+ (share) => fromHexString4(share)
15402
+ );
15403
+ for (const share of validatorPublicSharesBytes) {
15404
+ pubShares.push(share);
15103
15405
  }
15104
15406
  const depositAmounts = clusterLock.cluster_definition.deposit_amounts;
15105
15407
  if (!!depositAmounts && depositAmounts !== null) {
@@ -15122,9 +15424,9 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
15122
15424
  if (!isValidDepositData) {
15123
15425
  return false;
15124
15426
  }
15125
- pubKeys.push(fromHexString3(distributedPublicKey));
15427
+ pubKeys.push(fromHexString4(distributedPublicKey));
15126
15428
  builderRegistrationAndDepositDataMessages.push(depositDataMsg);
15127
- blsSignatures.push(fromHexString3(depositData == null ? void 0 : depositData.signature));
15429
+ blsSignatures.push(fromHexString4(depositData == null ? void 0 : depositData.signature));
15128
15430
  }
15129
15431
  const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
15130
15432
  validator,
@@ -15134,18 +15436,17 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
15134
15436
  if (!isValidBuilderRegistration) {
15135
15437
  return false;
15136
15438
  }
15137
- pubKeys.push(fromHexString3(distributedPublicKey));
15439
+ pubKeys.push(fromHexString4(distributedPublicKey));
15138
15440
  builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg);
15139
15441
  blsSignatures.push(
15140
- fromHexString3((_a6 = validator.builder_registration) == null ? void 0 : _a6.signature)
15442
+ fromHexString4((_a6 = validator.builder_registration) == null ? void 0 : _a6.signature)
15141
15443
  );
15142
15444
  }
15143
- const aggregateBLSSignature = blsAggregateSignatures(blsSignatures);
15144
- if (!blsVerifyMultiple(
15445
+ if (!(yield verifyBatchParallel(
15145
15446
  pubKeys,
15146
15447
  builderRegistrationAndDepositDataMessages,
15147
- aggregateBLSSignature
15148
- )) {
15448
+ blsSignatures
15449
+ ))) {
15149
15450
  return false;
15150
15451
  }
15151
15452
  if (!verifyNodeSignatures(clusterLock)) {
@@ -15153,8 +15454,8 @@ var verifyDVV1X8 = (clusterLock) => __async(null, null, function* () {
15153
15454
  }
15154
15455
  if (!blsVerifyAggregate(
15155
15456
  pubShares,
15156
- fromHexString3(clusterLock.lock_hash),
15157
- fromHexString3(clusterLock.signature_aggregate)
15457
+ fromHexString4(clusterLock.lock_hash),
15458
+ fromHexString4(clusterLock.signature_aggregate)
15158
15459
  )) {
15159
15460
  return false;
15160
15461
  }
@@ -15246,7 +15547,7 @@ import {
15246
15547
  ContainerType as ContainerType5,
15247
15548
  ListBasicType as ListBasicType2,
15248
15549
  ListCompositeType as ListCompositeType4,
15249
- fromHexString as fromHexString4,
15550
+ fromHexString as fromHexString5,
15250
15551
  BooleanType
15251
15552
  } from "@chainsafe/ssz";
15252
15553
  var clusterDefinitionContainerTypeV1X10 = (configOnly) => {
@@ -15287,25 +15588,25 @@ var hashClusterDefinitionV1X10 = (cluster, configOnly) => {
15287
15588
  val.num_validators = cluster.num_validators;
15288
15589
  val.threshold = cluster.threshold;
15289
15590
  val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
15290
- val.fork_version = fromHexString4(cluster.fork_version);
15591
+ val.fork_version = fromHexString5(cluster.fork_version);
15291
15592
  val.operators = cluster.operators.map((operator) => {
15292
- return configOnly ? { address: fromHexString4(operator.address) } : {
15293
- address: fromHexString4(operator.address),
15593
+ return configOnly ? { address: fromHexString5(operator.address) } : {
15594
+ address: fromHexString5(operator.address),
15294
15595
  enr: strToUint8Array(operator.enr),
15295
- config_signature: fromHexString4(operator.config_signature),
15296
- enr_signature: fromHexString4(operator.enr_signature)
15596
+ config_signature: fromHexString5(operator.config_signature),
15597
+ enr_signature: fromHexString5(operator.enr_signature)
15297
15598
  };
15298
15599
  });
15299
- val.creator = configOnly ? { address: fromHexString4(cluster.creator.address) } : {
15300
- address: fromHexString4(cluster.creator.address),
15301
- config_signature: fromHexString4(
15600
+ val.creator = configOnly ? { address: fromHexString5(cluster.creator.address) } : {
15601
+ address: fromHexString5(cluster.creator.address),
15602
+ config_signature: fromHexString5(
15302
15603
  cluster.creator.config_signature
15303
15604
  )
15304
15605
  };
15305
15606
  val.validators = cluster.validators.map((validator) => {
15306
15607
  return {
15307
- fee_recipient_address: fromHexString4(validator.fee_recipient_address),
15308
- withdrawal_address: fromHexString4(validator.withdrawal_address)
15608
+ fee_recipient_address: fromHexString5(validator.fee_recipient_address),
15609
+ withdrawal_address: fromHexString5(validator.withdrawal_address)
15309
15610
  };
15310
15611
  });
15311
15612
  if (cluster.deposit_amounts) {
@@ -15323,7 +15624,7 @@ var hashClusterDefinitionV1X10 = (cluster, configOnly) => {
15323
15624
  val.compounding = cluster.compounding;
15324
15625
  }
15325
15626
  if (!configOnly) {
15326
- val.config_hash = fromHexString4(cluster.config_hash);
15627
+ val.config_hash = fromHexString5(cluster.config_hash);
15327
15628
  }
15328
15629
  return val;
15329
15630
  };
@@ -15350,35 +15651,35 @@ var hashClusterLockV1X10 = (cluster) => {
15350
15651
  (dValidator) => {
15351
15652
  var _a6, _b2, _c, _d, _e;
15352
15653
  return {
15353
- distributed_public_key: fromHexString4(
15654
+ distributed_public_key: fromHexString5(
15354
15655
  dValidator.distributed_public_key
15355
15656
  ),
15356
15657
  public_shares: dValidator.public_shares.map(
15357
- (publicShare) => fromHexString4(publicShare)
15658
+ (publicShare) => fromHexString5(publicShare)
15358
15659
  ),
15359
15660
  // should be fixed
15360
15661
  partial_deposit_data: dValidator.partial_deposit_data.map((depositData) => {
15361
15662
  return {
15362
- pubkey: fromHexString4(depositData.pubkey),
15363
- withdrawal_credentials: fromHexString4(
15663
+ pubkey: fromHexString5(depositData.pubkey),
15664
+ withdrawal_credentials: fromHexString5(
15364
15665
  depositData.withdrawal_credentials
15365
15666
  ),
15366
15667
  amount: parseInt(depositData.amount),
15367
- signature: fromHexString4(depositData.signature)
15668
+ signature: fromHexString5(depositData.signature)
15368
15669
  };
15369
15670
  }),
15370
15671
  builder_registration: {
15371
15672
  message: {
15372
- fee_recipient: fromHexString4(
15673
+ fee_recipient: fromHexString5(
15373
15674
  (_a6 = dValidator.builder_registration) == null ? void 0 : _a6.message.fee_recipient
15374
15675
  ),
15375
15676
  gas_limit: (_b2 = dValidator.builder_registration) == null ? void 0 : _b2.message.gas_limit,
15376
15677
  timestamp: (_c = dValidator.builder_registration) == null ? void 0 : _c.message.timestamp,
15377
- pubkey: fromHexString4(
15678
+ pubkey: fromHexString5(
15378
15679
  (_d = dValidator.builder_registration) == null ? void 0 : _d.message.pubkey
15379
15680
  )
15380
15681
  },
15381
- signature: fromHexString4(
15682
+ signature: fromHexString5(
15382
15683
  (_e = dValidator.builder_registration) == null ? void 0 : _e.signature
15383
15684
  )
15384
15685
  }
@@ -15537,8 +15838,8 @@ var computeSigningRoot = (sszObjectRoot, domain) => {
15537
15838
  };
15538
15839
  var computeDepositMsgRoot = (msg) => {
15539
15840
  const depositMsgVal = depositMessageType.defaultValue();
15540
- depositMsgVal.pubkey = fromHexString5(msg.pubkey);
15541
- depositMsgVal.withdrawal_credentials = fromHexString5(
15841
+ depositMsgVal.pubkey = fromHexString6(msg.pubkey);
15842
+ depositMsgVal.withdrawal_credentials = fromHexString6(
15542
15843
  msg.withdrawal_credentials
15543
15844
  );
15544
15845
  depositMsgVal.amount = parseInt(msg.amount);
@@ -15552,16 +15853,16 @@ var computeForkDataRoot = (currentVersion, genesisValidatorsRoot) => {
15552
15853
  };
15553
15854
  var computebuilderRegistrationMsgRoot = (msg) => {
15554
15855
  const builderRegistrationMsgVal = builderRegistrationMessageType.defaultValue();
15555
- builderRegistrationMsgVal.fee_recipient = fromHexString5(msg.fee_recipient);
15856
+ builderRegistrationMsgVal.fee_recipient = fromHexString6(msg.fee_recipient);
15556
15857
  builderRegistrationMsgVal.gas_limit = msg.gas_limit;
15557
15858
  builderRegistrationMsgVal.timestamp = msg.timestamp;
15558
- builderRegistrationMsgVal.pubkey = fromHexString5(msg.pubkey);
15859
+ builderRegistrationMsgVal.pubkey = fromHexString6(msg.pubkey);
15559
15860
  return Buffer.from(
15560
15861
  builderRegistrationMessageType.hashTreeRoot(builderRegistrationMsgVal).buffer
15561
15862
  );
15562
15863
  };
15563
- var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHexString5(GENESIS_VALIDATOR_ROOT)) => {
15564
- const forkVersion = fromHexString5(
15864
+ var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHexString6(GENESIS_VALIDATOR_ROOT)) => {
15865
+ const forkVersion = fromHexString6(
15565
15866
  lockForkVersion.substring(2, lockForkVersion.length)
15566
15867
  );
15567
15868
  const forkDataRoot = computeForkDataRoot(forkVersion, genesisValidatorsRoot);
@@ -15572,7 +15873,7 @@ var computeDomain = (domainType, lockForkVersion, genesisValidatorsRoot = fromHe
15572
15873
  };
15573
15874
  var verifyDepositData = (distributedPublicKey, depositData, withdrawalAddress, forkVersion, compounding) => {
15574
15875
  const depositDomain = computeDomain(
15575
- fromHexString5(DOMAIN_DEPOSIT),
15876
+ fromHexString6(DOMAIN_DEPOSIT),
15576
15877
  forkVersion
15577
15878
  );
15578
15879
  const withdrawalPrefix = compounding ? "0x02" : "0x01";
@@ -15589,16 +15890,16 @@ var verifyDepositData = (distributedPublicKey, depositData, withdrawalAddress, f
15589
15890
  return { isValidDepositData: false, depositDataMsg: depositDataRoot };
15590
15891
  }
15591
15892
  const isValidDepositData = blsVerify(
15592
- fromHexString5(depositData.pubkey),
15893
+ fromHexString6(depositData.pubkey),
15593
15894
  depositDataRoot,
15594
- fromHexString5(depositData.signature)
15895
+ fromHexString6(depositData.signature)
15595
15896
  );
15596
15897
  return { isValidDepositData, depositDataMsg: depositDataRoot };
15597
15898
  };
15598
15899
  var verifyBuilderRegistration = (validator, feeRecipientAddress, forkVersion) => {
15599
15900
  var _a6;
15600
15901
  const builderDomain = computeDomain(
15601
- fromHexString5(DOMAIN_APPLICATION_BUILDER),
15902
+ fromHexString6(DOMAIN_APPLICATION_BUILDER),
15602
15903
  forkVersion
15603
15904
  );
15604
15905
  if (validator.distributed_public_key !== ((_a6 = validator.builder_registration) == null ? void 0 : _a6.message.pubkey)) {
@@ -15666,6 +15967,12 @@ var verifyLockData = (clusterLock) => __async(null, null, function* () {
15666
15967
  }
15667
15968
  return false;
15668
15969
  });
15970
+ var hasUniqueDistributedKeys = (clusterLock) => {
15971
+ const dvKeys = clusterLock.distributed_validators.map(
15972
+ (v) => v.distributed_public_key.toLowerCase()
15973
+ );
15974
+ return new Set(dvKeys).size === dvKeys.length;
15975
+ };
15669
15976
  var isValidClusterLock = (clusterLock, safeRpcUrl) => __async(null, null, function* () {
15670
15977
  try {
15671
15978
  const definitionType = definitionFlow(clusterLock.cluster_definition);
@@ -15686,6 +15993,9 @@ var isValidClusterLock = (clusterLock, safeRpcUrl) => __async(null, null, functi
15686
15993
  if (clusterLockHash(clusterLock) !== clusterLock.lock_hash) {
15687
15994
  return false;
15688
15995
  }
15996
+ if (!hasUniqueDistributedKeys(clusterLock)) {
15997
+ return false;
15998
+ }
15689
15999
  const isValidLockData = yield verifyLockData(clusterLock);
15690
16000
  if (!isValidLockData) {
15691
16001
  return false;
@@ -19360,7 +19670,7 @@ import * as elliptic2 from "elliptic";
19360
19670
  import {
19361
19671
  ByteVectorType as ByteVectorType7,
19362
19672
  ContainerType as ContainerType7,
19363
- fromHexString as fromHexString7,
19673
+ fromHexString as fromHexString8,
19364
19674
  ListCompositeType as ListCompositeType5,
19365
19675
  UintNumberType as UintNumberType6
19366
19676
  } from "@chainsafe/ssz";
@@ -19400,7 +19710,7 @@ function getGenesisValidatorsRoot(beaconNodeApiUrl) {
19400
19710
  }
19401
19711
 
19402
19712
  // src/exits/verificationHelpers.ts
19403
- import { ContainerType as ContainerType6, ByteVectorType as ByteVectorType6, fromHexString as fromHexString6 } from "@chainsafe/ssz";
19713
+ import { ContainerType as ContainerType6, ByteVectorType as ByteVectorType6, fromHexString as fromHexString7 } from "@chainsafe/ssz";
19404
19714
  var GENESIS_VALIDATOR_ROOT_HEX_STRING = "0x0000000000000000000000000000000000000000000000000000000000000000";
19405
19715
  var ForkDataType = new ContainerType6({
19406
19716
  currentVersion: new ByteVectorType6(4),
@@ -19417,7 +19727,7 @@ function computeForkDataRoot2(currentVersion, genesisValidatorsRoot) {
19417
19727
  return Buffer.from(ForkDataType.hashTreeRoot(forkDataVal).buffer);
19418
19728
  }
19419
19729
  function computeDomain2(domainType, forkVersionString, genesisValidatorsRootOverride) {
19420
- const forkVersionBytes = fromHexString6(
19730
+ const forkVersionBytes = fromHexString7(
19421
19731
  forkVersionString.substring(2, forkVersionString.length)
19422
19732
  );
19423
19733
  if (forkVersionBytes.length !== 4) {
@@ -19426,7 +19736,7 @@ function computeDomain2(domainType, forkVersionString, genesisValidatorsRootOver
19426
19736
  if (domainType.length !== 4) {
19427
19737
  throw new Error("Domain type must be 4 bytes");
19428
19738
  }
19429
- const actualGenesisValidatorsRoot = genesisValidatorsRootOverride != null ? genesisValidatorsRootOverride : fromHexString6(GENESIS_VALIDATOR_ROOT_HEX_STRING.substring(2));
19739
+ const actualGenesisValidatorsRoot = genesisValidatorsRootOverride != null ? genesisValidatorsRootOverride : fromHexString7(GENESIS_VALIDATOR_ROOT_HEX_STRING.substring(2));
19430
19740
  if (actualGenesisValidatorsRoot.length !== 32) {
19431
19741
  throw new Error("genesisValidatorsRoot must be 32 bytes");
19432
19742
  }
@@ -19519,7 +19829,7 @@ var Exit = class _Exit {
19519
19829
  static computeExitPayloadRoot(exits) {
19520
19830
  const sszValue = SSZPartialExitsPayloadType.defaultValue();
19521
19831
  sszValue.partial_exits = exits.partial_exits.map((pe) => ({
19522
- public_key: fromHexString7(pe.public_key),
19832
+ public_key: fromHexString8(pe.public_key),
19523
19833
  signed_exit_message: {
19524
19834
  message: {
19525
19835
  epoch: _Exit.safeParseInt(pe.signed_exit_message.message.epoch),
@@ -19527,7 +19837,7 @@ var Exit = class _Exit {
19527
19837
  pe.signed_exit_message.message.validator_index
19528
19838
  )
19529
19839
  },
19530
- signature: fromHexString7(pe.signed_exit_message.signature)
19840
+ signature: fromHexString8(pe.signed_exit_message.signature)
19531
19841
  }
19532
19842
  }));
19533
19843
  sszValue.share_idx = exits.share_idx;
@@ -19577,18 +19887,18 @@ var Exit = class _Exit {
19577
19887
  signedExitMessage.message
19578
19888
  );
19579
19889
  const exitDomain = computeDomain2(
19580
- fromHexString7(DOMAIN_VOLUNTARY_EXIT),
19890
+ fromHexString8(DOMAIN_VOLUNTARY_EXIT),
19581
19891
  capellaForkVersionString,
19582
- fromHexString7(genesisValidatorsRootString)
19892
+ fromHexString8(genesisValidatorsRootString)
19583
19893
  );
19584
19894
  const messageSigningRoot = signingRoot2(
19585
19895
  exitDomain,
19586
19896
  partialExitMessageBuffer
19587
19897
  );
19588
19898
  return blsVerify(
19589
- fromHexString7(publicShareKey),
19899
+ fromHexString8(publicShareKey),
19590
19900
  messageSigningRoot,
19591
- fromHexString7(signedExitMessage.signature)
19901
+ fromHexString8(signedExitMessage.signature)
19592
19902
  );
19593
19903
  });
19594
19904
  }
@@ -19891,7 +20201,7 @@ var Exit = class _Exit {
19891
20201
  );
19892
20202
  }
19893
20203
  try {
19894
- const sigBytes = fromHexString7(cleanSigStr);
20204
+ const sigBytes = fromHexString8(cleanSigStr);
19895
20205
  const sigIdx = parseInt(sigIdxStr, 10);
19896
20206
  signaturesByIndex.set(sigIdx + 1, sigBytes);
19897
20207
  } catch (err) {
@@ -21250,6 +21560,7 @@ export {
21250
21560
  Domain,
21251
21561
  EIP712_DOMAIN_NAME,
21252
21562
  EIP712_DOMAIN_VERSION,
21563
+ ENR,
21253
21564
  ENRTypedMessage,
21254
21565
  EOA,
21255
21566
  ETHER_TO_GWEI,
@@ -21276,6 +21587,7 @@ export {
21276
21587
  blsVerify,
21277
21588
  clusterConfigOrDefinitionHash,
21278
21589
  clusterLockHash,
21590
+ hasUniqueDistributedKeys,
21279
21591
  isChainSupportedForSplitters,
21280
21592
  isValidClusterLock,
21281
21593
  signCreatorConfigHashPayload,