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