@monolythium/core-sdk 0.4.22 → 0.4.24

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,9 +2,6 @@
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');
8
5
  var mlDsa_js = require('@noble/post-quantum/ml-dsa.js');
9
6
  var bls12381_js = require('@noble/curves/bls12-381.js');
10
7
  var bip39 = require('@scure/bip39');
@@ -382,10 +379,6 @@ var NODE_REGISTRY_SELECTORS = {
382
379
  formClusterV2: "0x" + selectorHex("formCluster(bytes,bytes,bytes,bytes)"),
383
380
  /** `setOperatorDisplay(bytes32,string,string)` — owner-callable public display metadata. */
384
381
  setOperatorDisplay: "0x" + selectorHex("setOperatorDisplay(bytes32,string,string)"),
385
- /** `publishOperatorSealKey(bytes32,bytes)` — owner-callable LythiumSeal EK publication. */
386
- publishOperatorSealKey: "0x" + selectorHex("publishOperatorSealKey(bytes32,bytes)"),
387
- /** `getOperatorSealKey(bytes32)` view — returns the operator's published LythiumSeal EK. */
388
- getOperatorSealKey: "0x" + selectorHex("getOperatorSealKey(bytes32)"),
389
382
  /**
390
383
  * `updateCharter(uint32,bytes,bytes,bytes)` — Component H live charter
391
384
  * amendment (Law §6.8); re-signs a new 30-byte charter for a LIVE cluster
@@ -419,7 +412,6 @@ var NODE_REGISTRY_BLS_PUBKEY_BYTES = NODE_REGISTRY_CLUSTER_MEMBER_REF_BYTES;
419
412
  var NODE_REGISTRY_CONSENSUS_PUBKEY_BYTES = 1952;
420
413
  var NODE_REGISTRY_CONSENSUS_SIGNATURE_BYTES = 3309;
421
414
  var NODE_REGISTRY_CONSENSUS_POP_BYTES = 3309;
422
- var NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES = 1184;
423
415
  var NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES = 96;
424
416
  var NODE_REGISTRY_DKG_THRESHOLD_SIG_BYTES = NODE_REGISTRY_DKG_ATTESTATION_SIG_BYTES;
425
417
  var NODE_REGISTRY_DKG_RESHARE_MIN_SIGNERS = 5;
@@ -686,43 +678,6 @@ function encodeSetOperatorDisplayCalldata(args) {
686
678
  )
687
679
  );
688
680
  }
689
- function encodePublishOperatorSealKeyCalldata(args) {
690
- const peerId = expectLength2(toBytes(args.peerId), 32, "peerId");
691
- const sealEk = expectNonZeroBytes(
692
- expectLength2(toBytes(args.sealEk), NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES, "sealEk"),
693
- "sealEk"
694
- );
695
- const sealEkPadded = padToWord(sealEk);
696
- return bytesToHex(
697
- concatBytes(
698
- hexToBytes(NODE_REGISTRY_SELECTORS.publishOperatorSealKey),
699
- peerId,
700
- uint64Word(2n * 32n, "sealEkOffset"),
701
- uint64Word(BigInt(sealEk.length), "sealEkLength"),
702
- sealEkPadded
703
- )
704
- );
705
- }
706
- function encodeGetOperatorSealKeyCalldata(args) {
707
- return bytesToHex(
708
- concatBytes(
709
- hexToBytes(NODE_REGISTRY_SELECTORS.getOperatorSealKey),
710
- expectLength2(toBytes(args.operatorId), 32, "operatorId")
711
- )
712
- );
713
- }
714
- function decodeOperatorSealKey(returnData) {
715
- const bytes = toBytes(returnData);
716
- if (bytes.length === NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES) {
717
- return bytesToHex(expectNonZeroBytes(bytes, "operatorSealKey"));
718
- }
719
- const sealEk = decodeDynamicBytesResult(
720
- bytes,
721
- NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES,
722
- "operatorSealKey"
723
- );
724
- return bytesToHex(expectNonZeroBytes(sealEk, "operatorSealKey"));
725
- }
726
681
  function encodeCancelClusterJoinCalldata(args) {
727
682
  return bytesToHex(
728
683
  concatBytes(
@@ -1651,30 +1606,6 @@ function expectLength2(value, len, name) {
1651
1606
  }
1652
1607
  return value;
1653
1608
  }
1654
- function expectNonZeroBytes(value, name) {
1655
- if (value.every((byte) => byte === 0)) {
1656
- throw new NodeRegistryError(`${name} must not be all-zero`);
1657
- }
1658
- return value;
1659
- }
1660
- function decodeDynamicBytesResult(bytes, expectedLength, label) {
1661
- if (bytes.length < 64) {
1662
- throw new NodeRegistryError(`${label} return must be ABI-encoded dynamic bytes`);
1663
- }
1664
- const offset = uintFromWord(bytes.slice(0, 32));
1665
- if (offset !== 32n) {
1666
- throw new NodeRegistryError(`${label} return offset must be 0x20`);
1667
- }
1668
- const len = uintFromWord(bytes.slice(32, 64));
1669
- if (len !== BigInt(expectedLength)) {
1670
- throw new NodeRegistryError(`${label} must be ${expectedLength} bytes, got ${len}`);
1671
- }
1672
- const paddedLen = Math.ceil(expectedLength / 32) * 32;
1673
- if (bytes.length < 64 + paddedLen) {
1674
- throw new NodeRegistryError(`${label} body is truncated`);
1675
- }
1676
- return bytes.slice(64, 64 + expectedLength);
1677
- }
1678
1609
 
1679
1610
  // src/native-events.ts
1680
1611
  var NATIVE_MARKET_EVENT_FAMILY = "market";
@@ -1816,6 +1747,40 @@ function parseBigint(value, label) {
1816
1747
  return BigInt(value);
1817
1748
  }
1818
1749
 
1750
+ // src/crypto/submission.ts
1751
+ function buildPlaintextSubmission(args) {
1752
+ const signed = args.backend.signEvmTx(args.tx);
1753
+ return {
1754
+ signedTxWireHex: `0x${signed.wireHex}`,
1755
+ innerTxHashHex: bytesToHex2(signed.txHash),
1756
+ innerSighashHex: bytesToHex2(signed.sighash),
1757
+ innerWireBytes: signed.wireBytes.length
1758
+ };
1759
+ }
1760
+ async function submitPlaintextTransaction(client, signedTxWireHex, expectedTxHashHex) {
1761
+ const returned = await client.call("mesh_submitTx", [signedTxWireHex]);
1762
+ const returnedBytes = hexToBytes2(returned, "mesh_submitTx tx hash");
1763
+ if (returnedBytes.length !== 32) {
1764
+ throw new Error(
1765
+ `mesh_submitTx tx hash must be 32 bytes, got ${returnedBytes.length}`
1766
+ );
1767
+ }
1768
+ const expectedBytes = hexToBytes2(expectedTxHashHex, "expected tx hash");
1769
+ if (!bytesEqual(returnedBytes, expectedBytes)) {
1770
+ throw new Error(
1771
+ `mesh_submitTx returned tx hash ${bytesToHex2(returnedBytes)} but the locally computed canonical hash is ${bytesToHex2(expectedBytes)}`
1772
+ );
1773
+ }
1774
+ return bytesToHex2(returnedBytes);
1775
+ }
1776
+ function bytesEqual(a, b) {
1777
+ if (a.length !== b.length) return false;
1778
+ for (let i = 0; i < a.length; i++) {
1779
+ if (a[i] !== b[i]) return false;
1780
+ }
1781
+ return true;
1782
+ }
1783
+
1819
1784
  // src/crypto/bincode.ts
1820
1785
  var BincodeWriter = class {
1821
1786
  #chunks = [];
@@ -1875,782 +1840,115 @@ var BincodeWriter = class {
1875
1840
  }
1876
1841
  };
1877
1842
 
1878
- // src/crypto/tx.ts
1879
- function encodeTransactionForHash(fields, tag) {
1880
- const n = normalizeTxFields(fields);
1881
- return concatBytes2(
1882
- Uint8Array.of(tag),
1883
- bigintToBeBytes(n.chainId, 8, "chainId"),
1884
- bigintToBeBytes(n.nonce, 8, "nonce"),
1885
- bigintToBeBytes(n.maxPriorityFeePerGas, 32, "maxPriorityFeePerGas"),
1886
- bigintToBeBytes(n.maxFeePerGas, 32, "maxFeePerGas"),
1887
- bigintToBeBytes(n.gasLimit, 8, "gasLimit"),
1888
- n.to === null ? Uint8Array.of(0) : concatBytes2(Uint8Array.of(1), n.to),
1889
- bigintToBeBytes(n.value, 32, "value"),
1890
- bigintToBeBytes(BigInt(n.input.length), 4, "input.length"),
1891
- n.input,
1892
- new Uint8Array(4),
1893
- // access_list length
1894
- encodeExtensionsForHash(n.extensions)
1895
- );
1896
- }
1897
- function bincodeSignedTransaction(fields, signature, publicKey) {
1898
- const n = normalizeTxFields(fields);
1899
- const sig = expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature");
1900
- const pk = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
1901
- const w = new BincodeWriter();
1902
- w.u64(n.chainId);
1903
- w.u64(n.nonce);
1904
- w.bytes(uint256Be(n.maxPriorityFeePerGas, "maxPriorityFeePerGas"));
1905
- w.bytes(uint256Be(n.maxFeePerGas, "maxFeePerGas"));
1906
- w.u64(n.gasLimit);
1907
- if (n.to === null) {
1908
- w.u8(0);
1909
- } else {
1910
- w.u8(1);
1911
- w.bytes(n.to);
1843
+ // src/mrv.ts
1844
+ var MRV_FORMAT_VERSION = 1;
1845
+ var MRV_DEPLOY_PAYLOAD_VERSION = 1;
1846
+ var MRV_PROFILE_MONO_RV32IM_V1 = "mono_rv32im_v1";
1847
+ var MRV_MEMORY_PAGE_BYTES = 65536;
1848
+ var MRV_MAX_CODE_BYTES = 16 * 1024 * 1024;
1849
+ var MRV_MAX_DEBUG_BYTES = 16 * 1024 * 1024;
1850
+ var MRV_MAX_MEMORY_PAGES = 1024;
1851
+ var MRV_MAX_ABI_SYMBOLS = 1024;
1852
+ var MRV_MAX_STORAGE_NAMESPACE_BYTES = 64;
1853
+ var LYTH_DECIMALS = 18;
1854
+ var NATIVE_LYTH_DECIMALS = LYTH_DECIMALS;
1855
+ var LYTHOSHI_PER_LYTH = 1000000000000000000n;
1856
+ var MRV_TX_EXTENSION_KIND = 48;
1857
+ var MRV_TX_EXTENSION_V1 = 1;
1858
+ var MRV_CODE_HASH_DOMAIN = new TextEncoder().encode("MONO_MRV_CODE_V1");
1859
+ var MRV_CONTRACT_ADDRESS_DOMAIN = new TextEncoder().encode("mono:riscv:contract-address:v1");
1860
+ var MONO_SYSCALL_MODULE = "mono";
1861
+ var SYSCALLS = [
1862
+ [257, "storage_read"],
1863
+ [258, "storage_write"],
1864
+ [259, "storage_delete"],
1865
+ [513, "caller"],
1866
+ [514, "contract_address"],
1867
+ [515, "block_height"],
1868
+ [516, "block_hash"],
1869
+ [769, "call_contract"],
1870
+ [770, "emit_event"],
1871
+ [771, "transfer_native"],
1872
+ [1025, "verify_signature"],
1873
+ [1026, "hash"],
1874
+ [1281, "revert"]
1875
+ ];
1876
+ var SYSCALL_NAME_BY_ID = new Map(SYSCALLS);
1877
+ var SYSCALL_ID_BY_NAME = new Map(SYSCALLS.map(([id, name]) => [name, id]));
1878
+ var MrvValidationError = class extends Error {
1879
+ constructor(message) {
1880
+ super(message);
1881
+ this.name = "MrvValidationError";
1912
1882
  }
1913
- w.bytes(uint256Be(n.value, "value"));
1914
- w.bytes(n.input);
1915
- w.u64(0n);
1916
- w.u64(BigInt(n.extensions.length));
1917
- for (const ext of n.extensions) bincodeTypedExtensionInto(w, ext);
1918
- bincodeMlDsa65OpaqueInto(w, sig);
1919
- bincodeMlDsa65OpaqueInto(w, pk);
1920
- return w.toBytes();
1921
- }
1922
- function normalizeTxFields(fields) {
1923
- return {
1924
- chainId: parseBigint(fields.chainId, "chainId"),
1925
- nonce: parseBigint(fields.nonce, "nonce"),
1926
- maxPriorityFeePerGas: parseBigint(fields.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
1927
- maxFeePerGas: parseBigint(fields.maxFeePerGas, "maxFeePerGas"),
1928
- gasLimit: parseBigint(fields.gasLimit, "gasLimit"),
1929
- to: normalizeTo(fields.to),
1930
- value: parseBigint(fields.value, "value"),
1931
- input: normalizeBytes(fields.input ?? new Uint8Array(0), "input"),
1932
- extensions: normalizeExtensions(fields.extensions)
1933
- };
1883
+ };
1884
+ var MRV_STRUCTURED_FEE_FIELDS = [
1885
+ "total_lythoshi",
1886
+ "cycles_used",
1887
+ "base_price_per_cycle_lythoshi",
1888
+ "state_io_units",
1889
+ "state_io_price_per_unit_lythoshi",
1890
+ "priority_tip_lythoshi"
1891
+ ];
1892
+ function formatLyth(lythoshi, options = {}) {
1893
+ const amount = BigInt(normalizeDecimalLike("lythoshi", lythoshi));
1894
+ const whole = amount / LYTHOSHI_PER_LYTH;
1895
+ const fraction = amount % LYTHOSHI_PER_LYTH;
1896
+ let formatted = formatWholeWithCommas(whole);
1897
+ if (fraction !== 0n) {
1898
+ formatted += `.${fraction.toString().padStart(NATIVE_LYTH_DECIMALS, "0").replace(/0+$/, "")}`;
1899
+ }
1900
+ if (options.includeUnit !== false) {
1901
+ formatted += " LYTH";
1902
+ }
1903
+ return formatted;
1934
1904
  }
1935
- function normalizeTo(value) {
1936
- if (value === null) return null;
1937
- const bytes = normalizeBytes(value, "to");
1938
- return expectBytes(bytes, 20, "to");
1905
+ function formatLythoshi(lythoshi, options = {}) {
1906
+ return formatLyth(lythoshi, options);
1939
1907
  }
1940
- function normalizeBytes(value, label) {
1941
- if (typeof value === "string") return hexToBytes2(value, label);
1942
- return value instanceof Uint8Array ? value : Uint8Array.from(value);
1908
+ function parseLythToLythoshi(input) {
1909
+ const numeric = stripLythUnit(input);
1910
+ const parts = numeric.split(".");
1911
+ if (parts.length > 2) {
1912
+ throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
1913
+ }
1914
+ const [wholeRaw, fractionRaw = ""] = parts;
1915
+ if (!isCanonicalWholeLyth(wholeRaw)) {
1916
+ throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
1917
+ }
1918
+ if (numeric.includes(".") && fractionRaw.length === 0) {
1919
+ throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
1920
+ }
1921
+ if (fractionRaw.length > NATIVE_LYTH_DECIMALS || !/^[0-9]*$/.test(fractionRaw)) {
1922
+ throw new MrvValidationError(`lyth amount supports at most ${NATIVE_LYTH_DECIMALS} decimal places`);
1923
+ }
1924
+ const whole = BigInt(wholeRaw.replaceAll(",", ""));
1925
+ const fraction = fractionRaw === "" ? 0n : BigInt(fractionRaw.padEnd(NATIVE_LYTH_DECIMALS, "0"));
1926
+ return whole * LYTHOSHI_PER_LYTH + fraction;
1943
1927
  }
1944
- function normalizeExtensions(value) {
1945
- if (value === void 0) return [];
1946
- return value.map((ext, index) => {
1947
- if (!Number.isInteger(ext.kind) || ext.kind < 0 || ext.kind > 255) {
1948
- throw new Error(`extensions[${index}].kind out of u8 range`);
1928
+ function checkMrvFeeDisplayConformance(input) {
1929
+ const expectedTotalLythoshi = normalizeDecimalLike("expectedTotalLythoshi", input.expectedTotalLythoshi);
1930
+ const expectedDefaultFeeText = formatLyth(expectedTotalLythoshi);
1931
+ const failures = [];
1932
+ const amountCandidates = extractLythAmountCandidates(input.defaultFeeText);
1933
+ if (amountCandidates.length !== 1) {
1934
+ failures.push("defaultFeeText must contain exactly one LYTH-denominated fee amount");
1935
+ } else {
1936
+ const renderedCandidate = `${amountCandidates[0]} LYTH`;
1937
+ if (renderedCandidate !== expectedDefaultFeeText) {
1938
+ failures.push(`defaultFeeText fee must be ${expectedDefaultFeeText}`);
1949
1939
  }
1950
- const body = normalizeBytes("bodyHex" in ext ? ext.bodyHex : ext.body, `extensions[${index}].body`);
1951
- if (body.length > 4294967295) {
1952
- throw new Error(`extensions[${index}].body exceeds u32 length`);
1940
+ try {
1941
+ const parsed = parseLythToLythoshi(renderedCandidate);
1942
+ if (parsed.toString() !== expectedTotalLythoshi) {
1943
+ failures.push(`defaultFeeText fee must total ${expectedTotalLythoshi} lythoshi`);
1944
+ }
1945
+ } catch {
1946
+ failures.push(`defaultFeeText fee must be a canonical ${NATIVE_LYTH_DECIMALS}-decimal LYTH amount`);
1953
1947
  }
1954
- return { kind: ext.kind, body };
1955
- });
1956
- }
1957
- function encodeExtensionsForHash(extensions) {
1958
- const chunks = [bigintToBeBytes(BigInt(extensions.length), 4, "extensions.length")];
1959
- for (const ext of extensions) {
1960
- chunks.push(
1961
- Uint8Array.of(ext.kind),
1962
- bigintToBeBytes(BigInt(ext.body.length), 4, "extension.body.length"),
1963
- ext.body
1964
- );
1965
1948
  }
1966
- return concatBytes2(...chunks);
1967
- }
1968
- function uint256Be(value, label) {
1969
- if (value < 0n || value >= 1n << 256n) throw new Error(`${label} out of u256 range`);
1970
- const out = new Uint8Array(32);
1971
- let v = value;
1972
- for (let i = 31; i >= 0; i--) {
1973
- out[i] = Number(v & 0xffn);
1974
- v >>= 8n;
1975
- }
1976
- return out;
1977
- }
1978
- function bincodeMlDsa65OpaqueInto(w, raw) {
1979
- w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
1980
- w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
1981
- w.bytes(raw);
1982
- }
1983
- function bincodeTypedExtensionInto(w, ext) {
1984
- w.u8(ext.kind);
1985
- w.bytes(ext.body);
1986
- }
1987
-
1988
- // src/crypto/ml-dsa.ts
1989
- var ML_DSA_65_SEED_LEN = 32;
1990
- var ML_DSA_65_SIGNING_KEY_LEN = 4032;
1991
- var ML_DSA_65_PUBLIC_KEY_LEN = 1952;
1992
- var ML_DSA_65_SIGNATURE_LEN = 3309;
1993
- var STANDARD_ALGO_NUMBER_ML_DSA_65 = 1001;
1994
- var ENUM_VARIANT_INDEX_ML_DSA_65 = 3;
1995
- var ADDRESS_DERIVATION_DOMAIN = "MONO_ADDRESS_BLAKE3_20_V1";
1996
- var ADDRESS_DERIVATION_DOMAIN_BYTES = new TextEncoder().encode(ADDRESS_DERIVATION_DOMAIN);
1997
- var MlDsa65Backend = class _MlDsa65Backend {
1998
- #secretKey;
1999
- #publicKey;
2000
- #addressBytes;
2001
- #disposed = false;
2002
- constructor(secretKey, publicKey) {
2003
- this.#secretKey = expectBytes(secretKey, ML_DSA_65_SIGNING_KEY_LEN, "ML-DSA-65 secret key").slice();
2004
- this.#publicKey = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key").slice();
2005
- this.#addressBytes = mlDsa65AddressBytes(this.#publicKey);
2006
- }
2007
- static fromSeed(seed) {
2008
- const kp = mlDsa_js.ml_dsa65.keygen(expectBytes(seed, ML_DSA_65_SEED_LEN, "ML-DSA-65 seed"));
2009
- return new _MlDsa65Backend(kp.secretKey, kp.publicKey);
2010
- }
2011
- publicKey() {
2012
- return this.#publicKey.slice();
2013
- }
2014
- addressBytes() {
2015
- return this.#addressBytes.slice();
2016
- }
2017
- getAddress() {
2018
- return bytesToHex2(this.#addressBytes);
2019
- }
2020
- sign(message) {
2021
- if (this.#disposed) {
2022
- throw new Error("MlDsa65Backend disposed");
2023
- }
2024
- return mlDsa_js.ml_dsa65.sign(message, this.#secretKey, { extraEntropy: false });
2025
- }
2026
- /**
2027
- * Best-effort deterministic wipe of the in-memory secret key. Zeroes the
2028
- * SDK-held `#secretKey` copy and makes any subsequent `sign()` /
2029
- * `signPrehash()` / `signEvmTx()` throw `"MlDsa65Backend disposed"` rather
2030
- * than signing with a zeroed key. Idempotent. Public material
2031
- * (`publicKey()` / `getAddress()` / `verify()`) stays usable.
2032
- *
2033
- * Defense-in-depth (S1-01): narrows the post-lock residency window of the
2034
- * ML-DSA-65 secret in the JS heap. `@noble/post-quantum`'s internal
2035
- * transient keygen/sign buffers are out of scope; the SDK-held copy is the
2036
- * meaningful residency win.
2037
- */
2038
- dispose() {
2039
- this.#secretKey.fill(0);
2040
- this.#disposed = true;
2041
- }
2042
- /** Alias for {@link dispose}. */
2043
- zeroize() {
2044
- this.dispose();
2045
- }
2046
- /** Whether {@link dispose} has been called (the secret key is wiped). */
2047
- get disposed() {
2048
- return this.#disposed;
2049
- }
2050
- signPrehash(digest) {
2051
- return this.sign(expectBytes(digest, 32, "prehash"));
2052
- }
2053
- verify(message, signature) {
2054
- return mlDsa_js.ml_dsa65.verify(
2055
- expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature"),
2056
- message,
2057
- this.#publicKey
2058
- );
2059
- }
2060
- signEvmTx(fields) {
2061
- const txHashPreimage = encodeTransactionForHash(fields, 1);
2062
- const sighash = sha3_js.keccak_256(txHashPreimage);
2063
- const signature = this.sign(sighash);
2064
- const wireBytes = bincodeSignedTransaction(fields, signature, this.#publicKey);
2065
- const txHash = sha3_js.keccak_256(
2066
- concatBytes2(
2067
- encodeTransactionForHash(fields, 2),
2068
- signature,
2069
- this.#publicKey
2070
- )
2071
- );
2072
- return {
2073
- wireHex: bytesToHex2(wireBytes).slice(2),
2074
- wireBytes,
2075
- sighash,
2076
- txHash
2077
- };
2078
- }
2079
- };
2080
- function mlDsa65AddressFromPublicKey(publicKey) {
2081
- return bytesToHex2(mlDsa65AddressBytes(publicKey));
2082
- }
2083
- function mlDsa65AddressBytes(publicKey) {
2084
- const bytes = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
2085
- return blake3_js.blake3(concatBytes2(
2086
- ADDRESS_DERIVATION_DOMAIN_BYTES,
2087
- bigintToBeBytes(BigInt(STANDARD_ALGO_NUMBER_ML_DSA_65), 2, "ML-DSA-65 algo id"),
2088
- bytes
2089
- )).slice(0, 20);
2090
- }
2091
-
2092
- // src/crypto/envelope.ts
2093
- new TextEncoder().encode("protocore/v2/mempool/dkg-mlkem768/1");
2094
- var MempoolClass = {
2095
- Transfer: 0,
2096
- ContractCall: 1,
2097
- CLOBOp: 3};
2098
- function bincodeNonceAad(aad) {
2099
- const w = new BincodeWriter();
2100
- w.bytes(expectBytes(aad.sender, 20, "NonceAad.sender"));
2101
- w.u64(aad.nonce);
2102
- w.u64(aad.chainId);
2103
- w.enumVariant(aad.class);
2104
- w.u128(aad.maxFeePerGas);
2105
- w.u128(aad.maxPriorityFeePerGas);
2106
- w.u64(aad.gasLimit);
2107
- return w.toBytes();
2108
- }
2109
- function bincodeDecryptHint(hint) {
2110
- const w = new BincodeWriter();
2111
- w.u64(hint.epoch);
2112
- w.u16(hint.scheme);
2113
- return w.toBytes();
2114
- }
2115
- function bincodeEncryptedEnvelope(env) {
2116
- const w = new BincodeWriter();
2117
- w.rawBytes(bincodeNonceAad(env.nonceAad));
2118
- w.bytes(env.ciphertext);
2119
- w.rawBytes(bincodeDecryptHint(env.decryptionHint));
2120
- bincodeMlDsa65OpaqueInto2(w, expectBytes(env.senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey"));
2121
- bincodeMlDsa65OpaqueInto2(w, expectBytes(env.outerSignature, ML_DSA_65_SIGNATURE_LEN, "outerSignature"));
2122
- w.bytes(expectBytes(env.sender, 20, "sender"));
2123
- return w.toBytes();
2124
- }
2125
- function outerSigDigest(nonceAad, ciphertext, decryptionHint, senderPubkey) {
2126
- const aad = bincodeNonceAad(nonceAad);
2127
- const hint = bincodeDecryptHint(decryptionHint);
2128
- return sha3_js.keccak_256(concatBytes2(aad, ciphertext, hint, expectBytes(senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey")));
2129
- }
2130
- function bincodeMlDsa65OpaqueInto2(w, raw) {
2131
- w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
2132
- w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
2133
- w.bytes(raw);
2134
- }
2135
- var SEAL_EK_LEN = 1184;
2136
- var SEAL_KEY_LEN = 32;
2137
- var SEAL_NONCE_LEN = 12;
2138
- var SEAL_COMMIT_LEN = 32;
2139
- var SEAL_SECRET_LEN = 32;
2140
- var SEAL_SHARE_LEN = 1 + SEAL_SECRET_LEN;
2141
- var CLUSTER_MLKEM_SHAMIR = 3;
2142
- var COMMIT_DOMAIN = new TextEncoder().encode("lythiumseal/commit/v1");
2143
- var KEK_DOMAIN = new TextEncoder().encode("lythiumseal/kek/v1");
2144
- var NONCE_DOMAIN = new TextEncoder().encode("lythiumseal/nonce/v1");
2145
- var BODY_AAD_DOMAIN = new TextEncoder().encode("lythiumseal/body/v1");
2146
- var SHARE_AAD_DOMAIN = new TextEncoder().encode("lythiumseal/share/v1");
2147
- var ROSTER_DOMAIN = new TextEncoder().encode("lythiumseal/roster/v1");
2148
- function cryptoRandomSource() {
2149
- return {
2150
- fillBytes(dest) {
2151
- crypto.getRandomValues(dest);
2152
- }
2153
- };
2154
- }
2155
- function u32le(n) {
2156
- const out = new Uint8Array(4);
2157
- out[0] = n & 255;
2158
- out[1] = n >>> 8 & 255;
2159
- out[2] = n >>> 16 & 255;
2160
- out[3] = n >>> 24 & 255;
2161
- return out;
2162
- }
2163
- function u64le(n) {
2164
- const out = new Uint8Array(8);
2165
- let v = n;
2166
- for (let i = 0; i < 8; i++) {
2167
- out[i] = Number(v & 0xffn);
2168
- v >>= 8n;
2169
- }
2170
- return out;
2171
- }
2172
- function framed(field2) {
2173
- return concatBytes2(u32le(field2.length), field2);
2174
- }
2175
- function keyCommitment(key) {
2176
- return sha3_js.shake256(concatBytes2(framed(COMMIT_DOMAIN), key), { dkLen: SEAL_COMMIT_LEN });
2177
- }
2178
- function deriveKek(sharedSecret, domain, clusterId, epoch, opIndex) {
2179
- const input = concatBytes2(
2180
- framed(KEK_DOMAIN),
2181
- framed(sharedSecret),
2182
- framed(domain),
2183
- u32le(clusterId),
2184
- u64le(epoch),
2185
- Uint8Array.of(opIndex)
2186
- );
2187
- return sha3_js.shake256(input, { dkLen: SEAL_KEY_LEN });
2188
- }
2189
- function deriveNonce(domain, context) {
2190
- const input = concatBytes2(framed(NONCE_DOMAIN), framed(domain), framed(context));
2191
- return sha3_js.shake256(input, { dkLen: SEAL_NONCE_LEN });
2192
- }
2193
- function bodyAad(ctx, k, n) {
2194
- return concatBytes2(
2195
- BODY_AAD_DOMAIN,
2196
- u32le(ctx.clusterId),
2197
- u64le(ctx.epoch),
2198
- Uint8Array.of(k),
2199
- Uint8Array.of(n),
2200
- ctx.rosterHash
2201
- );
2202
- }
2203
- function shareAad(ctx, opIndex) {
2204
- return concatBytes2(
2205
- SHARE_AAD_DOMAIN,
2206
- u32le(ctx.clusterId),
2207
- u64le(ctx.epoch),
2208
- Uint8Array.of(opIndex),
2209
- ctx.rosterHash
2210
- );
2211
- }
2212
- function aeadSeal(key, nonce, plaintext, aad) {
2213
- const cipher = chacha_js.chacha20poly1305(key, nonce, aad);
2214
- const ct = cipher.encrypt(plaintext);
2215
- return { nonce, ct, commitment: keyCommitment(key) };
2216
- }
2217
- function gfMul(a, b) {
2218
- let product = 0;
2219
- let x = a & 255;
2220
- let y = b & 255;
2221
- for (let i = 0; i < 8; i++) {
2222
- const mask = -(y & 1) & 255;
2223
- product ^= x & mask;
2224
- const high = -(x >> 7 & 1) & 255;
2225
- x = x << 1 & 255;
2226
- x ^= 27 & high;
2227
- y >>= 1;
2228
- }
2229
- return product & 255;
2230
- }
2231
- function polyEval(coeffs, x) {
2232
- let acc = 0;
2233
- for (let i = coeffs.length - 1; i >= 0; i--) {
2234
- acc = gfMul(acc, x) ^ coeffs[i];
2235
- }
2236
- return acc & 255;
2237
- }
2238
- function shamirSplit(secret, t, n, rng) {
2239
- const byteCoeffs = [];
2240
- for (let j = 0; j < SEAL_SECRET_LEN; j++) {
2241
- const c = new Uint8Array(t);
2242
- c[0] = secret[j];
2243
- if (t > 1) {
2244
- const tail = new Uint8Array(t - 1);
2245
- rng.fillBytes(tail);
2246
- c.set(tail, 1);
2247
- }
2248
- byteCoeffs.push(c);
2249
- }
2250
- const shares = [];
2251
- for (let k = 0; k < n; k++) {
2252
- const x = k + 1 & 255;
2253
- const value = new Uint8Array(SEAL_SECRET_LEN);
2254
- for (let j = 0; j < SEAL_SECRET_LEN; j++) {
2255
- value[j] = polyEval(byteCoeffs[j], x);
2256
- }
2257
- shares.push({ index: x, value });
2258
- }
2259
- return shares;
2260
- }
2261
- function shareToBytes(s) {
2262
- const out = new Uint8Array(SEAL_SHARE_LEN);
2263
- out[0] = s.index;
2264
- out.set(s.value, 1);
2265
- return out;
2266
- }
2267
- function sealRosterHash(keccak2562, clusterId, t, n, roster) {
2268
- const chunks = [ROSTER_DOMAIN, u32le(clusterId), Uint8Array.of(t), Uint8Array.of(n)];
2269
- for (const { operatorIndex, ek } of roster) {
2270
- chunks.push(Uint8Array.of(operatorIndex), ek);
2271
- }
2272
- return keccak2562(concatBytes2(...chunks));
2273
- }
2274
- function encodeSealEnvelope(env) {
2275
- const chunks = [];
2276
- chunks.push(u32le(env.clusterId));
2277
- chunks.push(u64le(env.epoch));
2278
- chunks.push(expectBytes(env.rosterHash, 32, "rosterHash"));
2279
- chunks.push(Uint8Array.of(env.t));
2280
- chunks.push(Uint8Array.of(env.n));
2281
- pushAeadBody(chunks, env.aeadBody);
2282
- chunks.push(u64le(BigInt(env.recipients.length)));
2283
- for (const r of env.recipients) {
2284
- chunks.push(Uint8Array.of(r.operatorIndex));
2285
- chunks.push(u64le(BigInt(r.kemCt.length)));
2286
- chunks.push(r.kemCt);
2287
- pushAeadBody(chunks, r.wrapped);
2288
- }
2289
- return concatBytes2(...chunks);
2290
- }
2291
- function pushAeadBody(chunks, body) {
2292
- chunks.push(expectBytes(body.nonce, SEAL_NONCE_LEN, "aead nonce"));
2293
- chunks.push(u64le(BigInt(body.ct.length)));
2294
- chunks.push(body.ct);
2295
- chunks.push(expectBytes(body.commitment, SEAL_COMMIT_LEN, "aead commitment"));
2296
- }
2297
- function sealToCluster(args) {
2298
- const { plaintext, recipientEks, t, clusterId } = args;
2299
- const epoch = args.epoch;
2300
- const rosterHash = expectBytes(args.rosterHash, 32, "rosterHash");
2301
- const rng = args.rng ?? cryptoRandomSource();
2302
- const n = recipientEks.length;
2303
- if (!Number.isInteger(t) || t < 1 || t > n || n < 1 || n > 255) {
2304
- throw new Error(`invalid threshold/recipient count: t=${t} n=${n}`);
2305
- }
2306
- for (let i = 0; i < n; i++) {
2307
- expectBytes(recipientEks[i], SEAL_EK_LEN, `recipientEks[${i}]`);
2308
- }
2309
- const ctx = { clusterId, epoch, rosterHash };
2310
- const bodyKey = new Uint8Array(SEAL_KEY_LEN);
2311
- rng.fillBytes(bodyKey);
2312
- const aad = bodyAad(ctx, t, n);
2313
- const bodyNonce = deriveNonce(new TextEncoder().encode("body"), aad);
2314
- const aeadBody = aeadSeal(bodyKey, bodyNonce, plaintext, aad);
2315
- const shares = shamirSplit(bodyKey, t, n, rng);
2316
- const recipients = [];
2317
- for (let i = 0; i < n; i++) {
2318
- const opIndex = i + 1 & 255;
2319
- const m = new Uint8Array(32);
2320
- rng.fillBytes(m);
2321
- const { cipherText: kemCt, sharedSecret } = mlKem_js.ml_kem768.encapsulate(recipientEks[i], m);
2322
- const kek = deriveKek(sharedSecret, rosterHash, clusterId, epoch, opIndex);
2323
- const sAad = shareAad(ctx, opIndex);
2324
- const wrapNonce = deriveNonce(new TextEncoder().encode("share"), sAad);
2325
- const wrapped = aeadSeal(kek, wrapNonce, shareToBytes(shares[i]), sAad);
2326
- recipients.push({ operatorIndex: opIndex, kemCt, wrapped });
2327
- sharedSecret.fill(0);
2328
- kek.fill(0);
2329
- }
2330
- bodyKey.fill(0);
2331
- return {
2332
- clusterId,
2333
- epoch,
2334
- rosterHash,
2335
- t,
2336
- n,
2337
- aeadBody,
2338
- recipients
2339
- };
2340
- }
2341
-
2342
- // src/crypto/seal.ts
2343
- var CLUSTER_MLKEM_SHAMIR_ALGO = "cluster-mlkem768-shamir";
2344
- function parseClusterSealKeys(source) {
2345
- const n = source.roster.length;
2346
- if (n === 0) {
2347
- throw new Error("cluster seal roster is empty");
2348
- }
2349
- if (source.n !== n) {
2350
- throw new Error(`cluster seal roster n=${source.n} disagrees with ${n} entries`);
2351
- }
2352
- if (!Number.isInteger(source.t) || source.t < 2 || source.t > n) {
2353
- throw new Error(`cluster seal threshold t=${source.t} out of range 2..=${n}`);
2354
- }
2355
- const sorted = [...source.roster].sort((a, b) => a.operatorIndex - b.operatorIndex);
2356
- const recipientEks = [];
2357
- const hashInput = [];
2358
- for (let i = 0; i < n; i++) {
2359
- const entry = sorted[i];
2360
- if (entry.operatorIndex !== i + 1) {
2361
- throw new Error(
2362
- `cluster seal roster operator indices must be 1..=${n}; got ${entry.operatorIndex} at slot ${i + 1}`
2363
- );
2364
- }
2365
- const ek = expectBytes(hexToBytes2(entry.mlKemEk, `operator ${entry.operatorIndex} mlKemEk`), SEAL_EK_LEN, `operator ${entry.operatorIndex} ek`);
2366
- recipientEks.push(ek);
2367
- hashInput.push({ operatorIndex: entry.operatorIndex, ek });
2368
- }
2369
- const recomputed = sealRosterHash(keccak256, source.clusterId, source.t, n, hashInput);
2370
- if (source.rosterHash !== void 0) {
2371
- const supplied = expectBytes(hexToBytes2(source.rosterHash, "rosterHash"), 32, "rosterHash");
2372
- if (!bytesEqual(supplied, recomputed)) {
2373
- throw new Error(
2374
- `cluster seal roster hash mismatch: source ${bytesToHex2(supplied)} != recomputed ${bytesToHex2(recomputed)} (the roster hash does not commit to this ek set)`
2375
- );
2376
- }
2377
- }
2378
- return {
2379
- algo: source.algo ?? CLUSTER_MLKEM_SHAMIR_ALGO,
2380
- clusterId: source.clusterId,
2381
- epoch: toBigInt(source.epoch),
2382
- rosterHash: recomputed,
2383
- t: source.t,
2384
- n,
2385
- recipientEks
2386
- };
2387
- }
2388
- async function sealTransaction(args) {
2389
- const keys = args.clusterSealKeys;
2390
- const senderPubkey = expectBytes(args.senderPubkey, ML_DSA_65_PUBLIC_KEY_LEN, "senderPubkey");
2391
- const senderAddress = expectBytes(args.senderAddress, 20, "senderAddress");
2392
- const env = sealToCluster({
2393
- plaintext: args.signedTxBincode,
2394
- recipientEks: keys.recipientEks,
2395
- t: keys.t,
2396
- clusterId: keys.clusterId,
2397
- epoch: keys.epoch,
2398
- rosterHash: keys.rosterHash,
2399
- rng: args.rng
2400
- });
2401
- const ciphertext = encodeSealEnvelope(env);
2402
- const decryptionHint = { epoch: keys.epoch, scheme: CLUSTER_MLKEM_SHAMIR };
2403
- const digest = outerSigDigest(args.aad, ciphertext, decryptionHint, senderPubkey);
2404
- const outerSignature = expectBytes(
2405
- await args.signOuterDigest(digest),
2406
- ML_DSA_65_SIGNATURE_LEN,
2407
- "outerSignature"
2408
- );
2409
- const envelope = {
2410
- nonceAad: args.aad,
2411
- ciphertext,
2412
- decryptionHint,
2413
- senderPubkey,
2414
- outerSignature,
2415
- sender: senderAddress
2416
- };
2417
- const envelopeWireBytes = bincodeEncryptedEnvelope(envelope);
2418
- return {
2419
- envelopeWireHex: `0x${bytesToHex2(envelopeWireBytes).slice(2)}`,
2420
- envelopeWireBytes,
2421
- ciphertextBytes: ciphertext.length
2422
- };
2423
- }
2424
- function keccak256(input) {
2425
- return sha3_js.keccak_256(input);
2426
- }
2427
- function toBigInt(value) {
2428
- if (typeof value === "bigint") return value;
2429
- return BigInt(value);
2430
- }
2431
- function bytesEqual(a, b) {
2432
- if (a.length !== b.length) return false;
2433
- for (let i = 0; i < a.length; i++) {
2434
- if (a[i] !== b[i]) return false;
2435
- }
2436
- return true;
2437
- }
2438
-
2439
- // src/crypto/submission.ts
2440
- async function fetchEncryptionKey(client) {
2441
- const result = await client.call(
2442
- "lyth_getEncryptionKey",
2443
- []
2444
- );
2445
- return {
2446
- algo: result.algo ?? "ml-kem-768",
2447
- epoch: typeof result.epoch === "string" ? BigInt(result.epoch) : BigInt(result.epoch),
2448
- encapsulationKey: hexToBytes2(result.encapsulationKey, "encapsulationKey")
2449
- };
2450
- }
2451
- var ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE = "private submission requires cluster seal keys; pass clusterSealKeysSource or enable lyth_getClusterSealKeys";
2452
- async function buildEncryptedSubmission(args) {
2453
- const signed = args.backend.signEvmTx(args.tx);
2454
- const clusterSealKeys = await resolveClusterSealKeys(args);
2455
- const aad = nonceAadForTx(args.tx, args.backend.addressBytes(), args.class);
2456
- const sealed = await sealTransaction({
2457
- signedTxBincode: signed.wireBytes,
2458
- clusterSealKeys,
2459
- aad,
2460
- senderAddress: args.backend.addressBytes(),
2461
- senderPubkey: args.backend.publicKey(),
2462
- signOuterDigest: (digest) => args.backend.signPrehash(digest)
2463
- });
2464
- return {
2465
- envelopeWireHex: sealed.envelopeWireHex,
2466
- innerSighashHex: bytesToHex2(signed.sighash),
2467
- innerTxHashHex: bytesToHex2(signed.txHash),
2468
- innerWireBytes: signed.wireBytes.length
2469
- };
2470
- }
2471
- async function submitEncryptedEnvelope(client, envelopeWireHex) {
2472
- return client.call("lyth_submitEncrypted", [envelopeWireHex]);
2473
- }
2474
- function buildPlaintextSubmission(args) {
2475
- const signed = args.backend.signEvmTx(args.tx);
2476
- return {
2477
- signedTxWireHex: `0x${signed.wireHex}`,
2478
- innerTxHashHex: bytesToHex2(signed.txHash),
2479
- innerSighashHex: bytesToHex2(signed.sighash),
2480
- innerWireBytes: signed.wireBytes.length
2481
- };
2482
- }
2483
- async function submitPlaintextTransaction(client, signedTxWireHex, expectedTxHashHex) {
2484
- const returned = await client.call("mesh_submitTx", [signedTxWireHex]);
2485
- const returnedBytes = hexToBytes2(returned, "mesh_submitTx tx hash");
2486
- if (returnedBytes.length !== 32) {
2487
- throw new Error(
2488
- `mesh_submitTx tx hash must be 32 bytes, got ${returnedBytes.length}`
2489
- );
2490
- }
2491
- const expectedBytes = hexToBytes2(expectedTxHashHex, "expected tx hash");
2492
- if (!bytesEqual2(returnedBytes, expectedBytes)) {
2493
- throw new Error(
2494
- `mesh_submitTx returned tx hash ${bytesToHex2(returnedBytes)} but the locally computed canonical hash is ${bytesToHex2(expectedBytes)}`
2495
- );
2496
- }
2497
- return bytesToHex2(returnedBytes);
2498
- }
2499
- function bytesEqual2(a, b) {
2500
- if (a.length !== b.length) return false;
2501
- for (let i = 0; i < a.length; i++) {
2502
- if (a[i] !== b[i]) return false;
2503
- }
2504
- return true;
2505
- }
2506
- async function resolveClusterSealKeys(args) {
2507
- if (args.clusterSealKeys !== void 0) return args.clusterSealKeys;
2508
- if (args.clusterSealKeysSource !== void 0) {
2509
- return parseClusterSealKeys(args.clusterSealKeysSource);
2510
- }
2511
- if (args.client === void 0) {
2512
- throw new Error(ENCRYPTED_SUBMISSION_UNAVAILABLE_MESSAGE);
2513
- }
2514
- const clusterId = args.clusterId ?? 0;
2515
- const result = await args.client.call(
2516
- "lyth_getClusterSealKeys",
2517
- [clusterId]
2518
- );
2519
- return parseClusterSealKeys({ ...result, clusterId: result.clusterId ?? clusterId });
2520
- }
2521
- function nonceAadForTx(tx, sender, mempoolClass) {
2522
- return {
2523
- sender,
2524
- nonce: parseBigint(tx.nonce, "nonce"),
2525
- chainId: parseBigint(tx.chainId, "chainId"),
2526
- class: mempoolClass ?? inferMempoolClass(tx),
2527
- maxFeePerGas: parseBigint(tx.maxFeePerGas, "maxFeePerGas"),
2528
- maxPriorityFeePerGas: parseBigint(tx.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
2529
- gasLimit: parseBigint(tx.gasLimit, "gasLimit")
2530
- };
2531
- }
2532
- function inferMempoolClass(tx) {
2533
- if (tx.to === null || hasInput(tx.input)) return MempoolClass.ContractCall;
2534
- return MempoolClass.Transfer;
2535
- }
2536
- function hasInput(input) {
2537
- if (input === void 0) return false;
2538
- if (typeof input === "string") {
2539
- const stripped = input.startsWith("0x") || input.startsWith("0X") ? input.slice(2) : input;
2540
- return stripped.length > 0;
2541
- }
2542
- return input.length > 0;
2543
- }
2544
-
2545
- // src/mrv.ts
2546
- var MRV_FORMAT_VERSION = 1;
2547
- var MRV_DEPLOY_PAYLOAD_VERSION = 1;
2548
- var MRV_PROFILE_MONO_RV32IM_V1 = "mono_rv32im_v1";
2549
- var MRV_MEMORY_PAGE_BYTES = 65536;
2550
- var MRV_MAX_CODE_BYTES = 16 * 1024 * 1024;
2551
- var MRV_MAX_DEBUG_BYTES = 16 * 1024 * 1024;
2552
- var MRV_MAX_MEMORY_PAGES = 1024;
2553
- var MRV_MAX_ABI_SYMBOLS = 1024;
2554
- var MRV_MAX_STORAGE_NAMESPACE_BYTES = 64;
2555
- var LYTH_DECIMALS = 18;
2556
- var NATIVE_LYTH_DECIMALS = LYTH_DECIMALS;
2557
- var LYTHOSHI_PER_LYTH = 1000000000000000000n;
2558
- var MRV_TX_EXTENSION_KIND = 48;
2559
- var MRV_TX_EXTENSION_V1 = 1;
2560
- var MRV_CODE_HASH_DOMAIN = new TextEncoder().encode("MONO_MRV_CODE_V1");
2561
- var MRV_CONTRACT_ADDRESS_DOMAIN = new TextEncoder().encode("mono:riscv:contract-address:v1");
2562
- var MONO_SYSCALL_MODULE = "mono";
2563
- var SYSCALLS = [
2564
- [257, "storage_read"],
2565
- [258, "storage_write"],
2566
- [259, "storage_delete"],
2567
- [513, "caller"],
2568
- [514, "contract_address"],
2569
- [515, "block_height"],
2570
- [516, "block_hash"],
2571
- [769, "call_contract"],
2572
- [770, "emit_event"],
2573
- [771, "transfer_native"],
2574
- [1025, "verify_signature"],
2575
- [1026, "hash"],
2576
- [1281, "revert"]
2577
- ];
2578
- var SYSCALL_NAME_BY_ID = new Map(SYSCALLS);
2579
- var SYSCALL_ID_BY_NAME = new Map(SYSCALLS.map(([id, name]) => [name, id]));
2580
- var MrvValidationError = class extends Error {
2581
- constructor(message) {
2582
- super(message);
2583
- this.name = "MrvValidationError";
2584
- }
2585
- };
2586
- var MRV_STRUCTURED_FEE_FIELDS = [
2587
- "total_lythoshi",
2588
- "cycles_used",
2589
- "base_price_per_cycle_lythoshi",
2590
- "state_io_units",
2591
- "state_io_price_per_unit_lythoshi",
2592
- "priority_tip_lythoshi"
2593
- ];
2594
- function formatLyth(lythoshi, options = {}) {
2595
- const amount = BigInt(normalizeDecimalLike("lythoshi", lythoshi));
2596
- const whole = amount / LYTHOSHI_PER_LYTH;
2597
- const fraction = amount % LYTHOSHI_PER_LYTH;
2598
- let formatted = formatWholeWithCommas(whole);
2599
- if (fraction !== 0n) {
2600
- formatted += `.${fraction.toString().padStart(NATIVE_LYTH_DECIMALS, "0").replace(/0+$/, "")}`;
2601
- }
2602
- if (options.includeUnit !== false) {
2603
- formatted += " LYTH";
2604
- }
2605
- return formatted;
2606
- }
2607
- function formatLythoshi(lythoshi, options = {}) {
2608
- return formatLyth(lythoshi, options);
2609
- }
2610
- function parseLythToLythoshi(input) {
2611
- const numeric = stripLythUnit(input);
2612
- const parts = numeric.split(".");
2613
- if (parts.length > 2) {
2614
- throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
2615
- }
2616
- const [wholeRaw, fractionRaw = ""] = parts;
2617
- if (!isCanonicalWholeLyth(wholeRaw)) {
2618
- throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
2619
- }
2620
- if (numeric.includes(".") && fractionRaw.length === 0) {
2621
- throw new MrvValidationError("lyth amount must be a canonical LYTH decimal");
2622
- }
2623
- if (fractionRaw.length > NATIVE_LYTH_DECIMALS || !/^[0-9]*$/.test(fractionRaw)) {
2624
- throw new MrvValidationError(`lyth amount supports at most ${NATIVE_LYTH_DECIMALS} decimal places`);
2625
- }
2626
- const whole = BigInt(wholeRaw.replaceAll(",", ""));
2627
- const fraction = fractionRaw === "" ? 0n : BigInt(fractionRaw.padEnd(NATIVE_LYTH_DECIMALS, "0"));
2628
- return whole * LYTHOSHI_PER_LYTH + fraction;
2629
- }
2630
- function checkMrvFeeDisplayConformance(input) {
2631
- const expectedTotalLythoshi = normalizeDecimalLike("expectedTotalLythoshi", input.expectedTotalLythoshi);
2632
- const expectedDefaultFeeText = formatLyth(expectedTotalLythoshi);
2633
- const failures = [];
2634
- const amountCandidates = extractLythAmountCandidates(input.defaultFeeText);
2635
- if (amountCandidates.length !== 1) {
2636
- failures.push("defaultFeeText must contain exactly one LYTH-denominated fee amount");
2637
- } else {
2638
- const renderedCandidate = `${amountCandidates[0]} LYTH`;
2639
- if (renderedCandidate !== expectedDefaultFeeText) {
2640
- failures.push(`defaultFeeText fee must be ${expectedDefaultFeeText}`);
2641
- }
2642
- try {
2643
- const parsed = parseLythToLythoshi(renderedCandidate);
2644
- if (parsed.toString() !== expectedTotalLythoshi) {
2645
- failures.push(`defaultFeeText fee must total ${expectedTotalLythoshi} lythoshi`);
2646
- }
2647
- } catch {
2648
- failures.push(`defaultFeeText fee must be a canonical ${NATIVE_LYTH_DECIMALS}-decimal LYTH amount`);
2649
- }
2650
- }
2651
- const defaultForbidden = firstForbiddenDefaultFeeTerm(input.defaultFeeText);
2652
- if (defaultForbidden !== void 0) {
2653
- failures.push(`defaultFeeText exposes detail-only fee term '${defaultForbidden}'`);
1949
+ const defaultForbidden = firstForbiddenDefaultFeeTerm(input.defaultFeeText);
1950
+ if (defaultForbidden !== void 0) {
1951
+ failures.push(`defaultFeeText exposes detail-only fee term '${defaultForbidden}'`);
2654
1952
  }
2655
1953
  for (const [index, detailText] of (input.detailTexts ?? []).entries()) {
2656
1954
  const detailForbidden = firstForbiddenDetailFeeTerm(detailText);
@@ -3029,29 +2327,28 @@ function buildMrvNativeFeePreview(executionUnitLimit, maxExecutionFeeLythoshi, p
3029
2327
  async function submitMrvDeployNativeTx(client, backend, artifactBytes, options) {
3030
2328
  const plan = buildMrvDeployNativeTxPlan(artifactBytes, options);
3031
2329
  assertMrvDeployNativeSubmissionPlan(plan);
3032
- return submitMrvEncryptedNativeTxGated(client, backend, plan, options);
2330
+ return submitMrvPlaintextNativeTx(client, backend, plan);
3033
2331
  }
3034
2332
  async function submitMrvDeployPayloadNativeTx(client, backend, artifactBytes, options) {
3035
2333
  const plan = buildMrvDeployPayloadNativeTxPlan(artifactBytes, options);
3036
2334
  assertMrvDeployNativeSubmissionPlan(plan);
3037
- return submitMrvEncryptedNativeTxGated(client, backend, plan, options);
2335
+ return submitMrvPlaintextNativeTx(client, backend, plan);
3038
2336
  }
3039
2337
  async function submitMrvCallNativeTx(client, backend, contractAddress, input, options) {
3040
2338
  const plan = buildMrvCallNativeTxPlan(contractAddress, input, options);
3041
2339
  assertMrvCallNativeSubmissionPlan(plan);
3042
- return submitMrvEncryptedNativeTxGated(client, backend, plan, options);
3043
- }
3044
- async function submitMrvEncryptedNativeTxGated(client, backend, plan, options) {
3045
- const submission = await buildEncryptedSubmission({
3046
- backend,
3047
- tx: plan.tx,
3048
- encryptionKey: options.encryptionKey ?? await fetchEncryptionKey(client),
3049
- class: options.class
3050
- });
2340
+ return submitMrvPlaintextNativeTx(client, backend, plan);
2341
+ }
2342
+ async function submitMrvPlaintextNativeTx(client, backend, plan) {
2343
+ const submission = buildPlaintextSubmission({ backend, tx: plan.tx });
3051
2344
  return {
3052
2345
  ...plan,
3053
2346
  ...submission,
3054
- txHash: await submitEncryptedEnvelope(client, submission.envelopeWireHex)
2347
+ txHash: await submitPlaintextTransaction(
2348
+ client,
2349
+ submission.signedTxWireHex,
2350
+ submission.innerTxHashHex
2351
+ )
3055
2352
  };
3056
2353
  }
3057
2354
  function assertMrvNativeSubmissionEnvelope(plan) {
@@ -3321,84 +2618,298 @@ function isCanonicalUnsignedDecimalString(value) {
3321
2618
  } catch {
3322
2619
  return false;
3323
2620
  }
3324
- }
3325
- function normalizeDecimalLike(field2, value, defaultValue) {
3326
- if (value === void 0) {
3327
- if (defaultValue === void 0) throw new MrvValidationError(`${field2} is required`);
3328
- return defaultValue;
2621
+ }
2622
+ function normalizeDecimalLike(field2, value, defaultValue) {
2623
+ if (value === void 0) {
2624
+ if (defaultValue === void 0) throw new MrvValidationError(`${field2} is required`);
2625
+ return defaultValue;
2626
+ }
2627
+ if (typeof value === "string") {
2628
+ validateDecimal(field2, value);
2629
+ return value;
2630
+ }
2631
+ if (typeof value === "number" && !Number.isSafeInteger(value)) {
2632
+ throw new MrvValidationError(`${field2} must be a safe unsigned integer`);
2633
+ }
2634
+ const out = BigInt(value);
2635
+ if (out < 0n) throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
2636
+ return out.toString();
2637
+ }
2638
+ function normalizeOptionalU64(field2, value) {
2639
+ return value === void 0 ? void 0 : normalizeU64(value, field2);
2640
+ }
2641
+ function validateDecimal(field2, value) {
2642
+ if (!/^(0|[1-9][0-9]*)$/.test(value)) {
2643
+ throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
2644
+ }
2645
+ try {
2646
+ BigInt(value);
2647
+ } catch {
2648
+ throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
2649
+ }
2650
+ }
2651
+ function validateExecutionUnitLimit(field2, value) {
2652
+ if (value !== void 0 && BigInt(value) === 0n) {
2653
+ throw new MrvValidationError(`${field2} must be greater than zero`);
2654
+ }
2655
+ }
2656
+ function normalizeU64(value, field2) {
2657
+ if (typeof value === "number" && !Number.isSafeInteger(value)) {
2658
+ throw new MrvValidationError(`${field2} must be a safe unsigned integer`);
2659
+ }
2660
+ const out = BigInt(value);
2661
+ if (out < 0n || out > 0xffffffffffffffffn) {
2662
+ throw new MrvValidationError(`${field2} must fit in u64`);
2663
+ }
2664
+ return out;
2665
+ }
2666
+ function validateHexLength(field2, value, expected) {
2667
+ const bytes = hexToBytes3(value, field2);
2668
+ if (bytes.length !== expected) throw new MrvValidationError(`${field2} must be ${expected} bytes`);
2669
+ }
2670
+ function bytesFrom(value, field2) {
2671
+ if (typeof value === "string") return hexToBytes3(value, field2);
2672
+ return value instanceof Uint8Array ? value : Uint8Array.from(value);
2673
+ }
2674
+ function hexToBytes3(value, field2) {
2675
+ if (!/^0x(?:[0-9a-fA-F]{2})*$/.test(value)) {
2676
+ throw new MrvValidationError(`${field2} must be 0x-prefixed even-length hex`);
2677
+ }
2678
+ const out = new Uint8Array((value.length - 2) / 2);
2679
+ for (let i = 0; i < out.length; i++) {
2680
+ out[i] = Number.parseInt(value.slice(2 + i * 2, 4 + i * 2), 16);
2681
+ }
2682
+ return out;
2683
+ }
2684
+ function bytesToHex3(bytes) {
2685
+ return `0x${[...bytes].map((b) => b.toString(16).padStart(2, "0")).join("")}`;
2686
+ }
2687
+ function concatBytes3(...parts) {
2688
+ const len = parts.reduce((sum, item) => sum + item.length, 0);
2689
+ const out = new Uint8Array(len);
2690
+ let offset = 0;
2691
+ for (const part of parts) {
2692
+ out.set(part, offset);
2693
+ offset += part.length;
2694
+ }
2695
+ return out;
2696
+ }
2697
+ function isIdentifier(value) {
2698
+ return /^[a-z][a-z0-9_]*$/.test(value);
2699
+ }
2700
+
2701
+ // src/crypto/tx.ts
2702
+ function encodeTransactionForHash(fields, tag) {
2703
+ const n = normalizeTxFields(fields);
2704
+ return concatBytes2(
2705
+ Uint8Array.of(tag),
2706
+ bigintToBeBytes(n.chainId, 8, "chainId"),
2707
+ bigintToBeBytes(n.nonce, 8, "nonce"),
2708
+ bigintToBeBytes(n.maxPriorityFeePerGas, 32, "maxPriorityFeePerGas"),
2709
+ bigintToBeBytes(n.maxFeePerGas, 32, "maxFeePerGas"),
2710
+ bigintToBeBytes(n.gasLimit, 8, "gasLimit"),
2711
+ n.to === null ? Uint8Array.of(0) : concatBytes2(Uint8Array.of(1), n.to),
2712
+ bigintToBeBytes(n.value, 32, "value"),
2713
+ bigintToBeBytes(BigInt(n.input.length), 4, "input.length"),
2714
+ n.input,
2715
+ new Uint8Array(4),
2716
+ // access_list length
2717
+ encodeExtensionsForHash(n.extensions)
2718
+ );
2719
+ }
2720
+ function bincodeSignedTransaction(fields, signature, publicKey) {
2721
+ const n = normalizeTxFields(fields);
2722
+ const sig = expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature");
2723
+ const pk = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
2724
+ const w = new BincodeWriter();
2725
+ w.u64(n.chainId);
2726
+ w.u64(n.nonce);
2727
+ w.bytes(uint256Be(n.maxPriorityFeePerGas, "maxPriorityFeePerGas"));
2728
+ w.bytes(uint256Be(n.maxFeePerGas, "maxFeePerGas"));
2729
+ w.u64(n.gasLimit);
2730
+ if (n.to === null) {
2731
+ w.u8(0);
2732
+ } else {
2733
+ w.u8(1);
2734
+ w.bytes(n.to);
2735
+ }
2736
+ w.bytes(uint256Be(n.value, "value"));
2737
+ w.bytes(n.input);
2738
+ w.u64(0n);
2739
+ w.u64(BigInt(n.extensions.length));
2740
+ for (const ext of n.extensions) bincodeTypedExtensionInto(w, ext);
2741
+ bincodeMlDsa65OpaqueInto(w, sig);
2742
+ bincodeMlDsa65OpaqueInto(w, pk);
2743
+ return w.toBytes();
2744
+ }
2745
+ function normalizeTxFields(fields) {
2746
+ return {
2747
+ chainId: parseBigint(fields.chainId, "chainId"),
2748
+ nonce: parseBigint(fields.nonce, "nonce"),
2749
+ maxPriorityFeePerGas: parseBigint(fields.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
2750
+ maxFeePerGas: parseBigint(fields.maxFeePerGas, "maxFeePerGas"),
2751
+ gasLimit: parseBigint(fields.gasLimit, "gasLimit"),
2752
+ to: normalizeTo(fields.to),
2753
+ value: parseBigint(fields.value, "value"),
2754
+ input: normalizeBytes(fields.input ?? new Uint8Array(0), "input"),
2755
+ extensions: normalizeExtensions(fields.extensions)
2756
+ };
2757
+ }
2758
+ function normalizeTo(value) {
2759
+ if (value === null) return null;
2760
+ const bytes = normalizeBytes(value, "to");
2761
+ return expectBytes(bytes, 20, "to");
2762
+ }
2763
+ function normalizeBytes(value, label) {
2764
+ if (typeof value === "string") return hexToBytes2(value, label);
2765
+ return value instanceof Uint8Array ? value : Uint8Array.from(value);
2766
+ }
2767
+ function normalizeExtensions(value) {
2768
+ if (value === void 0) return [];
2769
+ return value.map((ext, index) => {
2770
+ if (!Number.isInteger(ext.kind) || ext.kind < 0 || ext.kind > 255) {
2771
+ throw new Error(`extensions[${index}].kind out of u8 range`);
2772
+ }
2773
+ const body = normalizeBytes("bodyHex" in ext ? ext.bodyHex : ext.body, `extensions[${index}].body`);
2774
+ if (body.length > 4294967295) {
2775
+ throw new Error(`extensions[${index}].body exceeds u32 length`);
2776
+ }
2777
+ return { kind: ext.kind, body };
2778
+ });
2779
+ }
2780
+ function encodeExtensionsForHash(extensions) {
2781
+ const chunks = [bigintToBeBytes(BigInt(extensions.length), 4, "extensions.length")];
2782
+ for (const ext of extensions) {
2783
+ chunks.push(
2784
+ Uint8Array.of(ext.kind),
2785
+ bigintToBeBytes(BigInt(ext.body.length), 4, "extension.body.length"),
2786
+ ext.body
2787
+ );
2788
+ }
2789
+ return concatBytes2(...chunks);
2790
+ }
2791
+ function uint256Be(value, label) {
2792
+ if (value < 0n || value >= 1n << 256n) throw new Error(`${label} out of u256 range`);
2793
+ const out = new Uint8Array(32);
2794
+ let v = value;
2795
+ for (let i = 31; i >= 0; i--) {
2796
+ out[i] = Number(v & 0xffn);
2797
+ v >>= 8n;
2798
+ }
2799
+ return out;
2800
+ }
2801
+ function bincodeMlDsa65OpaqueInto(w, raw) {
2802
+ w.enumVariant(ENUM_VARIANT_INDEX_ML_DSA_65);
2803
+ w.u16(STANDARD_ALGO_NUMBER_ML_DSA_65);
2804
+ w.bytes(raw);
2805
+ }
2806
+ function bincodeTypedExtensionInto(w, ext) {
2807
+ w.u8(ext.kind);
2808
+ w.bytes(ext.body);
2809
+ }
2810
+
2811
+ // src/crypto/ml-dsa.ts
2812
+ var ML_DSA_65_SEED_LEN = 32;
2813
+ var ML_DSA_65_SIGNING_KEY_LEN = 4032;
2814
+ var ML_DSA_65_PUBLIC_KEY_LEN = 1952;
2815
+ var ML_DSA_65_SIGNATURE_LEN = 3309;
2816
+ var STANDARD_ALGO_NUMBER_ML_DSA_65 = 1001;
2817
+ var ENUM_VARIANT_INDEX_ML_DSA_65 = 3;
2818
+ var ADDRESS_DERIVATION_DOMAIN = "MONO_ADDRESS_BLAKE3_20_V1";
2819
+ var ADDRESS_DERIVATION_DOMAIN_BYTES = new TextEncoder().encode(ADDRESS_DERIVATION_DOMAIN);
2820
+ var MlDsa65Backend = class _MlDsa65Backend {
2821
+ #secretKey;
2822
+ #publicKey;
2823
+ #addressBytes;
2824
+ #disposed = false;
2825
+ constructor(secretKey, publicKey) {
2826
+ this.#secretKey = expectBytes(secretKey, ML_DSA_65_SIGNING_KEY_LEN, "ML-DSA-65 secret key").slice();
2827
+ this.#publicKey = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key").slice();
2828
+ this.#addressBytes = mlDsa65AddressBytes(this.#publicKey);
2829
+ }
2830
+ static fromSeed(seed) {
2831
+ const kp = mlDsa_js.ml_dsa65.keygen(expectBytes(seed, ML_DSA_65_SEED_LEN, "ML-DSA-65 seed"));
2832
+ return new _MlDsa65Backend(kp.secretKey, kp.publicKey);
3329
2833
  }
3330
- if (typeof value === "string") {
3331
- validateDecimal(field2, value);
3332
- return value;
2834
+ publicKey() {
2835
+ return this.#publicKey.slice();
3333
2836
  }
3334
- if (typeof value === "number" && !Number.isSafeInteger(value)) {
3335
- throw new MrvValidationError(`${field2} must be a safe unsigned integer`);
2837
+ addressBytes() {
2838
+ return this.#addressBytes.slice();
3336
2839
  }
3337
- const out = BigInt(value);
3338
- if (out < 0n) throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
3339
- return out.toString();
3340
- }
3341
- function normalizeOptionalU64(field2, value) {
3342
- return value === void 0 ? void 0 : normalizeU64(value, field2);
3343
- }
3344
- function validateDecimal(field2, value) {
3345
- if (!/^(0|[1-9][0-9]*)$/.test(value)) {
3346
- throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
2840
+ getAddress() {
2841
+ return bytesToHex2(this.#addressBytes);
3347
2842
  }
3348
- try {
3349
- BigInt(value);
3350
- } catch {
3351
- throw new MrvValidationError(`${field2} must be a canonical unsigned decimal string`);
2843
+ sign(message) {
2844
+ if (this.#disposed) {
2845
+ throw new Error("MlDsa65Backend disposed");
2846
+ }
2847
+ return mlDsa_js.ml_dsa65.sign(message, this.#secretKey, { extraEntropy: false });
3352
2848
  }
3353
- }
3354
- function validateExecutionUnitLimit(field2, value) {
3355
- if (value !== void 0 && BigInt(value) === 0n) {
3356
- throw new MrvValidationError(`${field2} must be greater than zero`);
2849
+ /**
2850
+ * Best-effort deterministic wipe of the in-memory secret key. Zeroes the
2851
+ * SDK-held `#secretKey` copy and makes any subsequent `sign()` /
2852
+ * `signPrehash()` / `signEvmTx()` throw `"MlDsa65Backend disposed"` rather
2853
+ * than signing with a zeroed key. Idempotent. Public material
2854
+ * (`publicKey()` / `getAddress()` / `verify()`) stays usable.
2855
+ *
2856
+ * Defense-in-depth (S1-01): narrows the post-lock residency window of the
2857
+ * ML-DSA-65 secret in the JS heap. `@noble/post-quantum`'s internal
2858
+ * transient keygen/sign buffers are out of scope; the SDK-held copy is the
2859
+ * meaningful residency win.
2860
+ */
2861
+ dispose() {
2862
+ this.#secretKey.fill(0);
2863
+ this.#disposed = true;
3357
2864
  }
3358
- }
3359
- function normalizeU64(value, field2) {
3360
- if (typeof value === "number" && !Number.isSafeInteger(value)) {
3361
- throw new MrvValidationError(`${field2} must be a safe unsigned integer`);
2865
+ /** Alias for {@link dispose}. */
2866
+ zeroize() {
2867
+ this.dispose();
3362
2868
  }
3363
- const out = BigInt(value);
3364
- if (out < 0n || out > 0xffffffffffffffffn) {
3365
- throw new MrvValidationError(`${field2} must fit in u64`);
2869
+ /** Whether {@link dispose} has been called (the secret key is wiped). */
2870
+ get disposed() {
2871
+ return this.#disposed;
3366
2872
  }
3367
- return out;
3368
- }
3369
- function validateHexLength(field2, value, expected) {
3370
- const bytes = hexToBytes3(value, field2);
3371
- if (bytes.length !== expected) throw new MrvValidationError(`${field2} must be ${expected} bytes`);
3372
- }
3373
- function bytesFrom(value, field2) {
3374
- if (typeof value === "string") return hexToBytes3(value, field2);
3375
- return value instanceof Uint8Array ? value : Uint8Array.from(value);
3376
- }
3377
- function hexToBytes3(value, field2) {
3378
- if (!/^0x(?:[0-9a-fA-F]{2})*$/.test(value)) {
3379
- throw new MrvValidationError(`${field2} must be 0x-prefixed even-length hex`);
2873
+ signPrehash(digest) {
2874
+ return this.sign(expectBytes(digest, 32, "prehash"));
3380
2875
  }
3381
- const out = new Uint8Array((value.length - 2) / 2);
3382
- for (let i = 0; i < out.length; i++) {
3383
- out[i] = Number.parseInt(value.slice(2 + i * 2, 4 + i * 2), 16);
2876
+ verify(message, signature) {
2877
+ return mlDsa_js.ml_dsa65.verify(
2878
+ expectBytes(signature, ML_DSA_65_SIGNATURE_LEN, "ML-DSA-65 signature"),
2879
+ message,
2880
+ this.#publicKey
2881
+ );
3384
2882
  }
3385
- return out;
3386
- }
3387
- function bytesToHex3(bytes) {
3388
- return `0x${[...bytes].map((b) => b.toString(16).padStart(2, "0")).join("")}`;
3389
- }
3390
- function concatBytes3(...parts) {
3391
- const len = parts.reduce((sum, item) => sum + item.length, 0);
3392
- const out = new Uint8Array(len);
3393
- let offset = 0;
3394
- for (const part of parts) {
3395
- out.set(part, offset);
3396
- offset += part.length;
2883
+ signEvmTx(fields) {
2884
+ const txHashPreimage = encodeTransactionForHash(fields, 1);
2885
+ const sighash = sha3_js.keccak_256(txHashPreimage);
2886
+ const signature = this.sign(sighash);
2887
+ const wireBytes = bincodeSignedTransaction(fields, signature, this.#publicKey);
2888
+ const txHash = sha3_js.keccak_256(
2889
+ concatBytes2(
2890
+ encodeTransactionForHash(fields, 2),
2891
+ signature,
2892
+ this.#publicKey
2893
+ )
2894
+ );
2895
+ return {
2896
+ wireHex: bytesToHex2(wireBytes).slice(2),
2897
+ wireBytes,
2898
+ sighash,
2899
+ txHash
2900
+ };
3397
2901
  }
3398
- return out;
2902
+ };
2903
+ function mlDsa65AddressFromPublicKey(publicKey) {
2904
+ return bytesToHex2(mlDsa65AddressBytes(publicKey));
3399
2905
  }
3400
- function isIdentifier(value) {
3401
- return /^[a-z][a-z0-9_]*$/.test(value);
2906
+ function mlDsa65AddressBytes(publicKey) {
2907
+ const bytes = expectBytes(publicKey, ML_DSA_65_PUBLIC_KEY_LEN, "ML-DSA-65 public key");
2908
+ return blake3_js.blake3(concatBytes2(
2909
+ ADDRESS_DERIVATION_DOMAIN_BYTES,
2910
+ bigintToBeBytes(BigInt(STANDARD_ALGO_NUMBER_ML_DSA_65), 2, "ML-DSA-65 algo id"),
2911
+ bytes
2912
+ )).slice(0, 20);
3402
2913
  }
3403
2914
 
3404
2915
  // src/registry.ts
@@ -3408,8 +2919,8 @@ var TESTNET_69420 = {
3408
2919
  network: "testnet-69420",
3409
2920
  display_name: "Monolythium Testnet",
3410
2921
  description: "Public Monolythium testnet. Testnet state may reset without notice; do not store value on this network.",
3411
- genesis_hash: "0x363fb60abd3f481e16fe74d6a3e5afd35d6d3ba9cc26e186f27d4195cd5a7359",
3412
- binary_sha: "76803f49",
2922
+ genesis_hash: "0xb52b59d667a0ad97c531607b840b7082547ba3151aa11a819eb6916b080b1ca9",
2923
+ binary_sha: "6f33aa30",
3413
2924
  rpc: [
3414
2925
  {
3415
2926
  url: "http://178.105.12.9:8545",
@@ -4989,14 +4500,6 @@ var RpcClient = class _RpcClient {
4989
4500
  async lythSubmitPendingChange(envelope) {
4990
4501
  return this.call("lyth_submitPendingChange", [envelope]);
4991
4502
  }
4992
- /** `lyth_submitEncrypted` — submit a bincode-encoded encrypted envelope hex. */
4993
- async lythSubmitEncrypted(envelopeHex) {
4994
- return this.call("lyth_submitEncrypted", [envelopeHex]);
4995
- }
4996
- /** `lyth_getEncryptionKey` — cluster ML-KEM encapsulation key. */
4997
- async lythGetEncryptionKey() {
4998
- return this.call("lyth_getEncryptionKey", []);
4999
- }
5000
4503
  /** `lyth_syncStatus` — DAG-sync driver snapshot. */
5001
4504
  async lythSyncStatus() {
5002
4505
  const v = await this.call("lyth_syncStatus", []);
@@ -8153,7 +7656,7 @@ function verifyBoundedReceiptProof(proof) {
8153
7656
  }
8154
7657
  const actualRoot = computeNoEvmReceiptsRoot(receipts);
8155
7658
  const expectedRoot = decodeHash(proof.receiptsRoot, "receiptsRoot");
8156
- if (!bytesEqual3(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
7659
+ if (!bytesEqual2(expectedRoot, decodeHash(actualRoot, "computedReceiptsRoot"))) {
8157
7660
  throw new NoEvmReceiptProofError(
8158
7661
  "receipts_root_mismatch",
8159
7662
  `receiptsRoot mismatch: expected ${proof.receiptsRoot}, computed ${actualRoot}`
@@ -8161,7 +7664,7 @@ function verifyBoundedReceiptProof(proof) {
8161
7664
  }
8162
7665
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
8163
7666
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
8164
- if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7667
+ if (!bytesEqual2(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
8165
7668
  throw new NoEvmReceiptProofError(
8166
7669
  "target_receipt_hash_mismatch",
8167
7670
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -8218,7 +7721,7 @@ function verifyCompactReceiptProof(proof) {
8218
7721
  const targetReceipt = decodeHexBytes(targetReceiptBytes, "targetReceiptBytes");
8219
7722
  const actualTargetHash = computeNoEvmTargetReceiptHash(targetReceipt);
8220
7723
  const expectedTargetHash = decodeHash(proof.targetReceiptHash, "targetReceiptHash");
8221
- if (!bytesEqual3(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
7724
+ if (!bytesEqual2(expectedTargetHash, decodeHash(actualTargetHash, "computedTargetReceiptHash"))) {
8222
7725
  throw new NoEvmReceiptProofError(
8223
7726
  "target_receipt_hash_mismatch",
8224
7727
  `targetReceiptHash mismatch: expected ${proof.targetReceiptHash}, computed ${actualTargetHash}`
@@ -8229,7 +7732,7 @@ function verifyCompactReceiptProof(proof) {
8229
7732
  compactProof.leafHash,
8230
7733
  "compactInclusionProof.leafHash"
8231
7734
  );
8232
- if (!bytesEqual3(expectedLeafHashBytes, actualLeafHashBytes)) {
7735
+ if (!bytesEqual2(expectedLeafHashBytes, actualLeafHashBytes)) {
8233
7736
  throw new NoEvmReceiptProofError(
8234
7737
  "compact_leaf_hash_mismatch",
8235
7738
  `compactInclusionProof.leafHash mismatch: expected ${compactProof.leafHash}, computed ${bytesToHex6(
@@ -8239,7 +7742,7 @@ function verifyCompactReceiptProof(proof) {
8239
7742
  }
8240
7743
  const compactRootBytes = decodeHash(compactProof.root, "compactInclusionProof.root");
8241
7744
  const receiptsRootBytes = decodeHash(proof.receiptsRoot, "receiptsRoot");
8242
- if (!bytesEqual3(receiptsRootBytes, compactRootBytes)) {
7745
+ if (!bytesEqual2(receiptsRootBytes, compactRootBytes)) {
8243
7746
  throw new NoEvmReceiptProofError(
8244
7747
  "compact_root_mismatch",
8245
7748
  `receiptsRoot must equal compactInclusionProof.root: receiptsRoot ${proof.receiptsRoot}, compact root ${compactProof.root}`
@@ -8262,7 +7765,7 @@ function verifyCompactReceiptProof(proof) {
8262
7765
  siblingHashes,
8263
7766
  pathSides
8264
7767
  );
8265
- if (!bytesEqual3(actualRootBytes, compactRootBytes)) {
7768
+ if (!bytesEqual2(actualRootBytes, compactRootBytes)) {
8266
7769
  throw new NoEvmReceiptProofError(
8267
7770
  "compact_path_mismatch",
8268
7771
  `compact inclusion path mismatch: expected ${compactProof.root}, computed ${bytesToHex6(
@@ -8416,7 +7919,7 @@ function validateCoveringSnapshotObject(snapshot, archiveContentHash, proofBlock
8416
7919
  "archiveProof.coveringSnapshot.checkpointTo must match blockHeight"
8417
7920
  );
8418
7921
  }
8419
- if (!bytesEqual3(checkpointContentHash, archiveContentHash)) {
7922
+ if (!bytesEqual2(checkpointContentHash, archiveContentHash)) {
8420
7923
  throw new NoEvmReceiptProofError(
8421
7924
  "invalid_proof_shape",
8422
7925
  "archiveProof.coveringSnapshot.checkpointContentHash must match archiveProof.contentHash"
@@ -8615,7 +8118,7 @@ function validateFinalityBlockReference(blockReference, round, proofBlockHash) {
8615
8118
  );
8616
8119
  if (proofBlockHash !== void 0) {
8617
8120
  const blockHash = decodeHash(proofBlockHash, "blockHash");
8618
- if (!bytesEqual3(digest, blockHash)) {
8121
+ if (!bytesEqual2(digest, blockHash)) {
8619
8122
  throw new NoEvmReceiptProofError(
8620
8123
  "invalid_proof_shape",
8621
8124
  "finalityEvidence.blockReference.digest must match blockHash"
@@ -8965,7 +8468,7 @@ function assertHashBytes(value, field2) {
8965
8468
  function isRecord3(value) {
8966
8469
  return typeof value === "object" && value !== null && !Array.isArray(value);
8967
8470
  }
8968
- function bytesEqual3(a, b) {
8471
+ function bytesEqual2(a, b) {
8969
8472
  if (a.length !== b.length) return false;
8970
8473
  let diff = 0;
8971
8474
  for (let index = 0; index < a.length; index++) {
@@ -8980,6 +8483,191 @@ function bytesToHex6(bytes) {
8980
8483
  }
8981
8484
  return out;
8982
8485
  }
8486
+ var TREE_TAG_LEAF = 0;
8487
+ var TREE_TAG_INTERNAL = 1;
8488
+ var TREE_TERMINATOR = new Uint8Array(32);
8489
+ var HASH_BYTE_LENGTH2 = 32;
8490
+ var PROOF_KIND_BINARY = "binary";
8491
+ var ProofVerifyError = class extends Error {
8492
+ constructor(code, message) {
8493
+ super(message);
8494
+ this.code = code;
8495
+ this.name = "ProofVerifyError";
8496
+ }
8497
+ code;
8498
+ };
8499
+ function hashValue(data) {
8500
+ return blake3_js.blake3(data);
8501
+ }
8502
+ function hashLeaf(path, valueHash) {
8503
+ const buf = new Uint8Array(1 + 32 + 32);
8504
+ buf[0] = TREE_TAG_LEAF;
8505
+ buf.set(path, 1);
8506
+ buf.set(valueHash, 33);
8507
+ return blake3_js.blake3(buf);
8508
+ }
8509
+ function compress(left, right) {
8510
+ if (isTerminator(left) && isTerminator(right)) {
8511
+ return TREE_TERMINATOR;
8512
+ }
8513
+ const buf = new Uint8Array(1 + 32 + 32);
8514
+ buf[0] = TREE_TAG_INTERNAL;
8515
+ buf.set(left, 1);
8516
+ buf.set(right, 33);
8517
+ return blake3_js.blake3(buf);
8518
+ }
8519
+ function isTerminator(hash) {
8520
+ for (let i = 0; i < hash.length; i++) {
8521
+ if (hash[i] !== 0) return false;
8522
+ }
8523
+ return true;
8524
+ }
8525
+ function pathBit(path, depth) {
8526
+ const byte = path[depth >>> 3];
8527
+ return byte >>> 7 - (depth & 7) & 1;
8528
+ }
8529
+ function foldToRoot(target, current, siblings) {
8530
+ const depth = siblings.length;
8531
+ let node = current;
8532
+ for (let i = 0; i < depth; i++) {
8533
+ const level = depth - 1 - i;
8534
+ const sibling = siblings[i];
8535
+ node = pathBit(target, level) === 0 ? compress(node, sibling) : compress(sibling, node);
8536
+ }
8537
+ return node;
8538
+ }
8539
+ function bytesEqual3(a, b) {
8540
+ if (a.length !== b.length) return false;
8541
+ for (let i = 0; i < a.length; i++) {
8542
+ if (a[i] !== b[i]) return false;
8543
+ }
8544
+ return true;
8545
+ }
8546
+ function decodeHash2(value, field2) {
8547
+ let bytes;
8548
+ try {
8549
+ bytes = hexToBytes2(value, field2);
8550
+ } catch (cause) {
8551
+ throw new ProofVerifyError("invalid_hex", `${field2} is not valid hex: ${String(cause)}`);
8552
+ }
8553
+ if (bytes.length !== HASH_BYTE_LENGTH2) {
8554
+ throw new ProofVerifyError(
8555
+ "invalid_hash_length",
8556
+ `${field2} must be ${HASH_BYTE_LENGTH2} bytes, got ${bytes.length}`
8557
+ );
8558
+ }
8559
+ return bytes;
8560
+ }
8561
+ function decodeSiblings(siblings) {
8562
+ return siblings.map((sib, index) => decodeHash2(sib, `siblings[${index}]`));
8563
+ }
8564
+ function assertBinaryKind(proofKind) {
8565
+ if (proofKind !== PROOF_KIND_BINARY) {
8566
+ throw new ProofVerifyError(
8567
+ "unsupported_proof_kind",
8568
+ `unsupported proofKind: ${proofKind} (expected ${PROOF_KIND_BINARY})`
8569
+ );
8570
+ }
8571
+ }
8572
+ var ProofVerifier = class {
8573
+ /**
8574
+ * Verify a {@link ProofEnvelope} inclusion proof against `stateRoot`.
8575
+ *
8576
+ * @returns `true` when the proof binds `(key, value)` to `stateRoot`.
8577
+ */
8578
+ verifyInclusion(stateRoot, proof) {
8579
+ assertBinaryKind(proof.proofKind);
8580
+ const root = toHashBytes(stateRoot, "stateRoot");
8581
+ const key = decodeHex(proof.key, "proof.key");
8582
+ const value = decodeHex(proof.value, "proof.value");
8583
+ const siblings = decodeSiblings(proof.siblings);
8584
+ const target = hashValue(key);
8585
+ const leaf = hashLeaf(target, hashValue(value));
8586
+ return bytesEqual3(foldToRoot(target, leaf, siblings), root);
8587
+ }
8588
+ /**
8589
+ * Verify a {@link ProofEnvelope} inclusion proof, throwing a
8590
+ * {@link ProofVerifyError} on failure (the loud variant for wallets).
8591
+ */
8592
+ assertInclusion(stateRoot, proof) {
8593
+ if (!this.verifyInclusion(stateRoot, proof)) {
8594
+ throw new ProofVerifyError(
8595
+ "proof_verify_failed",
8596
+ `inclusion proof for key ${proof.key} does not verify against the state root`
8597
+ );
8598
+ }
8599
+ }
8600
+ /**
8601
+ * Verify a {@link NonInclusionProofEnvelope} against `stateRoot`.
8602
+ *
8603
+ * Returns `false` for a `found` endpoint (that is an inclusion, not
8604
+ * absence) or an `otherLeaf` whose path equals the queried key. Mirrors
8605
+ * `protocore_state::verify_binary_non_inclusion`.
8606
+ */
8607
+ verifyNonInclusion(stateRoot, proof) {
8608
+ assertBinaryKind(proof.proofKind);
8609
+ const root = toHashBytes(stateRoot, "stateRoot");
8610
+ const key = decodeHex(proof.key, "proof.key");
8611
+ const siblings = decodeSiblings(proof.siblings);
8612
+ const target = hashValue(key);
8613
+ let endpointHash;
8614
+ switch (proof.endpoint.kind) {
8615
+ case "found":
8616
+ return false;
8617
+ case "terminator":
8618
+ endpointHash = TREE_TERMINATOR;
8619
+ break;
8620
+ case "otherLeaf": {
8621
+ const path = decodeHash2(proof.endpoint.path, "endpoint.path");
8622
+ if (bytesEqual3(path, target)) return false;
8623
+ endpointHash = hashLeaf(path, decodeHash2(proof.endpoint.valueHash, "endpoint.valueHash"));
8624
+ break;
8625
+ }
8626
+ }
8627
+ return bytesEqual3(foldToRoot(target, endpointHash, siblings), root);
8628
+ }
8629
+ /**
8630
+ * Verify a non-inclusion proof, throwing a {@link ProofVerifyError} on
8631
+ * failure.
8632
+ */
8633
+ assertNonInclusion(stateRoot, proof) {
8634
+ if (!this.verifyNonInclusion(stateRoot, proof)) {
8635
+ throw new ProofVerifyError(
8636
+ "non_inclusion_verify_failed",
8637
+ `non-inclusion proof for key ${proof.key} does not verify against the state root`
8638
+ );
8639
+ }
8640
+ }
8641
+ };
8642
+ var proofVerifier = new ProofVerifier();
8643
+ function toHashBytes(value, field2) {
8644
+ if (typeof value === "string") return decodeHash2(value, field2);
8645
+ return expectBytes(value, HASH_BYTE_LENGTH2, field2);
8646
+ }
8647
+ function decodeHex(value, field2) {
8648
+ try {
8649
+ return hexToBytes2(value, field2);
8650
+ } catch (cause) {
8651
+ throw new ProofVerifyError("invalid_hex", `${field2} is not valid hex: ${String(cause)}`);
8652
+ }
8653
+ }
8654
+ function asBinaryProofEnvelope(proof) {
8655
+ if (proof == null || typeof proof !== "object") return null;
8656
+ const obj = proof;
8657
+ if (obj.proofKind !== PROOF_KIND_BINARY) return null;
8658
+ if (typeof obj.key !== "string" || typeof obj.value !== "string" || !Array.isArray(obj.siblings) || obj.siblings.some((s) => typeof s !== "string")) {
8659
+ return null;
8660
+ }
8661
+ return {
8662
+ proofKind: PROOF_KIND_BINARY,
8663
+ siblings: obj.siblings,
8664
+ key: obj.key,
8665
+ value: obj.value
8666
+ };
8667
+ }
8668
+ function hashToHex(hash) {
8669
+ return bytesToHex2(hash);
8670
+ }
8983
8671
 
8984
8672
  // src/native-dev.ts
8985
8673
  var NATIVE_DEV_HOST_API_VERSION = "0.1.0";
@@ -9238,7 +8926,6 @@ function pqm1MnemonicToMlDsa65Backend(mnemonic) {
9238
8926
 
9239
8927
  // src/cluster-join.ts
9240
8928
  var DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT = REGISTRY_DEFAULT_EXECUTION_UNIT_LIMIT;
9241
- var DEFAULT_OPERATOR_SEAL_KEY_EXECUTION_UNIT_LIMIT = REGISTRY_DEFAULT_EXECUTION_UNIT_LIMIT;
9242
8929
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
9243
8930
  var MAX_UINT32 = (1n << 32n) - 1n;
9244
8931
  function deriveClusterJoinOperatorId(operatorPubkey) {
@@ -9346,24 +9033,6 @@ function buildVoteClusterAdmitTxFields(args) {
9346
9033
  })
9347
9034
  };
9348
9035
  }
9349
- function buildPublishOperatorSealKeyTxFields(args) {
9350
- return {
9351
- chainId: args.chainId,
9352
- nonce: args.nonce,
9353
- maxFeePerGas: parseBigint(args.fee.maxFeePerGas, "maxFeePerGas"),
9354
- maxPriorityFeePerGas: parseBigint(args.fee.maxPriorityFeePerGas, "maxPriorityFeePerGas"),
9355
- gasLimit: parseBigint(
9356
- args.fee.gasLimit ?? DEFAULT_OPERATOR_SEAL_KEY_EXECUTION_UNIT_LIMIT,
9357
- "gasLimit"
9358
- ),
9359
- to: nodeRegistryAddressHex(),
9360
- value: 0n,
9361
- input: encodePublishOperatorSealKeyCalldata({
9362
- peerId: normalizeOperatorId(args.peerId),
9363
- sealEk: normalizeOperatorSealEk(args.sealEk)
9364
- })
9365
- };
9366
- }
9367
9036
  async function submitRequestClusterJoin(args) {
9368
9037
  const clusterId = parseUint32(args.clusterId, "clusterId");
9369
9038
  const operatorPubkey = normalizeConsensusPubkey(args.operatorPubkey, "operatorPubkey");
@@ -9390,7 +9059,7 @@ async function submitRequestClusterJoin(args) {
9390
9059
  operatorPubkey,
9391
9060
  bondLythoshi: args.bondLythoshi
9392
9061
  });
9393
- return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex, args);
9062
+ return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex);
9394
9063
  }
9395
9064
  async function submitVoteClusterAdmit(args) {
9396
9065
  const clusterId = parseUint32(args.clusterId, "clusterId");
@@ -9417,62 +9086,9 @@ async function submitVoteClusterAdmit(args) {
9417
9086
  operatorId: operatorIdHex,
9418
9087
  voterPubkey: args.voterPubkey
9419
9088
  });
9420
- return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex, args);
9421
- }
9422
- async function submitPublishOperatorSealKey(args) {
9423
- const operatorIdHex = normalizeOperatorId(args.peerId);
9424
- const sealEk = normalizeOperatorSealEk(args.sealEk);
9425
- const backend = pqm1MnemonicToMlDsa65Backend(args.mnemonic);
9426
- const senderAddress = addressToTypedBech32("user", backend.addressBytes());
9427
- const [chainId, nonce, quote] = await Promise.all([
9428
- args.client.ethChainId(),
9429
- args.client.lythGetTransactionCount(senderAddress),
9430
- args.client.lythExecutionUnitPrice()
9431
- ]);
9432
- const tx = buildPublishOperatorSealKeyTxFields({
9433
- chainId,
9434
- nonce,
9435
- fee: resolveClusterJoinExecutionFee(quote, {
9436
- ...args,
9437
- executionUnitLimit: args.executionUnitLimit ?? DEFAULT_OPERATOR_SEAL_KEY_EXECUTION_UNIT_LIMIT
9438
- }),
9439
- peerId: operatorIdHex,
9440
- sealEk
9441
- });
9442
- const plaintext = buildPlaintextSubmission({ backend, tx });
9443
- const txHash = await submitPlaintextTransaction(
9444
- args.client,
9445
- plaintext.signedTxWireHex,
9446
- plaintext.innerTxHashHex
9447
- );
9448
- return {
9449
- txHash,
9450
- operatorIdHex,
9451
- innerSighashHex: plaintext.innerSighashHex,
9452
- signedTxWireBytes: plaintext.innerWireBytes
9453
- };
9089
+ return submitClusterJoinTx(args.client, backend, tx, clusterId, operatorIdHex);
9454
9090
  }
9455
- async function submitClusterJoinTx(client, backend, tx, clusterId, operatorIdHex, options) {
9456
- if (options.private !== false) {
9457
- const encrypted = await buildEncryptedSubmission({
9458
- client,
9459
- backend,
9460
- tx,
9461
- clusterId: Number(clusterId),
9462
- clusterSealKeys: options.clusterSealKeys,
9463
- clusterSealKeysSource: options.clusterSealKeysSource,
9464
- class: MempoolClass.ContractCall
9465
- });
9466
- assertRpcHash(await submitEncryptedEnvelope(client, encrypted.envelopeWireHex));
9467
- return {
9468
- txHash: encrypted.innerTxHashHex,
9469
- clusterId: clusterId.toString(10),
9470
- operatorIdHex,
9471
- innerSighashHex: encrypted.innerSighashHex,
9472
- signedTxWireBytes: encrypted.innerWireBytes,
9473
- envelopeWireBytes: hexByteLength(encrypted.envelopeWireHex)
9474
- };
9475
- }
9091
+ async function submitClusterJoinTx(client, backend, tx, clusterId, operatorIdHex) {
9476
9092
  const plaintext = buildPlaintextSubmission({ backend, tx });
9477
9093
  const txHash = await submitPlaintextTransaction(
9478
9094
  client,
@@ -9487,16 +9103,6 @@ async function submitClusterJoinTx(client, backend, tx, clusterId, operatorIdHex
9487
9103
  signedTxWireBytes: plaintext.innerWireBytes
9488
9104
  };
9489
9105
  }
9490
- function hexByteLength(value) {
9491
- const clean = value.startsWith("0x") || value.startsWith("0X") ? value.slice(2) : value;
9492
- return clean.length / 2;
9493
- }
9494
- function assertRpcHash(value) {
9495
- const bytes = hexToBytes2(value, "lyth_submitEncrypted tx hash");
9496
- if (bytes.length !== 32) {
9497
- throw new Error(`lyth_submitEncrypted tx hash must be 32 bytes, got ${bytes.length}`);
9498
- }
9499
- }
9500
9106
  function adaptNativeClusterJoinRequest(request) {
9501
9107
  return {
9502
9108
  owner: request.owner ?? ZERO_ADDRESS,
@@ -9539,10 +9145,6 @@ function normalizeOperatorId(value) {
9539
9145
  const bytes = typeof value === "string" ? hexToBytes2(value, "operatorId") : value;
9540
9146
  return bytesToHex2(expectBytes(bytes, 32, "operatorId"));
9541
9147
  }
9542
- function normalizeOperatorSealEk(value) {
9543
- const bytes = typeof value === "string" ? hexToBytes2(value, "sealEk") : value;
9544
- return expectBytes(bytes, NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES, "sealEk").slice();
9545
- }
9546
9148
  function parseUint32(value, label) {
9547
9149
  const parsed = parseBigint(value, label);
9548
9150
  if (parsed < 0n || parsed > MAX_UINT32) {
@@ -11051,6 +10653,12 @@ function wordToBigint(word) {
11051
10653
  }
11052
10654
  return out;
11053
10655
  }
10656
+
10657
+ // src/crypto/envelope.ts
10658
+ var MempoolClass = {
10659
+ CLOBOp: 3};
10660
+
10661
+ // src/market-actions.ts
11054
10662
  var CLOB_MARKET_ID_DOMAIN_TAG = 193;
11055
10663
  var NATIVE_MARKET_MODULE_ADDRESS_BYTES = "0x4d41524b45545f4e41544956455f4d4f445f5631";
11056
10664
  var NATIVE_MARKET_MODULE_ADDRESS = addressToTypedBech32(
@@ -12402,7 +12010,6 @@ exports.CLOB_MARKET_ID_DOMAIN_TAG = CLOB_MARKET_ID_DOMAIN_TAG;
12402
12010
  exports.CLOB_SELECTORS = CLOB_SELECTORS;
12403
12011
  exports.CLUSTER_FORMED_EVENT_SIG = CLUSTER_FORMED_EVENT_SIG;
12404
12012
  exports.DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT = DEFAULT_CLUSTER_JOIN_EXECUTION_UNIT_LIMIT;
12405
- exports.DEFAULT_OPERATOR_SEAL_KEY_EXECUTION_UNIT_LIMIT = DEFAULT_OPERATOR_SEAL_KEY_EXECUTION_UNIT_LIMIT;
12406
12013
  exports.DELEGATION_REVERT_TAGS = DELEGATION_REVERT_TAGS;
12407
12014
  exports.DELEGATION_SELECTORS = DELEGATION_SELECTORS;
12408
12015
  exports.DIVERSITY_SCORE_MAX = DIVERSITY_SCORE_MAX;
@@ -12491,7 +12098,6 @@ exports.NODE_REGISTRY_MERKLE_LEAF_DOMAIN = NODE_REGISTRY_MERKLE_LEAF_DOMAIN;
12491
12098
  exports.NODE_REGISTRY_MIN_ARCHIVE_LEAF_COUNT = NODE_REGISTRY_MIN_ARCHIVE_LEAF_COUNT;
12492
12099
  exports.NODE_REGISTRY_OPERATOR_ALIAS_MAX_BYTES = NODE_REGISTRY_OPERATOR_ALIAS_MAX_BYTES;
12493
12100
  exports.NODE_REGISTRY_OPERATOR_MONIKER_MAX_BYTES = NODE_REGISTRY_OPERATOR_MONIKER_MAX_BYTES;
12494
- exports.NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES = NODE_REGISTRY_OPERATOR_SEAL_EK_BYTES;
12495
12101
  exports.NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID = NODE_REGISTRY_PENDING_CHANGE_MAX_INTENT_ID;
12496
12102
  exports.NODE_REGISTRY_PUBLIC_SERVICE_MASK = NODE_REGISTRY_PUBLIC_SERVICE_MASK;
12497
12103
  exports.NODE_REGISTRY_SELECTORS = NODE_REGISTRY_SELECTORS;
@@ -12524,6 +12130,7 @@ exports.OperatorTrustError = OperatorTrustError;
12524
12130
  exports.OracleEventError = OracleEventError;
12525
12131
  exports.PENDING_CHANGE_KIND_CODES = PENDING_CHANGE_KIND_CODES;
12526
12132
  exports.PRECOMPILE_ADDRESSES = PRECOMPILE_ADDRESSES;
12133
+ exports.PROOF_KIND_BINARY = PROOF_KIND_BINARY;
12527
12134
  exports.PROTOCOL_MAX_OPERATOR_FEE_BPS = PROTOCOL_MAX_OPERATOR_FEE_BPS;
12528
12135
  exports.PROVER_MARKET_ADDRESS = PROVER_MARKET_ADDRESS;
12529
12136
  exports.PROVER_MARKET_BID_DOMAIN = PROVER_MARKET_BID_DOMAIN;
@@ -12535,6 +12142,8 @@ exports.PROVER_SLASH_REASON_BAD_PROOF = PROVER_SLASH_REASON_BAD_PROOF;
12535
12142
  exports.PROVER_SLASH_REASON_NON_DELIVERY = PROVER_SLASH_REASON_NON_DELIVERY;
12536
12143
  exports.PUBKEY_REGISTRY_ML_DSA_65_PUBLIC_KEY_LEN = PUBKEY_REGISTRY_ML_DSA_65_PUBLIC_KEY_LEN;
12537
12144
  exports.PUBKEY_REGISTRY_SELECTORS = PUBKEY_REGISTRY_SELECTORS;
12145
+ exports.ProofVerifier = ProofVerifier;
12146
+ exports.ProofVerifyError = ProofVerifyError;
12538
12147
  exports.ProverMarketError = ProverMarketError;
12539
12148
  exports.PubkeyRegistryError = PubkeyRegistryError;
12540
12149
  exports.QUARANTINED_RPC_CODE = QUARANTINED_RPC_CODE;
@@ -12575,6 +12184,7 @@ exports.allowRootFor = allowRootFor;
12575
12184
  exports.apiEndpointFromRpcEndpoint = apiEndpointFromRpcEndpoint;
12576
12185
  exports.archiveMerkleInnerHash = archiveMerkleInnerHash;
12577
12186
  exports.archiveMerkleLeafHash = archiveMerkleLeafHash;
12187
+ exports.asBinaryProofEnvelope = asBinaryProofEnvelope;
12578
12188
  exports.assembleMultisigSigned = assembleMultisigSigned;
12579
12189
  exports.assembleMultisigWitness = assembleMultisigWitness;
12580
12190
  exports.assertMrvCallNativeSubmissionPlan = assertMrvCallNativeSubmissionPlan;
@@ -12640,7 +12250,6 @@ exports.buildPlaceLimitOrderViaPlan = buildPlaceLimitOrderViaPlan;
12640
12250
  exports.buildPlaceSpotLimitOrderPlan = buildPlaceSpotLimitOrderPlan;
12641
12251
  exports.buildPlaceSpotMarketOrderExPlan = buildPlaceSpotMarketOrderExPlan;
12642
12252
  exports.buildPlaceSpotMarketOrderPlan = buildPlaceSpotMarketOrderPlan;
12643
- exports.buildPublishOperatorSealKeyTxFields = buildPublishOperatorSealKeyTxFields;
12644
12253
  exports.buildRequestClusterJoinTxFields = buildRequestClusterJoinTxFields;
12645
12254
  exports.buildVoteClusterAdmitTxFields = buildVoteClusterAdmitTxFields;
12646
12255
  exports.categoryRoot = categoryRoot;
@@ -12673,7 +12282,6 @@ exports.decodeNativeReceiptResponse = decodeNativeReceiptResponse;
12673
12282
  exports.decodeNoEvmReceiptTranscript = decodeNoEvmReceiptTranscript;
12674
12283
  exports.decodeOperatorFeeChargedEvent = decodeOperatorFeeChargedEvent;
12675
12284
  exports.decodeOperatorNetworkMetadata = decodeOperatorNetworkMetadata;
12676
- exports.decodeOperatorSealKey = decodeOperatorSealKey;
12677
12285
  exports.decodeOracleEvent = decodeOracleEvent;
12678
12286
  exports.decodePendingCharter = decodePendingCharter;
12679
12287
  exports.decodeProbeAuthority = decodeProbeAuthority;
@@ -12720,7 +12328,6 @@ exports.encodeExpireClusterJoinCalldata = encodeExpireClusterJoinCalldata;
12720
12328
  exports.encodeFormClusterCalldata = encodeFormClusterCalldata;
12721
12329
  exports.encodeFormClusterV2Calldata = encodeFormClusterV2Calldata;
12722
12330
  exports.encodeGetClusterJoinRequestCalldata = encodeGetClusterJoinRequestCalldata;
12723
- exports.encodeGetOperatorSealKeyCalldata = encodeGetOperatorSealKeyCalldata;
12724
12331
  exports.encodeGetPendingCharterCalldata = encodeGetPendingCharterCalldata;
12725
12332
  exports.encodeGetProbeAuthorityCalldata = encodeGetProbeAuthorityCalldata;
12726
12333
  exports.encodeHasPubkeyCalldata = encodeHasPubkeyCalldata;
@@ -12780,7 +12387,6 @@ exports.encodePlaceLimitOrderCalldata = encodePlaceLimitOrderCalldata;
12780
12387
  exports.encodePlaceLimitOrderViaCalldata = encodePlaceLimitOrderViaCalldata;
12781
12388
  exports.encodePlaceMarketOrderCalldata = encodePlaceMarketOrderCalldata;
12782
12389
  exports.encodePlaceMarketOrderExCalldata = encodePlaceMarketOrderExCalldata;
12783
- exports.encodePublishOperatorSealKeyCalldata = encodePublishOperatorSealKeyCalldata;
12784
12390
  exports.encodeRecoverOperatorNodeCalldata = encodeRecoverOperatorNodeCalldata;
12785
12391
  exports.encodeRedelegateCalldata = encodeRedelegateCalldata;
12786
12392
  exports.encodeRegisterPubkeyCalldata = encodeRegisterPubkeyCalldata;
@@ -12831,6 +12437,7 @@ exports.getChainInfo = getChainInfo;
12831
12437
  exports.getNoEvmReceiptTrustPolicy = getNoEvmReceiptTrustPolicy;
12832
12438
  exports.getP2pSeeds = getP2pSeeds;
12833
12439
  exports.getRpcEndpoints = getRpcEndpoints;
12440
+ exports.hashToHex = hashToHex;
12834
12441
  exports.hexToAddressBytes = hexToAddressBytes;
12835
12442
  exports.isBridgeAdminLockedRevert = isBridgeAdminLockedRevert;
12836
12443
  exports.isBridgeCooldownZeroRevert = isBridgeCooldownZeroRevert;
@@ -12886,6 +12493,7 @@ exports.parseQuantityBig = parseQuantityBig;
12886
12493
  exports.preflightClusterJoinRequest = preflightClusterJoinRequest;
12887
12494
  exports.previewRequestClusterJoin = previewRequestClusterJoin;
12888
12495
  exports.previewVoteClusterAdmit = previewVoteClusterAdmit;
12496
+ exports.proofVerifier = proofVerifier;
12889
12497
  exports.protocolNonceForEpoch = protocolNonceForEpoch;
12890
12498
  exports.proverMarketStateFromByte = proverMarketStateFromByte;
12891
12499
  exports.pubkeyRegistryAddressHex = pubkeyRegistryAddressHex;
@@ -12919,7 +12527,6 @@ exports.spendingPolicyAddressHex = spendingPolicyAddressHex;
12919
12527
  exports.submitMrvCallNativeTx = submitMrvCallNativeTx;
12920
12528
  exports.submitMrvDeployNativeTx = submitMrvDeployNativeTx;
12921
12529
  exports.submitMrvDeployPayloadNativeTx = submitMrvDeployPayloadNativeTx;
12922
- exports.submitPublishOperatorSealKey = submitPublishOperatorSealKey;
12923
12530
  exports.submitRequestClusterJoin = submitRequestClusterJoin;
12924
12531
  exports.submitSighash = submitSighash;
12925
12532
  exports.submitVoteClusterAdmit = submitVoteClusterAdmit;