@monolythium/core-sdk 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -240,32 +240,18 @@ const backend = pqm1MnemonicToMlDsa65Backend(mnemonic);
240
240
  const signature = backend.sign(new Uint8Array([1, 2, 3]));
241
241
  ```
242
242
 
243
- ### Legacy ethers.js v6 compat
244
-
245
- The package still ships an ethers v6 compat shim for legacy migration tooling:
246
- a `MonolythiumProvider` and `MonolythiumSigner` that drop in wherever ethers'
247
- `Provider` and `Signer` are expected. It is not the v4.1 no-EVM deployment path;
248
- new app work should use the MRV/RISC-V builders and `lyth_*` read surfaces.
249
- `ethers` is a peer dependency for this compatibility path.
250
-
251
- ```ts
252
- import { Wallet } from "ethers";
253
- import {
254
- MonolythiumProvider,
255
- MonolythiumSigner,
256
- } from "@monolythium/core-sdk/ethers";
257
-
258
- const provider = new MonolythiumProvider("https://rpc.testnet.monolythium.com");
259
- const wallet = new Wallet(process.env.PRIVATE_KEY!);
260
- const signer = MonolythiumSigner.fromEthersWallet(wallet, provider);
261
-
262
- // Legacy-only adapter setup. Do not use this path for new v4.1 MRV deployments.
263
- console.log(await signer.getAddress());
264
- ```
265
-
266
- For non-secp256k1 signing sources (OS keychain, hardware wallet, future
267
- ML-DSA-65 backends), implement `MonolythiumSignerBackend` and pass it to
268
- `new MonolythiumSigner(backend, provider)`.
243
+ ### ethers / viem compatibility
244
+
245
+ The SDK does not ship an ethers-style provider or signer. The chain
246
+ does not accept Ethereum-style ECDSA signatures at transaction
247
+ admission, and there is no `eth_call` / `eth_estimateGas` /
248
+ `eth_sendRawTransaction` on the dispatcher to translate to. Tooling
249
+ that wants to read EVM-shaped block, balance, receipt, or log fields
250
+ can keep using the curated `eth_*` read methods exposed by `RpcClient`
251
+ directly (`ethBlockNumber`, `ethGetBalance`, `ethGetBlockByNumber`,
252
+ `ethGetTransactionReceipt`, `ethGetLogs`, …). Submitting and signing
253
+ transactions go through the native builders (`mesh_buildUnsignedTx` +
254
+ ML-DSA-65 signer + `mesh_submitTx`, or `lyth_submitEncrypted`).
269
255
 
270
256
  ## Development
271
257
 
@@ -1,6 +1,5 @@
1
- import { a as MlDsa65Backend } from '../submission-BrsftNSl.cjs';
2
- export { A as ADDRESS_DERIVATION_DOMAIN, D as DKG_AEAD_TAG_LEN, b as DKG_NONCE_LEN, c as DecryptHint, d as ENUM_VARIANT_INDEX_ML_DSA_65, e as EncryptedEnvelope, f as EncryptedSubmission, E as EncryptionKey, g as ML_DSA_65_PUBLIC_KEY_LEN, h as ML_DSA_65_SEED_LEN, i as ML_DSA_65_SIGNATURE_LEN, j as ML_DSA_65_SIGNING_KEY_LEN, k as ML_KEM_768_CIPHERTEXT_LEN, l as ML_KEM_768_ENCAPSULATION_KEY_LEN, m as ML_KEM_768_SHARED_SECRET_LEN, M as MempoolClass, N as NativeEvmTxFields, n as NativeTxExtension, o as NativeTxExtensionDescriptor, p as NativeTxExtensionLike, q as NonceAad, S as STANDARD_ALGO_NUMBER_ML_DSA_65, r as bincodeDecryptHint, s as bincodeEncryptedEnvelope, t as bincodeNonceAad, u as bincodeSignedTransaction, v as buildEncryptedEnvelope, w as buildEncryptedSubmission, x as encodeMlDsa65Opaque, y as encodeTransactionForHash, z as encryptInnerTx, B as fetchEncryptionKey, C as mlDsa65AddressBytes, F as mlDsa65AddressFromPublicKey, G as outerSigDigest, H as submitEncryptedEnvelope } from '../submission-BrsftNSl.cjs';
3
- import '../native-events-BEkkGoak.cjs';
1
+ import { H as MlDsa65Backend } from '../submission-D8xzCLNl.cjs';
2
+ export { ej as ADDRESS_DERIVATION_DOMAIN, ek as DKG_AEAD_TAG_LEN, el as DKG_NONCE_LEN, em as DecryptHint, en as ENUM_VARIANT_INDEX_ML_DSA_65, eo as EncryptedEnvelope, ep as EncryptedSubmission, E as EncryptionKey, eq as ML_DSA_65_PUBLIC_KEY_LEN, er as ML_DSA_65_SEED_LEN, es as ML_DSA_65_SIGNATURE_LEN, et as ML_DSA_65_SIGNING_KEY_LEN, eu as ML_KEM_768_CIPHERTEXT_LEN, ev as ML_KEM_768_ENCAPSULATION_KEY_LEN, ew as ML_KEM_768_SHARED_SECRET_LEN, F as MempoolClass, D as NativeEvmTxFields, ex as NativeTxExtension, ey as NativeTxExtensionDescriptor, ez as NativeTxExtensionLike, eA as NonceAad, eB as STANDARD_ALGO_NUMBER_ML_DSA_65, eC as bincodeDecryptHint, eD as bincodeEncryptedEnvelope, eE as bincodeNonceAad, eF as bincodeSignedTransaction, eG as buildEncryptedEnvelope, eH as buildEncryptedSubmission, eI as encodeMlDsa65Opaque, eJ as encodeTransactionForHash, eK as encryptInnerTx, eL as fetchEncryptionKey, eM as mlDsa65AddressBytes, eN as mlDsa65AddressFromPublicKey, eO as outerSigDigest, eP as submitEncryptedEnvelope } from '../submission-D8xzCLNl.cjs';
4
3
 
5
4
  declare class BincodeWriter {
6
5
  #private;
@@ -1,6 +1,5 @@
1
- import { a as MlDsa65Backend } from '../submission-CelGfDRQ.js';
2
- export { A as ADDRESS_DERIVATION_DOMAIN, D as DKG_AEAD_TAG_LEN, b as DKG_NONCE_LEN, c as DecryptHint, d as ENUM_VARIANT_INDEX_ML_DSA_65, e as EncryptedEnvelope, f as EncryptedSubmission, E as EncryptionKey, g as ML_DSA_65_PUBLIC_KEY_LEN, h as ML_DSA_65_SEED_LEN, i as ML_DSA_65_SIGNATURE_LEN, j as ML_DSA_65_SIGNING_KEY_LEN, k as ML_KEM_768_CIPHERTEXT_LEN, l as ML_KEM_768_ENCAPSULATION_KEY_LEN, m as ML_KEM_768_SHARED_SECRET_LEN, M as MempoolClass, N as NativeEvmTxFields, n as NativeTxExtension, o as NativeTxExtensionDescriptor, p as NativeTxExtensionLike, q as NonceAad, S as STANDARD_ALGO_NUMBER_ML_DSA_65, r as bincodeDecryptHint, s as bincodeEncryptedEnvelope, t as bincodeNonceAad, u as bincodeSignedTransaction, v as buildEncryptedEnvelope, w as buildEncryptedSubmission, x as encodeMlDsa65Opaque, y as encodeTransactionForHash, z as encryptInnerTx, B as fetchEncryptionKey, C as mlDsa65AddressBytes, F as mlDsa65AddressFromPublicKey, G as outerSigDigest, H as submitEncryptedEnvelope } from '../submission-CelGfDRQ.js';
3
- import '../native-events-BEkkGoak.js';
1
+ import { H as MlDsa65Backend } from '../submission-D8xzCLNl.js';
2
+ export { ej as ADDRESS_DERIVATION_DOMAIN, ek as DKG_AEAD_TAG_LEN, el as DKG_NONCE_LEN, em as DecryptHint, en as ENUM_VARIANT_INDEX_ML_DSA_65, eo as EncryptedEnvelope, ep as EncryptedSubmission, E as EncryptionKey, eq as ML_DSA_65_PUBLIC_KEY_LEN, er as ML_DSA_65_SEED_LEN, es as ML_DSA_65_SIGNATURE_LEN, et as ML_DSA_65_SIGNING_KEY_LEN, eu as ML_KEM_768_CIPHERTEXT_LEN, ev as ML_KEM_768_ENCAPSULATION_KEY_LEN, ew as ML_KEM_768_SHARED_SECRET_LEN, F as MempoolClass, D as NativeEvmTxFields, ex as NativeTxExtension, ey as NativeTxExtensionDescriptor, ez as NativeTxExtensionLike, eA as NonceAad, eB as STANDARD_ALGO_NUMBER_ML_DSA_65, eC as bincodeDecryptHint, eD as bincodeEncryptedEnvelope, eE as bincodeNonceAad, eF as bincodeSignedTransaction, eG as buildEncryptedEnvelope, eH as buildEncryptedSubmission, eI as encodeMlDsa65Opaque, eJ as encodeTransactionForHash, eK as encryptInnerTx, eL as fetchEncryptionKey, eM as mlDsa65AddressBytes, eN as mlDsa65AddressFromPublicKey, eO as outerSigDigest, eP as submitEncryptedEnvelope } from '../submission-D8xzCLNl.js';
4
3
 
5
4
  declare class BincodeWriter {
6
5
  #private;
package/dist/index.cjs CHANGED
@@ -349,23 +349,23 @@ var PRECOMPILE_ADDRESSES = {
349
349
  TOKEN_FACTORY: "0x0000000000000000000000000000000000001000",
350
350
  /** Native central-limit order book — gateable. */
351
351
  CLOB: "0x0000000000000000000000000000000000001001",
352
- /** Agent execution surface (zkML-gated, ADR-0011/ADR-0020) — gateable. */
352
+ /** Agent execution surface — gateable. */
353
353
  AGENT: "0x0000000000000000000000000000000000001003",
354
354
  /** Account privacy policy + stealth/confidential ops — gateable. */
355
355
  PRIVACY: "0x0000000000000000000000000000000000001004",
356
356
  /** Operator + RPC node registry — non-gateable consensus invariant. */
357
357
  NODE_REGISTRY: "0x0000000000000000000000000000000000001005",
358
- /** Native zk-light-client bridge — gateable. */
358
+ /** Native bridge route-control surface — gateable. */
359
359
  BRIDGE: "0x0000000000000000000000000000000000001008",
360
- /** Decentralized multi-signer oracle (OI-0036) — non-gateable. */
360
+ /** Decentralized multi-signer oracle — non-gateable. */
361
361
  ORACLE: "0x0000000000000000000000000000000000001009",
362
- /** Distributed delegation primitive (Stage E.5a, Law §7.6) — gateable. */
362
+ /** Distributed delegation primitive — gateable. */
363
363
  DELEGATION: "0x000000000000000000000000000000000000100A",
364
- /** One-time emergency-key registry (Law §5.4 / §2.9) — non-gateable. */
364
+ /** One-time emergency-key registry — non-gateable. */
365
365
  EMERGENCY_KEY: "0x0000000000000000000000000000000000001100",
366
- /** VRF precompile (Law §5.4 / §5.6). */
366
+ /** VRF precompile. */
367
367
  VRF: "0x0000000000000000000000000000000000001101",
368
- /** Streaming-payments primitive (Law §5.4 / §5.7) — gateable. */
368
+ /** Streaming-payments primitive — gateable. */
369
369
  STREAMING_PAYMENTS: "0x0000000000000000000000000000000000001102",
370
370
  /** Cluster-name registry. */
371
371
  CLUSTER_NAME_REGISTRY: "0x0000000000000000000000000000000000001104",
@@ -383,11 +383,11 @@ var PRECOMPILE_ADDRESSES = {
383
383
  ESCROW: "0x000000000000000000000000000000000000110A",
384
384
  /** Agent-commerce arbiter registry. */
385
385
  ARBITER_REGISTRY: "0x000000000000000000000000000000000000110B",
386
- /** Agent spending policy — gateable, activated by Stage 7 milestones. */
386
+ /** Agent spending policy — gateable. */
387
387
  SPENDING_POLICY: "0x000000000000000000000000000000000000110C",
388
- /** Primary ML-DSA-65 pubkey registry — gateable, ADR-0034. */
388
+ /** Primary ML-DSA-65 pubkey registry — gateable. */
389
389
  PUBKEY_REGISTRY: "0x000000000000000000000000000000000000110D",
390
- /** Hierarchical name registry (Law §5.10, whitepaper §22.8) — gateable. */
390
+ /** Hierarchical name registry — gateable. */
391
391
  NAME_REGISTRY: "0x000000000000000000000000000000000000110E"
392
392
  };
393
393
 
@@ -2333,23 +2333,9 @@ var RpcClient = class _RpcClient {
2333
2333
  async ethGetTransactionReceipt(txHash) {
2334
2334
  return normalizeTransactionReceipt(await this.call("eth_getTransactionReceipt", [txHash]));
2335
2335
  }
2336
- /** `eth_sendRawTransaction` — submit a signed raw tx. */
2337
- async ethSendRawTransaction(rawTx) {
2338
- return this.call("eth_sendRawTransaction", [rawTx]);
2339
- }
2340
- /** `eth_call` — dry-run a transaction. */
2341
- async ethCall(request, block = "latest") {
2342
- return this.call("eth_call", [request, encodeBlockSelector(block)]);
2343
- }
2344
- /** `eth_estimateGas` — gas estimate for a dry-run. */
2345
- async ethEstimateGas(request, block = "latest") {
2346
- return parseQuantityBig(
2347
- await this.call("eth_estimateGas", [request, encodeBlockSelector(block)])
2348
- );
2349
- }
2350
2336
  /**
2351
- * `eth_gasPrice` — legacy compatibility fee quote for ethers/viem shims.
2352
- * Native v4.1 surfaces should use execution-unit and lythoshi fee fields.
2337
+ * `eth_gasPrice` — passive compatibility fee quote for EVM-shaped read
2338
+ * tooling. Native callers should prefer `lythExecutionUnitPrice`.
2353
2339
  */
2354
2340
  async ethGasPrice() {
2355
2341
  return parseQuantityBig(await this.call("eth_gasPrice", []));
@@ -2388,7 +2374,7 @@ var RpcClient = class _RpcClient {
2388
2374
  async web3Sha3(data) {
2389
2375
  return this.call("web3_sha3", [data]);
2390
2376
  }
2391
- // ---- lyth_* (Law §13.2 native namespace) --------------------------
2377
+ // ---- lyth_* native namespace --------------------------------------
2392
2378
  /** `lyth_listProviders` — paged registry enumeration. */
2393
2379
  async lythListProviders(capabilityMask, cursor = null, limit = 100) {
2394
2380
  return this.call("lyth_listProviders", [capabilityMask, cursor, limit]);
@@ -2620,14 +2606,26 @@ var RpcClient = class _RpcClient {
2620
2606
  async lythCurrentRound() {
2621
2607
  return normalizeRoundInfo(await this.call("lyth_currentRound", []));
2622
2608
  }
2609
+ /** `lyth_getTransactionCount` — native sender nonce. */
2610
+ async lythGetTransactionCount(address) {
2611
+ return parseRpcBigint(
2612
+ await this.call("lyth_getTransactionCount", [
2613
+ sdkTypedAddress(address, "user", "address")
2614
+ ]),
2615
+ "lyth_getTransactionCount"
2616
+ );
2617
+ }
2618
+ /** `lyth_executionUnitPrice` — native execution-unit price in lythoshi. */
2619
+ async lythExecutionUnitPrice() {
2620
+ return normalizeExecutionUnitPriceResponse(
2621
+ await this.call("lyth_executionUnitPrice", [])
2622
+ );
2623
+ }
2623
2624
  /** `lyth_peerSummary` — public-safe aggregate peer-network diagnostics. */
2624
2625
  async lythPeerSummary() {
2625
2626
  return this.call("lyth_peerSummary", []);
2626
2627
  }
2627
- /**
2628
- * `lyth_listActivePrecompiles` — milestone-gated precompile catalogue
2629
- * (OI-0170 / ADR-0015 §5).
2630
- */
2628
+ /** `lyth_listActivePrecompiles` — native precompile catalogue. */
2631
2629
  async lythListActivePrecompiles(block = "latest") {
2632
2630
  return this.call("lyth_listActivePrecompiles", [encodeBlockSelector(block)]);
2633
2631
  }
@@ -2855,14 +2853,6 @@ var RpcClient = class _RpcClient {
2855
2853
  async debugTraceTransaction(txHash) {
2856
2854
  return this.call("debug_traceTransaction", [txHash]);
2857
2855
  }
2858
- /** `debug_traceCall` — legacy compatibility trace for a dry-run. */
2859
- async debugTraceCall(request, block = "latest") {
2860
- return this.call("debug_traceCall", [request, encodeBlockSelector(block)]);
2861
- }
2862
- /** `debug_traceBlockByNumber` — legacy compatibility traces for an entire block. */
2863
- async debugTraceBlockByNumber(block) {
2864
- return this.call("debug_traceBlockByNumber", [encodeBlockSelector(block)]);
2865
- }
2866
2856
  /** `debug_mempoolDump` — full mempool snapshot. */
2867
2857
  async debugMempoolDump() {
2868
2858
  return normalizeMempoolSnapshot(await this.call("debug_mempoolDump", []));
@@ -3552,6 +3542,34 @@ function normalizeRoundInfo(value) {
3552
3542
  height: parseRpcBigint(row["height"], "round height")
3553
3543
  };
3554
3544
  }
3545
+ function normalizeExecutionUnitPriceResponse(value) {
3546
+ if (!value || typeof value !== "object") {
3547
+ throw SdkError.malformed("execution unit price response must be an object");
3548
+ }
3549
+ const row = value;
3550
+ return {
3551
+ executionUnitPriceLythoshi: parseRpcBigint(
3552
+ fieldAlias(row, ["executionUnitPriceLythoshi", "execution_unit_price_lythoshi"]),
3553
+ "executionUnitPriceLythoshi"
3554
+ ).toString(),
3555
+ basePricePerExecutionUnitLythoshi: parseRpcBigint(
3556
+ fieldAlias(row, [
3557
+ "basePricePerExecutionUnitLythoshi",
3558
+ "base_price_per_execution_unit_lythoshi"
3559
+ ]),
3560
+ "basePricePerExecutionUnitLythoshi"
3561
+ ).toString(),
3562
+ priorityTipLythoshi: parseRpcBigint(
3563
+ fieldAlias(row, ["priorityTipLythoshi", "priority_tip_lythoshi"]),
3564
+ "priorityTipLythoshi"
3565
+ ).toString(),
3566
+ blockNumber: parseRpcNumberNullable(
3567
+ fieldAlias(row, ["blockNumber", "block_number"]),
3568
+ "blockNumber"
3569
+ ),
3570
+ source: readStringField(row, ["source"], "execution unit price source")
3571
+ };
3572
+ }
3555
3573
  function normalizeMempoolSnapshot(value) {
3556
3574
  if (!value || typeof value !== "object") {
3557
3575
  throw SdkError.malformed("mempool snapshot must be an object");
@@ -3568,6 +3586,19 @@ function normalizeMempoolSnapshot(value) {
3568
3586
  bytes_by_class: bytesByClass.map((v, i) => parseRpcBigint(v, `mempool bytes_by_class[${i}]`))
3569
3587
  };
3570
3588
  }
3589
+ function fieldAlias(record, keys) {
3590
+ for (const key of keys) {
3591
+ if (Object.prototype.hasOwnProperty.call(record, key)) return record[key];
3592
+ }
3593
+ return void 0;
3594
+ }
3595
+ function readStringField(record, keys, label) {
3596
+ const value = fieldAlias(record, keys);
3597
+ if (typeof value !== "string" || value.trim().length === 0) {
3598
+ throw SdkError.malformed(`${label} must be a non-empty string`);
3599
+ }
3600
+ return value.trim();
3601
+ }
3571
3602
  function normalizeCapabilitiesResponse(value) {
3572
3603
  return {
3573
3604
  ...value,
@@ -4072,6 +4103,8 @@ var BRIDGE_REVERT_TAGS = {
4072
4103
  };
4073
4104
  var BRIDGE_QUOTE_API_BLOCKED_REASON = "bridge quote requires a mono-core live quote API/runtime primitive";
4074
4105
  var BRIDGE_SUBMIT_API_BLOCKED_REASON = "bridge submit requires a mono-core live submit API/runtime primitive";
4106
+ var V1_BRIDGE_ALLOWED_FEE_TOKEN = "LINK";
4107
+ var V1_BRIDGE_ALLOWED_PROTOCOL = "chainlink-ccip";
4075
4108
  var BridgePrecompileError = class extends Error {
4076
4109
  constructor(message) {
4077
4110
  super(message);
@@ -4130,9 +4163,18 @@ function isBridgeFinalityZeroRevert(data) {
4130
4163
  function assessBridgeRoute(route) {
4131
4164
  const blockedReasons = [];
4132
4165
  const warnings = [];
4166
+ const feeToken = String(route.feeToken ?? "").trim();
4133
4167
  if (route.routeId.trim() === "") blockedReasons.push("route id missing");
4134
4168
  if (route.bridge.trim() === "") blockedReasons.push("bridge name missing");
4169
+ if (!isChainlinkCcipRoute(route.protocol, route.bridge, route.verifier.model)) {
4170
+ blockedReasons.push("bridge protocol must be Chainlink CCIP");
4171
+ }
4135
4172
  if (route.asset.trim() === "") blockedReasons.push("asset disclosure missing");
4173
+ if (feeToken === "") {
4174
+ blockedReasons.push("route fee token missing");
4175
+ } else if (feeToken.toUpperCase() !== V1_BRIDGE_ALLOWED_FEE_TOKEN) {
4176
+ blockedReasons.push("CCIP route fee token must be LINK");
4177
+ }
4136
4178
  if (route.verifier.model.trim() === "") blockedReasons.push("verifier model missing");
4137
4179
  if (route.verifier.threshold < 2 || route.verifier.participantCount < 2) {
4138
4180
  blockedReasons.push("verifier set must not be 1-of-1");
@@ -4374,8 +4416,23 @@ function validateBridgeRouteCatalogueRoute(idx, value, seen, blockedReasons) {
4374
4416
  20,
4375
4417
  blockedReasons
4376
4418
  );
4377
- validateTextField(`${prefix}.bridge`, value.bridge, 64, blockedReasons);
4419
+ const bridge = validateTextField(`${prefix}.bridge`, value.bridge, 64, blockedReasons);
4420
+ const protocol = validateOptionalTextField(
4421
+ `${prefix}.protocol`,
4422
+ field(value, "protocol", "routeProtocol", "route_protocol"),
4423
+ 64,
4424
+ blockedReasons
4425
+ );
4378
4426
  validateTextField(`${prefix}.asset`, value.asset, 64, blockedReasons);
4427
+ const feeToken = validateTextField(
4428
+ `${prefix}.feeToken`,
4429
+ field(value, "feeToken", "fee_token"),
4430
+ 32,
4431
+ blockedReasons
4432
+ );
4433
+ if (feeToken != null && feeToken.toUpperCase() !== V1_BRIDGE_ALLOWED_FEE_TOKEN) {
4434
+ blockedReasons.push(`${prefix}.feeToken must be LINK for CCIP routes`);
4435
+ }
4379
4436
  validateTextField(
4380
4437
  `${prefix}.sourceChain`,
4381
4438
  field(value, "sourceChain", "source_chain"),
@@ -4389,10 +4446,11 @@ function validateBridgeRouteCatalogueRoute(idx, value, seen, blockedReasons) {
4389
4446
  blockedReasons
4390
4447
  );
4391
4448
  const verifier = value.verifier;
4449
+ let verifierModel = null;
4392
4450
  if (!isRecord2(verifier)) {
4393
4451
  blockedReasons.push(`${prefix}.verifier must be an object`);
4394
4452
  } else {
4395
- validateTextField(`${prefix}.verifier.model`, verifier.model, 64, blockedReasons);
4453
+ verifierModel = validateTextField(`${prefix}.verifier.model`, verifier.model, 64, blockedReasons);
4396
4454
  const participantCount = field(verifier, "participantCount", "participant_count");
4397
4455
  if (!isU16(participantCount) || participantCount === 0) {
4398
4456
  blockedReasons.push(`${prefix}.verifier.participantCount must be non-zero`);
@@ -4403,6 +4461,9 @@ function validateBridgeRouteCatalogueRoute(idx, value, seen, blockedReasons) {
4403
4461
  blockedReasons.push(`${prefix}.verifier.threshold must be in 1..=participantCount`);
4404
4462
  }
4405
4463
  }
4464
+ if (!isChainlinkCcipRoute(protocol, bridge ?? "", verifierModel ?? "")) {
4465
+ blockedReasons.push(`${prefix}.protocol must be Chainlink CCIP`);
4466
+ }
4406
4467
  if (!decimalStringIsPositiveU256(field(value, "drainCapAtomic", "drain_cap_atomic"))) {
4407
4468
  blockedReasons.push(`${prefix}.drainCapAtomic must be a non-zero decimal u256`);
4408
4469
  }
@@ -4444,7 +4505,9 @@ function coerceBridgeRouteCatalogueRoute(value) {
4444
4505
  bridgeId: stringField2(value, "bridgeId", "bridge_id"),
4445
4506
  wrappedAsset: stringField2(value, "wrappedAsset", "wrapped_asset"),
4446
4507
  bridge: stringField2(value, "bridge").trim(),
4508
+ protocol: optionalStringField(value, "protocol", "routeProtocol", "route_protocol"),
4447
4509
  asset: stringField2(value, "asset").trim(),
4510
+ feeToken: stringField2(value, "feeToken", "fee_token").trim(),
4448
4511
  sourceChain: stringField2(value, "sourceChain", "source_chain").trim(),
4449
4512
  destinationChain: stringField2(value, "destinationChain", "destination_chain").trim(),
4450
4513
  verifier: {
@@ -4473,6 +4536,19 @@ function cloneBridgeRouteCatalogueRoute(route) {
4473
4536
  verifier: { ...route.verifier }
4474
4537
  };
4475
4538
  }
4539
+ function isChainlinkCcipRoute(protocol, bridge, verifierModel) {
4540
+ const normalizedProtocol = normalizeBridgeProtocol(protocol ?? "");
4541
+ if (normalizedProtocol.length > 0) {
4542
+ return normalizedProtocol === "chainlinkccip" || normalizedProtocol === "ccip";
4543
+ }
4544
+ return bridgeLabelLooksCcip(bridge) || bridgeLabelLooksCcip(verifierModel);
4545
+ }
4546
+ function bridgeLabelLooksCcip(value) {
4547
+ return normalizeBridgeProtocol(value).includes("ccip");
4548
+ }
4549
+ function normalizeBridgeProtocol(value) {
4550
+ return value.trim().toLowerCase().replace(/[^a-z0-9]/g, "");
4551
+ }
4476
4552
  function bridgeRouteCandidate(intent, intentReasons, route) {
4477
4553
  const assessment = assessBridgeRoute(route);
4478
4554
  const blockedReasons = [...intentReasons, ...assessment.blockedReasons];
@@ -4568,16 +4644,28 @@ function trimmedEq(left, right) {
4568
4644
  function isRecord2(value) {
4569
4645
  return typeof value === "object" && value !== null && !Array.isArray(value);
4570
4646
  }
4571
- function field(record, camel, snake) {
4572
- if (Object.prototype.hasOwnProperty.call(record, camel)) return record[camel];
4573
- if (snake != null && Object.prototype.hasOwnProperty.call(record, snake)) return record[snake];
4647
+ function field(record, ...keys) {
4648
+ for (const key of keys) {
4649
+ if (Object.prototype.hasOwnProperty.call(record, key)) return record[key];
4650
+ }
4574
4651
  return void 0;
4575
4652
  }
4576
- function stringField2(record, camel, snake) {
4577
- return field(record, camel, snake);
4653
+ function stringField2(record, ...keys) {
4654
+ return field(record, ...keys);
4655
+ }
4656
+ function optionalStringField(record, ...keys) {
4657
+ let raw;
4658
+ for (const key of keys) {
4659
+ if (Object.prototype.hasOwnProperty.call(record, key)) {
4660
+ raw = record[key];
4661
+ break;
4662
+ }
4663
+ }
4664
+ if (raw === void 0 || raw === null) return null;
4665
+ return typeof raw === "string" ? raw.trim() : "";
4578
4666
  }
4579
- function numberField(record, camel, snake) {
4580
- return field(record, camel, snake);
4667
+ function numberField(record, ...keys) {
4668
+ return field(record, ...keys);
4581
4669
  }
4582
4670
  function validateTextField(name, value, maxLen, blockedReasons) {
4583
4671
  if (typeof value !== "string") {
@@ -4591,6 +4679,10 @@ function validateTextField(name, value, maxLen, blockedReasons) {
4591
4679
  }
4592
4680
  return trimmed;
4593
4681
  }
4682
+ function validateOptionalTextField(name, value, maxLen, blockedReasons) {
4683
+ if (value === void 0 || value === null) return null;
4684
+ return validateTextField(name, value, maxLen, blockedReasons);
4685
+ }
4594
4686
  function validateHexBytes(name, value, expectedBytes, blockedReasons) {
4595
4687
  if (typeof value !== "string") {
4596
4688
  blockedReasons.push(`${name} must be ${expectedBytes} bytes of hex`);
@@ -4720,9 +4812,10 @@ function concatBytes4(...parts) {
4720
4812
  var NO_EVM_RECEIPT_PROOF_SCHEMA = "mono.no_evm_receipt_proof.v1";
4721
4813
  var NO_EVM_RECEIPT_PROOF_TYPE = "canonicalReceiptsTranscript";
4722
4814
  var NO_EVM_RECEIPT_INCLUSION_PROOF_TYPE = "canonicalReceiptInclusion";
4723
- var NO_EVM_RECEIPT_ROOT_ALGORITHM = "keccak256(monolythium/v4.1/receipts_root_empty/1|receipt_leaf/1|receipt_node/1 binary Merkle)";
4815
+ var NO_EVM_RECEIPT_ROOT_ALGORITHM = "keccak256-binary-merkle(monolythium/v4.1/receipt_leaf/1, monolythium/v4.1/receipt_node/1, duplicate-last padding)";
4816
+ var NO_EVM_LEGACY_BINARY_RECEIPT_ROOT_ALGORITHM = "keccak256(monolythium/v4.1/receipts_root_empty/1|receipt_leaf/1|receipt_node/1 binary Merkle)";
4724
4817
  var NO_EVM_LEGACY_RECEIPT_ROOT_ALGORITHM = "keccak256(monolythium/v2/receipts_root/1 || len || indexed bincode receipts)";
4725
- var NO_EVM_RECEIPT_CODEC = "bincode(protocore_evm::Receipt)";
4818
+ var NO_EVM_RECEIPT_CODEC = "bincode(protocore_execution_types::Receipt)";
4726
4819
  var NO_EVM_RECEIPTS_ROOT_DOMAIN = "monolythium/v4.1/receipts_root_empty/1";
4727
4820
  var NO_EVM_RECEIPT_LEAF_DOMAIN = "monolythium/v4.1/receipt_leaf/1";
4728
4821
  var NO_EVM_RECEIPT_NODE_DOMAIN = "monolythium/v4.1/receipt_node/1";
@@ -5959,7 +6052,7 @@ function getOptionalHistorySource(proof) {
5959
6052
  return value === void 0 ? void 0 : String(value);
5960
6053
  }
5961
6054
  function assertSupportedRootAlgorithm(actual) {
5962
- if (actual !== NO_EVM_RECEIPT_ROOT_ALGORITHM && actual !== NO_EVM_LEGACY_RECEIPT_ROOT_ALGORITHM && actual !== NO_EVM_COMPACT_INCLUSION_TREE_ALGORITHM) {
6055
+ if (actual !== NO_EVM_RECEIPT_ROOT_ALGORITHM && actual !== NO_EVM_LEGACY_BINARY_RECEIPT_ROOT_ALGORITHM && actual !== NO_EVM_LEGACY_RECEIPT_ROOT_ALGORITHM && actual !== NO_EVM_COMPACT_INCLUSION_TREE_ALGORITHM) {
5963
6056
  throw new NoEvmReceiptProofError(
5964
6057
  "unsupported_root_algorithm",
5965
6058
  `unsupported no-EVM receipt proof rootAlgorithm: ${actual}`
@@ -7882,12 +7975,18 @@ function normalizeNativeAgentAddressString(address, expectedKind, name) {
7882
7975
  }
7883
7976
  }
7884
7977
 
7885
- // src/ethers/network.ts
7978
+ // src/network.ts
7886
7979
  var MONOLYTHIUM_TESTNET_CHAIN_ID = 69420n;
7887
7980
  var MONOLYTHIUM_TESTNET_NETWORK_NAME = "monolythium-testnet";
7981
+ var MONOLYTHIUM_NETWORKS = {
7982
+ testnet: {
7983
+ chainId: MONOLYTHIUM_TESTNET_CHAIN_ID,
7984
+ name: MONOLYTHIUM_TESTNET_NETWORK_NAME
7985
+ }
7986
+ };
7888
7987
 
7889
7988
  // src/index.ts
7890
- var version = "0.2.1";
7989
+ var version = "0.2.2";
7891
7990
 
7892
7991
  exports.ADDRESS_HRP = ADDRESS_HRP;
7893
7992
  exports.ADDRESS_KIND_HRPS = ADDRESS_KIND_HRPS;
@@ -7915,6 +8014,7 @@ exports.MAX_NATIVE_CALL_FORWARDER_REQUEST_BYTES = MAX_NATIVE_CALL_FORWARDER_REQU
7915
8014
  exports.MAX_NATIVE_RECEIPT_EVENTS = MAX_NATIVE_RECEIPT_EVENTS;
7916
8015
  exports.ML_DSA_65_PUBLIC_KEY_LEN = ML_DSA_65_PUBLIC_KEY_LEN2;
7917
8016
  exports.ML_DSA_65_SIGNATURE_LEN = ML_DSA_65_SIGNATURE_LEN2;
8017
+ exports.MONOLYTHIUM_NETWORKS = MONOLYTHIUM_NETWORKS;
7918
8018
  exports.MONOLYTHIUM_TESTNET_CHAIN_ID = MONOLYTHIUM_TESTNET_CHAIN_ID;
7919
8019
  exports.MONOLYTHIUM_TESTNET_NETWORK_NAME = MONOLYTHIUM_TESTNET_NETWORK_NAME;
7920
8020
  exports.MRV_DEPLOY_PAYLOAD_VERSION = MRV_DEPLOY_PAYLOAD_VERSION;
@@ -7971,6 +8071,8 @@ exports.SPENDING_POLICY_SELECTORS = SPENDING_POLICY_SELECTORS;
7971
8071
  exports.SdkError = SdkError;
7972
8072
  exports.SpendingPolicyError = SpendingPolicyError;
7973
8073
  exports.TESTNET_69420 = TESTNET_69420;
8074
+ exports.V1_BRIDGE_ALLOWED_FEE_TOKEN = V1_BRIDGE_ALLOWED_FEE_TOKEN;
8075
+ exports.V1_BRIDGE_ALLOWED_PROTOCOL = V1_BRIDGE_ALLOWED_PROTOCOL;
7974
8076
  exports.addressBytesToHex = addressBytesToHex;
7975
8077
  exports.addressToBech32 = addressToBech32;
7976
8078
  exports.addressToTypedBech32 = addressToTypedBech32;