@anywalletkit/protocol-swap2-omniston 0.0.0-stage → 0.2.2

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.
Files changed (48) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +94 -2
  3. package/dist/activity.cjs +79 -0
  4. package/dist/activity.cjs.map +1 -0
  5. package/dist/activity.d.cts +10 -0
  6. package/dist/activity.d.ts +10 -0
  7. package/dist/activity.js +13 -0
  8. package/dist/activity.js.map +1 -0
  9. package/dist/chunk-AIWAM7BS.js +59 -0
  10. package/dist/chunk-AIWAM7BS.js.map +1 -0
  11. package/dist/chunk-K2KBWGNL.js +27 -0
  12. package/dist/chunk-K2KBWGNL.js.map +1 -0
  13. package/dist/chunk-QDXFC6BC.js +30 -0
  14. package/dist/chunk-QDXFC6BC.js.map +1 -0
  15. package/dist/chunk-W3AXGSX3.js +2148 -0
  16. package/dist/chunk-W3AXGSX3.js.map +1 -0
  17. package/dist/config.cjs +50 -0
  18. package/dist/config.cjs.map +1 -0
  19. package/dist/config.d.cts +12 -0
  20. package/dist/config.d.ts +12 -0
  21. package/dist/config.js +7 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/index.cjs +2276 -0
  24. package/dist/index.cjs.map +1 -0
  25. package/dist/index.d.cts +8 -0
  26. package/dist/index.d.ts +8 -0
  27. package/dist/index.js +40 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/protocol.cjs +2262 -0
  30. package/dist/protocol.cjs.map +1 -0
  31. package/dist/protocol.d.cts +15 -0
  32. package/dist/protocol.d.ts +15 -0
  33. package/dist/protocol.js +10 -0
  34. package/dist/protocol.js.map +1 -0
  35. package/dist/provider.cjs +2251 -0
  36. package/dist/provider.cjs.map +1 -0
  37. package/dist/provider.d.cts +590 -0
  38. package/dist/provider.d.ts +590 -0
  39. package/dist/provider.js +23 -0
  40. package/dist/provider.js.map +1 -0
  41. package/dist/validators.cjs +1072 -0
  42. package/dist/validators.cjs.map +1 -0
  43. package/dist/validators.d.cts +199 -0
  44. package/dist/validators.d.ts +199 -0
  45. package/dist/validators.js +1065 -0
  46. package/dist/validators.js.map +1 -0
  47. package/module.json +17 -0
  48. package/package.json +88 -3
@@ -0,0 +1,1065 @@
1
+ // src/validators/evm-output.ts
2
+ import {
3
+ decodeAbiParameters,
4
+ decodeFunctionResult,
5
+ encodeFunctionData,
6
+ getAddress,
7
+ isAddress,
8
+ keccak256,
9
+ stringToHex
10
+ } from "viem";
11
+ var ESCROW_FACTORY_ABI = [
12
+ {
13
+ type: "function",
14
+ name: "createDstEscrow",
15
+ stateMutability: "payable",
16
+ inputs: [
17
+ {
18
+ name: "dstImmutables",
19
+ type: "tuple",
20
+ components: [
21
+ { name: "orderHash", type: "bytes32" },
22
+ { name: "hashlock", type: "bytes32" },
23
+ { name: "maker", type: "uint256" },
24
+ { name: "taker", type: "uint256" },
25
+ { name: "token", type: "uint256" },
26
+ { name: "amount", type: "uint256" },
27
+ { name: "safetyDeposit", type: "uint256" },
28
+ { name: "timelocks", type: "uint256" },
29
+ { name: "parameters", type: "bytes" }
30
+ ]
31
+ },
32
+ { name: "srcCancellationTimestamp", type: "uint256" }
33
+ ],
34
+ outputs: []
35
+ },
36
+ {
37
+ type: "function",
38
+ name: "addressOfEscrowDst",
39
+ stateMutability: "view",
40
+ inputs: [
41
+ {
42
+ name: "immutables",
43
+ type: "tuple",
44
+ components: [
45
+ { name: "orderHash", type: "bytes32" },
46
+ { name: "hashlock", type: "bytes32" },
47
+ { name: "maker", type: "uint256" },
48
+ { name: "taker", type: "uint256" },
49
+ { name: "token", type: "uint256" },
50
+ { name: "amount", type: "uint256" },
51
+ { name: "safetyDeposit", type: "uint256" },
52
+ { name: "timelocks", type: "uint256" },
53
+ { name: "parameters", type: "bytes" }
54
+ ]
55
+ }
56
+ ],
57
+ outputs: [{ name: "escrow", type: "address" }]
58
+ }
59
+ ];
60
+ var FACTORY_ABI = [{
61
+ type: "function",
62
+ name: "FACTORY",
63
+ stateMutability: "view",
64
+ inputs: [],
65
+ outputs: [{ type: "address" }]
66
+ }];
67
+ var BALANCE_OF_ABI = [{
68
+ type: "function",
69
+ name: "balanceOf",
70
+ stateMutability: "view",
71
+ inputs: [{ name: "account", type: "address" }],
72
+ outputs: [{ type: "uint256" }]
73
+ }];
74
+ var DST_ESCROW_CREATED_TOPIC = keccak256(stringToHex("DstEscrowCreated(address,bytes32,uint256)"));
75
+ var UINT32_MASK = (1n << 32n) - 1n;
76
+ var DEPLOYED_AT_OFFSET = 224n;
77
+ var DEPLOYED_AT_MASK = UINT32_MASK << DEPLOYED_AT_OFFSET;
78
+ var ADDRESS_MASK = (1n << 160n) - 1n;
79
+ var DST_STAGES = [1n, 120n, 180n];
80
+ var DST_STAGE_WORD = 4;
81
+ var DST_CANCELLATION_STAGE = 2;
82
+ var DISCLOSURE_MARGIN_SECONDS = 45n;
83
+ var FEE_PARAMETERS = [{ type: "uint256" }, { type: "uint256" }, { type: "uint256" }, { type: "uint256" }];
84
+ var FEE_PARAMETERS_HEX_LENGTH = 2 + 128 * 2;
85
+ var DEFAULT_RPC_URLS = {
86
+ "eip155:1": ["https://ethereum-rpc.publicnode.com"],
87
+ "eip155:56": ["https://bsc-rpc.publicnode.com"],
88
+ "eip155:137": ["https://polygon-bor-rpc.publicnode.com"],
89
+ "eip155:4663": ["https://rpc.mainnet.chain.robinhood.com"],
90
+ "eip155:8453": ["https://base-rpc.publicnode.com"],
91
+ "eip155:42161": ["https://arbitrum-one-rpc.publicnode.com"],
92
+ "eip155:43114": ["https://avalanche-c-chain-rpc.publicnode.com"],
93
+ "eip155:196": ["https://rpc.xlayer.tech"],
94
+ "eip155:999": ["https://rpc.hyperliquid.xyz/evm"],
95
+ "eip155:9745": ["https://rpc.plasma.to"]
96
+ };
97
+ var OMNISTON_EVM_LOOKBACK_BLOCKS = {
98
+ "eip155:1": 3000n,
99
+ "eip155:56": 40000n,
100
+ "eip155:137": 20000n,
101
+ "eip155:4663": 100000n,
102
+ "eip155:8453": 20000n,
103
+ "eip155:42161": 100000n,
104
+ "eip155:43114": 20000n,
105
+ // ~1 s blocks (measured 2026-10-20): ~11 h, past the 6 h quote horizon.
106
+ "eip155:196": 40000n,
107
+ "eip155:999": 40000n,
108
+ "eip155:9745": 40000n
109
+ };
110
+ var OMNISTON_EVM_MIN_CONFIRMATIONS = {
111
+ "eip155:1": 2n,
112
+ "eip155:56": 5n,
113
+ "eip155:137": 20n,
114
+ "eip155:4663": 20n,
115
+ "eip155:8453": 20n,
116
+ "eip155:42161": 20n,
117
+ "eip155:43114": 5n,
118
+ "eip155:196": 20n,
119
+ // sequencer rollup
120
+ "eip155:999": 5n,
121
+ // HyperBFT, fast finality
122
+ "eip155:9745": 5n
123
+ // PlasmaBFT, fast finality
124
+ };
125
+ function quantity(value) {
126
+ return `0x${value.toString(16)}`;
127
+ }
128
+ function uintAddress(value) {
129
+ return getAddress(`0x${(value & ADDRESS_MASK).toString(16).padStart(40, "0")}`);
130
+ }
131
+ function bytesHex(bytes) {
132
+ return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
133
+ }
134
+ function stage(timelocks, index) {
135
+ return timelocks >> BigInt(index * 32) & UINT32_MASK;
136
+ }
137
+ function decodeFeeParameters(parameters) {
138
+ if (parameters.length !== FEE_PARAMETERS_HEX_LENGTH) return null;
139
+ try {
140
+ const [protocolFee, integratorFee, protocolFeeRecipient, integratorFeeRecipient] = decodeAbiParameters(FEE_PARAMETERS, parameters);
141
+ return { protocolFee, integratorFee, protocolFeeRecipient, integratorFeeRecipient };
142
+ } catch {
143
+ return null;
144
+ }
145
+ }
146
+ async function omnistonEvmRpcRequest(chain, method, params, rpcUrls) {
147
+ const urls = [...rpcUrls?.[chain] ?? [], ...DEFAULT_RPC_URLS[chain] ?? []].filter((url) => !!url);
148
+ if (!urls.length) throw new Error(`omniston: no RPC configured for ${chain}`);
149
+ let lastError;
150
+ for (const url of urls) {
151
+ try {
152
+ const response = await fetch(url, {
153
+ method: "POST",
154
+ headers: { "content-type": "application/json" },
155
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
156
+ signal: AbortSignal.timeout(1e4)
157
+ });
158
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
159
+ const body = await response.json();
160
+ if (body.error !== void 0 || body.result === void 0) throw new Error("invalid JSON-RPC response");
161
+ return body.result;
162
+ } catch (error) {
163
+ lastError = error;
164
+ }
165
+ }
166
+ throw lastError instanceof Error ? lastError : new Error(`omniston: RPC failed for ${chain}`);
167
+ }
168
+ async function ethCall(request, chain, to, data) {
169
+ return await request(chain, "eth_call", [{ to, data }, "latest"]);
170
+ }
171
+ function locateImmutables(input, secretHash) {
172
+ const data = input.slice(2).toLowerCase();
173
+ const needle = secretHash.slice(2).toLowerCase();
174
+ const at = data.indexOf(needle);
175
+ if (at < 72 || (at - 8) % 64 !== 0 || data.length < at + 64 * 8) return null;
176
+ const start = at - 64;
177
+ const word = (i) => BigInt(`0x${data.slice(at + 64 * i, at + 64 * (i + 1))}`);
178
+ try {
179
+ const offset = word(7);
180
+ if (offset % 32n !== 0n || offset < 288n || offset > 4096n) return null;
181
+ const lengthAt = start + Number(offset) * 2;
182
+ if (data.length < lengthAt + 64) return null;
183
+ const length = BigInt(`0x${data.slice(lengthAt, lengthAt + 64)}`);
184
+ if (length > 1024n || data.length < lengthAt + 64 + Number(length) * 2) return null;
185
+ return {
186
+ orderHash: `0x${data.slice(start, at)}`,
187
+ hashlock: `0x${needle}`,
188
+ maker: word(1),
189
+ taker: word(2),
190
+ token: word(3),
191
+ amount: word(4),
192
+ safetyDeposit: word(5),
193
+ timelocks: word(6),
194
+ parameters: `0x${data.slice(lengthAt + 64, lengthAt + 64 + Number(length) * 2)}`
195
+ };
196
+ } catch {
197
+ return null;
198
+ }
199
+ }
200
+ function createOmnistonEvmOutputValidator(options = {}) {
201
+ const refuse = (reason, details) => {
202
+ try {
203
+ options.onRefusal?.(reason, details);
204
+ } catch {
205
+ }
206
+ return false;
207
+ };
208
+ const request = options.request ?? ((chain, method, params) => omnistonEvmRpcRequest(chain, method, params, options.rpcUrls));
209
+ const now = options.now ?? Date.now;
210
+ return async (input) => {
211
+ try {
212
+ if (!OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain] || input.executionIndex !== 0 || !isAddress(input.positionAddress) || !isAddress(input.factoryAddress) || !isAddress(input.recipientAddress) || !isAddress(input.outputTokenAddress) || !Number.isInteger(input.quoteTimestamp) || input.quoteTimestamp * 1e3 > now() + 12e4 || now() - input.quoteTimestamp * 1e3 > 6 * 60 * 60 * 1e3) return refuse("input-shape");
213
+ const position = getAddress(input.positionAddress);
214
+ const factory = getAddress(input.factoryAddress);
215
+ const recipient = getAddress(input.recipientAddress);
216
+ const token = getAddress(input.outputTokenAddress);
217
+ const secretHash = bytesHex(input.secretHash);
218
+ const outputUnits = BigInt(input.outputUnits);
219
+ const resolverSendsUnits = BigInt(input.resolverSendsUnits);
220
+ const protocolFeeUnits = BigInt(input.protocolFeeUnits);
221
+ const integratorFeeUnits = BigInt(input.integratorFeeUnits);
222
+ const dstDeposit = BigInt(input.dstSecurityDepositUnits);
223
+ if (BigInt(input.inputUnits) <= 0n || outputUnits <= 0n || dstDeposit <= 0n || resolverSendsUnits !== outputUnits + protocolFeeUnits + integratorFeeUnits || input.secretHash.length !== 32) return refuse("quote-amounts", { outputUnits: String(outputUnits), resolverSendsUnits: String(resolverSendsUnits), protocolFeeUnits: String(protocolFeeUnits), integratorFeeUnits: String(integratorFeeUnits) });
224
+ if (protocolFeeUnits < 0n || integratorFeeUnits < 0n) return refuse("quote-amounts", { protocolFeeUnits: String(protocolFeeUnits), integratorFeeUnits: String(integratorFeeUnits) });
225
+ if (protocolFeeUnits > 0n && (!input.protocolFeeRecipientAddress || !isAddress(input.protocolFeeRecipientAddress))) {
226
+ return refuse("quote-missing-protocol-fee-recipient", { protocolFeeUnits: String(protocolFeeUnits) });
227
+ }
228
+ if (integratorFeeUnits > 0n && (!input.integratorAddress || !isAddress(input.integratorAddress))) {
229
+ return refuse("quote-missing-integrator-address", { integratorFeeUnits: String(integratorFeeUnits) });
230
+ }
231
+ const latest = BigInt(await request(input.chain, "eth_blockNumber", []));
232
+ const minConfirmations = OMNISTON_EVM_MIN_CONFIRMATIONS[input.chain] ?? 20n;
233
+ const newestFinal = latest >= minConfirmations ? latest - minConfirmations : 0n;
234
+ const oldest = newestFinal > OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain] ? newestFinal - OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain] : 0n;
235
+ let matchingLog;
236
+ for (let to = newestFinal; to >= oldest && !matchingLog; ) {
237
+ const from = to - oldest > 4999n ? to - 4999n : oldest;
238
+ const logs = await request(input.chain, "eth_getLogs", [{
239
+ address: factory,
240
+ topics: [DST_ESCROW_CREATED_TOPIC],
241
+ fromBlock: quantity(from),
242
+ toBlock: quantity(to)
243
+ }]);
244
+ matchingLog = logs.find((log) => {
245
+ try {
246
+ const [escrow, hashlock] = decodeAbiParameters(
247
+ [{ type: "address" }, { type: "bytes32" }, { type: "uint256" }],
248
+ log.data
249
+ );
250
+ return getAddress(escrow) === position && hashlock.toLowerCase() === secretHash.toLowerCase();
251
+ } catch {
252
+ return false;
253
+ }
254
+ });
255
+ if (from === oldest) break;
256
+ to = from - 1n;
257
+ }
258
+ if (!matchingLog) return refuse("no-escrow-event", { factory, lookback: String(OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain]) });
259
+ const [transaction, receipt, block, code] = await Promise.all([
260
+ request(input.chain, "eth_getTransactionByHash", [matchingLog.transactionHash]),
261
+ request(input.chain, "eth_getTransactionReceipt", [matchingLog.transactionHash]),
262
+ request(input.chain, "eth_getBlockByNumber", [matchingLog.blockNumber, false]),
263
+ request(input.chain, "eth_getCode", [position, "latest"])
264
+ ]);
265
+ if (!transaction || !receipt || !block || !code || code === "0x" || receipt.status !== "0x1" || BigInt(receipt.blockNumber) !== BigInt(matchingLog.blockNumber) || latest - BigInt(receipt.blockNumber) < minConfirmations || BigInt(block.timestamp) + 120n < BigInt(input.quoteTimestamp)) return refuse("receipt-or-confirmations", { receiptStatus: receipt?.status, receiptBlock: receipt?.blockNumber, logBlock: matchingLog.blockNumber, latest: String(latest), minConfirmations: String(minConfirmations), codeLength: code ? code.length : 0, blockTimestamp: block?.timestamp });
266
+ const immutables = locateImmutables(transaction.input, secretHash);
267
+ if (!immutables) return refuse("immutables-not-found", { transaction: matchingLog.transactionHash });
268
+ const stamped = { ...immutables, timelocks: immutables.timelocks & ~DEPLOYED_AT_MASK | BigInt(block.timestamp) << DEPLOYED_AT_OFFSET };
269
+ const derived = decodeFunctionResult({
270
+ abi: ESCROW_FACTORY_ABI,
271
+ functionName: "addressOfEscrowDst",
272
+ data: await ethCall(request, input.chain, factory, encodeFunctionData({ abi: ESCROW_FACTORY_ABI, functionName: "addressOfEscrowDst", args: [stamped] }))
273
+ });
274
+ if (getAddress(derived) !== position) return refuse("derived-address", { derived, position });
275
+ if (!(uintAddress(immutables.maker) === recipient && uintAddress(immutables.token) === token && immutables.amount === resolverSendsUnits && immutables.safetyDeposit === dstDeposit)) return refuse("escrow-terms", { maker: uintAddress(immutables.maker), recipient, token: uintAddress(immutables.token), expectedToken: token, amount: String(immutables.amount), resolverSendsUnits: String(resolverSendsUnits), safetyDeposit: String(immutables.safetyDeposit), dstDeposit: String(dstDeposit) });
276
+ const fees = decodeFeeParameters(immutables.parameters);
277
+ if (!fees || fees.protocolFeeRecipient > ADDRESS_MASK || fees.integratorFeeRecipient > ADDRESS_MASK) {
278
+ return refuse("fee-parameters-shape", { parametersLength: (immutables.parameters.length - 2) / 2 });
279
+ }
280
+ if (fees.protocolFee !== protocolFeeUnits || fees.integratorFee !== integratorFeeUnits || immutables.amount - fees.protocolFee - fees.integratorFee !== outputUnits) {
281
+ return refuse("fee-amounts", { protocolFee: String(fees.protocolFee), protocolFeeUnits: String(protocolFeeUnits), integratorFee: String(fees.integratorFee), integratorFeeUnits: String(integratorFeeUnits), amount: String(immutables.amount), outputUnits: String(outputUnits) });
282
+ }
283
+ if (fees.protocolFee > 0n && uintAddress(fees.protocolFeeRecipient) !== getAddress(input.protocolFeeRecipientAddress)) {
284
+ return refuse("protocol-fee-recipient", { escrow: uintAddress(fees.protocolFeeRecipient), quote: getAddress(input.protocolFeeRecipientAddress) });
285
+ }
286
+ if (fees.integratorFee > 0n && uintAddress(fees.integratorFeeRecipient) !== getAddress(input.integratorAddress)) {
287
+ return refuse("integrator-fee-recipient", { escrow: uintAddress(fees.integratorFeeRecipient), quote: getAddress(input.integratorAddress) });
288
+ }
289
+ if (DST_STAGES.some((expected, index) => stage(immutables.timelocks, DST_STAGE_WORD + index) !== expected)) {
290
+ return refuse("dst-timelocks", { stages: DST_STAGES.map((_, index) => String(stage(immutables.timelocks, DST_STAGE_WORD + index))) });
291
+ }
292
+ const deployedAt = BigInt(block.timestamp);
293
+ const nowSeconds = BigInt(Math.floor(now() / 1e3));
294
+ if (nowSeconds + DISCLOSURE_MARGIN_SECONDS >= deployedAt + DST_STAGES[DST_CANCELLATION_STAGE]) {
295
+ return refuse("dst-cancellation-window", { now: String(nowSeconds), deployedAt: String(deployedAt), cancellationAt: String(deployedAt + DST_STAGES[DST_CANCELLATION_STAGE]), marginSeconds: String(DISCLOSURE_MARGIN_SECONDS) });
296
+ }
297
+ const [reportedFactory, tokenBalance, nativeBalance] = await Promise.all([
298
+ ethCall(request, input.chain, position, encodeFunctionData({ abi: FACTORY_ABI, functionName: "FACTORY" })).then((data) => decodeFunctionResult({ abi: FACTORY_ABI, functionName: "FACTORY", data })),
299
+ ethCall(request, input.chain, token, encodeFunctionData({ abi: BALANCE_OF_ABI, functionName: "balanceOf", args: [position] })).then((data) => decodeFunctionResult({ abi: BALANCE_OF_ABI, functionName: "balanceOf", data })),
300
+ request(input.chain, "eth_getBalance", [position, "latest"])
301
+ ]);
302
+ const ok = getAddress(reportedFactory) === factory && tokenBalance >= resolverSendsUnits && BigInt(nativeBalance) >= dstDeposit;
303
+ return ok || refuse("escrow-state", { reportedFactory, factory, tokenBalance: String(tokenBalance), resolverSendsUnits: String(resolverSendsUnits), nativeBalance: String(BigInt(nativeBalance)), dstDeposit: String(dstDeposit) });
304
+ } catch (error) {
305
+ return refuse("error", { message: error instanceof Error ? error.message : String(error) });
306
+ }
307
+ };
308
+ }
309
+ var TRANSFER_TOPIC = keccak256(stringToHex("Transfer(address,address,uint256)"));
310
+ var topicAddress = (address) => `0x${getAddress(address).slice(2).toLowerCase().padStart(64, "0")}`;
311
+ function createOmnistonEvmDeliveryLocator(options = {}) {
312
+ const request = options.request ?? ((chain, method, params) => omnistonEvmRpcRequest(chain, method, params, options.rpcUrls));
313
+ return async (input) => {
314
+ try {
315
+ const lookback = OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain];
316
+ if (!lookback || !isAddress(input.positionAddress) || !isAddress(input.recipientAddress) || !isAddress(input.tokenAddress)) return null;
317
+ const min = BigInt(input.minUnits);
318
+ const latest = BigInt(await request(input.chain, "eth_blockNumber", []));
319
+ const oldest = latest > lookback ? latest - lookback : 0n;
320
+ for (let to = latest; to >= oldest; ) {
321
+ const from = to - oldest > 4999n ? to - 4999n : oldest;
322
+ const logs = await request(input.chain, "eth_getLogs", [{
323
+ address: getAddress(input.tokenAddress),
324
+ topics: [TRANSFER_TOPIC, topicAddress(input.positionAddress), topicAddress(input.recipientAddress)],
325
+ fromBlock: quantity(from),
326
+ toBlock: quantity(to)
327
+ }]);
328
+ const hit = [...logs].reverse().find((log) => {
329
+ try {
330
+ return getAddress(log.address) === getAddress(input.tokenAddress) && BigInt(log.data) >= min;
331
+ } catch {
332
+ return false;
333
+ }
334
+ });
335
+ if (hit) return hit.transactionHash;
336
+ if (from === oldest) break;
337
+ to = from - 1n;
338
+ }
339
+ return null;
340
+ } catch {
341
+ return null;
342
+ }
343
+ };
344
+ }
345
+
346
+ // src/validators/evm-input.ts
347
+ import {
348
+ decodeEventLog,
349
+ decodeFunctionResult as decodeFunctionResult2,
350
+ encodeFunctionData as encodeFunctionData2,
351
+ getAddress as getAddress2,
352
+ isAddress as isAddress2,
353
+ keccak256 as keccak2562,
354
+ stringToHex as stringToHex2
355
+ } from "viem";
356
+ var IMMUTABLES = [
357
+ { name: "orderHash", type: "bytes32" },
358
+ { name: "hashlock", type: "bytes32" },
359
+ { name: "maker", type: "uint256" },
360
+ { name: "taker", type: "uint256" },
361
+ { name: "token", type: "uint256" },
362
+ { name: "amount", type: "uint256" },
363
+ { name: "safetyDeposit", type: "uint256" },
364
+ { name: "timelocks", type: "uint256" },
365
+ { name: "parameters", type: "bytes" }
366
+ ];
367
+ var DST_COMPLEMENT = [
368
+ { name: "maker", type: "uint256" },
369
+ { name: "amount", type: "uint256" },
370
+ { name: "token", type: "uint256" },
371
+ { name: "safetyDeposit", type: "uint256" },
372
+ { name: "chainId", type: "uint256" },
373
+ { name: "parameters", type: "bytes" }
374
+ ];
375
+ var FACTORY_ABI2 = [
376
+ {
377
+ type: "event",
378
+ name: "SrcEscrowCreated",
379
+ inputs: [
380
+ { name: "srcImmutables", type: "tuple", components: IMMUTABLES, indexed: false },
381
+ { name: "dstImmutablesComplement", type: "tuple", components: DST_COMPLEMENT, indexed: false }
382
+ ]
383
+ },
384
+ {
385
+ type: "function",
386
+ name: "addressOfEscrowSrc",
387
+ stateMutability: "view",
388
+ inputs: [{ name: "immutables", type: "tuple", components: IMMUTABLES }],
389
+ outputs: [{ name: "escrow", type: "address" }]
390
+ },
391
+ { type: "function", name: "FACTORY", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
392
+ { type: "function", name: "balanceOf", stateMutability: "view", inputs: [{ name: "account", type: "address" }], outputs: [{ type: "uint256" }] }
393
+ ];
394
+ var SRC_ESCROW_CREATED_TOPIC = keccak2562(stringToHex2(
395
+ "SrcEscrowCreated((bytes32,bytes32,uint256,uint256,uint256,uint256,uint256,uint256,bytes),(uint256,uint256,uint256,uint256,uint256,bytes))"
396
+ ));
397
+ var SRC_STAGES = [1n, 120n, 240n, 300n, 1n, 120n, 180n];
398
+ var SRC_CANCELLATION_STAGE = 2;
399
+ var DISCLOSURE_MARGIN_SECONDS2 = 45n;
400
+ var UINT32_MASK2 = (1n << 32n) - 1n;
401
+ var ADDRESS_MASK2 = (1n << 160n) - 1n;
402
+ function quantity2(value) {
403
+ return `0x${value.toString(16)}`;
404
+ }
405
+ function uintAddress2(value) {
406
+ return getAddress2(`0x${(value & ADDRESS_MASK2).toString(16).padStart(40, "0")}`);
407
+ }
408
+ function bytesHex2(bytes) {
409
+ return `0x${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
410
+ }
411
+ function stage2(timelocks, index) {
412
+ return timelocks >> BigInt(index * 32) & UINT32_MASK2;
413
+ }
414
+ async function ethCall2(request, chain, to, data) {
415
+ return await request(chain, "eth_call", [{ to, data }, "latest"]);
416
+ }
417
+ function createOmnistonEvmInputValidator(options = {}) {
418
+ const refuse = (reason, details) => {
419
+ try {
420
+ options.onRefusal?.(reason, details);
421
+ } catch {
422
+ }
423
+ return false;
424
+ };
425
+ const request = options.request ?? ((chain, method, params) => omnistonEvmRpcRequest(chain, method, params, options.rpcUrls));
426
+ const now = options.now ?? Date.now;
427
+ return async (input) => {
428
+ try {
429
+ if (!OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain] || !isAddress2(input.positionAddress) || !isAddress2(input.factoryAddress) || !isAddress2(input.orderProtocolAddress) || !isAddress2(input.ownerAddress) || !isAddress2(input.resolverAddress) || !isAddress2(input.inputTokenAddress) || !Number.isInteger(input.quoteTimestamp) || input.quoteTimestamp * 1e3 > now() + 12e4 || now() - input.quoteTimestamp * 1e3 > 6 * 60 * 60 * 1e3 || input.secretHash.length !== 32) return refuse("input-shape");
430
+ const position = getAddress2(input.positionAddress);
431
+ const factory = getAddress2(input.factoryAddress);
432
+ const owner = getAddress2(input.ownerAddress);
433
+ const resolver = getAddress2(input.resolverAddress);
434
+ const token = getAddress2(input.inputTokenAddress);
435
+ const secretHash = bytesHex2(input.secretHash).toLowerCase();
436
+ const inputUnits = BigInt(input.inputUnits);
437
+ const resolverSendsUnits = BigInt(input.resolverSendsUnits);
438
+ const safetyDeposit = BigInt(input.srcHtlcSecurityDepositUnits);
439
+ if (inputUnits <= 0n || resolverSendsUnits <= 0n || safetyDeposit <= 0n) return refuse("non-positive-amounts");
440
+ const latest = BigInt(await request(input.chain, "eth_blockNumber", []));
441
+ const minConfirmations = OMNISTON_EVM_MIN_CONFIRMATIONS[input.chain] ?? 20n;
442
+ const newestFinal = latest >= minConfirmations ? latest - minConfirmations : 0n;
443
+ const lookback = OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain];
444
+ const oldest = newestFinal > lookback ? newestFinal - lookback : 0n;
445
+ let match;
446
+ for (let to = newestFinal; to >= oldest && !match; ) {
447
+ const from = to - oldest > 4999n ? to - 4999n : oldest;
448
+ const logs = await request(input.chain, "eth_getLogs", [{
449
+ address: factory,
450
+ topics: [SRC_ESCROW_CREATED_TOPIC],
451
+ fromBlock: quantity2(from),
452
+ toBlock: quantity2(to)
453
+ }]);
454
+ for (const log2 of logs) {
455
+ if (getAddress2(log2.address) !== factory) continue;
456
+ try {
457
+ const decoded = decodeEventLog({ abi: FACTORY_ABI2, eventName: "SrcEscrowCreated", data: log2.data, topics: log2.topics });
458
+ if (decoded.args.srcImmutables.hashlock.toLowerCase() === secretHash) {
459
+ match = { log: log2, immutables: decoded.args.srcImmutables, complement: decoded.args.dstImmutablesComplement };
460
+ break;
461
+ }
462
+ } catch {
463
+ }
464
+ }
465
+ if (from === oldest) break;
466
+ to = from - 1n;
467
+ }
468
+ if (!match) return refuse("no-fill-event", { factory, lookback: String(OMNISTON_EVM_LOOKBACK_BLOCKS[input.chain]) });
469
+ const { immutables, complement, log } = match;
470
+ const deployedAt = stage2(immutables.timelocks, 7);
471
+ if (uintAddress2(immutables.maker) !== owner || uintAddress2(immutables.taker) !== resolver || uintAddress2(immutables.token) !== token || immutables.amount !== inputUnits || immutables.safetyDeposit !== safetyDeposit || immutables.parameters !== "0x" || SRC_STAGES.some((expected, index) => stage2(immutables.timelocks, index) !== expected) || deployedAt < BigInt(input.quoteTimestamp) - 120n || deployedAt > BigInt(input.quoteTimestamp) + 900n || // EVM destination: the complement is the destination escrow's amount, enforced by its CREATE2
472
+ // derivation — exact. TON destination: Omniston records a larger figure here (live 2026-10-20,
473
+ // both orders: 1.089 × resolverSendsUnits — 4 485 039 for 4 118 665, 791 340 for 726 690); the
474
+ // delivered amount is proven on the TON position itself (validateTonOutputPosition), so this
475
+ // only has to be no smaller than the promise. Strict equality blocked every EVM → TON disclosure.
476
+ (input.destinationChainId !== void 0 ? complement.amount !== resolverSendsUnits : complement.amount < resolverSendsUnits)) return refuse("refused");
477
+ if (input.destinationChainId !== void 0 && (complement.chainId !== BigInt(input.destinationChainId) || !input.destinationTokenAddress || !isAddress2(input.destinationTokenAddress) || uintAddress2(complement.token) !== getAddress2(input.destinationTokenAddress) || complement.safetyDeposit !== BigInt(input.dstSecurityDepositUnits ?? "-1"))) return refuse("complement-destination");
478
+ const derived = decodeFunctionResult2({
479
+ abi: FACTORY_ABI2,
480
+ functionName: "addressOfEscrowSrc",
481
+ data: await ethCall2(request, input.chain, factory, encodeFunctionData2({ abi: FACTORY_ABI2, functionName: "addressOfEscrowSrc", args: [immutables] }))
482
+ });
483
+ if (getAddress2(derived) !== position) return refuse("derived-address", { derived, position });
484
+ const [receipt, block, code] = await Promise.all([
485
+ request(input.chain, "eth_getTransactionReceipt", [log.transactionHash]),
486
+ request(input.chain, "eth_getBlockByNumber", [log.blockNumber, false]),
487
+ request(input.chain, "eth_getCode", [position, "latest"])
488
+ ]);
489
+ if (!receipt || !block || !code || code === "0x" || receipt.status !== "0x1" || BigInt(receipt.blockNumber) !== BigInt(log.blockNumber) || latest - BigInt(receipt.blockNumber) < minConfirmations || BigInt(block.timestamp) !== deployedAt) return refuse("receipt-or-confirmations", { receiptStatus: receipt?.status, receiptBlock: receipt?.blockNumber, logBlock: log.blockNumber, latest: String(latest), minConfirmations: String(minConfirmations), codeLength: code ? code.length : 0, blockTimestamp: block?.timestamp, deployedAt: String(deployedAt) });
490
+ const nowSeconds = BigInt(Math.floor(now() / 1e3));
491
+ if (nowSeconds + DISCLOSURE_MARGIN_SECONDS2 >= deployedAt + SRC_STAGES[SRC_CANCELLATION_STAGE]) return refuse("receipt-or-confirmations", { receiptStatus: receipt?.status, receiptBlock: receipt?.blockNumber, logBlock: log.blockNumber, latest: String(latest), minConfirmations: String(minConfirmations), codeLength: code ? code.length : 0, blockTimestamp: block?.timestamp, deployedAt: String(deployedAt) });
492
+ const [reportedFactory, tokenBalance, nativeBalance] = await Promise.all([
493
+ ethCall2(request, input.chain, position, encodeFunctionData2({ abi: FACTORY_ABI2, functionName: "FACTORY" })).then((data) => decodeFunctionResult2({ abi: FACTORY_ABI2, functionName: "FACTORY", data })),
494
+ ethCall2(request, input.chain, token, encodeFunctionData2({ abi: FACTORY_ABI2, functionName: "balanceOf", args: [position] })).then((data) => decodeFunctionResult2({ abi: FACTORY_ABI2, functionName: "balanceOf", data })),
495
+ request(input.chain, "eth_getBalance", [position, "latest"])
496
+ ]);
497
+ const ok = getAddress2(reportedFactory) === factory && tokenBalance >= inputUnits && BigInt(nativeBalance) >= safetyDeposit;
498
+ return ok || refuse("escrow-state", { reportedFactory, factory, tokenBalance: String(tokenBalance), inputUnits: String(inputUnits), nativeBalance: String(BigInt(nativeBalance)), safetyDeposit: String(safetyDeposit) });
499
+ } catch (error) {
500
+ return refuse("error", { message: error instanceof Error ? error.message : String(error) });
501
+ }
502
+ };
503
+ }
504
+
505
+ // src/validators/ton.ts
506
+ import { Buffer } from "buffer";
507
+ import { Address, Cell } from "@ton/core";
508
+ var JETTON_TRANSFER_OP = 260734629;
509
+ var ESCROW_CREATE_OP = 3232100569;
510
+ var ESCROW_CONFIG_OP = 4073126499;
511
+ var ESCROW_EXECUTION_KECCAK_OP = 3369382952;
512
+ var MAX_FORWARD_NANO = 2000000000n;
513
+ var DEFAULT_OMNISTON_TON_CODE_HASHES = {
514
+ escrow: ["9e77cb9e8fd7406d4e85e5f57378eb51e51b862424cf988306c783d50ade697a"],
515
+ execution: ["f6edbc76e6fbcd6bac573cb942401a3d9198ee9605f9403b0f5c8081259210e5"],
516
+ authorityKeys: ["ed210da12aa96ea42de4f2f61dc172bbaa3da86051a1b2a6f342f69a777d2770"],
517
+ /** EVM→TON output position: the contract the factory deploys for the
518
+ * resolver's jetton lock (observed on every resolver-created position,
519
+ * 2026-10-15/16), and the escrow code cell it carries in its state. */
520
+ position: ["e4d5115a321ade7b827e38fb522c20d2f2cd46e4c6b0b5f7dd8b6b096792d77b"],
521
+ outputEscrow: ["d30423575384773abaad8d3c6f763898afa3d57a5693005904b7c61e95cee630"]
522
+ };
523
+ var POSITION_DEPLOY_OP = "0xf240cd30";
524
+ var POSITION_STAGES = { publicWithdrawalAfterWithdrawal: 119n, cancellationAfterWithdrawal: 179n };
525
+ var OUTPUT_DISCLOSURE_MARGIN_SECONDS = 45;
526
+ var MAX_OMNISTON_EXCLUSIVITY_SECONDS = 3600;
527
+ var DEFAULT_OMNISTON_TON_SWAP_INTERFACES = [
528
+ "stonfi_router",
529
+ "stonfi_router_v2",
530
+ "stonfi_pool",
531
+ "stonfi_pool_v2",
532
+ "dedust_vault",
533
+ "dedust_v2_cpmm",
534
+ "dedust_pool"
535
+ ];
536
+ var DEFAULT_OMNISTON_TON_PROXY_TON_MASTERS = [
537
+ "EQCM3B12QK1e4yZSf8GtBRT0aLMNyEsBc_DhVfRRtOEffLez",
538
+ // pTON v1
539
+ "EQBnGWMCf3-FZZq1W4IWcWiGAc3PHuZ0_H-7sad2oY00o83S"
540
+ // pTON v2
541
+ ];
542
+ function cellFromApi(value) {
543
+ const roots = Cell.fromBoc(Buffer.from(value, /^b5ee9c/i.test(value) ? "hex" : "base64"));
544
+ if (roots.length !== 1) throw new Error("omniston TON validator: account cell must have one root");
545
+ return roots[0];
546
+ }
547
+ var lastStateRefusal = null;
548
+ function validateOutputPositionState(data, input, expected) {
549
+ if (!/^[0-9a-fA-F]{48,64}$/.test(input.quoteId) || input.secretHash.length !== 32) {
550
+ lastStateRefusal = "state#1: if (!/^[0-9a-fA-F]{48,64}$/.test(input.quoteId) || input.secretHash.length !== 32) return null;";
551
+ return null;
552
+ }
553
+ if (!/^\d+$/.test(input.resolverSendsUnits) || !/^\d+$/.test(input.outputUnits) || !/^\d+$/.test(input.dstSecurityDepositUnits)) {
554
+ lastStateRefusal = "state#2: if (!/^\\d+$/.test(input.resolverSendsUnits) || !/^\\d+$/.test(input.outputUnits) || !/^\\d+$/.test(inp";
555
+ return null;
556
+ }
557
+ if (data.refs.length !== 3) {
558
+ lastStateRefusal = "state#3: if (data.refs.length !== 3) return null;";
559
+ return null;
560
+ }
561
+ const root = data.beginParse();
562
+ root.loadUint(8);
563
+ if (!sameHex(root.loadBuffer(32), input.quoteId.padStart(64, "0"))) {
564
+ lastStateRefusal = 'state#4: if (!sameHex(root.loadBuffer(32), input.quoteId.padStart(64, "0"))) return null;';
565
+ return null;
566
+ }
567
+ if (!sameAddress(root.loadAddressAny(), input.protocolAddress)) {
568
+ lastStateRefusal = "state#5: if (!sameAddress(root.loadAddressAny(), input.protocolAddress)) return null;";
569
+ return null;
570
+ }
571
+ if (!sameAddress(root.loadAddressAny(), expected.jettonWallet)) {
572
+ lastStateRefusal = "state#6: if (!sameAddress(root.loadAddressAny(), expected.jettonWallet)) return null;";
573
+ return null;
574
+ }
575
+ if (root.remainingBits !== 5 && root.remainingBits !== 29 || root.remainingRefs !== 3) {
576
+ lastStateRefusal = `state#7: root tail ${root.remainingBits} bits / ${root.remainingRefs} refs`;
577
+ return null;
578
+ }
579
+ const parties = data.refs[0];
580
+ if (parties.refs.length !== 2) {
581
+ lastStateRefusal = "state#8: if (parties.refs.length !== 2) return null;";
582
+ return null;
583
+ }
584
+ const partySlice = parties.beginParse();
585
+ if (!(partySlice.loadAddressAny() instanceof Address)) {
586
+ lastStateRefusal = "state#9: if (!(partySlice.loadAddressAny() instanceof Address)) return null; // owner (resolver) \u2014 any";
587
+ return null;
588
+ }
589
+ if (!sameAddress(partySlice.loadAddressAny(), input.outputJettonMasterAddress)) {
590
+ lastStateRefusal = "state#10: if (!sameAddress(partySlice.loadAddressAny(), input.outputJettonMasterAddress)) return null;";
591
+ return null;
592
+ }
593
+ if (partySlice.remainingBits !== 6) {
594
+ lastStateRefusal = "state#11: if (partySlice.remainingBits !== 6) return null;";
595
+ return null;
596
+ }
597
+ const lock = data.refs[1];
598
+ if (lock.refs.length !== 2) {
599
+ lastStateRefusal = "state#12: if (lock.refs.length !== 2) return null;";
600
+ return null;
601
+ }
602
+ const lockSlice = lock.beginParse();
603
+ if (!Buffer.from(lockSlice.loadBuffer(32)).equals(Buffer.from(input.secretHash))) {
604
+ lastStateRefusal = "state#13: if (!Buffer.from(lockSlice.loadBuffer(32)).equals(Buffer.from(input.secretHash))) return null;";
605
+ return null;
606
+ }
607
+ if (lockSlice.loadCoins() < BigInt(input.resolverSendsUnits)) {
608
+ lastStateRefusal = "state#14: if (lockSlice.loadCoins() < BigInt(input.resolverSendsUnits)) return null;";
609
+ return null;
610
+ }
611
+ const withdrawalAt = lockSlice.loadUintBig(64);
612
+ const publicWithdrawalAt = lockSlice.loadUintBig(64);
613
+ const cancellationAt = lockSlice.loadUintBig(64);
614
+ if (lockSlice.remainingBits !== 0) {
615
+ lastStateRefusal = "state#15: if (lockSlice.remainingBits !== 0) return null; // its two refs are the terms and authority cells be";
616
+ return null;
617
+ }
618
+ if (publicWithdrawalAt - withdrawalAt !== POSITION_STAGES.publicWithdrawalAfterWithdrawal) {
619
+ lastStateRefusal = "state#16: if (publicWithdrawalAt - withdrawalAt !== POSITION_STAGES.publicWithdrawalAfterWithdrawal) return nu";
620
+ return null;
621
+ }
622
+ if (cancellationAt - withdrawalAt !== POSITION_STAGES.cancellationAfterWithdrawal) {
623
+ lastStateRefusal = "state#17: if (cancellationAt - withdrawalAt !== POSITION_STAGES.cancellationAfterWithdrawal) return null;";
624
+ return null;
625
+ }
626
+ if (withdrawalAt < BigInt(input.quoteTimestamp) - 120n || withdrawalAt > BigInt(input.quoteTimestamp) + 900n) {
627
+ lastStateRefusal = "state#18: if (withdrawalAt < BigInt(input.quoteTimestamp) - 120n || withdrawalAt > BigInt(input.quoteTimestamp";
628
+ return null;
629
+ }
630
+ if (BigInt(expected.nowSeconds + OUTPUT_DISCLOSURE_MARGIN_SECONDS) >= cancellationAt) {
631
+ lastStateRefusal = "state#19: if (BigInt(expected.nowSeconds + OUTPUT_DISCLOSURE_MARGIN_SECONDS) >= cancellationAt) return null;";
632
+ return null;
633
+ }
634
+ const terms = lock.refs[0].beginParse();
635
+ if (!sameAddress(terms.loadAddressAny(), input.recipientAddress)) {
636
+ lastStateRefusal = "state#20: if (!sameAddress(terms.loadAddressAny(), input.recipientAddress)) return null;";
637
+ return null;
638
+ }
639
+ if (!(terms.loadAddressAny() instanceof Address)) {
640
+ lastStateRefusal = "state#21: if (!(terms.loadAddressAny() instanceof Address)) return null; // resolver \u2014 any";
641
+ return null;
642
+ }
643
+ if (terms.loadCoins() !== BigInt(input.dstSecurityDepositUnits) || !exactCellEnd(terms)) {
644
+ lastStateRefusal = "state#22: if (terms.loadCoins() !== BigInt(input.dstSecurityDepositUnits) || !exactCellEnd(terms)) return null";
645
+ return null;
646
+ }
647
+ const authority = lock.refs[1].beginParse();
648
+ if (!authority.loadBit() || !expected.trusted.authorityKeys.has(Buffer.from(authority.loadBuffer(32)).toString("hex"))) {
649
+ lastStateRefusal = "state#23: if (!authority.loadBit() || !expected.trusted.authorityKeys.has(Buffer.from(authority.loadBuffer(32)";
650
+ return null;
651
+ }
652
+ const authorityAddress = authority.loadAddressAny();
653
+ if (authorityAddress !== null && !sameAddress(authorityAddress, input.recipientAddress) || !exactCellEnd(authority)) {
654
+ lastStateRefusal = "state#24: if ((authorityAddress !== null && !sameAddress(authorityAddress, input.recipientAddress)) || !exactC";
655
+ return null;
656
+ }
657
+ if (!expected.trusted.outputEscrow.has(data.refs[2].hash().toString("hex"))) {
658
+ lastStateRefusal = 'state#25: if (!expected.trusted.outputEscrow.has(data.refs[2]!.hash().toString("hex"))) return null;';
659
+ return null;
660
+ }
661
+ return { withdrawalAt };
662
+ }
663
+ function oneRoot(hex, label) {
664
+ if (!/^(?:[0-9a-fA-F]{2})+$/.test(hex)) throw new Error(`omniston TON validator: malformed ${label} hex`);
665
+ const roots = Cell.fromBoc(Buffer.from(hex, "hex"));
666
+ if (roots.length !== 1) throw new Error(`omniston TON validator: ${label} must have one root`);
667
+ return roots[0];
668
+ }
669
+ function sameAddress(actual, expected) {
670
+ try {
671
+ return actual instanceof Address && actual.equals(Address.parse(expected));
672
+ } catch {
673
+ return false;
674
+ }
675
+ }
676
+ function sameHex(actual, expected) {
677
+ const clean = expected.replace(/^0x/, "").toLowerCase();
678
+ return clean.length === actual.length * 2 && Buffer.from(actual).toString("hex") === clean;
679
+ }
680
+ function exactCellEnd(slice) {
681
+ return slice.remainingBits === 0 && slice.remainingRefs === 0;
682
+ }
683
+ function destinationChainId(chain) {
684
+ const ids = {
685
+ ethereum: 1n,
686
+ bnb: 56n,
687
+ polygon: 137n,
688
+ robinhood: 4663n,
689
+ base: 8453n,
690
+ arbitrum: 42161n,
691
+ avalanche: 43114n,
692
+ xlayer: 196n,
693
+ hyperevm: 999n,
694
+ plasma: 9745n
695
+ };
696
+ return ids[chain] ?? null;
697
+ }
698
+ function validatePayload(input, trusted) {
699
+ const exclusivityTimeout = input.exclusivityTimeout;
700
+ if (typeof exclusivityTimeout !== "number" || !Number.isSafeInteger(exclusivityTimeout) || exclusivityTimeout < 1 || exclusivityTimeout > MAX_OMNISTON_EXCLUSIVITY_SECONDS) return false;
701
+ if (!/^\d+$/.test(input.inputUnits) || !/^\d+$/.test(input.resolverSendsUnits) || !/^\d+$/.test(input.srcHtlcSecurityDepositUnits) || !/^[0-9a-fA-F]{48,64}$/.test(input.quoteId) || input.secretHashes.length !== 1 || input.secretHashes[0]?.length !== 32 || input.hashingFunction !== "HASHING_FUNCTION_KECCAK256") return false;
702
+ const payload = oneRoot(input.payloadBocHex, "payload");
703
+ const outer = payload.beginParse();
704
+ if (outer.loadUint(32) !== JETTON_TRANSFER_OP) return false;
705
+ outer.loadUintBig(64);
706
+ if (outer.loadCoins() !== BigInt(input.inputUnits)) return false;
707
+ if (!sameAddress(outer.loadAddressAny(), input.protocolAddress)) return false;
708
+ if (!sameAddress(outer.loadAddressAny(), input.ownerAddress)) return false;
709
+ if (outer.loadMaybeRef() !== null) return false;
710
+ const forwardNano = outer.loadCoins();
711
+ if (forwardNano <= 0n || forwardNano > MAX_FORWARD_NANO || !outer.loadBit()) return false;
712
+ if (outer.remainingBits !== 0 || outer.remainingRefs !== 1) return false;
713
+ const embeddedForward = outer.loadRef();
714
+ const forward = oneRoot(input.forwardPayloadBocHex, "forward payload");
715
+ if (!embeddedForward.hash().equals(forward.hash())) return false;
716
+ const root = forward.beginParse();
717
+ if (root.loadUint(32) !== ESCROW_CREATE_OP || !sameHex(root.loadBuffer(32), input.quoteId.padStart(64, "0"))) return false;
718
+ if (root.loadBit() || !sameAddress(root.loadAddressAny(), input.ownerAddress)) return false;
719
+ const escrowForwardNano = root.loadCoins();
720
+ if (escrowForwardNano <= 0n || escrowForwardNano > MAX_FORWARD_NANO || root.loadBit()) return false;
721
+ if (root.remainingBits !== 0 || root.remainingRefs !== 4) return false;
722
+ const [config, escrowCode, auxiliary, flags] = [root.loadRef(), root.loadRef(), root.loadRef(), root.loadRef()];
723
+ if (!trusted.escrow.has(escrowCode.hash().toString("hex"))) return false;
724
+ const configSlice = config.beginParse();
725
+ if (configSlice.loadUint(32) !== ESCROW_CONFIG_OP || !sameAddress(configSlice.loadAddressAny(), input.initialResolverAddress)) return false;
726
+ if (!configSlice.loadBit() || !trusted.authorityKeys.has(Buffer.from(configSlice.loadBuffer(32)).toString("hex"))) return false;
727
+ if (configSlice.loadUintBig(64) !== BigInt(exclusivityTimeout)) return false;
728
+ if (configSlice.loadUintBig(64) !== 0n) return false;
729
+ if (configSlice.remainingRefs !== 2) return false;
730
+ const state = configSlice.loadRef();
731
+ if (!configSlice.loadBit()) return false;
732
+ const destination = configSlice.loadRef();
733
+ if (configSlice.loadUint(16) !== 0 || !exactCellEnd(configSlice)) return false;
734
+ if (state.bits.length !== 0 || state.refs.length !== 2) return false;
735
+ if (!trusted.execution.has(state.refs[0].hash().toString("hex"))) return false;
736
+ const execution = state.refs[1].beginParse();
737
+ if (execution.loadUint(32) !== ESCROW_EXECUTION_KECCAK_OP || !Buffer.from(execution.loadBuffer(32)).equals(Buffer.from(input.secretHashes[0])) || !sameAddress(execution.loadAddressAny(), input.initialResolverAddress)) return false;
738
+ if ([1n, 120n, 240n, 300n].some((expected) => execution.loadUintBig(64) !== expected)) return false;
739
+ if (execution.remainingBits !== 0 || execution.remainingRefs !== 1) return false;
740
+ const ownerData = execution.loadRef().beginParse();
741
+ if (!sameAddress(ownerData.loadAddressAny(), input.ownerAddress) || ownerData.loadBit()) return false;
742
+ if (ownerData.loadCoins() !== BigInt(input.srcHtlcSecurityDepositUnits) || !exactCellEnd(ownerData)) return false;
743
+ const destinationSlice = destination.beginParse();
744
+ const chainId = destinationChainId(input.destinationChain);
745
+ if (chainId === null || destinationSlice.loadUintBig(64) !== chainId) return false;
746
+ if (!sameHex(destinationSlice.loadBuffer(20), input.outputTokenAddress)) return false;
747
+ if (!sameHex(destinationSlice.loadBuffer(20), input.destinationAddress)) return false;
748
+ if (destinationSlice.loadCoins() !== BigInt(input.resolverSendsUnits) || !exactCellEnd(destinationSlice)) return false;
749
+ if (auxiliary.bits.length !== 537 || auxiliary.refs.length !== 1) return false;
750
+ if (flags.bits.length !== 98 || flags.refs.length !== 0) return false;
751
+ return true;
752
+ }
753
+ function createOmnistonTonValidators(options = {}) {
754
+ const now = options.now ?? Date.now;
755
+ const swapInterfaces = new Set(options.swapTargetInterfaces ?? DEFAULT_OMNISTON_TON_SWAP_INTERFACES);
756
+ const proxyTonMasters = new Set(
757
+ (options.proxyTonMasters ?? DEFAULT_OMNISTON_TON_PROXY_TON_MASTERS).map((value) => Address.parse(value).toRawString())
758
+ );
759
+ const request = options.fetch ?? fetch;
760
+ const base = (options.tonApiUrl ?? "https://tonapi.io").replace(/\/$/, "");
761
+ const headers = options.tonApiKey ? { Authorization: `Bearer ${options.tonApiKey}` } : void 0;
762
+ const get = (path) => request(`${base}${path}`, { ...headers ? { headers } : {}, signal: AbortSignal.timeout(5e3) });
763
+ const getRetry = async (path) => {
764
+ for (let attempt = 0; ; attempt++) {
765
+ const response = await get(path);
766
+ if (response.status !== 429 || attempt >= 3) return response;
767
+ await new Promise((resolve) => setTimeout(resolve, 1100 * (attempt + 1)));
768
+ }
769
+ };
770
+ const runGet = async (address, method, args = []) => {
771
+ const query = args.length ? `?${args.map((arg) => `args=${encodeURIComponent(arg)}`).join("&")}` : "";
772
+ const response = await getRetry(`/v2/blockchain/accounts/${encodeURIComponent(address)}/methods/${method}${query}`);
773
+ if (!response.ok) return null;
774
+ const body = await response.json();
775
+ return body.success === true && (body.exit_code ?? 0) === 0 && Array.isArray(body.stack) ? body.stack : null;
776
+ };
777
+ const stackCell = (entry) => entry && (entry.type === "cell" || entry.type === "slice") && entry.cell ? cellFromApi(entry.cell) : null;
778
+ const derivedWallet = async (master, owner) => {
779
+ const cell = stackCell((await runGet(master, "get_wallet_address", [Address.parse(owner).toRawString()]))?.[0]);
780
+ return cell ? cell.beginParse().loadAddress() : null;
781
+ };
782
+ const walletData = async (wallet) => {
783
+ const stack = await runGet(wallet, "get_wallet_data");
784
+ const owner = stackCell(stack?.[1]);
785
+ const master = stackCell(stack?.[2]);
786
+ return owner && master ? { owner: owner.beginParse().loadAddress(), master: master.beginParse().loadAddress() } : null;
787
+ };
788
+ const accountHas = async (address, iface) => {
789
+ const response = await getRetry(`/v2/accounts/${encodeURIComponent(address)}`);
790
+ if (!response.ok) return false;
791
+ const body = await response.json();
792
+ return !!body.address && sameAddress(Address.parse(body.address), address) && body.is_wallet !== true && (body.interfaces ?? []).includes(iface);
793
+ };
794
+ const samePair = (pool, leg) => {
795
+ const key = (value) => value === null ? "native" : Address.parse(value).toRawString();
796
+ const a = pool.map(key).sort();
797
+ const b = leg.map(key).sort();
798
+ return a.length === 2 && a[0] === b[0] && a[1] === b[1] && a[0] !== a[1];
799
+ };
800
+ const readAccount = async (address) => {
801
+ const response = await get(`/v2/accounts/${encodeURIComponent(address)}`);
802
+ if (!response.ok) return null;
803
+ const body = await response.json();
804
+ if (!body.address || !sameAddress(Address.parse(body.address), address)) return null;
805
+ return { interfaces: body.interfaces ?? [], isWallet: body.is_wallet === true };
806
+ };
807
+ const isDexContract = (account) => !account.isWallet && account.interfaces.some((name) => swapInterfaces.has(name));
808
+ const trusted = {
809
+ escrow: new Set((options.escrowCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.escrow).map((value) => value.toLowerCase())),
810
+ execution: new Set((options.executionCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.execution).map((value) => value.toLowerCase())),
811
+ authorityKeys: new Set((options.authorityKeys ?? DEFAULT_OMNISTON_TON_CODE_HASHES.authorityKeys).map((value) => value.toLowerCase())),
812
+ position: new Set((options.positionCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.position).map((value) => value.toLowerCase())),
813
+ outputEscrow: new Set((options.outputEscrowCodeHashes ?? DEFAULT_OMNISTON_TON_CODE_HASHES.outputEscrow).map((value) => value.toLowerCase()))
814
+ };
815
+ const jettonWalletOf = async (ownerAddress, jettonMasterAddress) => {
816
+ const response = await get(`/v2/accounts/${encodeURIComponent(ownerAddress)}/jettons/${encodeURIComponent(jettonMasterAddress)}`);
817
+ if (!response.ok) return null;
818
+ const body = await response.json();
819
+ const wallet = body.wallet_address?.address;
820
+ if (!wallet || body.jetton?.address !== void 0 && !sameAddress(Address.parse(body.jetton.address), jettonMasterAddress)) return null;
821
+ return Address.parse(wallet).toString();
822
+ };
823
+ return {
824
+ async validateTonJettonWallet({ ownerAddress, jettonMasterAddress, walletAddress }) {
825
+ try {
826
+ const url = `${base}/v2/accounts/${encodeURIComponent(ownerAddress)}/jettons/${encodeURIComponent(jettonMasterAddress)}`;
827
+ const response = await request(url, {
828
+ ...headers ? { headers } : {},
829
+ signal: AbortSignal.timeout(5e3)
830
+ });
831
+ if (!response.ok) return false;
832
+ const body = await response.json();
833
+ if (!sameAddress(body.wallet_address?.address ? Address.parse(body.wallet_address.address) : null, walletAddress)) return false;
834
+ return body.jetton?.address === void 0 || sameAddress(Address.parse(body.jetton.address), jettonMasterAddress);
835
+ } catch {
836
+ return false;
837
+ }
838
+ },
839
+ validateTonEscrowPayload(input) {
840
+ try {
841
+ return validatePayload(input, trusted);
842
+ } catch {
843
+ return false;
844
+ }
845
+ },
846
+ /**
847
+ * EVM→TON: the position the tracking feed named must be (1) an active
848
+ * contract with the pinned position code, (2) carrying state that binds
849
+ * this quote, hashlock, recipient, output jetton, amount, deposit and the
850
+ * pinned timelocks — still inside the completion window — with jetton
851
+ * custody at the factory's own wallet, and (3) deployed by the trusted
852
+ * factory itself (its deploy message is only sent after the factory's
853
+ * jetton wallet notified it of the resolver's transfer). Nothing here
854
+ * trusts the feed beyond the address it suggested.
855
+ */
856
+ async validateTonOutputPosition(input) {
857
+ const refuse = (reason, details) => {
858
+ try {
859
+ options.onRefusal?.(reason, details);
860
+ } catch {
861
+ }
862
+ return false;
863
+ };
864
+ lastStateRefusal = null;
865
+ try {
866
+ Address.parse(input.positionAddress);
867
+ Address.parse(input.recipientAddress);
868
+ const nowSeconds = Math.floor(now() / 1e3);
869
+ if (!Number.isInteger(input.quoteTimestamp) || input.quoteTimestamp > nowSeconds + 120 || nowSeconds - input.quoteTimestamp > 6 * 60 * 60) return refuse("quote-age");
870
+ const accountResponse = await get(`/v2/blockchain/accounts/${encodeURIComponent(input.positionAddress)}`);
871
+ if (!accountResponse.ok) return refuse("account-fetch", { status: accountResponse.status });
872
+ const account = await accountResponse.json();
873
+ if (!account.address || !sameAddress(Address.parse(account.address), input.positionAddress) || account.status !== "active" || !account.code || !account.data) return refuse("account-state", { status: account.status, hasCode: !!account.code, hasData: !!account.data });
874
+ if (!trusted.position.has(cellFromApi(account.code).hash().toString("hex"))) return refuse("position-code-hash", { hash: cellFromApi(account.code).hash().toString("hex") });
875
+ const jettonWallet = await jettonWalletOf(input.protocolAddress, input.outputJettonMasterAddress);
876
+ if (!jettonWallet) return refuse("jetton-wallet");
877
+ const state = validateOutputPositionState(cellFromApi(account.data), input, { jettonWallet, trusted, nowSeconds });
878
+ if (!state) return refuse("state", { check: lastStateRefusal });
879
+ const txResponse = await get(`/v2/blockchain/accounts/${encodeURIComponent(input.positionAddress)}/transactions?limit=25`);
880
+ if (!txResponse.ok) return refuse("transactions-fetch", { status: txResponse.status });
881
+ const body = await txResponse.json();
882
+ const deployedByFactory = (body.transactions ?? []).some((tx) => tx.success === true && tx.aborted !== true && tx.in_msg?.op_code?.toLowerCase() === POSITION_DEPLOY_OP && !!tx.in_msg.source?.address && sameAddress(Address.parse(tx.in_msg.source.address), input.protocolAddress) && typeof tx.utime === "number" && Math.abs(Number(state.withdrawalAt) - 1 - tx.utime) <= 5);
883
+ return deployedByFactory || refuse("deploy-transaction", { transactions: (body.transactions ?? []).length });
884
+ } catch (error) {
885
+ return refuse("error", { message: error instanceof Error ? error.message : String(error) });
886
+ }
887
+ },
888
+ /**
889
+ * Scan F11: one chain fact a decoded TON swap body depends on.
890
+ * - STON.fi hop: the router carries the STON.fi router interface of its
891
+ * version; for native input the pTON wallet the message pays is a
892
+ * proxy-TON wallet OWNED BY that router; the hop's ask wallet is the
893
+ * router's own wallet of the hop's output (of a proxy-TON master for
894
+ * native output), as the output's master derives it.
895
+ * - DeDust pool: the pool carries the DeDust pool interface of its version
896
+ * and trades exactly the hop's pair.
897
+ */
898
+ async validateTonSwapLeg(leg) {
899
+ try {
900
+ if (leg.kind === "stonfi-router") {
901
+ let router = leg.router ? Address.parse(leg.router) : null;
902
+ if (leg.proxyTonWallet) {
903
+ const data = await walletData(leg.proxyTonWallet);
904
+ if (!data || !proxyTonMasters.has(data.master.toRawString())) return false;
905
+ if (router && !router.equals(data.owner)) return false;
906
+ router = data.owner;
907
+ }
908
+ if (!router) return false;
909
+ if (!await accountHas(router.toString(), leg.version === 1 ? "stonfi_router" : "stonfi_router_v2")) return false;
910
+ const masters = leg.outputJetton ? [leg.outputJetton] : [...proxyTonMasters];
911
+ for (const master of masters) {
912
+ const wallet = await derivedWallet(master, router.toString());
913
+ if (wallet && wallet.equals(Address.parse(leg.askWallet))) return true;
914
+ }
915
+ return false;
916
+ }
917
+ if (leg.version === 1) {
918
+ if (!await accountHas(leg.pool, "dedust_pool")) return false;
919
+ const stack2 = await runGet(leg.pool, "get_assets");
920
+ const assets2 = [stackCell(stack2?.[0]), stackCell(stack2?.[1])].map((cell) => {
921
+ if (!cell) return void 0;
922
+ const slice = cell.beginParse();
923
+ const tag = slice.loadUint(4);
924
+ if (tag === 0) return null;
925
+ if (tag !== 1) return void 0;
926
+ return new Address(slice.loadInt(8), slice.loadBuffer(32)).toString();
927
+ });
928
+ if (assets2.some((asset) => asset === void 0)) return false;
929
+ return samePair(assets2, [leg.inputJetton, leg.outputJetton]);
930
+ }
931
+ if (!await accountHas(leg.pool, "dedust_v2_cpmm")) return false;
932
+ const stack = await runGet(leg.pool, "get_pool_data");
933
+ const assets = [stackCell(stack?.[3]), stackCell(stack?.[4])].map((cell) => {
934
+ if (!cell) return void 0;
935
+ const address = cell.beginParse().loadAddressAny();
936
+ if (address === null) return null;
937
+ return address instanceof Address ? address.toString() : void 0;
938
+ });
939
+ if (assets.some((asset) => asset === void 0)) return false;
940
+ return samePair(assets, [leg.inputJetton, leg.outputJetton]);
941
+ } catch {
942
+ return false;
943
+ }
944
+ },
945
+ /** The contract a swap pays into must carry a recognised DEX code
946
+ * interface on the indexer — an EOA, an unknown contract or a fresh
947
+ * resolver-deployed proxy is refused. */
948
+ async validateTonSwapTarget({ address }) {
949
+ try {
950
+ Address.parse(address);
951
+ const account = await readAccount(address);
952
+ if (!account || account.isWallet) return false;
953
+ if (isDexContract(account)) return true;
954
+ if (!account.interfaces.includes("jetton_wallet")) return false;
955
+ const data = await get(`/v2/blockchain/accounts/${encodeURIComponent(address)}/methods/get_wallet_data`);
956
+ if (!data.ok) return false;
957
+ const body = await data.json();
958
+ const owner = body.decoded?.owner;
959
+ const master = body.decoded?.jetton;
960
+ if (!body.success || !owner || !master || !proxyTonMasters.has(Address.parse(master).toRawString())) return false;
961
+ const ownerAccount = await readAccount(owner);
962
+ return ownerAccount !== null && isDexContract(ownerAccount);
963
+ } catch {
964
+ return false;
965
+ }
966
+ }
967
+ };
968
+ }
969
+ function createOmnistonTonDeliveryLocator(options = {}) {
970
+ const request = options.fetch ?? fetch;
971
+ const base = (options.tonApiUrl ?? "https://tonapi.io").replace(/\/$/, "");
972
+ const headers = options.tonApiKey ? { Authorization: `Bearer ${options.tonApiKey}` } : void 0;
973
+ const limit = Math.min(100, Math.max(1, Math.floor(options.limit ?? 20)));
974
+ return async (input) => {
975
+ try {
976
+ const recipient = Address.parse(input.recipientAddress);
977
+ const master = Address.parse(input.jettonMasterAddress);
978
+ const position = input.positionAddress ? Address.parse(input.positionAddress) : null;
979
+ const min = BigInt(input.minUnits);
980
+ if (min <= 0n) return null;
981
+ const since = Number.isFinite(input.afterTimestamp) ? `&start_date=${Math.max(0, Math.floor(input.afterTimestamp))}` : "";
982
+ const until = Number.isFinite(input.beforeTimestamp) ? `&end_date=${Math.max(0, Math.floor(input.beforeTimestamp))}` : "";
983
+ const url = `${base}/v2/accounts/${encodeURIComponent(recipient.toString())}/events?limit=${limit}${since}${until}`;
984
+ const response = await request(url, { ...headers ? { headers } : {}, signal: AbortSignal.timeout(8e3) });
985
+ if (!response.ok) return null;
986
+ const body = await response.json();
987
+ const events = [...body.events ?? []];
988
+ if (input.afterTimestamp !== void 0) events.sort((a, b) => (a.timestamp ?? 0) - (b.timestamp ?? 0));
989
+ for (const event of events) {
990
+ if (!event.event_id || event.in_progress === true) continue;
991
+ if (input.afterTimestamp !== void 0 && typeof event.timestamp === "number" && event.timestamp < input.afterTimestamp) continue;
992
+ if (input.beforeTimestamp !== void 0 && typeof event.timestamp === "number" && event.timestamp > input.beforeTimestamp) continue;
993
+ for (const action of event.actions ?? []) {
994
+ if (action.type !== "JettonTransfer" || action.status !== "ok") continue;
995
+ const t = action.JettonTransfer;
996
+ if (!t?.jetton?.address || !t.recipient?.address || t.amount === void 0) continue;
997
+ if (!sameAddress(Address.parse(t.jetton.address), master.toString())) continue;
998
+ if (!sameAddress(Address.parse(t.recipient.address), recipient.toString())) continue;
999
+ if (position && (!t.sender?.address || !sameAddress(Address.parse(t.sender.address), position.toString()))) continue;
1000
+ let amount;
1001
+ try {
1002
+ amount = BigInt(t.amount);
1003
+ } catch {
1004
+ continue;
1005
+ }
1006
+ if (amount < min) continue;
1007
+ return event.event_id.toLowerCase();
1008
+ }
1009
+ }
1010
+ return null;
1011
+ } catch {
1012
+ return null;
1013
+ }
1014
+ };
1015
+ }
1016
+
1017
+ // src/validators/settlement.ts
1018
+ var AUDITED_OMNISTON_SETTLEMENT_CONTRACTS = {
1019
+ "ton:-239": ["EQAbWJ3Y1HgIIvcMq1prG1anlDC0T3cZlAU7luPT6LmTpmrZ"],
1020
+ "eip155:1": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1021
+ "eip155:56": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1022
+ "eip155:137": ["0x41A392062A4307a6961d48e30FF20bF6823715B8"],
1023
+ "eip155:4663": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1024
+ "eip155:8453": ["0xACa3E2F9b61a44892926bC6c3e104192E7D1c3cd"],
1025
+ "eip155:42161": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1026
+ "eip155:43114": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1027
+ // 2026-10-20: one factory address on X Layer, HyperEVM and Plasma. Runtime
1028
+ // bytecode equals Ethereum's 0xafCF… byte for byte except the immutable slots
1029
+ // (escrow implementations, its order protocol, domain hash); it references
1030
+ // the order protocol trusted below on the same chain.
1031
+ "eip155:196": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
1032
+ "eip155:999": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"],
1033
+ "eip155:9745": ["0xd602079AFa5c38F550510a2a988CbFa698Fa0189"]
1034
+ };
1035
+ var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
1036
+ "eip155:1": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1037
+ "eip155:56": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1038
+ "eip155:137": ["0xafCF681272AF10959736f45616eeCBC22D7095E2"],
1039
+ "eip155:8453": ["0xe7405fAcDEDB2512e91F2886BDff13231343aF5E"],
1040
+ "eip155:42161": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1041
+ "eip155:43114": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1042
+ // 2026-10-20: bytecode equals Ethereum's 0xb581… except immutables (wrapped
1043
+ // native, own address, chain id 196 / 9745 / 999 at the chain-id slot).
1044
+ "eip155:196": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1045
+ "eip155:9745": ["0xb5810aCfD45D85Eaa938bF90a5857295513DA7E9"],
1046
+ "eip155:999": ["0xD84778bbeEC5D2a8d17c6424249C438EC0b1ABE3"]
1047
+ };
1048
+ export {
1049
+ AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS,
1050
+ AUDITED_OMNISTON_SETTLEMENT_CONTRACTS,
1051
+ DEFAULT_OMNISTON_TON_CODE_HASHES,
1052
+ DEFAULT_OMNISTON_TON_PROXY_TON_MASTERS,
1053
+ DEFAULT_OMNISTON_TON_SWAP_INTERFACES,
1054
+ MAX_OMNISTON_EXCLUSIVITY_SECONDS,
1055
+ OMNISTON_EVM_LOOKBACK_BLOCKS,
1056
+ OMNISTON_EVM_MIN_CONFIRMATIONS,
1057
+ SRC_ESCROW_CREATED_TOPIC,
1058
+ createOmnistonEvmDeliveryLocator,
1059
+ createOmnistonEvmInputValidator,
1060
+ createOmnistonEvmOutputValidator,
1061
+ createOmnistonTonDeliveryLocator,
1062
+ createOmnistonTonValidators,
1063
+ omnistonEvmRpcRequest
1064
+ };
1065
+ //# sourceMappingURL=validators.js.map