@anywalletkit/protocol-swap2-lifi 0.4.0 → 0.5.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 +8 -4
- package/dist/{chunk-TQYG23FS.js → chunk-67QPKWAY.js} +286 -89
- package/dist/chunk-67QPKWAY.js.map +1 -0
- package/dist/{chunk-7SUAXOPF.js → chunk-V56FCCBC.js} +2 -2
- package/dist/index.cjs +290 -93
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/protocol.cjs +290 -93
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +2 -2
- package/dist/provider.cjs +290 -93
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +2 -1
- package/dist/provider.d.ts +2 -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-V56FCCBC.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
|
-
// startBridgeTokensViaDeBridgeDln (DeBridgeDlnFacet)
|
|
131
|
-
"0x2c7d2db0": { sourceSwaps: true },
|
|
132
|
-
// swapAndStartBridgeTokensViaDeBridgeDln (DeBridgeDlnFacet)
|
|
133
|
-
"0xbff90b61": { sourceSwaps: false },
|
|
129
|
+
"0xbff90b61": { sourceSwaps: false, facet: "Eco" },
|
|
134
130
|
// startBridgeTokensViaEco (EcoFacet)
|
|
135
|
-
"0x762aea18": { sourceSwaps: true },
|
|
131
|
+
"0x762aea18": { sourceSwaps: true, facet: "Eco" },
|
|
136
132
|
// swapAndStartBridgeTokensViaEco (EcoFacet)
|
|
137
|
-
"0x678786ea": { sourceSwaps: false },
|
|
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,79 @@ 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 FACET_DATA = {
|
|
347
|
+
AcrossV4: { refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
348
|
+
// the SpokePool depositor: an expired deposit refunds the input there
|
|
349
|
+
AcrossV4Swap: { nested: acrossSwapRefunds },
|
|
350
|
+
Centrifuge: { inline: 2, refunds: [["refundRecipient", 1]], zeroRefused: true },
|
|
351
|
+
Chainflip: { nested: chainflipRefunds },
|
|
352
|
+
Eco: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
353
|
+
// the intent's creator, refunded its reward (the input) on expiry
|
|
354
|
+
Frax: { inline: 5, refunds: [["refundRecipient", 3]], zeroRefused: true },
|
|
355
|
+
Glacis: { inline: 4, refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
356
|
+
LayerSwap: { refunds: [["refundRecipient", 2]], zeroRefused: true },
|
|
357
|
+
LiFiIntentEscrowV2: { refunds: [["depositAndRefundAddress", 2]], zeroRefused: true },
|
|
358
|
+
// the escrow order's user
|
|
359
|
+
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true },
|
|
360
|
+
// orderOwner gets a cancelled order back
|
|
361
|
+
Mayan: { refunds: [["refundRecipient", 7]], nested: mayanRefunds, zeroRefused: true },
|
|
362
|
+
NEARIntents: { refunds: [["refundRecipient", 6]], zeroRefused: true },
|
|
363
|
+
// also the 1Click quote's refundTo
|
|
364
|
+
PolymerCCTP: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
365
|
+
Stargate: { refunds: [["refundAddress", 4]] },
|
|
366
|
+
// (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund
|
|
367
|
+
Superset: { refunds: [["refundAddress", 2], ["fallbackEoA", 3]], zeroRefused: true }
|
|
368
|
+
};
|
|
369
|
+
var NO_REFUND_FIELDS = /* @__PURE__ */ new Set(["Across", "AllBridge", "ArbitrumBridge", "CelerCircleBridge", "GasZip", "GnosisBridge", "MegaETHBridge", "OmniBridge", "OptimismBridge", "PolygonBridge", "Unit"]);
|
|
370
|
+
function refundMismatch(r, bridge, e) {
|
|
371
|
+
const spec = FACET_DATA[bridge.facet];
|
|
372
|
+
if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;
|
|
373
|
+
const slot = 4 + (bridge.sourceSwaps ? 64 : 32);
|
|
374
|
+
const at = spec.inline ? slot : 4 + r.small(slot);
|
|
375
|
+
const paid = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);
|
|
376
|
+
paid.push(...spec.nested?.(r, at) ?? []);
|
|
377
|
+
for (const [what, to, zeroRefused] of paid) {
|
|
378
|
+
if (zeroRefused && /^0x0{40}$/.test(to)) continue;
|
|
379
|
+
if (!same(to, e.sender) && !same(to, e.receiver)) return `${what} pays ${to}, neither the sender ${e.sender} nor the recipient`;
|
|
380
|
+
}
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
292
383
|
function diamondCallMismatch(data, e) {
|
|
293
384
|
let r;
|
|
294
385
|
try {
|
|
@@ -313,6 +404,8 @@ function diamondCallMismatch(data, e) {
|
|
|
313
404
|
}
|
|
314
405
|
return checkSteps(steps, e, e.toToken);
|
|
315
406
|
}
|
|
407
|
+
const unbound = UNBOUND_BRIDGES[selector];
|
|
408
|
+
if (unbound) return `${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`;
|
|
316
409
|
const bridge = BRIDGE_CALLS[selector];
|
|
317
410
|
if (!bridge) return `unknown Diamond call ${selector}`;
|
|
318
411
|
const head = r.small(4);
|
|
@@ -331,6 +424,8 @@ function diamondCallMismatch(data, e) {
|
|
|
331
424
|
if (!e.evmDestination) return "the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here";
|
|
332
425
|
if (!same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;
|
|
333
426
|
if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;
|
|
427
|
+
const refund = refundMismatch(r, bridge, e);
|
|
428
|
+
if (refund) return refund;
|
|
334
429
|
if (hasSourceSwaps) {
|
|
335
430
|
if (minAmount === 0n) return "bridges nothing after the source swaps";
|
|
336
431
|
return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);
|
|
@@ -342,8 +437,98 @@ function diamondCallMismatch(data, e) {
|
|
|
342
437
|
}
|
|
343
438
|
}
|
|
344
439
|
|
|
345
|
-
// src/
|
|
440
|
+
// src/solana.ts
|
|
346
441
|
var import_util2 = require("@anywalletkit/protocol-swap2-core/util");
|
|
442
|
+
var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
443
|
+
var MAYAN_ENTRY_PROGRAMS = /* @__PURE__ */ new Set([
|
|
444
|
+
"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa",
|
|
445
|
+
// CPI_PROXY_PROGRAM_ID
|
|
446
|
+
"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY",
|
|
447
|
+
// SWIFT_PROGRAM_ID
|
|
448
|
+
"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny",
|
|
449
|
+
// SWIFT_V2_PROGRAM_ID
|
|
450
|
+
"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU",
|
|
451
|
+
// MCTP_PROGRAM_ID
|
|
452
|
+
"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5"
|
|
453
|
+
// FAST_MCTP_PROGRAM_ID
|
|
454
|
+
]);
|
|
455
|
+
var SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
456
|
+
var LIFI_SOLANA_FEE_WALLET = "34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm";
|
|
457
|
+
function base58(bytes) {
|
|
458
|
+
let n = 0n;
|
|
459
|
+
for (const b of bytes) n = n << 8n | BigInt(b);
|
|
460
|
+
let out = "";
|
|
461
|
+
while (n > 0n) {
|
|
462
|
+
out = ALPHABET[Number(n % 58n)] + out;
|
|
463
|
+
n /= 58n;
|
|
464
|
+
}
|
|
465
|
+
for (const b of bytes) {
|
|
466
|
+
if (b !== 0) break;
|
|
467
|
+
out = `1${out}`;
|
|
468
|
+
}
|
|
469
|
+
return out;
|
|
470
|
+
}
|
|
471
|
+
var Cursor = class {
|
|
472
|
+
constructor(b) {
|
|
473
|
+
this.b = b;
|
|
474
|
+
}
|
|
475
|
+
b;
|
|
476
|
+
at = 0;
|
|
477
|
+
byte() {
|
|
478
|
+
if (this.at >= this.b.length) throw new Error("truncated");
|
|
479
|
+
return this.b[this.at++];
|
|
480
|
+
}
|
|
481
|
+
bytes(n) {
|
|
482
|
+
if (n < 0 || this.at + n > this.b.length) throw new Error("truncated");
|
|
483
|
+
const out = this.b.subarray(this.at, this.at + n);
|
|
484
|
+
this.at += n;
|
|
485
|
+
return out;
|
|
486
|
+
}
|
|
487
|
+
/** compact-u16 */
|
|
488
|
+
short() {
|
|
489
|
+
let v = 0;
|
|
490
|
+
for (let shift = 0; shift < 21; shift += 7) {
|
|
491
|
+
const b = this.byte();
|
|
492
|
+
v |= (b & 127) << shift;
|
|
493
|
+
if (!(b & 128)) return v;
|
|
494
|
+
}
|
|
495
|
+
throw new Error("bad length");
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
function solanaBridgeTxMismatch(base64, sender) {
|
|
499
|
+
const bytes = (0, import_util2.base64Bytes)(base64);
|
|
500
|
+
if (!bytes) return "the Solana transaction is not base64";
|
|
501
|
+
const c = new Cursor(bytes);
|
|
502
|
+
try {
|
|
503
|
+
c.bytes(64 * c.short());
|
|
504
|
+
const first = c.byte();
|
|
505
|
+
if ((first & 128) === 0) c.at--;
|
|
506
|
+
c.bytes(3);
|
|
507
|
+
const keys = Array.from({ length: c.short() }, () => base58(c.bytes(32)));
|
|
508
|
+
if (keys[0] !== sender) return `the Solana transaction is paid by ${keys[0] ?? "nobody"}, not the sender ${sender}`;
|
|
509
|
+
c.bytes(32);
|
|
510
|
+
let mayan = false;
|
|
511
|
+
const payees = [];
|
|
512
|
+
const n = c.short();
|
|
513
|
+
for (let i = 0; i < n; i++) {
|
|
514
|
+
const program = keys[c.byte()];
|
|
515
|
+
const accounts = Array.from(c.bytes(c.short()));
|
|
516
|
+
const data = c.bytes(c.short());
|
|
517
|
+
if (program !== void 0 && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;
|
|
518
|
+
if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {
|
|
519
|
+
const to = keys[accounts[1] ?? -1];
|
|
520
|
+
if (to !== void 0 && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return mayan && payees.length ? `the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet` : null;
|
|
524
|
+
} catch (err) {
|
|
525
|
+
return `the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// src/provider.ts
|
|
530
|
+
var import_util3 = require("@anywalletkit/protocol-swap2-core/util");
|
|
531
|
+
var import_validate = require("@anywalletkit/protocol-swap2-core/validate");
|
|
347
532
|
var import_core = require("@anywalletkit/core");
|
|
348
533
|
var DEFAULT_LIFI_BASE = "https://li.quest/v1";
|
|
349
534
|
var LIFI_CHAIN = {
|
|
@@ -469,7 +654,7 @@ function trustMap(input, label) {
|
|
|
469
654
|
}
|
|
470
655
|
function lifiToken(params) {
|
|
471
656
|
const sourceChain = params.sourceChain;
|
|
472
|
-
const asset = (0,
|
|
657
|
+
const asset = (0, import_util3.sourceAssetOf)(params);
|
|
473
658
|
if (!asset) return null;
|
|
474
659
|
if (asset.contract) return asset.contract;
|
|
475
660
|
return isSolana(sourceChain) ? SOLANA_NATIVE : EVM_ZERO;
|
|
@@ -480,7 +665,8 @@ function headers(key) {
|
|
|
480
665
|
return h;
|
|
481
666
|
}
|
|
482
667
|
var TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;
|
|
483
|
-
|
|
668
|
+
var UNBOUND_TOOLS = Object.freeze(["relaydepository", "garden", "squid", "symbiosis"]);
|
|
669
|
+
function routeOptions(body, excluded) {
|
|
484
670
|
const routes = body?.routes;
|
|
485
671
|
if (!Array.isArray(routes)) return [];
|
|
486
672
|
const out = [];
|
|
@@ -490,7 +676,7 @@ function routeOptions(body) {
|
|
|
490
676
|
const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === "cross")?.tool : void 0;
|
|
491
677
|
const tool = typeof cross === "string" ? cross : step.tool;
|
|
492
678
|
const eta = step.estimate?.executionDuration;
|
|
493
|
-
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
679
|
+
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || excluded.includes(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
494
680
|
if (typeof r.toAmount !== "string" || typeof r.toAmountMin !== "string" || !/^\d{1,60}$/.test(r.toAmount) || !/^\d{1,60}$/.test(r.toAmountMin)) continue;
|
|
495
681
|
out.push({
|
|
496
682
|
tool,
|
|
@@ -576,12 +762,12 @@ function lifiProvider(config = {}) {
|
|
|
576
762
|
fromAmount: params.amountIn,
|
|
577
763
|
fromAddress,
|
|
578
764
|
toAddress,
|
|
579
|
-
options: { slippage: slippageBps / 1e4, ...integrator().trim() ? { integrator: integrator().trim() } : {} }
|
|
765
|
+
options: { slippage: slippageBps / 1e4, ...solanaSource ? {} : { bridges: { deny: UNBOUND_TOOLS } }, ...integrator().trim() ? { integrator: integrator().trim() } : {} }
|
|
580
766
|
}),
|
|
581
|
-
signal: signal ?? (0,
|
|
767
|
+
signal: signal ?? (0, import_util3.timeoutSignal)(8e3)
|
|
582
768
|
});
|
|
583
769
|
if (res.ok) {
|
|
584
|
-
const options = routeOptions(await res.json());
|
|
770
|
+
const options = routeOptions(await res.json(), solanaSource ? [] : UNBOUND_TOOLS);
|
|
585
771
|
if (options.length) choice = cleanChoice(config.chooseRoute(options, params));
|
|
586
772
|
}
|
|
587
773
|
} catch {
|
|
@@ -601,10 +787,11 @@ function lifiProvider(config = {}) {
|
|
|
601
787
|
if (sentSlippage !== void 0) {
|
|
602
788
|
url.searchParams.set("slippage", String(sentSlippage));
|
|
603
789
|
}
|
|
604
|
-
|
|
605
|
-
for (const t of choice?.
|
|
790
|
+
const unbound = params.sourceChain !== params.destChain && !solanaSource ? UNBOUND_TOOLS : [];
|
|
791
|
+
for (const t of (choice?.allowBridges ?? []).filter((b) => solanaSource || !UNBOUND_TOOLS.includes(b))) url.searchParams.append("allowBridges", t);
|
|
792
|
+
for (const t of /* @__PURE__ */ new Set([...choice?.denyBridges ?? [], ...unbound])) url.searchParams.append("denyBridges", t);
|
|
606
793
|
if (choice?.order) url.searchParams.set("order", choice.order);
|
|
607
|
-
deadline = signal ? void 0 : (0,
|
|
794
|
+
deadline = signal ? void 0 : (0, import_util3.timeoutSignal)(12e3);
|
|
608
795
|
const res = await fetch(url, { headers: headers(apiKey()), signal: signal ?? deadline });
|
|
609
796
|
if (!res.ok && choice) {
|
|
610
797
|
choice = null;
|
|
@@ -646,6 +833,10 @@ function lifiProvider(config = {}) {
|
|
|
646
833
|
if (solanaSource) {
|
|
647
834
|
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
835
|
if (tr.to !== void 0 || tr.value !== void 0 || tr.gasLimit !== void 0) return reject("the Solana transaction carries EVM fields");
|
|
836
|
+
if (fromChain !== toChain) {
|
|
837
|
+
const why = solanaBridgeTxMismatch(tr.data, fromAddress);
|
|
838
|
+
if (why) return reject(why);
|
|
839
|
+
}
|
|
649
840
|
} 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
841
|
if (sentSlippage !== void 0 && (typeof action.slippage !== "number" || Math.abs(action.slippage - sentSlippage) > 1e-12)) return reject("the quote ignored the requested slippage");
|
|
651
842
|
const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;
|
|
@@ -683,7 +874,7 @@ function lifiProvider(config = {}) {
|
|
|
683
874
|
if (sentSlippage !== void 0) {
|
|
684
875
|
const dest = BigInt(est.toAmount);
|
|
685
876
|
const min = BigInt(minDestAmount);
|
|
686
|
-
if (dest > 0n && min <
|
|
877
|
+
if (dest > 0n && min < (0, import_validate.slippageFloor)(dest, slippageBps)) {
|
|
687
878
|
const effective = (0, import_core.bigintToNumber)((dest - min) * 1000000n / dest) / 1e6;
|
|
688
879
|
const requested = slippageBps / 1e4;
|
|
689
880
|
const scaled = Math.floor(sentSlippage * requested / effective * 0.995 * 1e6) / 1e6;
|
|
@@ -712,6 +903,7 @@ function lifiProvider(config = {}) {
|
|
|
712
903
|
toToken: expectedToToken,
|
|
713
904
|
amountIn: BigInt(params.amountIn),
|
|
714
905
|
receiver: toAddress,
|
|
906
|
+
sender: fromAddress,
|
|
715
907
|
minOut: BigInt(minDestAmount),
|
|
716
908
|
destChainId: BigInt(toChain),
|
|
717
909
|
sameChain: fromChain === toChain,
|
|
@@ -730,6 +922,7 @@ function lifiProvider(config = {}) {
|
|
|
730
922
|
sourceAmount: params.amountIn,
|
|
731
923
|
destAmount: est.toAmount,
|
|
732
924
|
minDestAmount,
|
|
925
|
+
...Number.isInteger(action.toToken?.decimals) && action.toToken.decimals >= 0 && action.toToken.decimals <= 36 ? { destDecimals: action.toToken.decimals } : {},
|
|
733
926
|
feeUsd,
|
|
734
927
|
etaSeconds: est.executionDuration ?? 120,
|
|
735
928
|
reliability: 0.97,
|
|
@@ -766,7 +959,7 @@ function lifiProvider(config = {}) {
|
|
|
766
959
|
url.searchParams.set("txHash", ref.sourceTxHash);
|
|
767
960
|
if (fromChain) url.searchParams.set("fromChain", fromChain);
|
|
768
961
|
if (toChain) url.searchParams.set("toChain", toChain);
|
|
769
|
-
const res = await fetch(url, { headers: headers(apiKey()), signal: (0,
|
|
962
|
+
const res = await fetch(url, { headers: headers(apiKey()), signal: (0, import_util3.timeoutSignal)(12e3) });
|
|
770
963
|
if (!res.ok) return { state: "pending" };
|
|
771
964
|
const s = await res.json();
|
|
772
965
|
const map = {
|
|
@@ -797,7 +990,10 @@ function lifiVerifyQuote(params, quote) {
|
|
|
797
990
|
if (!fromChain || !toChain) return "not a LI.FI chain pair";
|
|
798
991
|
const tx = quote.txRequest;
|
|
799
992
|
if (!tx) return "the quote carries no transaction";
|
|
800
|
-
if (isSolana(params.sourceChain))
|
|
993
|
+
if (isSolana(params.sourceChain)) {
|
|
994
|
+
if (!tx.serializedTx || tx.data !== void 0 || tx.to !== void 0) return "a Solana source carries a serialized transaction only";
|
|
995
|
+
return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : ""));
|
|
996
|
+
}
|
|
801
997
|
if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== void 0) return "the quote carries no Diamond call";
|
|
802
998
|
if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return `the call targets ${tx.to}, not the LI.FI Diamond`;
|
|
803
999
|
if (tx.chainId !== void 0 && String(tx.chainId) !== fromChain) return `the call is for chain ${tx.chainId}, not ${fromChain}`;
|
|
@@ -832,6 +1028,7 @@ function lifiVerifyQuote(params, quote) {
|
|
|
832
1028
|
toToken: nativeFor(params.destChain, params.destToken),
|
|
833
1029
|
amountIn,
|
|
834
1030
|
receiver: toAddress,
|
|
1031
|
+
sender: fromAddress,
|
|
835
1032
|
minOut,
|
|
836
1033
|
destChainId: BigInt(toChain),
|
|
837
1034
|
sameChain: fromChain === toChain,
|