@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
package/dist/provider.cjs
CHANGED
|
@@ -94,144 +94,162 @@ var GENERIC_SWAPS = {
|
|
|
94
94
|
var BRIDGE_INPUT_FEE_MAX_BPS = 100n;
|
|
95
95
|
var kindOf = (asset) => /^0x0{40}$/i.test(asset) ? "native" : "erc20";
|
|
96
96
|
var BRIDGE_CALLS = {
|
|
97
|
-
"0x1fd8010c": { sourceSwaps: false },
|
|
97
|
+
"0x1fd8010c": { sourceSwaps: false, facet: "Across" },
|
|
98
98
|
// startBridgeTokensViaAcross (AcrossFacet)
|
|
99
|
-
"0x3a3f7332": { sourceSwaps: true },
|
|
99
|
+
"0x3a3f7332": { sourceSwaps: true, facet: "Across" },
|
|
100
100
|
// swapAndStartBridgeTokensViaAcross (AcrossFacet)
|
|
101
|
-
"0xa1f1ce43": { sourceSwaps: false },
|
|
101
|
+
"0xa1f1ce43": { sourceSwaps: false, facet: "AcrossV4" },
|
|
102
102
|
// startBridgeTokensViaAcrossV4 (AcrossFacetV4)
|
|
103
|
-
"0x1794958f": { sourceSwaps: true },
|
|
103
|
+
"0x1794958f": { sourceSwaps: true, facet: "AcrossV4" },
|
|
104
104
|
// swapAndStartBridgeTokensViaAcrossV4 (AcrossFacetV4)
|
|
105
|
-
"0x6a90d66e": { sourceSwaps: false },
|
|
105
|
+
"0x6a90d66e": { sourceSwaps: false, facet: "AcrossV4Swap" },
|
|
106
106
|
// startBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)
|
|
107
|
-
"0x9b054bc4": { sourceSwaps: true },
|
|
107
|
+
"0x9b054bc4": { sourceSwaps: true, facet: "AcrossV4Swap" },
|
|
108
108
|
// swapAndStartBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)
|
|
109
|
-
"0x6a51e9a9": { sourceSwaps: false },
|
|
109
|
+
"0x6a51e9a9": { sourceSwaps: false, facet: "AllBridge" },
|
|
110
110
|
// startBridgeTokensViaAllBridge (AllBridgeFacet)
|
|
111
|
-
"0x63267469": { sourceSwaps: true },
|
|
111
|
+
"0x63267469": { sourceSwaps: true, facet: "AllBridge" },
|
|
112
112
|
// swapAndStartBridgeTokensViaAllBridge (AllBridgeFacet)
|
|
113
|
-
"0xc9851d0b": { sourceSwaps: false },
|
|
113
|
+
"0xc9851d0b": { sourceSwaps: false, facet: "ArbitrumBridge" },
|
|
114
114
|
// startBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)
|
|
115
|
-
"0x3cc9517b": { sourceSwaps: true },
|
|
115
|
+
"0x3cc9517b": { sourceSwaps: true, facet: "ArbitrumBridge" },
|
|
116
116
|
// swapAndStartBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)
|
|
117
|
-
"0xe0a4201c": { sourceSwaps: false },
|
|
117
|
+
"0xe0a4201c": { sourceSwaps: false, facet: "CelerCircleBridge" },
|
|
118
118
|
// startBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)
|
|
119
|
-
"0x4f3b0759": { sourceSwaps: true },
|
|
119
|
+
"0x4f3b0759": { sourceSwaps: true, facet: "CelerCircleBridge" },
|
|
120
120
|
// swapAndStartBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)
|
|
121
|
-
"0x0315138f": { sourceSwaps: false },
|
|
121
|
+
"0x0315138f": { sourceSwaps: false, facet: "Centrifuge" },
|
|
122
122
|
// startBridgeTokensViaCentrifuge (CentrifugeFacet)
|
|
123
|
-
"0x8fd4d4dd": { sourceSwaps: true },
|
|
123
|
+
"0x8fd4d4dd": { sourceSwaps: true, facet: "Centrifuge" },
|
|
124
124
|
// swapAndStartBridgeTokensViaCentrifuge (CentrifugeFacet)
|
|
125
|
-
"0x0ad553b3": { sourceSwaps: false },
|
|
125
|
+
"0x0ad553b3": { sourceSwaps: false, facet: "Chainflip" },
|
|
126
126
|
// startBridgeTokensViaChainflip (ChainflipFacet)
|
|
127
|
-
"0xee3314a1": { sourceSwaps: true },
|
|
127
|
+
"0xee3314a1": { sourceSwaps: true, facet: "Chainflip" },
|
|
128
128
|
// swapAndStartBridgeTokensViaChainflip (ChainflipFacet)
|
|
129
|
-
"
|
|
130
|
-
//
|
|
131
|
-
"
|
|
132
|
-
//
|
|
133
|
-
"
|
|
134
|
-
// startBridgeTokensViaEco (EcoFacet)
|
|
135
|
-
"0x762aea18": { sourceSwaps: true },
|
|
136
|
-
// swapAndStartBridgeTokensViaEco (EcoFacet)
|
|
137
|
-
"0x678786ea": { sourceSwaps: false },
|
|
129
|
+
"0x05c54990": { sourceSwaps: false, facet: "Eco" },
|
|
130
|
+
// startBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
131
|
+
"0x8352664c": { sourceSwaps: true, facet: "Eco" },
|
|
132
|
+
// swapAndStartBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
133
|
+
"0x678786ea": { sourceSwaps: false, facet: "Frax" },
|
|
138
134
|
// startBridgeTokensViaFrax (FraxFacet)
|
|
139
|
-
"0x07b8e4c7": { sourceSwaps: true },
|
|
135
|
+
"0x07b8e4c7": { sourceSwaps: true, facet: "Frax" },
|
|
140
136
|
// swapAndStartBridgeTokensViaFrax (FraxFacet)
|
|
141
|
-
"
|
|
142
|
-
// startBridgeTokensViaGarden (GardenFacet)
|
|
143
|
-
"0x76ad76fe": { sourceSwaps: true },
|
|
144
|
-
// swapAndStartBridgeTokensViaGarden (GardenFacet)
|
|
145
|
-
"0xfc5f1003": { sourceSwaps: false },
|
|
137
|
+
"0xfc5f1003": { sourceSwaps: false, facet: "GasZip" },
|
|
146
138
|
// startBridgeTokensViaGasZip (GasZipFacet)
|
|
147
|
-
"0x606326ff": { sourceSwaps: true },
|
|
139
|
+
"0x606326ff": { sourceSwaps: true, facet: "GasZip" },
|
|
148
140
|
// swapAndStartBridgeTokensViaGasZip (GasZipFacet)
|
|
149
|
-
"0x6f9206ba": { sourceSwaps: false },
|
|
141
|
+
"0x6f9206ba": { sourceSwaps: false, facet: "Glacis" },
|
|
150
142
|
// startBridgeTokensViaGlacis (GlacisFacet)
|
|
151
|
-
"0x9c4b6dd9": { sourceSwaps: true },
|
|
143
|
+
"0x9c4b6dd9": { sourceSwaps: true, facet: "Glacis" },
|
|
152
144
|
// swapAndStartBridgeTokensViaGlacis (GlacisFacet)
|
|
153
|
-
"0xf66fe519": { sourceSwaps: false },
|
|
145
|
+
"0xf66fe519": { sourceSwaps: false, facet: "GnosisBridge" },
|
|
154
146
|
// startBridgeTokensViaGnosisBridge (GnosisBridgeFacet)
|
|
155
|
-
"0x7bf96e0a": { sourceSwaps: true },
|
|
147
|
+
"0x7bf96e0a": { sourceSwaps: true, facet: "GnosisBridge" },
|
|
156
148
|
// swapAndStartBridgeTokensViaGnosisBridge (GnosisBridgeFacet)
|
|
157
|
-
"0xee9e98e0": { sourceSwaps: false },
|
|
149
|
+
"0xee9e98e0": { sourceSwaps: false, facet: "LayerSwap" },
|
|
158
150
|
// startBridgeTokensViaLayerSwap (LayerSwapFacet)
|
|
159
|
-
"0x4c279d6b": { sourceSwaps: true },
|
|
151
|
+
"0x4c279d6b": { sourceSwaps: true, facet: "LayerSwap" },
|
|
160
152
|
// swapAndStartBridgeTokensViaLayerSwap (LayerSwapFacet)
|
|
161
|
-
"0x7dbcf1d9": { sourceSwaps: false },
|
|
153
|
+
"0x7dbcf1d9": { sourceSwaps: false, facet: "LiFiIntentEscrowV2" },
|
|
162
154
|
// startBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)
|
|
163
|
-
"0x6d21c5df": { sourceSwaps: true },
|
|
155
|
+
"0x6d21c5df": { sourceSwaps: true, facet: "LiFiIntentEscrowV2" },
|
|
164
156
|
// swapAndStartBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)
|
|
165
|
-
"0x65782c4b": { sourceSwaps: false },
|
|
157
|
+
"0x65782c4b": { sourceSwaps: false, facet: "M0" },
|
|
166
158
|
// startBridgeTokensViaM0 (M0Facet)
|
|
167
|
-
"0xb9eaf86d": { sourceSwaps: true },
|
|
159
|
+
"0xb9eaf86d": { sourceSwaps: true, facet: "M0" },
|
|
168
160
|
// swapAndStartBridgeTokensViaM0 (M0Facet)
|
|
169
|
-
"0xb4875292": { sourceSwaps: false },
|
|
161
|
+
"0xb4875292": { sourceSwaps: false, facet: "Mayan" },
|
|
170
162
|
// startBridgeTokensViaMayan (MayanFacet)
|
|
171
|
-
"0x80c65808": { sourceSwaps: true },
|
|
163
|
+
"0x80c65808": { sourceSwaps: true, facet: "Mayan" },
|
|
172
164
|
// swapAndStartBridgeTokensViaMayan (MayanFacet)
|
|
173
|
-
"0x4213dfff": { sourceSwaps: false },
|
|
165
|
+
"0x4213dfff": { sourceSwaps: false, facet: "MegaETHBridge" },
|
|
174
166
|
// startBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)
|
|
175
|
-
"0x22256e89": { sourceSwaps: true },
|
|
167
|
+
"0x22256e89": { sourceSwaps: true, facet: "MegaETHBridge" },
|
|
176
168
|
// swapAndStartBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)
|
|
177
|
-
"0x4698f032": { sourceSwaps: false },
|
|
169
|
+
"0x4698f032": { sourceSwaps: false, facet: "NEARIntents" },
|
|
178
170
|
// startBridgeTokensViaNEARIntents (NEARIntentsFacet)
|
|
179
|
-
"0x02631b09": { sourceSwaps: true },
|
|
171
|
+
"0x02631b09": { sourceSwaps: true, facet: "NEARIntents" },
|
|
180
172
|
// swapAndStartBridgeTokensViaNEARIntents (NEARIntentsFacet)
|
|
181
|
-
"0x782621d8": { sourceSwaps: false },
|
|
173
|
+
"0x782621d8": { sourceSwaps: false, facet: "OmniBridge" },
|
|
182
174
|
// startBridgeTokensViaOmniBridge (OmniBridgeFacet)
|
|
183
|
-
"0x95726782": { sourceSwaps: true },
|
|
175
|
+
"0x95726782": { sourceSwaps: true, facet: "OmniBridge" },
|
|
184
176
|
// swapAndStartBridgeTokensViaOmniBridge (OmniBridgeFacet)
|
|
185
|
-
"0xce8a97a5": { sourceSwaps: false },
|
|
177
|
+
"0xce8a97a5": { sourceSwaps: false, facet: "OptimismBridge" },
|
|
186
178
|
// startBridgeTokensViaOptimismBridge (OptimismBridgeFacet)
|
|
187
|
-
"0x5bb5d448": { sourceSwaps: true },
|
|
179
|
+
"0x5bb5d448": { sourceSwaps: true, facet: "OptimismBridge" },
|
|
188
180
|
// swapAndStartBridgeTokensViaOptimismBridge (OptimismBridgeFacet)
|
|
189
|
-
"0xaf62c7d6": { sourceSwaps: false },
|
|
181
|
+
"0xaf62c7d6": { sourceSwaps: false, facet: "PolygonBridge" },
|
|
190
182
|
// startBridgeTokensViaPolygonBridge (PolygonBridgeFacet)
|
|
191
|
-
"0xb4f37581": { sourceSwaps: true },
|
|
183
|
+
"0xb4f37581": { sourceSwaps: true, facet: "PolygonBridge" },
|
|
192
184
|
// swapAndStartBridgeTokensViaPolygonBridge (PolygonBridgeFacet)
|
|
193
|
-
"0xf434d6ca": { sourceSwaps: false },
|
|
185
|
+
"0xf434d6ca": { sourceSwaps: false, facet: "PolymerCCTP" },
|
|
194
186
|
// startBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)
|
|
195
|
-
"0x17917a4e": { sourceSwaps: true },
|
|
187
|
+
"0x17917a4e": { sourceSwaps: true, facet: "PolymerCCTP" },
|
|
196
188
|
// swapAndStartBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)
|
|
197
|
-
"
|
|
198
|
-
// startBridgeTokensViaRelayDepository (RelayDepositoryFacet)
|
|
199
|
-
"0xa3443faa": { sourceSwaps: true },
|
|
200
|
-
// swapAndStartBridgeTokensViaRelayDepository (RelayDepositoryFacet)
|
|
201
|
-
"0x3f313808": { sourceSwaps: false },
|
|
202
|
-
// startBridgeTokensViaSquid (SquidFacet)
|
|
203
|
-
"0xa8f66666": { sourceSwaps: true },
|
|
204
|
-
// swapAndStartBridgeTokensViaSquid (SquidFacet)
|
|
205
|
-
"0x14d53077": { sourceSwaps: false },
|
|
189
|
+
"0x14d53077": { sourceSwaps: false, facet: "Stargate" },
|
|
206
190
|
// startBridgeTokensViaStargate (StargateFacetV2)
|
|
207
|
-
"0xa6010a66": { sourceSwaps: true },
|
|
191
|
+
"0xa6010a66": { sourceSwaps: true, facet: "Stargate" },
|
|
208
192
|
// swapAndStartBridgeTokensViaStargate (StargateFacetV2)
|
|
209
|
-
"0x0691ff78": { sourceSwaps: false },
|
|
193
|
+
"0x0691ff78": { sourceSwaps: false, facet: "Superset" },
|
|
210
194
|
// startBridgeTokensViaSuperset (SupersetFacet)
|
|
211
|
-
"0xf26e657f": { sourceSwaps: true },
|
|
195
|
+
"0xf26e657f": { sourceSwaps: true, facet: "Superset" },
|
|
212
196
|
// swapAndStartBridgeTokensViaSuperset (SupersetFacet)
|
|
213
|
-
"
|
|
214
|
-
// startBridgeTokensViaSymbiosis (SymbiosisFacet)
|
|
215
|
-
"0xc46059b2": { sourceSwaps: true },
|
|
216
|
-
// swapAndStartBridgeTokensViaSymbiosis (SymbiosisFacet)
|
|
217
|
-
"0x2541ec57": { sourceSwaps: false },
|
|
218
|
-
// startBridgeTokensViaThorSwap (ThorSwapFacet)
|
|
219
|
-
"0xad673d88": { sourceSwaps: true },
|
|
220
|
-
// swapAndStartBridgeTokensViaThorSwap (ThorSwapFacet)
|
|
221
|
-
"0x64261d58": { sourceSwaps: false },
|
|
197
|
+
"0x64261d58": { sourceSwaps: false, facet: "Unit" },
|
|
222
198
|
// startBridgeTokensViaUnit (UnitFacet)
|
|
223
|
-
"0x21a3af52": { sourceSwaps: true }
|
|
199
|
+
"0x21a3af52": { sourceSwaps: true, facet: "Unit" }
|
|
224
200
|
// swapAndStartBridgeTokensViaUnit (UnitFacet)
|
|
225
201
|
};
|
|
226
|
-
var
|
|
202
|
+
var UNBOUND_BRIDGES = {
|
|
203
|
+
"0x092e8fa4": "Relay",
|
|
204
|
+
// startBridgeTokensViaRelayDepository
|
|
205
|
+
"0xa3443faa": "Relay",
|
|
206
|
+
// swapAndStartBridgeTokensViaRelayDepository
|
|
207
|
+
"0x5f9af35d": "Garden",
|
|
208
|
+
// startBridgeTokensViaGarden
|
|
209
|
+
"0x76ad76fe": "Garden",
|
|
210
|
+
// swapAndStartBridgeTokensViaGarden
|
|
211
|
+
"0x4004633e": "deBridge DLN",
|
|
212
|
+
// startBridgeTokensViaDeBridgeDln
|
|
213
|
+
"0x2c7d2db0": "deBridge DLN",
|
|
214
|
+
// swapAndStartBridgeTokensViaDeBridgeDln
|
|
215
|
+
"0x2541ec57": "ThorSwap",
|
|
216
|
+
// startBridgeTokensViaThorSwap
|
|
217
|
+
"0xad673d88": "ThorSwap",
|
|
218
|
+
// swapAndStartBridgeTokensViaThorSwap
|
|
219
|
+
"0x3f313808": "Squid",
|
|
220
|
+
// startBridgeTokensViaSquid
|
|
221
|
+
"0xa8f66666": "Squid",
|
|
222
|
+
// swapAndStartBridgeTokensViaSquid
|
|
223
|
+
"0xe23b7a08": "Symbiosis",
|
|
224
|
+
// startBridgeTokensViaSymbiosis
|
|
225
|
+
"0xc46059b2": "Symbiosis"
|
|
226
|
+
// swapAndStartBridgeTokensViaSymbiosis
|
|
227
|
+
};
|
|
228
|
+
var Reader = class _Reader {
|
|
227
229
|
b;
|
|
228
|
-
constructor(
|
|
229
|
-
if (
|
|
230
|
-
|
|
230
|
+
constructor(src) {
|
|
231
|
+
if (typeof src !== "string") {
|
|
232
|
+
this.b = src;
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (!/^0x([0-9a-fA-F]{2})*$/.test(src)) throw new Error("not hex");
|
|
236
|
+
this.b = Uint8Array.from(src.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16));
|
|
231
237
|
}
|
|
232
238
|
get length() {
|
|
233
239
|
return this.b.length;
|
|
234
240
|
}
|
|
241
|
+
/** `n` raw bytes at `at`, as 0x-hex. */
|
|
242
|
+
raw(at, n) {
|
|
243
|
+
if (at < 0 || at + n > this.b.length) throw new Error("out of bounds");
|
|
244
|
+
return `0x${Array.from(this.b.subarray(at, at + n), (x) => x.toString(16).padStart(2, "0")).join("")}`;
|
|
245
|
+
}
|
|
246
|
+
/** The `bytes` whose offset word sits at `head` (relative to `base`), as a reader over its contents only. */
|
|
247
|
+
bytes(base, head) {
|
|
248
|
+
const at = base + this.small(head);
|
|
249
|
+
const n = this.small(at);
|
|
250
|
+
if (at + 32 + n > this.b.length) throw new Error("bytes out of bounds");
|
|
251
|
+
return new _Reader(this.b.subarray(at + 32, at + 32 + n));
|
|
252
|
+
}
|
|
235
253
|
word(at) {
|
|
236
254
|
if (at < 0 || at + 32 > this.b.length) throw new Error("out of bounds");
|
|
237
255
|
let v = 0n;
|
|
@@ -289,6 +307,112 @@ function checkSteps(steps, e, finalAsset) {
|
|
|
289
307
|
if (!same(last.receivingAssetId, finalAsset)) return `delivers ${last.receivingAssetId}, not ${finalAsset}`;
|
|
290
308
|
return null;
|
|
291
309
|
}
|
|
310
|
+
var MAYAN_REFUND_AT = {
|
|
311
|
+
"0xa3a30834": 4 + 32 * 3,
|
|
312
|
+
// Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, …), customPayload)
|
|
313
|
+
"0x6147435b": 4 + 32 * 3,
|
|
314
|
+
// Swift v2 createOrderWithSig: the same order tuple
|
|
315
|
+
"0xb866e173": 4,
|
|
316
|
+
// Swift createOrderWithEth((trader, tokenOut, …))
|
|
317
|
+
"0x8e8d142b": 4 + 32 * 2,
|
|
318
|
+
// Swift createOrderWithToken(tokenIn, amountIn, (trader, tokenOut, …))
|
|
319
|
+
"0x6111ad25": 4 + 32 * 9,
|
|
320
|
+
// MayanSwap swap(relayerFees, (mayanAddr, mayanChainId, auctionAddr, destAddr, destChainId, referrer, refundAddr), …)
|
|
321
|
+
"0x1eb1cff0": 4 + 32 * 9
|
|
322
|
+
// MayanSwap wrapAndSwapETH: the same recipient tuple
|
|
323
|
+
};
|
|
324
|
+
function mayanRefunds(r, at) {
|
|
325
|
+
const p = r.bytes(at, at + 32 * 2);
|
|
326
|
+
const pos = MAYAN_REFUND_AT[p.raw(0, 4)];
|
|
327
|
+
return pos === void 0 ? [] : [["the Mayan order's refund address", p.address(pos)]];
|
|
328
|
+
}
|
|
329
|
+
function chainflipRefunds(r, at) {
|
|
330
|
+
const p = r.bytes(at, at + 32 * 5);
|
|
331
|
+
if (p.length < 25 || p.raw(0, 1) !== "0x01") throw new Error("unknown Chainflip parameters");
|
|
332
|
+
return [["the Chainflip refund address", p.raw(5, 20)]];
|
|
333
|
+
}
|
|
334
|
+
function acrossSwapRefunds(r, at) {
|
|
335
|
+
const target = r.word(at);
|
|
336
|
+
const c = r.bytes(at, at + 32);
|
|
337
|
+
if (target === 0n) return [["the Across deposit's depositor", c.address(c.small(0)), true]];
|
|
338
|
+
if (target === 1n) {
|
|
339
|
+
const swap = c.small(0);
|
|
340
|
+
return [["the Across deposit's depositor", c.address(swap + c.small(swap + 64) + 96), true]];
|
|
341
|
+
}
|
|
342
|
+
if (target === 2n) return [["the sponsored OFT refund recipient", c.address(c.small(0) + 32), true]];
|
|
343
|
+
if (target === 3n) return [["the sponsored CCTP refund recipient", c.address(64), true]];
|
|
344
|
+
throw new Error("unknown Across Swap API target");
|
|
345
|
+
}
|
|
346
|
+
var ERC20_TRANSFER = "0xa9059cbb";
|
|
347
|
+
function ecoDelivery(r, at, e) {
|
|
348
|
+
if (kindOf(e.toToken) === "native") return "an Eco route to the native token cannot be checked here";
|
|
349
|
+
const destination = r.word(at + 32 * 3);
|
|
350
|
+
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`;
|
|
351
|
+
const route = r.bytes(at, at + 32 * 4);
|
|
352
|
+
const tuple = route.small(0);
|
|
353
|
+
const calls = tuple + route.small(tuple + 32 * 5);
|
|
354
|
+
const n = route.small(calls);
|
|
355
|
+
if (n === 0) return "the Eco route makes no calls on the destination chain";
|
|
356
|
+
if (n > 16) return `the Eco route makes ${n} calls on the destination chain, more than the 16 read here`;
|
|
357
|
+
const last = calls + 32 + route.small(calls + 32 + 32 * (n - 1));
|
|
358
|
+
const target = route.address(last);
|
|
359
|
+
const data = route.bytes(last, last + 32);
|
|
360
|
+
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";
|
|
361
|
+
const to = data.address(4);
|
|
362
|
+
const amount = data.word(36);
|
|
363
|
+
if (!same(target, e.toToken)) return `the Eco route delivers ${target}, not ${e.toToken}`;
|
|
364
|
+
if (!same(to, e.receiver)) return `the Eco route pays ${to}, not ${e.receiver}`;
|
|
365
|
+
if (amount < e.minOut) return `the Eco route delivers ${amount}, below the ${e.minOut} shown`;
|
|
366
|
+
return null;
|
|
367
|
+
}
|
|
368
|
+
function m0Delivery(r, at, e) {
|
|
369
|
+
if (kindOf(e.toToken) === "native") return "an M0 order cannot deliver the native token";
|
|
370
|
+
const tokenOut = r.address(at + 32 * 3);
|
|
371
|
+
const amountOut = r.word(at + 32 * 5);
|
|
372
|
+
if (!same(tokenOut, e.toToken)) return `the M0 order asks for ${tokenOut}, not ${e.toToken}`;
|
|
373
|
+
if (amountOut < e.minOut) return `the M0 order asks for ${amountOut}, below the ${e.minOut} shown`;
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
var FACET_DATA = {
|
|
377
|
+
AcrossV4: { refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
378
|
+
// the SpokePool depositor: an expired deposit refunds the input there
|
|
379
|
+
AcrossV4Swap: { nested: acrossSwapRefunds },
|
|
380
|
+
Centrifuge: { inline: 2, refunds: [["refundRecipient", 1]], zeroRefused: true },
|
|
381
|
+
Chainflip: { nested: chainflipRefunds },
|
|
382
|
+
Eco: { refunds: [["refundRecipient", 6]], zeroRefused: true, delivery: ecoDelivery },
|
|
383
|
+
// the intent's creator, refunded its reward (the input) on expiry
|
|
384
|
+
Frax: { inline: 5, refunds: [["refundRecipient", 3]], zeroRefused: true },
|
|
385
|
+
Glacis: { inline: 4, refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
386
|
+
LayerSwap: { refunds: [["refundRecipient", 2]], zeroRefused: true },
|
|
387
|
+
LiFiIntentEscrowV2: { refunds: [["depositAndRefundAddress", 2]], zeroRefused: true },
|
|
388
|
+
// the escrow order's user
|
|
389
|
+
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true, delivery: m0Delivery },
|
|
390
|
+
// orderOwner gets a cancelled order back
|
|
391
|
+
Mayan: { refunds: [["refundRecipient", 7]], nested: mayanRefunds, zeroRefused: true },
|
|
392
|
+
NEARIntents: { refunds: [["refundRecipient", 6]], zeroRefused: true },
|
|
393
|
+
// also the 1Click quote's refundTo
|
|
394
|
+
PolymerCCTP: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
395
|
+
Stargate: { refunds: [["refundAddress", 4]] },
|
|
396
|
+
// (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund
|
|
397
|
+
Superset: { refunds: [["refundAddress", 2], ["fallbackEoA", 3]], zeroRefused: true }
|
|
398
|
+
};
|
|
399
|
+
var NO_REFUND_FIELDS = /* @__PURE__ */ new Set(["Across", "AllBridge", "ArbitrumBridge", "CelerCircleBridge", "GasZip", "GnosisBridge", "MegaETHBridge", "OmniBridge", "OptimismBridge", "PolygonBridge", "Unit"]);
|
|
400
|
+
function facetDataAt(r, bridge, spec) {
|
|
401
|
+
const slot = 4 + (bridge.sourceSwaps ? 64 : 32);
|
|
402
|
+
return spec.inline ? slot : 4 + r.small(slot);
|
|
403
|
+
}
|
|
404
|
+
function refundMismatch(r, bridge, e) {
|
|
405
|
+
const spec = FACET_DATA[bridge.facet];
|
|
406
|
+
if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;
|
|
407
|
+
const at = facetDataAt(r, bridge, spec);
|
|
408
|
+
const paid = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);
|
|
409
|
+
paid.push(...spec.nested?.(r, at) ?? []);
|
|
410
|
+
for (const [what, to, zeroRefused] of paid) {
|
|
411
|
+
if (zeroRefused && /^0x0{40}$/.test(to)) continue;
|
|
412
|
+
if (!same(to, e.sender) && !same(to, e.receiver)) return `${what} pays ${to}, neither the sender ${e.sender} nor the recipient`;
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
292
416
|
function diamondCallMismatch(data, e) {
|
|
293
417
|
let r;
|
|
294
418
|
try {
|
|
@@ -313,6 +437,8 @@ function diamondCallMismatch(data, e) {
|
|
|
313
437
|
}
|
|
314
438
|
return checkSteps(steps, e, e.toToken);
|
|
315
439
|
}
|
|
440
|
+
const unbound = UNBOUND_BRIDGES[selector];
|
|
441
|
+
if (unbound) return `${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`;
|
|
316
442
|
const bridge = BRIDGE_CALLS[selector];
|
|
317
443
|
if (!bridge) return `unknown Diamond call ${selector}`;
|
|
318
444
|
const head = r.small(4);
|
|
@@ -331,6 +457,11 @@ function diamondCallMismatch(data, e) {
|
|
|
331
457
|
if (!e.evmDestination) return "the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here";
|
|
332
458
|
if (!same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;
|
|
333
459
|
if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;
|
|
460
|
+
const refund = refundMismatch(r, bridge, e);
|
|
461
|
+
if (refund) return refund;
|
|
462
|
+
const spec = FACET_DATA[bridge.facet];
|
|
463
|
+
const delivery = spec?.delivery?.(r, facetDataAt(r, bridge, spec), e);
|
|
464
|
+
if (delivery) return delivery;
|
|
334
465
|
if (hasSourceSwaps) {
|
|
335
466
|
if (minAmount === 0n) return "bridges nothing after the source swaps";
|
|
336
467
|
return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);
|
|
@@ -342,8 +473,98 @@ function diamondCallMismatch(data, e) {
|
|
|
342
473
|
}
|
|
343
474
|
}
|
|
344
475
|
|
|
345
|
-
// src/
|
|
476
|
+
// src/solana.ts
|
|
346
477
|
var import_util2 = require("@anywalletkit/protocol-swap2-core/util");
|
|
478
|
+
var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
479
|
+
var MAYAN_ENTRY_PROGRAMS = /* @__PURE__ */ new Set([
|
|
480
|
+
"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa",
|
|
481
|
+
// CPI_PROXY_PROGRAM_ID
|
|
482
|
+
"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY",
|
|
483
|
+
// SWIFT_PROGRAM_ID
|
|
484
|
+
"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny",
|
|
485
|
+
// SWIFT_V2_PROGRAM_ID
|
|
486
|
+
"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU",
|
|
487
|
+
// MCTP_PROGRAM_ID
|
|
488
|
+
"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5"
|
|
489
|
+
// FAST_MCTP_PROGRAM_ID
|
|
490
|
+
]);
|
|
491
|
+
var SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
492
|
+
var LIFI_SOLANA_FEE_WALLET = "34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm";
|
|
493
|
+
function base58(bytes) {
|
|
494
|
+
let n = 0n;
|
|
495
|
+
for (const b of bytes) n = n << 8n | BigInt(b);
|
|
496
|
+
let out = "";
|
|
497
|
+
while (n > 0n) {
|
|
498
|
+
out = ALPHABET[Number(n % 58n)] + out;
|
|
499
|
+
n /= 58n;
|
|
500
|
+
}
|
|
501
|
+
for (const b of bytes) {
|
|
502
|
+
if (b !== 0) break;
|
|
503
|
+
out = `1${out}`;
|
|
504
|
+
}
|
|
505
|
+
return out;
|
|
506
|
+
}
|
|
507
|
+
var Cursor = class {
|
|
508
|
+
constructor(b) {
|
|
509
|
+
this.b = b;
|
|
510
|
+
}
|
|
511
|
+
b;
|
|
512
|
+
at = 0;
|
|
513
|
+
byte() {
|
|
514
|
+
if (this.at >= this.b.length) throw new Error("truncated");
|
|
515
|
+
return this.b[this.at++];
|
|
516
|
+
}
|
|
517
|
+
bytes(n) {
|
|
518
|
+
if (n < 0 || this.at + n > this.b.length) throw new Error("truncated");
|
|
519
|
+
const out = this.b.subarray(this.at, this.at + n);
|
|
520
|
+
this.at += n;
|
|
521
|
+
return out;
|
|
522
|
+
}
|
|
523
|
+
/** compact-u16 */
|
|
524
|
+
short() {
|
|
525
|
+
let v = 0;
|
|
526
|
+
for (let shift = 0; shift < 21; shift += 7) {
|
|
527
|
+
const b = this.byte();
|
|
528
|
+
v |= (b & 127) << shift;
|
|
529
|
+
if (!(b & 128)) return v;
|
|
530
|
+
}
|
|
531
|
+
throw new Error("bad length");
|
|
532
|
+
}
|
|
533
|
+
};
|
|
534
|
+
function solanaBridgeTxMismatch(base64, sender) {
|
|
535
|
+
const bytes = (0, import_util2.base64Bytes)(base64);
|
|
536
|
+
if (!bytes) return "the Solana transaction is not base64";
|
|
537
|
+
const c = new Cursor(bytes);
|
|
538
|
+
try {
|
|
539
|
+
c.bytes(64 * c.short());
|
|
540
|
+
const first = c.byte();
|
|
541
|
+
if ((first & 128) === 0) c.at--;
|
|
542
|
+
c.bytes(3);
|
|
543
|
+
const keys = Array.from({ length: c.short() }, () => base58(c.bytes(32)));
|
|
544
|
+
if (keys[0] !== sender) return `the Solana transaction is paid by ${keys[0] ?? "nobody"}, not the sender ${sender}`;
|
|
545
|
+
c.bytes(32);
|
|
546
|
+
let mayan = false;
|
|
547
|
+
const payees = [];
|
|
548
|
+
const n = c.short();
|
|
549
|
+
for (let i = 0; i < n; i++) {
|
|
550
|
+
const program = keys[c.byte()];
|
|
551
|
+
const accounts = Array.from(c.bytes(c.short()));
|
|
552
|
+
const data = c.bytes(c.short());
|
|
553
|
+
if (program !== void 0 && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;
|
|
554
|
+
if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {
|
|
555
|
+
const to = keys[accounts[1] ?? -1];
|
|
556
|
+
if (to !== void 0 && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return mayan && payees.length ? `the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet` : null;
|
|
560
|
+
} catch (err) {
|
|
561
|
+
return `the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/provider.ts
|
|
566
|
+
var import_util3 = require("@anywalletkit/protocol-swap2-core/util");
|
|
567
|
+
var import_validate = require("@anywalletkit/protocol-swap2-core/validate");
|
|
347
568
|
var import_core = require("@anywalletkit/core");
|
|
348
569
|
var DEFAULT_LIFI_BASE = "https://li.quest/v1";
|
|
349
570
|
var LIFI_CHAIN = {
|
|
@@ -469,7 +690,7 @@ function trustMap(input, label) {
|
|
|
469
690
|
}
|
|
470
691
|
function lifiToken(params) {
|
|
471
692
|
const sourceChain = params.sourceChain;
|
|
472
|
-
const asset = (0,
|
|
693
|
+
const asset = (0, import_util3.sourceAssetOf)(params);
|
|
473
694
|
if (!asset) return null;
|
|
474
695
|
if (asset.contract) return asset.contract;
|
|
475
696
|
return isSolana(sourceChain) ? SOLANA_NATIVE : EVM_ZERO;
|
|
@@ -480,7 +701,8 @@ function headers(key) {
|
|
|
480
701
|
return h;
|
|
481
702
|
}
|
|
482
703
|
var TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;
|
|
483
|
-
|
|
704
|
+
var UNBOUND_TOOLS = Object.freeze(["relaydepository", "garden", "squid", "symbiosis"]);
|
|
705
|
+
function routeOptions(body, excluded) {
|
|
484
706
|
const routes = body?.routes;
|
|
485
707
|
if (!Array.isArray(routes)) return [];
|
|
486
708
|
const out = [];
|
|
@@ -490,7 +712,7 @@ function routeOptions(body) {
|
|
|
490
712
|
const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === "cross")?.tool : void 0;
|
|
491
713
|
const tool = typeof cross === "string" ? cross : step.tool;
|
|
492
714
|
const eta = step.estimate?.executionDuration;
|
|
493
|
-
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
715
|
+
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || excluded.includes(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
494
716
|
if (typeof r.toAmount !== "string" || typeof r.toAmountMin !== "string" || !/^\d{1,60}$/.test(r.toAmount) || !/^\d{1,60}$/.test(r.toAmountMin)) continue;
|
|
495
717
|
out.push({
|
|
496
718
|
tool,
|
|
@@ -554,6 +776,9 @@ function lifiProvider(config = {}) {
|
|
|
554
776
|
const fromToken = lifiToken(params);
|
|
555
777
|
if (!fromToken) return null;
|
|
556
778
|
const solanaSource = isSolana(params.sourceChain);
|
|
779
|
+
const crossChain = params.sourceChain !== params.destChain;
|
|
780
|
+
const noDestinationCall = crossChain && !solanaSource;
|
|
781
|
+
let routeScope = config.routeWideSlippage === true && !solanaSource && !isSolana(params.destChain);
|
|
557
782
|
const dry = params.dry !== false;
|
|
558
783
|
const fromAddress = params.refundAddress || (dry ? solanaSource ? SOLANA_PLACEHOLDER : EVM_PLACEHOLDER : "");
|
|
559
784
|
const toAddress = params.destAddress || (dry ? fromAddress : "");
|
|
@@ -563,7 +788,7 @@ function lifiProvider(config = {}) {
|
|
|
563
788
|
let sentSlippage = slippageBps / 1e4;
|
|
564
789
|
let deadline;
|
|
565
790
|
let choice = null;
|
|
566
|
-
if (config.chooseRoute &&
|
|
791
|
+
if (config.chooseRoute && crossChain) {
|
|
567
792
|
try {
|
|
568
793
|
const res = await fetch(`${apiBase}/advanced/routes`, {
|
|
569
794
|
method: "POST",
|
|
@@ -576,12 +801,18 @@ function lifiProvider(config = {}) {
|
|
|
576
801
|
fromAmount: params.amountIn,
|
|
577
802
|
fromAddress,
|
|
578
803
|
toAddress,
|
|
579
|
-
options: {
|
|
804
|
+
options: {
|
|
805
|
+
slippage: slippageBps / 1e4,
|
|
806
|
+
...routeScope ? { slippageScope: "route" } : {},
|
|
807
|
+
...solanaSource ? {} : { bridges: { deny: UNBOUND_TOOLS } },
|
|
808
|
+
...noDestinationCall ? { allowDestinationCall: false } : {},
|
|
809
|
+
...integrator().trim() ? { integrator: integrator().trim() } : {}
|
|
810
|
+
}
|
|
580
811
|
}),
|
|
581
|
-
signal: signal ?? (0,
|
|
812
|
+
signal: signal ?? (0, import_util3.timeoutSignal)(8e3)
|
|
582
813
|
});
|
|
583
814
|
if (res.ok) {
|
|
584
|
-
const options = routeOptions(await res.json());
|
|
815
|
+
const options = routeOptions(await res.json(), solanaSource ? [] : UNBOUND_TOOLS);
|
|
585
816
|
if (options.length) choice = cleanChoice(config.chooseRoute(options, params));
|
|
586
817
|
}
|
|
587
818
|
} catch {
|
|
@@ -601,10 +832,13 @@ function lifiProvider(config = {}) {
|
|
|
601
832
|
if (sentSlippage !== void 0) {
|
|
602
833
|
url.searchParams.set("slippage", String(sentSlippage));
|
|
603
834
|
}
|
|
604
|
-
|
|
605
|
-
|
|
835
|
+
if (routeScope) url.searchParams.set("slippageScope", "route");
|
|
836
|
+
if (noDestinationCall) url.searchParams.set("allowDestinationCall", "false");
|
|
837
|
+
const unbound = crossChain && !solanaSource ? UNBOUND_TOOLS : [];
|
|
838
|
+
for (const t of (choice?.allowBridges ?? []).filter((b) => solanaSource || !UNBOUND_TOOLS.includes(b))) url.searchParams.append("allowBridges", t);
|
|
839
|
+
for (const t of /* @__PURE__ */ new Set([...choice?.denyBridges ?? [], ...unbound])) url.searchParams.append("denyBridges", t);
|
|
606
840
|
if (choice?.order) url.searchParams.set("order", choice.order);
|
|
607
|
-
deadline = signal ? void 0 : (0,
|
|
841
|
+
deadline = signal ? void 0 : (0, import_util3.timeoutSignal)(12e3);
|
|
608
842
|
const res = await fetch(url, { headers: headers(apiKey()), signal: signal ?? deadline });
|
|
609
843
|
if (!res.ok && choice) {
|
|
610
844
|
choice = null;
|
|
@@ -614,6 +848,11 @@ function lifiProvider(config = {}) {
|
|
|
614
848
|
if (!res.ok) {
|
|
615
849
|
const body = await res.json().catch(() => null);
|
|
616
850
|
const reasons = [...new Set((body?.errors?.filteredOut ?? []).map((f) => f.reason).filter((r) => typeof r === "string"))];
|
|
851
|
+
if (routeScope && [typeof body?.message === "string" ? body.message : "", ...reasons].some((r) => /^ROUTE_SLIPPAGE_(UNSUPPORTED|UNAVAILABLE)/.test(r))) {
|
|
852
|
+
routeScope = false;
|
|
853
|
+
attempt--;
|
|
854
|
+
continue;
|
|
855
|
+
}
|
|
617
856
|
const why = reasons.length === 1 ? ` (${reasons[0].slice(0, 200)})` : "";
|
|
618
857
|
params.onRefusal?.(`lifi: ${typeof body?.message === "string" ? body.message.slice(0, 200) : `HTTP ${res.status}`}${why}`);
|
|
619
858
|
return null;
|
|
@@ -646,6 +885,10 @@ function lifiProvider(config = {}) {
|
|
|
646
885
|
if (solanaSource) {
|
|
647
886
|
if (!tr.data || tr.data.length < 64 || tr.data.length % 4 !== 0 || !BASE64.test(tr.data)) return reject("the Solana transaction is not base64");
|
|
648
887
|
if (tr.to !== void 0 || tr.value !== void 0 || tr.gasLimit !== void 0) return reject("the Solana transaction carries EVM fields");
|
|
888
|
+
if (fromChain !== toChain) {
|
|
889
|
+
const why = solanaBridgeTxMismatch(tr.data, fromAddress);
|
|
890
|
+
if (why) return reject(why);
|
|
891
|
+
}
|
|
649
892
|
} 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");
|
|
650
893
|
if (sentSlippage !== void 0 && (typeof action.slippage !== "number" || Math.abs(action.slippage - sentSlippage) > 1e-12)) return reject("the quote ignored the requested slippage");
|
|
651
894
|
const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;
|
|
@@ -683,7 +926,7 @@ function lifiProvider(config = {}) {
|
|
|
683
926
|
if (sentSlippage !== void 0) {
|
|
684
927
|
const dest = BigInt(est.toAmount);
|
|
685
928
|
const min = BigInt(minDestAmount);
|
|
686
|
-
if (dest > 0n && min <
|
|
929
|
+
if (dest > 0n && min < (0, import_validate.slippageFloor)(dest, slippageBps)) {
|
|
687
930
|
const effective = (0, import_core.bigintToNumber)((dest - min) * 1000000n / dest) / 1e6;
|
|
688
931
|
const requested = slippageBps / 1e4;
|
|
689
932
|
const scaled = Math.floor(sentSlippage * requested / effective * 0.995 * 1e6) / 1e6;
|
|
@@ -712,6 +955,7 @@ function lifiProvider(config = {}) {
|
|
|
712
955
|
toToken: expectedToToken,
|
|
713
956
|
amountIn: BigInt(params.amountIn),
|
|
714
957
|
receiver: toAddress,
|
|
958
|
+
sender: fromAddress,
|
|
715
959
|
minOut: BigInt(minDestAmount),
|
|
716
960
|
destChainId: BigInt(toChain),
|
|
717
961
|
sameChain: fromChain === toChain,
|
|
@@ -730,6 +974,7 @@ function lifiProvider(config = {}) {
|
|
|
730
974
|
sourceAmount: params.amountIn,
|
|
731
975
|
destAmount: est.toAmount,
|
|
732
976
|
minDestAmount,
|
|
977
|
+
...Number.isInteger(action.toToken?.decimals) && action.toToken.decimals >= 0 && action.toToken.decimals <= 36 ? { destDecimals: action.toToken.decimals } : {},
|
|
733
978
|
feeUsd,
|
|
734
979
|
etaSeconds: est.executionDuration ?? 120,
|
|
735
980
|
reliability: 0.97,
|
|
@@ -766,7 +1011,7 @@ function lifiProvider(config = {}) {
|
|
|
766
1011
|
url.searchParams.set("txHash", ref.sourceTxHash);
|
|
767
1012
|
if (fromChain) url.searchParams.set("fromChain", fromChain);
|
|
768
1013
|
if (toChain) url.searchParams.set("toChain", toChain);
|
|
769
|
-
const res = await fetch(url, { headers: headers(apiKey()), signal: (0,
|
|
1014
|
+
const res = await fetch(url, { headers: headers(apiKey()), signal: (0, import_util3.timeoutSignal)(12e3) });
|
|
770
1015
|
if (!res.ok) return { state: "pending" };
|
|
771
1016
|
const s = await res.json();
|
|
772
1017
|
const map = {
|
|
@@ -797,7 +1042,10 @@ function lifiVerifyQuote(params, quote) {
|
|
|
797
1042
|
if (!fromChain || !toChain) return "not a LI.FI chain pair";
|
|
798
1043
|
const tx = quote.txRequest;
|
|
799
1044
|
if (!tx) return "the quote carries no transaction";
|
|
800
|
-
if (isSolana(params.sourceChain))
|
|
1045
|
+
if (isSolana(params.sourceChain)) {
|
|
1046
|
+
if (!tx.serializedTx || tx.data !== void 0 || tx.to !== void 0) return "a Solana source carries a serialized transaction only";
|
|
1047
|
+
return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : ""));
|
|
1048
|
+
}
|
|
801
1049
|
if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== void 0) return "the quote carries no Diamond call";
|
|
802
1050
|
if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return `the call targets ${tx.to}, not the LI.FI Diamond`;
|
|
803
1051
|
if (tx.chainId !== void 0 && String(tx.chainId) !== fromChain) return `the call is for chain ${tx.chainId}, not ${fromChain}`;
|
|
@@ -832,6 +1080,7 @@ function lifiVerifyQuote(params, quote) {
|
|
|
832
1080
|
toToken: nativeFor(params.destChain, params.destToken),
|
|
833
1081
|
amountIn,
|
|
834
1082
|
receiver: toAddress,
|
|
1083
|
+
sender: fromAddress,
|
|
835
1084
|
minOut,
|
|
836
1085
|
destChainId: BigInt(toChain),
|
|
837
1086
|
sameChain: fromChain === toChain,
|