@anywalletkit/protocol-swap2-lifi 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -7
- package/dist/{chunk-TQYG23FS.js → chunk-IZ7TP4KT.js} +341 -92
- package/dist/chunk-IZ7TP4KT.js.map +1 -0
- package/dist/{chunk-7SUAXOPF.js → chunk-YABKNR7N.js} +2 -2
- package/dist/index.cjs +345 -96
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/protocol.cjs +345 -96
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +2 -2
- package/dist/provider.cjs +345 -96
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +11 -1
- package/dist/provider.d.ts +11 -1
- package/dist/provider.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-TQYG23FS.js.map +0 -1
- /package/dist/{chunk-7SUAXOPF.js.map → chunk-YABKNR7N.js.map} +0 -0
|
@@ -26,144 +26,162 @@ var GENERIC_SWAPS = {
|
|
|
26
26
|
var BRIDGE_INPUT_FEE_MAX_BPS = 100n;
|
|
27
27
|
var kindOf = (asset) => /^0x0{40}$/i.test(asset) ? "native" : "erc20";
|
|
28
28
|
var BRIDGE_CALLS = {
|
|
29
|
-
"0x1fd8010c": { sourceSwaps: false },
|
|
29
|
+
"0x1fd8010c": { sourceSwaps: false, facet: "Across" },
|
|
30
30
|
// startBridgeTokensViaAcross (AcrossFacet)
|
|
31
|
-
"0x3a3f7332": { sourceSwaps: true },
|
|
31
|
+
"0x3a3f7332": { sourceSwaps: true, facet: "Across" },
|
|
32
32
|
// swapAndStartBridgeTokensViaAcross (AcrossFacet)
|
|
33
|
-
"0xa1f1ce43": { sourceSwaps: false },
|
|
33
|
+
"0xa1f1ce43": { sourceSwaps: false, facet: "AcrossV4" },
|
|
34
34
|
// startBridgeTokensViaAcrossV4 (AcrossFacetV4)
|
|
35
|
-
"0x1794958f": { sourceSwaps: true },
|
|
35
|
+
"0x1794958f": { sourceSwaps: true, facet: "AcrossV4" },
|
|
36
36
|
// swapAndStartBridgeTokensViaAcrossV4 (AcrossFacetV4)
|
|
37
|
-
"0x6a90d66e": { sourceSwaps: false },
|
|
37
|
+
"0x6a90d66e": { sourceSwaps: false, facet: "AcrossV4Swap" },
|
|
38
38
|
// startBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)
|
|
39
|
-
"0x9b054bc4": { sourceSwaps: true },
|
|
39
|
+
"0x9b054bc4": { sourceSwaps: true, facet: "AcrossV4Swap" },
|
|
40
40
|
// swapAndStartBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)
|
|
41
|
-
"0x6a51e9a9": { sourceSwaps: false },
|
|
41
|
+
"0x6a51e9a9": { sourceSwaps: false, facet: "AllBridge" },
|
|
42
42
|
// startBridgeTokensViaAllBridge (AllBridgeFacet)
|
|
43
|
-
"0x63267469": { sourceSwaps: true },
|
|
43
|
+
"0x63267469": { sourceSwaps: true, facet: "AllBridge" },
|
|
44
44
|
// swapAndStartBridgeTokensViaAllBridge (AllBridgeFacet)
|
|
45
|
-
"0xc9851d0b": { sourceSwaps: false },
|
|
45
|
+
"0xc9851d0b": { sourceSwaps: false, facet: "ArbitrumBridge" },
|
|
46
46
|
// startBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)
|
|
47
|
-
"0x3cc9517b": { sourceSwaps: true },
|
|
47
|
+
"0x3cc9517b": { sourceSwaps: true, facet: "ArbitrumBridge" },
|
|
48
48
|
// swapAndStartBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)
|
|
49
|
-
"0xe0a4201c": { sourceSwaps: false },
|
|
49
|
+
"0xe0a4201c": { sourceSwaps: false, facet: "CelerCircleBridge" },
|
|
50
50
|
// startBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)
|
|
51
|
-
"0x4f3b0759": { sourceSwaps: true },
|
|
51
|
+
"0x4f3b0759": { sourceSwaps: true, facet: "CelerCircleBridge" },
|
|
52
52
|
// swapAndStartBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)
|
|
53
|
-
"0x0315138f": { sourceSwaps: false },
|
|
53
|
+
"0x0315138f": { sourceSwaps: false, facet: "Centrifuge" },
|
|
54
54
|
// startBridgeTokensViaCentrifuge (CentrifugeFacet)
|
|
55
|
-
"0x8fd4d4dd": { sourceSwaps: true },
|
|
55
|
+
"0x8fd4d4dd": { sourceSwaps: true, facet: "Centrifuge" },
|
|
56
56
|
// swapAndStartBridgeTokensViaCentrifuge (CentrifugeFacet)
|
|
57
|
-
"0x0ad553b3": { sourceSwaps: false },
|
|
57
|
+
"0x0ad553b3": { sourceSwaps: false, facet: "Chainflip" },
|
|
58
58
|
// startBridgeTokensViaChainflip (ChainflipFacet)
|
|
59
|
-
"0xee3314a1": { sourceSwaps: true },
|
|
59
|
+
"0xee3314a1": { sourceSwaps: true, facet: "Chainflip" },
|
|
60
60
|
// swapAndStartBridgeTokensViaChainflip (ChainflipFacet)
|
|
61
|
-
"
|
|
62
|
-
//
|
|
63
|
-
"
|
|
64
|
-
//
|
|
65
|
-
"
|
|
66
|
-
// startBridgeTokensViaEco (EcoFacet)
|
|
67
|
-
"0x762aea18": { sourceSwaps: true },
|
|
68
|
-
// swapAndStartBridgeTokensViaEco (EcoFacet)
|
|
69
|
-
"0x678786ea": { sourceSwaps: false },
|
|
61
|
+
"0x05c54990": { sourceSwaps: false, facet: "Eco" },
|
|
62
|
+
// startBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
63
|
+
"0x8352664c": { sourceSwaps: true, facet: "Eco" },
|
|
64
|
+
// swapAndStartBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
65
|
+
"0x678786ea": { sourceSwaps: false, facet: "Frax" },
|
|
70
66
|
// startBridgeTokensViaFrax (FraxFacet)
|
|
71
|
-
"0x07b8e4c7": { sourceSwaps: true },
|
|
67
|
+
"0x07b8e4c7": { sourceSwaps: true, facet: "Frax" },
|
|
72
68
|
// swapAndStartBridgeTokensViaFrax (FraxFacet)
|
|
73
|
-
"
|
|
74
|
-
// startBridgeTokensViaGarden (GardenFacet)
|
|
75
|
-
"0x76ad76fe": { sourceSwaps: true },
|
|
76
|
-
// swapAndStartBridgeTokensViaGarden (GardenFacet)
|
|
77
|
-
"0xfc5f1003": { sourceSwaps: false },
|
|
69
|
+
"0xfc5f1003": { sourceSwaps: false, facet: "GasZip" },
|
|
78
70
|
// startBridgeTokensViaGasZip (GasZipFacet)
|
|
79
|
-
"0x606326ff": { sourceSwaps: true },
|
|
71
|
+
"0x606326ff": { sourceSwaps: true, facet: "GasZip" },
|
|
80
72
|
// swapAndStartBridgeTokensViaGasZip (GasZipFacet)
|
|
81
|
-
"0x6f9206ba": { sourceSwaps: false },
|
|
73
|
+
"0x6f9206ba": { sourceSwaps: false, facet: "Glacis" },
|
|
82
74
|
// startBridgeTokensViaGlacis (GlacisFacet)
|
|
83
|
-
"0x9c4b6dd9": { sourceSwaps: true },
|
|
75
|
+
"0x9c4b6dd9": { sourceSwaps: true, facet: "Glacis" },
|
|
84
76
|
// swapAndStartBridgeTokensViaGlacis (GlacisFacet)
|
|
85
|
-
"0xf66fe519": { sourceSwaps: false },
|
|
77
|
+
"0xf66fe519": { sourceSwaps: false, facet: "GnosisBridge" },
|
|
86
78
|
// startBridgeTokensViaGnosisBridge (GnosisBridgeFacet)
|
|
87
|
-
"0x7bf96e0a": { sourceSwaps: true },
|
|
79
|
+
"0x7bf96e0a": { sourceSwaps: true, facet: "GnosisBridge" },
|
|
88
80
|
// swapAndStartBridgeTokensViaGnosisBridge (GnosisBridgeFacet)
|
|
89
|
-
"0xee9e98e0": { sourceSwaps: false },
|
|
81
|
+
"0xee9e98e0": { sourceSwaps: false, facet: "LayerSwap" },
|
|
90
82
|
// startBridgeTokensViaLayerSwap (LayerSwapFacet)
|
|
91
|
-
"0x4c279d6b": { sourceSwaps: true },
|
|
83
|
+
"0x4c279d6b": { sourceSwaps: true, facet: "LayerSwap" },
|
|
92
84
|
// swapAndStartBridgeTokensViaLayerSwap (LayerSwapFacet)
|
|
93
|
-
"0x7dbcf1d9": { sourceSwaps: false },
|
|
85
|
+
"0x7dbcf1d9": { sourceSwaps: false, facet: "LiFiIntentEscrowV2" },
|
|
94
86
|
// startBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)
|
|
95
|
-
"0x6d21c5df": { sourceSwaps: true },
|
|
87
|
+
"0x6d21c5df": { sourceSwaps: true, facet: "LiFiIntentEscrowV2" },
|
|
96
88
|
// swapAndStartBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)
|
|
97
|
-
"0x65782c4b": { sourceSwaps: false },
|
|
89
|
+
"0x65782c4b": { sourceSwaps: false, facet: "M0" },
|
|
98
90
|
// startBridgeTokensViaM0 (M0Facet)
|
|
99
|
-
"0xb9eaf86d": { sourceSwaps: true },
|
|
91
|
+
"0xb9eaf86d": { sourceSwaps: true, facet: "M0" },
|
|
100
92
|
// swapAndStartBridgeTokensViaM0 (M0Facet)
|
|
101
|
-
"0xb4875292": { sourceSwaps: false },
|
|
93
|
+
"0xb4875292": { sourceSwaps: false, facet: "Mayan" },
|
|
102
94
|
// startBridgeTokensViaMayan (MayanFacet)
|
|
103
|
-
"0x80c65808": { sourceSwaps: true },
|
|
95
|
+
"0x80c65808": { sourceSwaps: true, facet: "Mayan" },
|
|
104
96
|
// swapAndStartBridgeTokensViaMayan (MayanFacet)
|
|
105
|
-
"0x4213dfff": { sourceSwaps: false },
|
|
97
|
+
"0x4213dfff": { sourceSwaps: false, facet: "MegaETHBridge" },
|
|
106
98
|
// startBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)
|
|
107
|
-
"0x22256e89": { sourceSwaps: true },
|
|
99
|
+
"0x22256e89": { sourceSwaps: true, facet: "MegaETHBridge" },
|
|
108
100
|
// swapAndStartBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)
|
|
109
|
-
"0x4698f032": { sourceSwaps: false },
|
|
101
|
+
"0x4698f032": { sourceSwaps: false, facet: "NEARIntents" },
|
|
110
102
|
// startBridgeTokensViaNEARIntents (NEARIntentsFacet)
|
|
111
|
-
"0x02631b09": { sourceSwaps: true },
|
|
103
|
+
"0x02631b09": { sourceSwaps: true, facet: "NEARIntents" },
|
|
112
104
|
// swapAndStartBridgeTokensViaNEARIntents (NEARIntentsFacet)
|
|
113
|
-
"0x782621d8": { sourceSwaps: false },
|
|
105
|
+
"0x782621d8": { sourceSwaps: false, facet: "OmniBridge" },
|
|
114
106
|
// startBridgeTokensViaOmniBridge (OmniBridgeFacet)
|
|
115
|
-
"0x95726782": { sourceSwaps: true },
|
|
107
|
+
"0x95726782": { sourceSwaps: true, facet: "OmniBridge" },
|
|
116
108
|
// swapAndStartBridgeTokensViaOmniBridge (OmniBridgeFacet)
|
|
117
|
-
"0xce8a97a5": { sourceSwaps: false },
|
|
109
|
+
"0xce8a97a5": { sourceSwaps: false, facet: "OptimismBridge" },
|
|
118
110
|
// startBridgeTokensViaOptimismBridge (OptimismBridgeFacet)
|
|
119
|
-
"0x5bb5d448": { sourceSwaps: true },
|
|
111
|
+
"0x5bb5d448": { sourceSwaps: true, facet: "OptimismBridge" },
|
|
120
112
|
// swapAndStartBridgeTokensViaOptimismBridge (OptimismBridgeFacet)
|
|
121
|
-
"0xaf62c7d6": { sourceSwaps: false },
|
|
113
|
+
"0xaf62c7d6": { sourceSwaps: false, facet: "PolygonBridge" },
|
|
122
114
|
// startBridgeTokensViaPolygonBridge (PolygonBridgeFacet)
|
|
123
|
-
"0xb4f37581": { sourceSwaps: true },
|
|
115
|
+
"0xb4f37581": { sourceSwaps: true, facet: "PolygonBridge" },
|
|
124
116
|
// swapAndStartBridgeTokensViaPolygonBridge (PolygonBridgeFacet)
|
|
125
|
-
"0xf434d6ca": { sourceSwaps: false },
|
|
117
|
+
"0xf434d6ca": { sourceSwaps: false, facet: "PolymerCCTP" },
|
|
126
118
|
// startBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)
|
|
127
|
-
"0x17917a4e": { sourceSwaps: true },
|
|
119
|
+
"0x17917a4e": { sourceSwaps: true, facet: "PolymerCCTP" },
|
|
128
120
|
// swapAndStartBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)
|
|
129
|
-
"
|
|
130
|
-
// startBridgeTokensViaRelayDepository (RelayDepositoryFacet)
|
|
131
|
-
"0xa3443faa": { sourceSwaps: true },
|
|
132
|
-
// swapAndStartBridgeTokensViaRelayDepository (RelayDepositoryFacet)
|
|
133
|
-
"0x3f313808": { sourceSwaps: false },
|
|
134
|
-
// startBridgeTokensViaSquid (SquidFacet)
|
|
135
|
-
"0xa8f66666": { sourceSwaps: true },
|
|
136
|
-
// swapAndStartBridgeTokensViaSquid (SquidFacet)
|
|
137
|
-
"0x14d53077": { sourceSwaps: false },
|
|
121
|
+
"0x14d53077": { sourceSwaps: false, facet: "Stargate" },
|
|
138
122
|
// startBridgeTokensViaStargate (StargateFacetV2)
|
|
139
|
-
"0xa6010a66": { sourceSwaps: true },
|
|
123
|
+
"0xa6010a66": { sourceSwaps: true, facet: "Stargate" },
|
|
140
124
|
// swapAndStartBridgeTokensViaStargate (StargateFacetV2)
|
|
141
|
-
"0x0691ff78": { sourceSwaps: false },
|
|
125
|
+
"0x0691ff78": { sourceSwaps: false, facet: "Superset" },
|
|
142
126
|
// startBridgeTokensViaSuperset (SupersetFacet)
|
|
143
|
-
"0xf26e657f": { sourceSwaps: true },
|
|
127
|
+
"0xf26e657f": { sourceSwaps: true, facet: "Superset" },
|
|
144
128
|
// swapAndStartBridgeTokensViaSuperset (SupersetFacet)
|
|
145
|
-
"
|
|
146
|
-
// startBridgeTokensViaSymbiosis (SymbiosisFacet)
|
|
147
|
-
"0xc46059b2": { sourceSwaps: true },
|
|
148
|
-
// swapAndStartBridgeTokensViaSymbiosis (SymbiosisFacet)
|
|
149
|
-
"0x2541ec57": { sourceSwaps: false },
|
|
150
|
-
// startBridgeTokensViaThorSwap (ThorSwapFacet)
|
|
151
|
-
"0xad673d88": { sourceSwaps: true },
|
|
152
|
-
// swapAndStartBridgeTokensViaThorSwap (ThorSwapFacet)
|
|
153
|
-
"0x64261d58": { sourceSwaps: false },
|
|
129
|
+
"0x64261d58": { sourceSwaps: false, facet: "Unit" },
|
|
154
130
|
// startBridgeTokensViaUnit (UnitFacet)
|
|
155
|
-
"0x21a3af52": { sourceSwaps: true }
|
|
131
|
+
"0x21a3af52": { sourceSwaps: true, facet: "Unit" }
|
|
156
132
|
// swapAndStartBridgeTokensViaUnit (UnitFacet)
|
|
157
133
|
};
|
|
158
|
-
var
|
|
134
|
+
var UNBOUND_BRIDGES = {
|
|
135
|
+
"0x092e8fa4": "Relay",
|
|
136
|
+
// startBridgeTokensViaRelayDepository
|
|
137
|
+
"0xa3443faa": "Relay",
|
|
138
|
+
// swapAndStartBridgeTokensViaRelayDepository
|
|
139
|
+
"0x5f9af35d": "Garden",
|
|
140
|
+
// startBridgeTokensViaGarden
|
|
141
|
+
"0x76ad76fe": "Garden",
|
|
142
|
+
// swapAndStartBridgeTokensViaGarden
|
|
143
|
+
"0x4004633e": "deBridge DLN",
|
|
144
|
+
// startBridgeTokensViaDeBridgeDln
|
|
145
|
+
"0x2c7d2db0": "deBridge DLN",
|
|
146
|
+
// swapAndStartBridgeTokensViaDeBridgeDln
|
|
147
|
+
"0x2541ec57": "ThorSwap",
|
|
148
|
+
// startBridgeTokensViaThorSwap
|
|
149
|
+
"0xad673d88": "ThorSwap",
|
|
150
|
+
// swapAndStartBridgeTokensViaThorSwap
|
|
151
|
+
"0x3f313808": "Squid",
|
|
152
|
+
// startBridgeTokensViaSquid
|
|
153
|
+
"0xa8f66666": "Squid",
|
|
154
|
+
// swapAndStartBridgeTokensViaSquid
|
|
155
|
+
"0xe23b7a08": "Symbiosis",
|
|
156
|
+
// startBridgeTokensViaSymbiosis
|
|
157
|
+
"0xc46059b2": "Symbiosis"
|
|
158
|
+
// swapAndStartBridgeTokensViaSymbiosis
|
|
159
|
+
};
|
|
160
|
+
var Reader = class _Reader {
|
|
159
161
|
b;
|
|
160
|
-
constructor(
|
|
161
|
-
if (
|
|
162
|
-
|
|
162
|
+
constructor(src) {
|
|
163
|
+
if (typeof src !== "string") {
|
|
164
|
+
this.b = src;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (!/^0x([0-9a-fA-F]{2})*$/.test(src)) throw new Error("not hex");
|
|
168
|
+
this.b = Uint8Array.from(src.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16));
|
|
163
169
|
}
|
|
164
170
|
get length() {
|
|
165
171
|
return this.b.length;
|
|
166
172
|
}
|
|
173
|
+
/** `n` raw bytes at `at`, as 0x-hex. */
|
|
174
|
+
raw(at, n) {
|
|
175
|
+
if (at < 0 || at + n > this.b.length) throw new Error("out of bounds");
|
|
176
|
+
return `0x${Array.from(this.b.subarray(at, at + n), (x) => x.toString(16).padStart(2, "0")).join("")}`;
|
|
177
|
+
}
|
|
178
|
+
/** The `bytes` whose offset word sits at `head` (relative to `base`), as a reader over its contents only. */
|
|
179
|
+
bytes(base, head) {
|
|
180
|
+
const at = base + this.small(head);
|
|
181
|
+
const n = this.small(at);
|
|
182
|
+
if (at + 32 + n > this.b.length) throw new Error("bytes out of bounds");
|
|
183
|
+
return new _Reader(this.b.subarray(at + 32, at + 32 + n));
|
|
184
|
+
}
|
|
167
185
|
word(at) {
|
|
168
186
|
if (at < 0 || at + 32 > this.b.length) throw new Error("out of bounds");
|
|
169
187
|
let v = 0n;
|
|
@@ -221,6 +239,112 @@ function checkSteps(steps, e, finalAsset) {
|
|
|
221
239
|
if (!same(last.receivingAssetId, finalAsset)) return `delivers ${last.receivingAssetId}, not ${finalAsset}`;
|
|
222
240
|
return null;
|
|
223
241
|
}
|
|
242
|
+
var MAYAN_REFUND_AT = {
|
|
243
|
+
"0xa3a30834": 4 + 32 * 3,
|
|
244
|
+
// Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, …), customPayload)
|
|
245
|
+
"0x6147435b": 4 + 32 * 3,
|
|
246
|
+
// Swift v2 createOrderWithSig: the same order tuple
|
|
247
|
+
"0xb866e173": 4,
|
|
248
|
+
// Swift createOrderWithEth((trader, tokenOut, …))
|
|
249
|
+
"0x8e8d142b": 4 + 32 * 2,
|
|
250
|
+
// Swift createOrderWithToken(tokenIn, amountIn, (trader, tokenOut, …))
|
|
251
|
+
"0x6111ad25": 4 + 32 * 9,
|
|
252
|
+
// MayanSwap swap(relayerFees, (mayanAddr, mayanChainId, auctionAddr, destAddr, destChainId, referrer, refundAddr), …)
|
|
253
|
+
"0x1eb1cff0": 4 + 32 * 9
|
|
254
|
+
// MayanSwap wrapAndSwapETH: the same recipient tuple
|
|
255
|
+
};
|
|
256
|
+
function mayanRefunds(r, at) {
|
|
257
|
+
const p = r.bytes(at, at + 32 * 2);
|
|
258
|
+
const pos = MAYAN_REFUND_AT[p.raw(0, 4)];
|
|
259
|
+
return pos === void 0 ? [] : [["the Mayan order's refund address", p.address(pos)]];
|
|
260
|
+
}
|
|
261
|
+
function chainflipRefunds(r, at) {
|
|
262
|
+
const p = r.bytes(at, at + 32 * 5);
|
|
263
|
+
if (p.length < 25 || p.raw(0, 1) !== "0x01") throw new Error("unknown Chainflip parameters");
|
|
264
|
+
return [["the Chainflip refund address", p.raw(5, 20)]];
|
|
265
|
+
}
|
|
266
|
+
function acrossSwapRefunds(r, at) {
|
|
267
|
+
const target = r.word(at);
|
|
268
|
+
const c = r.bytes(at, at + 32);
|
|
269
|
+
if (target === 0n) return [["the Across deposit's depositor", c.address(c.small(0)), true]];
|
|
270
|
+
if (target === 1n) {
|
|
271
|
+
const swap = c.small(0);
|
|
272
|
+
return [["the Across deposit's depositor", c.address(swap + c.small(swap + 64) + 96), true]];
|
|
273
|
+
}
|
|
274
|
+
if (target === 2n) return [["the sponsored OFT refund recipient", c.address(c.small(0) + 32), true]];
|
|
275
|
+
if (target === 3n) return [["the sponsored CCTP refund recipient", c.address(64), true]];
|
|
276
|
+
throw new Error("unknown Across Swap API target");
|
|
277
|
+
}
|
|
278
|
+
var ERC20_TRANSFER = "0xa9059cbb";
|
|
279
|
+
function ecoDelivery(r, at, e) {
|
|
280
|
+
if (kindOf(e.toToken) === "native") return "an Eco route to the native token cannot be checked here";
|
|
281
|
+
const destination = r.word(at + 32 * 3);
|
|
282
|
+
if (destination !== e.destChainId) return `the Eco intent executes on chain ${destination}, not the destination ${e.destChainId} \u2014 a route whose delivery cannot be checked here`;
|
|
283
|
+
const route = r.bytes(at, at + 32 * 4);
|
|
284
|
+
const tuple = route.small(0);
|
|
285
|
+
const calls = tuple + route.small(tuple + 32 * 5);
|
|
286
|
+
const n = route.small(calls);
|
|
287
|
+
if (n === 0) return "the Eco route makes no calls on the destination chain";
|
|
288
|
+
if (n > 16) return `the Eco route makes ${n} calls on the destination chain, more than the 16 read here`;
|
|
289
|
+
const last = calls + 32 + route.small(calls + 32 + 32 * (n - 1));
|
|
290
|
+
const target = route.address(last);
|
|
291
|
+
const data = route.bytes(last, last + 32);
|
|
292
|
+
if (route.word(last + 64) !== 0n || data.length !== 68 || data.raw(0, 4) !== ERC20_TRANSFER) return "the Eco route does not end in a token transfer";
|
|
293
|
+
const to = data.address(4);
|
|
294
|
+
const amount = data.word(36);
|
|
295
|
+
if (!same(target, e.toToken)) return `the Eco route delivers ${target}, not ${e.toToken}`;
|
|
296
|
+
if (!same(to, e.receiver)) return `the Eco route pays ${to}, not ${e.receiver}`;
|
|
297
|
+
if (amount < e.minOut) return `the Eco route delivers ${amount}, below the ${e.minOut} shown`;
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
function m0Delivery(r, at, e) {
|
|
301
|
+
if (kindOf(e.toToken) === "native") return "an M0 order cannot deliver the native token";
|
|
302
|
+
const tokenOut = r.address(at + 32 * 3);
|
|
303
|
+
const amountOut = r.word(at + 32 * 5);
|
|
304
|
+
if (!same(tokenOut, e.toToken)) return `the M0 order asks for ${tokenOut}, not ${e.toToken}`;
|
|
305
|
+
if (amountOut < e.minOut) return `the M0 order asks for ${amountOut}, below the ${e.minOut} shown`;
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
var FACET_DATA = {
|
|
309
|
+
AcrossV4: { refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
310
|
+
// the SpokePool depositor: an expired deposit refunds the input there
|
|
311
|
+
AcrossV4Swap: { nested: acrossSwapRefunds },
|
|
312
|
+
Centrifuge: { inline: 2, refunds: [["refundRecipient", 1]], zeroRefused: true },
|
|
313
|
+
Chainflip: { nested: chainflipRefunds },
|
|
314
|
+
Eco: { refunds: [["refundRecipient", 6]], zeroRefused: true, delivery: ecoDelivery },
|
|
315
|
+
// the intent's creator, refunded its reward (the input) on expiry
|
|
316
|
+
Frax: { inline: 5, refunds: [["refundRecipient", 3]], zeroRefused: true },
|
|
317
|
+
Glacis: { inline: 4, refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
318
|
+
LayerSwap: { refunds: [["refundRecipient", 2]], zeroRefused: true },
|
|
319
|
+
LiFiIntentEscrowV2: { refunds: [["depositAndRefundAddress", 2]], zeroRefused: true },
|
|
320
|
+
// the escrow order's user
|
|
321
|
+
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true, delivery: m0Delivery },
|
|
322
|
+
// orderOwner gets a cancelled order back
|
|
323
|
+
Mayan: { refunds: [["refundRecipient", 7]], nested: mayanRefunds, zeroRefused: true },
|
|
324
|
+
NEARIntents: { refunds: [["refundRecipient", 6]], zeroRefused: true },
|
|
325
|
+
// also the 1Click quote's refundTo
|
|
326
|
+
PolymerCCTP: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
327
|
+
Stargate: { refunds: [["refundAddress", 4]] },
|
|
328
|
+
// (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund
|
|
329
|
+
Superset: { refunds: [["refundAddress", 2], ["fallbackEoA", 3]], zeroRefused: true }
|
|
330
|
+
};
|
|
331
|
+
var NO_REFUND_FIELDS = /* @__PURE__ */ new Set(["Across", "AllBridge", "ArbitrumBridge", "CelerCircleBridge", "GasZip", "GnosisBridge", "MegaETHBridge", "OmniBridge", "OptimismBridge", "PolygonBridge", "Unit"]);
|
|
332
|
+
function facetDataAt(r, bridge, spec) {
|
|
333
|
+
const slot = 4 + (bridge.sourceSwaps ? 64 : 32);
|
|
334
|
+
return spec.inline ? slot : 4 + r.small(slot);
|
|
335
|
+
}
|
|
336
|
+
function refundMismatch(r, bridge, e) {
|
|
337
|
+
const spec = FACET_DATA[bridge.facet];
|
|
338
|
+
if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;
|
|
339
|
+
const at = facetDataAt(r, bridge, spec);
|
|
340
|
+
const paid = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);
|
|
341
|
+
paid.push(...spec.nested?.(r, at) ?? []);
|
|
342
|
+
for (const [what, to, zeroRefused] of paid) {
|
|
343
|
+
if (zeroRefused && /^0x0{40}$/.test(to)) continue;
|
|
344
|
+
if (!same(to, e.sender) && !same(to, e.receiver)) return `${what} pays ${to}, neither the sender ${e.sender} nor the recipient`;
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
224
348
|
function diamondCallMismatch(data, e) {
|
|
225
349
|
let r;
|
|
226
350
|
try {
|
|
@@ -245,6 +369,8 @@ function diamondCallMismatch(data, e) {
|
|
|
245
369
|
}
|
|
246
370
|
return checkSteps(steps, e, e.toToken);
|
|
247
371
|
}
|
|
372
|
+
const unbound = UNBOUND_BRIDGES[selector];
|
|
373
|
+
if (unbound) return `${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`;
|
|
248
374
|
const bridge = BRIDGE_CALLS[selector];
|
|
249
375
|
if (!bridge) return `unknown Diamond call ${selector}`;
|
|
250
376
|
const head = r.small(4);
|
|
@@ -263,6 +389,11 @@ function diamondCallMismatch(data, e) {
|
|
|
263
389
|
if (!e.evmDestination) return "the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here";
|
|
264
390
|
if (!same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;
|
|
265
391
|
if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;
|
|
392
|
+
const refund = refundMismatch(r, bridge, e);
|
|
393
|
+
if (refund) return refund;
|
|
394
|
+
const spec = FACET_DATA[bridge.facet];
|
|
395
|
+
const delivery = spec?.delivery?.(r, facetDataAt(r, bridge, spec), e);
|
|
396
|
+
if (delivery) return delivery;
|
|
266
397
|
if (hasSourceSwaps) {
|
|
267
398
|
if (minAmount === 0n) return "bridges nothing after the source swaps";
|
|
268
399
|
return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);
|
|
@@ -274,8 +405,98 @@ function diamondCallMismatch(data, e) {
|
|
|
274
405
|
}
|
|
275
406
|
}
|
|
276
407
|
|
|
408
|
+
// src/solana.ts
|
|
409
|
+
import { base64Bytes } from "@anywalletkit/protocol-swap2-core/util";
|
|
410
|
+
var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
411
|
+
var MAYAN_ENTRY_PROGRAMS = /* @__PURE__ */ new Set([
|
|
412
|
+
"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa",
|
|
413
|
+
// CPI_PROXY_PROGRAM_ID
|
|
414
|
+
"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY",
|
|
415
|
+
// SWIFT_PROGRAM_ID
|
|
416
|
+
"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny",
|
|
417
|
+
// SWIFT_V2_PROGRAM_ID
|
|
418
|
+
"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU",
|
|
419
|
+
// MCTP_PROGRAM_ID
|
|
420
|
+
"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5"
|
|
421
|
+
// FAST_MCTP_PROGRAM_ID
|
|
422
|
+
]);
|
|
423
|
+
var SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
424
|
+
var LIFI_SOLANA_FEE_WALLET = "34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm";
|
|
425
|
+
function base58(bytes) {
|
|
426
|
+
let n = 0n;
|
|
427
|
+
for (const b of bytes) n = n << 8n | BigInt(b);
|
|
428
|
+
let out = "";
|
|
429
|
+
while (n > 0n) {
|
|
430
|
+
out = ALPHABET[Number(n % 58n)] + out;
|
|
431
|
+
n /= 58n;
|
|
432
|
+
}
|
|
433
|
+
for (const b of bytes) {
|
|
434
|
+
if (b !== 0) break;
|
|
435
|
+
out = `1${out}`;
|
|
436
|
+
}
|
|
437
|
+
return out;
|
|
438
|
+
}
|
|
439
|
+
var Cursor = class {
|
|
440
|
+
constructor(b) {
|
|
441
|
+
this.b = b;
|
|
442
|
+
}
|
|
443
|
+
b;
|
|
444
|
+
at = 0;
|
|
445
|
+
byte() {
|
|
446
|
+
if (this.at >= this.b.length) throw new Error("truncated");
|
|
447
|
+
return this.b[this.at++];
|
|
448
|
+
}
|
|
449
|
+
bytes(n) {
|
|
450
|
+
if (n < 0 || this.at + n > this.b.length) throw new Error("truncated");
|
|
451
|
+
const out = this.b.subarray(this.at, this.at + n);
|
|
452
|
+
this.at += n;
|
|
453
|
+
return out;
|
|
454
|
+
}
|
|
455
|
+
/** compact-u16 */
|
|
456
|
+
short() {
|
|
457
|
+
let v = 0;
|
|
458
|
+
for (let shift = 0; shift < 21; shift += 7) {
|
|
459
|
+
const b = this.byte();
|
|
460
|
+
v |= (b & 127) << shift;
|
|
461
|
+
if (!(b & 128)) return v;
|
|
462
|
+
}
|
|
463
|
+
throw new Error("bad length");
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
function solanaBridgeTxMismatch(base64, sender) {
|
|
467
|
+
const bytes = base64Bytes(base64);
|
|
468
|
+
if (!bytes) return "the Solana transaction is not base64";
|
|
469
|
+
const c = new Cursor(bytes);
|
|
470
|
+
try {
|
|
471
|
+
c.bytes(64 * c.short());
|
|
472
|
+
const first = c.byte();
|
|
473
|
+
if ((first & 128) === 0) c.at--;
|
|
474
|
+
c.bytes(3);
|
|
475
|
+
const keys = Array.from({ length: c.short() }, () => base58(c.bytes(32)));
|
|
476
|
+
if (keys[0] !== sender) return `the Solana transaction is paid by ${keys[0] ?? "nobody"}, not the sender ${sender}`;
|
|
477
|
+
c.bytes(32);
|
|
478
|
+
let mayan = false;
|
|
479
|
+
const payees = [];
|
|
480
|
+
const n = c.short();
|
|
481
|
+
for (let i = 0; i < n; i++) {
|
|
482
|
+
const program = keys[c.byte()];
|
|
483
|
+
const accounts = Array.from(c.bytes(c.short()));
|
|
484
|
+
const data = c.bytes(c.short());
|
|
485
|
+
if (program !== void 0 && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;
|
|
486
|
+
if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {
|
|
487
|
+
const to = keys[accounts[1] ?? -1];
|
|
488
|
+
if (to !== void 0 && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return mayan && payees.length ? `the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet` : null;
|
|
492
|
+
} catch (err) {
|
|
493
|
+
return `the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
277
497
|
// src/provider.ts
|
|
278
498
|
import { timeoutSignal, sourceAssetOf } from "@anywalletkit/protocol-swap2-core/util";
|
|
499
|
+
import { slippageFloor } from "@anywalletkit/protocol-swap2-core/validate";
|
|
279
500
|
import { bigintToNumber } from "@anywalletkit/core";
|
|
280
501
|
var DEFAULT_LIFI_BASE = "https://li.quest/v1";
|
|
281
502
|
var LIFI_CHAIN = {
|
|
@@ -412,7 +633,8 @@ function headers(key) {
|
|
|
412
633
|
return h;
|
|
413
634
|
}
|
|
414
635
|
var TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;
|
|
415
|
-
|
|
636
|
+
var UNBOUND_TOOLS = Object.freeze(["relaydepository", "garden", "squid", "symbiosis"]);
|
|
637
|
+
function routeOptions(body, excluded) {
|
|
416
638
|
const routes = body?.routes;
|
|
417
639
|
if (!Array.isArray(routes)) return [];
|
|
418
640
|
const out = [];
|
|
@@ -422,7 +644,7 @@ function routeOptions(body) {
|
|
|
422
644
|
const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === "cross")?.tool : void 0;
|
|
423
645
|
const tool = typeof cross === "string" ? cross : step.tool;
|
|
424
646
|
const eta = step.estimate?.executionDuration;
|
|
425
|
-
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
647
|
+
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || excluded.includes(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
426
648
|
if (typeof r.toAmount !== "string" || typeof r.toAmountMin !== "string" || !/^\d{1,60}$/.test(r.toAmount) || !/^\d{1,60}$/.test(r.toAmountMin)) continue;
|
|
427
649
|
out.push({
|
|
428
650
|
tool,
|
|
@@ -486,6 +708,9 @@ function lifiProvider(config = {}) {
|
|
|
486
708
|
const fromToken = lifiToken(params);
|
|
487
709
|
if (!fromToken) return null;
|
|
488
710
|
const solanaSource = isSolana(params.sourceChain);
|
|
711
|
+
const crossChain = params.sourceChain !== params.destChain;
|
|
712
|
+
const noDestinationCall = crossChain && !solanaSource;
|
|
713
|
+
let routeScope = config.routeWideSlippage === true && !solanaSource && !isSolana(params.destChain);
|
|
489
714
|
const dry = params.dry !== false;
|
|
490
715
|
const fromAddress = params.refundAddress || (dry ? solanaSource ? SOLANA_PLACEHOLDER : EVM_PLACEHOLDER : "");
|
|
491
716
|
const toAddress = params.destAddress || (dry ? fromAddress : "");
|
|
@@ -495,7 +720,7 @@ function lifiProvider(config = {}) {
|
|
|
495
720
|
let sentSlippage = slippageBps / 1e4;
|
|
496
721
|
let deadline;
|
|
497
722
|
let choice = null;
|
|
498
|
-
if (config.chooseRoute &&
|
|
723
|
+
if (config.chooseRoute && crossChain) {
|
|
499
724
|
try {
|
|
500
725
|
const res = await fetch(`${apiBase}/advanced/routes`, {
|
|
501
726
|
method: "POST",
|
|
@@ -508,12 +733,18 @@ function lifiProvider(config = {}) {
|
|
|
508
733
|
fromAmount: params.amountIn,
|
|
509
734
|
fromAddress,
|
|
510
735
|
toAddress,
|
|
511
|
-
options: {
|
|
736
|
+
options: {
|
|
737
|
+
slippage: slippageBps / 1e4,
|
|
738
|
+
...routeScope ? { slippageScope: "route" } : {},
|
|
739
|
+
...solanaSource ? {} : { bridges: { deny: UNBOUND_TOOLS } },
|
|
740
|
+
...noDestinationCall ? { allowDestinationCall: false } : {},
|
|
741
|
+
...integrator().trim() ? { integrator: integrator().trim() } : {}
|
|
742
|
+
}
|
|
512
743
|
}),
|
|
513
744
|
signal: signal ?? timeoutSignal(8e3)
|
|
514
745
|
});
|
|
515
746
|
if (res.ok) {
|
|
516
|
-
const options = routeOptions(await res.json());
|
|
747
|
+
const options = routeOptions(await res.json(), solanaSource ? [] : UNBOUND_TOOLS);
|
|
517
748
|
if (options.length) choice = cleanChoice(config.chooseRoute(options, params));
|
|
518
749
|
}
|
|
519
750
|
} catch {
|
|
@@ -533,8 +764,11 @@ function lifiProvider(config = {}) {
|
|
|
533
764
|
if (sentSlippage !== void 0) {
|
|
534
765
|
url.searchParams.set("slippage", String(sentSlippage));
|
|
535
766
|
}
|
|
536
|
-
|
|
537
|
-
|
|
767
|
+
if (routeScope) url.searchParams.set("slippageScope", "route");
|
|
768
|
+
if (noDestinationCall) url.searchParams.set("allowDestinationCall", "false");
|
|
769
|
+
const unbound = crossChain && !solanaSource ? UNBOUND_TOOLS : [];
|
|
770
|
+
for (const t of (choice?.allowBridges ?? []).filter((b) => solanaSource || !UNBOUND_TOOLS.includes(b))) url.searchParams.append("allowBridges", t);
|
|
771
|
+
for (const t of /* @__PURE__ */ new Set([...choice?.denyBridges ?? [], ...unbound])) url.searchParams.append("denyBridges", t);
|
|
538
772
|
if (choice?.order) url.searchParams.set("order", choice.order);
|
|
539
773
|
deadline = signal ? void 0 : timeoutSignal(12e3);
|
|
540
774
|
const res = await fetch(url, { headers: headers(apiKey()), signal: signal ?? deadline });
|
|
@@ -546,6 +780,11 @@ function lifiProvider(config = {}) {
|
|
|
546
780
|
if (!res.ok) {
|
|
547
781
|
const body = await res.json().catch(() => null);
|
|
548
782
|
const reasons = [...new Set((body?.errors?.filteredOut ?? []).map((f) => f.reason).filter((r) => typeof r === "string"))];
|
|
783
|
+
if (routeScope && [typeof body?.message === "string" ? body.message : "", ...reasons].some((r) => /^ROUTE_SLIPPAGE_(UNSUPPORTED|UNAVAILABLE)/.test(r))) {
|
|
784
|
+
routeScope = false;
|
|
785
|
+
attempt--;
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
549
788
|
const why = reasons.length === 1 ? ` (${reasons[0].slice(0, 200)})` : "";
|
|
550
789
|
params.onRefusal?.(`lifi: ${typeof body?.message === "string" ? body.message.slice(0, 200) : `HTTP ${res.status}`}${why}`);
|
|
551
790
|
return null;
|
|
@@ -578,6 +817,10 @@ function lifiProvider(config = {}) {
|
|
|
578
817
|
if (solanaSource) {
|
|
579
818
|
if (!tr.data || tr.data.length < 64 || tr.data.length % 4 !== 0 || !BASE64.test(tr.data)) return reject("the Solana transaction is not base64");
|
|
580
819
|
if (tr.to !== void 0 || tr.value !== void 0 || tr.gasLimit !== void 0) return reject("the Solana transaction carries EVM fields");
|
|
820
|
+
if (fromChain !== toChain) {
|
|
821
|
+
const why = solanaBridgeTxMismatch(tr.data, fromAddress);
|
|
822
|
+
if (why) return reject(why);
|
|
823
|
+
}
|
|
581
824
|
} else if (!isHexData(tr.data) || !normalizeAddress(tr.to) || !normalizeAddress(tr.from) || tr.chainId !== expectedFromChain || !tr.value || !tr.gasLimit || !trustedAddress(params.sourceChain, tr.to, trustedTransactionTargets) || !sameAddress(tr.from, fromAddress)) return reject("the transaction is malformed or targets an untrusted contract");
|
|
582
825
|
if (sentSlippage !== void 0 && (typeof action.slippage !== "number" || Math.abs(action.slippage - sentSlippage) > 1e-12)) return reject("the quote ignored the requested slippage");
|
|
583
826
|
const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;
|
|
@@ -615,7 +858,7 @@ function lifiProvider(config = {}) {
|
|
|
615
858
|
if (sentSlippage !== void 0) {
|
|
616
859
|
const dest = BigInt(est.toAmount);
|
|
617
860
|
const min = BigInt(minDestAmount);
|
|
618
|
-
if (dest > 0n && min < dest
|
|
861
|
+
if (dest > 0n && min < slippageFloor(dest, slippageBps)) {
|
|
619
862
|
const effective = bigintToNumber((dest - min) * 1000000n / dest) / 1e6;
|
|
620
863
|
const requested = slippageBps / 1e4;
|
|
621
864
|
const scaled = Math.floor(sentSlippage * requested / effective * 0.995 * 1e6) / 1e6;
|
|
@@ -644,6 +887,7 @@ function lifiProvider(config = {}) {
|
|
|
644
887
|
toToken: expectedToToken,
|
|
645
888
|
amountIn: BigInt(params.amountIn),
|
|
646
889
|
receiver: toAddress,
|
|
890
|
+
sender: fromAddress,
|
|
647
891
|
minOut: BigInt(minDestAmount),
|
|
648
892
|
destChainId: BigInt(toChain),
|
|
649
893
|
sameChain: fromChain === toChain,
|
|
@@ -662,6 +906,7 @@ function lifiProvider(config = {}) {
|
|
|
662
906
|
sourceAmount: params.amountIn,
|
|
663
907
|
destAmount: est.toAmount,
|
|
664
908
|
minDestAmount,
|
|
909
|
+
...Number.isInteger(action.toToken?.decimals) && action.toToken.decimals >= 0 && action.toToken.decimals <= 36 ? { destDecimals: action.toToken.decimals } : {},
|
|
665
910
|
feeUsd,
|
|
666
911
|
etaSeconds: est.executionDuration ?? 120,
|
|
667
912
|
reliability: 0.97,
|
|
@@ -729,7 +974,10 @@ function lifiVerifyQuote(params, quote) {
|
|
|
729
974
|
if (!fromChain || !toChain) return "not a LI.FI chain pair";
|
|
730
975
|
const tx = quote.txRequest;
|
|
731
976
|
if (!tx) return "the quote carries no transaction";
|
|
732
|
-
if (isSolana(params.sourceChain))
|
|
977
|
+
if (isSolana(params.sourceChain)) {
|
|
978
|
+
if (!tx.serializedTx || tx.data !== void 0 || tx.to !== void 0) return "a Solana source carries a serialized transaction only";
|
|
979
|
+
return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : ""));
|
|
980
|
+
}
|
|
733
981
|
if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== void 0) return "the quote carries no Diamond call";
|
|
734
982
|
if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return `the call targets ${tx.to}, not the LI.FI Diamond`;
|
|
735
983
|
if (tx.chainId !== void 0 && String(tx.chainId) !== fromChain) return `the call is for chain ${tx.chainId}, not ${fromChain}`;
|
|
@@ -764,6 +1012,7 @@ function lifiVerifyQuote(params, quote) {
|
|
|
764
1012
|
toToken: nativeFor(params.destChain, params.destToken),
|
|
765
1013
|
amountIn,
|
|
766
1014
|
receiver: toAddress,
|
|
1015
|
+
sender: fromAddress,
|
|
767
1016
|
minOut,
|
|
768
1017
|
destChainId: BigInt(toChain),
|
|
769
1018
|
sameChain: fromChain === toChain,
|
|
@@ -782,4 +1031,4 @@ export {
|
|
|
782
1031
|
lifiVerifyQuote,
|
|
783
1032
|
lifiPins
|
|
784
1033
|
};
|
|
785
|
-
//# sourceMappingURL=chunk-
|
|
1034
|
+
//# sourceMappingURL=chunk-IZ7TP4KT.js.map
|