@anywalletkit/protocol-swap2-lifi 0.5.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 +19 -4
- package/dist/{chunk-67QPKWAY.js → chunk-IZ7TP4KT.js} +64 -12
- package/dist/chunk-IZ7TP4KT.js.map +1 -0
- package/dist/{chunk-V56FCCBC.js → chunk-YABKNR7N.js} +2 -2
- package/dist/index.cjs +63 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/protocol.cjs +63 -11
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +2 -2
- package/dist/provider.cjs +63 -11
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +9 -0
- package/dist/provider.d.ts +9 -0
- package/dist/provider.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-67QPKWAY.js.map +0 -1
- /package/dist/{chunk-V56FCCBC.js.map → chunk-YABKNR7N.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -133,10 +133,10 @@ var BRIDGE_CALLS = {
|
|
|
133
133
|
// startBridgeTokensViaChainflip (ChainflipFacet)
|
|
134
134
|
"0xee3314a1": { sourceSwaps: true, facet: "Chainflip" },
|
|
135
135
|
// swapAndStartBridgeTokensViaChainflip (ChainflipFacet)
|
|
136
|
-
"
|
|
137
|
-
// startBridgeTokensViaEco (EcoFacet)
|
|
138
|
-
"
|
|
139
|
-
// swapAndStartBridgeTokensViaEco (EcoFacet)
|
|
136
|
+
"0x05c54990": { sourceSwaps: false, facet: "Eco" },
|
|
137
|
+
// startBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
138
|
+
"0x8352664c": { sourceSwaps: true, facet: "Eco" },
|
|
139
|
+
// swapAndStartBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)
|
|
140
140
|
"0x678786ea": { sourceSwaps: false, facet: "Frax" },
|
|
141
141
|
// startBridgeTokensViaFrax (FraxFacet)
|
|
142
142
|
"0x07b8e4c7": { sourceSwaps: true, facet: "Frax" },
|
|
@@ -350,20 +350,50 @@ function acrossSwapRefunds(r, at) {
|
|
|
350
350
|
if (target === 3n) return [["the sponsored CCTP refund recipient", c.address(64), true]];
|
|
351
351
|
throw new Error("unknown Across Swap API target");
|
|
352
352
|
}
|
|
353
|
+
var ERC20_TRANSFER = "0xa9059cbb";
|
|
354
|
+
function ecoDelivery(r, at, e) {
|
|
355
|
+
if (kindOf(e.toToken) === "native") return "an Eco route to the native token cannot be checked here";
|
|
356
|
+
const destination = r.word(at + 32 * 3);
|
|
357
|
+
if (destination !== e.destChainId) return `the Eco intent executes on chain ${destination}, not the destination ${e.destChainId} \u2014 a route whose delivery cannot be checked here`;
|
|
358
|
+
const route = r.bytes(at, at + 32 * 4);
|
|
359
|
+
const tuple = route.small(0);
|
|
360
|
+
const calls = tuple + route.small(tuple + 32 * 5);
|
|
361
|
+
const n = route.small(calls);
|
|
362
|
+
if (n === 0) return "the Eco route makes no calls on the destination chain";
|
|
363
|
+
if (n > 16) return `the Eco route makes ${n} calls on the destination chain, more than the 16 read here`;
|
|
364
|
+
const last = calls + 32 + route.small(calls + 32 + 32 * (n - 1));
|
|
365
|
+
const target = route.address(last);
|
|
366
|
+
const data = route.bytes(last, last + 32);
|
|
367
|
+
if (route.word(last + 64) !== 0n || data.length !== 68 || data.raw(0, 4) !== ERC20_TRANSFER) return "the Eco route does not end in a token transfer";
|
|
368
|
+
const to = data.address(4);
|
|
369
|
+
const amount = data.word(36);
|
|
370
|
+
if (!same(target, e.toToken)) return `the Eco route delivers ${target}, not ${e.toToken}`;
|
|
371
|
+
if (!same(to, e.receiver)) return `the Eco route pays ${to}, not ${e.receiver}`;
|
|
372
|
+
if (amount < e.minOut) return `the Eco route delivers ${amount}, below the ${e.minOut} shown`;
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
function m0Delivery(r, at, e) {
|
|
376
|
+
if (kindOf(e.toToken) === "native") return "an M0 order cannot deliver the native token";
|
|
377
|
+
const tokenOut = r.address(at + 32 * 3);
|
|
378
|
+
const amountOut = r.word(at + 32 * 5);
|
|
379
|
+
if (!same(tokenOut, e.toToken)) return `the M0 order asks for ${tokenOut}, not ${e.toToken}`;
|
|
380
|
+
if (amountOut < e.minOut) return `the M0 order asks for ${amountOut}, below the ${e.minOut} shown`;
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
353
383
|
var FACET_DATA = {
|
|
354
384
|
AcrossV4: { refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
355
385
|
// the SpokePool depositor: an expired deposit refunds the input there
|
|
356
386
|
AcrossV4Swap: { nested: acrossSwapRefunds },
|
|
357
387
|
Centrifuge: { inline: 2, refunds: [["refundRecipient", 1]], zeroRefused: true },
|
|
358
388
|
Chainflip: { nested: chainflipRefunds },
|
|
359
|
-
Eco: { refunds: [["refundRecipient",
|
|
389
|
+
Eco: { refunds: [["refundRecipient", 6]], zeroRefused: true, delivery: ecoDelivery },
|
|
360
390
|
// the intent's creator, refunded its reward (the input) on expiry
|
|
361
391
|
Frax: { inline: 5, refunds: [["refundRecipient", 3]], zeroRefused: true },
|
|
362
392
|
Glacis: { inline: 4, refunds: [["refundAddress", 1]], zeroRefused: true },
|
|
363
393
|
LayerSwap: { refunds: [["refundRecipient", 2]], zeroRefused: true },
|
|
364
394
|
LiFiIntentEscrowV2: { refunds: [["depositAndRefundAddress", 2]], zeroRefused: true },
|
|
365
395
|
// the escrow order's user
|
|
366
|
-
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true },
|
|
396
|
+
M0: { inline: 7, refunds: [["refundRecipient", 1], ["orderOwner", 2]], zeroRefused: true, delivery: m0Delivery },
|
|
367
397
|
// orderOwner gets a cancelled order back
|
|
368
398
|
Mayan: { refunds: [["refundRecipient", 7]], nested: mayanRefunds, zeroRefused: true },
|
|
369
399
|
NEARIntents: { refunds: [["refundRecipient", 6]], zeroRefused: true },
|
|
@@ -374,11 +404,14 @@ var FACET_DATA = {
|
|
|
374
404
|
Superset: { refunds: [["refundAddress", 2], ["fallbackEoA", 3]], zeroRefused: true }
|
|
375
405
|
};
|
|
376
406
|
var NO_REFUND_FIELDS = /* @__PURE__ */ new Set(["Across", "AllBridge", "ArbitrumBridge", "CelerCircleBridge", "GasZip", "GnosisBridge", "MegaETHBridge", "OmniBridge", "OptimismBridge", "PolygonBridge", "Unit"]);
|
|
407
|
+
function facetDataAt(r, bridge, spec) {
|
|
408
|
+
const slot = 4 + (bridge.sourceSwaps ? 64 : 32);
|
|
409
|
+
return spec.inline ? slot : 4 + r.small(slot);
|
|
410
|
+
}
|
|
377
411
|
function refundMismatch(r, bridge, e) {
|
|
378
412
|
const spec = FACET_DATA[bridge.facet];
|
|
379
413
|
if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;
|
|
380
|
-
const
|
|
381
|
-
const at = spec.inline ? slot : 4 + r.small(slot);
|
|
414
|
+
const at = facetDataAt(r, bridge, spec);
|
|
382
415
|
const paid = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);
|
|
383
416
|
paid.push(...spec.nested?.(r, at) ?? []);
|
|
384
417
|
for (const [what, to, zeroRefused] of paid) {
|
|
@@ -433,6 +466,9 @@ function diamondCallMismatch(data, e) {
|
|
|
433
466
|
if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;
|
|
434
467
|
const refund = refundMismatch(r, bridge, e);
|
|
435
468
|
if (refund) return refund;
|
|
469
|
+
const spec = FACET_DATA[bridge.facet];
|
|
470
|
+
const delivery = spec?.delivery?.(r, facetDataAt(r, bridge, spec), e);
|
|
471
|
+
if (delivery) return delivery;
|
|
436
472
|
if (hasSourceSwaps) {
|
|
437
473
|
if (minAmount === 0n) return "bridges nothing after the source swaps";
|
|
438
474
|
return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);
|
|
@@ -747,6 +783,9 @@ function lifiProvider(config = {}) {
|
|
|
747
783
|
const fromToken = lifiToken(params);
|
|
748
784
|
if (!fromToken) return null;
|
|
749
785
|
const solanaSource = isSolana(params.sourceChain);
|
|
786
|
+
const crossChain = params.sourceChain !== params.destChain;
|
|
787
|
+
const noDestinationCall = crossChain && !solanaSource;
|
|
788
|
+
let routeScope = config.routeWideSlippage === true && !solanaSource && !isSolana(params.destChain);
|
|
750
789
|
const dry = params.dry !== false;
|
|
751
790
|
const fromAddress = params.refundAddress || (dry ? solanaSource ? SOLANA_PLACEHOLDER : EVM_PLACEHOLDER : "");
|
|
752
791
|
const toAddress = params.destAddress || (dry ? fromAddress : "");
|
|
@@ -756,7 +795,7 @@ function lifiProvider(config = {}) {
|
|
|
756
795
|
let sentSlippage = slippageBps / 1e4;
|
|
757
796
|
let deadline;
|
|
758
797
|
let choice = null;
|
|
759
|
-
if (config.chooseRoute &&
|
|
798
|
+
if (config.chooseRoute && crossChain) {
|
|
760
799
|
try {
|
|
761
800
|
const res = await fetch(`${apiBase}/advanced/routes`, {
|
|
762
801
|
method: "POST",
|
|
@@ -769,7 +808,13 @@ function lifiProvider(config = {}) {
|
|
|
769
808
|
fromAmount: params.amountIn,
|
|
770
809
|
fromAddress,
|
|
771
810
|
toAddress,
|
|
772
|
-
options: {
|
|
811
|
+
options: {
|
|
812
|
+
slippage: slippageBps / 1e4,
|
|
813
|
+
...routeScope ? { slippageScope: "route" } : {},
|
|
814
|
+
...solanaSource ? {} : { bridges: { deny: UNBOUND_TOOLS } },
|
|
815
|
+
...noDestinationCall ? { allowDestinationCall: false } : {},
|
|
816
|
+
...integrator().trim() ? { integrator: integrator().trim() } : {}
|
|
817
|
+
}
|
|
773
818
|
}),
|
|
774
819
|
signal: signal ?? (0, import_util3.timeoutSignal)(8e3)
|
|
775
820
|
});
|
|
@@ -794,7 +839,9 @@ function lifiProvider(config = {}) {
|
|
|
794
839
|
if (sentSlippage !== void 0) {
|
|
795
840
|
url.searchParams.set("slippage", String(sentSlippage));
|
|
796
841
|
}
|
|
797
|
-
|
|
842
|
+
if (routeScope) url.searchParams.set("slippageScope", "route");
|
|
843
|
+
if (noDestinationCall) url.searchParams.set("allowDestinationCall", "false");
|
|
844
|
+
const unbound = crossChain && !solanaSource ? UNBOUND_TOOLS : [];
|
|
798
845
|
for (const t of (choice?.allowBridges ?? []).filter((b) => solanaSource || !UNBOUND_TOOLS.includes(b))) url.searchParams.append("allowBridges", t);
|
|
799
846
|
for (const t of /* @__PURE__ */ new Set([...choice?.denyBridges ?? [], ...unbound])) url.searchParams.append("denyBridges", t);
|
|
800
847
|
if (choice?.order) url.searchParams.set("order", choice.order);
|
|
@@ -808,6 +855,11 @@ function lifiProvider(config = {}) {
|
|
|
808
855
|
if (!res.ok) {
|
|
809
856
|
const body = await res.json().catch(() => null);
|
|
810
857
|
const reasons = [...new Set((body?.errors?.filteredOut ?? []).map((f) => f.reason).filter((r) => typeof r === "string"))];
|
|
858
|
+
if (routeScope && [typeof body?.message === "string" ? body.message : "", ...reasons].some((r) => /^ROUTE_SLIPPAGE_(UNSUPPORTED|UNAVAILABLE)/.test(r))) {
|
|
859
|
+
routeScope = false;
|
|
860
|
+
attempt--;
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
811
863
|
const why = reasons.length === 1 ? ` (${reasons[0].slice(0, 200)})` : "";
|
|
812
864
|
params.onRefusal?.(`lifi: ${typeof body?.message === "string" ? body.message.slice(0, 200) : `HTTP ${res.status}`}${why}`);
|
|
813
865
|
return null;
|