@anywalletkit/protocol-swap2-omniston 0.5.5 → 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/provider.cjs
CHANGED
|
@@ -502,6 +502,7 @@ var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
|
|
|
502
502
|
};
|
|
503
503
|
|
|
504
504
|
// src/provider.ts
|
|
505
|
+
var import_errors = require("@anywalletkit/protocol-swap2-core/errors");
|
|
505
506
|
var import_core4 = require("@anywalletkit/core");
|
|
506
507
|
var EVM_CASE = {
|
|
507
508
|
1: "ethereum",
|
|
@@ -639,6 +640,54 @@ function encodeTypedMessage(td) {
|
|
|
639
640
|
(0, import_viem.encodeAbiParameters)([paramFor(td.primaryType)], [td.message])
|
|
640
641
|
);
|
|
641
642
|
}
|
|
643
|
+
function venueReason(error) {
|
|
644
|
+
const details = typeof error === "object" && error !== null ? error.details : void 0;
|
|
645
|
+
const info = typeof details === "object" && details !== null ? details.error_info : void 0;
|
|
646
|
+
if (typeof info !== "object" || info === null) return "upstream_unavailable";
|
|
647
|
+
const { reason, metadata } = info;
|
|
648
|
+
const meta = typeof metadata === "object" && metadata !== null ? metadata : {};
|
|
649
|
+
const type = typeof meta.type === "string" ? meta.type : "";
|
|
650
|
+
switch (reason) {
|
|
651
|
+
case "INVALID_ARGUMENT":
|
|
652
|
+
case "INVALID_PARAMETERS":
|
|
653
|
+
return void 0;
|
|
654
|
+
case "NOT_FOUND":
|
|
655
|
+
return typeof meta.object_type === "string" && meta.object_type.toLowerCase() === "quote" ? "quote_expired" : "upstream_unavailable";
|
|
656
|
+
case "UNSUPPORTED":
|
|
657
|
+
return "unsupported_pair";
|
|
658
|
+
case "SWAP_LIMIT_EXCEEDED":
|
|
659
|
+
return "amount_too_large";
|
|
660
|
+
case "QUOTE_VALIDATION_FAILED":
|
|
661
|
+
if (type === "EMULATION_UNSUPPORTED_TOKEN") return "unsupported_pair";
|
|
662
|
+
if (type === "EMULATION_WRONG_OUTPUT_AMOUNT" || type === "EMULATION_REFUND_SLIPPAGE") return "price_check_failed";
|
|
663
|
+
return type.startsWith("EMULATION_") ? "simulation_failed" : "upstream_unavailable";
|
|
664
|
+
default:
|
|
665
|
+
return "upstream_unavailable";
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
function venueFailure(error) {
|
|
669
|
+
if (!(error instanceof Error)) return error;
|
|
670
|
+
const reason = venueReason(error);
|
|
671
|
+
return reason ? (0, import_errors.withReason)(error, reason) : error;
|
|
672
|
+
}
|
|
673
|
+
function mismatchReason(field) {
|
|
674
|
+
return field === "trader" || field === "dest" || field === "owner" ? "recipient_mismatch" : "policy_refused";
|
|
675
|
+
}
|
|
676
|
+
function tonSwapPayloadReason(code) {
|
|
677
|
+
switch (code) {
|
|
678
|
+
case "receiver-not-destination":
|
|
679
|
+
case "refund-not-trader":
|
|
680
|
+
case "excess-not-trader":
|
|
681
|
+
return "recipient_mismatch";
|
|
682
|
+
case "min-out-zero":
|
|
683
|
+
case "min-out-below-quote":
|
|
684
|
+
return "price_check_failed";
|
|
685
|
+
case "leg-unverified":
|
|
686
|
+
return "vault_mismatch";
|
|
687
|
+
default:
|
|
688
|
+
return "policy_refused";
|
|
689
|
+
}
|
|
690
|
+
}
|
|
642
691
|
function generateSecret() {
|
|
643
692
|
return crypto.getRandomValues(new Uint8Array(32));
|
|
644
693
|
}
|
|
@@ -649,7 +698,7 @@ function hashlock(secret, hashingFunction) {
|
|
|
649
698
|
case "HASHING_FUNCTION_SHA256":
|
|
650
699
|
return (0, import_viem.sha256)(secret, "bytes");
|
|
651
700
|
default:
|
|
652
|
-
throw
|
|
701
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: unsupported HTLC hashing function ${String(hashingFunction)}`);
|
|
653
702
|
}
|
|
654
703
|
}
|
|
655
704
|
function sameAsset(a, b) {
|
|
@@ -687,7 +736,7 @@ function stepJetton(asset) {
|
|
|
687
736
|
}
|
|
688
737
|
function readBigEndian(bytes, offset, length) {
|
|
689
738
|
if (!Number.isInteger(offset) || !Number.isInteger(length) || length < 1 || offset < 0 || offset + length > bytes.length) {
|
|
690
|
-
throw
|
|
739
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: truncated EVM order extension");
|
|
691
740
|
}
|
|
692
741
|
let value = 0n;
|
|
693
742
|
for (let index = offset; index < offset + length; index++) value = value << 8n | BigInt(bytes[index]);
|
|
@@ -732,30 +781,30 @@ var EVM_DEST_PROTOCOL_FEE_RECIPIENTS = /* @__PURE__ */ new Set(["0x076268146b4ec
|
|
|
732
781
|
var EVM_AUCTION_POINTS = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
|
|
733
782
|
var EVM_TIMELOCKS = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
|
|
734
783
|
function readEvmOrderExtension(extension) {
|
|
735
|
-
if (extension.length < 32) throw
|
|
784
|
+
if (extension.length < 32) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension");
|
|
736
785
|
const view = new DataView(extension.buffer, extension.byteOffset, extension.byteLength);
|
|
737
786
|
const fields = [];
|
|
738
787
|
let begin = 0;
|
|
739
788
|
const concatLength = extension.length - 32;
|
|
740
789
|
for (let index = 0; index < 8; index++) {
|
|
741
790
|
const end2 = view.getUint32(28 - index * 4, false);
|
|
742
|
-
if (end2 < begin || end2 > concatLength) throw
|
|
791
|
+
if (end2 < begin || end2 > concatLength) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension offsets");
|
|
743
792
|
fields.push(extension.slice(32 + begin, 32 + end2));
|
|
744
793
|
begin = end2;
|
|
745
794
|
}
|
|
746
795
|
for (const index of [0, 1, 4, 5, 6]) {
|
|
747
|
-
if (fields[index].length !== 0) throw
|
|
796
|
+
if (fields[index].length !== 0) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM order extension field");
|
|
748
797
|
}
|
|
749
798
|
if (!sliceEqual(fields[2], fields[3])) {
|
|
750
|
-
throw
|
|
799
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: making/taking amount getters use different programs");
|
|
751
800
|
}
|
|
752
801
|
let target;
|
|
753
802
|
for (const index of [2, 3, 7]) {
|
|
754
803
|
const field2 = fields[index];
|
|
755
|
-
if (field2.length <= 20) throw
|
|
804
|
+
if (field2.length <= 20) throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete EVM order extension program");
|
|
756
805
|
const address = (0, import_viem.getAddress)(`0x${bytesToHex(field2.slice(0, 20))}`);
|
|
757
806
|
if (target !== void 0 && (0, import_viem.getAddress)(target) !== address) {
|
|
758
|
-
throw
|
|
807
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
759
808
|
}
|
|
760
809
|
target = address;
|
|
761
810
|
}
|
|
@@ -773,7 +822,7 @@ function readEvmOrderExtension(extension) {
|
|
|
773
822
|
cursor += 3;
|
|
774
823
|
const pointCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
775
824
|
cursor += 1;
|
|
776
|
-
if (pointCount !== 5) throw
|
|
825
|
+
if (pointCount !== 5) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM auction profile");
|
|
777
826
|
const points = [];
|
|
778
827
|
for (let index = 0; index < pointCount; index++) {
|
|
779
828
|
points.push([readBigEndian(field, cursor, 3), readBigEndian(field, cursor + 3, 2)]);
|
|
@@ -790,7 +839,7 @@ function readEvmOrderExtension(extension) {
|
|
|
790
839
|
const getterWhitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
791
840
|
cursor += 1;
|
|
792
841
|
if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== field.length) {
|
|
793
|
-
throw
|
|
842
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM amount-getter whitelist");
|
|
794
843
|
}
|
|
795
844
|
const getter = { gasBump, gasPrice, auctionStart, duration, initialRateBump, points, integratorFee, integratorShare, resolverFee, whitelistDiscount, resolver: readBigEndian(field, cursor, 10) };
|
|
796
845
|
const post = fields[7];
|
|
@@ -812,7 +861,7 @@ function readEvmOrderExtension(extension) {
|
|
|
812
861
|
const whitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(post, cursor, 1));
|
|
813
862
|
cursor += 1;
|
|
814
863
|
if (whitelistCount !== 1 || cursor + whitelistCount * 12 + 160 !== post.length) {
|
|
815
|
-
throw
|
|
864
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM post-interaction whitelist");
|
|
816
865
|
}
|
|
817
866
|
const postResolver = readBigEndian(post, cursor, 10);
|
|
818
867
|
cursor += 10;
|
|
@@ -824,7 +873,7 @@ function readEvmOrderExtension(extension) {
|
|
|
824
873
|
return value;
|
|
825
874
|
});
|
|
826
875
|
const customData = extension.slice(32 + begin);
|
|
827
|
-
if (customData.length !== 131) throw
|
|
876
|
+
if (customData.length !== 131) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension custom data");
|
|
828
877
|
return {
|
|
829
878
|
target,
|
|
830
879
|
getter,
|
|
@@ -837,29 +886,29 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
837
886
|
const evmDest = expected.dstChainId !== void 0;
|
|
838
887
|
if (evmDest && (!Number.isSafeInteger(expected.dstChainId) || expected.dstChainId <= 0)) throw new Error("omniston: invalid EVM destination chain id");
|
|
839
888
|
const { target, getter, post, extra, customData } = readEvmOrderExtension(extension);
|
|
840
|
-
if (!expected.trustedTarget(target)) throw
|
|
889
|
+
if (!expected.trustedTarget(target)) throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
841
890
|
const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
|
|
842
891
|
const resolverLow80 = BigInt((0, import_viem.getAddress)(expected.initialResolverAddress)) & (1n << 80n) - 1n;
|
|
843
892
|
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) {
|
|
844
|
-
throw
|
|
893
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
|
|
845
894
|
}
|
|
846
895
|
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) {
|
|
847
|
-
throw
|
|
896
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
|
|
848
897
|
}
|
|
849
898
|
const hashlock2 = readBigEndian(expected.secretHash, 0, expected.secretHash.length);
|
|
850
899
|
const dstToken = evmDest ? BigInt((0, import_viem.getAddress)(expected.outputTokenAddress)) : BigInt((0, import_viem.getAddress)(expected.takerAsset));
|
|
851
900
|
const deposits = BigInt(expected.srcSecurityDepositUnits) << 128n | BigInt(expected.dstSecurityDepositUnits);
|
|
852
901
|
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) {
|
|
853
|
-
throw
|
|
902
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: signed EVM HTLC terms do not match the validated order details");
|
|
854
903
|
}
|
|
855
904
|
await checkOrderCustomData(customData, { evmDest, outputToken: expected.outputTokenAddress, traderDst: expected.traderDstAddress, quoteId: expected.quoteId });
|
|
856
905
|
if (expected.tradeStartDeadline < expected.quoteTimestamp) {
|
|
857
|
-
throw
|
|
906
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: invalid EVM order quote deadline");
|
|
858
907
|
}
|
|
859
908
|
}
|
|
860
909
|
async function checkOrderCustomData(customData, expected) {
|
|
861
910
|
if (expected.evmDest) {
|
|
862
|
-
if (!zeroBytes(customData.slice(0, 66))) throw
|
|
911
|
+
if (!zeroBytes(customData.slice(0, 66))) throw (0, import_errors.refusal)("recipient_mismatch", "omniston: unexpected TON addresses in an EVM-destination order");
|
|
863
912
|
} else {
|
|
864
913
|
const { Address: Address3 } = await import("@ton/core");
|
|
865
914
|
const expectedTon = [expected.outputToken, expected.traderDst].map((value) => Address3.parse(value));
|
|
@@ -867,16 +916,16 @@ async function checkOrderCustomData(customData, expected) {
|
|
|
867
916
|
const offset = index * 33;
|
|
868
917
|
const workchain = customData[offset] === 255 ? -1 : customData[offset];
|
|
869
918
|
if (workchain !== expectedTon[index].workChain || !sliceEqual(customData.slice(offset + 1, offset + 33), expectedTon[index].hash)) {
|
|
870
|
-
throw
|
|
919
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: signed EVM\u2192TON address does not match the validated request");
|
|
871
920
|
}
|
|
872
921
|
}
|
|
873
922
|
}
|
|
874
923
|
if (!zeroBytes(customData.slice(66, 99))) {
|
|
875
|
-
throw
|
|
924
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unexpected private TON disclosure address");
|
|
876
925
|
}
|
|
877
926
|
const quoteId = expected.quoteId.replace(/^0x/, "");
|
|
878
927
|
if (!QUOTE_ID.test(quoteId) || !sliceEqual(customData.slice(99), hexToBytes(quoteId.padStart(64, "0")))) {
|
|
879
|
-
throw
|
|
928
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order extension custom data is not bound to the quote id");
|
|
880
929
|
}
|
|
881
930
|
}
|
|
882
931
|
function validateEvmTypedOrder(td, expected) {
|
|
@@ -898,7 +947,7 @@ function validateEvmTypedOrder(td, expected) {
|
|
|
898
947
|
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
|
|
899
948
|
// skew between the quote and the order builder), never later.
|
|
900
949
|
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)) {
|
|
901
|
-
throw
|
|
950
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order fields do not match the validated quote/request");
|
|
902
951
|
}
|
|
903
952
|
}
|
|
904
953
|
async function validateTonEscrowPayload(message, expected, validateForwardPayload) {
|
|
@@ -908,9 +957,9 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
908
957
|
try {
|
|
909
958
|
roots = Cell2.fromBoc(import_buffer2.Buffer.from(boc));
|
|
910
959
|
} catch {
|
|
911
|
-
throw
|
|
960
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed TON escrow BoC");
|
|
912
961
|
}
|
|
913
|
-
if (roots.length !== 1) throw
|
|
962
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow must contain exactly one root cell");
|
|
914
963
|
const slice = roots[0].beginParse();
|
|
915
964
|
const op = slice.loadUint(32);
|
|
916
965
|
slice.loadUintBig(64);
|
|
@@ -921,7 +970,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
921
970
|
const forwardAmount = slice.loadCoins();
|
|
922
971
|
const payloadByRef = slice.loadBit();
|
|
923
972
|
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) {
|
|
924
|
-
throw
|
|
973
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: TON jetton transfer does not match the validated quote/request");
|
|
925
974
|
}
|
|
926
975
|
const forwardPayload = slice.loadRef();
|
|
927
976
|
const verified = await validateForwardPayload({
|
|
@@ -941,7 +990,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
941
990
|
...expected.hashingFunction ? { hashingFunction: expected.hashingFunction } : {},
|
|
942
991
|
exclusivityTimeout: expected.exclusivityTimeout
|
|
943
992
|
});
|
|
944
|
-
if (!verified) throw
|
|
993
|
+
if (!verified) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow forward payload failed independent semantic validation");
|
|
945
994
|
}
|
|
946
995
|
function feeToken(asset) {
|
|
947
996
|
return asset.assetId || asset.contract || asset.symbol;
|
|
@@ -971,24 +1020,24 @@ var ProtoReader = class {
|
|
|
971
1020
|
const byte = this.bytes[this.pos++];
|
|
972
1021
|
out += (byte & 127) * 2 ** shift;
|
|
973
1022
|
if ((byte & 128) === 0) {
|
|
974
|
-
if (!Number.isSafeInteger(out)) throw
|
|
1023
|
+
if (!Number.isSafeInteger(out)) throw (0, import_errors.refusal)("policy_refused", "omniston: unsafe protobuf varint");
|
|
975
1024
|
return out;
|
|
976
1025
|
}
|
|
977
1026
|
shift += 7;
|
|
978
1027
|
}
|
|
979
|
-
throw
|
|
1028
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf varint");
|
|
980
1029
|
}
|
|
981
1030
|
field() {
|
|
982
1031
|
const tag = this.varint();
|
|
983
1032
|
const number = Math.floor(tag / 8);
|
|
984
1033
|
const wire = tag & 7;
|
|
985
|
-
if (number < 1) throw
|
|
1034
|
+
if (number < 1) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf field");
|
|
986
1035
|
return { number, wire };
|
|
987
1036
|
}
|
|
988
1037
|
lengthDelimited() {
|
|
989
1038
|
const length = this.varint();
|
|
990
1039
|
const end2 = this.pos + length;
|
|
991
|
-
if (length < 0 || end2 > this.bytes.length) throw
|
|
1040
|
+
if (length < 0 || end2 > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
992
1041
|
const value = this.bytes.slice(this.pos, end2);
|
|
993
1042
|
this.pos = end2;
|
|
994
1043
|
return value;
|
|
@@ -1010,10 +1059,10 @@ var ProtoReader = class {
|
|
|
1010
1059
|
this.advance(4);
|
|
1011
1060
|
return;
|
|
1012
1061
|
}
|
|
1013
|
-
throw
|
|
1062
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported protobuf wire type");
|
|
1014
1063
|
}
|
|
1015
1064
|
advance(length) {
|
|
1016
|
-
if (this.pos + length > this.bytes.length) throw
|
|
1065
|
+
if (this.pos + length > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
1017
1066
|
this.pos += length;
|
|
1018
1067
|
}
|
|
1019
1068
|
};
|
|
@@ -1040,10 +1089,10 @@ function decodeChainAddress(bytes) {
|
|
|
1040
1089
|
while (!reader.done) {
|
|
1041
1090
|
const { number, wire } = reader.field();
|
|
1042
1091
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
1043
|
-
if (!$case || wire !== 2 || address) throw
|
|
1092
|
+
if (!$case || wire !== 2 || address) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed chain address in order details");
|
|
1044
1093
|
address = { chain: { $case, value: utf8.decode(reader.lengthDelimited()) } };
|
|
1045
1094
|
}
|
|
1046
|
-
if (!address?.chain.value) throw
|
|
1095
|
+
if (!address?.chain.value) throw (0, import_errors.refusal)("policy_refused", "omniston: empty chain address in order details");
|
|
1047
1096
|
return address;
|
|
1048
1097
|
}
|
|
1049
1098
|
function decodeAssetId(bytes) {
|
|
@@ -1052,27 +1101,27 @@ function decodeAssetId(bytes) {
|
|
|
1052
1101
|
while (!reader.done) {
|
|
1053
1102
|
const { number, wire } = reader.field();
|
|
1054
1103
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
1055
|
-
if (!$case || wire !== 2 || asset) throw
|
|
1104
|
+
if (!$case || wire !== 2 || asset) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset id in order details");
|
|
1056
1105
|
const kindReader = new ProtoReader(reader.lengthDelimited());
|
|
1057
1106
|
const kindField = kindReader.field();
|
|
1058
1107
|
if (kindField.wire !== 2 || kindField.number !== 1 && kindField.number !== 2) {
|
|
1059
|
-
throw
|
|
1108
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported asset kind in order details");
|
|
1060
1109
|
}
|
|
1061
1110
|
const kindCase = kindField.number === 1 ? "native" : $case === "ton" ? "jetton" : $case === "tron" ? "trc20" : "erc20";
|
|
1062
1111
|
const value = kindField.number === 1 ? {} : utf8.decode(kindReader.lengthDelimited());
|
|
1063
|
-
if (!kindReader.done || kindField.number === 2 && !value) throw
|
|
1112
|
+
if (!kindReader.done || kindField.number === 2 && !value) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset kind in order details");
|
|
1064
1113
|
asset = { chain: { $case, value: { kind: { $case: kindCase, value } } } };
|
|
1065
1114
|
}
|
|
1066
|
-
if (!asset) throw
|
|
1115
|
+
if (!asset) throw (0, import_errors.refusal)("policy_refused", "omniston: empty asset id in order details");
|
|
1067
1116
|
return asset;
|
|
1068
1117
|
}
|
|
1069
1118
|
function validateSerializedOrderDetails(bytes, expected) {
|
|
1070
|
-
if (!bytes?.length) throw
|
|
1119
|
+
if (!bytes?.length) throw (0, import_errors.refusal)("policy_refused", "omniston: EVM HTLC order payload has no serialized details");
|
|
1071
1120
|
const wrapper = new ProtoReader(bytes);
|
|
1072
1121
|
const outer = wrapper.field();
|
|
1073
|
-
if (outer.number !== 1 || outer.wire !== 2) throw
|
|
1122
|
+
if (outer.number !== 1 || outer.wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported HTLC order-details version");
|
|
1074
1123
|
const detailsBytes = wrapper.lengthDelimited();
|
|
1075
|
-
if (!wrapper.done) throw
|
|
1124
|
+
if (!wrapper.done) throw (0, import_errors.refusal)("policy_refused", "omniston: ambiguous HTLC order-details wrapper");
|
|
1076
1125
|
const reader = new ProtoReader(detailsBytes);
|
|
1077
1126
|
let quoteId;
|
|
1078
1127
|
let outputAsset;
|
|
@@ -1080,16 +1129,16 @@ function validateSerializedOrderDetails(bytes, expected) {
|
|
|
1080
1129
|
const hashes = [];
|
|
1081
1130
|
while (!reader.done) {
|
|
1082
1131
|
const { number, wire } = reader.field();
|
|
1083
|
-
if (wire !== 2) throw
|
|
1132
|
+
if (wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed HTLC order details");
|
|
1084
1133
|
const value = reader.lengthDelimited();
|
|
1085
1134
|
if (number === 1 && quoteId === void 0) quoteId = utf8.decode(value);
|
|
1086
1135
|
else if (number === 2 && outputAsset === void 0) outputAsset = decodeAssetId(value);
|
|
1087
1136
|
else if (number === 3 && traderDstAddress === void 0) traderDstAddress = decodeChainAddress(value);
|
|
1088
1137
|
else if (number === 5) hashes.push(value);
|
|
1089
|
-
else throw
|
|
1138
|
+
else throw (0, import_errors.refusal)("policy_refused", "omniston: duplicate or unexpected HTLC order-details field");
|
|
1090
1139
|
}
|
|
1091
1140
|
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]))) {
|
|
1092
|
-
throw
|
|
1141
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver order payload does not match the validated quote/request");
|
|
1093
1142
|
}
|
|
1094
1143
|
}
|
|
1095
1144
|
function isPositiveInteger(value) {
|
|
@@ -1120,7 +1169,7 @@ function bytesToHex(bytes) {
|
|
|
1120
1169
|
function hexToBytes(hex) {
|
|
1121
1170
|
const clean = hex.replace(/^0x/, "");
|
|
1122
1171
|
if (!clean || !/^(?:[0-9a-fA-F]{2})+$/.test(clean)) {
|
|
1123
|
-
throw
|
|
1172
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed hex payload");
|
|
1124
1173
|
}
|
|
1125
1174
|
const out = new Uint8Array(clean.length / 2);
|
|
1126
1175
|
for (let i = 0; i < out.length; i++) out[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
@@ -1154,6 +1203,14 @@ function swapProtocols(v) {
|
|
|
1154
1203
|
for (const route of v.routes) for (const step of route.steps) for (const chunk of step.chunks) names.add(chunk.protocol);
|
|
1155
1204
|
return [...names];
|
|
1156
1205
|
}
|
|
1206
|
+
function rejectionReason(rejection) {
|
|
1207
|
+
return rejection === "quote timestamp out of range" ? "quote_expired" : "upstream_unavailable";
|
|
1208
|
+
}
|
|
1209
|
+
function rfqReason(outcome) {
|
|
1210
|
+
if (outcome.error) return outcome.errorReason;
|
|
1211
|
+
if (outcome.rejected) return rejectionReason(outcome.rejected);
|
|
1212
|
+
return outcome.answered ? "no_route" : "upstream_unavailable";
|
|
1213
|
+
}
|
|
1157
1214
|
function quoteRejection(q, update, acknowledgedRfqId, request, settlement) {
|
|
1158
1215
|
if (!q) return "empty quote";
|
|
1159
1216
|
if (!acknowledgedRfqId || update.rfqId !== acknowledgedRfqId || q.rfqId !== acknowledgedRfqId) return "quote for another RFQ";
|
|
@@ -1193,6 +1250,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1193
1250
|
const max = setTimeout(() => finish(latest), QUOTE_MAX_MS);
|
|
1194
1251
|
sub = stream.subscribe({
|
|
1195
1252
|
next: (event) => {
|
|
1253
|
+
if (event.$case === "ack" || event.$case === "quoteUpdated" || event.$case === "noQuote") outcome.answered = true;
|
|
1196
1254
|
if (event.$case === "ack") {
|
|
1197
1255
|
acknowledgedRfqId = event.value.rfqId || null;
|
|
1198
1256
|
} else if (event.$case === "quoteUpdated") {
|
|
@@ -1212,6 +1270,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1212
1270
|
},
|
|
1213
1271
|
error: (err) => {
|
|
1214
1272
|
outcome.error = String(err?.message ?? err).slice(0, 200);
|
|
1273
|
+
outcome.errorReason = venueReason(err);
|
|
1215
1274
|
finish(null);
|
|
1216
1275
|
},
|
|
1217
1276
|
complete: () => finish(latest)
|
|
@@ -1253,9 +1312,9 @@ function awaitSwapProgress(stream) {
|
|
|
1253
1312
|
}
|
|
1254
1313
|
var JETTON_TRANSFER_OP = 260734629;
|
|
1255
1314
|
function parseSwapPayload(payloadHex) {
|
|
1256
|
-
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw
|
|
1315
|
+
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap payload hex");
|
|
1257
1316
|
const roots = import_core3.Cell.fromBoc(import_buffer2.Buffer.from(payloadHex, "hex"));
|
|
1258
|
-
if (roots.length !== 1) throw
|
|
1317
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: swap payload must have one root");
|
|
1259
1318
|
const s = roots[0].beginParse();
|
|
1260
1319
|
const op = s.loadUint(32);
|
|
1261
1320
|
if (op !== JETTON_TRANSFER_OP) return { op, jettonTransfer: null };
|
|
@@ -1327,86 +1386,108 @@ function mapOrderStatus(order) {
|
|
|
1327
1386
|
}
|
|
1328
1387
|
function omnistonPins(trustedEvmOrderProtocols) {
|
|
1329
1388
|
const byChain = new Map(Object.entries(trustedEvmOrderProtocols).map(([chain, list]) => [chain, list.map((a) => (0, import_viem.getAddress)(a))]));
|
|
1330
|
-
return Object.freeze({
|
|
1389
|
+
return Object.freeze({
|
|
1390
|
+
callTargets: () => [],
|
|
1391
|
+
spenders: (chain) => byChain.get(chain) ?? [],
|
|
1392
|
+
// The reason behind a text omnistonVerifyBuild returned, so the remote stub's refusal carries it.
|
|
1393
|
+
reasonOf: verifyNotes.reasonOf
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
var VERIFY_NOTES = /* @__PURE__ */ Symbol.for("@anywalletkit/protocol-swap2-omniston/verify-notes@1");
|
|
1397
|
+
var verifyNotes = (() => {
|
|
1398
|
+
const shared = globalThis[VERIFY_NOTES];
|
|
1399
|
+
if (shared && typeof shared.note === "function" && typeof shared.reasonOf === "function") return shared;
|
|
1400
|
+
const notes = (0, import_errors.refusalNotes)();
|
|
1401
|
+
try {
|
|
1402
|
+
Object.defineProperty(globalThis, VERIFY_NOTES, { value: notes });
|
|
1403
|
+
} catch {
|
|
1404
|
+
}
|
|
1405
|
+
return notes;
|
|
1406
|
+
})();
|
|
1407
|
+
var said = verifyNotes.note;
|
|
1408
|
+
function tonEscrowBuildReason(text) {
|
|
1409
|
+
if (text.startsWith("the escrow transfer pays ")) return "vault_mismatch";
|
|
1410
|
+
if (text.startsWith("the resolver is bound to deliver ")) return "price_check_failed";
|
|
1411
|
+
return "policy_refused";
|
|
1331
1412
|
}
|
|
1332
1413
|
var MAX_EVM_ORDER_LIFETIME_S = 900;
|
|
1333
1414
|
async function checkRemoteEvmOrder(quote, tx, params, trusted) {
|
|
1334
1415
|
const chainId = evmRef2(params.sourceChain);
|
|
1335
|
-
if (chainId === null || !params.sourceChain.startsWith("eip155:")) return "a typed order needs an EVM source";
|
|
1416
|
+
if (chainId === null || !params.sourceChain.startsWith("eip155:")) return said("a typed order needs an EVM source", "policy_refused");
|
|
1336
1417
|
const intent = decodeIntent(quote.intentId.replace(/~[0-9a-f]{32}$/, ""));
|
|
1337
|
-
if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return "the quote's intent is not an order from this chain";
|
|
1338
|
-
if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return "the build carries no order extension to check";
|
|
1418
|
+
if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return said("the quote's intent is not an order from this chain", "policy_refused");
|
|
1419
|
+
if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return said("the build carries no order extension to check", "policy_refused");
|
|
1339
1420
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1340
|
-
if (!source?.contract) return "unknown source token";
|
|
1421
|
+
if (!source?.contract) return said("unknown source token", "unsupported_pair");
|
|
1341
1422
|
const tonDest = isTon(params.destChain);
|
|
1342
1423
|
const destChainId = tonDest ? null : evmRef2(params.destChain);
|
|
1343
|
-
if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return "the destination is neither TON nor an EVM chain";
|
|
1424
|
+
if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return said("the destination is neither TON nor an EVM chain", "unsupported_pair");
|
|
1344
1425
|
const outputToken = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken)?.contract ?? params.destToken;
|
|
1345
1426
|
const listed = (table, chain, address) => typeof address === "string" && validEvmAddress(address) && (table[chain] ?? []).some((a) => validEvmAddress(a) && (0, import_viem.getAddress)(a) === (0, import_viem.getAddress)(address));
|
|
1346
1427
|
let td;
|
|
1347
1428
|
try {
|
|
1348
1429
|
td = JSON.parse(tx.typedData ?? "");
|
|
1349
1430
|
} catch {
|
|
1350
|
-
return "the typed data is not JSON";
|
|
1431
|
+
return said("the typed data is not JSON", "policy_refused");
|
|
1351
1432
|
}
|
|
1352
1433
|
const domain = td.domain ?? {};
|
|
1353
1434
|
const contract = domain.verifyingContract;
|
|
1354
|
-
if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return "the domain is not the 1inch Limit Order Protocol v4";
|
|
1435
|
+
if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return said("the domain is not the 1inch Limit Order Protocol v4", "policy_refused");
|
|
1355
1436
|
if (!listed(trusted.orderProtocols, params.sourceChain, contract) || !tx.approvalAddress || (0, import_viem.getAddress)(tx.approvalAddress) !== (0, import_viem.getAddress)(String(contract))) {
|
|
1356
|
-
return `${String(contract)} is not a trusted order protocol on ${params.sourceChain}
|
|
1437
|
+
return said(`${String(contract)} is not a trusted order protocol on ${params.sourceChain}`, "vault_mismatch");
|
|
1357
1438
|
}
|
|
1358
|
-
if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return "the domain chainId is not the source chain";
|
|
1439
|
+
if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return said("the domain chainId is not the source chain", "policy_refused");
|
|
1359
1440
|
const order = td.types?.Order;
|
|
1360
1441
|
const message = td.message;
|
|
1361
1442
|
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]))) {
|
|
1362
|
-
return "the typed data is not exactly a v4 Order";
|
|
1443
|
+
return said("the typed data is not exactly a v4 Order", "policy_refused");
|
|
1363
1444
|
}
|
|
1364
|
-
if (!validEvmAddress(intent.trader) || (0, import_viem.getAddress)(String(message.maker)) !== (0, import_viem.getAddress)(intent.trader)) return "the maker is not the trader";
|
|
1365
|
-
if ((0, import_viem.getAddress)(String(message.makerAsset)) !== (0, import_viem.getAddress)(source.contract)) return "the makerAsset is not the source token";
|
|
1366
|
-
if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return "the makingAmount is not the input";
|
|
1367
|
-
if ((0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(String(message.makerAsset))) return "the takerAsset is the makerAsset";
|
|
1445
|
+
if (!validEvmAddress(intent.trader) || (0, import_viem.getAddress)(String(message.maker)) !== (0, import_viem.getAddress)(intent.trader)) return said("the maker is not the trader", "policy_refused");
|
|
1446
|
+
if ((0, import_viem.getAddress)(String(message.makerAsset)) !== (0, import_viem.getAddress)(source.contract)) return said("the makerAsset is not the source token", "policy_refused");
|
|
1447
|
+
if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return said("the makingAmount is not the input", "policy_refused");
|
|
1448
|
+
if ((0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(String(message.makerAsset))) return said("the takerAsset is the makerAsset", "policy_refused");
|
|
1368
1449
|
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);
|
|
1369
|
-
if (floor <= 0n || BigInt(message.takingAmount) < floor) return `takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}
|
|
1450
|
+
if (floor <= 0n || BigInt(message.takingAmount) < floor) return said(`takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}`, "price_check_failed");
|
|
1370
1451
|
const traits = BigInt(message.makerTraits);
|
|
1371
1452
|
const flags = traits & (1n << 56n) - 1n << 200n;
|
|
1372
1453
|
const baseFlags = 1n << 251n | 1n << 249n;
|
|
1373
|
-
if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return "the makerTraits flags are not a single-fill order with its extension";
|
|
1374
|
-
if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return "the makerTraits restrict the taker or the series";
|
|
1454
|
+
if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return said("the makerTraits flags are not a single-fill order with its extension", "policy_refused");
|
|
1455
|
+
if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return said("the makerTraits restrict the taker or the series", "policy_refused");
|
|
1375
1456
|
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1376
1457
|
const expiration = traits >> 80n & (1n << 40n) - 1n;
|
|
1377
|
-
if (expiration <= now || expiration > now + BigInt(MAX_EVM_ORDER_LIFETIME_S)) return "the order's expiry is not minutes away";
|
|
1458
|
+
if (expiration <= now || expiration > now + BigInt(MAX_EVM_ORDER_LIFETIME_S)) return said("the order's expiry is not minutes away", expiration <= now ? "quote_expired" : "policy_refused");
|
|
1378
1459
|
const extension = (0, import_viem.hexToBytes)(tx.orderExtension);
|
|
1379
1460
|
const mask = (1n << 160n) - 1n;
|
|
1380
|
-
if ((BigInt(message.salt) & mask) !== (BigInt((0, import_viem.keccak256)(extension)) & mask)) return "the salt does not commit the order extension";
|
|
1461
|
+
if ((BigInt(message.salt) & mask) !== (BigInt((0, import_viem.keccak256)(extension)) & mask)) return said("the salt does not commit the order extension", "policy_refused");
|
|
1381
1462
|
let parsed;
|
|
1382
1463
|
try {
|
|
1383
1464
|
parsed = readEvmOrderExtension(extension);
|
|
1384
1465
|
} catch (e) {
|
|
1385
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1466
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), (0, import_errors.refusalOf)(e) ?? "policy_refused");
|
|
1386
1467
|
}
|
|
1387
1468
|
const { target, getter, post, extra, customData } = parsed;
|
|
1388
|
-
if (!listed(trusted.factories, params.sourceChain, target)) return `the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}
|
|
1469
|
+
if (!listed(trusted.factories, params.sourceChain, target)) return said(`the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}`, "vault_mismatch");
|
|
1389
1470
|
const receiverLow80 = BigInt((0, import_viem.getAddress)(String(message.receiver))) & (1n << 80n) - 1n;
|
|
1390
|
-
if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return "the order's receiver is not the resolver its extension whitelists";
|
|
1471
|
+
if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return said("the order's receiver is not the resolver its extension whitelists", "recipient_mismatch");
|
|
1391
1472
|
if (getter.gasBump !== 0n || getter.gasPrice !== 0n || getter.duration !== 1800n || getter.initialRateBump !== 900000n || getter.points.some((point, index) => point[0] !== EVM_AUCTION_POINTS[index][0] || point[1] !== EVM_AUCTION_POINTS[index][1]) || getter.integratorFee !== 0n || getter.integratorShare !== 100n || getter.whitelistDiscount !== 50n || !within(getter.auctionStart, (0, import_core4.bigintToNumber)(now), MAX_EVM_ORDER_LIFETIME_S, 60)) {
|
|
1392
|
-
return "the amount-getter terms do not match the pinned v1beta8 profile";
|
|
1473
|
+
return said("the amount-getter terms do not match the pinned v1beta8 profile", "policy_refused");
|
|
1393
1474
|
}
|
|
1394
1475
|
if (!zeroBytes(post.integratorRecipient) || !(zeroBytes(post.protocolRecipient) || !tonDest && EVM_DEST_PROTOCOL_FEE_RECIPIENTS.has(`0x${bytesToHex(post.protocolRecipient)}`)) || post.integratorFee !== 0n || post.integratorShare !== 100n || post.resolverFee !== getter.resolverFee || post.discount !== 50n || post.resolverTimeDelta !== 0n || !within(post.allowedTime, (0, import_core4.bigintToNumber)(getter.auctionStart), 60, 5)) {
|
|
1395
|
-
return "the post-interaction terms do not match the pinned v1beta8 profile";
|
|
1476
|
+
return said("the post-interaction terms do not match the pinned v1beta8 profile", "policy_refused");
|
|
1396
1477
|
}
|
|
1397
1478
|
let dstToken;
|
|
1398
1479
|
try {
|
|
1399
1480
|
dstToken = tonDest ? BigInt((0, import_viem.getAddress)(String(message.takerAsset))) : BigInt((0, import_viem.getAddress)(outputToken));
|
|
1400
1481
|
} catch {
|
|
1401
|
-
return "the destination token is not an EVM address";
|
|
1482
|
+
return said("the destination token is not an EVM address", "policy_refused");
|
|
1402
1483
|
}
|
|
1403
1484
|
if (extra[1] !== (tonDest ? 0n : BigInt(destChainId)) || extra[2] !== dstToken || extra[4] !== EVM_TIMELOCKS) {
|
|
1404
|
-
return "the signed HTLC terms name another destination chain or token, or other timelocks";
|
|
1485
|
+
return said("the signed HTLC terms name another destination chain or token, or other timelocks", "policy_refused");
|
|
1405
1486
|
}
|
|
1406
1487
|
try {
|
|
1407
1488
|
await checkOrderCustomData(customData, { evmDest: !tonDest, outputToken, traderDst: params.destAddress, quoteId: intent.quoteId });
|
|
1408
1489
|
} catch (e) {
|
|
1409
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1490
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), (0, import_errors.refusalOf)(e) ?? "policy_refused");
|
|
1410
1491
|
}
|
|
1411
1492
|
return null;
|
|
1412
1493
|
}
|
|
@@ -1417,22 +1498,22 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1417
1498
|
};
|
|
1418
1499
|
return async (quote, tx, params) => {
|
|
1419
1500
|
if (tx.typedData !== void 0) {
|
|
1420
|
-
if (!params) return "the request this quote answered is unknown";
|
|
1501
|
+
if (!params) return said("the request this quote answered is unknown", "policy_refused");
|
|
1421
1502
|
try {
|
|
1422
1503
|
return await checkRemoteEvmOrder(quote, tx, params, trusted);
|
|
1423
1504
|
} catch {
|
|
1424
|
-
return "the typed order could not be checked";
|
|
1505
|
+
return said("the typed order could not be checked", "policy_refused");
|
|
1425
1506
|
}
|
|
1426
1507
|
}
|
|
1427
1508
|
if (tx.bodyBoc === void 0) return null;
|
|
1428
|
-
if (!params) return "the request this quote answered is unknown";
|
|
1509
|
+
if (!params) return said("the request this quote answered is unknown", "policy_refused");
|
|
1429
1510
|
if (quote.providerData?.settlement !== "swap") {
|
|
1430
1511
|
if (params.sourceChain.startsWith("ton:") && params.destChain.startsWith("eip155:")) {
|
|
1431
|
-
if (!hooks.verifyTonEscrowBuild) return "a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)";
|
|
1432
|
-
if (!params.refundAddress) return "the trader's TON address (refundAddress) is unknown";
|
|
1512
|
+
if (!hooks.verifyTonEscrowBuild) return said("a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)", "unsupported_pair");
|
|
1513
|
+
if (!params.refundAddress) return said("the trader's TON address (refundAddress) is unknown", "recipient_unverifiable");
|
|
1433
1514
|
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);
|
|
1434
1515
|
try {
|
|
1435
|
-
|
|
1516
|
+
const text = await hooks.verifyTonEscrowBuild({
|
|
1436
1517
|
payloadBocHex: import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"),
|
|
1437
1518
|
ownerAddress: params.refundAddress,
|
|
1438
1519
|
inputUnits: quote.sourceAmount,
|
|
@@ -1441,22 +1522,23 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1441
1522
|
outputTokenAddress: params.destToken,
|
|
1442
1523
|
minResolverSendsUnits: floor.toString()
|
|
1443
1524
|
});
|
|
1525
|
+
return text ? said(text, tonEscrowBuildReason(text)) : text;
|
|
1444
1526
|
} catch {
|
|
1445
|
-
return "the escrow body could not be checked";
|
|
1527
|
+
return said("the escrow body could not be checked", "policy_refused");
|
|
1446
1528
|
}
|
|
1447
1529
|
}
|
|
1448
|
-
return "only TON swap and TON \u2192 EVM escrow bodies can be checked on the client";
|
|
1530
|
+
return said("only TON swap and TON \u2192 EVM escrow bodies can be checked on the client", "unsupported_pair");
|
|
1449
1531
|
}
|
|
1450
1532
|
let steps;
|
|
1451
1533
|
try {
|
|
1452
1534
|
steps = JSON.parse(quote.providerData.routeSteps ?? "");
|
|
1453
1535
|
} catch {
|
|
1454
|
-
return "the quote carries no route steps";
|
|
1536
|
+
return said("the quote carries no route steps", "policy_refused");
|
|
1455
1537
|
}
|
|
1456
|
-
if (!Array.isArray(steps) || steps.length === 0) return "the quote carries no route steps";
|
|
1538
|
+
if (!Array.isArray(steps) || steps.length === 0) return said("the quote carries no route steps", "policy_refused");
|
|
1457
1539
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1458
1540
|
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
1459
|
-
if (!source || !dest) return "unknown source or destination token";
|
|
1541
|
+
if (!source || !dest) return said("unknown source or destination token", "unsupported_pair");
|
|
1460
1542
|
const protocols = (quote.providerData.protocols ?? "").split(",").filter(Boolean);
|
|
1461
1543
|
let checked;
|
|
1462
1544
|
try {
|
|
@@ -1474,17 +1556,17 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1474
1556
|
integratorAddress: hooks.integratorAddress ?? null
|
|
1475
1557
|
});
|
|
1476
1558
|
} catch (e) {
|
|
1477
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1559
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), e instanceof TonSwapPayloadError ? tonSwapPayloadReason(e.reason) : "policy_refused");
|
|
1478
1560
|
}
|
|
1479
1561
|
const payload = parseSwapPayload(import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"));
|
|
1480
1562
|
const target = source.contract ? payload.jettonTransfer?.destination : tx.to;
|
|
1481
|
-
if (!target) return "the body names no swap destination";
|
|
1563
|
+
if (!target) return said("the body names no swap destination", "policy_refused");
|
|
1482
1564
|
try {
|
|
1483
|
-
if (!await hooks.validateTonSwapTarget({ address: target, protocols })) return `${target} is not a recognized DEX contract for ${protocols.join("+")}
|
|
1565
|
+
if (!await hooks.validateTonSwapTarget({ address: target, protocols })) return said(`${target} is not a recognized DEX contract for ${protocols.join("+")}`, "vault_mismatch");
|
|
1484
1566
|
} catch {
|
|
1485
|
-
return "the swap target could not be checked";
|
|
1567
|
+
return said("the swap target could not be checked", "policy_refused");
|
|
1486
1568
|
}
|
|
1487
|
-
if (!hooks.validateTonSwapLeg) return "a TON swap body needs validateTonSwapLeg (createOmnistonTonValidators)";
|
|
1569
|
+
if (!hooks.validateTonSwapLeg) return said("a TON swap body needs validateTonSwapLeg (createOmnistonTonValidators)", "unsupported_pair");
|
|
1488
1570
|
for (const leg of checked.legs) {
|
|
1489
1571
|
let ok = false;
|
|
1490
1572
|
try {
|
|
@@ -1492,7 +1574,7 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1492
1574
|
} catch {
|
|
1493
1575
|
ok = false;
|
|
1494
1576
|
}
|
|
1495
|
-
if (!ok) return `${leg.kind} v${leg.version} leg not verified
|
|
1577
|
+
if (!ok) return said(`${leg.kind} v${leg.version} leg not verified`, "vault_mismatch");
|
|
1496
1578
|
}
|
|
1497
1579
|
return null;
|
|
1498
1580
|
};
|
|
@@ -1676,19 +1758,19 @@ function omnistonProvider(opts = {}) {
|
|
|
1676
1758
|
if (!bound.ok) {
|
|
1677
1759
|
if (bound.reason === "legacy-expired") {
|
|
1678
1760
|
trace("legacy-intent-expired", { where });
|
|
1679
|
-
throw
|
|
1761
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
1680
1762
|
}
|
|
1681
1763
|
trace("intent-mismatch", { where, field: bound.field });
|
|
1682
|
-
throw
|
|
1764
|
+
throw (0, import_errors.refusal)(mismatchReason(bound.field), `omniston: intent id does not match the quote it was issued for (${bound.field})`);
|
|
1683
1765
|
}
|
|
1684
1766
|
if (bound.legacy) trace("legacy-intent", { where });
|
|
1685
1767
|
if (!decoded.digest) {
|
|
1686
1768
|
trace("intent-mismatch", { where, field: "digest-missing" });
|
|
1687
|
-
throw
|
|
1769
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: this quote was issued before an update \u2014 request a fresh quote");
|
|
1688
1770
|
}
|
|
1689
1771
|
if (decoded.digest !== quoteDigest(entry.quote)) {
|
|
1690
1772
|
trace("intent-mismatch", { where, field: "digest" });
|
|
1691
|
-
throw
|
|
1773
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: quote was replaced \u2014 request a fresh quote");
|
|
1692
1774
|
}
|
|
1693
1775
|
return bound.ref;
|
|
1694
1776
|
}
|
|
@@ -1722,10 +1804,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1722
1804
|
const disclosed = (await store.load(disclosedKey(quoteId)) ?? []).length > 0;
|
|
1723
1805
|
if (boundTo !== binding || disclosed) {
|
|
1724
1806
|
traceFor(quoteId)("secret-reuse-refused", { disclosed, bound: boundTo !== void 0 });
|
|
1725
|
-
throw
|
|
1807
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: this quote id already belongs to another order \u2014 request a fresh quote");
|
|
1726
1808
|
}
|
|
1727
1809
|
if (existing.length !== count || !existing.every((s) => /^[0-9a-fA-F]{64}$/.test(s))) {
|
|
1728
|
-
throw
|
|
1810
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: stored HTLC secrets for this quote do not fit the order \u2014 request a fresh quote");
|
|
1729
1811
|
}
|
|
1730
1812
|
traceFor(quoteId)("secret-reused", { count });
|
|
1731
1813
|
return { secrets: existing.map(hexToBytes), created: false };
|
|
@@ -1784,7 +1866,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1784
1866
|
let q = await rfq(slippagePips);
|
|
1785
1867
|
if (!q) {
|
|
1786
1868
|
if (!signal?.aborted) {
|
|
1787
|
-
|
|
1869
|
+
const text = `omniston: ${outcome.error ? `RFQ failed: ${outcome.error}` : outcome.rejected ? `swap quote rejected: ${outcome.rejected}` : "no TON DEX route quoted this pair/amount"}`;
|
|
1870
|
+
const reason = rfqReason(outcome);
|
|
1871
|
+
if (reason) params.onRefusal?.(text, { reason });
|
|
1872
|
+
else params.onRefusal?.(text);
|
|
1788
1873
|
}
|
|
1789
1874
|
return null;
|
|
1790
1875
|
}
|
|
@@ -1850,27 +1935,32 @@ function omnistonProvider(opts = {}) {
|
|
|
1850
1935
|
async function buildSwapDeposit(ref, q, swap) {
|
|
1851
1936
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
1852
1937
|
if (!isTon(ref.srcChain) || q.inputAsset.chain.$case !== "ton" || q.outputAsset.chain.$case !== "ton") {
|
|
1853
|
-
throw
|
|
1938
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: swap quote is not a TON same-chain swap");
|
|
1854
1939
|
}
|
|
1855
|
-
if (!sameChainTonReady()) throw
|
|
1940
|
+
if (!sameChainTonReady()) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON same-chain swaps need independent jetton-wallet, swap-target and swap-leg validators");
|
|
1856
1941
|
const owner = { chain: { $case: "ton", value: ref.trader } };
|
|
1857
1942
|
const receiver = { chain: { $case: "ton", value: ref.dest } };
|
|
1858
1943
|
const omni = await getClient();
|
|
1859
|
-
if (typeof omni.tonBuildSwap !== "function") throw
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1944
|
+
if (typeof omni.tonBuildSwap !== "function") throw (0, import_errors.refusal)("unsupported_pair", "omniston: client does not support swap settlement (tonBuildSwap)");
|
|
1945
|
+
let tx;
|
|
1946
|
+
try {
|
|
1947
|
+
tx = await omni.tonBuildSwap({
|
|
1948
|
+
quoteId: ref.quoteId,
|
|
1949
|
+
transferSrcAddress: owner,
|
|
1950
|
+
refundSrcAddress: owner,
|
|
1951
|
+
gasExcessAddress: owner,
|
|
1952
|
+
traderDstAddress: receiver,
|
|
1953
|
+
// Build at the slippage the quote was requested with: its
|
|
1954
|
+
// minOutputAmount is the minimum this module reported to the router.
|
|
1955
|
+
useRecommendedSlippage: false
|
|
1956
|
+
});
|
|
1957
|
+
} catch (error) {
|
|
1958
|
+
throw venueFailure(error);
|
|
1959
|
+
}
|
|
1870
1960
|
const [message, ...rest] = tx.messages;
|
|
1871
|
-
if (!message || rest.length > 0) throw
|
|
1872
|
-
if (message.jettonWalletStateInit) throw
|
|
1873
|
-
if (!isPositiveInteger(message.sendAmount)) throw
|
|
1961
|
+
if (!message || rest.length > 0) throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one swap message, got ${tx.messages.length}`);
|
|
1962
|
+
if (message.jettonWalletStateInit) throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
1963
|
+
if (!isPositiveInteger(message.sendAmount)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap message value");
|
|
1874
1964
|
const sendAmount = BigInt(message.sendAmount);
|
|
1875
1965
|
const gasCap = BigInt(maxTonExecutionNano);
|
|
1876
1966
|
const gasBudget = q.gasBudget && isPositiveInteger(q.gasBudget) ? BigInt(q.gasBudget) : gasCap;
|
|
@@ -1882,53 +1972,53 @@ function omnistonProvider(opts = {}) {
|
|
|
1882
1972
|
const ptonV1Native = !inputJetton && !!payload.jettonTransfer && singleV1;
|
|
1883
1973
|
if (inputJetton) {
|
|
1884
1974
|
const transfer = payload.jettonTransfer;
|
|
1885
|
-
if (!transfer) throw
|
|
1886
|
-
if (sendAmount > gasCap || sendAmount > gasBudget) throw
|
|
1887
|
-
if (transfer.amount !== BigInt(q.inputUnits)) throw
|
|
1975
|
+
if (!transfer) throw (0, import_errors.refusal)("policy_refused", "omniston: jetton-input swap message is not a jetton transfer");
|
|
1976
|
+
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("+")})`);
|
|
1977
|
+
if (transfer.amount !== BigInt(q.inputUnits)) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
1888
1978
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1889
|
-
throw
|
|
1979
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1890
1980
|
}
|
|
1891
|
-
if (transfer.forwardTon >= sendAmount) throw
|
|
1981
|
+
if (transfer.forwardTon >= sendAmount) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than it carries");
|
|
1892
1982
|
const walletValid = await opts.validateTonJettonWallet({
|
|
1893
1983
|
ownerAddress: ref.trader,
|
|
1894
1984
|
jettonMasterAddress: inputJetton,
|
|
1895
1985
|
walletAddress: message.targetAddress
|
|
1896
1986
|
});
|
|
1897
|
-
if (!walletValid) throw
|
|
1987
|
+
if (!walletValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
1898
1988
|
const targetValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1899
|
-
if (!targetValid) throw
|
|
1989
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1900
1990
|
} else if (ptonV1Native) {
|
|
1901
1991
|
const transfer = payload.jettonTransfer;
|
|
1902
1992
|
const input = BigInt(q.inputUnits);
|
|
1903
|
-
if (transfer.amount !== input) throw
|
|
1904
|
-
if (sendAmount < input) throw
|
|
1993
|
+
if (transfer.amount !== input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
1994
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1905
1995
|
const gas = sendAmount - input;
|
|
1906
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
1907
|
-
if (transfer.forwardTon > gas) throw
|
|
1996
|
+
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("+")})`);
|
|
1997
|
+
if (transfer.forwardTon > gas) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than its gas");
|
|
1908
1998
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1909
|
-
throw
|
|
1999
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1910
2000
|
}
|
|
1911
|
-
if (typeof opts.validateTonSwapLeg !== "function") throw
|
|
2001
|
+
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)");
|
|
1912
2002
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1913
|
-
if (!targetValid) throw
|
|
2003
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1914
2004
|
const routerValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1915
|
-
if (!routerValid) throw
|
|
2005
|
+
if (!routerValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1916
2006
|
} else {
|
|
1917
2007
|
if (payload.jettonTransfer) {
|
|
1918
|
-
throw
|
|
2008
|
+
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})`);
|
|
1919
2009
|
}
|
|
1920
2010
|
const input = BigInt(q.inputUnits);
|
|
1921
|
-
if (sendAmount < input) throw
|
|
2011
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1922
2012
|
const gas = sendAmount - input;
|
|
1923
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
2013
|
+
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("+")})`);
|
|
1924
2014
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1925
|
-
if (!targetValid) throw
|
|
2015
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1926
2016
|
}
|
|
1927
2017
|
const mode = ptonV1Native ? "enforce" : opts.tonSwapPayloadCheck ?? "enforce";
|
|
1928
2018
|
const trace = traceFor(ref.quoteId);
|
|
1929
2019
|
const payloadRefusal = (reason, detail) => {
|
|
1930
2020
|
trace("ton-swap-payload", { reason, detail, mode, protocols: protocols.join("+") });
|
|
1931
|
-
if (mode === "enforce") throw
|
|
2021
|
+
if (mode === "enforce") throw (0, import_errors.refusal)(tonSwapPayloadReason(reason), `omniston: ton-swap-payload ${reason} \u2014 ${detail}`);
|
|
1932
2022
|
};
|
|
1933
2023
|
let checked = null;
|
|
1934
2024
|
try {
|
|
@@ -2002,33 +2092,33 @@ function omnistonProvider(opts = {}) {
|
|
|
2002
2092
|
const srcChain = ref.srcChain;
|
|
2003
2093
|
const chainId = evmRef2(srcChain);
|
|
2004
2094
|
const srcCase = q.inputAsset.chain.$case;
|
|
2005
|
-
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw
|
|
2095
|
+
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match the EVM quote");
|
|
2006
2096
|
const destCase = q.outputAsset.chain.$case;
|
|
2007
2097
|
const destChain = caipForChainCase(destCase);
|
|
2008
2098
|
const tonDest = destCase === "ton";
|
|
2009
|
-
if (!destChain || destChain === srcChain) throw
|
|
2099
|
+
if (!destChain || destChain === srcChain) throw (0, import_errors.refusal)("unsupported_pair", "omniston: EVM-source order has no supported destination chain");
|
|
2010
2100
|
if (!trustedOrderProtocols.has(srcChain) || typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
2011
|
-
throw
|
|
2101
|
+
throw (0, import_errors.refusal)("unsupported_pair", `omniston: EVM\u2192${tonDest ? "TON" : "EVM"} needs a trusted order protocol and both position validators`);
|
|
2012
2102
|
}
|
|
2013
2103
|
let owner;
|
|
2014
2104
|
try {
|
|
2015
2105
|
owner = (0, import_viem.getAddress)(ref.trader);
|
|
2016
2106
|
} catch {
|
|
2017
|
-
throw
|
|
2107
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: trader is not an EVM address");
|
|
2018
2108
|
}
|
|
2019
2109
|
let dest;
|
|
2020
2110
|
if (tonDest) {
|
|
2021
2111
|
try {
|
|
2022
2112
|
import_core3.Address.parse(ref.dest);
|
|
2023
2113
|
} catch {
|
|
2024
|
-
throw
|
|
2114
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not a TON address");
|
|
2025
2115
|
}
|
|
2026
2116
|
dest = ref.dest;
|
|
2027
2117
|
} else {
|
|
2028
2118
|
try {
|
|
2029
2119
|
dest = (0, import_viem.getAddress)(ref.dest);
|
|
2030
2120
|
} catch {
|
|
2031
|
-
throw
|
|
2121
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not an EVM address");
|
|
2032
2122
|
}
|
|
2033
2123
|
}
|
|
2034
2124
|
const traderDst = { chain: { $case: destCase, value: dest } };
|
|
@@ -2039,9 +2129,9 @@ function omnistonProvider(opts = {}) {
|
|
|
2039
2129
|
const outputToken = assetContract(q.outputAsset);
|
|
2040
2130
|
const destChainId = tonDest ? null : evmRef2(destChain);
|
|
2041
2131
|
if (factory?.chain.$case === destCase && !isTrusted(destChain, factory.chain.value)) {
|
|
2042
|
-
throw
|
|
2132
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted ${destChain} settlement contract ${factory.chain.value}`);
|
|
2043
2133
|
}
|
|
2044
|
-
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
|
|
2134
|
+
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");
|
|
2045
2135
|
const { secrets, created } = await secretsFor(ref, q, 1);
|
|
2046
2136
|
const hashes = secrets.map((secret) => hashlock(secret, settlement.htlcHashingFunction));
|
|
2047
2137
|
const forget = async () => {
|
|
@@ -2058,14 +2148,14 @@ function omnistonProvider(opts = {}) {
|
|
|
2058
2148
|
});
|
|
2059
2149
|
} catch (error) {
|
|
2060
2150
|
await forget();
|
|
2061
|
-
throw error;
|
|
2151
|
+
throw venueFailure(error);
|
|
2062
2152
|
}
|
|
2063
2153
|
let td;
|
|
2064
2154
|
try {
|
|
2065
2155
|
try {
|
|
2066
2156
|
td = JSON.parse(payload.typedData);
|
|
2067
2157
|
} catch {
|
|
2068
|
-
throw
|
|
2158
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order typed data");
|
|
2069
2159
|
}
|
|
2070
2160
|
validateSerializedOrderDetails(payload.serializedOrderDetails, {
|
|
2071
2161
|
quoteId: ref.quoteId,
|
|
@@ -2148,45 +2238,46 @@ function omnistonProvider(opts = {}) {
|
|
|
2148
2238
|
async getQuote(params, signal) {
|
|
2149
2239
|
if (params.flex) return null;
|
|
2150
2240
|
if (isTon(params.sourceChain) && isTon(params.destChain)) return await getSwapQuote(params, signal);
|
|
2151
|
-
const refuse2 = (reason) => {
|
|
2152
|
-
params.onRefusal?.(`omniston: ${reason}
|
|
2241
|
+
const refuse2 = (reason, why) => {
|
|
2242
|
+
if (why) params.onRefusal?.(`omniston: ${reason}`, { reason: why });
|
|
2243
|
+
else params.onRefusal?.(`omniston: ${reason}`);
|
|
2153
2244
|
return null;
|
|
2154
2245
|
};
|
|
2155
2246
|
const evmSource = !isTon(params.sourceChain);
|
|
2156
2247
|
const tonDest = isTon(params.destChain);
|
|
2157
|
-
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor");
|
|
2248
|
+
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor", "unsupported_pair");
|
|
2158
2249
|
if (!trustedContracts.has(params.sourceChain) || !trustedContracts.has(params.destChain)) {
|
|
2159
|
-
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}
|
|
2250
|
+
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}`, "unsupported_pair");
|
|
2160
2251
|
}
|
|
2161
2252
|
if (evmSource) {
|
|
2162
|
-
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}
|
|
2253
|
+
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}`, "unsupported_pair");
|
|
2163
2254
|
if (typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
2164
|
-
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");
|
|
2255
|
+
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");
|
|
2165
2256
|
}
|
|
2166
2257
|
if (params.dry === false) {
|
|
2167
2258
|
if (tonDest) {
|
|
2168
2259
|
try {
|
|
2169
2260
|
import_core3.Address.parse(params.destAddress);
|
|
2170
2261
|
} catch {
|
|
2171
|
-
return refuse2("destination is not a TON address");
|
|
2262
|
+
return refuse2("destination is not a TON address", "recipient_mismatch");
|
|
2172
2263
|
}
|
|
2173
|
-
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address");
|
|
2264
|
+
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address", "recipient_mismatch");
|
|
2174
2265
|
}
|
|
2175
|
-
} 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");
|
|
2266
|
+
} 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");
|
|
2176
2267
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
2177
2268
|
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
2178
|
-
if (!source || !dest) return refuse2("asset is not in the catalog");
|
|
2269
|
+
if (!source || !dest) return refuse2("asset is not in the catalog", "unsupported_pair");
|
|
2179
2270
|
const inputAsset = toAssetId(params.sourceChain, source);
|
|
2180
2271
|
const outputAsset = toAssetId(params.destChain, dest);
|
|
2181
2272
|
if (!inputAsset || !outputAsset) {
|
|
2182
|
-
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)
|
|
2273
|
+
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)`, "unsupported_pair");
|
|
2183
2274
|
}
|
|
2184
2275
|
const maxUnits = decimalToUnits(maxUsdText, source.decimals);
|
|
2185
2276
|
if (!maxUnits || !isPositiveInteger(params.amountIn)) return refuse2("invalid amount");
|
|
2186
|
-
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap
|
|
2277
|
+
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap`, "amount_too_large");
|
|
2187
2278
|
const trader = params.refundAddress ?? "";
|
|
2188
2279
|
if (!trader && !params.dry) return refuse2(`execution quote needs the trader's ${evmSource ? "EVM" : "TON"} address (refundAddress)`);
|
|
2189
|
-
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address");
|
|
2280
|
+
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address", "recipient_mismatch");
|
|
2190
2281
|
const request = {
|
|
2191
2282
|
inputAsset,
|
|
2192
2283
|
outputAsset,
|
|
@@ -2214,27 +2305,28 @@ function omnistonProvider(opts = {}) {
|
|
|
2214
2305
|
if (!q) {
|
|
2215
2306
|
if (signal?.aborted) return null;
|
|
2216
2307
|
return refuse2(
|
|
2217
|
-
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount"
|
|
2308
|
+
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount",
|
|
2309
|
+
rfqReason(rfq)
|
|
2218
2310
|
);
|
|
2219
2311
|
}
|
|
2220
2312
|
const orderData = q.settlementData.$case === "order" ? q.settlementData.value : null;
|
|
2221
|
-
if (!orderData) return refuse2("resolver answered without order settlement");
|
|
2313
|
+
if (!orderData) return refuse2("resolver answered without order settlement", "upstream_unavailable");
|
|
2222
2314
|
const srcContract = orderData.srcProtocolContractAddress.chain.value;
|
|
2223
2315
|
if (evmSource ? !isTrustedOrderProtocol(params.sourceChain, srcContract) : !isTrusted(params.sourceChain, srcContract)) {
|
|
2224
|
-
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}
|
|
2316
|
+
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}`, "vault_mismatch");
|
|
2225
2317
|
}
|
|
2226
2318
|
if (!orderData.dstProtocolContractAddress || !isTrusted(params.destChain, orderData.dstProtocolContractAddress.chain.value)) {
|
|
2227
|
-
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}
|
|
2319
|
+
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}`, "vault_mismatch");
|
|
2228
2320
|
}
|
|
2229
2321
|
const deadlineMs = orderData.tradeStartDeadline * 1e3;
|
|
2230
|
-
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed");
|
|
2231
|
-
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute");
|
|
2322
|
+
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed", "quote_expired");
|
|
2323
|
+
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute", "quote_expired");
|
|
2232
2324
|
const inputScaled = BigInt(q.inputUnits) * 10n ** BigInt(dest.decimals);
|
|
2233
2325
|
const outputScaled = BigInt(q.outputUnits) * 10n ** BigInt(source.decimals);
|
|
2234
|
-
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input");
|
|
2235
|
-
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order");
|
|
2326
|
+
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input", "price_check_failed");
|
|
2327
|
+
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order", "policy_refused");
|
|
2236
2328
|
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "order" } })) {
|
|
2237
|
-
return refuse2("the platform reused a quote id that already holds another quote");
|
|
2329
|
+
return refuse2("the platform reused a quote id that already holds another quote", "policy_refused");
|
|
2238
2330
|
}
|
|
2239
2331
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
2240
2332
|
const feeUsd = feeUnits / 10 ** dest.decimals;
|
|
@@ -2265,29 +2357,29 @@ function omnistonProvider(opts = {}) {
|
|
|
2265
2357
|
*/
|
|
2266
2358
|
async buildDeposit(quote) {
|
|
2267
2359
|
if (!Number.isFinite(quote.validUntilMs) || quote.validUntilMs <= Date.now()) {
|
|
2268
|
-
throw
|
|
2360
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2269
2361
|
}
|
|
2270
2362
|
const decoded = decodeIntent(quote.intentId);
|
|
2271
2363
|
if (!decoded) throw new Error("omniston: malformed intent id");
|
|
2272
2364
|
const cached = await loadBuilt(decoded.quoteId);
|
|
2273
|
-
if (!cached) throw
|
|
2365
|
+
if (!cached) throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2274
2366
|
const ref = requireBinding(decoded, cached, "buildDeposit");
|
|
2275
2367
|
const q = cached.quote;
|
|
2276
2368
|
if (q.settlementData.$case === "swap") return await buildSwapDeposit(ref, q, q.settlementData.value);
|
|
2277
2369
|
if (q.settlementData.$case !== "order" || q.settlementData.value.tradeStartDeadline * 1e3 <= Date.now()) {
|
|
2278
|
-
throw
|
|
2370
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote trade deadline expired \u2014 request a fresh quote");
|
|
2279
2371
|
}
|
|
2280
2372
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
2281
2373
|
const srcCase = q.inputAsset.chain.$case;
|
|
2282
2374
|
if (srcCase !== "ton") return await buildEvmOrder(ref, q, q.settlementData.value, cached.bound);
|
|
2283
2375
|
const srcChain = ref.srcChain;
|
|
2284
|
-
if (!isTon(srcChain)) throw
|
|
2376
|
+
if (!isTon(srcChain)) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match TON quote");
|
|
2285
2377
|
const destCase = q.outputAsset.chain.$case;
|
|
2286
2378
|
const traderDst = destCase === "ton" ? null : { chain: { $case: destCase, value: (0, import_viem.getAddress)(ref.dest) } };
|
|
2287
|
-
if (!traderDst) throw
|
|
2379
|
+
if (!traderDst) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON-destination orders are not supported");
|
|
2288
2380
|
const minter = q.settlementData.value.srcProtocolContractAddress;
|
|
2289
2381
|
if (minter.chain.$case !== "ton" || !isTrusted(srcChain, minter.chain.value)) {
|
|
2290
|
-
throw
|
|
2382
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted TON settlement contract ${minter.chain.value}`);
|
|
2291
2383
|
}
|
|
2292
2384
|
const settlement = q.settlementData;
|
|
2293
2385
|
const hashingFunction = settlement.$case === "order" ? settlement.value.htlcHashingFunction : void 0;
|
|
@@ -2311,27 +2403,27 @@ function omnistonProvider(opts = {}) {
|
|
|
2311
2403
|
});
|
|
2312
2404
|
} catch (error) {
|
|
2313
2405
|
await forget();
|
|
2314
|
-
throw error;
|
|
2406
|
+
throw venueFailure(error);
|
|
2315
2407
|
}
|
|
2316
2408
|
const [message, ...rest] = tx.messages;
|
|
2317
2409
|
if (!message || rest.length > 0) {
|
|
2318
2410
|
await forget();
|
|
2319
|
-
throw
|
|
2411
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one escrow message, got ${tx.messages.length}`);
|
|
2320
2412
|
}
|
|
2321
2413
|
if (!isPositiveInteger(message.sendAmount) || BigInt(message.sendAmount) > BigInt(maxTonExecutionNano)) {
|
|
2322
2414
|
await forget();
|
|
2323
|
-
throw
|
|
2415
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver TON execution value exceeds the configured safety cap");
|
|
2324
2416
|
}
|
|
2325
2417
|
const expectedProtocol = q.settlementData.value.srcProtocolContractAddress;
|
|
2326
2418
|
const initialResolver = q.settlementData.value.srcInitialResolverAddress;
|
|
2327
2419
|
const jettonMaster = assetContract(q.inputAsset);
|
|
2328
2420
|
if (expectedProtocol.chain.$case !== "ton" || initialResolver?.chain.$case !== "ton" || !jettonMaster) {
|
|
2329
2421
|
await forget();
|
|
2330
|
-
throw
|
|
2422
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete TON settlement binding in quote");
|
|
2331
2423
|
}
|
|
2332
2424
|
if (message.jettonWalletStateInit) {
|
|
2333
2425
|
await forget();
|
|
2334
|
-
throw
|
|
2426
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
2335
2427
|
}
|
|
2336
2428
|
let walletValid = false;
|
|
2337
2429
|
try {
|
|
@@ -2346,11 +2438,11 @@ function omnistonProvider(opts = {}) {
|
|
|
2346
2438
|
}
|
|
2347
2439
|
if (!walletValid) {
|
|
2348
2440
|
await forget();
|
|
2349
|
-
throw
|
|
2441
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
2350
2442
|
}
|
|
2351
2443
|
try {
|
|
2352
2444
|
if (!opts.validateTonEscrowPayload) {
|
|
2353
|
-
throw
|
|
2445
|
+
throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON source requires an independent escrow-payload validator");
|
|
2354
2446
|
}
|
|
2355
2447
|
await validateTonEscrowPayload(message, {
|
|
2356
2448
|
quoteId: ref.quoteId,
|
|
@@ -2397,7 +2489,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2397
2489
|
const result = bindIntent(decoded, stored);
|
|
2398
2490
|
if (!result.ok && result.reason === "mismatch") {
|
|
2399
2491
|
trace("intent-mismatch", { where: "trackIntent", field: result.field });
|
|
2400
|
-
throw
|
|
2492
|
+
throw (0, import_errors.refusal)(mismatchReason(result.field), `omniston: intent id does not match the quote it was issued for (${result.field})`);
|
|
2401
2493
|
}
|
|
2402
2494
|
if (result.ok) {
|
|
2403
2495
|
if (result.legacy) trace("legacy-intent", { where: "trackIntent" });
|
|
@@ -2577,12 +2669,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2577
2669
|
if (!ref) throw new Error("omniston: malformed intent id");
|
|
2578
2670
|
const cached = await loadBuilt(ref.quoteId);
|
|
2579
2671
|
const order = cached?.evmOrder;
|
|
2580
|
-
if (!order) throw
|
|
2672
|
+
if (!order) throw (0, import_errors.refusal)("quote_expired", "omniston: no signed-order context for this quote \u2014 build the order again");
|
|
2581
2673
|
requireBinding(ref, cached, "registerSignedOrder");
|
|
2582
2674
|
if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) throw new Error("omniston: malformed order signature");
|
|
2583
2675
|
const td = JSON.parse(order.typedData);
|
|
2584
2676
|
const omni = await getClient();
|
|
2585
|
-
|
|
2677
|
+
const request = {
|
|
2586
2678
|
quoteId: ref.quoteId,
|
|
2587
2679
|
ownerSrcAddress: { chain: { $case: order.chainCase, value: order.owner } },
|
|
2588
2680
|
signedOrder: { order: { $case: "evmV1", value: {
|
|
@@ -2591,7 +2683,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2591
2683
|
orderExtension: hexToBytes(order.orderExtension)
|
|
2592
2684
|
} } },
|
|
2593
2685
|
...order.serializedOrderDetails ? { serializedOrderDetails: hexToBytes(order.serializedOrderDetails) } : {}
|
|
2594
|
-
}
|
|
2686
|
+
};
|
|
2687
|
+
try {
|
|
2688
|
+
await omni.orderRegisterSignedOrder(request);
|
|
2689
|
+
} catch (error) {
|
|
2690
|
+
throw venueFailure(error);
|
|
2691
|
+
}
|
|
2595
2692
|
},
|
|
2596
2693
|
close() {
|
|
2597
2694
|
clientGeneration += 1;
|