@monolythium/core-sdk 0.4.0 → 0.4.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/dist/index.cjs CHANGED
@@ -2,11 +2,13 @@
2
2
 
3
3
  var blake3_js = require('@noble/hashes/blake3.js');
4
4
  var sha3_js = require('@noble/hashes/sha3.js');
5
+ var mlKem_js = require('@noble/post-quantum/ml-kem.js');
6
+ var chacha_js = require('@noble/ciphers/chacha.js');
7
+ require('@noble/hashes/utils.js');
5
8
  var mlDsa_js = require('@noble/post-quantum/ml-dsa.js');
6
9
  var bls12381_js = require('@noble/curves/bls12-381.js');
7
- require('@noble/post-quantum/ml-kem.js');
8
- require('@noble/ciphers/chacha.js');
9
- require('@noble/hashes/utils.js');
10
+ var bip39 = require('@scure/bip39');
11
+ var english_js = require('@scure/bip39/wordlists/english.js');
10
12
 
11
13
  // src/error.ts
12
14
  var SdkError = class _SdkError extends Error {
@@ -437,13 +439,36 @@ var NODE_REGISTRY_SELECTORS = {
437
439
  /** `getOperatorNetworkMetadata(bytes32)` view (PF-6). */
438
440
  getOperatorNetworkMetadata: "0x" + selectorHex("getOperatorNetworkMetadata(bytes32)"),
439
441
  /** `getClusterDiversity(uint32)` view (PF-6). */
440
- getClusterDiversity: "0x" + selectorHex("getClusterDiversity(uint32)")
442
+ getClusterDiversity: "0x" + selectorHex("getClusterDiversity(uint32)"),
443
+ /** `requestClusterJoin(uint32,bytes)` — CJ-1 joining operator posts an admit request. */
444
+ requestClusterJoin: "0x" + selectorHex("requestClusterJoin(uint32,bytes)"),
445
+ /** `voteClusterAdmit(uint32,bytes32,bytes)` — CJ-1 current member admit vote. */
446
+ voteClusterAdmit: "0x" + selectorHex("voteClusterAdmit(uint32,bytes32,bytes)"),
447
+ /** `cancelClusterJoin(uint32,bytes32)` — CJ-1 requester cancellation/refund. */
448
+ cancelClusterJoin: "0x" + selectorHex("cancelClusterJoin(uint32,bytes32)"),
449
+ /** `expireClusterJoin(uint32,bytes32)` — CJ-1 public reaper/refund. */
450
+ expireClusterJoin: "0x" + selectorHex("expireClusterJoin(uint32,bytes32)"),
451
+ /** `getClusterJoinRequest(uint32,bytes32)` — CJ-1 request status view. */
452
+ getClusterJoinRequest: "0x" + selectorHex("getClusterJoinRequest(uint32,bytes32)"),
453
+ /** `formCluster(bytes,bytes,bytes)` — no-foundation cluster formation by roster consent. */
454
+ formCluster: "0x" + selectorHex("formCluster(bytes,bytes,bytes)")
441
455
  };
442
- var NODE_REGISTRY_BLS_PUBKEY_BYTES = 48;
443
- var NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES = 96;
456
+ var NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES = 48;
457
+ var NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES = NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES;
458
+ var NODE_REGISTRY_BLS_PUBKEY_BYTES = NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES;
459
+ var NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES = 1952;
460
+ var NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES = 3309;
461
+ var NODE_REGISTRY_CONSENSUS_POP_BYTES = 3309;
462
+ var NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES = 96;
463
+ var NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES = NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES;
444
464
  var NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS = 5;
445
465
  var NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS = 7;
446
466
  var NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID = (1n << 56n) - 1n;
467
+ var NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT = 7;
468
+ var NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT = 3;
469
+ var NODE_REGISTRY_FORM_CLUSTER_MEMBER_COUNT = NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT + NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT;
470
+ var NODE_REGISTRY_FORM_CLUSTER_THRESHOLD = 7;
471
+ var NODE_REGISTRY_FORM_CLUSTER_MESSAGE_DOMAIN = "PROTOCORE_NODE_REGISTRY_CLUSTER_FORM_V1\0";
447
472
  var PENDING_CHANGE_KIND_CODES = {
448
473
  add: 1,
449
474
  remove: 2,
@@ -510,7 +535,7 @@ function encodeSubmitPendingChangeCalldata(args) {
510
535
  const { kind, kindCode } = normalizePendingChangeKind(args.kind);
511
536
  const targetPubkey = expectLength2(
512
537
  toBytes(args.targetPubkey),
513
- NODE_REGISTRY_BLS_PUBKEY_BYTES,
538
+ NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
514
539
  "targetPubkey"
515
540
  );
516
541
  const effectiveEpoch = toUint64(args.effectiveEpoch, "effectiveEpoch");
@@ -524,8 +549,7 @@ function encodeSubmitPendingChangeCalldata(args) {
524
549
  if (kind !== "rotate" && intentId !== 0n) {
525
550
  throw new NodeRegistryError("only rotate pending changes may carry a non-zero intentId");
526
551
  }
527
- const targetTail = new Uint8Array(32);
528
- targetTail.set(targetPubkey.slice(32, 48), 0);
552
+ const targetPubkeyPadded = padToWord(targetPubkey);
529
553
  return bytesToHex(
530
554
  concatBytes(
531
555
  hexToBytes(NODE_REGISTRY_SELECTORS.submitPendingChange),
@@ -533,55 +557,59 @@ function encodeSubmitPendingChangeCalldata(args) {
533
557
  uint64Word(4n * 32n, "targetPubkeyOffset"),
534
558
  uint64Word(effectiveEpoch, "effectiveEpoch"),
535
559
  uint64Word(intentId, "intentId"),
536
- uint64Word(BigInt(NODE_REGISTRY_BLS_PUBKEY_BYTES), "targetPubkeyLength"),
537
- targetPubkey.slice(0, 32),
538
- targetTail
560
+ uint64Word(BigInt(targetPubkey.length), "targetPubkeyLength"),
561
+ targetPubkeyPadded
539
562
  )
540
563
  );
541
564
  }
542
565
  function encodeCancelPendingChangeCalldata(args) {
543
566
  const targetPubkey = expectLength2(
544
567
  toBytes(args.targetPubkey),
545
- NODE_REGISTRY_BLS_PUBKEY_BYTES,
568
+ NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
546
569
  "targetPubkey"
547
570
  );
548
- const targetTail = new Uint8Array(32);
549
- targetTail.set(targetPubkey.slice(32, 48), 0);
571
+ const targetPubkeyPadded = padToWord(targetPubkey);
550
572
  return bytesToHex(
551
573
  concatBytes(
552
574
  hexToBytes(NODE_REGISTRY_SELECTORS.cancelPendingChange),
553
575
  uint64Word(args.epoch, "epoch"),
554
576
  uint64Word(2n * 32n, "targetPubkeyOffset"),
555
- uint64Word(BigInt(NODE_REGISTRY_BLS_PUBKEY_BYTES), "targetPubkeyLength"),
556
- targetPubkey.slice(0, 32),
557
- targetTail
577
+ uint64Word(BigInt(targetPubkey.length), "targetPubkeyLength"),
578
+ targetPubkeyPadded
558
579
  )
559
580
  );
560
581
  }
561
- function parseDkgResharePublicKeys(blsPublicKeys) {
562
- const keys = toBytes(blsPublicKeys);
563
- if (keys.length % NODE_REGISTRY_BLS_PUBKEY_BYTES !== 0) {
564
- throw new NodeRegistryError("blsPublicKeys length must be a multiple of 48 bytes");
582
+ function parseDkgResharePublicKeys(consensusPublicKeys) {
583
+ const keys = toBytes(consensusPublicKeys);
584
+ if (keys.length % NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES !== 0) {
585
+ throw new NodeRegistryError(
586
+ `consensusPublicKeys length must be a multiple of ${NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES} bytes`
587
+ );
565
588
  }
566
- const signerCount = keys.length / NODE_REGISTRY_BLS_PUBKEY_BYTES;
589
+ const signerCount = keys.length / NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES;
567
590
  if (signerCount < NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS || signerCount > NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS) {
568
591
  throw new NodeRegistryError(
569
- `blsPublicKeys must contain ${NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS}..${NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS} signers`
592
+ `consensusPublicKeys must contain ${NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS}..${NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS} signers`
570
593
  );
571
594
  }
572
595
  const out = [];
573
596
  const seen = /* @__PURE__ */ new Set();
574
- for (let offset = 0; offset < keys.length; offset += NODE_REGISTRY_BLS_PUBKEY_BYTES) {
575
- const key = keys.slice(offset, offset + NODE_REGISTRY_BLS_PUBKEY_BYTES);
597
+ for (let offset = 0; offset < keys.length; offset += NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES) {
598
+ const key = keys.slice(offset, offset + NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES);
576
599
  const keyHex = bytesToHex(key);
577
600
  if (seen.has(keyHex)) {
578
- throw new NodeRegistryError("blsPublicKeys contains a duplicate signer pubkey");
601
+ throw new NodeRegistryError("consensusPublicKeys contains a duplicate signer pubkey");
579
602
  }
580
603
  seen.add(keyHex);
581
604
  out.push(key);
582
605
  }
583
606
  return out;
584
607
  }
608
+ function dkgReshareConsensusPublicKeys(args) {
609
+ if (args.consensusPublicKeys !== void 0) return args.consensusPublicKeys;
610
+ if (args.blsPublicKeys !== void 0) return args.blsPublicKeys;
611
+ throw new NodeRegistryError("consensusPublicKeys is required");
612
+ }
585
613
  function encodeAttestDkgReshareCalldata(args) {
586
614
  const intentId = toUint64(args.intentId, "intentId");
587
615
  if (intentId === 0n) {
@@ -590,10 +618,10 @@ function encodeAttestDkgReshareCalldata(args) {
590
618
  if (intentId > NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID) {
591
619
  throw new NodeRegistryError("intentId must be <= 2^56-1");
592
620
  }
593
- const publicKeys = concatBytes(...parseDkgResharePublicKeys(args.blsPublicKeys));
621
+ const publicKeys = concatBytes(...parseDkgResharePublicKeys(dkgReshareConsensusPublicKeys(args)));
594
622
  const thresholdSig = expectLength2(
595
623
  toBytes(args.thresholdSig),
596
- NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES,
624
+ NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES,
597
625
  "thresholdSig"
598
626
  );
599
627
  const keysPadded = padToWord(publicKeys);
@@ -604,15 +632,158 @@ function encodeAttestDkgReshareCalldata(args) {
604
632
  concatBytes(
605
633
  hexToBytes(NODE_REGISTRY_SELECTORS.attestDkgReshare),
606
634
  uint64Word(intentId, "intentId"),
607
- uint64Word(offsetKeys, "blsPublicKeysOffset"),
635
+ uint64Word(offsetKeys, "consensusPublicKeysOffset"),
608
636
  uint64Word(offsetSig, "thresholdSigOffset"),
609
- uint64Word(BigInt(publicKeys.length), "blsPublicKeysLength"),
637
+ uint64Word(BigInt(publicKeys.length), "consensusPublicKeysLength"),
610
638
  keysPadded,
611
639
  uint64Word(BigInt(thresholdSig.length), "thresholdSigLength"),
612
640
  sigPadded
613
641
  )
614
642
  );
615
643
  }
644
+ function encodeRequestClusterJoinCalldata(args) {
645
+ const operatorPubkey = expectLength2(
646
+ toBytes(args.operatorPubkey),
647
+ NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
648
+ "operatorPubkey"
649
+ );
650
+ const operatorPubkeyPadded = padToWord(operatorPubkey);
651
+ return bytesToHex(
652
+ concatBytes(
653
+ hexToBytes(NODE_REGISTRY_SELECTORS.requestClusterJoin),
654
+ uint32Word(toUint32(args.clusterId, "clusterId")),
655
+ uint64Word(2n * 32n, "operatorPubkeyOffset"),
656
+ uint64Word(BigInt(operatorPubkey.length), "operatorPubkeyLength"),
657
+ operatorPubkeyPadded
658
+ )
659
+ );
660
+ }
661
+ function encodeVoteClusterAdmitCalldata(args) {
662
+ const operatorId = expectLength2(toBytes(args.operatorId), 32, "operatorId");
663
+ const voterPubkey = expectLength2(
664
+ toBytes(args.voterPubkey),
665
+ NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
666
+ "voterPubkey"
667
+ );
668
+ const voterPubkeyPadded = padToWord(voterPubkey);
669
+ return bytesToHex(
670
+ concatBytes(
671
+ hexToBytes(NODE_REGISTRY_SELECTORS.voteClusterAdmit),
672
+ uint32Word(toUint32(args.clusterId, "clusterId")),
673
+ operatorId,
674
+ uint64Word(3n * 32n, "voterPubkeyOffset"),
675
+ uint64Word(BigInt(voterPubkey.length), "voterPubkeyLength"),
676
+ voterPubkeyPadded
677
+ )
678
+ );
679
+ }
680
+ function encodeCancelClusterJoinCalldata(args) {
681
+ return bytesToHex(
682
+ concatBytes(
683
+ hexToBytes(NODE_REGISTRY_SELECTORS.cancelClusterJoin),
684
+ uint32Word(toUint32(args.clusterId, "clusterId")),
685
+ expectLength2(toBytes(args.operatorId), 32, "operatorId")
686
+ )
687
+ );
688
+ }
689
+ function encodeExpireClusterJoinCalldata(args) {
690
+ return bytesToHex(
691
+ concatBytes(
692
+ hexToBytes(NODE_REGISTRY_SELECTORS.expireClusterJoin),
693
+ uint32Word(toUint32(args.clusterId, "clusterId")),
694
+ expectLength2(toBytes(args.operatorId), 32, "operatorId")
695
+ )
696
+ );
697
+ }
698
+ function encodeGetClusterJoinRequestCalldata(args) {
699
+ return bytesToHex(
700
+ concatBytes(
701
+ hexToBytes(NODE_REGISTRY_SELECTORS.getClusterJoinRequest),
702
+ uint32Word(toUint32(args.clusterId, "clusterId")),
703
+ expectLength2(toBytes(args.operatorId), 32, "operatorId")
704
+ )
705
+ );
706
+ }
707
+ function formClusterMessage(activePubkeys, standbyPubkeys) {
708
+ const active = expectLength2(
709
+ toBytes(activePubkeys),
710
+ NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT * NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
711
+ "activePubkeys"
712
+ );
713
+ const standby = expectLength2(
714
+ toBytes(standbyPubkeys),
715
+ NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT * NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
716
+ "standbyPubkeys"
717
+ );
718
+ return blake3_js.blake3(
719
+ concatBytes(
720
+ new TextEncoder().encode(NODE_REGISTRY_FORM_CLUSTER_MESSAGE_DOMAIN),
721
+ u16BeBytes(NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT),
722
+ u16BeBytes(NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT),
723
+ u16BeBytes(NODE_REGISTRY_FORM_CLUSTER_THRESHOLD),
724
+ u32BeBytes(active.length),
725
+ active,
726
+ u32BeBytes(standby.length),
727
+ standby
728
+ )
729
+ );
730
+ }
731
+ function formClusterMessageHex(activePubkeys, standbyPubkeys) {
732
+ return bytesToHex(formClusterMessage(activePubkeys, standbyPubkeys));
733
+ }
734
+ function encodeFormClusterCalldata(args) {
735
+ const activePubkeys = expectLength2(
736
+ toBytes(args.activePubkeys),
737
+ NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT * NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
738
+ "activePubkeys"
739
+ );
740
+ const standbyPubkeys = expectLength2(
741
+ toBytes(args.standbyPubkeys),
742
+ NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT * NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES,
743
+ "standbyPubkeys"
744
+ );
745
+ const signatures = expectLength2(
746
+ toBytes(args.signatures),
747
+ NODE_REGISTRY_FORM_CLUSTER_MEMBER_COUNT * NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES,
748
+ "signatures"
749
+ );
750
+ const activePadded = padToWord(activePubkeys);
751
+ const standbyPadded = padToWord(standbyPubkeys);
752
+ const signaturesPadded = padToWord(signatures);
753
+ const activeOffset = 3n * 32n;
754
+ const standbyOffset = activeOffset + 32n + BigInt(activePadded.length);
755
+ const signaturesOffset = standbyOffset + 32n + BigInt(standbyPadded.length);
756
+ return bytesToHex(
757
+ concatBytes(
758
+ hexToBytes(NODE_REGISTRY_SELECTORS.formCluster),
759
+ uint64Word(activeOffset, "activePubkeysOffset"),
760
+ uint64Word(standbyOffset, "standbyPubkeysOffset"),
761
+ uint64Word(signaturesOffset, "signaturesOffset"),
762
+ uint64Word(BigInt(activePubkeys.length), "activePubkeysLength"),
763
+ activePadded,
764
+ uint64Word(BigInt(standbyPubkeys.length), "standbyPubkeysLength"),
765
+ standbyPadded,
766
+ uint64Word(BigInt(signatures.length), "signaturesLength"),
767
+ signaturesPadded
768
+ )
769
+ );
770
+ }
771
+ function decodeClusterJoinRequest(returnData) {
772
+ const bytes = expectLength2(toBytes(returnData), 8 * 32, "clusterJoinRequest");
773
+ const word = (i) => bytes.slice(i * 32, (i + 1) * 32);
774
+ const statusCode = numberFromWord(word(5), "status", 255);
775
+ return {
776
+ owner: bytesToHex(word(0).slice(12, 32)),
777
+ requestEpoch: u64FromWord(word(1)),
778
+ snapshotThreshold: numberFromWord(word(2), "snapshotThreshold", 65535),
779
+ snapshotN: numberFromWord(word(3), "snapshotN", 65535),
780
+ voteCount: numberFromWord(word(4), "voteCount", 65535),
781
+ statusCode,
782
+ status: clusterJoinRequestStatusLabel(statusCode),
783
+ bondLythoshi: uintFromWord(word(6)),
784
+ sealRosterPending: numberFromWord(word(7), "sealRosterPending", 1) === 1
785
+ };
786
+ }
616
787
  function encodeReportServiceProbeCalldata(args) {
617
788
  if (!isValidPublicServiceProbeMask(args.serviceMask)) {
618
789
  throw new NodeRegistryError(
@@ -699,7 +870,9 @@ function deriveClusterAnchorAddress(roster, threshold) {
699
870
  if (!Number.isInteger(threshold) || threshold < 0 || threshold > 65535) {
700
871
  throw new NodeRegistryError("threshold must be a uint16");
701
872
  }
702
- const members = roster.map((m, i) => expectLength2(toBytes(m), 48, `roster[${i}]`));
873
+ const members = roster.map(
874
+ (m, i) => expectLength2(toBytes(m), NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES, `roster[${i}]`)
875
+ );
703
876
  members.sort(compareBytes);
704
877
  const parts = [
705
878
  new TextEncoder().encode(MULTISIG_ADDRESS_DERIVATION_DOMAIN),
@@ -724,6 +897,36 @@ function u64FromWord(word) {
724
897
  }
725
898
  return v;
726
899
  }
900
+ function uintFromWord(word) {
901
+ let v = 0n;
902
+ for (const byte of word) {
903
+ v = v << 8n | BigInt(byte);
904
+ }
905
+ return v;
906
+ }
907
+ function numberFromWord(word, name, max) {
908
+ const value = uintFromWord(word);
909
+ if (value > BigInt(max)) {
910
+ throw new NodeRegistryError(`${name} must be <= ${max}`);
911
+ }
912
+ return Number(value);
913
+ }
914
+ function clusterJoinRequestStatusLabel(status) {
915
+ switch (status) {
916
+ case 0:
917
+ return "none";
918
+ case 1:
919
+ return "open";
920
+ case 2:
921
+ return "admitted";
922
+ case 3:
923
+ return "cancelled";
924
+ case 4:
925
+ return "expired";
926
+ default:
927
+ return "unknown";
928
+ }
929
+ }
727
930
  function u64BeBytes(value) {
728
931
  const out = new Uint8Array(8);
729
932
  let n = value;
@@ -733,6 +936,16 @@ function u64BeBytes(value) {
733
936
  }
734
937
  return out;
735
938
  }
939
+ function u32BeBytes(value) {
940
+ const n = expectUint32(value, "uint32");
941
+ return Uint8Array.from([n >>> 24 & 255, n >>> 16 & 255, n >>> 8 & 255, n & 255]);
942
+ }
943
+ function u16BeBytes(value) {
944
+ if (!Number.isInteger(value) || value < 0 || value > 65535) {
945
+ throw new NodeRegistryError("uint16 value out of range");
946
+ }
947
+ return Uint8Array.from([value >>> 8 & 255, value & 255]);
948
+ }
736
949
  function compareBytes(a, b) {
737
950
  const len = Math.min(a.length, b.length);
738
951
  for (let i = 0; i < len; i++) {
@@ -755,6 +968,27 @@ function expectUint32(value, name) {
755
968
  }
756
969
  return value;
757
970
  }
971
+ function toUint32(value, name) {
972
+ let parsed;
973
+ if (typeof value === "bigint") {
974
+ parsed = value;
975
+ } else if (typeof value === "number") {
976
+ if (!Number.isSafeInteger(value)) {
977
+ throw new NodeRegistryError(`${name} must be a safe integer`);
978
+ }
979
+ parsed = BigInt(value);
980
+ } else {
981
+ const trimmed = value.trim();
982
+ if (!/^\d+$/u.test(trimmed)) {
983
+ throw new NodeRegistryError(`${name} must be a decimal uint32`);
984
+ }
985
+ parsed = BigInt(trimmed);
986
+ }
987
+ if (parsed < 0n || parsed > 0xffffffffn) {
988
+ throw new NodeRegistryError(`${name} must fit uint32`);
989
+ }
990
+ return Number(parsed);
991
+ }
758
992
  function uint32Word(value) {
759
993
  const out = new Uint8Array(32);
760
994
  const n = expectUint32(value, "uint32");
@@ -897,26 +1131,15 @@ function bigintToBeBytes(value, bytes, label) {
897
1131
  }
898
1132
  return out;
899
1133
  }
900
-
901
- // src/crypto/submission.ts
902
- async function fetchEncryptionKey(client) {
903
- const result = await client.call(
904
- "lyth_getEncryptionKey",
905
- []
906
- );
907
- return {
908
- algo: result.algo ?? "ml-kem-768",
909
- epoch: typeof result.epoch === "string" ? BigInt(result.epoch) : BigInt(result.epoch),
910
- encapsulationKey: hexToBytes2(result.encapsulationKey, "encapsulationKey")
911
- };
912
- }
913
- var ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE = "encrypted mempool submission unavailable until MB-3 threshold decryption is active";
914
- async function buildEncryptedSubmission(_args) {
915
- await Promise.resolve();
916
- throw new Error(ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE);
917
- }
918
- async function submitEncryptedEnvelope(client, envelopeWireHex) {
919
- return client.call("lyth_submitEncrypted", [envelopeWireHex]);
1134
+ function parseBigint(value, label) {
1135
+ if (value === void 0) throw new Error(`${label} missing`);
1136
+ if (typeof value === "bigint") return value;
1137
+ if (typeof value === "number") {
1138
+ if (!Number.isSafeInteger(value) || value < 0) throw new Error(`${label} must be a non-negative safe integer`);
1139
+ return BigInt(value);
1140
+ }
1141
+ if (value.startsWith("0x") || value.startsWith("0X")) return BigInt(value);
1142
+ return BigInt(value);
920
1143
  }
921
1144
 
922
1145
  // src/crypto/bincode.ts
@@ -978,6 +1201,645 @@ var BincodeWriter = class {
978
1201
  }
979
1202
  };
980
1203
 
1204
+ // src/crypto/tx.ts
1205
+ function encodeTransactionForHash(fields, tag) {
1206
+ const n = normalizeTxFields(fields);
1207
+ return concatBytes2(
1208
+ Uint8Array.of(tag),
1209
+ bigintToBeBytes(n.chainId, 8, "chainId"),
1210
+ bigintToBeBytes(n.nonce, 8, "nonce"),
1211
+ bigintToBeBytes(n.maxPriorityFeePerGas, 32, "maxPriorityFeePerGas"),
1212
+ bigintToBeBytes(n.maxFeePerGas, 32, "maxFeePerGas"),
1213
+ bigintToBeBytes(n.gasLimit, 8, "gasLimit"),
1214
+ n.to === null ? Uint8Array.of(0) : concatBytes2(Uint8Array.of(1), n.to),
1215
+ bigintToBeBytes(n.value, 32, "value"),
1216
+ bigintToBeBytes(BigInt(n.input.length), 4, "input.length"),
1217
+ n.input,
1218
+ new Uint8Array(4),
1219
+ // access_list length
1220
+ encodeExtensionsForHash(n.extensions)
1221
+ );
1222
+ }
1223
+ function bincodeSignedTransaction(fields, signature, publicKey) {
1224
+ const n = normalizeTxFields(fields);
1225
+ const sig = expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature");
1226
+ const pk = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
1227
+ const w = new BincodeWriter();
1228
+ w.u64(n.chainId);
1229
+ w.u64(n.nonce);
1230
+ w.bytes(uint256Be(n.maxPriorityFeePerGas, "maxPriorityFeePerGas"));
1231
+ w.bytes(uint256Be(n.maxFeePerGas, "maxFeePerGas"));
1232
+ w.u64(n.gasLimit);
1233
+ if (n.to === null) {
1234
+ w.u8(0);
1235
+ } else {
1236
+ w.u8(1);
1237
+ w.bytes(n.to);
1238
+ }
1239
+ w.bytes(uint256Be(n.value, "value"));
1240
+ w.bytes(n.input);
1241
+ w.u64(0n);
1242
+ w.u64(BigInt(n.extensions.length));
1243
+ for (const ext of n.extensions) bincodeTypedExtensionInto(w, ext);
1244
+ bincodeMlDsa65OpaqueInto(w, sig);
1245
+ bincodeMlDsa65OpaqueInto(w, pk);
1246
+ return w.toBytes();
1247
+ }
1248
+ function normalizeTxFields(fields) {
1249
+ return {
1250
+ chainId: parseBigint(fields.chainId, "chainId"),
1251
+ nonce: parseBigint(fields.nonce, "nonce"),
1252
+ maxPriorityFeePerGas: parseBigint(fields.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
1253
+ maxFeePerGas: parseBigint(fields.maxFeePerGas, "maxFeePerGas"),
1254
+ gasLimit: parseBigint(fields.gasLimit, "gasLimit"),
1255
+ to: normalizeTo(fields.to),
1256
+ value: parseBigint(fields.value, "value"),
1257
+ input: normalizeBytes(fields.input ?? new Uint8Array(0), "input"),
1258
+ extensions: normalizeExtensions(fields.extensions)
1259
+ };
1260
+ }
1261
+ function normalizeTo(value) {
1262
+ if (value === null) return null;
1263
+ const bytes = normalizeBytes(value, "to");
1264
+ return expectBytes(bytes, 20, "to");
1265
+ }
1266
+ function normalizeBytes(value, label) {
1267
+ if (typeof value === "string") return hexToBytes2(value, label);
1268
+ return value instanceof Uint8Array ? value : Uint8Array.from(value);
1269
+ }
1270
+ function normalizeExtensions(value) {
1271
+ if (value === void 0) return [];
1272
+ return value.map((ext, index) => {
1273
+ if (!Number.isInteger(ext.kind) || ext.kind < 0 || ext.kind > 255) {
1274
+ throw new Error(`extensions[${index}].kind out of u8 range`);
1275
+ }
1276
+ const body = normalizeBytes("bodyHex" in ext ? ext.bodyHex : ext.body, `extensions[${index}].body`);
1277
+ if (body.length > 4294967295) {
1278
+ throw new Error(`extensions[${index}].body exceeds u32 length`);
1279
+ }
1280
+ return { kind: ext.kind, body };
1281
+ });
1282
+ }
1283
+ function encodeExtensionsForHash(extensions) {
1284
+ const chunks = [bigintToBeBytes(BigInt(extensions.length), 4, "extensions.length")];
1285
+ for (const ext of extensions) {
1286
+ chunks.push(
1287
+ Uint8Array.of(ext.kind),
1288
+ bigintToBeBytes(BigInt(ext.body.length), 4, "extension.body.length"),
1289
+ ext.body
1290
+ );
1291
+ }
1292
+ return concatBytes2(...chunks);
1293
+ }
1294
+ function uint256Be(value, label) {
1295
+ if (value < 0n || value >= 1n << 256n) throw new Error(`${label} out of u256 range`);
1296
+ const out = new Uint8Array(32);
1297
+ let v = value;
1298
+ for (let i = 31; i >= 0; i--) {
1299
+ out[i] = Number(v & 0xffn);
1300
+ v >>= 8n;
1301
+ }
1302
+ return out;
1303
+ }
1304
+ function bincodeMlDsa65OpaqueInto(w, raw) {
1305
+ w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
1306
+ w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
1307
+ w.bytes(raw);
1308
+ }
1309
+ function bincodeTypedExtensionInto(w, ext) {
1310
+ w.u8(ext.kind);
1311
+ w.bytes(ext.body);
1312
+ }
1313
+
1314
+ // src/crypto/ml-dsa.ts
1315
+ var ML_DSA_65_SEED_LEN = 32;
1316
+ var ML_DSA_65_SIGNING_KEY_LEN = 4032;
1317
+ var ML_DSA_65_PUBLIC_KEY_LEN = 1952;
1318
+ var ML_DSA_65_SIGNATURE_LEN = 3309;
1319
+ var STANDARD_ALGO_NUMBER_ML_DSA_65 = 1001;
1320
+ var ENUM_VARIANT_INDEX_ML_DSA_65 = 5;
1321
+ var ADDRESS_DERIVATION_DOMAIN = "MONO_ADDRESS_BLAKE3_20_V1";
1322
+ var ADDRESS_DERIVATION_DOMAIN_BYTES = new TextEncoder().encode(ADDRESS_DERIVATION_DOMAIN);
1323
+ var MlDsa65Backend = class _MlDsa65Backend {
1324
+ #secretKey;
1325
+ #publicKey;
1326
+ #addressBytes;
1327
+ constructor(secretKey, publicKey) {
1328
+ this.#secretKey = expectBytes(secretKey, ML_DSA_65_SIGNING_KEY_LEN, "ML-DSA-65 secret key").slice();
1329
+ this.#publicKey = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key").slice();
1330
+ this.#addressBytes = mlDsa65AddressBytes(this.#publicKey);
1331
+ }
1332
+ static fromSeed(seed) {
1333
+ const kp = mlDsa_js.ml_dsa65.keygen(expectBytes(seed, ML_DSA_65_SEED_LEN, "ML-DSA-65 seed"));
1334
+ return new _MlDsa65Backend(kp.secretKey, kp.publicKey);
1335
+ }
1336
+ publicKey() {
1337
+ return this.#publicKey.slice();
1338
+ }
1339
+ addressBytes() {
1340
+ return this.#addressBytes.slice();
1341
+ }
1342
+ getAddress() {
1343
+ return bytesToHex2(this.#addressBytes);
1344
+ }
1345
+ sign(message) {
1346
+ return mlDsa_js.ml_dsa65.sign(message, this.#secretKey, { extraEntropy: false });
1347
+ }
1348
+ signPrehash(digest) {
1349
+ return this.sign(expectBytes(digest, 32, "prehash"));
1350
+ }
1351
+ verify(message, signature) {
1352
+ return mlDsa_js.ml_dsa65.verify(
1353
+ expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature"),
1354
+ message,
1355
+ this.#publicKey
1356
+ );
1357
+ }
1358
+ signEvmTx(fields) {
1359
+ const txHashPreimage = encodeTransactionForHash(fields, 1);
1360
+ const sighash = sha3_js.keccak_256(txHashPreimage);
1361
+ const signature = this.sign(sighash);
1362
+ const wireBytes = bincodeSignedTransaction(fields, signature, this.#publicKey);
1363
+ const txHash = sha3_js.keccak_256(
1364
+ concatBytes2(
1365
+ encodeTransactionForHash(fields, 2),
1366
+ signature,
1367
+ this.#publicKey
1368
+ )
1369
+ );
1370
+ return {
1371
+ wireHex: bytesToHex2(wireBytes).slice(2),
1372
+ wireBytes,
1373
+ sighash,
1374
+ txHash
1375
+ };
1376
+ }
1377
+ };
1378
+ function mlDsa65AddressFromPublicKey(publicKey) {
1379
+ return bytesToHex2(mlDsa65AddressBytes(publicKey));
1380
+ }
1381
+ function mlDsa65AddressBytes(publicKey) {
1382
+ const bytes = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
1383
+ return blake3_js.blake3(concatBytes2(
1384
+ ADDRESS_DERIVATION_DOMAIN_BYTES,
1385
+ bigintToBeBytes(BigInt(STANDARD_ALGO_NUMBER_ML_DSA_65), 2, "ML-DSA-65 algo id"),
1386
+ bytes
1387
+ )).slice(0, 20);
1388
+ }
1389
+
1390
+ // src/crypto/envelope.ts
1391
+ new TextEncoder().encode("protocore/v2/mempool/dkg-mlkem768/1");
1392
+ var MempoolClass = {
1393
+ Transfer: 0,
1394
+ ContractCall: 1,
1395
+ CLOBOp: 3};
1396
+ function bincodeNonceAad(aad) {
1397
+ const w = new BincodeWriter();
1398
+ w.bytes(expectBytes(aad.sender, 20, "NonceAad.sender"));
1399
+ w.u64(aad.nonce);
1400
+ w.u64(aad.chainId);
1401
+ w.enumVariant(aad.class);
1402
+ w.u128(aad.maxFeePerGas);
1403
+ w.u128(aad.maxPriorityFeePerGas);
1404
+ w.u64(aad.gasLimit);
1405
+ return w.toBytes();
1406
+ }
1407
+ function bincodeDecryptHint(hint) {
1408
+ const w = new BincodeWriter();
1409
+ w.u64(hint.epoch);
1410
+ w.u16(hint.scheme);
1411
+ return w.toBytes();
1412
+ }
1413
+ function bincodeEncryptedEnvelope(env) {
1414
+ const w = new BincodeWriter();
1415
+ w.rawBytes(bincodeNonceAad(env.nonceAad));
1416
+ w.bytes(env.ciphertext);
1417
+ w.rawBytes(bincodeDecryptHint(env.decryptionHint));
1418
+ bincodeMlDsa65OpaqueInto2(w, expectBytes(env.senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey"));
1419
+ bincodeMlDsa65OpaqueInto2(w, expectBytes(env.outerSignature, ML_DSA_65_SIGNATURE_LEN, "outerSignature"));
1420
+ w.bytes(expectBytes(env.sender, 20, "sender"));
1421
+ return w.toBytes();
1422
+ }
1423
+ function outerSigDigest(nonceAad, ciphertext, decryptionHint, senderPubkey) {
1424
+ const aad = bincodeNonceAad(nonceAad);
1425
+ const hint = bincodeDecryptHint(decryptionHint);
1426
+ return sha3_js.keccak_256(concatBytes2(aad, ciphertext, hint, expectBytes(senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey")));
1427
+ }
1428
+ function bincodeMlDsa65OpaqueInto2(w, raw) {
1429
+ w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
1430
+ w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
1431
+ w.bytes(raw);
1432
+ }
1433
+ var SEAL_EK_LEN = 1184;
1434
+ var SEAL_KEY_LEN = 32;
1435
+ var SEAL_NONCE_LEN = 12;
1436
+ var SEAL_COMMIT_LEN = 32;
1437
+ var SEAL_SECRET_LEN = 32;
1438
+ var SEAL_SHARE_LEN = 1 + SEAL_SECRET_LEN;
1439
+ var CLUSTER_MLKEM_SHAMIR = 3;
1440
+ var COMMIT_DOMAIN = new TextEncoder().encode("lythiumseal/commit/v1");
1441
+ var KEK_DOMAIN = new TextEncoder().encode("lythiumseal/kek/v1");
1442
+ var NONCE_DOMAIN = new TextEncoder().encode("lythiumseal/nonce/v1");
1443
+ var BODY_AAD_DOMAIN = new TextEncoder().encode("lythiumseal/body/v1");
1444
+ var SHARE_AAD_DOMAIN = new TextEncoder().encode("lythiumseal/share/v1");
1445
+ var ROSTER_DOMAIN = new TextEncoder().encode("lythiumseal/roster/v1");
1446
+ function cryptoRandomSource() {
1447
+ return {
1448
+ fillBytes(dest) {
1449
+ crypto.getRandomValues(dest);
1450
+ }
1451
+ };
1452
+ }
1453
+ function u32le(n) {
1454
+ const out = new Uint8Array(4);
1455
+ out[0] = n & 255;
1456
+ out[1] = n >>> 8 & 255;
1457
+ out[2] = n >>> 16 & 255;
1458
+ out[3] = n >>> 24 & 255;
1459
+ return out;
1460
+ }
1461
+ function u64le(n) {
1462
+ const out = new Uint8Array(8);
1463
+ let v = n;
1464
+ for (let i = 0; i < 8; i++) {
1465
+ out[i] = Number(v & 0xffn);
1466
+ v >>= 8n;
1467
+ }
1468
+ return out;
1469
+ }
1470
+ function framed(field2) {
1471
+ return concatBytes2(u32le(field2.length), field2);
1472
+ }
1473
+ function keyCommitment(key) {
1474
+ return sha3_js.shake256(concatBytes2(framed(COMMIT_DOMAIN), key), { dkLen: SEAL_COMMIT_LEN });
1475
+ }
1476
+ function deriveKek(sharedSecret, domain, clusterId, epoch, opIndex) {
1477
+ const input = concatBytes2(
1478
+ framed(KEK_DOMAIN),
1479
+ framed(sharedSecret),
1480
+ framed(domain),
1481
+ u32le(clusterId),
1482
+ u64le(epoch),
1483
+ Uint8Array.of(opIndex)
1484
+ );
1485
+ return sha3_js.shake256(input, { dkLen: SEAL_KEY_LEN });
1486
+ }
1487
+ function deriveNonce(domain, context) {
1488
+ const input = concatBytes2(framed(NONCE_DOMAIN), framed(domain), framed(context));
1489
+ return sha3_js.shake256(input, { dkLen: SEAL_NONCE_LEN });
1490
+ }
1491
+ function bodyAad(ctx, k, n) {
1492
+ return concatBytes2(
1493
+ BODY_AAD_DOMAIN,
1494
+ u32le(ctx.clusterId),
1495
+ u64le(ctx.epoch),
1496
+ Uint8Array.of(k),
1497
+ Uint8Array.of(n),
1498
+ ctx.rosterHash
1499
+ );
1500
+ }
1501
+ function shareAad(ctx, opIndex) {
1502
+ return concatBytes2(
1503
+ SHARE_AAD_DOMAIN,
1504
+ u32le(ctx.clusterId),
1505
+ u64le(ctx.epoch),
1506
+ Uint8Array.of(opIndex),
1507
+ ctx.rosterHash
1508
+ );
1509
+ }
1510
+ function aeadSeal(key, nonce, plaintext, aad) {
1511
+ const cipher = chacha_js.chacha20poly1305(key, nonce, aad);
1512
+ const ct = cipher.encrypt(plaintext);
1513
+ return { nonce, ct, commitment: keyCommitment(key) };
1514
+ }
1515
+ function gfMul(a, b) {
1516
+ let product = 0;
1517
+ let x = a & 255;
1518
+ let y = b & 255;
1519
+ for (let i = 0; i < 8; i++) {
1520
+ const mask = -(y & 1) & 255;
1521
+ product ^= x & mask;
1522
+ const high = -(x >> 7 & 1) & 255;
1523
+ x = x << 1 & 255;
1524
+ x ^= 27 & high;
1525
+ y >>= 1;
1526
+ }
1527
+ return product & 255;
1528
+ }
1529
+ function polyEval(coeffs, x) {
1530
+ let acc = 0;
1531
+ for (let i = coeffs.length - 1; i >= 0; i--) {
1532
+ acc = gfMul(acc, x) ^ coeffs[i];
1533
+ }
1534
+ return acc & 255;
1535
+ }
1536
+ function shamirSplit(secret, t, n, rng) {
1537
+ const byteCoeffs = [];
1538
+ for (let j = 0; j < SEAL_SECRET_LEN; j++) {
1539
+ const c = new Uint8Array(t);
1540
+ c[0] = secret[j];
1541
+ if (t > 1) {
1542
+ const tail = new Uint8Array(t - 1);
1543
+ rng.fillBytes(tail);
1544
+ c.set(tail, 1);
1545
+ }
1546
+ byteCoeffs.push(c);
1547
+ }
1548
+ const shares = [];
1549
+ for (let k = 0; k < n; k++) {
1550
+ const x = k + 1 & 255;
1551
+ const value = new Uint8Array(SEAL_SECRET_LEN);
1552
+ for (let j = 0; j < SEAL_SECRET_LEN; j++) {
1553
+ value[j] = polyEval(byteCoeffs[j], x);
1554
+ }
1555
+ shares.push({ index: x, value });
1556
+ }
1557
+ return shares;
1558
+ }
1559
+ function shareToBytes(s) {
1560
+ const out = new Uint8Array(SEAL_SHARE_LEN);
1561
+ out[0] = s.index;
1562
+ out.set(s.value, 1);
1563
+ return out;
1564
+ }
1565
+ function sealRosterHash(keccak2562, clusterId, t, n, roster) {
1566
+ const chunks = [ROSTER_DOMAIN, u32le(clusterId), Uint8Array.of(t), Uint8Array.of(n)];
1567
+ for (const { operatorIndex, ek } of roster) {
1568
+ chunks.push(Uint8Array.of(operatorIndex), ek);
1569
+ }
1570
+ return keccak2562(concatBytes2(...chunks));
1571
+ }
1572
+ function encodeSealEnvelope(env) {
1573
+ const chunks = [];
1574
+ chunks.push(u32le(env.clusterId));
1575
+ chunks.push(u64le(env.epoch));
1576
+ chunks.push(expectBytes(env.rosterHash, 32, "rosterHash"));
1577
+ chunks.push(Uint8Array.of(env.t));
1578
+ chunks.push(Uint8Array.of(env.n));
1579
+ pushAeadBody(chunks, env.aeadBody);
1580
+ chunks.push(u64le(BigInt(env.recipients.length)));
1581
+ for (const r of env.recipients) {
1582
+ chunks.push(Uint8Array.of(r.operatorIndex));
1583
+ chunks.push(u64le(BigInt(r.kemCt.length)));
1584
+ chunks.push(r.kemCt);
1585
+ pushAeadBody(chunks, r.wrapped);
1586
+ }
1587
+ return concatBytes2(...chunks);
1588
+ }
1589
+ function pushAeadBody(chunks, body) {
1590
+ chunks.push(expectBytes(body.nonce, SEAL_NONCE_LEN, "aead nonce"));
1591
+ chunks.push(u64le(BigInt(body.ct.length)));
1592
+ chunks.push(body.ct);
1593
+ chunks.push(expectBytes(body.commitment, SEAL_COMMIT_LEN, "aead commitment"));
1594
+ }
1595
+ function sealToCluster(args) {
1596
+ const { plaintext, recipientEks, t, clusterId } = args;
1597
+ const epoch = args.epoch;
1598
+ const rosterHash = expectBytes(args.rosterHash, 32, "rosterHash");
1599
+ const rng = args.rng ?? cryptoRandomSource();
1600
+ const n = recipientEks.length;
1601
+ if (!Number.isInteger(t) || t < 1 || t > n || n < 1 || n > 255) {
1602
+ throw new Error(`invalid threshold/recipient count: t=${t} n=${n}`);
1603
+ }
1604
+ for (let i = 0; i < n; i++) {
1605
+ expectBytes(recipientEks[i], SEAL_EK_LEN, `recipientEks[${i}]`);
1606
+ }
1607
+ const ctx = { clusterId, epoch, rosterHash };
1608
+ const bodyKey = new Uint8Array(SEAL_KEY_LEN);
1609
+ rng.fillBytes(bodyKey);
1610
+ const aad = bodyAad(ctx, t, n);
1611
+ const bodyNonce = deriveNonce(new TextEncoder().encode("body"), aad);
1612
+ const aeadBody = aeadSeal(bodyKey, bodyNonce, plaintext, aad);
1613
+ const shares = shamirSplit(bodyKey, t, n, rng);
1614
+ const recipients = [];
1615
+ for (let i = 0; i < n; i++) {
1616
+ const opIndex = i + 1 & 255;
1617
+ const m = new Uint8Array(32);
1618
+ rng.fillBytes(m);
1619
+ const { cipherText: kemCt, sharedSecret } = mlKem_js.ml_kem768.encapsulate(recipientEks[i], m);
1620
+ const kek = deriveKek(sharedSecret, rosterHash, clusterId, epoch, opIndex);
1621
+ const sAad = shareAad(ctx, opIndex);
1622
+ const wrapNonce = deriveNonce(new TextEncoder().encode("share"), sAad);
1623
+ const wrapped = aeadSeal(kek, wrapNonce, shareToBytes(shares[i]), sAad);
1624
+ recipients.push({ operatorIndex: opIndex, kemCt, wrapped });
1625
+ sharedSecret.fill(0);
1626
+ kek.fill(0);
1627
+ }
1628
+ bodyKey.fill(0);
1629
+ return {
1630
+ clusterId,
1631
+ epoch,
1632
+ rosterHash,
1633
+ t,
1634
+ n,
1635
+ aeadBody,
1636
+ recipients
1637
+ };
1638
+ }
1639
+
1640
+ // src/crypto/seal.ts
1641
+ var CLUSTER_MLKEM_SHAMIR_ALGO = "cluster-mlkem768-shamir";
1642
+ function parseClusterSealKeys(source) {
1643
+ const n = source.roster.length;
1644
+ if (n === 0) {
1645
+ throw new Error("cluster seal roster is empty");
1646
+ }
1647
+ if (source.n !== n) {
1648
+ throw new Error(`cluster seal roster n=${source.n} disagrees with ${n} entries`);
1649
+ }
1650
+ if (!Number.isInteger(source.t) || source.t < 2 || source.t > n) {
1651
+ throw new Error(`cluster seal threshold t=${source.t} out of range 2..=${n}`);
1652
+ }
1653
+ const sorted = [...source.roster].sort((a, b) => a.operatorIndex - b.operatorIndex);
1654
+ const recipientEks = [];
1655
+ const hashInput = [];
1656
+ for (let i = 0; i < n; i++) {
1657
+ const entry = sorted[i];
1658
+ if (entry.operatorIndex !== i + 1) {
1659
+ throw new Error(
1660
+ `cluster seal roster operator indices must be 1..=${n}; got ${entry.operatorIndex} at slot ${i + 1}`
1661
+ );
1662
+ }
1663
+ const ek = expectBytes(hexToBytes2(entry.mlKemEk, `operator ${entry.operatorIndex} mlKemEk`), SEAL_EK_LEN, `operator ${entry.operatorIndex} ek`);
1664
+ recipientEks.push(ek);
1665
+ hashInput.push({ operatorIndex: entry.operatorIndex, ek });
1666
+ }
1667
+ const recomputed = sealRosterHash(keccak256, source.clusterId, source.t, n, hashInput);
1668
+ if (source.rosterHash !== void 0) {
1669
+ const supplied = expectBytes(hexToBytes2(source.rosterHash, "rosterHash"), 32, "rosterHash");
1670
+ if (!bytesEqual(supplied, recomputed)) {
1671
+ throw new Error(
1672
+ `cluster seal roster hash mismatch: source ${bytesToHex2(supplied)} != recomputed ${bytesToHex2(recomputed)} (the roster hash does not commit to this ek set)`
1673
+ );
1674
+ }
1675
+ }
1676
+ return {
1677
+ algo: source.algo ?? CLUSTER_MLKEM_SHAMIR_ALGO,
1678
+ clusterId: source.clusterId,
1679
+ epoch: toBigInt(source.epoch),
1680
+ rosterHash: recomputed,
1681
+ t: source.t,
1682
+ n,
1683
+ recipientEks
1684
+ };
1685
+ }
1686
+ async function sealTransaction(args) {
1687
+ const keys = args.clusterSealKeys;
1688
+ const senderPubkey = expectBytes(args.senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey");
1689
+ const senderAddress = expectBytes(args.senderAddress, 20, "senderAddress");
1690
+ const env = sealToCluster({
1691
+ plaintext: args.signedTxBincode,
1692
+ recipientEks: keys.recipientEks,
1693
+ t: keys.t,
1694
+ clusterId: keys.clusterId,
1695
+ epoch: keys.epoch,
1696
+ rosterHash: keys.rosterHash,
1697
+ rng: args.rng
1698
+ });
1699
+ const ciphertext = encodeSealEnvelope(env);
1700
+ const decryptionHint = { epoch: keys.epoch, scheme: CLUSTER_MLKEM_SHAMIR };
1701
+ const digest = outerSigDigest(args.aad, ciphertext, decryptionHint, senderPubkey);
1702
+ const outerSignature = expectBytes(
1703
+ await args.signOuterDigest(digest),
1704
+ ML_DSA_65_SIGNATURE_LEN,
1705
+ "outerSignature"
1706
+ );
1707
+ const envelope = {
1708
+ nonceAad: args.aad,
1709
+ ciphertext,
1710
+ decryptionHint,
1711
+ senderPubkey,
1712
+ outerSignature,
1713
+ sender: senderAddress
1714
+ };
1715
+ const envelopeWireBytes = bincodeEncryptedEnvelope(envelope);
1716
+ return {
1717
+ envelopeWireHex: `0x${bytesToHex2(envelopeWireBytes).slice(2)}`,
1718
+ envelopeWireBytes,
1719
+ ciphertextBytes: ciphertext.length
1720
+ };
1721
+ }
1722
+ function keccak256(input) {
1723
+ return sha3_js.keccak_256(input);
1724
+ }
1725
+ function toBigInt(value) {
1726
+ if (typeof value === "bigint") return value;
1727
+ return BigInt(value);
1728
+ }
1729
+ function bytesEqual(a, b) {
1730
+ if (a.length !== b.length) return false;
1731
+ for (let i = 0; i < a.length; i++) {
1732
+ if (a[i] !== b[i]) return false;
1733
+ }
1734
+ return true;
1735
+ }
1736
+
1737
+ // src/crypto/submission.ts
1738
+ async function fetchEncryptionKey(client) {
1739
+ const result = await client.call(
1740
+ "lyth_getEncryptionKey",
1741
+ []
1742
+ );
1743
+ return {
1744
+ algo: result.algo ?? "ml-kem-768",
1745
+ epoch: typeof result.epoch === "string" ? BigInt(result.epoch) : BigInt(result.epoch),
1746
+ encapsulationKey: hexToBytes2(result.encapsulationKey, "encapsulationKey")
1747
+ };
1748
+ }
1749
+ var ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE = "private submission requires cluster seal keys; pass clusterSealKeysSource or enable lyth_getClusterSealKeys";
1750
+ async function buildEncryptedSubmission(args) {
1751
+ const signed = args.backend.signEvmTx(args.tx);
1752
+ const clusterSealKeys = await resolveClusterSealKeys(args);
1753
+ const aad = nonceAadForTx(args.tx, args.backend.addressBytes(), args.class);
1754
+ const sealed = await sealTransaction({
1755
+ signedTxBincode: signed.wireBytes,
1756
+ clusterSealKeys,
1757
+ aad,
1758
+ senderAddress: args.backend.addressBytes(),
1759
+ senderPubkey: args.backend.publicKey(),
1760
+ signOuterDigest: (digest) => args.backend.signPrehash(digest)
1761
+ });
1762
+ return {
1763
+ envelopeWireHex: sealed.envelopeWireHex,
1764
+ innerSighashHex: bytesToHex2(signed.sighash),
1765
+ innerTxHashHex: bytesToHex2(signed.txHash),
1766
+ innerWireBytes: signed.wireBytes.length
1767
+ };
1768
+ }
1769
+ async function submitEncryptedEnvelope(client, envelopeWireHex) {
1770
+ return client.call("lyth_submitEncrypted", [envelopeWireHex]);
1771
+ }
1772
+ function buildPlaintextSubmission(args) {
1773
+ const signed = args.backend.signEvmTx(args.tx);
1774
+ return {
1775
+ signedTxWireHex: `0x${signed.wireHex}`,
1776
+ innerTxHashHex: bytesToHex2(signed.txHash),
1777
+ innerSighashHex: bytesToHex2(signed.sighash),
1778
+ innerWireBytes: signed.wireBytes.length
1779
+ };
1780
+ }
1781
+ async function submitPlaintextTransaction(client, signedTxWireHex, expectedTxHashHex) {
1782
+ const returned = await client.call("mesh_submitTx", [signedTxWireHex]);
1783
+ const returnedBytes = hexToBytes2(returned, "mesh_submitTx tx hash");
1784
+ if (returnedBytes.length !== 32) {
1785
+ throw new Error(
1786
+ `mesh_submitTx tx hash must be 32 bytes, got ${returnedBytes.length}`
1787
+ );
1788
+ }
1789
+ const expectedBytes = hexToBytes2(expectedTxHashHex, "expected tx hash");
1790
+ if (!bytesEqual2(returnedBytes, expectedBytes)) {
1791
+ throw new Error(
1792
+ `mesh_submitTx returned tx hash ${bytesToHex2(returnedBytes)} but the locally computed canonical hash is ${bytesToHex2(expectedBytes)}`
1793
+ );
1794
+ }
1795
+ return bytesToHex2(returnedBytes);
1796
+ }
1797
+ function bytesEqual2(a, b) {
1798
+ if (a.length !== b.length) return false;
1799
+ for (let i = 0; i < a.length; i++) {
1800
+ if (a[i] !== b[i]) return false;
1801
+ }
1802
+ return true;
1803
+ }
1804
+ async function resolveClusterSealKeys(args) {
1805
+ if (args.clusterSealKeys !== void 0) return args.clusterSealKeys;
1806
+ if (args.clusterSealKeysSource !== void 0) {
1807
+ return parseClusterSealKeys(args.clusterSealKeysSource);
1808
+ }
1809
+ if (args.client === void 0) {
1810
+ throw new Error(ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE);
1811
+ }
1812
+ const clusterId = args.clusterId ?? 0;
1813
+ const result = await args.client.call(
1814
+ "lyth_getClusterSealKeys",
1815
+ [clusterId]
1816
+ );
1817
+ return parseClusterSealKeys({ ...result, clusterId: result.clusterId ?? clusterId });
1818
+ }
1819
+ function nonceAadForTx(tx, sender, mempoolClass) {
1820
+ return {
1821
+ sender,
1822
+ nonce: parseBigint(tx.nonce, "nonce"),
1823
+ chainId: parseBigint(tx.chainId, "chainId"),
1824
+ class: mempoolClass ?? inferMempoolClass(tx),
1825
+ maxFeePerGas: parseBigint(tx.maxFeePerGas, "maxFeePerGas"),
1826
+ maxPriorityFeePerGas: parseBigint(tx.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
1827
+ gasLimit: parseBigint(tx.gasLimit, "gasLimit")
1828
+ };
1829
+ }
1830
+ function inferMempoolClass(tx) {
1831
+ if (tx.to === null || hasInput(tx.input)) return MempoolClass.ContractCall;
1832
+ return MempoolClass.Transfer;
1833
+ }
1834
+ function hasInput(input) {
1835
+ if (input === void 0) return false;
1836
+ if (typeof input === "string") {
1837
+ const stripped = input.startsWith("0x") || input.startsWith("0X") ? input.slice(2) : input;
1838
+ return stripped.length > 0;
1839
+ }
1840
+ return input.length > 0;
1841
+ }
1842
+
981
1843
  // src/mrv.ts
982
1844
  var MRV_FORMAT_VERSION = 1;
983
1845
  var MRV_DEPLOY_PAYLOAD_VERSION = 1;
@@ -1479,6 +2341,7 @@ async function submitMrvCallNativeTx(client, backend, contractAddress, input, op
1479
2341
  }
1480
2342
  async function submitMrvEncryptedNativeTxGated(client, backend, plan, options) {
1481
2343
  const submission = await buildEncryptedSubmission({
2344
+ backend,
1482
2345
  tx: plan.tx,
1483
2346
  encryptionKey: options.encryptionKey ?? await fetchEncryptionKey(client),
1484
2347
  class: options.class
@@ -1835,22 +2698,6 @@ function concatBytes3(...parts) {
1835
2698
  function isIdentifier(value) {
1836
2699
  return /^[a-z][a-z0-9_]*$/.test(value);
1837
2700
  }
1838
- var ML_DSA_65_PUBLIC_KEY_LEN = 1952;
1839
- var ML_DSA_65_SIGNATURE_LEN = 3309;
1840
- var STANDARD_ALGO_NUMBER_ML_DSA_65 = 1001;
1841
- var ADDRESS_DERIVATION_DOMAIN = "MONO_ADDRESS_BLAKE3_20_V1";
1842
- var ADDRESS_DERIVATION_DOMAIN_BYTES = new TextEncoder().encode(ADDRESS_DERIVATION_DOMAIN);
1843
- function mlDsa65AddressFromPublicKey(publicKey) {
1844
- return bytesToHex2(mlDsa65AddressBytes(publicKey));
1845
- }
1846
- function mlDsa65AddressBytes(publicKey) {
1847
- const bytes = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
1848
- return blake3_js.blake3(concatBytes2(
1849
- ADDRESS_DERIVATION_DOMAIN_BYTES,
1850
- bigintToBeBytes(BigInt(STANDARD_ALGO_NUMBER_ML_DSA_65), 2, "ML-DSA-65 algo id"),
1851
- bytes
1852
- )).slice(0, 20);
1853
- }
1854
2701
 
1855
2702
  // src/registry.ts
1856
2703
  var BLS_PUBLIC_KEY_BYTE_LENGTH = 48;
@@ -1859,8 +2706,8 @@ var TESTNET_69420 = {
1859
2706
  network: "testnet-69420",
1860
2707
  display_name: "Monolythium Testnet",
1861
2708
  description: "Public Monolythium testnet. Testnet state may reset without notice; do not store value on this network.",
1862
- genesis_hash: "0xe67cf82131fc63e335ce61afeae53299283eaa3a692830a618911aa840245031",
1863
- binary_sha: "e4697f9b",
2709
+ genesis_hash: "0x6a2bb3c8a6701bedcddc0447583bb24f34b77310e3aa77c62ca303a453e9f7ba",
2710
+ binary_sha: "c283c75d",
1864
2711
  rpc: [
1865
2712
  {
1866
2713
  url: "http://178.105.12.9:8545",
@@ -3447,11 +4294,15 @@ var RpcClient = class _RpcClient {
3447
4294
  const params = status === void 0 ? operator == null ? [] : [operator] : [operator ?? null, status];
3448
4295
  return this.call("lyth_getClusterResignations", params);
3449
4296
  }
3450
- /** `lyth_getBlsRoundCertificate` — round-advancement BLS aggregate. */
4297
+ /** `lyth_getRoundCertificate` — round-advancement certificate. */
4298
+ async lythGetRoundCertificate(round) {
4299
+ return this.call("lyth_getRoundCertificate", [encodeRpcInteger(round)]);
4300
+ }
4301
+ /** @deprecated Use lythGetRoundCertificate. */
3451
4302
  async lythGetBlsRoundCertificate(round) {
3452
- return this.call("lyth_getBlsRoundCertificate", [encodeRpcInteger(round)]);
4303
+ return this.lythGetRoundCertificate(round);
3453
4304
  }
3454
- /** `lyth_getLeaderCertificate` — leader-vote BLS aggregate for a block ref. */
4305
+ /** `lyth_getLeaderCertificate` — leader-vote certificate for a block ref. */
3455
4306
  async lythGetLeaderCertificate(round, authority, digest) {
3456
4307
  return this.call("lyth_getLeaderCertificate", [encodeRpcInteger(round), authority, digest]);
3457
4308
  }
@@ -4049,7 +4900,9 @@ function normalizeOperatorInfo(value) {
4049
4900
  (v, i) => parseRpcNumber(v, `operator info activeClusterIds[${i}]`)
4050
4901
  ),
4051
4902
  operatorKeyFingerprint: parseStringNullable(row["operatorKeyFingerprint"]),
4052
- blsKeyFingerprint: parseStringNullable(row["blsKeyFingerprint"]),
4903
+ consensusKeyFingerprint: parseStringNullable(
4904
+ row["consensusKeyFingerprint"] ?? row["blsKeyFingerprint"]
4905
+ ),
4053
4906
  lifecycleState: String(row["lifecycleState"]),
4054
4907
  capability: capability && typeof capability === "object" && !Array.isArray(capability) ? capability : {}
4055
4908
  };
@@ -4058,7 +4911,7 @@ function normalizeClusterMember(value, label) {
4058
4911
  const row = expectObject(value, label);
4059
4912
  return {
4060
4913
  operatorId: String(row["operatorId"]),
4061
- blsPubkey: String(row["blsPubkey"]),
4914
+ consensusPubkey: String(row["consensusPubkey"] ?? row["blsPubkey"]),
4062
4915
  state: String(row["state"])
4063
4916
  };
4064
4917
  }
@@ -4124,7 +4977,7 @@ function normalizeOperatorAuthority(value) {
4124
4977
  schemaVersion: parseRpcNumber(row["schemaVersion"], "operator authority schemaVersion"),
4125
4978
  operatorId: String(row["operatorId"]),
4126
4979
  authorityIndex: parseRpcNumber(row["authorityIndex"], "operator authority authorityIndex"),
4127
- blsPubkey: String(row["blsPubkey"]),
4980
+ consensusPubkey: String(row["consensusPubkey"] ?? row["blsPubkey"]),
4128
4981
  active: Boolean(row["active"])
4129
4982
  };
4130
4983
  }
@@ -5870,7 +6723,7 @@ var NO_EVM_COMPACT_INCLUSION_TREE_ALGORITHM = "binary-keccak-receipt-tree";
5870
6723
  var NO_EVM_ARCHIVE_PROOF_SCHEMA = "mono.no_evm_receipt_archive_binding.v1";
5871
6724
  var NO_EVM_ARCHIVE_SIGNATURE_SCHEME = "mono.snapshot.sig.v1";
5872
6725
  var NO_EVM_FINALITY_EVIDENCE_SCHEMA = "mono.no_evm_receipt_finality.v1";
5873
- var NO_EVM_FINALITY_EVIDENCE_SOURCE = "blsRoundCertificate";
6726
+ var NO_EVM_FINALITY_EVIDENCE_SOURCE = "roundCertificate";
5874
6727
  var EMPTY_ROOT_DOMAIN_BYTES = new TextEncoder().encode(NO_EVM_RECEIPTS_ROOT_DOMAIN);
5875
6728
  var LEAF_DOMAIN_BYTES = new TextEncoder().encode(NO_EVM_RECEIPT_LEAF_DOMAIN);
5876
6729
  var NODE_DOMAIN_BYTES = new TextEncoder().encode(NO_EVM_RECEIPT_NODE_DOMAIN);
@@ -6412,7 +7265,7 @@ function verifyBoundedReceiptProof(proof) {
6412
7265
  }
6413
7266
  const actualRoot = computeNoEvmReceiptsRoot(receipts);
6414
7267
  const expectedRoot = decodeHash(proof.receiptsRoot, "receiptsRoot");
6415
- if (!bytesEqual(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
7268
+ if (!bytesEqual3(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
6416
7269
  throw new NoEvmReceiptProofError(
6417
7270
  "receipts_root_mismatch",
6418
7271
  `receiptsRoot mismatch: expected ${proof.receiptsRoot}, computed ${actualRoot}`
@@ -6420,7 +7273,7 @@ function verifyBoundedReceiptProof(proof) {
6420
7273
  }
6421
7274
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
6422
7275
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
6423
- if (!bytesEqual(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7276
+ if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
6424
7277
  throw new NoEvmReceiptProofError(
6425
7278
  "target_receipt_hash_mismatch",
6426
7279
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -6477,7 +7330,7 @@ function verifyCompactReceiptProof(proof) {
6477
7330
  const targetReceipt = decodeHexBytes(targetReceiptBytes, "targetReceiptBytes");
6478
7331
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
6479
7332
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
6480
- if (!bytesEqual(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7333
+ if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
6481
7334
  throw new NoEvmReceiptProofError(
6482
7335
  "target_receipt_hash_mismatch",
6483
7336
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -6488,7 +7341,7 @@ function verifyCompactReceiptProof(proof) {
6488
7341
  compactProof.leafHash,
6489
7342
  "compactInclusionProof.leafHash"
6490
7343
  );
6491
- if (!bytesEqual(expectedLeafHashBytes, actualLeafHashBytes)) {
7344
+ if (!bytesEqual3(expectedLeafHashBytes, actualLeafHashBytes)) {
6492
7345
  throw new NoEvmReceiptProofError(
6493
7346
  "compact_leaf_hash_mismatch",
6494
7347
  `compactInclusionProof.leafHash mismatch: expected ${compactProof.leafHash}, computed ${bytesToHex6(
@@ -6498,7 +7351,7 @@ function verifyCompactReceiptProof(proof) {
6498
7351
  }
6499
7352
  const compactRootBytes = decodeHash(compactProof.root, "compactInclusionProof.root");
6500
7353
  const receiptsRootBytes = decodeHash(proof.receiptsRoot, "receiptsRoot");
6501
- if (!bytesEqual(receiptsRootBytes, compactRootBytes)) {
7354
+ if (!bytesEqual3(receiptsRootBytes, compactRootBytes)) {
6502
7355
  throw new NoEvmReceiptProofError(
6503
7356
  "compact_root_mismatch",
6504
7357
  `receiptsRoot must equal compactInclusionProof.root: receiptsRoot ${proof.receiptsRoot}, compact root ${compactProof.root}`
@@ -6521,7 +7374,7 @@ function verifyCompactReceiptProof(proof) {
6521
7374
  siblingHashes,
6522
7375
  pathSides
6523
7376
  );
6524
- if (!bytesEqual(actualRootBytes, compactRootBytes)) {
7377
+ if (!bytesEqual3(actualRootBytes, compactRootBytes)) {
6525
7378
  throw new NoEvmReceiptProofError(
6526
7379
  "compact_path_mismatch",
6527
7380
  `compact inclusion path mismatch: expected ${compactProof.root}, computed ${bytesToHex6(
@@ -6675,7 +7528,7 @@ function validateCoveringSnapshotObject(snapshot, archiveContentHash, proofBlock
6675
7528
  "archiveProof.coveringSnapshot.checkpointTo must match blockHeight"
6676
7529
  );
6677
7530
  }
6678
- if (!bytesEqual(checkpointContentHash, archiveContentHash)) {
7531
+ if (!bytesEqual3(checkpointContentHash, archiveContentHash)) {
6679
7532
  throw new NoEvmReceiptProofError(
6680
7533
  "invalid_proof_shape",
6681
7534
  "archiveProof.coveringSnapshot.checkpointContentHash must match archiveProof.contentHash"
@@ -6874,7 +7727,7 @@ function validateFinalityBlockReference(blockReference, round, proofBlockHash) {
6874
7727
  );
6875
7728
  if (proofBlockHash !== void 0) {
6876
7729
  const blockHash = decodeHash(proofBlockHash, "blockHash");
6877
- if (!bytesEqual(digest, blockHash)) {
7730
+ if (!bytesEqual3(digest, blockHash)) {
6878
7731
  throw new NoEvmReceiptProofError(
6879
7732
  "invalid_proof_shape",
6880
7733
  "finalityEvidence.blockReference.digest must match blockHash"
@@ -7224,7 +8077,7 @@ function assertHashBytes(value, field2) {
7224
8077
  function isRecord3(value) {
7225
8078
  return typeof value === "object" && value !== null && !Array.isArray(value);
7226
8079
  }
7227
- function bytesEqual(a, b) {
8080
+ function bytesEqual3(a, b) {
7228
8081
  if (a.length !== b.length) return false;
7229
8082
  let diff = 0;
7230
8083
  for (let index = 0; index < a.length; index++) {
@@ -7432,6 +8285,307 @@ function assertWholeNumber(field2, value) {
7432
8285
  throw new Error(`${field2} must be a whole number`);
7433
8286
  }
7434
8287
  }
8288
+ var PQM1_ALGO_TAG_MLDSA65 = 1;
8289
+ var PQM1_VERSION_V1 = 1;
8290
+ var PQM1_PAYLOAD_LEN = 32;
8291
+ var PQM1_V1_MNEMONIC_WORDS = 24;
8292
+ var PQM1_V1_MLDSA65_DOMAIN_TAG = "monolythium.pqm1.v1.mldsa65";
8293
+ var Pqm1Error = class extends Error {
8294
+ constructor(kind, message) {
8295
+ super(message);
8296
+ this.kind = kind;
8297
+ this.name = "Pqm1Error";
8298
+ }
8299
+ kind;
8300
+ };
8301
+ var DOMAIN_BYTES = new TextEncoder().encode(PQM1_V1_MLDSA65_DOMAIN_TAG);
8302
+ function normalizeMnemonic(mnemonic) {
8303
+ return mnemonic.trim().toLowerCase().replace(/\s+/g, " ");
8304
+ }
8305
+ function ensureSupportedPayload(bytes) {
8306
+ if (bytes.length !== PQM1_PAYLOAD_LEN) {
8307
+ throw new Pqm1Error("badPayloadLength", `PQM-1 payload must be ${PQM1_PAYLOAD_LEN} bytes, got ${bytes.length}`);
8308
+ }
8309
+ if (bytes[0] !== PQM1_ALGO_TAG_MLDSA65) {
8310
+ throw new Pqm1Error("unsupportedAlgorithm", `unsupported PQM-1 algorithm tag 0x${bytes[0].toString(16).padStart(2, "0")}`);
8311
+ }
8312
+ if (bytes[1] !== PQM1_VERSION_V1) {
8313
+ throw new Pqm1Error("unsupportedVersion", `unsupported PQM-1 version 0x${bytes[1].toString(16).padStart(2, "0")}`);
8314
+ }
8315
+ }
8316
+ function parsePqm1Payload(payload) {
8317
+ const bytes = expectBytes(payload, PQM1_PAYLOAD_LEN, "PQM-1 payload").slice();
8318
+ ensureSupportedPayload(bytes);
8319
+ return {
8320
+ algoTag: PQM1_ALGO_TAG_MLDSA65,
8321
+ version: PQM1_VERSION_V1,
8322
+ entropy: bytes.slice(2),
8323
+ bytes
8324
+ };
8325
+ }
8326
+ function pqm1MnemonicToPayload(mnemonic) {
8327
+ const normalized = normalizeMnemonic(mnemonic);
8328
+ const words = normalized.length === 0 ? [] : normalized.split(" ");
8329
+ if (words.length !== PQM1_V1_MNEMONIC_WORDS) {
8330
+ throw new Pqm1Error("badWordCount", `PQM-1 mnemonic must be ${PQM1_V1_MNEMONIC_WORDS} words, got ${words.length}`);
8331
+ }
8332
+ let payload;
8333
+ try {
8334
+ payload = bip39.mnemonicToEntropy(normalized, english_js.wordlist);
8335
+ } catch (e) {
8336
+ throw new Pqm1Error("bip39Decode", `invalid PQM-1 mnemonic: ${e.message}`);
8337
+ }
8338
+ return parsePqm1Payload(payload);
8339
+ }
8340
+ function derivePqm1MlDsa65SeedFromPayload(payload) {
8341
+ const parsed = parsePqm1Payload(payload);
8342
+ return sha3_js.shake256(concatBytes2(DOMAIN_BYTES, parsed.bytes), { dkLen: ML_DSA_65_SEED_LEN });
8343
+ }
8344
+ function pqm1MnemonicToMlDsa65Seed(mnemonic) {
8345
+ return derivePqm1MlDsa65SeedFromPayload(pqm1MnemonicToPayload(mnemonic).bytes);
8346
+ }
8347
+ function pqm1MnemonicToMlDsa65Backend(mnemonic) {
8348
+ return MlDsa65Backend.fromSeed(pqm1MnemonicToMlDsa65Seed(mnemonic));
8349
+ }
8350
+
8351
+ // src/cluster-join.ts
8352
+ var DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT = REGISTRY_DEFAULT_EXECUTION_UNIT_LIMIT;
8353
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
8354
+ var MAX_UINT32 = (1n << 32n) - 1n;
8355
+ function deriveClusterJoinOperatorId(operatorPubkey) {
8356
+ return bytesToHex2(blake3_js.blake3(normalizeConsensusPubkey(operatorPubkey, "operatorPubkey")));
8357
+ }
8358
+ function clusterJoinRequestExists(view) {
8359
+ return view.status !== "none" || view.owner.toLowerCase() !== ZERO_ADDRESS || view.bondLythoshi !== 0n;
8360
+ }
8361
+ async function readClusterJoinRequest(client, args) {
8362
+ const clusterId = parseUint32(args.clusterId, "clusterId");
8363
+ const operatorId = normalizeOperatorId(args.operatorId);
8364
+ const envelope = await client.call("lyth_getClusterJoinRequest", [
8365
+ Number(clusterId),
8366
+ operatorId
8367
+ ]);
8368
+ return adaptNativeClusterJoinRequest(envelope.request);
8369
+ }
8370
+ async function preflightClusterJoinRequest(client, args) {
8371
+ try {
8372
+ return await readClusterJoinRequest(client, args);
8373
+ } catch (cause) {
8374
+ throw new Error(
8375
+ `CJ-1 lyth_getClusterJoinRequest is not exposed or failed on the connected chain: ${errorMessage(cause)}`
8376
+ );
8377
+ }
8378
+ }
8379
+ async function previewRequestClusterJoin(client, args) {
8380
+ const clusterId = parseUint32(args.clusterId, "clusterId");
8381
+ try {
8382
+ return await client.call("lyth_previewRequestClusterJoin", [{
8383
+ from: args.from,
8384
+ clusterId: Number(clusterId),
8385
+ operatorPubkey: bytesToHex2(normalizeConsensusPubkey(args.operatorPubkey, "operatorPubkey")),
8386
+ bondLythoshi: parseU256(args.bondLythoshi, "bondLythoshi").toString(10)
8387
+ }]);
8388
+ } catch (cause) {
8389
+ throw new Error(
8390
+ `CJ-1 request preview is not exposed or failed on the connected chain: ${errorMessage(cause)}`
8391
+ );
8392
+ }
8393
+ }
8394
+ async function previewVoteClusterAdmit(client, args) {
8395
+ const clusterId = parseUint32(args.clusterId, "clusterId");
8396
+ try {
8397
+ return await client.call("lyth_previewVoteClusterAdmit", [{
8398
+ from: args.from,
8399
+ clusterId: Number(clusterId),
8400
+ operatorId: normalizeOperatorId(args.operatorId),
8401
+ voterPubkey: bytesToHex2(normalizeConsensusPubkey(args.voterPubkey, "voterPubkey"))
8402
+ }]);
8403
+ } catch (cause) {
8404
+ throw new Error(
8405
+ `CJ-1 admit-vote preview is not exposed or failed on the connected chain: ${errorMessage(cause)}`
8406
+ );
8407
+ }
8408
+ }
8409
+ function resolveClusterJoinExecutionFee(quote, options = {}) {
8410
+ const quoted = parseBigint(quote.executionUnitPriceLythoshi, "executionUnitPriceLythoshi");
8411
+ const floor = options.minPriceLythoshi === void 0 ? MIN_EXECUTION_UNIT_PRICE_LYTHOSHI : parseBigint(options.minPriceLythoshi, "minPriceLythoshi");
8412
+ const multiplier = options.safetyMultiplier === void 0 ? EXECUTION_UNIT_PRICE_SAFETY_MULTIPLIER : parseBigint(options.safetyMultiplier, "safetyMultiplier");
8413
+ if (multiplier <= 0n) throw new Error("safetyMultiplier must be greater than zero");
8414
+ const base = quoted > floor ? quoted : floor;
8415
+ const maxFeePerGas = base * multiplier;
8416
+ const tip = options.priorityTipLythoshi === void 0 ? maxFeePerGas : clampPriorityTip(options.priorityTipLythoshi, maxFeePerGas);
8417
+ return {
8418
+ maxFeePerGas,
8419
+ maxPriorityFeePerGas: tip,
8420
+ gasLimit: options.executionUnitLimit ?? DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT
8421
+ };
8422
+ }
8423
+ function buildRequestClusterJoinTxFields(args) {
8424
+ return {
8425
+ chainId: args.chainId,
8426
+ nonce: args.nonce,
8427
+ maxFeePerGas: parseBigint(args.fee.maxFeePerGas, "maxFeePerGas"),
8428
+ maxPriorityFeePerGas: parseBigint(args.fee.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
8429
+ gasLimit: parseBigint(
8430
+ args.fee.gasLimit ?? DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT,
8431
+ "gasLimit"
8432
+ ),
8433
+ to: nodeRegistryAddressHex(),
8434
+ value: parseU256(args.bondLythoshi, "bondLythoshi"),
8435
+ input: encodeRequestClusterJoinCalldata({
8436
+ clusterId: args.clusterId,
8437
+ operatorPubkey: normalizeConsensusPubkey(args.operatorPubkey, "operatorPubkey")
8438
+ })
8439
+ };
8440
+ }
8441
+ function buildVoteClusterAdmitTxFields(args) {
8442
+ return {
8443
+ chainId: args.chainId,
8444
+ nonce: args.nonce,
8445
+ maxFeePerGas: parseBigint(args.fee.maxFeePerGas, "maxFeePerGas"),
8446
+ maxPriorityFeePerGas: parseBigint(args.fee.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
8447
+ gasLimit: parseBigint(
8448
+ args.fee.gasLimit ?? DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT,
8449
+ "gasLimit"
8450
+ ),
8451
+ to: nodeRegistryAddressHex(),
8452
+ value: 0n,
8453
+ input: encodeVoteClusterAdmitCalldata({
8454
+ clusterId: args.clusterId,
8455
+ operatorId: normalizeOperatorId(args.operatorId),
8456
+ voterPubkey: normalizeConsensusPubkey(args.voterPubkey, "voterPubkey")
8457
+ })
8458
+ };
8459
+ }
8460
+ async function submitRequestClusterJoin(args) {
8461
+ const clusterId = parseUint32(args.clusterId, "clusterId");
8462
+ const operatorPubkey = normalizeConsensusPubkey(args.operatorPubkey, "operatorPubkey");
8463
+ const operatorIdHex = deriveClusterJoinOperatorId(operatorPubkey);
8464
+ const backend = pqm1MnemonicToMlDsa65Backend(args.mnemonic);
8465
+ const senderAddress = addressToTypedBech32("user", backend.addressBytes());
8466
+ const preview = await previewRequestClusterJoin(args.client, {
8467
+ from: senderAddress,
8468
+ clusterId,
8469
+ operatorPubkey,
8470
+ bondLythoshi: args.bondLythoshi
8471
+ });
8472
+ assertPreviewOk("requestClusterJoin", preview);
8473
+ const [chainId, nonce, quote] = await Promise.all([
8474
+ args.client.ethChainId(),
8475
+ args.client.lythGetTransactionCount(senderAddress),
8476
+ args.client.lythExecutionUnitPrice()
8477
+ ]);
8478
+ const tx = buildRequestClusterJoinTxFields({
8479
+ chainId,
8480
+ nonce,
8481
+ fee: resolveClusterJoinExecutionFee(quote, args),
8482
+ clusterId,
8483
+ operatorPubkey,
8484
+ bondLythoshi: args.bondLythoshi
8485
+ });
8486
+ return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex);
8487
+ }
8488
+ async function submitVoteClusterAdmit(args) {
8489
+ const clusterId = parseUint32(args.clusterId, "clusterId");
8490
+ const operatorIdHex = normalizeOperatorId(args.operatorId);
8491
+ const backend = pqm1MnemonicToMlDsa65Backend(args.mnemonic);
8492
+ const senderAddress = addressToTypedBech32("user", backend.addressBytes());
8493
+ const preview = await previewVoteClusterAdmit(args.client, {
8494
+ from: senderAddress,
8495
+ clusterId,
8496
+ operatorId: operatorIdHex,
8497
+ voterPubkey: args.voterPubkey
8498
+ });
8499
+ assertPreviewOk("voteClusterAdmit", preview);
8500
+ const [chainId, nonce, quote] = await Promise.all([
8501
+ args.client.ethChainId(),
8502
+ args.client.lythGetTransactionCount(senderAddress),
8503
+ args.client.lythExecutionUnitPrice()
8504
+ ]);
8505
+ const tx = buildVoteClusterAdmitTxFields({
8506
+ chainId,
8507
+ nonce,
8508
+ fee: resolveClusterJoinExecutionFee(quote, args),
8509
+ clusterId,
8510
+ operatorId: operatorIdHex,
8511
+ voterPubkey: args.voterPubkey
8512
+ });
8513
+ return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex);
8514
+ }
8515
+ async function submitClusterJoinTx(client, backend, tx, clusterId, operatorIdHex) {
8516
+ const plaintext = buildPlaintextSubmission({ backend, tx });
8517
+ const txHash = await submitPlaintextTransaction(
8518
+ client,
8519
+ plaintext.signedTxWireHex,
8520
+ plaintext.innerTxHashHex
8521
+ );
8522
+ return {
8523
+ txHash,
8524
+ clusterId: clusterId.toString(10),
8525
+ operatorIdHex,
8526
+ innerSighashHex: plaintext.innerSighashHex,
8527
+ signedTxWireBytes: plaintext.innerWireBytes
8528
+ };
8529
+ }
8530
+ function adaptNativeClusterJoinRequest(request) {
8531
+ return {
8532
+ owner: request.owner ?? ZERO_ADDRESS,
8533
+ requestEpoch: parseBigint(request.requestEpoch, "requestEpoch"),
8534
+ requestNonce: request.requestNonce === void 0 ? void 0 : parseBigint(request.requestNonce, "requestNonce"),
8535
+ snapshotThreshold: request.snapshotThreshold,
8536
+ snapshotN: request.snapshotN,
8537
+ voteCount: request.voteCount,
8538
+ statusCode: request.statusCode,
8539
+ status: clusterJoinStatus(request.status),
8540
+ bondLythoshi: parseBigint(request.bondLythoshi, "bondLythoshi"),
8541
+ sealRosterPending: request.sealRosterPending
8542
+ };
8543
+ }
8544
+ function clusterJoinStatus(status) {
8545
+ switch (status) {
8546
+ case "none":
8547
+ case "open":
8548
+ case "admitted":
8549
+ case "cancelled":
8550
+ case "expired":
8551
+ return status;
8552
+ default:
8553
+ return "unknown";
8554
+ }
8555
+ }
8556
+ function previewError(action, preview) {
8557
+ const reason = preview.reason ? `: ${preview.reason}` : "";
8558
+ const message = preview.message ? ` (${preview.message})` : "";
8559
+ return new Error(`${action} preview rejected${reason}${message}`);
8560
+ }
8561
+ function assertPreviewOk(action, preview) {
8562
+ if (!preview.ok) throw previewError(action, preview);
8563
+ }
8564
+ function normalizeConsensusPubkey(value, label) {
8565
+ const bytes = typeof value === "string" ? hexToBytes2(value, label) : value;
8566
+ return expectBytes(bytes, NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES, label).slice();
8567
+ }
8568
+ function normalizeOperatorId(value) {
8569
+ const bytes = typeof value === "string" ? hexToBytes2(value, "operatorId") : value;
8570
+ return bytesToHex2(expectBytes(bytes, 32, "operatorId"));
8571
+ }
8572
+ function parseUint32(value, label) {
8573
+ const parsed = parseBigint(value, label);
8574
+ if (parsed < 0n || parsed > MAX_UINT32) {
8575
+ throw new Error(`${label} out of 32-bit range`);
8576
+ }
8577
+ return parsed;
8578
+ }
8579
+ function parseU256(value, label) {
8580
+ const parsed = parseBigint(value, label);
8581
+ if (parsed < 0n || parsed >= 1n << 256n) {
8582
+ throw new Error(`${label} out of 256-bit range`);
8583
+ }
8584
+ return parsed;
8585
+ }
8586
+ function errorMessage(cause) {
8587
+ return cause instanceof Error ? cause.message : String(cause);
8588
+ }
7435
8589
  var ORACLE_EVENT_SIGS = {
7436
8590
  oracleRoundFinalized: "OracleRoundFinalized(bytes32,uint64,uint256,uint64,uint32)",
7437
8591
  observationSubmitted: "ObservationSubmitted(bytes32,uint64,address,uint256,uint64)",
@@ -8400,11 +9554,6 @@ function wordToBigint(word) {
8400
9554
  }
8401
9555
  return out;
8402
9556
  }
8403
- new TextEncoder().encode("protocore/v2/mempool/dkg-mlkem768/1");
8404
- var MempoolClass = {
8405
- CLOBOp: 3};
8406
-
8407
- // src/market-actions.ts
8408
9557
  var CLOB_MARKET_ID_DOMAIN_TAG = 193;
8409
9558
  var NATIVE_MARKET_MODULE_ADDRESS_BYTES = "0x4d41524b45545f4e41544956455f4d4f445f5631";
8410
9559
  var NATIVE_MARKET_MODULE_ADDRESS = addressToTypedBech32(
@@ -9735,7 +10884,7 @@ var MONOLYTHIUM_NETWORKS = {
9735
10884
  };
9736
10885
 
9737
10886
  // src/index.ts
9738
- var version = "0.3.16";
10887
+ var version = "0.4.2";
9739
10888
 
9740
10889
  exports.ADDRESS_HRP = ADDRESS_HRP;
9741
10890
  exports.ADDRESS_KIND_HRPS = ADDRESS_KIND_HRPS;
@@ -9755,6 +10904,7 @@ exports.CHAIN_REGISTRY_RAW_BASE = CHAIN_REGISTRY_RAW_BASE;
9755
10904
  exports.CLOB_MARKET_ID_DOMAIN_TAG = CLOB_MARKET_ID_DOMAIN_TAG;
9756
10905
  exports.CLOB_SELECTORS = CLOB_SELECTORS;
9757
10906
  exports.CLUSTER_FORMED_EVENT_SIG = CLUSTER_FORMED_EVENT_SIG;
10907
+ exports.DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT = DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT;
9758
10908
  exports.DELEGATION_REVERT_TAGS = DELEGATION_REVERT_TAGS;
9759
10909
  exports.DELEGATION_SELECTORS = DELEGATION_SELECTORS;
9760
10910
  exports.DIVERSITY_SCORE_MAX = DIVERSITY_SCORE_MAX;
@@ -9809,9 +10959,20 @@ exports.NATIVE_MARKET_ORDER_BOOK_STREAM_TOPIC = NATIVE_MARKET_ORDER_BOOK_STREAM_
9809
10959
  exports.NODE_REGISTRY_BLS_PUBKEY_BYTES = NODE_REGISTRY_BLS_PUBKEY_BYTES;
9810
10960
  exports.NODE_REGISTRY_CAPABILITIES = NODE_REGISTRY_CAPABILITIES;
9811
10961
  exports.NODE_REGISTRY_CAPABILITY_MASK = NODE_REGISTRY_CAPABILITY_MASK;
10962
+ exports.NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES = NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES;
10963
+ exports.NODE_REGISTRY_CONSENSUS_POP_BYTES = NODE_REGISTRY_CONSENSUS_POP_BYTES;
10964
+ exports.NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES = NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES;
10965
+ exports.NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES = NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES;
10966
+ exports.NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES = NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES;
9812
10967
  exports.NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS = NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS;
9813
10968
  exports.NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS = NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS;
9814
10969
  exports.NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES = NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES;
10970
+ exports.NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT = NODE_REGISTRY_FORM_CLUSTER_ACTIVE_COUNT;
10971
+ exports.NODE_REGISTRY_FORM_CLUSTER_MEMBER_COUNT = NODE_REGISTRY_FORM_CLUSTER_MEMBER_COUNT;
10972
+ exports.NODE_REGISTRY_FORM_CLUSTER_MESSAGE_DOMAIN = NODE_REGISTRY_FORM_CLUSTER_MESSAGE_DOMAIN;
10973
+ exports.NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT = NODE_REGISTRY_FORM_CLUSTER_STANDBY_COUNT;
10974
+ exports.NODE_REGISTRY_FORM_CLUSTER_THRESHOLD = NODE_REGISTRY_FORM_CLUSTER_THRESHOLD;
10975
+ exports.NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES = NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES;
9815
10976
  exports.NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID = NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID;
9816
10977
  exports.NODE_REGISTRY_PUBLIC_SERVICE_MASK = NODE_REGISTRY_PUBLIC_SERVICE_MASK;
9817
10978
  exports.NODE_REGISTRY_SELECTORS = NODE_REGISTRY_SELECTORS;
@@ -9929,6 +11090,8 @@ exports.buildPlaceLimitOrderViaPlan = buildPlaceLimitOrderViaPlan;
9929
11090
  exports.buildPlaceSpotLimitOrderPlan = buildPlaceSpotLimitOrderPlan;
9930
11091
  exports.buildPlaceSpotMarketOrderExPlan = buildPlaceSpotMarketOrderExPlan;
9931
11092
  exports.buildPlaceSpotMarketOrderPlan = buildPlaceSpotMarketOrderPlan;
11093
+ exports.buildRequestClusterJoinTxFields = buildRequestClusterJoinTxFields;
11094
+ exports.buildVoteClusterAdmitTxFields = buildVoteClusterAdmitTxFields;
9932
11095
  exports.categoryRoot = categoryRoot;
9933
11096
  exports.checkMrvFeeDisplayConformance = checkMrvFeeDisplayConformance;
9934
11097
  exports.checkMrvStructuredFeeConformance = checkMrvStructuredFeeConformance;
@@ -9936,6 +11099,7 @@ exports.checkNativeDevkitCompatibility = checkNativeDevkitCompatibility;
9936
11099
  exports.clampPriorityTip = clampPriorityTip;
9937
11100
  exports.clobAddressHex = clobAddressHex;
9938
11101
  exports.clusterApyPercent = clusterApyPercent;
11102
+ exports.clusterJoinRequestExists = clusterJoinRequestExists;
9939
11103
  exports.compareNativeDevVersions = compareNativeDevVersions;
9940
11104
  exports.composeClaimBoundMessage = composeClaimBoundMessage;
9941
11105
  exports.computeNoEvmDacFinalityMessage = computeNoEvmDacFinalityMessage;
@@ -9947,6 +11111,7 @@ exports.computeQuoteLiquidity = computeQuoteLiquidity;
9947
11111
  exports.consumeNativeEvents = consumeNativeEvents;
9948
11112
  exports.decodeClusterDiversity = decodeClusterDiversity;
9949
11113
  exports.decodeClusterFormedEvent = decodeClusterFormedEvent;
11114
+ exports.decodeClusterJoinRequest = decodeClusterJoinRequest;
9950
11115
  exports.decodeHasPubkeyReturn = decodeHasPubkeyReturn;
9951
11116
  exports.decodeLookupPubkeyReturn = decodeLookupPubkeyReturn;
9952
11117
  exports.decodeNativeAgentStateResponse = decodeNativeAgentStateResponse;
@@ -9962,6 +11127,7 @@ exports.delegationAddressHex = delegationAddressHex;
9962
11127
  exports.denyRootFor = denyRootFor;
9963
11128
  exports.deriveClobMarketId = deriveClobMarketId;
9964
11129
  exports.deriveClusterAnchorAddress = deriveClusterAnchorAddress;
11130
+ exports.deriveClusterJoinOperatorId = deriveClusterJoinOperatorId;
9965
11131
  exports.deriveFeedId = deriveFeedId;
9966
11132
  exports.deriveMrvContractAddress = deriveMrvContractAddress;
9967
11133
  exports.deriveNativeSpotMarketId = deriveNativeSpotMarketId;
@@ -9971,6 +11137,7 @@ exports.encodeAttestDkgReshareCalldata = encodeAttestDkgReshareCalldata;
9971
11137
  exports.encodeBlockSelector = encodeBlockSelector;
9972
11138
  exports.encodeBridgeChallengeCalldata = encodeBridgeChallengeCalldata;
9973
11139
  exports.encodeBridgeClaimCalldata = encodeBridgeClaimCalldata;
11140
+ exports.encodeCancelClusterJoinCalldata = encodeCancelClusterJoinCalldata;
9974
11141
  exports.encodeCancelOrderCalldata = encodeCancelOrderCalldata;
9975
11142
  exports.encodeCancelPendingChangeCalldata = encodeCancelPendingChangeCalldata;
9976
11143
  exports.encodeClaimCalldata = encodeClaimCalldata;
@@ -9981,6 +11148,9 @@ exports.encodeCreateRequestCanonical = encodeCreateRequestCanonical;
9981
11148
  exports.encodeDelegateCalldata = encodeDelegateCalldata;
9982
11149
  exports.encodeDisableCalldata = encodeDisableCalldata;
9983
11150
  exports.encodeEnableCalldata = encodeEnableCalldata;
11151
+ exports.encodeExpireClusterJoinCalldata = encodeExpireClusterJoinCalldata;
11152
+ exports.encodeFormClusterCalldata = encodeFormClusterCalldata;
11153
+ exports.encodeGetClusterJoinRequestCalldata = encodeGetClusterJoinRequestCalldata;
9984
11154
  exports.encodeHasPubkeyCalldata = encodeHasPubkeyCalldata;
9985
11155
  exports.encodeLockBridgeConfigCalldata = encodeLockBridgeConfigCalldata;
9986
11156
  exports.encodeLookupPubkeyCalldata = encodeLookupPubkeyCalldata;
@@ -10041,6 +11211,7 @@ exports.encodeRecoverOperatorNodeCalldata = encodeRecoverOperatorNodeCalldata;
10041
11211
  exports.encodeRedelegateCalldata = encodeRedelegateCalldata;
10042
11212
  exports.encodeRegisterPubkeyCalldata = encodeRegisterPubkeyCalldata;
10043
11213
  exports.encodeReportServiceProbeCalldata = encodeReportServiceProbeCalldata;
11214
+ exports.encodeRequestClusterJoinCalldata = encodeRequestClusterJoinCalldata;
10044
11215
  exports.encodeSetAutoCompoundCalldata = encodeSetAutoCompoundCalldata;
10045
11216
  exports.encodeSetBridgeResumeCooldownCalldata = encodeSetBridgeResumeCooldownCalldata;
10046
11217
  exports.encodeSetBridgeRouteFinalityCalldata = encodeSetBridgeRouteFinalityCalldata;
@@ -10052,9 +11223,12 @@ exports.encodeSetTickSizeCalldata = encodeSetTickSizeCalldata;
10052
11223
  exports.encodeSubmitBridgeProofCalldata = encodeSubmitBridgeProofCalldata;
10053
11224
  exports.encodeSubmitPendingChangeCalldata = encodeSubmitPendingChangeCalldata;
10054
11225
  exports.encodeUndelegateCalldata = encodeUndelegateCalldata;
11226
+ exports.encodeVoteClusterAdmitCalldata = encodeVoteClusterAdmitCalldata;
10055
11227
  exports.exportBridgeRouteCatalogueJson = exportBridgeRouteCatalogueJson;
10056
11228
  exports.fetchChainInfoLatest = fetchChainInfoLatest;
10057
11229
  exports.fetchChainRegistryLatest = fetchChainRegistryLatest;
11230
+ exports.formClusterMessage = formClusterMessage;
11231
+ exports.formClusterMessageHex = formClusterMessageHex;
10058
11232
  exports.formatLyth = formatLyth;
10059
11233
  exports.formatLythoshi = formatLythoshi;
10060
11234
  exports.formatNativeReceiptFeeDisplay = formatNativeReceiptFeeDisplay;
@@ -10112,13 +11286,18 @@ exports.parseNameCategory = parseNameCategory;
10112
11286
  exports.parseNativeDecodedEvent = parseNativeDecodedEvent;
10113
11287
  exports.parseQuantity = parseQuantity;
10114
11288
  exports.parseQuantityBig = parseQuantityBig;
11289
+ exports.preflightClusterJoinRequest = preflightClusterJoinRequest;
11290
+ exports.previewRequestClusterJoin = previewRequestClusterJoin;
11291
+ exports.previewVoteClusterAdmit = previewVoteClusterAdmit;
10115
11292
  exports.proverMarketStateFromByte = proverMarketStateFromByte;
10116
11293
  exports.pubkeyRegistryAddressHex = pubkeyRegistryAddressHex;
10117
11294
  exports.quoteOperatorFee = quoteOperatorFee;
10118
11295
  exports.rankBridgeRoutes = rankBridgeRoutes;
10119
11296
  exports.rankMarketsByVolume = rankMarketsByVolume;
11297
+ exports.readClusterJoinRequest = readClusterJoinRequest;
10120
11298
  exports.requestSighash = requestSighash;
10121
11299
  exports.requireTypedAddress = requireTypedAddress;
11300
+ exports.resolveClusterJoinExecutionFee = resolveClusterJoinExecutionFee;
10122
11301
  exports.resolveExecutionFee = resolveExecutionFee;
10123
11302
  exports.resolveMaxExecutionUnitPrice = resolveMaxExecutionUnitPrice;
10124
11303
  exports.resolveRegistryExecutionFee = resolveRegistryExecutionFee;
@@ -10130,7 +11309,9 @@ exports.spendingPolicyAddressHex = spendingPolicyAddressHex;
10130
11309
  exports.submitMrvCallNativeTx = submitMrvCallNativeTx;
10131
11310
  exports.submitMrvDeployNativeTx = submitMrvDeployNativeTx;
10132
11311
  exports.submitMrvDeployPayloadNativeTx = submitMrvDeployPayloadNativeTx;
11312
+ exports.submitRequestClusterJoin = submitRequestClusterJoin;
10133
11313
  exports.submitSighash = submitSighash;
11314
+ exports.submitVoteClusterAdmit = submitVoteClusterAdmit;
10134
11315
  exports.transactionFeeExposure = transactionFeeExposure;
10135
11316
  exports.typedBech32ToAddress = typedBech32ToAddress;
10136
11317
  exports.validateAddress = validateAddress;