@monolythium/core-sdk 0.4.1 → 0.4.3

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,13 +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
10
  var bip39 = require('@scure/bip39');
8
11
  var english_js = require('@scure/bip39/wordlists/english.js');
9
- require('@noble/post-quantum/ml-kem.js');
10
- require('@noble/ciphers/chacha.js');
11
- require('@noble/hashes/utils.js');
12
12
 
13
13
  // src/error.ts
14
14
  var SdkError = class _SdkError extends Error {
@@ -449,17 +449,26 @@ var NODE_REGISTRY_SELECTORS = {
449
449
  /** `expireClusterJoin(uint32,bytes32)` — CJ-1 public reaper/refund. */
450
450
  expireClusterJoin: "0x" + selectorHex("expireClusterJoin(uint32,bytes32)"),
451
451
  /** `getClusterJoinRequest(uint32,bytes32)` — CJ-1 request status view. */
452
- getClusterJoinRequest: "0x" + selectorHex("getClusterJoinRequest(uint32,bytes32)")
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)")
453
455
  };
454
- var NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES = 48;
455
- var NODE_REGISTRY_BLS_PUBKEY_BYTES = NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES;
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;
456
459
  var NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES = 1952;
460
+ var NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES = 3309;
457
461
  var NODE_REGISTRY_CONSENSUS_POP_BYTES = 3309;
458
462
  var NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES = 96;
459
463
  var NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES = NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES;
460
464
  var NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS = 5;
461
465
  var NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS = 7;
462
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";
463
472
  var PENDING_CHANGE_KIND_CODES = {
464
473
  add: 1,
465
474
  remove: 2,
@@ -695,6 +704,70 @@ function encodeGetClusterJoinRequestCalldata(args) {
695
704
  )
696
705
  );
697
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
+ }
698
771
  function decodeClusterJoinRequest(returnData) {
699
772
  const bytes = expectLength2(toBytes(returnData), 8 * 32, "clusterJoinRequest");
700
773
  const word = (i) => bytes.slice(i * 32, (i + 1) * 32);
@@ -798,7 +871,7 @@ function deriveClusterAnchorAddress(roster, threshold) {
798
871
  throw new NodeRegistryError("threshold must be a uint16");
799
872
  }
800
873
  const members = roster.map(
801
- (m, i) => expectLength2(toBytes(m), NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES, `roster[${i}]`)
874
+ (m, i) => expectLength2(toBytes(m), NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES, `roster[${i}]`)
802
875
  );
803
876
  members.sort(compareBytes);
804
877
  const parts = [
@@ -863,6 +936,16 @@ function u64BeBytes(value) {
863
936
  }
864
937
  return out;
865
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
+ }
866
949
  function compareBytes(a, b) {
867
950
  const len = Math.min(a.length, b.length);
868
951
  for (let i = 0; i < len; i++) {
@@ -1059,59 +1142,6 @@ function parseBigint(value, label) {
1059
1142
  return BigInt(value);
1060
1143
  }
1061
1144
 
1062
- // src/crypto/submission.ts
1063
- async function fetchEncryptionKey(client) {
1064
- const result = await client.call(
1065
- "lyth_getEncryptionKey",
1066
- []
1067
- );
1068
- return {
1069
- algo: result.algo ?? "ml-kem-768",
1070
- epoch: typeof result.epoch === "string" ? BigInt(result.epoch) : BigInt(result.epoch),
1071
- encapsulationKey: hexToBytes2(result.encapsulationKey, "encapsulationKey")
1072
- };
1073
- }
1074
- var ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE = "encrypted mempool submission unavailable until MB-3 threshold decryption is active";
1075
- async function buildEncryptedSubmission(_args) {
1076
- await Promise.resolve();
1077
- throw new Error(ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE);
1078
- }
1079
- async function submitEncryptedEnvelope(client, envelopeWireHex) {
1080
- return client.call("lyth_submitEncrypted", [envelopeWireHex]);
1081
- }
1082
- function buildPlaintextSubmission(args) {
1083
- const signed = args.backend.signEvmTx(args.tx);
1084
- return {
1085
- signedTxWireHex: `0x${signed.wireHex}`,
1086
- innerTxHashHex: bytesToHex2(signed.txHash),
1087
- innerSighashHex: bytesToHex2(signed.sighash),
1088
- innerWireBytes: signed.wireBytes.length
1089
- };
1090
- }
1091
- async function submitPlaintextTransaction(client, signedTxWireHex, expectedTxHashHex) {
1092
- const returned = await client.call("mesh_submitTx", [signedTxWireHex]);
1093
- const returnedBytes = hexToBytes2(returned, "mesh_submitTx tx hash");
1094
- if (returnedBytes.length !== 32) {
1095
- throw new Error(
1096
- `mesh_submitTx tx hash must be 32 bytes, got ${returnedBytes.length}`
1097
- );
1098
- }
1099
- const expectedBytes = hexToBytes2(expectedTxHashHex, "expected tx hash");
1100
- if (!bytesEqual(returnedBytes, expectedBytes)) {
1101
- throw new Error(
1102
- `mesh_submitTx returned tx hash ${bytesToHex2(returnedBytes)} but the locally computed canonical hash is ${bytesToHex2(expectedBytes)}`
1103
- );
1104
- }
1105
- return bytesToHex2(returnedBytes);
1106
- }
1107
- function bytesEqual(a, b) {
1108
- if (a.length !== b.length) return false;
1109
- for (let i = 0; i < a.length; i++) {
1110
- if (a[i] !== b[i]) return false;
1111
- }
1112
- return true;
1113
- }
1114
-
1115
1145
  // src/crypto/bincode.ts
1116
1146
  var BincodeWriter = class {
1117
1147
  #chunks = [];
@@ -1159,17 +1189,656 @@ var BincodeWriter = class {
1159
1189
  this.#chunks.push(value >> 8 * i & 255);
1160
1190
  }
1161
1191
  }
1162
- #big(value, bytes) {
1163
- let v = typeof value === "bigint" ? value : BigInt(value);
1164
- if (v < 0n || v >= 1n << BigInt(bytes * 8)) {
1165
- throw new Error(`integer out of u${bytes * 8} range`);
1166
- }
1167
- for (let i = 0; i < bytes; i++) {
1168
- this.#chunks.push(Number(v & 0xffn));
1169
- v >>= 8n;
1170
- }
1192
+ #big(value, bytes) {
1193
+ let v = typeof value === "bigint" ? value : BigInt(value);
1194
+ if (v < 0n || v >= 1n << BigInt(bytes * 8)) {
1195
+ throw new Error(`integer out of u${bytes * 8} range`);
1196
+ }
1197
+ for (let i = 0; i < bytes; i++) {
1198
+ this.#chunks.push(Number(v & 0xffn));
1199
+ v >>= 8n;
1200
+ }
1201
+ }
1202
+ };
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 = 2;
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);
1171
1811
  }
1172
- };
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
+ }
1173
1842
 
1174
1843
  // src/mrv.ts
1175
1844
  var MRV_FORMAT_VERSION = 1;
@@ -1672,6 +2341,7 @@ async function submitMrvCallNativeTx(client, backend, contractAddress, input, op
1672
2341
  }
1673
2342
  async function submitMrvEncryptedNativeTxGated(client, backend, plan, options) {
1674
2343
  const submission = await buildEncryptedSubmission({
2344
+ backend,
1675
2345
  tx: plan.tx,
1676
2346
  encryptionKey: options.encryptionKey ?? await fetchEncryptionKey(client),
1677
2347
  class: options.class
@@ -2029,192 +2699,6 @@ function isIdentifier(value) {
2029
2699
  return /^[a-z][a-z0-9_]*$/.test(value);
2030
2700
  }
2031
2701
 
2032
- // src/crypto/tx.ts
2033
- function encodeTransactionForHash(fields, tag) {
2034
- const n = normalizeTxFields(fields);
2035
- return concatBytes2(
2036
- Uint8Array.of(tag),
2037
- bigintToBeBytes(n.chainId, 8, "chainId"),
2038
- bigintToBeBytes(n.nonce, 8, "nonce"),
2039
- bigintToBeBytes(n.maxPriorityFeePerGas, 32, "maxPriorityFeePerGas"),
2040
- bigintToBeBytes(n.maxFeePerGas, 32, "maxFeePerGas"),
2041
- bigintToBeBytes(n.gasLimit, 8, "gasLimit"),
2042
- n.to === null ? Uint8Array.of(0) : concatBytes2(Uint8Array.of(1), n.to),
2043
- bigintToBeBytes(n.value, 32, "value"),
2044
- bigintToBeBytes(BigInt(n.input.length), 4, "input.length"),
2045
- n.input,
2046
- new Uint8Array(4),
2047
- // access_list length
2048
- encodeExtensionsForHash(n.extensions)
2049
- );
2050
- }
2051
- function bincodeSignedTransaction(fields, signature, publicKey) {
2052
- const n = normalizeTxFields(fields);
2053
- const sig = expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature");
2054
- const pk = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
2055
- const w = new BincodeWriter();
2056
- w.u64(n.chainId);
2057
- w.u64(n.nonce);
2058
- w.bytes(uint256Be(n.maxPriorityFeePerGas, "maxPriorityFeePerGas"));
2059
- w.bytes(uint256Be(n.maxFeePerGas, "maxFeePerGas"));
2060
- w.u64(n.gasLimit);
2061
- if (n.to === null) {
2062
- w.u8(0);
2063
- } else {
2064
- w.u8(1);
2065
- w.bytes(n.to);
2066
- }
2067
- w.bytes(uint256Be(n.value, "value"));
2068
- w.bytes(n.input);
2069
- w.u64(0n);
2070
- w.u64(BigInt(n.extensions.length));
2071
- for (const ext of n.extensions) bincodeTypedExtensionInto(w, ext);
2072
- bincodeMlDsa65OpaqueInto(w, sig);
2073
- bincodeMlDsa65OpaqueInto(w, pk);
2074
- return w.toBytes();
2075
- }
2076
- function normalizeTxFields(fields) {
2077
- return {
2078
- chainId: parseBigint(fields.chainId, "chainId"),
2079
- nonce: parseBigint(fields.nonce, "nonce"),
2080
- maxPriorityFeePerGas: parseBigint(fields.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
2081
- maxFeePerGas: parseBigint(fields.maxFeePerGas, "maxFeePerGas"),
2082
- gasLimit: parseBigint(fields.gasLimit, "gasLimit"),
2083
- to: normalizeTo(fields.to),
2084
- value: parseBigint(fields.value, "value"),
2085
- input: normalizeBytes(fields.input ?? new Uint8Array(0), "input"),
2086
- extensions: normalizeExtensions(fields.extensions)
2087
- };
2088
- }
2089
- function normalizeTo(value) {
2090
- if (value === null) return null;
2091
- const bytes = normalizeBytes(value, "to");
2092
- return expectBytes(bytes, 20, "to");
2093
- }
2094
- function normalizeBytes(value, label) {
2095
- if (typeof value === "string") return hexToBytes2(value, label);
2096
- return value instanceof Uint8Array ? value : Uint8Array.from(value);
2097
- }
2098
- function normalizeExtensions(value) {
2099
- if (value === void 0) return [];
2100
- return value.map((ext, index) => {
2101
- if (!Number.isInteger(ext.kind) || ext.kind < 0 || ext.kind > 255) {
2102
- throw new Error(`extensions[${index}].kind out of u8 range`);
2103
- }
2104
- const body = normalizeBytes("bodyHex" in ext ? ext.bodyHex : ext.body, `extensions[${index}].body`);
2105
- if (body.length > 4294967295) {
2106
- throw new Error(`extensions[${index}].body exceeds u32 length`);
2107
- }
2108
- return { kind: ext.kind, body };
2109
- });
2110
- }
2111
- function encodeExtensionsForHash(extensions) {
2112
- const chunks = [bigintToBeBytes(BigInt(extensions.length), 4, "extensions.length")];
2113
- for (const ext of extensions) {
2114
- chunks.push(
2115
- Uint8Array.of(ext.kind),
2116
- bigintToBeBytes(BigInt(ext.body.length), 4, "extension.body.length"),
2117
- ext.body
2118
- );
2119
- }
2120
- return concatBytes2(...chunks);
2121
- }
2122
- function uint256Be(value, label) {
2123
- if (value < 0n || value >= 1n << 256n) throw new Error(`${label} out of u256 range`);
2124
- const out = new Uint8Array(32);
2125
- let v = value;
2126
- for (let i = 31; i >= 0; i--) {
2127
- out[i] = Number(v & 0xffn);
2128
- v >>= 8n;
2129
- }
2130
- return out;
2131
- }
2132
- function bincodeMlDsa65OpaqueInto(w, raw) {
2133
- w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
2134
- w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
2135
- w.bytes(raw);
2136
- }
2137
- function bincodeTypedExtensionInto(w, ext) {
2138
- w.u8(ext.kind);
2139
- w.bytes(ext.body);
2140
- }
2141
-
2142
- // src/crypto/ml-dsa.ts
2143
- var ML_DSA_65_SEED_LEN = 32;
2144
- var ML_DSA_65_SIGNING_KEY_LEN = 4032;
2145
- var ML_DSA_65_PUBLIC_KEY_LEN = 1952;
2146
- var ML_DSA_65_SIGNATURE_LEN = 3309;
2147
- var STANDARD_ALGO_NUMBER_ML_DSA_65 = 1001;
2148
- var ENUM_VARIANT_INDEX_ML_DSA_65 = 5;
2149
- var ADDRESS_DERIVATION_DOMAIN = "MONO_ADDRESS_BLAKE3_20_V1";
2150
- var ADDRESS_DERIVATION_DOMAIN_BYTES = new TextEncoder().encode(ADDRESS_DERIVATION_DOMAIN);
2151
- var MlDsa65Backend = class _MlDsa65Backend {
2152
- #secretKey;
2153
- #publicKey;
2154
- #addressBytes;
2155
- constructor(secretKey, publicKey) {
2156
- this.#secretKey = expectBytes(secretKey, ML_DSA_65_SIGNING_KEY_LEN, "ML-DSA-65 secret key").slice();
2157
- this.#publicKey = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key").slice();
2158
- this.#addressBytes = mlDsa65AddressBytes(this.#publicKey);
2159
- }
2160
- static fromSeed(seed) {
2161
- const kp = mlDsa_js.ml_dsa65.keygen(expectBytes(seed, ML_DSA_65_SEED_LEN, "ML-DSA-65 seed"));
2162
- return new _MlDsa65Backend(kp.secretKey, kp.publicKey);
2163
- }
2164
- publicKey() {
2165
- return this.#publicKey.slice();
2166
- }
2167
- addressBytes() {
2168
- return this.#addressBytes.slice();
2169
- }
2170
- getAddress() {
2171
- return bytesToHex2(this.#addressBytes);
2172
- }
2173
- sign(message) {
2174
- return mlDsa_js.ml_dsa65.sign(message, this.#secretKey, { extraEntropy: false });
2175
- }
2176
- signPrehash(digest) {
2177
- return this.sign(expectBytes(digest, 32, "prehash"));
2178
- }
2179
- verify(message, signature) {
2180
- return mlDsa_js.ml_dsa65.verify(
2181
- expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature"),
2182
- message,
2183
- this.#publicKey
2184
- );
2185
- }
2186
- signEvmTx(fields) {
2187
- const txHashPreimage = encodeTransactionForHash(fields, 1);
2188
- const sighash = sha3_js.keccak_256(txHashPreimage);
2189
- const signature = this.sign(sighash);
2190
- const wireBytes = bincodeSignedTransaction(fields, signature, this.#publicKey);
2191
- const txHash = sha3_js.keccak_256(
2192
- concatBytes2(
2193
- encodeTransactionForHash(fields, 2),
2194
- signature,
2195
- this.#publicKey
2196
- )
2197
- );
2198
- return {
2199
- wireHex: bytesToHex2(wireBytes).slice(2),
2200
- wireBytes,
2201
- sighash,
2202
- txHash
2203
- };
2204
- }
2205
- };
2206
- function mlDsa65AddressFromPublicKey(publicKey) {
2207
- return bytesToHex2(mlDsa65AddressBytes(publicKey));
2208
- }
2209
- function mlDsa65AddressBytes(publicKey) {
2210
- const bytes = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
2211
- return blake3_js.blake3(concatBytes2(
2212
- ADDRESS_DERIVATION_DOMAIN_BYTES,
2213
- bigintToBeBytes(BigInt(STANDARD_ALGO_NUMBER_ML_DSA_65), 2, "ML-DSA-65 algo id"),
2214
- bytes
2215
- )).slice(0, 20);
2216
- }
2217
-
2218
2702
  // src/registry.ts
2219
2703
  var BLS_PUBLIC_KEY_BYTE_LENGTH = 48;
2220
2704
  var TESTNET_69420 = {
@@ -2222,8 +2706,8 @@ var TESTNET_69420 = {
2222
2706
  network: "testnet-69420",
2223
2707
  display_name: "Monolythium Testnet",
2224
2708
  description: "Public Monolythium testnet. Testnet state may reset without notice; do not store value on this network.",
2225
- genesis_hash: "0xe67cf82131fc63e335ce61afeae53299283eaa3a692830a618911aa840245031",
2226
- binary_sha: "e4697f9b",
2709
+ genesis_hash: "0x6a2bb3c8a6701bedcddc0447583bb24f34b77310e3aa77c62ca303a453e9f7ba",
2710
+ binary_sha: "c283c75d",
2227
2711
  rpc: [
2228
2712
  {
2229
2713
  url: "http://178.105.12.9:8545",
@@ -6781,7 +7265,7 @@ function verifyBoundedReceiptProof(proof) {
6781
7265
  }
6782
7266
  const actualRoot = computeNoEvmReceiptsRoot(receipts);
6783
7267
  const expectedRoot = decodeHash(proof.receiptsRoot, "receiptsRoot");
6784
- if (!bytesEqual2(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
7268
+ if (!bytesEqual3(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
6785
7269
  throw new NoEvmReceiptProofError(
6786
7270
  "receipts_root_mismatch",
6787
7271
  `receiptsRoot mismatch: expected ${proof.receiptsRoot}, computed ${actualRoot}`
@@ -6789,7 +7273,7 @@ function verifyBoundedReceiptProof(proof) {
6789
7273
  }
6790
7274
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
6791
7275
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
6792
- if (!bytesEqual2(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7276
+ if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
6793
7277
  throw new NoEvmReceiptProofError(
6794
7278
  "target_receipt_hash_mismatch",
6795
7279
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -6846,7 +7330,7 @@ function verifyCompactReceiptProof(proof) {
6846
7330
  const targetReceipt = decodeHexBytes(targetReceiptBytes, "targetReceiptBytes");
6847
7331
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
6848
7332
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
6849
- if (!bytesEqual2(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7333
+ if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
6850
7334
  throw new NoEvmReceiptProofError(
6851
7335
  "target_receipt_hash_mismatch",
6852
7336
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -6857,7 +7341,7 @@ function verifyCompactReceiptProof(proof) {
6857
7341
  compactProof.leafHash,
6858
7342
  "compactInclusionProof.leafHash"
6859
7343
  );
6860
- if (!bytesEqual2(expectedLeafHashBytes, actualLeafHashBytes)) {
7344
+ if (!bytesEqual3(expectedLeafHashBytes, actualLeafHashBytes)) {
6861
7345
  throw new NoEvmReceiptProofError(
6862
7346
  "compact_leaf_hash_mismatch",
6863
7347
  `compactInclusionProof.leafHash mismatch: expected ${compactProof.leafHash}, computed ${bytesToHex6(
@@ -6867,7 +7351,7 @@ function verifyCompactReceiptProof(proof) {
6867
7351
  }
6868
7352
  const compactRootBytes = decodeHash(compactProof.root, "compactInclusionProof.root");
6869
7353
  const receiptsRootBytes = decodeHash(proof.receiptsRoot, "receiptsRoot");
6870
- if (!bytesEqual2(receiptsRootBytes, compactRootBytes)) {
7354
+ if (!bytesEqual3(receiptsRootBytes, compactRootBytes)) {
6871
7355
  throw new NoEvmReceiptProofError(
6872
7356
  "compact_root_mismatch",
6873
7357
  `receiptsRoot must equal compactInclusionProof.root: receiptsRoot ${proof.receiptsRoot}, compact root ${compactProof.root}`
@@ -6890,7 +7374,7 @@ function verifyCompactReceiptProof(proof) {
6890
7374
  siblingHashes,
6891
7375
  pathSides
6892
7376
  );
6893
- if (!bytesEqual2(actualRootBytes, compactRootBytes)) {
7377
+ if (!bytesEqual3(actualRootBytes, compactRootBytes)) {
6894
7378
  throw new NoEvmReceiptProofError(
6895
7379
  "compact_path_mismatch",
6896
7380
  `compact inclusion path mismatch: expected ${compactProof.root}, computed ${bytesToHex6(
@@ -7044,7 +7528,7 @@ function validateCoveringSnapshotObject(snapshot, archiveContentHash, proofBlock
7044
7528
  "archiveProof.coveringSnapshot.checkpointTo must match blockHeight"
7045
7529
  );
7046
7530
  }
7047
- if (!bytesEqual2(checkpointContentHash, archiveContentHash)) {
7531
+ if (!bytesEqual3(checkpointContentHash, archiveContentHash)) {
7048
7532
  throw new NoEvmReceiptProofError(
7049
7533
  "invalid_proof_shape",
7050
7534
  "archiveProof.coveringSnapshot.checkpointContentHash must match archiveProof.contentHash"
@@ -7243,7 +7727,7 @@ function validateFinalityBlockReference(blockReference, round, proofBlockHash) {
7243
7727
  );
7244
7728
  if (proofBlockHash !== void 0) {
7245
7729
  const blockHash = decodeHash(proofBlockHash, "blockHash");
7246
- if (!bytesEqual2(digest, blockHash)) {
7730
+ if (!bytesEqual3(digest, blockHash)) {
7247
7731
  throw new NoEvmReceiptProofError(
7248
7732
  "invalid_proof_shape",
7249
7733
  "finalityEvidence.blockReference.digest must match blockHash"
@@ -7593,7 +8077,7 @@ function assertHashBytes(value, field2) {
7593
8077
  function isRecord3(value) {
7594
8078
  return typeof value === "object" && value !== null && !Array.isArray(value);
7595
8079
  }
7596
- function bytesEqual2(a, b) {
8080
+ function bytesEqual3(a, b) {
7597
8081
  if (a.length !== b.length) return false;
7598
8082
  let diff = 0;
7599
8083
  for (let index = 0; index < a.length; index++) {
@@ -7875,25 +8359,50 @@ function clusterJoinRequestExists(view) {
7875
8359
  return view.status !== "none" || view.owner.toLowerCase() !== ZERO_ADDRESS || view.bondLythoshi !== 0n;
7876
8360
  }
7877
8361
  async function readClusterJoinRequest(client, args) {
7878
- const data = encodeGetClusterJoinRequestCalldata({
7879
- clusterId: args.clusterId,
7880
- operatorId: normalizeOperatorId(args.operatorId)
7881
- });
7882
- const output = await client.call("eth_call", [
7883
- {
7884
- to: nodeRegistryAddressHex(),
7885
- data
7886
- },
7887
- "latest"
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
7888
8367
  ]);
7889
- return decodeClusterJoinRequest(output);
8368
+ return adaptNativeClusterJoinRequest(envelope.request);
7890
8369
  }
7891
8370
  async function preflightClusterJoinRequest(client, args) {
7892
8371
  try {
7893
8372
  return await readClusterJoinRequest(client, args);
7894
8373
  } catch (cause) {
7895
8374
  throw new Error(
7896
- `CJ-1 getClusterJoinRequest is not exposed or failed on the connected chain: ${errorMessage(cause)}`
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)}`
7897
8406
  );
7898
8407
  }
7899
8408
  }
@@ -7952,18 +8461,15 @@ async function submitRequestClusterJoin(args) {
7952
8461
  const clusterId = parseUint32(args.clusterId, "clusterId");
7953
8462
  const operatorPubkey = normalizeConsensusPubkey(args.operatorPubkey, "operatorPubkey");
7954
8463
  const operatorIdHex = deriveClusterJoinOperatorId(operatorPubkey);
7955
- const existing = await preflightClusterJoinRequest(args.client, {
7956
- clusterId,
7957
- operatorId: operatorIdHex
7958
- });
7959
- if (existing.status === "open") {
7960
- throw new Error("cluster join request is already open for this operator");
7961
- }
7962
- if (existing.status === "admitted") {
7963
- throw new Error("operator is already admitted for this cluster request");
7964
- }
7965
8464
  const backend = pqm1MnemonicToMlDsa65Backend(args.mnemonic);
7966
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);
7967
8473
  const [chainId, nonce, quote] = await Promise.all([
7968
8474
  args.client.ethChainId(),
7969
8475
  args.client.lythGetTransactionCount(senderAddress),
@@ -7982,15 +8488,15 @@ async function submitRequestClusterJoin(args) {
7982
8488
  async function submitVoteClusterAdmit(args) {
7983
8489
  const clusterId = parseUint32(args.clusterId, "clusterId");
7984
8490
  const operatorIdHex = normalizeOperatorId(args.operatorId);
7985
- const existing = await preflightClusterJoinRequest(args.client, {
7986
- clusterId,
7987
- operatorId: operatorIdHex
7988
- });
7989
- if (!clusterJoinRequestExists(existing) || existing.status !== "open") {
7990
- throw new Error("candidate cluster join request is not open for voting");
7991
- }
7992
8491
  const backend = pqm1MnemonicToMlDsa65Backend(args.mnemonic);
7993
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);
7994
8500
  const [chainId, nonce, quote] = await Promise.all([
7995
8501
  args.client.ethChainId(),
7996
8502
  args.client.lythGetTransactionCount(senderAddress),
@@ -8021,6 +8527,40 @@ async function submitClusterJoinTx(client, backend, tx, clusterId, operatorIdHex
8021
8527
  signedTxWireBytes: plaintext.innerWireBytes
8022
8528
  };
8023
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
+ }
8024
8564
  function normalizeConsensusPubkey(value, label) {
8025
8565
  const bytes = typeof value === "string" ? hexToBytes2(value, label) : value;
8026
8566
  return expectBytes(bytes, NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES, label).slice();
@@ -9014,11 +9554,6 @@ function wordToBigint(word) {
9014
9554
  }
9015
9555
  return out;
9016
9556
  }
9017
- new TextEncoder().encode("protocore/v2/mempool/dkg-mlkem768/1");
9018
- var MempoolClass = {
9019
- CLOBOp: 3};
9020
-
9021
- // src/market-actions.ts
9022
9557
  var CLOB_MARKET_ID_DOMAIN_TAG = 193;
9023
9558
  var NATIVE_MARKET_MODULE_ADDRESS_BYTES = "0x4d41524b45545f4e41544956455f4d4f445f5631";
9024
9559
  var NATIVE_MARKET_MODULE_ADDRESS = addressToTypedBech32(
@@ -10349,7 +10884,7 @@ var MONOLYTHIUM_NETWORKS = {
10349
10884
  };
10350
10885
 
10351
10886
  // src/index.ts
10352
- var version = "0.4.1";
10887
+ var version = "0.4.3";
10353
10888
 
10354
10889
  exports.ADDRESS_HRP = ADDRESS_HRP;
10355
10890
  exports.ADDRESS_KIND_HRPS = ADDRESS_KIND_HRPS;
@@ -10424,12 +10959,19 @@ exports.NATIVE_MARKET_ORDER_BOOK_STREAM_TOPIC = NATIVE_MARKET_ORDER_BOOK_STREAM_
10424
10959
  exports.NODE_REGISTRY_BLS_PUBKEY_BYTES = NODE_REGISTRY_BLS_PUBKEY_BYTES;
10425
10960
  exports.NODE_REGISTRY_CAPABILITIES = NODE_REGISTRY_CAPABILITIES;
10426
10961
  exports.NODE_REGISTRY_CAPABILITY_MASK = NODE_REGISTRY_CAPABILITY_MASK;
10962
+ exports.NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES = NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES;
10427
10963
  exports.NODE_REGISTRY_CONSENSUS_POP_BYTES = NODE_REGISTRY_CONSENSUS_POP_BYTES;
10428
10964
  exports.NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES = NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES;
10965
+ exports.NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES = NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES;
10429
10966
  exports.NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES = NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES;
10430
10967
  exports.NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS = NODE_REGISTRY_DKG_RESHARE_MAX_SIGNERS;
10431
10968
  exports.NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS = NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS;
10432
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;
10433
10975
  exports.NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES = NODE_REGISTRY_LEGACY_CLUSTER_MEMBER_PUBKEY_BYTES;
10434
10976
  exports.NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID = NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID;
10435
10977
  exports.NODE_REGISTRY_PUBLIC_SERVICE_MASK = NODE_REGISTRY_PUBLIC_SERVICE_MASK;
@@ -10607,6 +11149,7 @@ exports.encodeDelegateCalldata = encodeDelegateCalldata;
10607
11149
  exports.encodeDisableCalldata = encodeDisableCalldata;
10608
11150
  exports.encodeEnableCalldata = encodeEnableCalldata;
10609
11151
  exports.encodeExpireClusterJoinCalldata = encodeExpireClusterJoinCalldata;
11152
+ exports.encodeFormClusterCalldata = encodeFormClusterCalldata;
10610
11153
  exports.encodeGetClusterJoinRequestCalldata = encodeGetClusterJoinRequestCalldata;
10611
11154
  exports.encodeHasPubkeyCalldata = encodeHasPubkeyCalldata;
10612
11155
  exports.encodeLockBridgeConfigCalldata = encodeLockBridgeConfigCalldata;
@@ -10684,6 +11227,8 @@ exports.encodeVoteClusterAdmitCalldata = encodeVoteClusterAdmitCalldata;
10684
11227
  exports.exportBridgeRouteCatalogueJson = exportBridgeRouteCatalogueJson;
10685
11228
  exports.fetchChainInfoLatest = fetchChainInfoLatest;
10686
11229
  exports.fetchChainRegistryLatest = fetchChainRegistryLatest;
11230
+ exports.formClusterMessage = formClusterMessage;
11231
+ exports.formClusterMessageHex = formClusterMessageHex;
10687
11232
  exports.formatLyth = formatLyth;
10688
11233
  exports.formatLythoshi = formatLythoshi;
10689
11234
  exports.formatNativeReceiptFeeDisplay = formatNativeReceiptFeeDisplay;
@@ -10742,6 +11287,8 @@ exports.parseNativeDecodedEvent = parseNativeDecodedEvent;
10742
11287
  exports.parseQuantity = parseQuantity;
10743
11288
  exports.parseQuantityBig = parseQuantityBig;
10744
11289
  exports.preflightClusterJoinRequest = preflightClusterJoinRequest;
11290
+ exports.previewRequestClusterJoin = previewRequestClusterJoin;
11291
+ exports.previewVoteClusterAdmit = previewVoteClusterAdmit;
10745
11292
  exports.proverMarketStateFromByte = proverMarketStateFromByte;
10746
11293
  exports.pubkeyRegistryAddressHex = pubkeyRegistryAddressHex;
10747
11294
  exports.quoteOperatorFee = quoteOperatorFee;