@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.
@@ -531,6 +531,40 @@ function createOmnistonEvmInputValidator(options = {}) {
531
531
  var import_buffer = require("buffer");
532
532
  var import_core2 = require("@ton/core");
533
533
  var import_core3 = require("@anywalletkit/core");
534
+
535
+ // src/validators/settlement.ts
536
+ var AUDITED_OMNISTON_SETTLEMENT_CONTRACTS = {
537
+ "ton:-239": ["EQAbWJ3Y1HgIIvcMq1prG1anlDC0T3cZlAU7luPT6LmTpmrZ"],
538
+ "eip155:1": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
539
+ "eip155:56": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
540
+ "eip155:137": ["0x41A392062A4307a6961d48e30FF20bF6823715B8"],
541
+ "eip155:4663": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
542
+ "eip155:8453": ["0xACa3E2F9b61a44892926bC6c3e104192E7D1c3cd"],
543
+ "eip155:42161": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
544
+ "eip155:43114": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
545
+ // 2026-10-20: one factory address on X Layer, HyperEVM and Plasma. Runtime
546
+ // bytecode equals Ethereum's 0xafCF… byte for byte except the immutable slots
547
+ // (escrow implementations, its order protocol, domain hash); it references
548
+ // the order protocol trusted below on the same chain.
549
+ "eip155:196": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
550
+ "eip155:999": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
551
+ "eip155:9745": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"]
552
+ };
553
+ var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
554
+ "eip155:1": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
555
+ "eip155:56": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
556
+ "eip155:137": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
557
+ "eip155:8453": ["0xe7405fAcDEDB2512e91F2886BDff13231343aF5E"],
558
+ "eip155:42161": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
559
+ "eip155:43114": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
560
+ // 2026-10-20: bytecode equals Ethereum's 0xb581… except immutables (wrapped
561
+ // native, own address, chain id 196 / 9745 / 999 at the chain-id slot).
562
+ "eip155:196": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
563
+ "eip155:9745": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
564
+ "eip155:999": ["0xD84778bbeEC5D2a8d17c6424249C438EC0b1ABE3"]
565
+ };
566
+
567
+ // src/validators/ton.ts
534
568
  var JETTON_TRANSFER_OP = 260734629;
535
569
  var ESCROW_CREATE_OP = 3232100569;
536
570
  var ESCROW_CONFIG_OP = 4073126499;
@@ -707,6 +741,11 @@ function exactCellEnd(slice) {
707
741
  return slice.remainingBits === 0 && slice.remainingRefs === 0;
708
742
  }
709
743
  function destinationChainId(chain) {
744
+ const caip2 = /^eip155:([0-9]{1,10})$/.exec(chain);
745
+ if (caip2) {
746
+ const id = BigInt(caip2[1]);
747
+ return [1n, 56n, 137n, 4663n, 8453n, 42161n, 43114n, 196n, 999n, 9745n].includes(id) ? id : null;
748
+ }
710
749
  const ids = {
711
750
  ethereum: 1n,
712
751
  bnb: 56n,
@@ -721,6 +760,65 @@ function destinationChainId(chain) {
721
760
  };
722
761
  return ids[chain] ?? null;
723
762
  }
763
+ function readTonEscrowBody(payloadBocHex) {
764
+ const outer = oneRoot(payloadBocHex, "payload").beginParse();
765
+ if (outer.loadUint(32) !== JETTON_TRANSFER_OP) throw new Error("not a jetton transfer");
766
+ outer.loadUintBig(64);
767
+ const amount = outer.loadCoins();
768
+ const protocol = outer.loadAddressAny();
769
+ if (!(protocol instanceof import_core2.Address)) throw new Error("no protocol address");
770
+ outer.loadAddressAny();
771
+ if (outer.loadMaybeRef() !== null) throw new Error("custom payload");
772
+ outer.loadCoins();
773
+ if (!outer.loadBit() || outer.remainingRefs !== 1) throw new Error("no forward payload");
774
+ const forward = outer.loadRef();
775
+ const root = forward.beginParse();
776
+ if (root.loadUint(32) !== ESCROW_CREATE_OP) throw new Error("not an escrow create");
777
+ const quoteId = import_buffer.Buffer.from(root.loadBuffer(32)).toString("hex");
778
+ root.loadBit();
779
+ root.loadAddressAny();
780
+ root.loadCoins();
781
+ root.loadBit();
782
+ if (root.remainingRefs !== 4) throw new Error("escrow refs");
783
+ const config = root.loadRef().beginParse();
784
+ if (config.loadUint(32) !== ESCROW_CONFIG_OP) throw new Error("escrow config");
785
+ const resolver = config.loadAddressAny();
786
+ if (!(resolver instanceof import_core2.Address)) throw new Error("no resolver");
787
+ if (config.loadBit()) config.loadBuffer(32);
788
+ const exclusivity = config.loadUintBig(64);
789
+ config.loadUintBig(64);
790
+ if (config.remainingRefs !== 2) throw new Error("escrow config refs");
791
+ const state = config.loadRef();
792
+ if (!config.loadBit()) throw new Error("no destination");
793
+ const destination = config.loadRef().beginParse();
794
+ if (state.refs.length !== 2) throw new Error("escrow state");
795
+ const execution = state.refs[1].beginParse();
796
+ execution.loadUint(32);
797
+ const secretHash = new Uint8Array(execution.loadBuffer(32));
798
+ execution.loadAddressAny();
799
+ for (let i = 0; i < 4; i++) execution.loadUintBig(64);
800
+ const ownerData = execution.loadRef().beginParse();
801
+ ownerData.loadAddressAny();
802
+ ownerData.loadBit();
803
+ const deposit = ownerData.loadCoins();
804
+ destination.loadUintBig(64);
805
+ destination.loadBuffer(20);
806
+ destination.loadBuffer(20);
807
+ const resolverSends = destination.loadCoins();
808
+ if (exclusivity > BigInt(MAX_OMNISTON_EXCLUSIVITY_SECONDS)) throw new Error("exclusivity");
809
+ return {
810
+ amount,
811
+ protocolAddress: protocol.toString(),
812
+ forwardPayloadBocHex: import_buffer.Buffer.from(forward.toBoc()).toString("hex"),
813
+ quoteId,
814
+ initialResolverAddress: resolver.toString(),
815
+ exclusivityTimeout: Number(exclusivity.toString()),
816
+ // bounded above
817
+ secretHash,
818
+ depositUnits: deposit.toString(),
819
+ resolverSendsUnits: resolverSends.toString()
820
+ };
821
+ }
724
822
  function validatePayload(input, trusted) {
725
823
  const exclusivityTimeout = input.exclusivityTimeout;
726
824
  if (typeof exclusivityTimeout !== "number" || !Number.isSafeInteger(exclusivityTimeout) || exclusivityTimeout < 1 || exclusivityTimeout > MAX_OMNISTON_EXCLUSIVITY_SECONDS) return false;
@@ -838,6 +936,7 @@ function createOmnistonTonValidators(options = {}) {
838
936
  position: new Set((options.positionCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.position).map((value) => value.toLowerCase())),
839
937
  outputEscrow: new Set((options.outputEscrowCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.outputEscrow).map((value) => value.toLowerCase()))
840
938
  };
939
+ const trustedProtocols = new Set((options.trustedProtocolAddresses ?? AUDITED_OMNISTON_SETTLEMENT_CONTRACTS["ton:-239"] ?? []).map((value) => import_core2.Address.parse(value).toRawString()));
841
940
  const jettonWalletOf = async (ownerAddress, jettonMasterAddress) => {
842
941
  const response = await get(`/v2/accounts/${encodeURIComponent(ownerAddress)}/jettons/${encodeURIComponent(jettonMasterAddress)}`);
843
942
  if (!response.ok) return null;
@@ -869,6 +968,51 @@ function createOmnistonTonValidators(options = {}) {
869
968
  return false;
870
969
  }
871
970
  },
971
+ /**
972
+ * The app's own check of a TON → EVM escrow build behind `remoteProvider` (through `omnistonVerifyBuild`): the
973
+ * structural check `validateTonEscrowPayload` runs on the server, with every field that decides where the
974
+ * trader's money goes taken from the app — the jetton amount, the owner the excess and refunds go to, the
975
+ * destination chain, address and token, a delivery of at least `minResolverSendsUnits`, and a protocol contract
976
+ * from `trustedProtocolAddresses`. The fields the server and the resolver choose (quote id, resolver, hashlock,
977
+ * exclusivity, deposit) are read from the body and held to the same pins and bounds: audited escrow and
978
+ * execution code, authority key, one execution, the reviewed timelocks, no Dutch auction. A reason, or `null`.
979
+ */
980
+ verifyTonEscrowBuild(input) {
981
+ let body;
982
+ try {
983
+ body = readTonEscrowBody(input.payloadBocHex);
984
+ } catch {
985
+ return "the escrow body is not an Omniston escrow transfer";
986
+ }
987
+ if (!trustedProtocols.has(import_core2.Address.parse(body.protocolAddress).toRawString())) return `the escrow transfer pays ${body.protocolAddress}, not an Omniston protocol contract this app trusts`;
988
+ if (!/^\d{1,40}$/.test(input.inputUnits) || body.amount !== BigInt(input.inputUnits)) return `the escrow transfer moves ${body.amount}, not the ${input.inputUnits} this swap sells`;
989
+ if (!/^\d{1,80}$/.test(input.minResolverSendsUnits) || BigInt(body.resolverSendsUnits) < BigInt(input.minResolverSendsUnits)) {
990
+ return `the resolver is bound to deliver ${body.resolverSendsUnits}, under the quote's minimum ${input.minResolverSendsUnits}`;
991
+ }
992
+ let ok = false;
993
+ try {
994
+ ok = validatePayload({
995
+ payloadBocHex: input.payloadBocHex,
996
+ forwardPayloadBocHex: body.forwardPayloadBocHex,
997
+ quoteId: body.quoteId,
998
+ inputUnits: input.inputUnits,
999
+ resolverSendsUnits: body.resolverSendsUnits,
1000
+ srcHtlcSecurityDepositUnits: body.depositUnits,
1001
+ protocolAddress: body.protocolAddress,
1002
+ ownerAddress: input.ownerAddress,
1003
+ destinationChain: input.destinationChain,
1004
+ destinationAddress: input.destinationAddress,
1005
+ outputTokenAddress: input.outputTokenAddress,
1006
+ initialResolverAddress: body.initialResolverAddress,
1007
+ secretHashes: [body.secretHash],
1008
+ hashingFunction: "HASHING_FUNCTION_KECCAK256",
1009
+ exclusivityTimeout: body.exclusivityTimeout
1010
+ }, trusted);
1011
+ } catch {
1012
+ ok = false;
1013
+ }
1014
+ return ok ? null : "the escrow body is not this swap's (owner, destination chain, address or token) or not the audited escrow (code, authority, timelocks)";
1015
+ },
872
1016
  /**
873
1017
  * EVM→TON: the position the tracking feed named must be (1) an active
874
1018
  * contract with the pinned position code, (2) carrying state that binds
@@ -1039,36 +1183,4 @@ function createOmnistonTonDeliveryLocator(options = {}) {
1039
1183
  }
1040
1184
  };
1041
1185
  }
1042
-
1043
- // src/validators/settlement.ts
1044
- var AUDITED_OMNISTON_SETTLEMENT_CONTRACTS = {
1045
- "ton:-239": ["EQAbWJ3Y1HgIIvcMq1prG1anlDC0T3cZlAU7luPT6LmTpmrZ"],
1046
- "eip155:1": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1047
- "eip155:56": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1048
- "eip155:137": ["0x41A392062A4307a6961d48e30FF20bF6823715B8"],
1049
- "eip155:4663": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1050
- "eip155:8453": ["0xACa3E2F9b61a44892926bC6c3e104192E7D1c3cd"],
1051
- "eip155:42161": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1052
- "eip155:43114": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1053
- // 2026-10-20: one factory address on X Layer, HyperEVM and Plasma. Runtime
1054
- // bytecode equals Ethereum's 0xafCF… byte for byte except the immutable slots
1055
- // (escrow implementations, its order protocol, domain hash); it references
1056
- // the order protocol trusted below on the same chain.
1057
- "eip155:196": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
1058
- "eip155:999": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
1059
- "eip155:9745": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"]
1060
- };
1061
- var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
1062
- "eip155:1": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1063
- "eip155:56": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1064
- "eip155:137": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1065
- "eip155:8453": ["0xe7405fAcDEDB2512e91F2886BDff13231343aF5E"],
1066
- "eip155:42161": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1067
- "eip155:43114": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1068
- // 2026-10-20: bytecode equals Ethereum's 0xb581… except immutables (wrapped
1069
- // native, own address, chain id 196 / 9745 / 999 at the chain-id slot).
1070
- "eip155:196": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1071
- "eip155:9745": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1072
- "eip155:999": ["0xD84778bbeEC5D2a8d17c6424249C438EC0b1ABE3"]
1073
- };
1074
1186
  //# sourceMappingURL=validators.cjs.map