@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/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
|
-
// startBridgeTokensViaDeBridgeDln (DeBridgeDlnFacet)
|
|
138
|
-
"0x2c7d2db0": { sourceSwaps: true },
|
|
139
|
-
// swapAndStartBridgeTokensViaDeBridgeDln (DeBridgeDlnFacet)
|
|
140
|
-
"0xbff90b61": { sourceSwaps: false },
|
|
136
|
+
"0xbff90b61": { sourceSwaps: false, facet: "Eco" },
|
|
141
137
|
// startBridgeTokensViaEco (EcoFacet)
|
|
142
|
-
"0x762aea18": { sourceSwaps: true },
|
|
138
|
+
"0x762aea18": { sourceSwaps: true, facet: "Eco" },
|
|
143
139
|
// swapAndStartBridgeTokensViaEco (EcoFacet)
|
|
144
|
-
"0x678786ea": { sourceSwaps: false },
|
|
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,79 @@ 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 FACET_DATA = {
|
|
354
|
+
AcrossV4: { refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
355
|
+
// the SpokePool depositor: an expired deposit refunds the input there
|
|
356
|
+
AcrossV4Swap: { nested: acrossSwapRefunds },
|
|
357
|
+
Centrifuge: { inline: 2, refunds: [["refundRecipient", 1]], zeroRefused: true },
|
|
358
|
+
Chainflip: { nested: chainflipRefunds },
|
|
359
|
+
Eco: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
360
|
+
// the intent's creator, refunded its reward (the input) on expiry
|
|
361
|
+
Frax: { inline: 5, refunds: [["refundRecipient", 3]], zeroRefused: true },
|
|
362
|
+
Glacis: { inline: 4, refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
363
|
+
LayerSwap: { refunds: [["refundRecipient", 2]], zeroRefused: true },
|
|
364
|
+
LiFiIntentEscrowV2: { refunds: [["depositAndRefundAddress", 2]], zeroRefused: true },
|
|
365
|
+
// the escrow order's user
|
|
366
|
+
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true },
|
|
367
|
+
// orderOwner gets a cancelled order back
|
|
368
|
+
Mayan: { refunds: [["refundRecipient", 7]], nested: mayanRefunds, zeroRefused: true },
|
|
369
|
+
NEARIntents: { refunds: [["refundRecipient", 6]], zeroRefused: true },
|
|
370
|
+
// also the 1Click quote's refundTo
|
|
371
|
+
PolymerCCTP: { refunds: [["refundRecipient", 5]], zeroRefused: true },
|
|
372
|
+
Stargate: { refunds: [["refundAddress", 4]] },
|
|
373
|
+
// (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund
|
|
374
|
+
Superset: { refunds: [["refundAddress", 2], ["fallbackEoA", 3]], zeroRefused: true }
|
|
375
|
+
};
|
|
376
|
+
var NO_REFUND_FIELDS = /* @__PURE__ */ new Set(["Across", "AllBridge", "ArbitrumBridge", "CelerCircleBridge", "GasZip", "GnosisBridge", "MegaETHBridge", "OmniBridge", "OptimismBridge", "PolygonBridge", "Unit"]);
|
|
377
|
+
function refundMismatch(r, bridge, e) {
|
|
378
|
+
const spec = FACET_DATA[bridge.facet];
|
|
379
|
+
if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;
|
|
380
|
+
const slot = 4 + (bridge.sourceSwaps ? 64 : 32);
|
|
381
|
+
const at = spec.inline ? slot : 4 + r.small(slot);
|
|
382
|
+
const paid = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);
|
|
383
|
+
paid.push(...spec.nested?.(r, at) ?? []);
|
|
384
|
+
for (const [what, to, zeroRefused] of paid) {
|
|
385
|
+
if (zeroRefused && /^0x0{40}$/.test(to)) continue;
|
|
386
|
+
if (!same(to, e.sender) && !same(to, e.receiver)) return `${what} pays ${to}, neither the sender ${e.sender} nor the recipient`;
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
299
390
|
function diamondCallMismatch(data, e) {
|
|
300
391
|
let r;
|
|
301
392
|
try {
|
|
@@ -320,6 +411,8 @@ function diamondCallMismatch(data, e) {
|
|
|
320
411
|
}
|
|
321
412
|
return checkSteps(steps, e, e.toToken);
|
|
322
413
|
}
|
|
414
|
+
const unbound = UNBOUND_BRIDGES[selector];
|
|
415
|
+
if (unbound) return `${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`;
|
|
323
416
|
const bridge = BRIDGE_CALLS[selector];
|
|
324
417
|
if (!bridge) return `unknown Diamond call ${selector}`;
|
|
325
418
|
const head = r.small(4);
|
|
@@ -338,6 +431,8 @@ function diamondCallMismatch(data, e) {
|
|
|
338
431
|
if (!e.evmDestination) return "the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here";
|
|
339
432
|
if (!same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;
|
|
340
433
|
if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;
|
|
434
|
+
const refund = refundMismatch(r, bridge, e);
|
|
435
|
+
if (refund) return refund;
|
|
341
436
|
if (hasSourceSwaps) {
|
|
342
437
|
if (minAmount === 0n) return "bridges nothing after the source swaps";
|
|
343
438
|
return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);
|
|
@@ -349,8 +444,98 @@ function diamondCallMismatch(data, e) {
|
|
|
349
444
|
}
|
|
350
445
|
}
|
|
351
446
|
|
|
352
|
-
// src/
|
|
447
|
+
// src/solana.ts
|
|
353
448
|
var import_util2 = require("@anywalletkit/protocol-swap2-core/util");
|
|
449
|
+
var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
450
|
+
var MAYAN_ENTRY_PROGRAMS = /* @__PURE__ */ new Set([
|
|
451
|
+
"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa",
|
|
452
|
+
// CPI_PROXY_PROGRAM_ID
|
|
453
|
+
"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY",
|
|
454
|
+
// SWIFT_PROGRAM_ID
|
|
455
|
+
"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny",
|
|
456
|
+
// SWIFT_V2_PROGRAM_ID
|
|
457
|
+
"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU",
|
|
458
|
+
// MCTP_PROGRAM_ID
|
|
459
|
+
"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5"
|
|
460
|
+
// FAST_MCTP_PROGRAM_ID
|
|
461
|
+
]);
|
|
462
|
+
var SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
463
|
+
var LIFI_SOLANA_FEE_WALLET = "34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm";
|
|
464
|
+
function base58(bytes) {
|
|
465
|
+
let n = 0n;
|
|
466
|
+
for (const b of bytes) n = n << 8n | BigInt(b);
|
|
467
|
+
let out = "";
|
|
468
|
+
while (n > 0n) {
|
|
469
|
+
out = ALPHABET[Number(n % 58n)] + out;
|
|
470
|
+
n /= 58n;
|
|
471
|
+
}
|
|
472
|
+
for (const b of bytes) {
|
|
473
|
+
if (b !== 0) break;
|
|
474
|
+
out = `1${out}`;
|
|
475
|
+
}
|
|
476
|
+
return out;
|
|
477
|
+
}
|
|
478
|
+
var Cursor = class {
|
|
479
|
+
constructor(b) {
|
|
480
|
+
this.b = b;
|
|
481
|
+
}
|
|
482
|
+
b;
|
|
483
|
+
at = 0;
|
|
484
|
+
byte() {
|
|
485
|
+
if (this.at >= this.b.length) throw new Error("truncated");
|
|
486
|
+
return this.b[this.at++];
|
|
487
|
+
}
|
|
488
|
+
bytes(n) {
|
|
489
|
+
if (n < 0 || this.at + n > this.b.length) throw new Error("truncated");
|
|
490
|
+
const out = this.b.subarray(this.at, this.at + n);
|
|
491
|
+
this.at += n;
|
|
492
|
+
return out;
|
|
493
|
+
}
|
|
494
|
+
/** compact-u16 */
|
|
495
|
+
short() {
|
|
496
|
+
let v = 0;
|
|
497
|
+
for (let shift = 0; shift < 21; shift += 7) {
|
|
498
|
+
const b = this.byte();
|
|
499
|
+
v |= (b & 127) << shift;
|
|
500
|
+
if (!(b & 128)) return v;
|
|
501
|
+
}
|
|
502
|
+
throw new Error("bad length");
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
function solanaBridgeTxMismatch(base64, sender) {
|
|
506
|
+
const bytes = (0, import_util2.base64Bytes)(base64);
|
|
507
|
+
if (!bytes) return "the Solana transaction is not base64";
|
|
508
|
+
const c = new Cursor(bytes);
|
|
509
|
+
try {
|
|
510
|
+
c.bytes(64 * c.short());
|
|
511
|
+
const first = c.byte();
|
|
512
|
+
if ((first & 128) === 0) c.at--;
|
|
513
|
+
c.bytes(3);
|
|
514
|
+
const keys = Array.from({ length: c.short() }, () => base58(c.bytes(32)));
|
|
515
|
+
if (keys[0] !== sender) return `the Solana transaction is paid by ${keys[0] ?? "nobody"}, not the sender ${sender}`;
|
|
516
|
+
c.bytes(32);
|
|
517
|
+
let mayan = false;
|
|
518
|
+
const payees = [];
|
|
519
|
+
const n = c.short();
|
|
520
|
+
for (let i = 0; i < n; i++) {
|
|
521
|
+
const program = keys[c.byte()];
|
|
522
|
+
const accounts = Array.from(c.bytes(c.short()));
|
|
523
|
+
const data = c.bytes(c.short());
|
|
524
|
+
if (program !== void 0 && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;
|
|
525
|
+
if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {
|
|
526
|
+
const to = keys[accounts[1] ?? -1];
|
|
527
|
+
if (to !== void 0 && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return mayan && payees.length ? `the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet` : null;
|
|
531
|
+
} catch (err) {
|
|
532
|
+
return `the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// src/provider.ts
|
|
537
|
+
var import_util3 = require("@anywalletkit/protocol-swap2-core/util");
|
|
538
|
+
var import_validate = require("@anywalletkit/protocol-swap2-core/validate");
|
|
354
539
|
var import_core = require("@anywalletkit/core");
|
|
355
540
|
var DEFAULT_LIFI_BASE = "https://li.quest/v1";
|
|
356
541
|
var LIFI_CHAIN = {
|
|
@@ -476,7 +661,7 @@ function trustMap(input, label) {
|
|
|
476
661
|
}
|
|
477
662
|
function lifiToken(params) {
|
|
478
663
|
const sourceChain = params.sourceChain;
|
|
479
|
-
const asset = (0,
|
|
664
|
+
const asset = (0, import_util3.sourceAssetOf)(params);
|
|
480
665
|
if (!asset) return null;
|
|
481
666
|
if (asset.contract) return asset.contract;
|
|
482
667
|
return isSolana(sourceChain) ? SOLANA_NATIVE : EVM_ZERO;
|
|
@@ -487,7 +672,8 @@ function headers(key) {
|
|
|
487
672
|
return h;
|
|
488
673
|
}
|
|
489
674
|
var TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;
|
|
490
|
-
|
|
675
|
+
var UNBOUND_TOOLS = Object.freeze(["relaydepository", "garden", "squid", "symbiosis"]);
|
|
676
|
+
function routeOptions(body, excluded) {
|
|
491
677
|
const routes = body?.routes;
|
|
492
678
|
if (!Array.isArray(routes)) return [];
|
|
493
679
|
const out = [];
|
|
@@ -497,7 +683,7 @@ function routeOptions(body) {
|
|
|
497
683
|
const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === "cross")?.tool : void 0;
|
|
498
684
|
const tool = typeof cross === "string" ? cross : step.tool;
|
|
499
685
|
const eta = step.estimate?.executionDuration;
|
|
500
|
-
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
686
|
+
if (typeof tool !== "string" || !TOOL_KEY.test(tool) || excluded.includes(tool) || typeof eta !== "number" || !Number.isFinite(eta) || eta < 0) continue;
|
|
501
687
|
if (typeof r.toAmount !== "string" || typeof r.toAmountMin !== "string" || !/^\d{1,60}$/.test(r.toAmount) || !/^\d{1,60}$/.test(r.toAmountMin)) continue;
|
|
502
688
|
out.push({
|
|
503
689
|
tool,
|
|
@@ -583,12 +769,12 @@ function lifiProvider(config = {}) {
|
|
|
583
769
|
fromAmount: params.amountIn,
|
|
584
770
|
fromAddress,
|
|
585
771
|
toAddress,
|
|
586
|
-
options: { slippage: slippageBps / 1e4, ...integrator().trim() ? { integrator: integrator().trim() } : {} }
|
|
772
|
+
options: { slippage: slippageBps / 1e4, ...solanaSource ? {} : { bridges: { deny: UNBOUND_TOOLS } }, ...integrator().trim() ? { integrator: integrator().trim() } : {} }
|
|
587
773
|
}),
|
|
588
|
-
signal: signal ?? (0,
|
|
774
|
+
signal: signal ?? (0, import_util3.timeoutSignal)(8e3)
|
|
589
775
|
});
|
|
590
776
|
if (res.ok) {
|
|
591
|
-
const options = routeOptions(await res.json());
|
|
777
|
+
const options = routeOptions(await res.json(), solanaSource ? [] : UNBOUND_TOOLS);
|
|
592
778
|
if (options.length) choice = cleanChoice(config.chooseRoute(options, params));
|
|
593
779
|
}
|
|
594
780
|
} catch {
|
|
@@ -608,10 +794,11 @@ function lifiProvider(config = {}) {
|
|
|
608
794
|
if (sentSlippage !== void 0) {
|
|
609
795
|
url.searchParams.set("slippage", String(sentSlippage));
|
|
610
796
|
}
|
|
611
|
-
|
|
612
|
-
for (const t of choice?.
|
|
797
|
+
const unbound = params.sourceChain !== params.destChain && !solanaSource ? UNBOUND_TOOLS : [];
|
|
798
|
+
for (const t of (choice?.allowBridges ?? []).filter((b) => solanaSource || !UNBOUND_TOOLS.includes(b))) url.searchParams.append("allowBridges", t);
|
|
799
|
+
for (const t of /* @__PURE__ */ new Set([...choice?.denyBridges ?? [], ...unbound])) url.searchParams.append("denyBridges", t);
|
|
613
800
|
if (choice?.order) url.searchParams.set("order", choice.order);
|
|
614
|
-
deadline = signal ? void 0 : (0,
|
|
801
|
+
deadline = signal ? void 0 : (0, import_util3.timeoutSignal)(12e3);
|
|
615
802
|
const res = await fetch(url, { headers: headers(apiKey()), signal: signal ?? deadline });
|
|
616
803
|
if (!res.ok && choice) {
|
|
617
804
|
choice = null;
|
|
@@ -653,6 +840,10 @@ function lifiProvider(config = {}) {
|
|
|
653
840
|
if (solanaSource) {
|
|
654
841
|
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
842
|
if (tr.to !== void 0 || tr.value !== void 0 || tr.gasLimit !== void 0) return reject("the Solana transaction carries EVM fields");
|
|
843
|
+
if (fromChain !== toChain) {
|
|
844
|
+
const why = solanaBridgeTxMismatch(tr.data, fromAddress);
|
|
845
|
+
if (why) return reject(why);
|
|
846
|
+
}
|
|
656
847
|
} 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
848
|
if (sentSlippage !== void 0 && (typeof action.slippage !== "number" || Math.abs(action.slippage - sentSlippage) > 1e-12)) return reject("the quote ignored the requested slippage");
|
|
658
849
|
const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;
|
|
@@ -690,7 +881,7 @@ function lifiProvider(config = {}) {
|
|
|
690
881
|
if (sentSlippage !== void 0) {
|
|
691
882
|
const dest = BigInt(est.toAmount);
|
|
692
883
|
const min = BigInt(minDestAmount);
|
|
693
|
-
if (dest > 0n && min <
|
|
884
|
+
if (dest > 0n && min < (0, import_validate.slippageFloor)(dest, slippageBps)) {
|
|
694
885
|
const effective = (0, import_core.bigintToNumber)((dest - min) * 1000000n / dest) / 1e6;
|
|
695
886
|
const requested = slippageBps / 1e4;
|
|
696
887
|
const scaled = Math.floor(sentSlippage * requested / effective * 0.995 * 1e6) / 1e6;
|
|
@@ -719,6 +910,7 @@ function lifiProvider(config = {}) {
|
|
|
719
910
|
toToken: expectedToToken,
|
|
720
911
|
amountIn: BigInt(params.amountIn),
|
|
721
912
|
receiver: toAddress,
|
|
913
|
+
sender: fromAddress,
|
|
722
914
|
minOut: BigInt(minDestAmount),
|
|
723
915
|
destChainId: BigInt(toChain),
|
|
724
916
|
sameChain: fromChain === toChain,
|
|
@@ -737,6 +929,7 @@ function lifiProvider(config = {}) {
|
|
|
737
929
|
sourceAmount: params.amountIn,
|
|
738
930
|
destAmount: est.toAmount,
|
|
739
931
|
minDestAmount,
|
|
932
|
+
...Number.isInteger(action.toToken?.decimals) && action.toToken.decimals >= 0 && action.toToken.decimals <= 36 ? { destDecimals: action.toToken.decimals } : {},
|
|
740
933
|
feeUsd,
|
|
741
934
|
etaSeconds: est.executionDuration ?? 120,
|
|
742
935
|
reliability: 0.97,
|
|
@@ -773,7 +966,7 @@ function lifiProvider(config = {}) {
|
|
|
773
966
|
url.searchParams.set("txHash", ref.sourceTxHash);
|
|
774
967
|
if (fromChain) url.searchParams.set("fromChain", fromChain);
|
|
775
968
|
if (toChain) url.searchParams.set("toChain", toChain);
|
|
776
|
-
const res = await fetch(url, { headers: headers(apiKey()), signal: (0,
|
|
969
|
+
const res = await fetch(url, { headers: headers(apiKey()), signal: (0, import_util3.timeoutSignal)(12e3) });
|
|
777
970
|
if (!res.ok) return { state: "pending" };
|
|
778
971
|
const s = await res.json();
|
|
779
972
|
const map = {
|
|
@@ -804,7 +997,10 @@ function lifiVerifyQuote(params, quote) {
|
|
|
804
997
|
if (!fromChain || !toChain) return "not a LI.FI chain pair";
|
|
805
998
|
const tx = quote.txRequest;
|
|
806
999
|
if (!tx) return "the quote carries no transaction";
|
|
807
|
-
if (isSolana(params.sourceChain))
|
|
1000
|
+
if (isSolana(params.sourceChain)) {
|
|
1001
|
+
if (!tx.serializedTx || tx.data !== void 0 || tx.to !== void 0) return "a Solana source carries a serialized transaction only";
|
|
1002
|
+
return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : ""));
|
|
1003
|
+
}
|
|
808
1004
|
if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== void 0) return "the quote carries no Diamond call";
|
|
809
1005
|
if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return `the call targets ${tx.to}, not the LI.FI Diamond`;
|
|
810
1006
|
if (tx.chainId !== void 0 && String(tx.chainId) !== fromChain) return `the call is for chain ${tx.chainId}, not ${fromChain}`;
|
|
@@ -839,6 +1035,7 @@ function lifiVerifyQuote(params, quote) {
|
|
|
839
1035
|
toToken: nativeFor(params.destChain, params.destToken),
|
|
840
1036
|
amountIn,
|
|
841
1037
|
receiver: toAddress,
|
|
1038
|
+
sender: fromAddress,
|
|
842
1039
|
minOut,
|
|
843
1040
|
destChainId: BigInt(toChain),
|
|
844
1041
|
sameChain: fromChain === toChain,
|