@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/index.cjs
CHANGED
|
@@ -511,6 +511,7 @@ var AUDITED_OMNISTON_EVM_ORDER_PROTOCOLS = {
|
|
|
511
511
|
};
|
|
512
512
|
|
|
513
513
|
// src/provider.ts
|
|
514
|
+
var import_errors = require("@anywalletkit/protocol-swap2-core/errors");
|
|
514
515
|
var import_core4 = require("@anywalletkit/core");
|
|
515
516
|
var EVM_CASE = {
|
|
516
517
|
1: "ethereum",
|
|
@@ -648,6 +649,54 @@ function encodeTypedMessage(td) {
|
|
|
648
649
|
(0, import_viem.encodeAbiParameters)([paramFor(td.primaryType)], [td.message])
|
|
649
650
|
);
|
|
650
651
|
}
|
|
652
|
+
function venueReason(error) {
|
|
653
|
+
const details = typeof error === "object" && error !== null ? error.details : void 0;
|
|
654
|
+
const info = typeof details === "object" && details !== null ? details.error_info : void 0;
|
|
655
|
+
if (typeof info !== "object" || info === null) return "upstream_unavailable";
|
|
656
|
+
const { reason, metadata } = info;
|
|
657
|
+
const meta = typeof metadata === "object" && metadata !== null ? metadata : {};
|
|
658
|
+
const type = typeof meta.type === "string" ? meta.type : "";
|
|
659
|
+
switch (reason) {
|
|
660
|
+
case "INVALID_ARGUMENT":
|
|
661
|
+
case "INVALID_PARAMETERS":
|
|
662
|
+
return void 0;
|
|
663
|
+
case "NOT_FOUND":
|
|
664
|
+
return typeof meta.object_type === "string" && meta.object_type.toLowerCase() === "quote" ? "quote_expired" : "upstream_unavailable";
|
|
665
|
+
case "UNSUPPORTED":
|
|
666
|
+
return "unsupported_pair";
|
|
667
|
+
case "SWAP_LIMIT_EXCEEDED":
|
|
668
|
+
return "amount_too_large";
|
|
669
|
+
case "QUOTE_VALIDATION_FAILED":
|
|
670
|
+
if (type === "EMULATION_UNSUPPORTED_TOKEN") return "unsupported_pair";
|
|
671
|
+
if (type === "EMULATION_WRONG_OUTPUT_AMOUNT" || type === "EMULATION_REFUND_SLIPPAGE") return "price_check_failed";
|
|
672
|
+
return type.startsWith("EMULATION_") ? "simulation_failed" : "upstream_unavailable";
|
|
673
|
+
default:
|
|
674
|
+
return "upstream_unavailable";
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function venueFailure(error) {
|
|
678
|
+
if (!(error instanceof Error)) return error;
|
|
679
|
+
const reason = venueReason(error);
|
|
680
|
+
return reason ? (0, import_errors.withReason)(error, reason) : error;
|
|
681
|
+
}
|
|
682
|
+
function mismatchReason(field) {
|
|
683
|
+
return field === "trader" || field === "dest" || field === "owner" ? "recipient_mismatch" : "policy_refused";
|
|
684
|
+
}
|
|
685
|
+
function tonSwapPayloadReason(code) {
|
|
686
|
+
switch (code) {
|
|
687
|
+
case "receiver-not-destination":
|
|
688
|
+
case "refund-not-trader":
|
|
689
|
+
case "excess-not-trader":
|
|
690
|
+
return "recipient_mismatch";
|
|
691
|
+
case "min-out-zero":
|
|
692
|
+
case "min-out-below-quote":
|
|
693
|
+
return "price_check_failed";
|
|
694
|
+
case "leg-unverified":
|
|
695
|
+
return "vault_mismatch";
|
|
696
|
+
default:
|
|
697
|
+
return "policy_refused";
|
|
698
|
+
}
|
|
699
|
+
}
|
|
651
700
|
function generateSecret() {
|
|
652
701
|
return crypto.getRandomValues(new Uint8Array(32));
|
|
653
702
|
}
|
|
@@ -658,7 +707,7 @@ function hashlock(secret, hashingFunction) {
|
|
|
658
707
|
case "HASHING_FUNCTION_SHA256":
|
|
659
708
|
return (0, import_viem.sha256)(secret, "bytes");
|
|
660
709
|
default:
|
|
661
|
-
throw
|
|
710
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: unsupported HTLC hashing function ${String(hashingFunction)}`);
|
|
662
711
|
}
|
|
663
712
|
}
|
|
664
713
|
function sameAsset(a, b) {
|
|
@@ -696,7 +745,7 @@ function stepJetton(asset) {
|
|
|
696
745
|
}
|
|
697
746
|
function readBigEndian(bytes, offset, length) {
|
|
698
747
|
if (!Number.isInteger(offset) || !Number.isInteger(length) || length < 1 || offset < 0 || offset + length > bytes.length) {
|
|
699
|
-
throw
|
|
748
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: truncated EVM order extension");
|
|
700
749
|
}
|
|
701
750
|
let value = 0n;
|
|
702
751
|
for (let index = offset; index < offset + length; index++) value = value << 8n | BigInt(bytes[index]);
|
|
@@ -741,30 +790,30 @@ var EVM_DEST_PROTOCOL_FEE_RECIPIENTS = /* @__PURE__ */ new Set(["0x076268146b4ec
|
|
|
741
790
|
var EVM_AUCTION_POINTS = [[800000n, 100n], [700000n, 100n], [600000n, 100n], [500000n, 100n], [400000n, 100n]];
|
|
742
791
|
var EVM_TIMELOCKS = [1n, 120n, 240n, 300n, 1n, 120n, 180n, 0n].reduce((packed, value, index) => packed | value << BigInt(index * 32), 0n);
|
|
743
792
|
function readEvmOrderExtension(extension) {
|
|
744
|
-
if (extension.length < 32) throw
|
|
793
|
+
if (extension.length < 32) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension");
|
|
745
794
|
const view = new DataView(extension.buffer, extension.byteOffset, extension.byteLength);
|
|
746
795
|
const fields = [];
|
|
747
796
|
let begin = 0;
|
|
748
797
|
const concatLength = extension.length - 32;
|
|
749
798
|
for (let index = 0; index < 8; index++) {
|
|
750
799
|
const end2 = view.getUint32(28 - index * 4, false);
|
|
751
|
-
if (end2 < begin || end2 > concatLength) throw
|
|
800
|
+
if (end2 < begin || end2 > concatLength) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension offsets");
|
|
752
801
|
fields.push(extension.slice(32 + begin, 32 + end2));
|
|
753
802
|
begin = end2;
|
|
754
803
|
}
|
|
755
804
|
for (const index of [0, 1, 4, 5, 6]) {
|
|
756
|
-
if (fields[index].length !== 0) throw
|
|
805
|
+
if (fields[index].length !== 0) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM order extension field");
|
|
757
806
|
}
|
|
758
807
|
if (!sliceEqual(fields[2], fields[3])) {
|
|
759
|
-
throw
|
|
808
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: making/taking amount getters use different programs");
|
|
760
809
|
}
|
|
761
810
|
let target;
|
|
762
811
|
for (const index of [2, 3, 7]) {
|
|
763
812
|
const field2 = fields[index];
|
|
764
|
-
if (field2.length <= 20) throw
|
|
813
|
+
if (field2.length <= 20) throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete EVM order extension program");
|
|
765
814
|
const address = (0, import_viem.getAddress)(`0x${bytesToHex(field2.slice(0, 20))}`);
|
|
766
815
|
if (target !== void 0 && (0, import_viem.getAddress)(target) !== address) {
|
|
767
|
-
throw
|
|
816
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
768
817
|
}
|
|
769
818
|
target = address;
|
|
770
819
|
}
|
|
@@ -782,7 +831,7 @@ function readEvmOrderExtension(extension) {
|
|
|
782
831
|
cursor += 3;
|
|
783
832
|
const pointCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
784
833
|
cursor += 1;
|
|
785
|
-
if (pointCount !== 5) throw
|
|
834
|
+
if (pointCount !== 5) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported EVM auction profile");
|
|
786
835
|
const points = [];
|
|
787
836
|
for (let index = 0; index < pointCount; index++) {
|
|
788
837
|
points.push([readBigEndian(field, cursor, 3), readBigEndian(field, cursor + 3, 2)]);
|
|
@@ -799,7 +848,7 @@ function readEvmOrderExtension(extension) {
|
|
|
799
848
|
const getterWhitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(field, cursor, 1));
|
|
800
849
|
cursor += 1;
|
|
801
850
|
if (getterWhitelistCount !== 1 || cursor + getterWhitelistCount * 10 !== field.length) {
|
|
802
|
-
throw
|
|
851
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM amount-getter whitelist");
|
|
803
852
|
}
|
|
804
853
|
const getter = { gasBump, gasPrice, auctionStart, duration, initialRateBump, points, integratorFee, integratorShare, resolverFee, whitelistDiscount, resolver: readBigEndian(field, cursor, 10) };
|
|
805
854
|
const post = fields[7];
|
|
@@ -821,7 +870,7 @@ function readEvmOrderExtension(extension) {
|
|
|
821
870
|
const whitelistCount = (0, import_core4.bigintToNumber)(readBigEndian(post, cursor, 1));
|
|
822
871
|
cursor += 1;
|
|
823
872
|
if (whitelistCount !== 1 || cursor + whitelistCount * 12 + 160 !== post.length) {
|
|
824
|
-
throw
|
|
873
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM post-interaction whitelist");
|
|
825
874
|
}
|
|
826
875
|
const postResolver = readBigEndian(post, cursor, 10);
|
|
827
876
|
cursor += 10;
|
|
@@ -833,7 +882,7 @@ function readEvmOrderExtension(extension) {
|
|
|
833
882
|
return value;
|
|
834
883
|
});
|
|
835
884
|
const customData = extension.slice(32 + begin);
|
|
836
|
-
if (customData.length !== 131) throw
|
|
885
|
+
if (customData.length !== 131) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order extension custom data");
|
|
837
886
|
return {
|
|
838
887
|
target,
|
|
839
888
|
getter,
|
|
@@ -846,29 +895,29 @@ async function validateEvmToTonOrderExtension(extension, expected) {
|
|
|
846
895
|
const evmDest = expected.dstChainId !== void 0;
|
|
847
896
|
if (evmDest && (!Number.isSafeInteger(expected.dstChainId) || expected.dstChainId <= 0)) throw new Error("omniston: invalid EVM destination chain id");
|
|
848
897
|
const { target, getter, post, extra, customData } = readEvmOrderExtension(extension);
|
|
849
|
-
if (!expected.trustedTarget(target)) throw
|
|
898
|
+
if (!expected.trustedTarget(target)) throw (0, import_errors.refusal)("vault_mismatch", "omniston: EVM order extension target is not independently trusted");
|
|
850
899
|
const quoteResolverFee = expected.protocolFeePips % 10 === 0 ? BigInt(expected.protocolFeePips / 10) : -1n;
|
|
851
900
|
const resolverLow80 = BigInt((0, import_viem.getAddress)(expected.initialResolverAddress)) & (1n << 80n) - 1n;
|
|
852
901
|
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) {
|
|
853
|
-
throw
|
|
902
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM amount-getter terms do not match the pinned v1beta8 profile");
|
|
854
903
|
}
|
|
855
904
|
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) {
|
|
856
|
-
throw
|
|
905
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM post-interaction terms do not match the pinned v1beta8 profile");
|
|
857
906
|
}
|
|
858
907
|
const hashlock2 = readBigEndian(expected.secretHash, 0, expected.secretHash.length);
|
|
859
908
|
const dstToken = evmDest ? BigInt((0, import_viem.getAddress)(expected.outputTokenAddress)) : BigInt((0, import_viem.getAddress)(expected.takerAsset));
|
|
860
909
|
const deposits = BigInt(expected.srcSecurityDepositUnits) << 128n | BigInt(expected.dstSecurityDepositUnits);
|
|
861
910
|
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) {
|
|
862
|
-
throw
|
|
911
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: signed EVM HTLC terms do not match the validated order details");
|
|
863
912
|
}
|
|
864
913
|
await checkOrderCustomData(customData, { evmDest, outputToken: expected.outputTokenAddress, traderDst: expected.traderDstAddress, quoteId: expected.quoteId });
|
|
865
914
|
if (expected.tradeStartDeadline < expected.quoteTimestamp) {
|
|
866
|
-
throw
|
|
915
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: invalid EVM order quote deadline");
|
|
867
916
|
}
|
|
868
917
|
}
|
|
869
918
|
async function checkOrderCustomData(customData, expected) {
|
|
870
919
|
if (expected.evmDest) {
|
|
871
|
-
if (!zeroBytes(customData.slice(0, 66))) throw
|
|
920
|
+
if (!zeroBytes(customData.slice(0, 66))) throw (0, import_errors.refusal)("recipient_mismatch", "omniston: unexpected TON addresses in an EVM-destination order");
|
|
872
921
|
} else {
|
|
873
922
|
const { Address: Address3 } = await import("@ton/core");
|
|
874
923
|
const expectedTon = [expected.outputToken, expected.traderDst].map((value) => Address3.parse(value));
|
|
@@ -876,16 +925,16 @@ async function checkOrderCustomData(customData, expected) {
|
|
|
876
925
|
const offset = index * 33;
|
|
877
926
|
const workchain = customData[offset] === 255 ? -1 : customData[offset];
|
|
878
927
|
if (workchain !== expectedTon[index].workChain || !sliceEqual(customData.slice(offset + 1, offset + 33), expectedTon[index].hash)) {
|
|
879
|
-
throw
|
|
928
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: signed EVM\u2192TON address does not match the validated request");
|
|
880
929
|
}
|
|
881
930
|
}
|
|
882
931
|
}
|
|
883
932
|
if (!zeroBytes(customData.slice(66, 99))) {
|
|
884
|
-
throw
|
|
933
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unexpected private TON disclosure address");
|
|
885
934
|
}
|
|
886
935
|
const quoteId = expected.quoteId.replace(/^0x/, "");
|
|
887
936
|
if (!QUOTE_ID.test(quoteId) || !sliceEqual(customData.slice(99), hexToBytes(quoteId.padStart(64, "0")))) {
|
|
888
|
-
throw
|
|
937
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order extension custom data is not bound to the quote id");
|
|
889
938
|
}
|
|
890
939
|
}
|
|
891
940
|
function validateEvmTypedOrder(td, expected) {
|
|
@@ -907,7 +956,7 @@ function validateEvmTypedOrder(td, expected) {
|
|
|
907
956
|
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
|
|
908
957
|
// skew between the quote and the order builder), never later.
|
|
909
958
|
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)) {
|
|
910
|
-
throw
|
|
959
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: EVM order fields do not match the validated quote/request");
|
|
911
960
|
}
|
|
912
961
|
}
|
|
913
962
|
async function validateTonEscrowPayload(message, expected, validateForwardPayload) {
|
|
@@ -917,9 +966,9 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
917
966
|
try {
|
|
918
967
|
roots = Cell2.fromBoc(import_buffer2.Buffer.from(boc));
|
|
919
968
|
} catch {
|
|
920
|
-
throw
|
|
969
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed TON escrow BoC");
|
|
921
970
|
}
|
|
922
|
-
if (roots.length !== 1) throw
|
|
971
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow must contain exactly one root cell");
|
|
923
972
|
const slice = roots[0].beginParse();
|
|
924
973
|
const op = slice.loadUint(32);
|
|
925
974
|
slice.loadUintBig(64);
|
|
@@ -930,7 +979,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
930
979
|
const forwardAmount = slice.loadCoins();
|
|
931
980
|
const payloadByRef = slice.loadBit();
|
|
932
981
|
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) {
|
|
933
|
-
throw
|
|
982
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: TON jetton transfer does not match the validated quote/request");
|
|
934
983
|
}
|
|
935
984
|
const forwardPayload = slice.loadRef();
|
|
936
985
|
const verified = await validateForwardPayload({
|
|
@@ -950,7 +999,7 @@ async function validateTonEscrowPayload(message, expected, validateForwardPayloa
|
|
|
950
999
|
...expected.hashingFunction ? { hashingFunction: expected.hashingFunction } : {},
|
|
951
1000
|
exclusivityTimeout: expected.exclusivityTimeout
|
|
952
1001
|
});
|
|
953
|
-
if (!verified) throw
|
|
1002
|
+
if (!verified) throw (0, import_errors.refusal)("policy_refused", "omniston: TON escrow forward payload failed independent semantic validation");
|
|
954
1003
|
}
|
|
955
1004
|
function feeToken(asset) {
|
|
956
1005
|
return asset.assetId || asset.contract || asset.symbol;
|
|
@@ -980,24 +1029,24 @@ var ProtoReader = class {
|
|
|
980
1029
|
const byte = this.bytes[this.pos++];
|
|
981
1030
|
out += (byte & 127) * 2 ** shift;
|
|
982
1031
|
if ((byte & 128) === 0) {
|
|
983
|
-
if (!Number.isSafeInteger(out)) throw
|
|
1032
|
+
if (!Number.isSafeInteger(out)) throw (0, import_errors.refusal)("policy_refused", "omniston: unsafe protobuf varint");
|
|
984
1033
|
return out;
|
|
985
1034
|
}
|
|
986
1035
|
shift += 7;
|
|
987
1036
|
}
|
|
988
|
-
throw
|
|
1037
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf varint");
|
|
989
1038
|
}
|
|
990
1039
|
field() {
|
|
991
1040
|
const tag = this.varint();
|
|
992
1041
|
const number = Math.floor(tag / 8);
|
|
993
1042
|
const wire = tag & 7;
|
|
994
|
-
if (number < 1) throw
|
|
1043
|
+
if (number < 1) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed protobuf field");
|
|
995
1044
|
return { number, wire };
|
|
996
1045
|
}
|
|
997
1046
|
lengthDelimited() {
|
|
998
1047
|
const length = this.varint();
|
|
999
1048
|
const end2 = this.pos + length;
|
|
1000
|
-
if (length < 0 || end2 > this.bytes.length) throw
|
|
1049
|
+
if (length < 0 || end2 > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
1001
1050
|
const value = this.bytes.slice(this.pos, end2);
|
|
1002
1051
|
this.pos = end2;
|
|
1003
1052
|
return value;
|
|
@@ -1019,10 +1068,10 @@ var ProtoReader = class {
|
|
|
1019
1068
|
this.advance(4);
|
|
1020
1069
|
return;
|
|
1021
1070
|
}
|
|
1022
|
-
throw
|
|
1071
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported protobuf wire type");
|
|
1023
1072
|
}
|
|
1024
1073
|
advance(length) {
|
|
1025
|
-
if (this.pos + length > this.bytes.length) throw
|
|
1074
|
+
if (this.pos + length > this.bytes.length) throw (0, import_errors.refusal)("policy_refused", "omniston: truncated protobuf payload");
|
|
1026
1075
|
this.pos += length;
|
|
1027
1076
|
}
|
|
1028
1077
|
};
|
|
@@ -1049,10 +1098,10 @@ function decodeChainAddress(bytes) {
|
|
|
1049
1098
|
while (!reader.done) {
|
|
1050
1099
|
const { number, wire } = reader.field();
|
|
1051
1100
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
1052
|
-
if (!$case || wire !== 2 || address) throw
|
|
1101
|
+
if (!$case || wire !== 2 || address) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed chain address in order details");
|
|
1053
1102
|
address = { chain: { $case, value: utf8.decode(reader.lengthDelimited()) } };
|
|
1054
1103
|
}
|
|
1055
|
-
if (!address?.chain.value) throw
|
|
1104
|
+
if (!address?.chain.value) throw (0, import_errors.refusal)("policy_refused", "omniston: empty chain address in order details");
|
|
1056
1105
|
return address;
|
|
1057
1106
|
}
|
|
1058
1107
|
function decodeAssetId(bytes) {
|
|
@@ -1061,27 +1110,27 @@ function decodeAssetId(bytes) {
|
|
|
1061
1110
|
while (!reader.done) {
|
|
1062
1111
|
const { number, wire } = reader.field();
|
|
1063
1112
|
const $case = PROTO_CASE_BY_FIELD[number];
|
|
1064
|
-
if (!$case || wire !== 2 || asset) throw
|
|
1113
|
+
if (!$case || wire !== 2 || asset) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset id in order details");
|
|
1065
1114
|
const kindReader = new ProtoReader(reader.lengthDelimited());
|
|
1066
1115
|
const kindField = kindReader.field();
|
|
1067
1116
|
if (kindField.wire !== 2 || kindField.number !== 1 && kindField.number !== 2) {
|
|
1068
|
-
throw
|
|
1117
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported asset kind in order details");
|
|
1069
1118
|
}
|
|
1070
1119
|
const kindCase = kindField.number === 1 ? "native" : $case === "ton" ? "jetton" : $case === "tron" ? "trc20" : "erc20";
|
|
1071
1120
|
const value = kindField.number === 1 ? {} : utf8.decode(kindReader.lengthDelimited());
|
|
1072
|
-
if (!kindReader.done || kindField.number === 2 && !value) throw
|
|
1121
|
+
if (!kindReader.done || kindField.number === 2 && !value) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed asset kind in order details");
|
|
1073
1122
|
asset = { chain: { $case, value: { kind: { $case: kindCase, value } } } };
|
|
1074
1123
|
}
|
|
1075
|
-
if (!asset) throw
|
|
1124
|
+
if (!asset) throw (0, import_errors.refusal)("policy_refused", "omniston: empty asset id in order details");
|
|
1076
1125
|
return asset;
|
|
1077
1126
|
}
|
|
1078
1127
|
function validateSerializedOrderDetails(bytes, expected) {
|
|
1079
|
-
if (!bytes?.length) throw
|
|
1128
|
+
if (!bytes?.length) throw (0, import_errors.refusal)("policy_refused", "omniston: EVM HTLC order payload has no serialized details");
|
|
1080
1129
|
const wrapper = new ProtoReader(bytes);
|
|
1081
1130
|
const outer = wrapper.field();
|
|
1082
|
-
if (outer.number !== 1 || outer.wire !== 2) throw
|
|
1131
|
+
if (outer.number !== 1 || outer.wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: unsupported HTLC order-details version");
|
|
1083
1132
|
const detailsBytes = wrapper.lengthDelimited();
|
|
1084
|
-
if (!wrapper.done) throw
|
|
1133
|
+
if (!wrapper.done) throw (0, import_errors.refusal)("policy_refused", "omniston: ambiguous HTLC order-details wrapper");
|
|
1085
1134
|
const reader = new ProtoReader(detailsBytes);
|
|
1086
1135
|
let quoteId;
|
|
1087
1136
|
let outputAsset;
|
|
@@ -1089,16 +1138,16 @@ function validateSerializedOrderDetails(bytes, expected) {
|
|
|
1089
1138
|
const hashes = [];
|
|
1090
1139
|
while (!reader.done) {
|
|
1091
1140
|
const { number, wire } = reader.field();
|
|
1092
|
-
if (wire !== 2) throw
|
|
1141
|
+
if (wire !== 2) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed HTLC order details");
|
|
1093
1142
|
const value = reader.lengthDelimited();
|
|
1094
1143
|
if (number === 1 && quoteId === void 0) quoteId = utf8.decode(value);
|
|
1095
1144
|
else if (number === 2 && outputAsset === void 0) outputAsset = decodeAssetId(value);
|
|
1096
1145
|
else if (number === 3 && traderDstAddress === void 0) traderDstAddress = decodeChainAddress(value);
|
|
1097
1146
|
else if (number === 5) hashes.push(value);
|
|
1098
|
-
else throw
|
|
1147
|
+
else throw (0, import_errors.refusal)("policy_refused", "omniston: duplicate or unexpected HTLC order-details field");
|
|
1099
1148
|
}
|
|
1100
1149
|
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]))) {
|
|
1101
|
-
throw
|
|
1150
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver order payload does not match the validated quote/request");
|
|
1102
1151
|
}
|
|
1103
1152
|
}
|
|
1104
1153
|
function isPositiveInteger(value) {
|
|
@@ -1129,7 +1178,7 @@ function bytesToHex(bytes) {
|
|
|
1129
1178
|
function hexToBytes(hex) {
|
|
1130
1179
|
const clean = hex.replace(/^0x/, "");
|
|
1131
1180
|
if (!clean || !/^(?:[0-9a-fA-F]{2})+$/.test(clean)) {
|
|
1132
|
-
throw
|
|
1181
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed hex payload");
|
|
1133
1182
|
}
|
|
1134
1183
|
const out = new Uint8Array(clean.length / 2);
|
|
1135
1184
|
for (let i = 0; i < out.length; i++) out[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
@@ -1163,6 +1212,14 @@ function swapProtocols(v) {
|
|
|
1163
1212
|
for (const route of v.routes) for (const step of route.steps) for (const chunk of step.chunks) names.add(chunk.protocol);
|
|
1164
1213
|
return [...names];
|
|
1165
1214
|
}
|
|
1215
|
+
function rejectionReason(rejection) {
|
|
1216
|
+
return rejection === "quote timestamp out of range" ? "quote_expired" : "upstream_unavailable";
|
|
1217
|
+
}
|
|
1218
|
+
function rfqReason(outcome) {
|
|
1219
|
+
if (outcome.error) return outcome.errorReason;
|
|
1220
|
+
if (outcome.rejected) return rejectionReason(outcome.rejected);
|
|
1221
|
+
return outcome.answered ? "no_route" : "upstream_unavailable";
|
|
1222
|
+
}
|
|
1166
1223
|
function quoteRejection(q, update, acknowledgedRfqId, request, settlement) {
|
|
1167
1224
|
if (!q) return "empty quote";
|
|
1168
1225
|
if (!acknowledgedRfqId || update.rfqId !== acknowledgedRfqId || q.rfqId !== acknowledgedRfqId) return "quote for another RFQ";
|
|
@@ -1202,6 +1259,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1202
1259
|
const max = setTimeout(() => finish(latest), QUOTE_MAX_MS);
|
|
1203
1260
|
sub = stream.subscribe({
|
|
1204
1261
|
next: (event) => {
|
|
1262
|
+
if (event.$case === "ack" || event.$case === "quoteUpdated" || event.$case === "noQuote") outcome.answered = true;
|
|
1205
1263
|
if (event.$case === "ack") {
|
|
1206
1264
|
acknowledgedRfqId = event.value.rfqId || null;
|
|
1207
1265
|
} else if (event.$case === "quoteUpdated") {
|
|
@@ -1221,6 +1279,7 @@ function awaitQuote(stream, request, signal, settleMs = QUOTE_SETTLE_MS, settlem
|
|
|
1221
1279
|
},
|
|
1222
1280
|
error: (err) => {
|
|
1223
1281
|
outcome.error = String(err?.message ?? err).slice(0, 200);
|
|
1282
|
+
outcome.errorReason = venueReason(err);
|
|
1224
1283
|
finish(null);
|
|
1225
1284
|
},
|
|
1226
1285
|
complete: () => finish(latest)
|
|
@@ -1262,9 +1321,9 @@ function awaitSwapProgress(stream) {
|
|
|
1262
1321
|
}
|
|
1263
1322
|
var JETTON_TRANSFER_OP = 260734629;
|
|
1264
1323
|
function parseSwapPayload(payloadHex) {
|
|
1265
|
-
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw
|
|
1324
|
+
if (!/^(?:[0-9a-fA-F]{2})+$/.test(payloadHex)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap payload hex");
|
|
1266
1325
|
const roots = import_core3.Cell.fromBoc(import_buffer2.Buffer.from(payloadHex, "hex"));
|
|
1267
|
-
if (roots.length !== 1) throw
|
|
1326
|
+
if (roots.length !== 1) throw (0, import_errors.refusal)("policy_refused", "omniston: swap payload must have one root");
|
|
1268
1327
|
const s = roots[0].beginParse();
|
|
1269
1328
|
const op = s.loadUint(32);
|
|
1270
1329
|
if (op !== JETTON_TRANSFER_OP) return { op, jettonTransfer: null };
|
|
@@ -1336,86 +1395,108 @@ function mapOrderStatus(order) {
|
|
|
1336
1395
|
}
|
|
1337
1396
|
function omnistonPins(trustedEvmOrderProtocols) {
|
|
1338
1397
|
const byChain = new Map(Object.entries(trustedEvmOrderProtocols).map(([chain, list]) => [chain, list.map((a) => (0, import_viem.getAddress)(a))]));
|
|
1339
|
-
return Object.freeze({
|
|
1398
|
+
return Object.freeze({
|
|
1399
|
+
callTargets: () => [],
|
|
1400
|
+
spenders: (chain) => byChain.get(chain) ?? [],
|
|
1401
|
+
// The reason behind a text omnistonVerifyBuild returned, so the remote stub's refusal carries it.
|
|
1402
|
+
reasonOf: verifyNotes.reasonOf
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
var VERIFY_NOTES = /* @__PURE__ */ Symbol.for("@anywalletkit/protocol-swap2-omniston/verify-notes@1");
|
|
1406
|
+
var verifyNotes = (() => {
|
|
1407
|
+
const shared = globalThis[VERIFY_NOTES];
|
|
1408
|
+
if (shared && typeof shared.note === "function" && typeof shared.reasonOf === "function") return shared;
|
|
1409
|
+
const notes = (0, import_errors.refusalNotes)();
|
|
1410
|
+
try {
|
|
1411
|
+
Object.defineProperty(globalThis, VERIFY_NOTES, { value: notes });
|
|
1412
|
+
} catch {
|
|
1413
|
+
}
|
|
1414
|
+
return notes;
|
|
1415
|
+
})();
|
|
1416
|
+
var said = verifyNotes.note;
|
|
1417
|
+
function tonEscrowBuildReason(text) {
|
|
1418
|
+
if (text.startsWith("the escrow transfer pays ")) return "vault_mismatch";
|
|
1419
|
+
if (text.startsWith("the resolver is bound to deliver ")) return "price_check_failed";
|
|
1420
|
+
return "policy_refused";
|
|
1340
1421
|
}
|
|
1341
1422
|
var MAX_EVM_ORDER_LIFETIME_S = 900;
|
|
1342
1423
|
async function checkRemoteEvmOrder(quote, tx, params, trusted) {
|
|
1343
1424
|
const chainId = evmRef2(params.sourceChain);
|
|
1344
|
-
if (chainId === null || !params.sourceChain.startsWith("eip155:")) return "a typed order needs an EVM source";
|
|
1425
|
+
if (chainId === null || !params.sourceChain.startsWith("eip155:")) return said("a typed order needs an EVM source", "policy_refused");
|
|
1345
1426
|
const intent = decodeIntent(quote.intentId.replace(/~[0-9a-f]{32}$/, ""));
|
|
1346
|
-
if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return "the quote's intent is not an order from this chain";
|
|
1347
|
-
if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return "the build carries no order extension to check";
|
|
1427
|
+
if (!intent || intent.kind !== "order" || intent.srcChain !== params.sourceChain) return said("the quote's intent is not an order from this chain", "policy_refused");
|
|
1428
|
+
if (!tx.orderExtension || !/^0x(?:[0-9a-fA-F]{2})+$/.test(tx.orderExtension)) return said("the build carries no order extension to check", "policy_refused");
|
|
1348
1429
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1349
|
-
if (!source?.contract) return "unknown source token";
|
|
1430
|
+
if (!source?.contract) return said("unknown source token", "unsupported_pair");
|
|
1350
1431
|
const tonDest = isTon(params.destChain);
|
|
1351
1432
|
const destChainId = tonDest ? null : evmRef2(params.destChain);
|
|
1352
|
-
if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return "the destination is neither TON nor an EVM chain";
|
|
1433
|
+
if (!tonDest && (destChainId === null || !params.destChain.startsWith("eip155:"))) return said("the destination is neither TON nor an EVM chain", "unsupported_pair");
|
|
1353
1434
|
const outputToken = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken)?.contract ?? params.destToken;
|
|
1354
1435
|
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));
|
|
1355
1436
|
let td;
|
|
1356
1437
|
try {
|
|
1357
1438
|
td = JSON.parse(tx.typedData ?? "");
|
|
1358
1439
|
} catch {
|
|
1359
|
-
return "the typed data is not JSON";
|
|
1440
|
+
return said("the typed data is not JSON", "policy_refused");
|
|
1360
1441
|
}
|
|
1361
1442
|
const domain = td.domain ?? {};
|
|
1362
1443
|
const contract = domain.verifyingContract;
|
|
1363
|
-
if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return "the domain is not the 1inch Limit Order Protocol v4";
|
|
1444
|
+
if (domain.name !== "1inch Limit Order Protocol" || domain.version !== "4") return said("the domain is not the 1inch Limit Order Protocol v4", "policy_refused");
|
|
1364
1445
|
if (!listed(trusted.orderProtocols, params.sourceChain, contract) || !tx.approvalAddress || (0, import_viem.getAddress)(tx.approvalAddress) !== (0, import_viem.getAddress)(String(contract))) {
|
|
1365
|
-
return `${String(contract)} is not a trusted order protocol on ${params.sourceChain}
|
|
1446
|
+
return said(`${String(contract)} is not a trusted order protocol on ${params.sourceChain}`, "vault_mismatch");
|
|
1366
1447
|
}
|
|
1367
|
-
if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return "the domain chainId is not the source chain";
|
|
1448
|
+
if (Number(domain.chainId) !== chainId || tx.chainId !== void 0 && tx.chainId !== chainId) return said("the domain chainId is not the source chain", "policy_refused");
|
|
1368
1449
|
const order = td.types?.Order;
|
|
1369
1450
|
const message = td.message;
|
|
1370
1451
|
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]))) {
|
|
1371
|
-
return "the typed data is not exactly a v4 Order";
|
|
1452
|
+
return said("the typed data is not exactly a v4 Order", "policy_refused");
|
|
1372
1453
|
}
|
|
1373
|
-
if (!validEvmAddress(intent.trader) || (0, import_viem.getAddress)(String(message.maker)) !== (0, import_viem.getAddress)(intent.trader)) return "the maker is not the trader";
|
|
1374
|
-
if ((0, import_viem.getAddress)(String(message.makerAsset)) !== (0, import_viem.getAddress)(source.contract)) return "the makerAsset is not the source token";
|
|
1375
|
-
if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return "the makingAmount is not the input";
|
|
1376
|
-
if ((0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(String(message.makerAsset))) return "the takerAsset is the makerAsset";
|
|
1454
|
+
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");
|
|
1455
|
+
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");
|
|
1456
|
+
if (BigInt(message.makingAmount) !== BigInt(quote.sourceAmount)) return said("the makingAmount is not the input", "policy_refused");
|
|
1457
|
+
if ((0, import_viem.getAddress)(String(message.takerAsset)) === (0, import_viem.getAddress)(String(message.makerAsset))) return said("the takerAsset is the makerAsset", "policy_refused");
|
|
1377
1458
|
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);
|
|
1378
|
-
if (floor <= 0n || BigInt(message.takingAmount) < floor) return `takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}
|
|
1459
|
+
if (floor <= 0n || BigInt(message.takingAmount) < floor) return said(`takingAmount ${String(message.takingAmount)} is below the quote's minimum ${floor}`, "price_check_failed");
|
|
1379
1460
|
const traits = BigInt(message.makerTraits);
|
|
1380
1461
|
const flags = traits & (1n << 56n) - 1n << 200n;
|
|
1381
1462
|
const baseFlags = 1n << 251n | 1n << 249n;
|
|
1382
|
-
if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return "the makerTraits flags are not a single-fill order with its extension";
|
|
1383
|
-
if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return "the makerTraits restrict the taker or the series";
|
|
1463
|
+
if (flags !== baseFlags && flags !== (baseFlags | 1n << 255n)) return said("the makerTraits flags are not a single-fill order with its extension", "policy_refused");
|
|
1464
|
+
if ((traits & (1n << 80n) - 1n) !== 0n || (traits >> 160n & (1n << 40n) - 1n) !== 0n) return said("the makerTraits restrict the taker or the series", "policy_refused");
|
|
1384
1465
|
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1385
1466
|
const expiration = traits >> 80n & (1n << 40n) - 1n;
|
|
1386
|
-
if (expiration <= now || expiration > now + BigInt(MAX_EVM_ORDER_LIFETIME_S)) return "the order's expiry is not minutes away";
|
|
1467
|
+
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");
|
|
1387
1468
|
const extension = (0, import_viem.hexToBytes)(tx.orderExtension);
|
|
1388
1469
|
const mask = (1n << 160n) - 1n;
|
|
1389
|
-
if ((BigInt(message.salt) & mask) !== (BigInt((0, import_viem.keccak256)(extension)) & mask)) return "the salt does not commit the order extension";
|
|
1470
|
+
if ((BigInt(message.salt) & mask) !== (BigInt((0, import_viem.keccak256)(extension)) & mask)) return said("the salt does not commit the order extension", "policy_refused");
|
|
1390
1471
|
let parsed;
|
|
1391
1472
|
try {
|
|
1392
1473
|
parsed = readEvmOrderExtension(extension);
|
|
1393
1474
|
} catch (e) {
|
|
1394
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1475
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), (0, import_errors.refusalOf)(e) ?? "policy_refused");
|
|
1395
1476
|
}
|
|
1396
1477
|
const { target, getter, post, extra, customData } = parsed;
|
|
1397
|
-
if (!listed(trusted.factories, params.sourceChain, target)) return `the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}
|
|
1478
|
+
if (!listed(trusted.factories, params.sourceChain, target)) return said(`the extension targets ${target}, not a trusted escrow factory on ${params.sourceChain}`, "vault_mismatch");
|
|
1398
1479
|
const receiverLow80 = BigInt((0, import_viem.getAddress)(String(message.receiver))) & (1n << 80n) - 1n;
|
|
1399
|
-
if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return "the order's receiver is not the resolver its extension whitelists";
|
|
1480
|
+
if (getter.resolver !== receiverLow80 || post.resolver !== receiverLow80) return said("the order's receiver is not the resolver its extension whitelists", "recipient_mismatch");
|
|
1400
1481
|
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)) {
|
|
1401
|
-
return "the amount-getter terms do not match the pinned v1beta8 profile";
|
|
1482
|
+
return said("the amount-getter terms do not match the pinned v1beta8 profile", "policy_refused");
|
|
1402
1483
|
}
|
|
1403
1484
|
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)) {
|
|
1404
|
-
return "the post-interaction terms do not match the pinned v1beta8 profile";
|
|
1485
|
+
return said("the post-interaction terms do not match the pinned v1beta8 profile", "policy_refused");
|
|
1405
1486
|
}
|
|
1406
1487
|
let dstToken;
|
|
1407
1488
|
try {
|
|
1408
1489
|
dstToken = tonDest ? BigInt((0, import_viem.getAddress)(String(message.takerAsset))) : BigInt((0, import_viem.getAddress)(outputToken));
|
|
1409
1490
|
} catch {
|
|
1410
|
-
return "the destination token is not an EVM address";
|
|
1491
|
+
return said("the destination token is not an EVM address", "policy_refused");
|
|
1411
1492
|
}
|
|
1412
1493
|
if (extra[1] !== (tonDest ? 0n : BigInt(destChainId)) || extra[2] !== dstToken || extra[4] !== EVM_TIMELOCKS) {
|
|
1413
|
-
return "the signed HTLC terms name another destination chain or token, or other timelocks";
|
|
1494
|
+
return said("the signed HTLC terms name another destination chain or token, or other timelocks", "policy_refused");
|
|
1414
1495
|
}
|
|
1415
1496
|
try {
|
|
1416
1497
|
await checkOrderCustomData(customData, { evmDest: !tonDest, outputToken, traderDst: params.destAddress, quoteId: intent.quoteId });
|
|
1417
1498
|
} catch (e) {
|
|
1418
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1499
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), (0, import_errors.refusalOf)(e) ?? "policy_refused");
|
|
1419
1500
|
}
|
|
1420
1501
|
return null;
|
|
1421
1502
|
}
|
|
@@ -1426,22 +1507,22 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1426
1507
|
};
|
|
1427
1508
|
return async (quote, tx, params) => {
|
|
1428
1509
|
if (tx.typedData !== void 0) {
|
|
1429
|
-
if (!params) return "the request this quote answered is unknown";
|
|
1510
|
+
if (!params) return said("the request this quote answered is unknown", "policy_refused");
|
|
1430
1511
|
try {
|
|
1431
1512
|
return await checkRemoteEvmOrder(quote, tx, params, trusted);
|
|
1432
1513
|
} catch {
|
|
1433
|
-
return "the typed order could not be checked";
|
|
1514
|
+
return said("the typed order could not be checked", "policy_refused");
|
|
1434
1515
|
}
|
|
1435
1516
|
}
|
|
1436
1517
|
if (tx.bodyBoc === void 0) return null;
|
|
1437
|
-
if (!params) return "the request this quote answered is unknown";
|
|
1518
|
+
if (!params) return said("the request this quote answered is unknown", "policy_refused");
|
|
1438
1519
|
if (quote.providerData?.settlement !== "swap") {
|
|
1439
1520
|
if (params.sourceChain.startsWith("ton:") && params.destChain.startsWith("eip155:")) {
|
|
1440
|
-
if (!hooks.verifyTonEscrowBuild) return "a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)";
|
|
1441
|
-
if (!params.refundAddress) return "the trader's TON address (refundAddress) is unknown";
|
|
1521
|
+
if (!hooks.verifyTonEscrowBuild) return said("a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)", "unsupported_pair");
|
|
1522
|
+
if (!params.refundAddress) return said("the trader's TON address (refundAddress) is unknown", "recipient_unverifiable");
|
|
1442
1523
|
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);
|
|
1443
1524
|
try {
|
|
1444
|
-
|
|
1525
|
+
const text = await hooks.verifyTonEscrowBuild({
|
|
1445
1526
|
payloadBocHex: import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"),
|
|
1446
1527
|
ownerAddress: params.refundAddress,
|
|
1447
1528
|
inputUnits: quote.sourceAmount,
|
|
@@ -1450,22 +1531,23 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1450
1531
|
outputTokenAddress: params.destToken,
|
|
1451
1532
|
minResolverSendsUnits: floor.toString()
|
|
1452
1533
|
});
|
|
1534
|
+
return text ? said(text, tonEscrowBuildReason(text)) : text;
|
|
1453
1535
|
} catch {
|
|
1454
|
-
return "the escrow body could not be checked";
|
|
1536
|
+
return said("the escrow body could not be checked", "policy_refused");
|
|
1455
1537
|
}
|
|
1456
1538
|
}
|
|
1457
|
-
return "only TON swap and TON \u2192 EVM escrow bodies can be checked on the client";
|
|
1539
|
+
return said("only TON swap and TON \u2192 EVM escrow bodies can be checked on the client", "unsupported_pair");
|
|
1458
1540
|
}
|
|
1459
1541
|
let steps;
|
|
1460
1542
|
try {
|
|
1461
1543
|
steps = JSON.parse(quote.providerData.routeSteps ?? "");
|
|
1462
1544
|
} catch {
|
|
1463
|
-
return "the quote carries no route steps";
|
|
1545
|
+
return said("the quote carries no route steps", "policy_refused");
|
|
1464
1546
|
}
|
|
1465
|
-
if (!Array.isArray(steps) || steps.length === 0) return "the quote carries no route steps";
|
|
1547
|
+
if (!Array.isArray(steps) || steps.length === 0) return said("the quote carries no route steps", "policy_refused");
|
|
1466
1548
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1467
1549
|
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
1468
|
-
if (!source || !dest) return "unknown source or destination token";
|
|
1550
|
+
if (!source || !dest) return said("unknown source or destination token", "unsupported_pair");
|
|
1469
1551
|
const protocols = (quote.providerData.protocols ?? "").split(",").filter(Boolean);
|
|
1470
1552
|
let checked;
|
|
1471
1553
|
try {
|
|
@@ -1483,17 +1565,17 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1483
1565
|
integratorAddress: hooks.integratorAddress ?? null
|
|
1484
1566
|
});
|
|
1485
1567
|
} catch (e) {
|
|
1486
|
-
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1568
|
+
return said(e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e), e instanceof TonSwapPayloadError ? tonSwapPayloadReason(e.reason) : "policy_refused");
|
|
1487
1569
|
}
|
|
1488
1570
|
const payload = parseSwapPayload(import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"));
|
|
1489
1571
|
const target = source.contract ? payload.jettonTransfer?.destination : tx.to;
|
|
1490
|
-
if (!target) return "the body names no swap destination";
|
|
1572
|
+
if (!target) return said("the body names no swap destination", "policy_refused");
|
|
1491
1573
|
try {
|
|
1492
|
-
if (!await hooks.validateTonSwapTarget({ address: target, protocols })) return `${target} is not a recognized DEX contract for ${protocols.join("+")}
|
|
1574
|
+
if (!await hooks.validateTonSwapTarget({ address: target, protocols })) return said(`${target} is not a recognized DEX contract for ${protocols.join("+")}`, "vault_mismatch");
|
|
1493
1575
|
} catch {
|
|
1494
|
-
return "the swap target could not be checked";
|
|
1576
|
+
return said("the swap target could not be checked", "policy_refused");
|
|
1495
1577
|
}
|
|
1496
|
-
if (!hooks.validateTonSwapLeg) return "a TON swap body needs validateTonSwapLeg (createOmnistonTonValidators)";
|
|
1578
|
+
if (!hooks.validateTonSwapLeg) return said("a TON swap body needs validateTonSwapLeg (createOmnistonTonValidators)", "unsupported_pair");
|
|
1497
1579
|
for (const leg of checked.legs) {
|
|
1498
1580
|
let ok = false;
|
|
1499
1581
|
try {
|
|
@@ -1501,7 +1583,7 @@ function omnistonVerifyBuild(hooks) {
|
|
|
1501
1583
|
} catch {
|
|
1502
1584
|
ok = false;
|
|
1503
1585
|
}
|
|
1504
|
-
if (!ok) return `${leg.kind} v${leg.version} leg not verified
|
|
1586
|
+
if (!ok) return said(`${leg.kind} v${leg.version} leg not verified`, "vault_mismatch");
|
|
1505
1587
|
}
|
|
1506
1588
|
return null;
|
|
1507
1589
|
};
|
|
@@ -1685,19 +1767,19 @@ function omnistonProvider(opts = {}) {
|
|
|
1685
1767
|
if (!bound.ok) {
|
|
1686
1768
|
if (bound.reason === "legacy-expired") {
|
|
1687
1769
|
trace("legacy-intent-expired", { where });
|
|
1688
|
-
throw
|
|
1770
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
1689
1771
|
}
|
|
1690
1772
|
trace("intent-mismatch", { where, field: bound.field });
|
|
1691
|
-
throw
|
|
1773
|
+
throw (0, import_errors.refusal)(mismatchReason(bound.field), `omniston: intent id does not match the quote it was issued for (${bound.field})`);
|
|
1692
1774
|
}
|
|
1693
1775
|
if (bound.legacy) trace("legacy-intent", { where });
|
|
1694
1776
|
if (!decoded.digest) {
|
|
1695
1777
|
trace("intent-mismatch", { where, field: "digest-missing" });
|
|
1696
|
-
throw
|
|
1778
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: this quote was issued before an update \u2014 request a fresh quote");
|
|
1697
1779
|
}
|
|
1698
1780
|
if (decoded.digest !== quoteDigest(entry.quote)) {
|
|
1699
1781
|
trace("intent-mismatch", { where, field: "digest" });
|
|
1700
|
-
throw
|
|
1782
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: quote was replaced \u2014 request a fresh quote");
|
|
1701
1783
|
}
|
|
1702
1784
|
return bound.ref;
|
|
1703
1785
|
}
|
|
@@ -1731,10 +1813,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1731
1813
|
const disclosed = (await store.load(disclosedKey(quoteId)) ?? []).length > 0;
|
|
1732
1814
|
if (boundTo !== binding || disclosed) {
|
|
1733
1815
|
traceFor(quoteId)("secret-reuse-refused", { disclosed, bound: boundTo !== void 0 });
|
|
1734
|
-
throw
|
|
1816
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: this quote id already belongs to another order \u2014 request a fresh quote");
|
|
1735
1817
|
}
|
|
1736
1818
|
if (existing.length !== count || !existing.every((s) => /^[0-9a-fA-F]{64}$/.test(s))) {
|
|
1737
|
-
throw
|
|
1819
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: stored HTLC secrets for this quote do not fit the order \u2014 request a fresh quote");
|
|
1738
1820
|
}
|
|
1739
1821
|
traceFor(quoteId)("secret-reused", { count });
|
|
1740
1822
|
return { secrets: existing.map(hexToBytes), created: false };
|
|
@@ -1793,7 +1875,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1793
1875
|
let q = await rfq(slippagePips);
|
|
1794
1876
|
if (!q) {
|
|
1795
1877
|
if (!signal?.aborted) {
|
|
1796
|
-
|
|
1878
|
+
const text = `omniston: ${outcome.error ? `RFQ failed: ${outcome.error}` : outcome.rejected ? `swap quote rejected: ${outcome.rejected}` : "no TON DEX route quoted this pair/amount"}`;
|
|
1879
|
+
const reason = rfqReason(outcome);
|
|
1880
|
+
if (reason) params.onRefusal?.(text, { reason });
|
|
1881
|
+
else params.onRefusal?.(text);
|
|
1797
1882
|
}
|
|
1798
1883
|
return null;
|
|
1799
1884
|
}
|
|
@@ -1859,27 +1944,32 @@ function omnistonProvider(opts = {}) {
|
|
|
1859
1944
|
async function buildSwapDeposit(ref, q, swap) {
|
|
1860
1945
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
1861
1946
|
if (!isTon(ref.srcChain) || q.inputAsset.chain.$case !== "ton" || q.outputAsset.chain.$case !== "ton") {
|
|
1862
|
-
throw
|
|
1947
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: swap quote is not a TON same-chain swap");
|
|
1863
1948
|
}
|
|
1864
|
-
if (!sameChainTonReady()) throw
|
|
1949
|
+
if (!sameChainTonReady()) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON same-chain swaps need independent jetton-wallet, swap-target and swap-leg validators");
|
|
1865
1950
|
const owner = { chain: { $case: "ton", value: ref.trader } };
|
|
1866
1951
|
const receiver = { chain: { $case: "ton", value: ref.dest } };
|
|
1867
1952
|
const omni = await getClient();
|
|
1868
|
-
if (typeof omni.tonBuildSwap !== "function") throw
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1953
|
+
if (typeof omni.tonBuildSwap !== "function") throw (0, import_errors.refusal)("unsupported_pair", "omniston: client does not support swap settlement (tonBuildSwap)");
|
|
1954
|
+
let tx;
|
|
1955
|
+
try {
|
|
1956
|
+
tx = await omni.tonBuildSwap({
|
|
1957
|
+
quoteId: ref.quoteId,
|
|
1958
|
+
transferSrcAddress: owner,
|
|
1959
|
+
refundSrcAddress: owner,
|
|
1960
|
+
gasExcessAddress: owner,
|
|
1961
|
+
traderDstAddress: receiver,
|
|
1962
|
+
// Build at the slippage the quote was requested with: its
|
|
1963
|
+
// minOutputAmount is the minimum this module reported to the router.
|
|
1964
|
+
useRecommendedSlippage: false
|
|
1965
|
+
});
|
|
1966
|
+
} catch (error) {
|
|
1967
|
+
throw venueFailure(error);
|
|
1968
|
+
}
|
|
1879
1969
|
const [message, ...rest] = tx.messages;
|
|
1880
|
-
if (!message || rest.length > 0) throw
|
|
1881
|
-
if (message.jettonWalletStateInit) throw
|
|
1882
|
-
if (!isPositiveInteger(message.sendAmount)) throw
|
|
1970
|
+
if (!message || rest.length > 0) throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one swap message, got ${tx.messages.length}`);
|
|
1971
|
+
if (message.jettonWalletStateInit) throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
1972
|
+
if (!isPositiveInteger(message.sendAmount)) throw (0, import_errors.refusal)("policy_refused", "omniston: malformed swap message value");
|
|
1883
1973
|
const sendAmount = BigInt(message.sendAmount);
|
|
1884
1974
|
const gasCap = BigInt(maxTonExecutionNano);
|
|
1885
1975
|
const gasBudget = q.gasBudget && isPositiveInteger(q.gasBudget) ? BigInt(q.gasBudget) : gasCap;
|
|
@@ -1891,53 +1981,53 @@ function omnistonProvider(opts = {}) {
|
|
|
1891
1981
|
const ptonV1Native = !inputJetton && !!payload.jettonTransfer && singleV1;
|
|
1892
1982
|
if (inputJetton) {
|
|
1893
1983
|
const transfer = payload.jettonTransfer;
|
|
1894
|
-
if (!transfer) throw
|
|
1895
|
-
if (sendAmount > gasCap || sendAmount > gasBudget) throw
|
|
1896
|
-
if (transfer.amount !== BigInt(q.inputUnits)) throw
|
|
1984
|
+
if (!transfer) throw (0, import_errors.refusal)("policy_refused", "omniston: jetton-input swap message is not a jetton transfer");
|
|
1985
|
+
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("+")})`);
|
|
1986
|
+
if (transfer.amount !== BigInt(q.inputUnits)) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
1897
1987
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1898
|
-
throw
|
|
1988
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1899
1989
|
}
|
|
1900
|
-
if (transfer.forwardTon >= sendAmount) throw
|
|
1990
|
+
if (transfer.forwardTon >= sendAmount) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than it carries");
|
|
1901
1991
|
const walletValid = await opts.validateTonJettonWallet({
|
|
1902
1992
|
ownerAddress: ref.trader,
|
|
1903
1993
|
jettonMasterAddress: inputJetton,
|
|
1904
1994
|
walletAddress: message.targetAddress
|
|
1905
1995
|
});
|
|
1906
|
-
if (!walletValid) throw
|
|
1996
|
+
if (!walletValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
1907
1997
|
const targetValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1908
|
-
if (!targetValid) throw
|
|
1998
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1909
1999
|
} else if (ptonV1Native) {
|
|
1910
2000
|
const transfer = payload.jettonTransfer;
|
|
1911
2001
|
const input = BigInt(q.inputUnits);
|
|
1912
|
-
if (transfer.amount !== input) throw
|
|
1913
|
-
if (sendAmount < input) throw
|
|
2002
|
+
if (transfer.amount !== input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message moves a different amount than quoted");
|
|
2003
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1914
2004
|
const gas = sendAmount - input;
|
|
1915
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
1916
|
-
if (transfer.forwardTon > gas) throw
|
|
2005
|
+
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("+")})`);
|
|
2006
|
+
if (transfer.forwardTon > gas) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message forwards more TON than its gas");
|
|
1917
2007
|
if (!transfer.responseDestination || !sameTonAddress(transfer.responseDestination, ref.trader)) {
|
|
1918
|
-
throw
|
|
2008
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: swap message returns excess to a wallet other than the trader");
|
|
1919
2009
|
}
|
|
1920
|
-
if (typeof opts.validateTonSwapLeg !== "function") throw
|
|
2010
|
+
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)");
|
|
1921
2011
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1922
|
-
if (!targetValid) throw
|
|
2012
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1923
2013
|
const routerValid = await opts.validateTonSwapTarget({ address: transfer.destination, protocols });
|
|
1924
|
-
if (!routerValid) throw
|
|
2014
|
+
if (!routerValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap destination is not a recognized DEX contract for the quoted protocol");
|
|
1925
2015
|
} else {
|
|
1926
2016
|
if (payload.jettonTransfer) {
|
|
1927
|
-
throw
|
|
2017
|
+
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})`);
|
|
1928
2018
|
}
|
|
1929
2019
|
const input = BigInt(q.inputUnits);
|
|
1930
|
-
if (sendAmount < input) throw
|
|
2020
|
+
if (sendAmount < input) throw (0, import_errors.refusal)("policy_refused", "omniston: swap message carries less than the quoted input");
|
|
1931
2021
|
const gas = sendAmount - input;
|
|
1932
|
-
if (gas > gasCap || gas > gasBudget) throw
|
|
2022
|
+
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("+")})`);
|
|
1933
2023
|
const targetValid = await opts.validateTonSwapTarget({ address: message.targetAddress, protocols });
|
|
1934
|
-
if (!targetValid) throw
|
|
2024
|
+
if (!targetValid) throw (0, import_errors.refusal)("vault_mismatch", "omniston: swap target is not a recognized DEX contract for the quoted protocol");
|
|
1935
2025
|
}
|
|
1936
2026
|
const mode = ptonV1Native ? "enforce" : opts.tonSwapPayloadCheck ?? "enforce";
|
|
1937
2027
|
const trace = traceFor(ref.quoteId);
|
|
1938
2028
|
const payloadRefusal = (reason, detail) => {
|
|
1939
2029
|
trace("ton-swap-payload", { reason, detail, mode, protocols: protocols.join("+") });
|
|
1940
|
-
if (mode === "enforce") throw
|
|
2030
|
+
if (mode === "enforce") throw (0, import_errors.refusal)(tonSwapPayloadReason(reason), `omniston: ton-swap-payload ${reason} \u2014 ${detail}`);
|
|
1941
2031
|
};
|
|
1942
2032
|
let checked = null;
|
|
1943
2033
|
try {
|
|
@@ -2011,33 +2101,33 @@ function omnistonProvider(opts = {}) {
|
|
|
2011
2101
|
const srcChain = ref.srcChain;
|
|
2012
2102
|
const chainId = evmRef2(srcChain);
|
|
2013
2103
|
const srcCase = q.inputAsset.chain.$case;
|
|
2014
|
-
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw
|
|
2104
|
+
if (chainId === null || EVM_CASE[chainId] !== srcCase) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match the EVM quote");
|
|
2015
2105
|
const destCase = q.outputAsset.chain.$case;
|
|
2016
2106
|
const destChain = caipForChainCase(destCase);
|
|
2017
2107
|
const tonDest = destCase === "ton";
|
|
2018
|
-
if (!destChain || destChain === srcChain) throw
|
|
2108
|
+
if (!destChain || destChain === srcChain) throw (0, import_errors.refusal)("unsupported_pair", "omniston: EVM-source order has no supported destination chain");
|
|
2019
2109
|
if (!trustedOrderProtocols.has(srcChain) || typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
2020
|
-
throw
|
|
2110
|
+
throw (0, import_errors.refusal)("unsupported_pair", `omniston: EVM\u2192${tonDest ? "TON" : "EVM"} needs a trusted order protocol and both position validators`);
|
|
2021
2111
|
}
|
|
2022
2112
|
let owner;
|
|
2023
2113
|
try {
|
|
2024
2114
|
owner = (0, import_viem.getAddress)(ref.trader);
|
|
2025
2115
|
} catch {
|
|
2026
|
-
throw
|
|
2116
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: trader is not an EVM address");
|
|
2027
2117
|
}
|
|
2028
2118
|
let dest;
|
|
2029
2119
|
if (tonDest) {
|
|
2030
2120
|
try {
|
|
2031
2121
|
import_core3.Address.parse(ref.dest);
|
|
2032
2122
|
} catch {
|
|
2033
|
-
throw
|
|
2123
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not a TON address");
|
|
2034
2124
|
}
|
|
2035
2125
|
dest = ref.dest;
|
|
2036
2126
|
} else {
|
|
2037
2127
|
try {
|
|
2038
2128
|
dest = (0, import_viem.getAddress)(ref.dest);
|
|
2039
2129
|
} catch {
|
|
2040
|
-
throw
|
|
2130
|
+
throw (0, import_errors.refusal)("recipient_mismatch", "omniston: destination is not an EVM address");
|
|
2041
2131
|
}
|
|
2042
2132
|
}
|
|
2043
2133
|
const traderDst = { chain: { $case: destCase, value: dest } };
|
|
@@ -2048,9 +2138,9 @@ function omnistonProvider(opts = {}) {
|
|
|
2048
2138
|
const outputToken = assetContract(q.outputAsset);
|
|
2049
2139
|
const destChainId = tonDest ? null : evmRef2(destChain);
|
|
2050
2140
|
if (factory?.chain.$case === destCase && !isTrusted(destChain, factory.chain.value)) {
|
|
2051
|
-
throw
|
|
2141
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted ${destChain} settlement contract ${factory.chain.value}`);
|
|
2052
2142
|
}
|
|
2053
|
-
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
|
|
2143
|
+
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");
|
|
2054
2144
|
const { secrets, created } = await secretsFor(ref, q, 1);
|
|
2055
2145
|
const hashes = secrets.map((secret) => hashlock(secret, settlement.htlcHashingFunction));
|
|
2056
2146
|
const forget = async () => {
|
|
@@ -2067,14 +2157,14 @@ function omnistonProvider(opts = {}) {
|
|
|
2067
2157
|
});
|
|
2068
2158
|
} catch (error) {
|
|
2069
2159
|
await forget();
|
|
2070
|
-
throw error;
|
|
2160
|
+
throw venueFailure(error);
|
|
2071
2161
|
}
|
|
2072
2162
|
let td;
|
|
2073
2163
|
try {
|
|
2074
2164
|
try {
|
|
2075
2165
|
td = JSON.parse(payload.typedData);
|
|
2076
2166
|
} catch {
|
|
2077
|
-
throw
|
|
2167
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: malformed EVM order typed data");
|
|
2078
2168
|
}
|
|
2079
2169
|
validateSerializedOrderDetails(payload.serializedOrderDetails, {
|
|
2080
2170
|
quoteId: ref.quoteId,
|
|
@@ -2157,45 +2247,46 @@ function omnistonProvider(opts = {}) {
|
|
|
2157
2247
|
async getQuote(params, signal) {
|
|
2158
2248
|
if (params.flex) return null;
|
|
2159
2249
|
if (isTon(params.sourceChain) && isTon(params.destChain)) return await getSwapQuote(params, signal);
|
|
2160
|
-
const refuse2 = (reason) => {
|
|
2161
|
-
params.onRefusal?.(`omniston: ${reason}
|
|
2250
|
+
const refuse2 = (reason, why) => {
|
|
2251
|
+
if (why) params.onRefusal?.(`omniston: ${reason}`, { reason: why });
|
|
2252
|
+
else params.onRefusal?.(`omniston: ${reason}`);
|
|
2162
2253
|
return null;
|
|
2163
2254
|
};
|
|
2164
2255
|
const evmSource = !isTon(params.sourceChain);
|
|
2165
2256
|
const tonDest = isTon(params.destChain);
|
|
2166
|
-
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor");
|
|
2257
|
+
if (!omniston.supports(params.sourceChain, params.destChain)) return refuse2("route is not an Omniston order corridor", "unsupported_pair");
|
|
2167
2258
|
if (!trustedContracts.has(params.sourceChain) || !trustedContracts.has(params.destChain)) {
|
|
2168
|
-
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}
|
|
2259
|
+
return refuse2(`no trusted settlement contract configured for ${trustedContracts.has(params.sourceChain) ? params.destChain : params.sourceChain}`, "unsupported_pair");
|
|
2169
2260
|
}
|
|
2170
2261
|
if (evmSource) {
|
|
2171
|
-
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}
|
|
2262
|
+
if (!trustedOrderProtocols.has(params.sourceChain)) return refuse2(`no trusted EVM order protocol configured for ${params.sourceChain}`, "unsupported_pair");
|
|
2172
2263
|
if (typeof opts.validateEvmInputPosition !== "function" || typeof (tonDest ? opts.validateTonOutputPosition : opts.validateEvmOutputPosition) !== "function") {
|
|
2173
|
-
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");
|
|
2264
|
+
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");
|
|
2174
2265
|
}
|
|
2175
2266
|
if (params.dry === false) {
|
|
2176
2267
|
if (tonDest) {
|
|
2177
2268
|
try {
|
|
2178
2269
|
import_core3.Address.parse(params.destAddress);
|
|
2179
2270
|
} catch {
|
|
2180
|
-
return refuse2("destination is not a TON address");
|
|
2271
|
+
return refuse2("destination is not a TON address", "recipient_mismatch");
|
|
2181
2272
|
}
|
|
2182
|
-
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address");
|
|
2273
|
+
} else if (!validEvmAddress(params.destAddress)) return refuse2("destination is not an EVM address", "recipient_mismatch");
|
|
2183
2274
|
}
|
|
2184
|
-
} 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");
|
|
2275
|
+
} 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");
|
|
2185
2276
|
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
2186
2277
|
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
2187
|
-
if (!source || !dest) return refuse2("asset is not in the catalog");
|
|
2278
|
+
if (!source || !dest) return refuse2("asset is not in the catalog", "unsupported_pair");
|
|
2188
2279
|
const inputAsset = toAssetId(params.sourceChain, source);
|
|
2189
2280
|
const outputAsset = toAssetId(params.destChain, dest);
|
|
2190
2281
|
if (!inputAsset || !outputAsset) {
|
|
2191
|
-
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)
|
|
2282
|
+
return refuse2(`cross-chain orders are token corridors only (no ${!inputAsset ? source.symbol : dest.symbol} native leg)`, "unsupported_pair");
|
|
2192
2283
|
}
|
|
2193
2284
|
const maxUnits = decimalToUnits(maxUsdText, source.decimals);
|
|
2194
2285
|
if (!maxUnits || !isPositiveInteger(params.amountIn)) return refuse2("invalid amount");
|
|
2195
|
-
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap
|
|
2286
|
+
if (BigInt(params.amountIn) > maxUnits) return refuse2(`amount above the ${maxUsdText} USD per-swap cap`, "amount_too_large");
|
|
2196
2287
|
const trader = params.refundAddress ?? "";
|
|
2197
2288
|
if (!trader && !params.dry) return refuse2(`execution quote needs the trader's ${evmSource ? "EVM" : "TON"} address (refundAddress)`);
|
|
2198
|
-
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address");
|
|
2289
|
+
if (evmSource && trader && !validEvmAddress(trader)) return refuse2("refundAddress is not an EVM address", "recipient_mismatch");
|
|
2199
2290
|
const request = {
|
|
2200
2291
|
inputAsset,
|
|
2201
2292
|
outputAsset,
|
|
@@ -2223,27 +2314,28 @@ function omnistonProvider(opts = {}) {
|
|
|
2223
2314
|
if (!q) {
|
|
2224
2315
|
if (signal?.aborted) return null;
|
|
2225
2316
|
return refuse2(
|
|
2226
|
-
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount"
|
|
2317
|
+
rfq.error ? `RFQ failed: ${rfq.error}` : rfq.rejected ? `resolver quote rejected: ${rfq.rejected}` : "no resolver quoted this route/amount",
|
|
2318
|
+
rfqReason(rfq)
|
|
2227
2319
|
);
|
|
2228
2320
|
}
|
|
2229
2321
|
const orderData = q.settlementData.$case === "order" ? q.settlementData.value : null;
|
|
2230
|
-
if (!orderData) return refuse2("resolver answered without order settlement");
|
|
2322
|
+
if (!orderData) return refuse2("resolver answered without order settlement", "upstream_unavailable");
|
|
2231
2323
|
const srcContract = orderData.srcProtocolContractAddress.chain.value;
|
|
2232
2324
|
if (evmSource ? !isTrustedOrderProtocol(params.sourceChain, srcContract) : !isTrusted(params.sourceChain, srcContract)) {
|
|
2233
|
-
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}
|
|
2325
|
+
return refuse2(evmSource ? `untrusted ${params.sourceChain} order protocol ${srcContract}` : `untrusted TON settlement contract ${srcContract}`, "vault_mismatch");
|
|
2234
2326
|
}
|
|
2235
2327
|
if (!orderData.dstProtocolContractAddress || !isTrusted(params.destChain, orderData.dstProtocolContractAddress.chain.value)) {
|
|
2236
|
-
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}
|
|
2328
|
+
return refuse2(`untrusted ${params.destChain} settlement contract ${orderData.dstProtocolContractAddress?.chain.value ?? "(none)"}`, "vault_mismatch");
|
|
2237
2329
|
}
|
|
2238
2330
|
const deadlineMs = orderData.tradeStartDeadline * 1e3;
|
|
2239
|
-
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed");
|
|
2240
|
-
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute");
|
|
2331
|
+
if (!Number.isFinite(deadlineMs) || deadlineMs <= Date.now()) return refuse2("quote trade-start deadline already passed", "quote_expired");
|
|
2332
|
+
if (params.dry === false && deadlineMs - Date.now() < MIN_START_HEADROOM_MS) return refuse2("quote trade-start deadline too close to execute", "quote_expired");
|
|
2241
2333
|
const inputScaled = BigInt(q.inputUnits) * 10n ** BigInt(dest.decimals);
|
|
2242
2334
|
const outputScaled = BigInt(q.outputUnits) * 10n ** BigInt(source.decimals);
|
|
2243
|
-
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input");
|
|
2244
|
-
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order");
|
|
2335
|
+
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input", "price_check_failed");
|
|
2336
|
+
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order", "policy_refused");
|
|
2245
2337
|
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "order" } })) {
|
|
2246
|
-
return refuse2("the platform reused a quote id that already holds another quote");
|
|
2338
|
+
return refuse2("the platform reused a quote id that already holds another quote", "policy_refused");
|
|
2247
2339
|
}
|
|
2248
2340
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
2249
2341
|
const feeUsd = feeUnits / 10 ** dest.decimals;
|
|
@@ -2274,29 +2366,29 @@ function omnistonProvider(opts = {}) {
|
|
|
2274
2366
|
*/
|
|
2275
2367
|
async buildDeposit(quote) {
|
|
2276
2368
|
if (!Number.isFinite(quote.validUntilMs) || quote.validUntilMs <= Date.now()) {
|
|
2277
|
-
throw
|
|
2369
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2278
2370
|
}
|
|
2279
2371
|
const decoded = decodeIntent(quote.intentId);
|
|
2280
2372
|
if (!decoded) throw new Error("omniston: malformed intent id");
|
|
2281
2373
|
const cached = await loadBuilt(decoded.quoteId);
|
|
2282
|
-
if (!cached) throw
|
|
2374
|
+
if (!cached) throw (0, import_errors.refusal)("quote_expired", "omniston: quote expired \u2014 request a fresh quote");
|
|
2283
2375
|
const ref = requireBinding(decoded, cached, "buildDeposit");
|
|
2284
2376
|
const q = cached.quote;
|
|
2285
2377
|
if (q.settlementData.$case === "swap") return await buildSwapDeposit(ref, q, q.settlementData.value);
|
|
2286
2378
|
if (q.settlementData.$case !== "order" || q.settlementData.value.tradeStartDeadline * 1e3 <= Date.now()) {
|
|
2287
|
-
throw
|
|
2379
|
+
throw (0, import_errors.refusal)("quote_expired", "omniston: quote trade deadline expired \u2014 request a fresh quote");
|
|
2288
2380
|
}
|
|
2289
2381
|
if (!ref.trader) throw new Error("omniston: quote was requested without a refund/source address");
|
|
2290
2382
|
const srcCase = q.inputAsset.chain.$case;
|
|
2291
2383
|
if (srcCase !== "ton") return await buildEvmOrder(ref, q, q.settlementData.value, cached.bound);
|
|
2292
2384
|
const srcChain = ref.srcChain;
|
|
2293
|
-
if (!isTon(srcChain)) throw
|
|
2385
|
+
if (!isTon(srcChain)) throw (0, import_errors.refusal)("policy_refused", "omniston: source chain does not match TON quote");
|
|
2294
2386
|
const destCase = q.outputAsset.chain.$case;
|
|
2295
2387
|
const traderDst = destCase === "ton" ? null : { chain: { $case: destCase, value: (0, import_viem.getAddress)(ref.dest) } };
|
|
2296
|
-
if (!traderDst) throw
|
|
2388
|
+
if (!traderDst) throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON-destination orders are not supported");
|
|
2297
2389
|
const minter = q.settlementData.value.srcProtocolContractAddress;
|
|
2298
2390
|
if (minter.chain.$case !== "ton" || !isTrusted(srcChain, minter.chain.value)) {
|
|
2299
|
-
throw
|
|
2391
|
+
throw (0, import_errors.refusal)("vault_mismatch", `omniston: untrusted TON settlement contract ${minter.chain.value}`);
|
|
2300
2392
|
}
|
|
2301
2393
|
const settlement = q.settlementData;
|
|
2302
2394
|
const hashingFunction = settlement.$case === "order" ? settlement.value.htlcHashingFunction : void 0;
|
|
@@ -2320,27 +2412,27 @@ function omnistonProvider(opts = {}) {
|
|
|
2320
2412
|
});
|
|
2321
2413
|
} catch (error) {
|
|
2322
2414
|
await forget();
|
|
2323
|
-
throw error;
|
|
2415
|
+
throw venueFailure(error);
|
|
2324
2416
|
}
|
|
2325
2417
|
const [message, ...rest] = tx.messages;
|
|
2326
2418
|
if (!message || rest.length > 0) {
|
|
2327
2419
|
await forget();
|
|
2328
|
-
throw
|
|
2420
|
+
throw (0, import_errors.refusal)("policy_refused", `omniston: expected exactly one escrow message, got ${tx.messages.length}`);
|
|
2329
2421
|
}
|
|
2330
2422
|
if (!isPositiveInteger(message.sendAmount) || BigInt(message.sendAmount) > BigInt(maxTonExecutionNano)) {
|
|
2331
2423
|
await forget();
|
|
2332
|
-
throw
|
|
2424
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: resolver TON execution value exceeds the configured safety cap");
|
|
2333
2425
|
}
|
|
2334
2426
|
const expectedProtocol = q.settlementData.value.srcProtocolContractAddress;
|
|
2335
2427
|
const initialResolver = q.settlementData.value.srcInitialResolverAddress;
|
|
2336
2428
|
const jettonMaster = assetContract(q.inputAsset);
|
|
2337
2429
|
if (expectedProtocol.chain.$case !== "ton" || initialResolver?.chain.$case !== "ton" || !jettonMaster) {
|
|
2338
2430
|
await forget();
|
|
2339
|
-
throw
|
|
2431
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: incomplete TON settlement binding in quote");
|
|
2340
2432
|
}
|
|
2341
2433
|
if (message.jettonWalletStateInit) {
|
|
2342
2434
|
await forget();
|
|
2343
|
-
throw
|
|
2435
|
+
throw (0, import_errors.refusal)("policy_refused", "omniston: deploying a resolver-provided jetton wallet is not supported");
|
|
2344
2436
|
}
|
|
2345
2437
|
let walletValid = false;
|
|
2346
2438
|
try {
|
|
@@ -2355,11 +2447,11 @@ function omnistonProvider(opts = {}) {
|
|
|
2355
2447
|
}
|
|
2356
2448
|
if (!walletValid) {
|
|
2357
2449
|
await forget();
|
|
2358
|
-
throw
|
|
2450
|
+
throw (0, import_errors.refusal)("vault_mismatch", "omniston: TON jetton wallet was not independently validated");
|
|
2359
2451
|
}
|
|
2360
2452
|
try {
|
|
2361
2453
|
if (!opts.validateTonEscrowPayload) {
|
|
2362
|
-
throw
|
|
2454
|
+
throw (0, import_errors.refusal)("unsupported_pair", "omniston: TON source requires an independent escrow-payload validator");
|
|
2363
2455
|
}
|
|
2364
2456
|
await validateTonEscrowPayload(message, {
|
|
2365
2457
|
quoteId: ref.quoteId,
|
|
@@ -2406,7 +2498,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2406
2498
|
const result = bindIntent(decoded, stored);
|
|
2407
2499
|
if (!result.ok && result.reason === "mismatch") {
|
|
2408
2500
|
trace("intent-mismatch", { where: "trackIntent", field: result.field });
|
|
2409
|
-
throw
|
|
2501
|
+
throw (0, import_errors.refusal)(mismatchReason(result.field), `omniston: intent id does not match the quote it was issued for (${result.field})`);
|
|
2410
2502
|
}
|
|
2411
2503
|
if (result.ok) {
|
|
2412
2504
|
if (result.legacy) trace("legacy-intent", { where: "trackIntent" });
|
|
@@ -2586,12 +2678,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2586
2678
|
if (!ref) throw new Error("omniston: malformed intent id");
|
|
2587
2679
|
const cached = await loadBuilt(ref.quoteId);
|
|
2588
2680
|
const order = cached?.evmOrder;
|
|
2589
|
-
if (!order) throw
|
|
2681
|
+
if (!order) throw (0, import_errors.refusal)("quote_expired", "omniston: no signed-order context for this quote \u2014 build the order again");
|
|
2590
2682
|
requireBinding(ref, cached, "registerSignedOrder");
|
|
2591
2683
|
if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) throw new Error("omniston: malformed order signature");
|
|
2592
2684
|
const td = JSON.parse(order.typedData);
|
|
2593
2685
|
const omni = await getClient();
|
|
2594
|
-
|
|
2686
|
+
const request = {
|
|
2595
2687
|
quoteId: ref.quoteId,
|
|
2596
2688
|
ownerSrcAddress: { chain: { $case: order.chainCase, value: order.owner } },
|
|
2597
2689
|
signedOrder: { order: { $case: "evmV1", value: {
|
|
@@ -2600,7 +2692,12 @@ function omnistonProvider(opts = {}) {
|
|
|
2600
2692
|
orderExtension: hexToBytes(order.orderExtension)
|
|
2601
2693
|
} } },
|
|
2602
2694
|
...order.serializedOrderDetails ? { serializedOrderDetails: hexToBytes(order.serializedOrderDetails) } : {}
|
|
2603
|
-
}
|
|
2695
|
+
};
|
|
2696
|
+
try {
|
|
2697
|
+
await omni.orderRegisterSignedOrder(request);
|
|
2698
|
+
} catch (error) {
|
|
2699
|
+
throw venueFailure(error);
|
|
2700
|
+
}
|
|
2604
2701
|
},
|
|
2605
2702
|
close() {
|
|
2606
2703
|
clientGeneration += 1;
|