@anywalletkit/protocol-swap2-omniston 0.5.6 → 0.5.7
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 +3 -0
- package/dist/{chunk-FDSTD34Z.js → chunk-DMO24BFW.js} +282 -185
- package/dist/chunk-DMO24BFW.js.map +1 -0
- package/dist/{chunk-IX4NF2J7.js → chunk-NOIL6LQK.js} +2 -2
- package/dist/index.cjs +281 -184
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/protocol.cjs +225 -139
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +2 -2
- package/dist/provider.cjs +281 -184
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-FDSTD34Z.js.map +0 -1
- /package/dist/{chunk-IX4NF2J7.js.map → chunk-NOIL6LQK.js.map} +0 -0
package/dist/protocol.cjs
CHANGED
|
@@ -426,6 +426,7 @@ function sameJetton(a, b) {
|
|
|
426
426
|
}
|
|
427
427
|
|
|
428
428
|
// src/provider.ts
|
|
429
|
+
var import_errors = require("@anywalletkit/protocol-swap2-core/errors");
|
|
429
430
|
var import_core4 = require("@anywalletkit/core");
|
|
430
431
|
var EVM_CASE = {
|
|
431
432
|
1: "ethereum",
|
|
@@ -563,6 +564,54 @@ function encodeTypedMessage(td) {
|
|
|
563
564
|
(0, import_viem.encodeAbiParameters)([paramFor(td.primaryType)], [td.message])
|
|
564
565
|
);
|
|
565
566
|
}
|
|
567
|
+
function venueReason(error) {
|
|
568
|
+
const details = typeof error === "object" && error !== null ? error.details : void 0;
|
|
569
|
+
const info = typeof details === "object" && details !== null ? details.error_info : void 0;
|
|
570
|
+
if (typeof info !== "object" || info === null) return "upstream_unavailable";
|
|
571
|
+
const { reason, metadata } = info;
|
|
572
|
+
const meta = typeof metadata === "object" && metadata !== null ? metadata : {};
|
|
573
|
+
const type = typeof meta.type === "string" ? meta.type : "";
|
|
574
|
+
switch (reason) {
|
|
575
|
+
case "INVALID_ARGUMENT":
|
|
576
|
+
case "INVALID_PARAMETERS":
|
|
577
|
+
return void 0;
|
|
578
|
+
case "NOT_FOUND":
|
|
579
|
+
return typeof meta.object_type === "string" && meta.object_type.toLowerCase() === "quote" ? "quote_expired" : "upstream_unavailable";
|
|
580
|
+
case "UNSUPPORTED":
|
|
581
|
+
return "unsupported_pair";
|
|
582
|
+
case "SWAP_LIMIT_EXCEEDED":
|
|
583
|
+
return "amount_too_large";
|
|
584
|
+
case "QUOTE_VALIDATION_FAILED":
|
|
585
|
+
if (type === "EMULATION_UNSUPPORTED_TOKEN") return "unsupported_pair";
|
|
586
|
+
if (type === "EMULATION_WRONG_OUTPUT_AMOUNT" || type === "EMULATION_REFUND_SLIPPAGE") return "price_check_failed";
|
|
587
|
+
return type.startsWith("EMULATION_") ? "simulation_failed" : "upstream_unavailable";
|
|
588
|
+
default:
|
|
589
|
+
return "upstream_unavailable";
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
function venueFailure(error) {
|
|
593
|
+
if (!(error instanceof Error)) return error;
|
|
594
|
+
const reason = venueReason(error);
|
|
595
|
+
return reason ? (0, import_errors.withReason)(error, reason) : error;
|
|
596
|
+
}
|
|
597
|
+
function mismatchReason(field) {
|
|
598
|
+
return field === "trader" || field === "dest" || field === "owner" ? "recipient_mismatch" : "policy_refused";
|
|
599
|
+
}
|
|
600
|
+
function tonSwapPayloadReason(code) {
|
|
601
|
+
switch (code) {
|
|
602
|
+
case "receiver-not-destination":
|
|
603
|
+
case "refund-not-trader":
|
|
604
|
+
case "excess-not-trader":
|
|
605
|
+
return "recipient_mismatch";
|
|
606
|
+
case "min-out-zero":
|
|
607
|
+
case "min-out-below-quote":
|
|
608
|
+
return "price_check_failed";
|
|
609
|
+
case "leg-unverified":
|
|
610
|
+
return "vault_mismatch";
|
|
611
|
+
default:
|
|
612
|
+
return "policy_refused";
|
|
613
|
+
}
|
|
614
|
+
}
|
|
566
615
|
function generateSecret() {
|
|
567
616
|
return crypto.getRandomValues(new Uint8Array(32));
|
|
568
617
|
}
|
|
@@ -573,7 +622,7 @@ function hashlock(secret, hashingFunction) {
|
|
|
573
622
|
case "HASHING_FUNCTION_SHA256":
|
|
574
623
|
return (0, import_viem.sha256)(secret, "bytes");
|
|
575
624
|
default:
|
|
576
|
-
throw
|
|
625
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: unsupported HTLC hashing function ${String(hashingFunction)}`);
|
|
577
626
|
}
|
|
578
627
|
}
|
|
579
628
|
function sameAsset(a, b) {
|
|
@@ -611,7 +660,7 @@ function stepJetton(asset) {
|
|
|
611
660
|
}
|
|
612
661
|
function readBigEndian(bytes, offset, length) {
|
|
613
662
|
if (!Number.isInteger(offset) || !Number.isInteger(length) || length < 1 || offset < 0 || offset + length > bytes.length) {
|
|
614
|
-
throw
|
|
663
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: truncated EVM order extension");
|
|
615
664
|
}
|
|
616
665
|
let value = 0n;
|
|
617
666
|
for (let index = offset; index < offset + length; index++) value = value << 8n | BigInt(bytes[index]);
|
|
@@ -656,30 +705,30 @@ var EVM_DEST_PROTOCOL_FEE_RECIPIENTS = /* @__PURE__ */ new Set(["0x076268146b4ec
|
|
|
656
705
|
var EVM_AUCTION_POINTS = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
|
|
657
706
|
var EVM_TIMELOCKS = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
|
|
658
707
|
function readEvmOrderExtension(extension) {
|
|
659
|
-
if (extension.length < 32) throw
|
|
708
|
+
if (extension.length < 32) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension");
|
|
660
709
|
const view = new DataView(extension.buffer, extension.byteOffset, extension.byteLength);
|
|
661
710
|
const fields = [];
|
|
662
711
|
let begin = 0;
|
|
663
712
|
const concatLength = extension.length - 32;
|
|
664
713
|
for (let index = 0; index < 8; index++) {
|
|
665
714
|
const end2 = view.getUint32(28 - index * 4, false);
|
|
666
|
-
if (end2 < begin || end2 > concatLength) throw
|
|
715
|
+
if (end2 < begin || end2 > concatLength) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension offsets");
|
|
667
716
|
fields.push(extension.slice(32 + begin, 32 + end2));
|
|
668
717
|
begin = end2;
|
|
669
718
|
}
|
|
670
719
|
for (const index of [0, 1, 4, 5, 6]) {
|
|
671
|
-
if (fields[index].length !== 0) throw
|
|
720
|
+
if (fields[index].length !== 0) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM order extension field");
|
|
672
721
|
}
|
|
673
722
|
if (!sliceEqual(fields[2], fields[3])) {
|
|
674
|
-
throw
|
|
723
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: making/taking amount getters use different programs");
|
|
675
724
|
}
|
|
676
725
|
let target;
|
|
677
726
|
for (const index of [2, 3, 7]) {
|
|
678
727
|
const field2 = fields[index];
|
|
679
|
-
if (field2.length <= 20) throw
|
|
728
|
+
if (field2.length <= 20) throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete EVM order extension program");
|
|
680
729
|
const address = (0, import_viem.getAddress)(`0x${bytesToHex(field2.slice(0, 20))}`);
|
|
681
730
|
if (target !== void 0 && (0, import_viem.getAddress)(target) !== address) {
|
|
682
|
-
throw
|
|
731
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
683
732
|
}
|
|
684
733
|
target = address;
|
|
685
734
|
}
|
|
@@ -697,7 +746,7 @@ function readEvmOrderExtension(extension) {
|
|
|
697
746
|
cursor += 3;
|
|
698
747
|
const pointCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
699
748
|
cursor += 1;
|
|
700
|
-
if (pointCount !== 5) throw
|
|
749
|
+
if (pointCount !== 5) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM auction profile");
|
|
701
750
|
const points = [];
|
|
702
751
|
for (let index = 0; index < pointCount; index++) {
|
|
703
752
|
points.push([readBigEndian(field, cursor, 3), readBigEndian(field, cursor + 3, 2)]);
|
|
@@ -714,7 +763,7 @@ function readEvmOrderExtension(extension) {
|
|
|
714
763
|
const getterWhitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
715
764
|
cursor += 1;
|
|
716
765
|
if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== field.length) {
|
|
717
|
-
throw
|
|
766
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM amount-getter whitelist");
|
|
718
767
|
}
|
|
719
768
|
const getter = { gasBump, gasPrice, auctionStart, duration, initialRateBump, points, integratorFee, integratorShare, resolverFee, whitelistDiscount, resolver: readBigEndian(field, cursor, 10) };
|
|
720
769
|
const post = fields[7];
|
|
@@ -736,7 +785,7 @@ function readEvmOrderExtension(extension) {
|
|
|
736
785
|
const whitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(post, cursor, 1));
|
|
737
786
|
cursor += 1;
|
|
738
787
|
if (whitelistCount !== 1 || cursor + whitelistCount * 12 + 160 !== post.length) {
|
|
739
|
-
throw
|
|
788
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM post-interaction whitelist");
|
|
740
789
|
}
|
|
741
790
|
const postResolver = readBigEndian(post, cursor, 10);
|
|
742
791
|
cursor += 10;
|
|
@@ -748,7 +797,7 @@ function readEvmOrderExtension(extension) {
|
|
|
748
797
|
return value;
|
|
749
798
|
});
|
|
750
799
|
const customData = extension.slice(32 + begin);
|
|
751
|
-
if (customData.length !== 131) throw
|
|
800
|
+
if (customData.length !== 131) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension custom data");
|
|
752
801
|
return {
|
|
753
802
|
target,
|
|
754
803
|
getter,
|
|
@@ -761,29 +810,29 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
761
810
|
const evmDest = expected.dstChainId !== void 0;
|
|
762
811
|
if (evmDest && (!Number.isSafeInteger(expected.dstChainId) || expected.dstChainId <= 0)) throw new Error("omniston: invalid EVM destination chain id");
|
|
763
812
|
const { target, getter, post, extra, customData } = readEvmOrderExtension(extension);
|
|
764
|
-
if (!expected.trustedTarget(target)) throw
|
|
813
|
+
if (!expected.trustedTarget(target)) throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
765
814
|
const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
|
|
766
815
|
const resolverLow80 = BigInt((0, import_viem.getAddress)(expected.initialResolverAddress)) & (1n << 80n) - 1n;
|
|
767
816
|
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) {
|
|
768
|
-
throw
|
|
817
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
|
|
769
818
|
}
|
|
770
819
|
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) {
|
|
771
|
-
throw
|
|
820
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
|
|
772
821
|
}
|
|
773
822
|
const hashlock2 = readBigEndian(expected.secretHash, 0, expected.secretHash.length);
|
|
774
823
|
const dstToken = evmDest ? BigInt((0, import_viem.getAddress)(expected.outputTokenAddress)) : BigInt((0, import_viem.getAddress)(expected.takerAsset));
|
|
775
824
|
const deposits = BigInt(expected.srcSecurityDepositUnits) << 128n | BigInt(expected.dstSecurityDepositUnits);
|
|
776
825
|
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) {
|
|
777
|
-
throw
|
|
826
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: signed EVM HTLC terms do not match the validated order details");
|
|
778
827
|
}
|
|
779
828
|
await checkOrderCustomData(customData, { evmDest, outputToken: expected.outputTokenAddress, traderDst: expected.traderDstAddress, quoteId: expected.quoteId });
|
|
780
829
|
if (expected.tradeStartDeadline < expected.quoteTimestamp) {
|
|
781
|
-
throw
|
|
830
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: invalid EVM order quote deadline");
|
|
782
831
|
}
|
|
783
832
|
}
|
|
784
833
|
async function checkOrderCustomData(customData, expected) {
|
|
785
834
|
if (expected.evmDest) {
|
|
786
|
-
if (!zeroBytes(customData.slice(0, 66))) throw
|
|
835
|
+
if (!zeroBytes(customData.slice(0, 66))) throw (0, import_errors.refusal)("recipient_mismatch", "omniston: unexpected TON addresses in an EVM-destination order");
|
|
787
836
|
} else {
|
|
788
837
|
const { Address: Address3 } = await import("@ton/core");
|
|
789
838
|
const expectedTon = [expected.outputToken, expected.traderDst].map((value) => Address3.parse(value));
|
|
@@ -791,16 +840,16 @@ async function checkOrderCustomData(customData, expected) {
|
|
|
791
840
|
const offset = index * 33;
|
|
792
841
|
const workchain = customData[offset] === 255 ? -1 : customData[offset];
|
|
793
842
|
if (workchain !== expectedTon[index].workChain || !sliceEqual(customData.slice(offset + 1, offset + 33), expectedTon[index].hash)) {
|
|
794
|
-
throw
|
|
843
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: signed EVM\u2192TON address does not match the validated request");
|
|
795
844
|
}
|
|
796
845
|
}
|
|
797
846
|
}
|
|
798
847
|
if (!zeroBytes(customData.slice(66, 99))) {
|
|
799
|
-
throw
|
|
848
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unexpected private TON disclosure address");
|
|
800
849
|
}
|
|
801
850
|
const quoteId = expected.quoteId.replace(/^0x/, "");
|
|
802
851
|
if (!QUOTE_ID.test(quoteId) || !sliceEqual(customData.slice(99), hexToBytes(quoteId.padStart(64, "0")))) {
|
|
803
|
-
throw
|
|
852
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order extension custom data is not bound to the quote id");
|
|
804
853
|
}
|
|
805
854
|
}
|
|
806
855
|
function validateEvmTypedOrder(td, expected) {
|
|
@@ -822,7 +871,7 @@ function validateEvmTypedOrder(td, expected) {
|
|
|
822
871
|
if (value.domain?.name !== "1inch Limit Order Protocol" || value.domain.version !== "4" || typeof value.domain.verifyingContract !== "string" || (0, import_viem.getAddress)(value.domain.verifyingContract) !== (0, import_viem.getAddress)(expected.settlementContract) || Number(value.domain.chainId) !== expected.chainId || value.primaryType !== "Order" || !exactSchema || !message || !exactMessage || (0, import_viem.getAddress)(String(message.maker)) !== (0, import_viem.getAddress)(expected.owner) || (0, import_viem.getAddress)(String(message.receiver)) !== (0, import_viem.getAddress)(expected.receiver) || (0, import_viem.getAddress)(String(message.makerAsset)) !== (0, import_viem.getAddress)(expected.makerAsset) || !validUint256(salt) || (BigInt(salt) & (1n << 160n) - 1n) !== (extensionHash & (1n << 160n) - 1n) || // The order expires at the quote's trade-start deadline (±15 s of clock
|
|
823
872
|
// skew between the quote and the order builder), never later.
|
|
824
873
|
traits < 0n || !flagsOk || allowedSender !== 0n || series !== 0n || !within(expiration, expected.tradeStartDeadline, 15, 15) || expiration <= BigInt(expected.quoteTimestamp) || !validEvmAddress(message.takerAsset) || (0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(expected.makerAsset) || !validUint256(message.makingAmount) || BigInt(message.makingAmount) !== BigInt(expected.makingAmount) || !validUint256(message.takingAmount) || BigInt(message.takingAmount) !== BigInt(expected.takingAmount)) {
|
|
825
|
-
throw
|
|
874
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order fields do not match the validated quote/request");
|
|
826
875
|
}
|
|
827
876
|
}
|
|
828
877
|
async function validateTonEscrowPayload(message, expected, validateForwardPayload) {
|
|
@@ -832,9 +881,9 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
832
881
|
try {
|
|
833
882
|
roots = Cell2.fromBoc(import_buffer2.Buffer.from(boc));
|
|
834
883
|
} catch {
|
|
835
|
-
throw
|
|
884
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed TON escrow BoC");
|
|
836
885
|
}
|
|
837
|
-
if (roots.length !== 1) throw
|
|
886
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow must contain exactly one root cell");
|
|
838
887
|
const slice = roots[0].beginParse();
|
|
839
888
|
const op = slice.loadUint(32);
|
|
840
889
|
slice.loadUintBig(64);
|
|
@@ -845,7 +894,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
845
894
|
const forwardAmount = slice.loadCoins();
|
|
846
895
|
const payloadByRef = slice.loadBit();
|
|
847
896
|
if (op !== 260734629 || amount !== BigInt(expected.inputUnits) || !(destination instanceof Address3) || !destination.equals(Address3.parse(expected.protocolAddress)) || response !== null && (!(response instanceof Address3) || !response.equals(Address3.parse(expected.ownerAddress))) || customPayload !== null || forwardAmount <= 0n || forwardAmount > BigInt(message.sendAmount) || !payloadByRef || slice.remainingBits !== 0 || slice.remainingRefs !== 1) {
|
|
848
|
-
throw
|
|
897
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: TON jetton transfer does not match the validated quote/request");
|
|
849
898
|
}
|
|
850
899
|
const forwardPayload = slice.loadRef();
|
|
851
900
|
const verified = await validateForwardPayload({
|
|
@@ -865,7 +914,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
865
914
|
...expected.hashingFunction ? { hashingFunction: expected.hashingFunction } : {},
|
|
866
915
|
exclusivityTimeout: expected.exclusivityTimeout
|
|
867
916
|
});
|
|
868
|
-
if (!verified) throw
|
|
917
|
+
if (!verified) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow forward payload failed independent semantic validation");
|
|
869
918
|
}
|
|
870
919
|
function feeToken(asset) {
|
|
871
920
|
return asset.assetId || asset.contract || asset.symbol;
|
|
@@ -895,24 +944,24 @@ var ProtoReader = class {
|
|
|
895
944
|
const byte = this.bytes[this.pos++];
|
|
896
945
|
out += (byte & 127) * 2 ** shift;
|
|
897
946
|
if ((byte & 128) === 0) {
|
|
898
|
-
if (!Number.isSafeInteger(out)) throw
|
|
947
|
+
if (!Number.isSafeInteger(out)) throw (0, import_errors.refusal)("policy_refused", "omniston: unsafe protobuf varint");
|
|
899
948
|
return out;
|
|
900
949
|
}
|
|
901
950
|
shift += 7;
|
|
902
951
|
}
|
|
903
|
-
throw
|
|
952
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf varint");
|
|
904
953
|
}
|
|
905
954
|
field() {
|
|
906
955
|
const tag = this.varint();
|
|
907
956
|
const number = Math.floor(tag / 8);
|
|
908
957
|
const wire = tag & 7;
|
|
909
|
-
if (number < 1) throw
|
|
958
|
+
if (number < 1) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf field");
|
|
910
959
|
return { number, wire };
|
|
911
960
|
}
|
|
912
961
|
lengthDelimited() {
|
|
913
962
|
const length = this.varint();
|
|
914
963
|
const end2 = this.pos + length;
|
|
915
|
-
if (length < 0 || end2 > this.bytes.length) throw
|
|
964
|
+
if (length < 0 || end2 > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
916
965
|
const value = this.bytes.slice(this.pos, end2);
|
|
917
966
|
this.pos = end2;
|
|
918
967
|
return value;
|
|
@@ -934,10 +983,10 @@ var ProtoReader = class {
|
|
|
934
983
|
this.advance(4);
|
|
935
984
|
return;
|
|
936
985
|
}
|
|
937
|
-
throw
|
|
986
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported protobuf wire type");
|
|
938
987
|
}
|
|
939
988
|
advance(length) {
|
|
940
|
-
if (this.pos + length > this.bytes.length) throw
|
|
989
|
+
if (this.pos + length > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
941
990
|
this.pos += length;
|
|
942
991
|
}
|
|
943
992
|
};
|
|
@@ -964,10 +1013,10 @@ function decodeChainAddress(bytes) {
|
|
|
964
1013
|
while (!reader.done) {
|
|
965
1014
|
const { number, wire } = reader.field();
|
|
966
1015
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
967
|
-
if (!$case || wire !== 2 || address) throw
|
|
1016
|
+
if (!$case || wire !== 2 || address) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed chain address in order details");
|
|
968
1017
|
address = { chain: { $case, value: utf8.decode(reader.lengthDelimited()) } };
|
|
969
1018
|
}
|
|
970
|
-
if (!address?.chain.value) throw
|
|
1019
|
+
if (!address?.chain.value) throw (0, import_errors.refusal)("policy_refused", "omniston: empty chain address in order details");
|
|
971
1020
|
return address;
|
|
972
1021
|
}
|
|
973
1022
|
function decodeAssetId(bytes) {
|
|
@@ -976,27 +1025,27 @@ function decodeAssetId(bytes) {
|
|
|
976
1025
|
while (!reader.done) {
|
|
977
1026
|
const { number, wire } = reader.field();
|
|
978
1027
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
979
|
-
if (!$case || wire !== 2 || asset) throw
|
|
1028
|
+
if (!$case || wire !== 2 || asset) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset id in order details");
|
|
980
1029
|
const kindReader = new ProtoReader(reader.lengthDelimited());
|
|
981
1030
|
const kindField = kindReader.field();
|
|
982
1031
|
if (kindField.wire !== 2 || kindField.number !== 1 && kindField.number !== 2) {
|
|
983
|
-
throw
|
|
1032
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported asset kind in order details");
|
|
984
1033
|
}
|
|
985
1034
|
const kindCase = kindField.number === 1 ? "native" : $case === "ton" ? "jetton" : $case === "tron" ? "trc20" : "erc20";
|
|
986
1035
|
const value = kindField.number === 1 ? {} : utf8.decode(kindReader.lengthDelimited());
|
|
987
|
-
if (!kindReader.done || kindField.number === 2 && !value) throw
|
|
1036
|
+
if (!kindReader.done || kindField.number === 2 && !value) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset kind in order details");
|
|
988
1037
|
asset = { chain: { $case, value: { kind: { $case: kindCase, value } } } };
|
|
989
1038
|
}
|
|
990
|
-
if (!asset) throw
|
|
1039
|
+
if (!asset) throw (0, import_errors.refusal)("policy_refused", "omniston: empty asset id in order details");
|
|
991
1040
|
return asset;
|
|
992
1041
|
}
|
|
993
1042
|
function validateSerializedOrderDetails(bytes, expected) {
|
|
994
|
-
if (!bytes?.length) throw
|
|
1043
|
+
if (!bytes?.length) throw (0, import_errors.refusal)("policy_refused", "omniston: EVM HTLC order payload has no serialized details");
|
|
995
1044
|
const wrapper = new ProtoReader(bytes);
|
|
996
1045
|
const outer = wrapper.field();
|
|
997
|
-
if (outer.number !== 1 || outer.wire !== 2) throw
|
|
1046
|
+
if (outer.number !== 1 || outer.wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported HTLC order-details version");
|
|
998
1047
|
const detailsBytes = wrapper.lengthDelimited();
|
|
999
|
-
if (!wrapper.done) throw
|
|
1048
|
+
if (!wrapper.done) throw (0, import_errors.refusal)("policy_refused", "omniston: ambiguous HTLC order-details wrapper");
|
|
1000
1049
|
const reader = new ProtoReader(detailsBytes);
|
|
1001
1050
|
let quoteId;
|
|
1002
1051
|
let outputAsset;
|
|
@@ -1004,16 +1053,16 @@ function validateSerializedOrderDetails(bytes, expected) {
|
|
|
1004
1053
|
const hashes = [];
|
|
1005
1054
|
while (!reader.done) {
|
|
1006
1055
|
const { number, wire } = reader.field();
|
|
1007
|
-
if (wire !== 2) throw
|
|
1056
|
+
if (wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed HTLC order details");
|
|
1008
1057
|
const value = reader.lengthDelimited();
|
|
1009
1058
|
if (number === 1 && quoteId === void 0) quoteId = utf8.decode(value);
|
|
1010
1059
|
else if (number === 2 && outputAsset === void 0) outputAsset = decodeAssetId(value);
|
|
1011
1060
|
else if (number === 3 && traderDstAddress === void 0) traderDstAddress = decodeChainAddress(value);
|
|
1012
1061
|
else if (number === 5) hashes.push(value);
|
|
1013
|
-
else throw
|
|
1062
|
+
else throw (0, import_errors.refusal)("policy_refused", "omniston: duplicate or unexpected HTLC order-details field");
|
|
1014
1063
|
}
|
|
1015
1064
|
if (quoteId !== expected.quoteId || !outputAsset || !sameAsset(outputAsset, expected.outputAsset) || !traderDstAddress || !sameChainAddress(traderDstAddress, expected.traderDstAddress) || hashes.length !== expected.secretHashes.length || hashes.some((hash, i) => !bytesEqual(hash, expected.secretHashes[i]))) {
|
|
1016
|
-
throw
|
|
1065
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver order payload does not match the validated quote/request");
|
|
1017
1066
|
}
|
|
1018
1067
|
}
|
|
1019
1068
|
function isPositiveInteger(value) {
|
|
@@ -1044,7 +1093,7 @@ function bytesToHex(bytes) {
|
|
|
1044
1093
|
function hexToBytes(hex) {
|
|
1045
1094
|
const clean = hex.replace(/^0x/, "");
|
|
1046
1095
|
if (!clean || !/^(?:[0-9a-fA-F]{2})+$/.test(clean)) {
|
|
1047
|
-
throw
|
|
1096
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed hex payload");
|
|
1048
1097
|
}
|
|
1049
1098
|
const out = new Uint8Array(clean.length / 2);
|
|
1050
1099
|
for (let i = 0; i < out.length; i++) out[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
@@ -1078,6 +1127,14 @@ function swapProtocols(v) {
|
|
|
1078
1127
|
for (const route of v.routes) for (const step of route.steps) for (const chunk of step.chunks) names.add(chunk.protocol);
|
|
1079
1128
|
return [...names];
|
|
1080
1129
|
}
|
|
1130
|
+
function rejectionReason(rejection) {
|
|
1131
|
+
return rejection === "quote timestamp out of range" ? "quote_expired" : "upstream_unavailable";
|
|
1132
|
+
}
|
|
1133
|
+
function rfqReason(outcome) {
|
|
1134
|
+
if (outcome.error) return outcome.errorReason;
|
|
1135
|
+
if (outcome.rejected) return rejectionReason(outcome.rejected);
|
|
1136
|
+
return outcome.answered ? "no_route" : "upstream_unavailable";
|
|
1137
|
+
}
|
|
1081
1138
|
function quoteRejection(q, update, acknowledgedRfqId, request, settlement) {
|
|
1082
1139
|
if (!q) return "empty quote";
|
|
1083
1140
|
if (!acknowledgedRfqId || update.rfqId !== acknowledgedRfqId || q.rfqId !== acknowledgedRfqId) return "quote for another RFQ";
|
|
@@ -1117,6 +1174,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1117
1174
|
const max = setTimeout(() => finish(latest), QUOTE_MAX_MS);
|
|
1118
1175
|
sub = stream.subscribe({
|
|
1119
1176
|
next: (event) => {
|
|
1177
|
+
if (event.$case === "ack" || event.$case === "quoteUpdated" || event.$case === "noQuote") outcome.answered = true;
|
|
1120
1178
|
if (event.$case === "ack") {
|
|
1121
1179
|
acknowledgedRfqId = event.value.rfqId || null;
|
|
1122
1180
|
} else if (event.$case === "quoteUpdated") {
|
|
@@ -1136,6 +1194,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1136
1194
|
},
|
|
1137
1195
|
error: (err) => {
|
|
1138
1196
|
outcome.error = String(err?.message ?? err).slice(0, 200);
|
|
1197
|
+
outcome.errorReason = venueReason(err);
|
|
1139
1198
|
finish(null);
|
|
1140
1199
|
},
|
|
1141
1200
|
complete: () => finish(latest)
|
|
@@ -1177,9 +1236,9 @@ function awaitSwapProgress(stream) {
|
|
|
1177
1236
|
}
|
|
1178
1237
|
var JETTON_TRANSFER_OP = 260734629;
|
|
1179
1238
|
function parseSwapPayload(payloadHex) {
|
|
1180
|
-
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw
|
|
1239
|
+
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap payload hex");
|
|
1181
1240
|
const roots = import_core3.Cell.fromBoc(import_buffer2.Buffer.from(payloadHex, "hex"));
|
|
1182
|
-
if (roots.length !== 1) throw
|
|
1241
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: swap payload must have one root");
|
|
1183
1242
|
const s = roots[0].beginParse();
|
|
1184
1243
|
const op = s.loadUint(32);
|
|
1185
1244
|
if (op !== JETTON_TRANSFER_OP) return { op, jettonTransfer: null };
|
|
@@ -1249,6 +1308,18 @@ function mapOrderStatus(order) {
|
|
|
1249
1308
|
return { state: "pending", depositReceived };
|
|
1250
1309
|
}
|
|
1251
1310
|
}
|
|
1311
|
+
var VERIFY_NOTES = /* @__PURE__ */ Symbol.for("@anywalletkit/protocol-swap2-omniston/verify-notes@1");
|
|
1312
|
+
var verifyNotes = (() => {
|
|
1313
|
+
const shared = globalThis[VERIFY_NOTES];
|
|
1314
|
+
if (shared && typeof shared.note === "function" && typeof shared.reasonOf === "function") return shared;
|
|
1315
|
+
const notes = (0, import_errors.refusalNotes)();
|
|
1316
|
+
try {
|
|
1317
|
+
Object.defineProperty(globalThis, VERIFY_NOTES, { value: notes });
|
|
1318
|
+
} catch {
|
|
1319
|
+
}
|
|
1320
|
+
return notes;
|
|
1321
|
+
})();
|
|
1322
|
+
var said = verifyNotes.note;
|
|
1252
1323
|
function omnistonProvider(opts = {}) {
|
|
1253
1324
|
opts = Object.freeze({ ...opts });
|
|
1254
1325
|
const apiUrl = opts.apiUrl ?? "wss://omni-ws.ston.fi";
|
|
@@ -1428,19 +1499,19 @@ function omnistonProvider(opts = {}) {
|
|
|
1428
1499
|
if (!bound.ok) {
|
|
1429
1500
|
if (bound.reason === "legacy-expired") {
|
|
1430
1501
|
trace("legacy-intent-expired", { where });
|
|
1431
|
-
throw
|
|
1502
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
1432
1503
|
}
|
|
1433
1504
|
trace("intent-mismatch", { where, field: bound.field });
|
|
1434
|
-
throw
|
|
1505
|
+
throw (0, import_errors.refusal)(mismatchReason(bound.field), `omniston: intent id does not match the quote it was issued for (${bound.field})`);
|
|
1435
1506
|
}
|
|
1436
1507
|
if (bound.legacy) trace("legacy-intent", { where });
|
|
1437
1508
|
if (!decoded.digest) {
|
|
1438
1509
|
trace("intent-mismatch", { where, field: "digest-missing" });
|
|
1439
|
-
throw
|
|
1510
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: this quote was issued before an update \u2014 request a fresh quote");
|
|
1440
1511
|
}
|
|
1441
1512
|
if (decoded.digest !== quoteDigest(entry.quote)) {
|
|
1442
1513
|
trace("intent-mismatch", { where, field: "digest" });
|
|
1443
|
-
throw
|
|
1514
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: quote was replaced \u2014 request a fresh quote");
|
|
1444
1515
|
}
|
|
1445
1516
|
return bound.ref;
|
|
1446
1517
|
}
|
|
@@ -1474,10 +1545,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1474
1545
|
const disclosed = (await store.load(disclosedKey(quoteId)) ?? []).length > 0;
|
|
1475
1546
|
if (boundTo !== binding || disclosed) {
|
|
1476
1547
|
traceFor(quoteId)("secret-reuse-refused", { disclosed, bound: boundTo !== void 0 });
|
|
1477
|
-
throw
|
|
1548
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: this quote id already belongs to another order \u2014 request a fresh quote");
|
|
1478
1549
|
}
|
|
1479
1550
|
if (existing.length !== count || !existing.every((s) => /^[0-9a-fA-F]{64}$/.test(s))) {
|
|
1480
|
-
throw
|
|
1551
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: stored HTLC secrets for this quote do not fit the order \u2014 request a fresh quote");
|
|
1481
1552
|
}
|
|
1482
1553
|
traceFor(quoteId)("secret-reused", { count });
|
|
1483
1554
|
return { secrets: existing.map(hexToBytes), created: false };
|
|
@@ -1536,7 +1607,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1536
1607
|
let q = await rfq(slippagePips);
|
|
1537
1608
|
if (!q) {
|
|
1538
1609
|
if (!signal?.aborted) {
|
|
1539
|
-
|
|
1610
|
+
const text = `omniston: ${outcome.error ? `RFQ failed: ${outcome.error}` : outcome.rejected ? `swap quote rejected: ${outcome.rejected}` : "no TON DEX route quoted this pair/amount"}`;
|
|
1611
|
+
const reason = rfqReason(outcome);
|
|
1612
|
+
if (reason) params.onRefusal?.(text, { reason });
|
|
1613
|
+
else params.onRefusal?.(text);
|
|
1540
1614
|
}
|
|
1541
1615
|
return null;
|
|
1542
1616
|
}
|
|
@@ -1602,27 +1676,32 @@ function omnistonProvider(opts = {}) {
|
|
|
1602
1676
|
async function buildSwapDeposit(ref, q, swap) {
|
|
1603
1677
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
1604
1678
|
if (!isTon(ref.srcChain) || q.inputAsset.chain.$case !== "ton" || q.outputAsset.chain.$case !== "ton") {
|
|
1605
|
-
throw
|
|
1679
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: swap quote is not a TON same-chain swap");
|
|
1606
1680
|
}
|
|
1607
|
-
if (!sameChainTonReady()) throw
|
|
1681
|
+
if (!sameChainTonReady()) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON same-chain swaps need independent jetton-wallet, swap-target and swap-leg validators");
|
|
1608
1682
|
const owner = { chain: { $case: "ton", value: ref.trader } };
|
|
1609
1683
|
const receiver = { chain: { $case: "ton", value: ref.dest } };
|
|
1610
1684
|
const omni = await getClient();
|
|
1611
|
-
if (typeof omni.tonBuildSwap !== "function") throw
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1685
|
+
if (typeof omni.tonBuildSwap !== "function") throw (0, import_errors.refusal)("unsupported_pair", "omniston: client does not support swap settlement (tonBuildSwap)");
|
|
1686
|
+
let tx;
|
|
1687
|
+
try {
|
|
1688
|
+
tx = await omni.tonBuildSwap({
|
|
1689
|
+
quoteId: ref.quoteId,
|
|
1690
|
+
transferSrcAddress: owner,
|
|
1691
|
+
refundSrcAddress: owner,
|
|
1692
|
+
gasExcessAddress: owner,
|
|
1693
|
+
traderDstAddress: receiver,
|
|
1694
|
+
// Build at the slippage the quote was requested with: its
|
|
1695
|
+
// minOutputAmount is the minimum this module reported to the router.
|
|
1696
|
+
useRecommendedSlippage: false
|
|
1697
|
+
});
|
|
1698
|
+
} catch (error) {
|
|
1699
|
+
throw venueFailure(error);
|
|
1700
|
+
}
|
|
1622
1701
|
const [message, ...rest] = tx.messages;
|
|
1623
|
-
if (!message || rest.length > 0) throw
|
|
1624
|
-
if (message.jettonWalletStateInit) throw
|
|
1625
|
-
if (!isPositiveInteger(message.sendAmount)) throw
|
|
1702
|
+
if (!message || rest.length > 0) throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one swap message, got ${tx.messages.length}`);
|
|
1703
|
+
if (message.jettonWalletStateInit) throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
1704
|
+
if (!isPositiveInteger(message.sendAmount)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap message value");
|
|
1626
1705
|
const sendAmount = BigInt(message.sendAmount);
|
|
1627
1706
|
const gasCap = BigInt(maxTonExecutionNano);
|
|
1628
1707
|
const gasBudget = q.gasBudget && isPositiveInteger(q.gasBudget) ? BigInt(q.gasBudget) : gasCap;
|
|
@@ -1634,53 +1713,53 @@ function omnistonProvider(opts = {}) {
|
|
|
1634
1713
|
const ptonV1Native = !inputJetton && !!payload.jettonTransfer && singleV1;
|
|
1635
1714
|
if (inputJetton) {
|
|
1636
1715
|
const transfer = payload.jettonTransfer;
|
|
1637
|
-
if (!transfer) throw
|
|
1638
|
-
if (sendAmount > gasCap || sendAmount > gasBudget) throw
|
|
1639
|
-
if (transfer.amount !== BigInt(q.inputUnits)) throw
|
|
1716
|
+
if (!transfer) throw (0, import_errors.refusal)("policy_refused", "omniston: jetton-input swap message is not a jetton transfer");
|
|
1717
|
+
if (sendAmount > gasCap || sendAmount > gasBudget) throw (0, import_errors.refusal)("policy_refused", `omniston: swap message attaches more TON than the quoted gas budget (${sendAmount} > ${gasBudget} nanoTON, cap ${gasCap}, ${protocols.join("+")})`);
|
|
1718
|
+
if (transfer.amount !== BigInt(q.inputUnits)) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
1640
1719
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1641
|
-
throw
|
|
1720
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1642
1721
|
}
|
|
1643
|
-
if (transfer.forwardTon >= sendAmount) throw
|
|
1722
|
+
if (transfer.forwardTon >= sendAmount) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than it carries");
|
|
1644
1723
|
const walletValid = await opts.validateTonJettonWallet({
|
|
1645
1724
|
ownerAddress: ref.trader,
|
|
1646
1725
|
jettonMasterAddress: inputJetton,
|
|
1647
1726
|
walletAddress: message.targetAddress
|
|
1648
1727
|
});
|
|
1649
|
-
if (!walletValid) throw
|
|
1728
|
+
if (!walletValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
1650
1729
|
const targetValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1651
|
-
if (!targetValid) throw
|
|
1730
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1652
1731
|
} else if (ptonV1Native) {
|
|
1653
1732
|
const transfer = payload.jettonTransfer;
|
|
1654
1733
|
const input = BigInt(q.inputUnits);
|
|
1655
|
-
if (transfer.amount !== input) throw
|
|
1656
|
-
if (sendAmount < input) throw
|
|
1734
|
+
if (transfer.amount !== input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
1735
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1657
1736
|
const gas = sendAmount - input;
|
|
1658
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
1659
|
-
if (transfer.forwardTon > gas) throw
|
|
1737
|
+
if (gas > gasCap || gas > gasBudget) throw (0, import_errors.refusal)("policy_refused", `omniston: swap message attaches more TON than the quoted gas budget (${gas} > ${gasBudget} nanoTON, cap ${gasCap}, ${protocols.join("+")})`);
|
|
1738
|
+
if (transfer.forwardTon > gas) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than its gas");
|
|
1660
1739
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1661
|
-
throw
|
|
1740
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1662
1741
|
}
|
|
1663
|
-
if (typeof opts.validateTonSwapLeg !== "function") throw
|
|
1742
|
+
if (typeof opts.validateTonSwapLeg !== "function") throw (0, import_errors.refusal)("unsupported_pair", "omniston: STON.fi v1 native input needs the validateTonSwapLeg validator (pTON v1 wallet ownership)");
|
|
1664
1743
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1665
|
-
if (!targetValid) throw
|
|
1744
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1666
1745
|
const routerValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1667
|
-
if (!routerValid) throw
|
|
1746
|
+
if (!routerValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1668
1747
|
} else {
|
|
1669
1748
|
if (payload.jettonTransfer) {
|
|
1670
|
-
throw
|
|
1749
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: native-input swap message must not be a jetton transfer (route ${protocols.join("+") || "?"}, target ${message.targetAddress}, transfer ${payload.jettonTransfer.amount} to ${payload.jettonTransfer.destination}, forwardTon ${payload.jettonTransfer.forwardTon}, value ${sendAmount})`);
|
|
1671
1750
|
}
|
|
1672
1751
|
const input = BigInt(q.inputUnits);
|
|
1673
|
-
if (sendAmount < input) throw
|
|
1752
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1674
1753
|
const gas = sendAmount - input;
|
|
1675
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
1754
|
+
if (gas > gasCap || gas > gasBudget) throw (0, import_errors.refusal)("policy_refused", `omniston: swap message attaches more TON than the quoted gas budget (${gas} > ${gasBudget} nanoTON, cap ${gasCap}, ${protocols.join("+")})`);
|
|
1676
1755
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1677
|
-
if (!targetValid) throw
|
|
1756
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1678
1757
|
}
|
|
1679
1758
|
const mode = ptonV1Native ? "enforce" : opts.tonSwapPayloadCheck ?? "enforce";
|
|
1680
1759
|
const trace = traceFor(ref.quoteId);
|
|
1681
1760
|
const payloadRefusal = (reason, detail) => {
|
|
1682
1761
|
trace("ton-swap-payload", { reason, detail, mode, protocols: protocols.join("+") });
|
|
1683
|
-
if (mode === "enforce") throw
|
|
1762
|
+
if (mode === "enforce") throw (0, import_errors.refusal)(tonSwapPayloadReason(reason), `omniston: ton-swap-payload ${reason} \u2014 ${detail}`);
|
|
1684
1763
|
};
|
|
1685
1764
|
let checked = null;
|
|
1686
1765
|
try {
|
|
@@ -1754,33 +1833,33 @@ function omnistonProvider(opts = {}) {
|
|
|
1754
1833
|
const srcChain = ref.srcChain;
|
|
1755
1834
|
const chainId = evmRef2(srcChain);
|
|
1756
1835
|
const srcCase = q.inputAsset.chain.$case;
|
|
1757
|
-
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw
|
|
1836
|
+
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match the EVM quote");
|
|
1758
1837
|
const destCase = q.outputAsset.chain.$case;
|
|
1759
1838
|
const destChain = caipForChainCase(destCase);
|
|
1760
1839
|
const tonDest = destCase === "ton";
|
|
1761
|
-
if (!destChain || destChain === srcChain) throw
|
|
1840
|
+
if (!destChain || destChain === srcChain) throw (0, import_errors.refusal)("unsupported_pair", "omniston: EVM-source order has no supported destination chain");
|
|
1762
1841
|
if (!trustedOrderProtocols.has(srcChain) || typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
1763
|
-
throw
|
|
1842
|
+
throw (0, import_errors.refusal)("unsupported_pair", `omniston: EVM\u2192${tonDest ? "TON" : "EVM"} needs a trusted order protocol and both position validators`);
|
|
1764
1843
|
}
|
|
1765
1844
|
let owner;
|
|
1766
1845
|
try {
|
|
1767
1846
|
owner = (0, import_viem.getAddress)(ref.trader);
|
|
1768
1847
|
} catch {
|
|
1769
|
-
throw
|
|
1848
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: trader is not an EVM address");
|
|
1770
1849
|
}
|
|
1771
1850
|
let dest;
|
|
1772
1851
|
if (tonDest) {
|
|
1773
1852
|
try {
|
|
1774
1853
|
import_core3.Address.parse(ref.dest);
|
|
1775
1854
|
} catch {
|
|
1776
|
-
throw
|
|
1855
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not a TON address");
|
|
1777
1856
|
}
|
|
1778
1857
|
dest = ref.dest;
|
|
1779
1858
|
} else {
|
|
1780
1859
|
try {
|
|
1781
1860
|
dest = (0, import_viem.getAddress)(ref.dest);
|
|
1782
1861
|
} catch {
|
|
1783
|
-
throw
|
|
1862
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not an EVM address");
|
|
1784
1863
|
}
|
|
1785
1864
|
}
|
|
1786
1865
|
const traderDst = { chain: { $case: destCase, value: dest } };
|
|
@@ -1791,9 +1870,9 @@ function omnistonProvider(opts = {}) {
|
|
|
1791
1870
|
const outputToken = assetContract(q.outputAsset);
|
|
1792
1871
|
const destChainId = tonDest ? null : evmRef2(destChain);
|
|
1793
1872
|
if (factory?.chain.$case === destCase && !isTrusted(destChain, factory.chain.value)) {
|
|
1794
|
-
throw
|
|
1873
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted ${destChain} settlement contract ${factory.chain.value}`);
|
|
1795
1874
|
}
|
|
1796
|
-
if (protocol.chain.$case !== srcCase || !isTrustedOrderProtocol(srcChain, protocol.chain.value) || resolver?.chain.$case !== srcCase || !validEvmAddress(resolver.chain.value) || factory?.chain.$case !== destCase || !isTrusted(destChain, factory.chain.value) || !inputToken || !outputToken || !Number.isSafeInteger(settlement.protocolFeePips) || !tonDest && (destChainId === null || !validEvmAddress(outputToken) || !isPositiveInteger(settlement.dstSecurityDepositUnits ?? ""))) throw
|
|
1875
|
+
if (protocol.chain.$case !== srcCase || !isTrustedOrderProtocol(srcChain, protocol.chain.value) || resolver?.chain.$case !== srcCase || !validEvmAddress(resolver.chain.value) || factory?.chain.$case !== destCase || !isTrusted(destChain, factory.chain.value) || !inputToken || !outputToken || !Number.isSafeInteger(settlement.protocolFeePips) || !tonDest && (destChainId === null || !validEvmAddress(outputToken) || !isPositiveInteger(settlement.dstSecurityDepositUnits ?? ""))) throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete EVM order settlement binding in quote");
|
|
1797
1876
|
const { secrets, created } = await secretsFor(ref, q, 1);
|
|
1798
1877
|
const hashes = secrets.map((secret) => hashlock(secret, settlement.htlcHashingFunction));
|
|
1799
1878
|
const forget = async () => {
|
|
@@ -1810,14 +1889,14 @@ function omnistonProvider(opts = {}) {
|
|
|
1810
1889
|
});
|
|
1811
1890
|
} catch (error) {
|
|
1812
1891
|
await forget();
|
|
1813
|
-
throw error;
|
|
1892
|
+
throw venueFailure(error);
|
|
1814
1893
|
}
|
|
1815
1894
|
let td;
|
|
1816
1895
|
try {
|
|
1817
1896
|
try {
|
|
1818
1897
|
td = JSON.parse(payload.typedData);
|
|
1819
1898
|
} catch {
|
|
1820
|
-
throw
|
|
1899
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order typed data");
|
|
1821
1900
|
}
|
|
1822
1901
|
validateSerializedOrderDetails(payload.serializedOrderDetails, {
|
|
1823
1902
|
quoteId: ref.quoteId,
|
|
@@ -1900,45 +1979,46 @@ function omnistonProvider(opts = {}) {
|
|
|
1900
1979
|
async getQuote(params, signal) {
|
|
1901
1980
|
if (params.flex) return null;
|
|
1902
1981
|
if (isTon(params.sourceChain) && isTon(params.destChain)) return await getSwapQuote(params, signal);
|
|
1903
|
-
const refuse2 = (reason) => {
|
|
1904
|
-
params.onRefusal?.(`omniston: ${reason}
|
|
1982
|
+
const refuse2 = (reason, why) => {
|
|
1983
|
+
if (why) params.onRefusal?.(`omniston: ${reason}`, { reason: why });
|
|
1984
|
+
else params.onRefusal?.(`omniston: ${reason}`);
|
|
1905
1985
|
return null;
|
|
1906
1986
|
};
|
|
1907
1987
|
const evmSource = !isTon(params.sourceChain);
|
|
1908
1988
|
const tonDest = isTon(params.destChain);
|
|
1909
|
-
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor");
|
|
1989
|
+
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor", "unsupported_pair");
|
|
1910
1990
|
if (!trustedContracts.has(params.sourceChain) || !trustedContracts.has(params.destChain)) {
|
|
1911
|
-
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}
|
|
1991
|
+
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}`, "unsupported_pair");
|
|
1912
1992
|
}
|
|
1913
1993
|
if (evmSource) {
|
|
1914
|
-
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}
|
|
1994
|
+
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}`, "unsupported_pair");
|
|
1915
1995
|
if (typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
1916
|
-
return refuse2(tonDest ? "EVM\u2192TON needs the EVM input-position and TON output-position validators" : "EVM\u2192EVM needs the EVM input-position and EVM output-position validators");
|
|
1996
|
+
return refuse2(tonDest ? "EVM\u2192TON needs the EVM input-position and TON output-position validators" : "EVM\u2192EVM needs the EVM input-position and EVM output-position validators", "unsupported_pair");
|
|
1917
1997
|
}
|
|
1918
1998
|
if (params.dry === false) {
|
|
1919
1999
|
if (tonDest) {
|
|
1920
2000
|
try {
|
|
1921
2001
|
import_core3.Address.parse(params.destAddress);
|
|
1922
2002
|
} catch {
|
|
1923
|
-
return refuse2("destination is not a TON address");
|
|
2003
|
+
return refuse2("destination is not a TON address", "recipient_mismatch");
|
|
1924
2004
|
}
|
|
1925
|
-
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address");
|
|
2005
|
+
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address", "recipient_mismatch");
|
|
1926
2006
|
}
|
|
1927
|
-
} else if (typeof opts.validateTonJettonWallet !== "function" || typeof opts.validateTonEscrowPayload !== "function" || typeof opts.validateEvmOutputPosition !== "function") return refuse2("TON\u2192EVM needs the jetton-wallet, escrow-payload and EVM output-position validators");
|
|
2007
|
+
} else if (typeof opts.validateTonJettonWallet !== "function" || typeof opts.validateTonEscrowPayload !== "function" || typeof opts.validateEvmOutputPosition !== "function") return refuse2("TON\u2192EVM needs the jetton-wallet, escrow-payload and EVM output-position validators", "unsupported_pair");
|
|
1928
2008
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1929
2009
|
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
1930
|
-
if (!source || !dest) return refuse2("asset is not in the catalog");
|
|
2010
|
+
if (!source || !dest) return refuse2("asset is not in the catalog", "unsupported_pair");
|
|
1931
2011
|
const inputAsset = toAssetId(params.sourceChain, source);
|
|
1932
2012
|
const outputAsset = toAssetId(params.destChain, dest);
|
|
1933
2013
|
if (!inputAsset || !outputAsset) {
|
|
1934
|
-
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)
|
|
2014
|
+
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)`, "unsupported_pair");
|
|
1935
2015
|
}
|
|
1936
2016
|
const maxUnits = decimalToUnits(maxUsdText, source.decimals);
|
|
1937
2017
|
if (!maxUnits || !isPositiveInteger(params.amountIn)) return refuse2("invalid amount");
|
|
1938
|
-
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap
|
|
2018
|
+
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap`, "amount_too_large");
|
|
1939
2019
|
const trader = params.refundAddress ?? "";
|
|
1940
2020
|
if (!trader && !params.dry) return refuse2(`execution quote needs the trader's ${evmSource ? "EVM" : "TON"} address (refundAddress)`);
|
|
1941
|
-
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address");
|
|
2021
|
+
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address", "recipient_mismatch");
|
|
1942
2022
|
const request = {
|
|
1943
2023
|
inputAsset,
|
|
1944
2024
|
outputAsset,
|
|
@@ -1966,27 +2046,28 @@ function omnistonProvider(opts = {}) {
|
|
|
1966
2046
|
if (!q) {
|
|
1967
2047
|
if (signal?.aborted) return null;
|
|
1968
2048
|
return refuse2(
|
|
1969
|
-
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount"
|
|
2049
|
+
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount",
|
|
2050
|
+
rfqReason(rfq)
|
|
1970
2051
|
);
|
|
1971
2052
|
}
|
|
1972
2053
|
const orderData = q.settlementData.$case === "order" ? q.settlementData.value : null;
|
|
1973
|
-
if (!orderData) return refuse2("resolver answered without order settlement");
|
|
2054
|
+
if (!orderData) return refuse2("resolver answered without order settlement", "upstream_unavailable");
|
|
1974
2055
|
const srcContract = orderData.srcProtocolContractAddress.chain.value;
|
|
1975
2056
|
if (evmSource ? !isTrustedOrderProtocol(params.sourceChain, srcContract) : !isTrusted(params.sourceChain, srcContract)) {
|
|
1976
|
-
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}
|
|
2057
|
+
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}`, "vault_mismatch");
|
|
1977
2058
|
}
|
|
1978
2059
|
if (!orderData.dstProtocolContractAddress || !isTrusted(params.destChain, orderData.dstProtocolContractAddress.chain.value)) {
|
|
1979
|
-
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}
|
|
2060
|
+
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}`, "vault_mismatch");
|
|
1980
2061
|
}
|
|
1981
2062
|
const deadlineMs = orderData.tradeStartDeadline * 1e3;
|
|
1982
|
-
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed");
|
|
1983
|
-
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute");
|
|
2063
|
+
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed", "quote_expired");
|
|
2064
|
+
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute", "quote_expired");
|
|
1984
2065
|
const inputScaled = BigInt(q.inputUnits) * 10n ** BigInt(dest.decimals);
|
|
1985
2066
|
const outputScaled = BigInt(q.outputUnits) * 10n ** BigInt(source.decimals);
|
|
1986
|
-
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input");
|
|
1987
|
-
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order");
|
|
2067
|
+
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input", "price_check_failed");
|
|
2068
|
+
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order", "policy_refused");
|
|
1988
2069
|
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "order" } })) {
|
|
1989
|
-
return refuse2("the platform reused a quote id that already holds another quote");
|
|
2070
|
+
return refuse2("the platform reused a quote id that already holds another quote", "policy_refused");
|
|
1990
2071
|
}
|
|
1991
2072
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
1992
2073
|
const feeUsd = feeUnits / 10 ** dest.decimals;
|
|
@@ -2017,29 +2098,29 @@ function omnistonProvider(opts = {}) {
|
|
|
2017
2098
|
*/
|
|
2018
2099
|
async buildDeposit(quote) {
|
|
2019
2100
|
if (!Number.isFinite(quote.validUntilMs) || quote.validUntilMs <= Date.now()) {
|
|
2020
|
-
throw
|
|
2101
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2021
2102
|
}
|
|
2022
2103
|
const decoded = decodeIntent(quote.intentId);
|
|
2023
2104
|
if (!decoded) throw new Error("omniston: malformed intent id");
|
|
2024
2105
|
const cached = await loadBuilt(decoded.quoteId);
|
|
2025
|
-
if (!cached) throw
|
|
2106
|
+
if (!cached) throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2026
2107
|
const ref = requireBinding(decoded, cached, "buildDeposit");
|
|
2027
2108
|
const q = cached.quote;
|
|
2028
2109
|
if (q.settlementData.$case === "swap") return await buildSwapDeposit(ref, q, q.settlementData.value);
|
|
2029
2110
|
if (q.settlementData.$case !== "order" || q.settlementData.value.tradeStartDeadline * 1e3 <= Date.now()) {
|
|
2030
|
-
throw
|
|
2111
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote trade deadline expired \u2014 request a fresh quote");
|
|
2031
2112
|
}
|
|
2032
2113
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
2033
2114
|
const srcCase = q.inputAsset.chain.$case;
|
|
2034
2115
|
if (srcCase !== "ton") return await buildEvmOrder(ref, q, q.settlementData.value, cached.bound);
|
|
2035
2116
|
const srcChain = ref.srcChain;
|
|
2036
|
-
if (!isTon(srcChain)) throw
|
|
2117
|
+
if (!isTon(srcChain)) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match TON quote");
|
|
2037
2118
|
const destCase = q.outputAsset.chain.$case;
|
|
2038
2119
|
const traderDst = destCase === "ton" ? null : { chain: { $case: destCase, value: (0, import_viem.getAddress)(ref.dest) } };
|
|
2039
|
-
if (!traderDst) throw
|
|
2120
|
+
if (!traderDst) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON-destination orders are not supported");
|
|
2040
2121
|
const minter = q.settlementData.value.srcProtocolContractAddress;
|
|
2041
2122
|
if (minter.chain.$case !== "ton" || !isTrusted(srcChain, minter.chain.value)) {
|
|
2042
|
-
throw
|
|
2123
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted TON settlement contract ${minter.chain.value}`);
|
|
2043
2124
|
}
|
|
2044
2125
|
const settlement = q.settlementData;
|
|
2045
2126
|
const hashingFunction = settlement.$case === "order" ? settlement.value.htlcHashingFunction : void 0;
|
|
@@ -2063,27 +2144,27 @@ function omnistonProvider(opts = {}) {
|
|
|
2063
2144
|
});
|
|
2064
2145
|
} catch (error) {
|
|
2065
2146
|
await forget();
|
|
2066
|
-
throw error;
|
|
2147
|
+
throw venueFailure(error);
|
|
2067
2148
|
}
|
|
2068
2149
|
const [message, ...rest] = tx.messages;
|
|
2069
2150
|
if (!message || rest.length > 0) {
|
|
2070
2151
|
await forget();
|
|
2071
|
-
throw
|
|
2152
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one escrow message, got ${tx.messages.length}`);
|
|
2072
2153
|
}
|
|
2073
2154
|
if (!isPositiveInteger(message.sendAmount) || BigInt(message.sendAmount) > BigInt(maxTonExecutionNano)) {
|
|
2074
2155
|
await forget();
|
|
2075
|
-
throw
|
|
2156
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver TON execution value exceeds the configured safety cap");
|
|
2076
2157
|
}
|
|
2077
2158
|
const expectedProtocol = q.settlementData.value.srcProtocolContractAddress;
|
|
2078
2159
|
const initialResolver = q.settlementData.value.srcInitialResolverAddress;
|
|
2079
2160
|
const jettonMaster = assetContract(q.inputAsset);
|
|
2080
2161
|
if (expectedProtocol.chain.$case !== "ton" || initialResolver?.chain.$case !== "ton" || !jettonMaster) {
|
|
2081
2162
|
await forget();
|
|
2082
|
-
throw
|
|
2163
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete TON settlement binding in quote");
|
|
2083
2164
|
}
|
|
2084
2165
|
if (message.jettonWalletStateInit) {
|
|
2085
2166
|
await forget();
|
|
2086
|
-
throw
|
|
2167
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
2087
2168
|
}
|
|
2088
2169
|
let walletValid = false;
|
|
2089
2170
|
try {
|
|
@@ -2098,11 +2179,11 @@ function omnistonProvider(opts = {}) {
|
|
|
2098
2179
|
}
|
|
2099
2180
|
if (!walletValid) {
|
|
2100
2181
|
await forget();
|
|
2101
|
-
throw
|
|
2182
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
2102
2183
|
}
|
|
2103
2184
|
try {
|
|
2104
2185
|
if (!opts.validateTonEscrowPayload) {
|
|
2105
|
-
throw
|
|
2186
|
+
throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON source requires an independent escrow-payload validator");
|
|
2106
2187
|
}
|
|
2107
2188
|
await validateTonEscrowPayload(message, {
|
|
2108
2189
|
quoteId: ref.quoteId,
|
|
@@ -2149,7 +2230,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2149
2230
|
const result = bindIntent(decoded, stored);
|
|
2150
2231
|
if (!result.ok && result.reason === "mismatch") {
|
|
2151
2232
|
trace("intent-mismatch", { where: "trackIntent", field: result.field });
|
|
2152
|
-
throw
|
|
2233
|
+
throw (0, import_errors.refusal)(mismatchReason(result.field), `omniston: intent id does not match the quote it was issued for (${result.field})`);
|
|
2153
2234
|
}
|
|
2154
2235
|
if (result.ok) {
|
|
2155
2236
|
if (result.legacy) trace("legacy-intent", { where: "trackIntent" });
|
|
@@ -2329,12 +2410,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2329
2410
|
if (!ref) throw new Error("omniston: malformed intent id");
|
|
2330
2411
|
const cached = await loadBuilt(ref.quoteId);
|
|
2331
2412
|
const order = cached?.evmOrder;
|
|
2332
|
-
if (!order) throw
|
|
2413
|
+
if (!order) throw (0, import_errors.refusal)("quote_expired", "omniston: no signed-order context for this quote \u2014 build the order again");
|
|
2333
2414
|
requireBinding(ref, cached, "registerSignedOrder");
|
|
2334
2415
|
if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) throw new Error("omniston: malformed order signature");
|
|
2335
2416
|
const td = JSON.parse(order.typedData);
|
|
2336
2417
|
const omni = await getClient();
|
|
2337
|
-
|
|
2418
|
+
const request = {
|
|
2338
2419
|
quoteId: ref.quoteId,
|
|
2339
2420
|
ownerSrcAddress: { chain: { $case: order.chainCase, value: order.owner } },
|
|
2340
2421
|
signedOrder: { order: { $case: "evmV1", value: {
|
|
@@ -2343,7 +2424,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2343
2424
|
orderExtension: hexToBytes(order.orderExtension)
|
|
2344
2425
|
} } },
|
|
2345
2426
|
...order.serializedOrderDetails ? { serializedOrderDetails: hexToBytes(order.serializedOrderDetails) } : {}
|
|
2346
|
-
}
|
|
2427
|
+
};
|
|
2428
|
+
try {
|
|
2429
|
+
await omni.orderRegisterSignedOrder(request);
|
|
2430
|
+
} catch (error) {
|
|
2431
|
+
throw venueFailure(error);
|
|
2432
|
+
}
|
|
2347
2433
|
},
|
|
2348
2434
|
close() {
|
|
2349
2435
|
clientGeneration += 1;
|