@anywalletkit/protocol-swap2-omniston 0.3.0 → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  omnistonProvider
3
- } from "./chunk-JVFDD7PV.js";
3
+ } from "./chunk-R6B2CV5Z.js";
4
4
  import {
5
5
  omniston
6
6
  } from "./chunk-QDXFC6BC.js";
@@ -24,4 +24,4 @@ var OmnistonSwap2Protocol = class extends SingleProviderSwap2 {
24
24
  export {
25
25
  OmnistonSwap2Protocol
26
26
  };
27
- //# sourceMappingURL=chunk-CRYYP6X3.js.map
27
+ //# sourceMappingURL=chunk-WL7BSEBR.js.map
package/dist/index.cjs CHANGED
@@ -438,6 +438,38 @@ function sameJetton(a, b) {
438
438
  }
439
439
  }
440
440
 
441
+ // src/validators/settlement.ts
442
+ var AUDITED_OMNISTON_SETTLEMENT_CONTRACTS = {
443
+ "ton:-239": ["EQAbWJ3Y1HgIIvcMq1prG1anlDC0T3cZlAU7luPT6LmTpmrZ"],
444
+ "eip155:1": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
445
+ "eip155:56": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
446
+ "eip155:137": ["0x41A392062A4307a6961d48e30FF20bF6823715B8"],
447
+ "eip155:4663": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
448
+ "eip155:8453": ["0xACa3E2F9b61a44892926bC6c3e104192E7D1c3cd"],
449
+ "eip155:42161": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
450
+ "eip155:43114": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
451
+ // 2026-10-20: one factory address on X Layer, HyperEVM and Plasma. Runtime
452
+ // bytecode equals Ethereum's 0xafCF… byte for byte except the immutable slots
453
+ // (escrow implementations, its order protocol, domain hash); it references
454
+ // the order protocol trusted below on the same chain.
455
+ "eip155:196": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
456
+ "eip155:999": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
457
+ "eip155:9745": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"]
458
+ };
459
+ var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
460
+ "eip155:1": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
461
+ "eip155:56": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
462
+ "eip155:137": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
463
+ "eip155:8453": ["0xe7405fAcDEDB2512e91F2886BDff13231343aF5E"],
464
+ "eip155:42161": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
465
+ "eip155:43114": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
466
+ // 2026-10-20: bytecode equals Ethereum's 0xb581… except immutables (wrapped
467
+ // native, own address, chain id 196 / 9745 / 999 at the chain-id slot).
468
+ "eip155:196": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
469
+ "eip155:9745": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
470
+ "eip155:999": ["0xD84778bbeEC5D2a8d17c6424249C438EC0b1ABE3"]
471
+ };
472
+
441
473
  // src/provider.ts
442
474
  var import_core4 = require("@anywalletkit/core");
443
475
  var EVM_CASE = {
@@ -648,9 +680,9 @@ function validEvmAddress(value) {
648
680
  }
649
681
  }
650
682
  var EVM_DEST_PROTOCOL_FEE_RECIPIENTS = /* @__PURE__ */ new Set(["0x076268146b4ec6d21fc49c27586cfa91b9079a00"]);
651
- async function validateEvmToTonOrderExtension(extension, expected) {
652
- const evmDest = expected.dstChainId !== void 0;
653
- if (evmDest && (!Number.isSafeInteger(expected.dstChainId) || expected.dstChainId <= 0)) throw new Error("omniston: invalid EVM destination chain id");
683
+ var EVM_AUCTION_POINTS = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
684
+ var EVM_TIMELOCKS = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
685
+ function readEvmOrderExtension(extension) {
654
686
  if (extension.length < 32) throw new Error("omniston: malformed EVM order extension");
655
687
  const view = new DataView(extension.buffer, extension.byteOffset, extension.byteLength);
656
688
  const fields = [];
@@ -670,54 +702,48 @@ async function validateEvmToTonOrderExtension(extension, expected) {
670
702
  }
671
703
  let target;
672
704
  for (const index of [2, 3, 7]) {
673
- const field = fields[index];
674
- if (field.length <= 20) throw new Error("omniston: incomplete EVM order extension program");
675
- const address = (0, import_viem.getAddress)(`0x${bytesToHex(field.slice(0, 20))}`);
676
- if (!expected.trustedTarget(address) || target !== void 0 && (0, import_viem.getAddress)(target) !== address) {
705
+ const field2 = fields[index];
706
+ if (field2.length <= 20) throw new Error("omniston: incomplete EVM order extension program");
707
+ const address = (0, import_viem.getAddress)(`0x${bytesToHex(field2.slice(0, 20))}`);
708
+ if (target !== void 0 && (0, import_viem.getAddress)(target) !== address) {
677
709
  throw new Error("omniston: EVM order extension target is not independently trusted");
678
710
  }
679
711
  target = address;
680
712
  }
681
- const getter = fields[2];
713
+ const field = fields[2];
682
714
  let cursor = 20;
683
- const gasBump = readBigEndian(getter, cursor, 3);
715
+ const gasBump = readBigEndian(field, cursor, 3);
684
716
  cursor += 3;
685
- const gasPrice = readBigEndian(getter, cursor, 4);
717
+ const gasPrice = readBigEndian(field, cursor, 4);
686
718
  cursor += 4;
687
- const auctionStart = readBigEndian(getter, cursor, 4);
719
+ const auctionStart = readBigEndian(field, cursor, 4);
688
720
  cursor += 4;
689
- const duration = readBigEndian(getter, cursor, 3);
721
+ const duration = readBigEndian(field, cursor, 3);
690
722
  cursor += 3;
691
- const initialRateBump = readBigEndian(getter, cursor, 3);
723
+ const initialRateBump = readBigEndian(field, cursor, 3);
692
724
  cursor += 3;
693
- const pointCount = (0, import_core4.bigintToNumber)(readBigEndian(getter, cursor, 1));
725
+ const pointCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
694
726
  cursor += 1;
695
727
  if (pointCount !== 5) throw new Error("omniston: unsupported EVM auction profile");
696
728
  const points = [];
697
729
  for (let index = 0; index < pointCount; index++) {
698
- points.push([readBigEndian(getter, cursor, 3), readBigEndian(getter, cursor + 3, 2)]);
730
+ points.push([readBigEndian(field, cursor, 3), readBigEndian(field, cursor + 3, 2)]);
699
731
  cursor += 5;
700
732
  }
701
- const integratorFee = readBigEndian(getter, cursor, 2);
733
+ const integratorFee = readBigEndian(field, cursor, 2);
702
734
  cursor += 2;
703
- const integratorShare = readBigEndian(getter, cursor, 1);
735
+ const integratorShare = readBigEndian(field, cursor, 1);
704
736
  cursor += 1;
705
- const resolverFee = readBigEndian(getter, cursor, 2);
737
+ const resolverFee = readBigEndian(field, cursor, 2);
706
738
  cursor += 2;
707
- const whitelistDiscount = readBigEndian(getter, cursor, 1);
739
+ const whitelistDiscount = readBigEndian(field, cursor, 1);
708
740
  cursor += 1;
709
- const getterWhitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(getter, cursor, 1));
741
+ const getterWhitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
710
742
  cursor += 1;
711
- if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== getter.length) {
743
+ if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== field.length) {
712
744
  throw new Error("omniston: malformed EVM amount-getter whitelist");
713
745
  }
714
- const getterResolver = readBigEndian(getter, cursor, 10);
715
- const expectedPoints = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
716
- const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
717
- const resolverLow80 = BigInt((0, import_viem.getAddress)(expected.initialResolverAddress)) & (1n << 80n) - 1n;
718
- if (gasBump !== 0n || gasPrice !== 0n || !within(auctionStart, expected.quoteTimestamp, 5, 5) || duration !== 1800n || initialRateBump !== 900000n || points.some((point, index) => point[0] !== expectedPoints[index][0] || point[1] !== expectedPoints[index][1]) || expected.integratorFeePips !== 0 || integratorFee !== 0n || integratorShare !== 100n || quoteResolverFee < 0n || resolverFee !== quoteResolverFee || whitelistDiscount !== 50n || getterResolver !== resolverLow80) {
719
- throw new Error("omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
720
- }
746
+ const getter = { gasBump, gasPrice, auctionStart, duration, initialRateBump, points, integratorFee, integratorShare, resolverFee, whitelistDiscount, resolver: readBigEndian(field, cursor, 10) };
721
747
  const post = fields[7];
722
748
  cursor = 20;
723
749
  const integratorRecipient = post.slice(cursor, cursor + 20);
@@ -743,28 +769,51 @@ async function validateEvmToTonOrderExtension(extension, expected) {
743
769
  cursor += 10;
744
770
  const resolverTimeDelta = readBigEndian(post, cursor, 2);
745
771
  cursor += 2;
746
- if (!zeroBytes(integratorRecipient) || !(zeroBytes(protocolRecipient) || evmDest && EVM_DEST_PROTOCOL_FEE_RECIPIENTS.has(`0x${bytesToHex(protocolRecipient)}`)) || postIntegratorFee !== 0n || postIntegratorShare !== 100n || postResolverFee !== quoteResolverFee || postDiscount !== 50n || !within(allowedTime, expected.quoteTimestamp, 60, 5) || postResolver !== resolverLow80 || resolverTimeDelta !== 0n) {
747
- throw new Error("omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
748
- }
749
772
  const extra = Array.from({ length: 5 }, () => {
750
773
  const value = readBigEndian(post, cursor, 32);
751
774
  cursor += 32;
752
775
  return value;
753
776
  });
777
+ const customData = extension.slice(32 + begin);
778
+ if (customData.length !== 131) throw new Error("omniston: malformed EVM order extension custom data");
779
+ return {
780
+ target,
781
+ getter,
782
+ post: { integratorRecipient, protocolRecipient, integratorFee: postIntegratorFee, integratorShare: postIntegratorShare, resolverFee: postResolverFee, discount: postDiscount, allowedTime, resolver: postResolver, resolverTimeDelta },
783
+ extra,
784
+ customData
785
+ };
786
+ }
787
+ async function validateEvmToTonOrderExtension(extension, expected) {
788
+ const evmDest = expected.dstChainId !== void 0;
789
+ if (evmDest && (!Number.isSafeInteger(expected.dstChainId) || expected.dstChainId <= 0)) throw new Error("omniston: invalid EVM destination chain id");
790
+ const { target, getter, post, extra, customData } = readEvmOrderExtension(extension);
791
+ if (!expected.trustedTarget(target)) throw new Error("omniston: EVM order extension target is not independently trusted");
792
+ const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
793
+ const resolverLow80 = BigInt((0, import_viem.getAddress)(expected.initialResolverAddress)) & (1n << 80n) - 1n;
794
+ if (getter.gasBump !== 0n || getter.gasPrice !== 0n || !within(getter.auctionStart, expected.quoteTimestamp, 5, 5) || getter.duration !== 1800n || getter.initialRateBump !== 900000n || getter.points.some((point, index) => point[0] !== EVM_AUCTION_POINTS[index][0] || point[1] !== EVM_AUCTION_POINTS[index][1]) || expected.integratorFeePips !== 0 || getter.integratorFee !== 0n || getter.integratorShare !== 100n || quoteResolverFee < 0n || getter.resolverFee !== quoteResolverFee || getter.whitelistDiscount !== 50n || getter.resolver !== resolverLow80) {
795
+ throw new Error("omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
796
+ }
797
+ if (!zeroBytes(post.integratorRecipient) || !(zeroBytes(post.protocolRecipient) || evmDest && EVM_DEST_PROTOCOL_FEE_RECIPIENTS.has(`0x${bytesToHex(post.protocolRecipient)}`)) || post.integratorFee !== 0n || post.integratorShare !== 100n || post.resolverFee !== quoteResolverFee || post.discount !== 50n || !within(post.allowedTime, expected.quoteTimestamp, 60, 5) || post.resolver !== resolverLow80 || post.resolverTimeDelta !== 0n) {
798
+ throw new Error("omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
799
+ }
754
800
  const hashlock2 = readBigEndian(expected.secretHash, 0, expected.secretHash.length);
755
801
  const dstToken = evmDest ? BigInt((0, import_viem.getAddress)(expected.outputTokenAddress)) : BigInt((0, import_viem.getAddress)(expected.takerAsset));
756
802
  const deposits = BigInt(expected.srcSecurityDepositUnits) << 128n | BigInt(expected.dstSecurityDepositUnits);
757
- const timelocks = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
758
- if (expected.secretHash.length !== 32 || extra[0] !== hashlock2 || extra[1] !== (evmDest ? BigInt(expected.dstChainId) : 0n) || extra[2] !== dstToken || extra[3] !== deposits || extra[4] !== timelocks) {
803
+ if (expected.secretHash.length !== 32 || extra[0] !== hashlock2 || extra[1] !== (evmDest ? BigInt(expected.dstChainId) : 0n) || extra[2] !== dstToken || extra[3] !== deposits || extra[4] !== EVM_TIMELOCKS) {
759
804
  throw new Error("omniston: signed EVM HTLC terms do not match the validated order details");
760
805
  }
761
- const customData = extension.slice(32 + begin);
762
- if (customData.length !== 131) throw new Error("omniston: malformed EVM order extension custom data");
763
- if (evmDest) {
806
+ await checkOrderCustomData(customData, { evmDest, outputToken: expected.outputTokenAddress, traderDst: expected.traderDstAddress, quoteId: expected.quoteId });
807
+ if (expected.tradeStartDeadline < expected.quoteTimestamp) {
808
+ throw new Error("omniston: invalid EVM order quote deadline");
809
+ }
810
+ }
811
+ async function checkOrderCustomData(customData, expected) {
812
+ if (expected.evmDest) {
764
813
  if (!zeroBytes(customData.slice(0, 66))) throw new Error("omniston: unexpected TON addresses in an EVM-destination order");
765
814
  } else {
766
815
  const { Address: Address3 } = await import("@ton/core");
767
- const expectedTon = [expected.outputTokenAddress, expected.traderDstAddress].map((value) => Address3.parse(value));
816
+ const expectedTon = [expected.outputToken, expected.traderDst].map((value) => Address3.parse(value));
768
817
  for (let index = 0; index < expectedTon.length; index++) {
769
818
  const offset = index * 33;
770
819
  const workchain = customData[offset] === 255 ? -1 : customData[offset];
@@ -780,9 +829,6 @@ async function validateEvmToTonOrderExtension(extension, expected) {
780
829
  if (!QUOTE_ID.test(quoteId) || !sliceEqual(customData.slice(99), hexToBytes(quoteId.padStart(64, "0")))) {
781
830
  throw new Error("omniston: EVM order extension custom data is not bound to the quote id");
782
831
  }
783
- if (expected.tradeStartDeadline < expected.quoteTimestamp) {
784
- throw new Error("omniston: invalid EVM order quote deadline");
785
- }
786
832
  }
787
833
  function validateEvmTypedOrder(td, expected) {
788
834
  const value = td;
@@ -1234,11 +1280,124 @@ function omnistonPins(trustedEvmOrderProtocols) {
1234
1280
  const byChain = new Map(Object.entries(trustedEvmOrderProtocols).map(([chain, list]) => [chain, list.map((a) => (0, import_viem.getAddress)(a))]));
1235
1281
  return Object.freeze({ callTargets: () => [], spenders: (chain) => byChain.get(chain) ?? [] });
1236
1282
  }
1283
+ var MAX_EVM_ORDER_LIFETIME_S = 900;
1284
+ async function checkRemoteEvmOrder(quote, tx, params, trusted) {
1285
+ const chainId = evmRef2(params.sourceChain);
1286
+ if (chainId === null || !params.sourceChain.startsWith("eip155:")) return "a typed order needs an EVM source";
1287
+ const intent = decodeIntent(quote.intentId.replace(/~[0-9a-f]{32}$/, ""));
1288
+ if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return "the quote's intent is not an order from this chain";
1289
+ if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return "the build carries no order extension to check";
1290
+ const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
1291
+ if (!source?.contract) return "unknown source token";
1292
+ const tonDest = isTon(params.destChain);
1293
+ const destChainId = tonDest ? null : evmRef2(params.destChain);
1294
+ if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return "the destination is neither TON nor an EVM chain";
1295
+ const outputToken = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken)?.contract ?? params.destToken;
1296
+ const listed = (table, chain, address) => typeof address === "string" && validEvmAddress(address) && (table[chain] ?? []).some((a) => validEvmAddress(a) && (0, import_viem.getAddress)(a) === (0, import_viem.getAddress)(address));
1297
+ let td;
1298
+ try {
1299
+ td = JSON.parse(tx.typedData ?? "");
1300
+ } catch {
1301
+ return "the typed data is not JSON";
1302
+ }
1303
+ const domain = td.domain ?? {};
1304
+ const contract = domain.verifyingContract;
1305
+ if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return "the domain is not the 1inch Limit Order Protocol v4";
1306
+ if (!listed(trusted.orderProtocols, params.sourceChain, contract) || !tx.approvalAddress || (0, import_viem.getAddress)(tx.approvalAddress) !== (0, import_viem.getAddress)(String(contract))) {
1307
+ return `${String(contract)} is not a trusted order protocol on ${params.sourceChain}`;
1308
+ }
1309
+ if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return "the domain chainId is not the source chain";
1310
+ const order = td.types?.Order;
1311
+ const message = td.message;
1312
+ if (td.primaryType !== "Order" || !Array.isArray(order) || order.length !== ORDER_FIELDS.length || !order.every((field, i) => field.name === ORDER_FIELDS[i][0] && field.type === ORDER_FIELDS[i][1]) || !message || Object.keys(message).length !== ORDER_FIELDS.length || !ORDER_FIELDS.every(([name]) => Object.hasOwn(message, name)) || !ORDER_FIELDS.every(([name, type]) => type === "address" ? validEvmAddress(message[name]) : validUint256(message[name]))) {
1313
+ return "the typed data is not exactly a v4 Order";
1314
+ }
1315
+ if (!validEvmAddress(intent.trader) || (0, import_viem.getAddress)(String(message.maker)) !== (0, import_viem.getAddress)(intent.trader)) return "the maker is not the trader";
1316
+ if ((0, import_viem.getAddress)(String(message.makerAsset)) !== (0, import_viem.getAddress)(source.contract)) return "the makerAsset is not the source token";
1317
+ if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return "the makingAmount is not the input";
1318
+ if ((0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(String(message.makerAsset))) return "the takerAsset is the makerAsset";
1319
+ const floor = [quote.minDestAmount, params.minAmountOut ?? "0"].filter((v) => /^\d{1,80}$/.test(v)).map((v) => BigInt(v)).reduce((a, b) => a > b ? a : b, 0n);
1320
+ if (floor <= 0n || BigInt(message.takingAmount) < floor) return `takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}`;
1321
+ const traits = BigInt(message.makerTraits);
1322
+ const flags = traits & (1n << 56n) - 1n << 200n;
1323
+ const baseFlags = 1n << 251n | 1n << 249n;
1324
+ if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return "the makerTraits flags are not a single-fill order with its extension";
1325
+ if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return "the makerTraits restrict the taker or the series";
1326
+ const now = BigInt(Math.floor(Date.now() / 1e3));
1327
+ const expiration = traits >> 80n & (1n << 40n) - 1n;
1328
+ if (expiration <= now || expiration > now + BigInt(MAX_EVM_ORDER_LIFETIME_S)) return "the order's expiry is not minutes away";
1329
+ const extension = (0, import_viem.hexToBytes)(tx.orderExtension);
1330
+ const mask = (1n << 160n) - 1n;
1331
+ if ((BigInt(message.salt) & mask) !== (BigInt((0, import_viem.keccak256)(extension)) & mask)) return "the salt does not commit the order extension";
1332
+ let parsed;
1333
+ try {
1334
+ parsed = readEvmOrderExtension(extension);
1335
+ } catch (e) {
1336
+ return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
1337
+ }
1338
+ const { target, getter, post, extra, customData } = parsed;
1339
+ if (!listed(trusted.factories, params.sourceChain, target)) return `the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}`;
1340
+ const receiverLow80 = BigInt((0, import_viem.getAddress)(String(message.receiver))) & (1n << 80n) - 1n;
1341
+ if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return "the order's receiver is not the resolver its extension whitelists";
1342
+ if (getter.gasBump !== 0n || getter.gasPrice !== 0n || getter.duration !== 1800n || getter.initialRateBump !== 900000n || getter.points.some((point, index) => point[0] !== EVM_AUCTION_POINTS[index][0] || point[1] !== EVM_AUCTION_POINTS[index][1]) || getter.integratorFee !== 0n || getter.integratorShare !== 100n || getter.whitelistDiscount !== 50n || !within(getter.auctionStart, (0, import_core4.bigintToNumber)(now), MAX_EVM_ORDER_LIFETIME_S, 60)) {
1343
+ return "the amount-getter terms do not match the pinned v1beta8 profile";
1344
+ }
1345
+ if (!zeroBytes(post.integratorRecipient) || !(zeroBytes(post.protocolRecipient) || !tonDest && EVM_DEST_PROTOCOL_FEE_RECIPIENTS.has(`0x${bytesToHex(post.protocolRecipient)}`)) || post.integratorFee !== 0n || post.integratorShare !== 100n || post.resolverFee !== getter.resolverFee || post.discount !== 50n || post.resolverTimeDelta !== 0n || !within(post.allowedTime, (0, import_core4.bigintToNumber)(getter.auctionStart), 60, 5)) {
1346
+ return "the post-interaction terms do not match the pinned v1beta8 profile";
1347
+ }
1348
+ let dstToken;
1349
+ try {
1350
+ dstToken = tonDest ? BigInt((0, import_viem.getAddress)(String(message.takerAsset))) : BigInt((0, import_viem.getAddress)(outputToken));
1351
+ } catch {
1352
+ return "the destination token is not an EVM address";
1353
+ }
1354
+ if (extra[1] !== (tonDest ? 0n : BigInt(destChainId)) || extra[2] !== dstToken || extra[4] !== EVM_TIMELOCKS) {
1355
+ return "the signed HTLC terms name another destination chain or token, or other timelocks";
1356
+ }
1357
+ try {
1358
+ await checkOrderCustomData(customData, { evmDest: !tonDest, outputToken, traderDst: params.destAddress, quoteId: intent.quoteId });
1359
+ } catch (e) {
1360
+ return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
1361
+ }
1362
+ return null;
1363
+ }
1237
1364
  function omnistonVerifyBuild(hooks) {
1365
+ const trusted = {
1366
+ orderProtocols: hooks.trustedEvmOrderProtocols ?? AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS,
1367
+ factories: hooks.trustedSettlementContracts ?? AUDITED_OMNISTON_SETTLEMENT_CONTRACTS
1368
+ };
1238
1369
  return async (quote, tx, params) => {
1370
+ if (tx.typedData !== void 0) {
1371
+ if (!params) return "the request this quote answered is unknown";
1372
+ try {
1373
+ return await checkRemoteEvmOrder(quote, tx, params, trusted);
1374
+ } catch {
1375
+ return "the typed order could not be checked";
1376
+ }
1377
+ }
1239
1378
  if (tx.bodyBoc === void 0) return null;
1240
1379
  if (!params) return "the request this quote answered is unknown";
1241
- if (quote.providerData?.settlement !== "swap") return "only TON swap bodies can be checked on the client";
1380
+ if (quote.providerData?.settlement !== "swap") {
1381
+ if (params.sourceChain.startsWith("ton:") && params.destChain.startsWith("eip155:")) {
1382
+ if (!hooks.verifyTonEscrowBuild) return "a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)";
1383
+ if (!params.refundAddress) return "the trader's TON address (refundAddress) is unknown";
1384
+ const floor = [quote.minDestAmount, params.minAmountOut ?? "0"].filter((v) => /^\d{1,80}$/.test(v)).map((v) => BigInt(v)).reduce((a, b) => a > b ? a : b, 0n);
1385
+ try {
1386
+ return await hooks.verifyTonEscrowBuild({
1387
+ payloadBocHex: import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"),
1388
+ ownerAddress: params.refundAddress,
1389
+ inputUnits: quote.sourceAmount,
1390
+ destinationChain: params.destChain,
1391
+ destinationAddress: params.destAddress,
1392
+ outputTokenAddress: params.destToken,
1393
+ minResolverSendsUnits: floor.toString()
1394
+ });
1395
+ } catch {
1396
+ return "the escrow body could not be checked";
1397
+ }
1398
+ }
1399
+ return "only TON swap and TON \u2192 EVM escrow bodies can be checked on the client";
1400
+ }
1242
1401
  let steps;
1243
1402
  try {
1244
1403
  steps = JSON.parse(quote.providerData.routeSteps ?? "");
@@ -1905,7 +2064,7 @@ function omnistonProvider(opts = {}) {
1905
2064
  }
1906
2065
  });
1907
2066
  const orderProtocol = (0, import_viem.getAddress)(protocol.chain.value);
1908
- return { chain: srcChain, to: orderProtocol, value: "0", chainId, approvalAddress: orderProtocol, typedData };
2067
+ return { chain: srcChain, to: orderProtocol, value: "0", chainId, approvalAddress: orderProtocol, typedData, orderExtension: `0x${bytesToHex(payload.orderExtension)}` };
1909
2068
  }
1910
2069
  return {
1911
2070
  name: "omniston",