@anywalletkit/protocol-swap2-omniston 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -4
- package/dist/{chunk-HOTFZYSW.js → chunk-2DGCZD5K.js} +214 -62
- package/dist/chunk-2DGCZD5K.js.map +1 -0
- package/dist/{chunk-RW4XZWNC.js → chunk-4MKR2SUZ.js} +2 -2
- package/dist/chunk-JWYDIW4V.js +37 -0
- package/dist/chunk-JWYDIW4V.js.map +1 -0
- package/dist/index.cjs +241 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -2
- package/dist/protocol.cjs +108 -52
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +1 -1
- package/dist/protocol.d.ts +1 -1
- package/dist/protocol.js +3 -2
- package/dist/{provider-BBG2zhpu.d.cts → provider-CcCZB-Cj.d.cts} +15 -5
- package/dist/{provider-BBG2zhpu.d.ts → provider-CcCZB-Cj.d.ts} +15 -5
- package/dist/provider.cjs +241 -61
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/provider.js +2 -1
- package/dist/validators.d.cts +1 -1
- package/dist/validators.d.ts +1 -1
- package/dist/validators.js +5 -34
- package/dist/validators.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunk-HOTFZYSW.js.map +0 -1
- /package/dist/{chunk-RW4XZWNC.js.map → chunk-4MKR2SUZ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -25,20 +25,23 @@ TRON needs its own order path and is not wired yet.
|
|
|
25
25
|
Every route is fail-closed until its allowlists and validators are configured:
|
|
26
26
|
|
|
27
27
|
- **TON → TON** (DEX swap): `trustedSettlementContracts["ton:-239"]`,
|
|
28
|
-
`validateTonJettonWallet`, `validateTonSwapTarget`. The built message's DEX
|
|
28
|
+
`validateTonJettonWallet`, `validateTonSwapTarget`, `validateTonSwapLeg`. The built message's DEX
|
|
29
29
|
call is decoded in the package (STON.fi v1/v2 incl. pTON and cross-swap,
|
|
30
30
|
DeDust v1, DeDust CPMM v2): receiver = destination, refunds/excess = trader,
|
|
31
31
|
on-chain minimum ≥ the quote's, no foreign referral; unknown layouts and
|
|
32
32
|
split/multi-route quotes are refused by name. `validateTonSwapLeg`
|
|
33
33
|
(supplied by `createOmnistonTonValidators`) confirms the routers' ask
|
|
34
34
|
wallets, pTON wallet ownership and DeDust pool pairs on chain.
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
Without it the decoder cannot tell which token the DEX pays out, so the
|
|
36
|
+
route is not advertised. `tonSwapPayloadCheck: "report"` traces
|
|
37
|
+
`ton-swap-payload <reason>` (incl. `legs-unverified`) instead of refusing
|
|
38
|
+
(default `"enforce"`) — an explicit rollout opt-in.
|
|
37
39
|
Behind `remoteProvider`, the app checks the built body itself:
|
|
38
40
|
`remoteProvider({name: "omniston", baseUrl, verifyBuild: omnistonVerifyBuild({...createOmnistonTonValidators()})})`.
|
|
39
41
|
A TON → TON swap body is opened with `checkTonSwapPayload` against the app's own request (receiver,
|
|
40
42
|
refund, on-chain minimum, input; the quote carries `routeSteps`) and the DEX it pays is confirmed with
|
|
41
|
-
the app's validators
|
|
43
|
+
the app's validators — `validateTonSwapTarget` and `validateTonSwapLeg`; without the leg check a TON swap body
|
|
44
|
+
is refused. A TON → EVM escrow body goes to `verifyTonEscrowBuild`: the jetton amount, the
|
|
42
45
|
trader as owner, the destination chain, address and token and the quote's minimum delivery come from
|
|
43
46
|
the app, the protocol contract from `trustedProtocolAddresses`, and the escrow code, authority key and
|
|
44
47
|
timelocks are the audited ones. Without `verifyBuild` the engine refuses remote cell bodies.
|
|
@@ -62,6 +65,19 @@ Every route is fail-closed until its allowlists and validators are configured:
|
|
|
62
65
|
engine then signs only an `Order` whose verifying contract is a pinned
|
|
63
66
|
spender, whose maker is this account and that sells exactly the swap's input
|
|
64
67
|
of the source token; a `Permit` or any other typed message is refused.
|
|
68
|
+
The rest of the order is the app's to check, and the engine signs a remote
|
|
69
|
+
typed order only with `verifyBuild`: `remoteProvider({name: "omniston",
|
|
70
|
+
baseUrl, ...omnistonPins(AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS), verifyBuild:
|
|
71
|
+
omnistonVerifyBuild({...createOmnistonTonValidators()})})`. The build carries
|
|
72
|
+
the `orderExtension` the order's salt commits to, and `omnistonVerifyBuild`
|
|
73
|
+
opens both: the v4 domain on a trusted order protocol, the exact Order schema,
|
|
74
|
+
`takingAmount` at least the quote's minimum, a single-fill order with no
|
|
75
|
+
allowed sender and an expiry minutes away, the pinned v1beta8 auction and fee
|
|
76
|
+
terms, one trusted escrow factory (`trustedSettlementContracts`, default the
|
|
77
|
+
audited table) as the extension target, the whitelisted resolver as the
|
|
78
|
+
order's receiver, the destination chain and token, the audited timelocks, the
|
|
79
|
+
TON token and recipient and the quote id. The hashlock is the server's: the
|
|
80
|
+
server holds the HTLC secret. The same applies to EVM → EVM.
|
|
65
81
|
`validateEvmTypedOrder` is exported for apps that hold the settlement data.
|
|
66
82
|
- **EVM → EVM** (gasless order, same order protocol as EVM → TON): the signed
|
|
67
83
|
extension's ExtraDataArgs name the destination chain, token and deposit and
|
|
@@ -4,6 +4,10 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
describeOmnistonActivity
|
|
6
6
|
} from "./chunk-AIWAM7BS.js";
|
|
7
|
+
import {
|
|
8
|
+
AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS,
|
|
9
|
+
AUDITED_OMNISTON_SETTLEMENT_CONTRACTS
|
|
10
|
+
} from "./chunk-JWYDIW4V.js";
|
|
7
11
|
|
|
8
12
|
// src/provider.ts
|
|
9
13
|
import { Address as TonAddress, Cell as TonCell } from "@ton/core";
|
|
@@ -390,18 +394,36 @@ function toChainAddress(caip2, address) {
|
|
|
390
394
|
if (!$case) return null;
|
|
391
395
|
return { chain: { $case, value: getAddress(address) } };
|
|
392
396
|
}
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
var QUOTE_DIGEST_SKIP = /* @__PURE__ */ new Set(["rfqId", "resolverName", "estimatedSettlementDuration", "estimatedGasConsumption"]);
|
|
398
|
+
function canonicalJson(value) {
|
|
399
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
|
|
400
|
+
if (value && typeof value === "object") {
|
|
401
|
+
return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${canonicalJson(value[k])}`).join(",")}}`;
|
|
402
|
+
}
|
|
403
|
+
return JSON.stringify(value) ?? "null";
|
|
404
|
+
}
|
|
405
|
+
function quoteDigest(q) {
|
|
406
|
+
const terms = JSON.parse(JSON.stringify(q));
|
|
407
|
+
for (const key of QUOTE_DIGEST_SKIP) delete terms[key];
|
|
408
|
+
return sha256(new TextEncoder().encode(canonicalJson(terms))).slice(2, 34);
|
|
409
|
+
}
|
|
410
|
+
var QUOTE_DIGEST = /^[0-9a-f]{32}$/;
|
|
411
|
+
function encodeIntent(quoteId, trader, dest, srcChain, kind, digest) {
|
|
412
|
+
return [INTENT_PREFIX, quoteId, trader, `${dest}#${digest}`, srcChain, ...kind === "swap" ? ["swap"] : []].map(encodeURIComponent).join("|");
|
|
395
413
|
}
|
|
396
414
|
var QUOTE_ID = /^[0-9a-fA-F]{48,64}$/;
|
|
397
415
|
function decodeIntent(intentId) {
|
|
398
416
|
try {
|
|
399
417
|
const parts = intentId.split("|");
|
|
400
418
|
if (parts.length !== 5 && parts.length !== 6 || parts[0] !== INTENT_PREFIX) return null;
|
|
401
|
-
const [, quoteId = "", trader = "",
|
|
419
|
+
const [, quoteId = "", trader = "", destPart = "", srcChain = "", kindPart = ""] = parts.map(decodeURIComponent);
|
|
420
|
+
const mark = destPart.lastIndexOf("#");
|
|
421
|
+
const dest = mark < 0 ? destPart : destPart.slice(0, mark);
|
|
422
|
+
const digest = mark < 0 ? void 0 : destPart.slice(mark + 1);
|
|
423
|
+
if (digest !== void 0 && !QUOTE_DIGEST.test(digest)) return null;
|
|
402
424
|
if (!QUOTE_ID.test(quoteId) || !trader || !dest || !srcChain) return null;
|
|
403
425
|
if (parts.length === 6 && kindPart !== "swap") return null;
|
|
404
|
-
return { quoteId, trader, dest, srcChain, kind: parts.length === 6 ? "swap" : "order" };
|
|
426
|
+
return { quoteId, trader, dest, srcChain, kind: parts.length === 6 ? "swap" : "order", ...digest ? { digest } : {} };
|
|
405
427
|
} catch {
|
|
406
428
|
return null;
|
|
407
429
|
}
|
|
@@ -522,9 +544,9 @@ function validEvmAddress(value) {
|
|
|
522
544
|
}
|
|
523
545
|
}
|
|
524
546
|
var EVM_DEST_PROTOCOL_FEE_RECIPIENTS = /* @__PURE__ */ new Set(["0x076268146b4ec6d21fc49c27586cfa91b9079a00"]);
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
547
|
+
var EVM_AUCTION_POINTS = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
|
|
548
|
+
var EVM_TIMELOCKS = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
|
|
549
|
+
function readEvmOrderExtension(extension) {
|
|
528
550
|
if (extension.length < 32) throw new Error("omniston: malformed EVM order extension");
|
|
529
551
|
const view = new DataView(extension.buffer, extension.byteOffset, extension.byteLength);
|
|
530
552
|
const fields = [];
|
|
@@ -544,54 +566,48 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
544
566
|
}
|
|
545
567
|
let target;
|
|
546
568
|
for (const index of [2, 3, 7]) {
|
|
547
|
-
const
|
|
548
|
-
if (
|
|
549
|
-
const address = getAddress(`0x${bytesToHex(
|
|
550
|
-
if (
|
|
569
|
+
const field2 = fields[index];
|
|
570
|
+
if (field2.length <= 20) throw new Error("omniston: incomplete EVM order extension program");
|
|
571
|
+
const address = getAddress(`0x${bytesToHex(field2.slice(0, 20))}`);
|
|
572
|
+
if (target !== void 0 && getAddress(target) !== address) {
|
|
551
573
|
throw new Error("omniston: EVM order extension target is not independently trusted");
|
|
552
574
|
}
|
|
553
575
|
target = address;
|
|
554
576
|
}
|
|
555
|
-
const
|
|
577
|
+
const field = fields[2];
|
|
556
578
|
let cursor = 20;
|
|
557
|
-
const gasBump = readBigEndian(
|
|
579
|
+
const gasBump = readBigEndian(field, cursor, 3);
|
|
558
580
|
cursor += 3;
|
|
559
|
-
const gasPrice = readBigEndian(
|
|
581
|
+
const gasPrice = readBigEndian(field, cursor, 4);
|
|
560
582
|
cursor += 4;
|
|
561
|
-
const auctionStart = readBigEndian(
|
|
583
|
+
const auctionStart = readBigEndian(field, cursor, 4);
|
|
562
584
|
cursor += 4;
|
|
563
|
-
const duration = readBigEndian(
|
|
585
|
+
const duration = readBigEndian(field, cursor, 3);
|
|
564
586
|
cursor += 3;
|
|
565
|
-
const initialRateBump = readBigEndian(
|
|
587
|
+
const initialRateBump = readBigEndian(field, cursor, 3);
|
|
566
588
|
cursor += 3;
|
|
567
|
-
const pointCount = bigintToNumber(readBigEndian(
|
|
589
|
+
const pointCount = bigintToNumber(readBigEndian(field, cursor, 1));
|
|
568
590
|
cursor += 1;
|
|
569
591
|
if (pointCount !== 5) throw new Error("omniston: unsupported EVM auction profile");
|
|
570
592
|
const points = [];
|
|
571
593
|
for (let index = 0; index < pointCount; index++) {
|
|
572
|
-
points.push([readBigEndian(
|
|
594
|
+
points.push([readBigEndian(field, cursor, 3), readBigEndian(field, cursor + 3, 2)]);
|
|
573
595
|
cursor += 5;
|
|
574
596
|
}
|
|
575
|
-
const integratorFee = readBigEndian(
|
|
597
|
+
const integratorFee = readBigEndian(field, cursor, 2);
|
|
576
598
|
cursor += 2;
|
|
577
|
-
const integratorShare = readBigEndian(
|
|
599
|
+
const integratorShare = readBigEndian(field, cursor, 1);
|
|
578
600
|
cursor += 1;
|
|
579
|
-
const resolverFee = readBigEndian(
|
|
601
|
+
const resolverFee = readBigEndian(field, cursor, 2);
|
|
580
602
|
cursor += 2;
|
|
581
|
-
const whitelistDiscount = readBigEndian(
|
|
603
|
+
const whitelistDiscount = readBigEndian(field, cursor, 1);
|
|
582
604
|
cursor += 1;
|
|
583
|
-
const getterWhitelistCount = bigintToNumber(readBigEndian(
|
|
605
|
+
const getterWhitelistCount = bigintToNumber(readBigEndian(field, cursor, 1));
|
|
584
606
|
cursor += 1;
|
|
585
|
-
if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !==
|
|
607
|
+
if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== field.length) {
|
|
586
608
|
throw new Error("omniston: malformed EVM amount-getter whitelist");
|
|
587
609
|
}
|
|
588
|
-
const
|
|
589
|
-
const expectedPoints = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
|
|
590
|
-
const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
|
|
591
|
-
const resolverLow80 = BigInt(getAddress(expected.initialResolverAddress)) & (1n << 80n) - 1n;
|
|
592
|
-
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) {
|
|
593
|
-
throw new Error("omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
|
|
594
|
-
}
|
|
610
|
+
const getter = { gasBump, gasPrice, auctionStart, duration, initialRateBump, points, integratorFee, integratorShare, resolverFee, whitelistDiscount, resolver: readBigEndian(field, cursor, 10) };
|
|
595
611
|
const post = fields[7];
|
|
596
612
|
cursor = 20;
|
|
597
613
|
const integratorRecipient = post.slice(cursor, cursor + 20);
|
|
@@ -617,28 +633,51 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
617
633
|
cursor += 10;
|
|
618
634
|
const resolverTimeDelta = readBigEndian(post, cursor, 2);
|
|
619
635
|
cursor += 2;
|
|
620
|
-
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) {
|
|
621
|
-
throw new Error("omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
|
|
622
|
-
}
|
|
623
636
|
const extra = Array.from({ length: 5 }, () => {
|
|
624
637
|
const value = readBigEndian(post, cursor, 32);
|
|
625
638
|
cursor += 32;
|
|
626
639
|
return value;
|
|
627
640
|
});
|
|
641
|
+
const customData = extension.slice(32 + begin);
|
|
642
|
+
if (customData.length !== 131) throw new Error("omniston: malformed EVM order extension custom data");
|
|
643
|
+
return {
|
|
644
|
+
target,
|
|
645
|
+
getter,
|
|
646
|
+
post: { integratorRecipient, protocolRecipient, integratorFee: postIntegratorFee, integratorShare: postIntegratorShare, resolverFee: postResolverFee, discount: postDiscount, allowedTime, resolver: postResolver, resolverTimeDelta },
|
|
647
|
+
extra,
|
|
648
|
+
customData
|
|
649
|
+
};
|
|
650
|
+
}
|
|
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");
|
|
654
|
+
const { target, getter, post, extra, customData } = readEvmOrderExtension(extension);
|
|
655
|
+
if (!expected.trustedTarget(target)) throw new Error("omniston: EVM order extension target is not independently trusted");
|
|
656
|
+
const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
|
|
657
|
+
const resolverLow80 = BigInt(getAddress(expected.initialResolverAddress)) & (1n << 80n) - 1n;
|
|
658
|
+
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) {
|
|
659
|
+
throw new Error("omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
|
|
660
|
+
}
|
|
661
|
+
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) {
|
|
662
|
+
throw new Error("omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
|
|
663
|
+
}
|
|
628
664
|
const hashlock2 = readBigEndian(expected.secretHash, 0, expected.secretHash.length);
|
|
629
665
|
const dstToken = evmDest ? BigInt(getAddress(expected.outputTokenAddress)) : BigInt(getAddress(expected.takerAsset));
|
|
630
666
|
const deposits = BigInt(expected.srcSecurityDepositUnits) << 128n | BigInt(expected.dstSecurityDepositUnits);
|
|
631
|
-
|
|
632
|
-
if (expected.secretHash.length !== 32 || extra[0] !== hashlock2 || extra[1] !== (evmDest ? BigInt(expected.dstChainId) : 0n) || extra[2] !== dstToken || extra[3] !== deposits || extra[4] !== timelocks) {
|
|
667
|
+
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) {
|
|
633
668
|
throw new Error("omniston: signed EVM HTLC terms do not match the validated order details");
|
|
634
669
|
}
|
|
635
|
-
|
|
636
|
-
if (
|
|
637
|
-
|
|
670
|
+
await checkOrderCustomData(customData, { evmDest, outputToken: expected.outputTokenAddress, traderDst: expected.traderDstAddress, quoteId: expected.quoteId });
|
|
671
|
+
if (expected.tradeStartDeadline < expected.quoteTimestamp) {
|
|
672
|
+
throw new Error("omniston: invalid EVM order quote deadline");
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
async function checkOrderCustomData(customData, expected) {
|
|
676
|
+
if (expected.evmDest) {
|
|
638
677
|
if (!zeroBytes(customData.slice(0, 66))) throw new Error("omniston: unexpected TON addresses in an EVM-destination order");
|
|
639
678
|
} else {
|
|
640
679
|
const { Address: Address2 } = await import("@ton/core");
|
|
641
|
-
const expectedTon = [expected.
|
|
680
|
+
const expectedTon = [expected.outputToken, expected.traderDst].map((value) => Address2.parse(value));
|
|
642
681
|
for (let index = 0; index < expectedTon.length; index++) {
|
|
643
682
|
const offset = index * 33;
|
|
644
683
|
const workchain = customData[offset] === 255 ? -1 : customData[offset];
|
|
@@ -654,9 +693,6 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
654
693
|
if (!QUOTE_ID.test(quoteId) || !sliceEqual(customData.slice(99), hexToBytes(quoteId.padStart(64, "0")))) {
|
|
655
694
|
throw new Error("omniston: EVM order extension custom data is not bound to the quote id");
|
|
656
695
|
}
|
|
657
|
-
if (expected.tradeStartDeadline < expected.quoteTimestamp) {
|
|
658
|
-
throw new Error("omniston: invalid EVM order quote deadline");
|
|
659
|
-
}
|
|
660
696
|
}
|
|
661
697
|
function validateEvmTypedOrder(td, expected) {
|
|
662
698
|
const value = td;
|
|
@@ -1108,8 +1144,101 @@ function omnistonPins(trustedEvmOrderProtocols) {
|
|
|
1108
1144
|
const byChain = new Map(Object.entries(trustedEvmOrderProtocols).map(([chain, list]) => [chain, list.map((a) => getAddress(a))]));
|
|
1109
1145
|
return Object.freeze({ callTargets: () => [], spenders: (chain) => byChain.get(chain) ?? [] });
|
|
1110
1146
|
}
|
|
1147
|
+
var MAX_EVM_ORDER_LIFETIME_S = 900;
|
|
1148
|
+
async function checkRemoteEvmOrder(quote, tx, params, trusted) {
|
|
1149
|
+
const chainId = evmRef(params.sourceChain);
|
|
1150
|
+
if (chainId === null || !params.sourceChain.startsWith("eip155:")) return "a typed order needs an EVM source";
|
|
1151
|
+
const intent = decodeIntent(quote.intentId.replace(/~[0-9a-f]{32}$/, ""));
|
|
1152
|
+
if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return "the quote's intent is not an order from this chain";
|
|
1153
|
+
if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return "the build carries no order extension to check";
|
|
1154
|
+
const source = ccAsset(params.sourceChain, params.sourceToken);
|
|
1155
|
+
if (!source?.contract) return "unknown source token";
|
|
1156
|
+
const tonDest = isTon(params.destChain);
|
|
1157
|
+
const destChainId = tonDest ? null : evmRef(params.destChain);
|
|
1158
|
+
if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return "the destination is neither TON nor an EVM chain";
|
|
1159
|
+
const outputToken = ccAssetByToken(params.destChain, params.destToken)?.contract ?? params.destToken;
|
|
1160
|
+
const listed = (table, chain, address) => typeof address === "string" && validEvmAddress(address) && (table[chain] ?? []).some((a) => validEvmAddress(a) && getAddress(a) === getAddress(address));
|
|
1161
|
+
let td;
|
|
1162
|
+
try {
|
|
1163
|
+
td = JSON.parse(tx.typedData ?? "");
|
|
1164
|
+
} catch {
|
|
1165
|
+
return "the typed data is not JSON";
|
|
1166
|
+
}
|
|
1167
|
+
const domain = td.domain ?? {};
|
|
1168
|
+
const contract = domain.verifyingContract;
|
|
1169
|
+
if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return "the domain is not the 1inch Limit Order Protocol v4";
|
|
1170
|
+
if (!listed(trusted.orderProtocols, params.sourceChain, contract) || !tx.approvalAddress || getAddress(tx.approvalAddress) !== getAddress(String(contract))) {
|
|
1171
|
+
return `${String(contract)} is not a trusted order protocol on ${params.sourceChain}`;
|
|
1172
|
+
}
|
|
1173
|
+
if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return "the domain chainId is not the source chain";
|
|
1174
|
+
const order = td.types?.Order;
|
|
1175
|
+
const message = td.message;
|
|
1176
|
+
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]))) {
|
|
1177
|
+
return "the typed data is not exactly a v4 Order";
|
|
1178
|
+
}
|
|
1179
|
+
if (!validEvmAddress(intent.trader) || getAddress(String(message.maker)) !== getAddress(intent.trader)) return "the maker is not the trader";
|
|
1180
|
+
if (getAddress(String(message.makerAsset)) !== getAddress(source.contract)) return "the makerAsset is not the source token";
|
|
1181
|
+
if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return "the makingAmount is not the input";
|
|
1182
|
+
if (getAddress(String(message.takerAsset)) === getAddress(String(message.makerAsset))) return "the takerAsset is the makerAsset";
|
|
1183
|
+
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);
|
|
1184
|
+
if (floor <= 0n || BigInt(message.takingAmount) < floor) return `takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}`;
|
|
1185
|
+
const traits = BigInt(message.makerTraits);
|
|
1186
|
+
const flags = traits & (1n << 56n) - 1n << 200n;
|
|
1187
|
+
const baseFlags = 1n << 251n | 1n << 249n;
|
|
1188
|
+
if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return "the makerTraits flags are not a single-fill order with its extension";
|
|
1189
|
+
if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return "the makerTraits restrict the taker or the series";
|
|
1190
|
+
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1191
|
+
const expiration = traits >> 80n & (1n << 40n) - 1n;
|
|
1192
|
+
if (expiration <= now || expiration > now + BigInt(MAX_EVM_ORDER_LIFETIME_S)) return "the order's expiry is not minutes away";
|
|
1193
|
+
const extension = viemHexToBytes(tx.orderExtension);
|
|
1194
|
+
const mask = (1n << 160n) - 1n;
|
|
1195
|
+
if ((BigInt(message.salt) & mask) !== (BigInt(keccak256(extension)) & mask)) return "the salt does not commit the order extension";
|
|
1196
|
+
let parsed;
|
|
1197
|
+
try {
|
|
1198
|
+
parsed = readEvmOrderExtension(extension);
|
|
1199
|
+
} catch (e) {
|
|
1200
|
+
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1201
|
+
}
|
|
1202
|
+
const { target, getter, post, extra, customData } = parsed;
|
|
1203
|
+
if (!listed(trusted.factories, params.sourceChain, target)) return `the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}`;
|
|
1204
|
+
const receiverLow80 = BigInt(getAddress(String(message.receiver))) & (1n << 80n) - 1n;
|
|
1205
|
+
if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return "the order's receiver is not the resolver its extension whitelists";
|
|
1206
|
+
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, bigintToNumber(now), MAX_EVM_ORDER_LIFETIME_S, 60)) {
|
|
1207
|
+
return "the amount-getter terms do not match the pinned v1beta8 profile";
|
|
1208
|
+
}
|
|
1209
|
+
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, bigintToNumber(getter.auctionStart), 60, 5)) {
|
|
1210
|
+
return "the post-interaction terms do not match the pinned v1beta8 profile";
|
|
1211
|
+
}
|
|
1212
|
+
let dstToken;
|
|
1213
|
+
try {
|
|
1214
|
+
dstToken = tonDest ? BigInt(getAddress(String(message.takerAsset))) : BigInt(getAddress(outputToken));
|
|
1215
|
+
} catch {
|
|
1216
|
+
return "the destination token is not an EVM address";
|
|
1217
|
+
}
|
|
1218
|
+
if (extra[1] !== (tonDest ? 0n : BigInt(destChainId)) || extra[2] !== dstToken || extra[4] !== EVM_TIMELOCKS) {
|
|
1219
|
+
return "the signed HTLC terms name another destination chain or token, or other timelocks";
|
|
1220
|
+
}
|
|
1221
|
+
try {
|
|
1222
|
+
await checkOrderCustomData(customData, { evmDest: !tonDest, outputToken, traderDst: params.destAddress, quoteId: intent.quoteId });
|
|
1223
|
+
} catch (e) {
|
|
1224
|
+
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1225
|
+
}
|
|
1226
|
+
return null;
|
|
1227
|
+
}
|
|
1111
1228
|
function omnistonVerifyBuild(hooks) {
|
|
1229
|
+
const trusted = {
|
|
1230
|
+
orderProtocols: hooks.trustedEvmOrderProtocols ?? AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS,
|
|
1231
|
+
factories: hooks.trustedSettlementContracts ?? AUDITED_OMNISTON_SETTLEMENT_CONTRACTS
|
|
1232
|
+
};
|
|
1112
1233
|
return async (quote, tx, params) => {
|
|
1234
|
+
if (tx.typedData !== void 0) {
|
|
1235
|
+
if (!params) return "the request this quote answered is unknown";
|
|
1236
|
+
try {
|
|
1237
|
+
return await checkRemoteEvmOrder(quote, tx, params, trusted);
|
|
1238
|
+
} catch {
|
|
1239
|
+
return "the typed order could not be checked";
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1113
1242
|
if (tx.bodyBoc === void 0) return null;
|
|
1114
1243
|
if (!params) return "the request this quote answered is unknown";
|
|
1115
1244
|
if (quote.providerData?.settlement !== "swap") {
|
|
@@ -1170,16 +1299,15 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1170
1299
|
} catch {
|
|
1171
1300
|
return "the swap target could not be checked";
|
|
1172
1301
|
}
|
|
1173
|
-
if (hooks.validateTonSwapLeg)
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
}
|
|
1181
|
-
if (!ok) return `${leg.kind} v${leg.version} leg not verified`;
|
|
1302
|
+
if (!hooks.validateTonSwapLeg) return "a TON swap body needs validateTonSwapLeg (createOmnistonTonValidators)";
|
|
1303
|
+
for (const leg of checked.legs) {
|
|
1304
|
+
let ok = false;
|
|
1305
|
+
try {
|
|
1306
|
+
ok = await hooks.validateTonSwapLeg(leg);
|
|
1307
|
+
} catch {
|
|
1308
|
+
ok = false;
|
|
1182
1309
|
}
|
|
1310
|
+
if (!ok) return `${leg.kind} v${leg.version} leg not verified`;
|
|
1183
1311
|
}
|
|
1184
1312
|
return null;
|
|
1185
1313
|
};
|
|
@@ -1316,7 +1444,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1316
1444
|
return true;
|
|
1317
1445
|
}
|
|
1318
1446
|
const a = existing.bound, b = entry.bound;
|
|
1319
|
-
const same = !!a && !!b && a.kind === b.kind && a.srcChain === b.srcChain && sameIntentAddress(a.trader, b.trader) && sameIntentAddress(a.dest, b.dest);
|
|
1447
|
+
const same = !!a && !!b && a.kind === b.kind && a.srcChain === b.srcChain && sameIntentAddress(a.trader, b.trader) && sameIntentAddress(a.dest, b.dest) && quoteDigest(existing.quote) === quoteDigest(entry.quote);
|
|
1320
1448
|
if (!same) return false;
|
|
1321
1449
|
await quotes.save(quoteId, json);
|
|
1322
1450
|
return true;
|
|
@@ -1369,10 +1497,19 @@ function omnistonProvider(opts = {}) {
|
|
|
1369
1497
|
throw new Error(`omniston: intent id does not match the quote it was issued for (${bound.field})`);
|
|
1370
1498
|
}
|
|
1371
1499
|
if (bound.legacy) trace("legacy-intent", { where });
|
|
1500
|
+
if (!decoded.digest) {
|
|
1501
|
+
trace("intent-mismatch", { where, field: "digest-missing" });
|
|
1502
|
+
throw new Error("omniston: this quote was issued before an update \u2014 request a fresh quote");
|
|
1503
|
+
}
|
|
1504
|
+
if (decoded.digest !== quoteDigest(entry.quote)) {
|
|
1505
|
+
trace("intent-mismatch", { where, field: "digest" });
|
|
1506
|
+
throw new Error("omniston: quote was replaced \u2014 request a fresh quote");
|
|
1507
|
+
}
|
|
1372
1508
|
return bound.ref;
|
|
1373
1509
|
}
|
|
1374
1510
|
const bindKey = (quoteId) => `${quoteId}#bind`;
|
|
1375
1511
|
const disclosedKey = (quoteId) => `${quoteId}#disclosed`;
|
|
1512
|
+
const disclosedIndicesKey = (quoteId) => `${quoteId}#disclosed-indices`;
|
|
1376
1513
|
function orderBinding(ref, q) {
|
|
1377
1514
|
return sha256(new TextEncoder().encode(JSON.stringify([
|
|
1378
1515
|
ref.quoteId,
|
|
@@ -1389,6 +1526,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1389
1526
|
await store.clear(quoteId);
|
|
1390
1527
|
await store.clear(bindKey(quoteId));
|
|
1391
1528
|
await store.clear(disclosedKey(quoteId));
|
|
1529
|
+
await store.clear(disclosedIndicesKey(quoteId));
|
|
1392
1530
|
}
|
|
1393
1531
|
async function secretsFor(ref, q, count) {
|
|
1394
1532
|
const quoteId = ref.quoteId;
|
|
@@ -1417,7 +1555,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1417
1555
|
return !!existing && existing.length > 0;
|
|
1418
1556
|
}
|
|
1419
1557
|
const SWAP_SLIPPAGE_PIPS_DEFAULT = 5e3;
|
|
1420
|
-
const sameChainTonReady = () => typeof opts.validateTonJettonWallet === "function" && typeof opts.validateTonSwapTarget === "function";
|
|
1558
|
+
const sameChainTonReady = () => typeof opts.validateTonJettonWallet === "function" && typeof opts.validateTonSwapTarget === "function" && (typeof opts.validateTonSwapLeg === "function" || opts.tonSwapPayloadCheck === "report");
|
|
1421
1559
|
const tonSourceReady = (from, to) => omniston.supports(from, to) && trustedContracts.has(from) && trustedContracts.has(to) && typeof opts.validateTonJettonWallet === "function" && typeof opts.validateTonEscrowPayload === "function" && typeof opts.validateEvmOutputPosition === "function";
|
|
1422
1560
|
const evmSourceReady = (from, to) => omniston.supports(from, to) && trustedOrderProtocols.has(from) && trustedContracts.has(from) && trustedContracts.has(to) && typeof opts.validateEvmInputPosition === "function" && typeof opts.validateTonOutputPosition === "function";
|
|
1423
1561
|
const evmToEvmReady = (from, to) => omniston.supports(from, to) && trustedOrderProtocols.has(from) && trustedContracts.has(from) && trustedContracts.has(to) && typeof opts.validateEvmInputPosition === "function" && typeof opts.validateEvmOutputPosition === "function";
|
|
@@ -1496,7 +1634,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1496
1634
|
const feeUsd = stableOut ? feeUnits / 10 ** dest.decimals : 0;
|
|
1497
1635
|
return {
|
|
1498
1636
|
provider: "omniston",
|
|
1499
|
-
intentId: encodeIntent(q.quoteId, trader, params.destAddress, params.sourceChain, "swap"),
|
|
1637
|
+
intentId: encodeIntent(q.quoteId, trader, params.destAddress, params.sourceChain, "swap", quoteDigest(q)),
|
|
1500
1638
|
depositAddress: "",
|
|
1501
1639
|
// swap settlement — the built message pays the DEX directly
|
|
1502
1640
|
depositMemo: null,
|
|
@@ -1529,7 +1667,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1529
1667
|
if (!isTon(ref.srcChain) || q.inputAsset.chain.$case !== "ton" || q.outputAsset.chain.$case !== "ton") {
|
|
1530
1668
|
throw new Error("omniston: swap quote is not a TON same-chain swap");
|
|
1531
1669
|
}
|
|
1532
|
-
if (!sameChainTonReady()) throw new Error("omniston: TON same-chain swaps need independent jetton-wallet and swap-
|
|
1670
|
+
if (!sameChainTonReady()) throw new Error("omniston: TON same-chain swaps need independent jetton-wallet, swap-target and swap-leg validators");
|
|
1533
1671
|
const owner = { chain: { $case: "ton", value: ref.trader } };
|
|
1534
1672
|
const receiver = { chain: { $case: "ton", value: ref.dest } };
|
|
1535
1673
|
const omni = await getClient();
|
|
@@ -1628,7 +1766,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1628
1766
|
}
|
|
1629
1767
|
if (checked) {
|
|
1630
1768
|
if (typeof opts.validateTonSwapLeg !== "function") {
|
|
1631
|
-
|
|
1769
|
+
payloadRefusal("legs-unverified", `no validateTonSwapLeg hook for ${checked.legs.length} leg(s)`);
|
|
1632
1770
|
} else {
|
|
1633
1771
|
for (const leg of checked.legs) {
|
|
1634
1772
|
let ok = false;
|
|
@@ -1799,7 +1937,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1799
1937
|
}
|
|
1800
1938
|
});
|
|
1801
1939
|
const orderProtocol = getAddress(protocol.chain.value);
|
|
1802
|
-
return { chain: srcChain, to: orderProtocol, value: "0", chainId, approvalAddress: orderProtocol, typedData };
|
|
1940
|
+
return { chain: srcChain, to: orderProtocol, value: "0", chainId, approvalAddress: orderProtocol, typedData, orderExtension: `0x${bytesToHex(payload.orderExtension)}` };
|
|
1803
1941
|
}
|
|
1804
1942
|
return {
|
|
1805
1943
|
name: "omniston",
|
|
@@ -1908,13 +2046,13 @@ function omnistonProvider(opts = {}) {
|
|
|
1908
2046
|
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input");
|
|
1909
2047
|
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order");
|
|
1910
2048
|
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "order" } })) {
|
|
1911
|
-
return refuse2("the platform reused a quote id that already holds another
|
|
2049
|
+
return refuse2("the platform reused a quote id that already holds another quote");
|
|
1912
2050
|
}
|
|
1913
2051
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
1914
2052
|
const feeUsd = feeUnits / 10 ** dest.decimals;
|
|
1915
2053
|
return {
|
|
1916
2054
|
provider: "omniston",
|
|
1917
|
-
intentId: encodeIntent(q.quoteId, trader, params.destAddress, params.sourceChain),
|
|
2055
|
+
intentId: encodeIntent(q.quoteId, trader, params.destAddress, params.sourceChain, "order", quoteDigest(q)),
|
|
1918
2056
|
depositAddress: "",
|
|
1919
2057
|
// order settlement — no static deposit address
|
|
1920
2058
|
depositMemo: null,
|
|
@@ -2086,6 +2224,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2086
2224
|
);
|
|
2087
2225
|
if (!order) return { state: "pending" };
|
|
2088
2226
|
let secretsHex = await store.load(decoded.quoteId);
|
|
2227
|
+
const storedSecrets = secretsHex?.length ?? 0;
|
|
2089
2228
|
if (!secretsHex || cached?.quote.settlementData.$case !== "order") trace("disclosure-skipped", { gate: "context", secrets: !!secretsHex, cached: !!cached, feedStatus: order.status });
|
|
2090
2229
|
if (secretsHex && cached?.quote.settlementData.$case === "order") {
|
|
2091
2230
|
const [lockedTo] = await store.load(bindKey(decoded.quoteId)) ?? [];
|
|
@@ -2094,6 +2233,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2094
2233
|
secretsHex = void 0;
|
|
2095
2234
|
}
|
|
2096
2235
|
}
|
|
2236
|
+
const disclosedNow = /* @__PURE__ */ new Set();
|
|
2097
2237
|
if (secretsHex && cached?.quote.settlementData.$case === "order") {
|
|
2098
2238
|
const q = cached.quote;
|
|
2099
2239
|
const settlement = q.settlementData.value;
|
|
@@ -2192,11 +2332,15 @@ function omnistonProvider(opts = {}) {
|
|
|
2192
2332
|
}
|
|
2193
2333
|
await omni.orderDiscloseHtlcSecret({ quoteId: decoded.quoteId, executionIndex: i, secret: secretBytes }).then(async () => {
|
|
2194
2334
|
trace("secret-disclosed", { index: i });
|
|
2335
|
+
disclosedNow.add(i);
|
|
2195
2336
|
await store.save(disclosedKey(decoded.quoteId), ["1"]);
|
|
2196
2337
|
}, (error) => trace("disclose-failed", { index: i, error: error instanceof Error ? error.message : String(error) }));
|
|
2197
2338
|
})
|
|
2198
2339
|
);
|
|
2199
2340
|
}
|
|
2341
|
+
const disclosedBefore = (await store.load(disclosedIndicesKey(decoded.quoteId)) ?? []).map(Number).filter(Number.isSafeInteger);
|
|
2342
|
+
const disclosedAll = /* @__PURE__ */ new Set([...disclosedBefore, ...disclosedNow]);
|
|
2343
|
+
if (disclosedNow.size > 0) await store.save(disclosedIndicesKey(decoded.quoteId), [...disclosedAll].sort((a, b) => a - b).map(String));
|
|
2200
2344
|
const status = mapOrderStatus(order);
|
|
2201
2345
|
const delivered = order.executions[0]?.outputPositionAddress;
|
|
2202
2346
|
const outCase = cached?.quote.outputAsset.chain.$case;
|
|
@@ -2221,6 +2365,14 @@ function omnistonProvider(opts = {}) {
|
|
|
2221
2365
|
}).catch(() => null);
|
|
2222
2366
|
if (hash) status.destTxHash = hash;
|
|
2223
2367
|
}
|
|
2368
|
+
if (status.state === "completed" && storedSecrets > 0 && !status.destTxHash) {
|
|
2369
|
+
const legacyDisclosed = disclosedBefore.length === 0 && storedSecrets === 1 && (await store.load(disclosedKey(decoded.quoteId)) ?? []).length > 0;
|
|
2370
|
+
const allDisclosed = legacyDisclosed || (order.executions.length > 0 ? order.executions.every((execution) => disclosedAll.has(execution.index)) : disclosedAll.size > 0);
|
|
2371
|
+
if (!allDisclosed) {
|
|
2372
|
+
trace("completion-unproven", { feedStatus: order.status, executions: order.executions.length, disclosed: disclosedAll.size });
|
|
2373
|
+
return { state: "pending", depositReceived: order.executions.length > 0 || disclosedAll.size > 0 };
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2224
2376
|
if (status.state === "completed") {
|
|
2225
2377
|
await clearSecrets(decoded.quoteId);
|
|
2226
2378
|
await quotes.clear(decoded.quoteId);
|
|
@@ -2273,4 +2425,4 @@ export {
|
|
|
2273
2425
|
omnistonVerifyBuild,
|
|
2274
2426
|
omnistonProvider
|
|
2275
2427
|
};
|
|
2276
|
-
//# sourceMappingURL=chunk-
|
|
2428
|
+
//# sourceMappingURL=chunk-2DGCZD5K.js.map
|