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