@shapeshiftoss/swap-widget 0.7.0 → 0.8.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 +171 -1
- package/dist/index.css +19 -0
- package/dist/index.d.ts +16 -2
- package/dist/index.js +412 -206
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { useCallback as useCallback11, useEffect as useEffect10, useMemo as useM
|
|
|
4
4
|
|
|
5
5
|
// src/api/client.ts
|
|
6
6
|
var DEFAULT_API_BASE_URL = "https://api.shapeshift.com";
|
|
7
|
+
var getTradeAmount = (params) => params.buyAmountCryptoBaseUnit !== void 0 ? { buyAmountCryptoBaseUnit: params.buyAmountCryptoBaseUnit } : { sellAmountCryptoBaseUnit: params.sellAmountCryptoBaseUnit };
|
|
7
8
|
var createApiClient = (config = {}) => {
|
|
8
9
|
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
9
10
|
const fetchWithConfig = async (endpoint, params, method = "GET", timeoutMs = 3e4) => {
|
|
@@ -41,7 +42,7 @@ var createApiClient = (config = {}) => {
|
|
|
41
42
|
getRates: (params) => fetchWithConfig("/v1/swap/rates", {
|
|
42
43
|
sellAssetId: params.sellAssetId,
|
|
43
44
|
buyAssetId: params.buyAssetId,
|
|
44
|
-
|
|
45
|
+
...getTradeAmount(params)
|
|
45
46
|
}),
|
|
46
47
|
getSwapStatus: (params) => fetchWithConfig("/v1/swap/status", {
|
|
47
48
|
quoteId: params.quoteId,
|
|
@@ -52,7 +53,7 @@ var createApiClient = (config = {}) => {
|
|
|
52
53
|
{
|
|
53
54
|
sellAssetId: params.sellAssetId,
|
|
54
55
|
buyAssetId: params.buyAssetId,
|
|
55
|
-
|
|
56
|
+
...getTradeAmount(params),
|
|
56
57
|
sendAddress: params.sendAddress,
|
|
57
58
|
receiveAddress: params.receiveAddress,
|
|
58
59
|
swapperName: params.swapperName,
|
|
@@ -680,6 +681,7 @@ var formatAmount = (amount, decimals, maxDecimals) => {
|
|
|
680
681
|
minimumFractionDigits: 0
|
|
681
682
|
});
|
|
682
683
|
};
|
|
684
|
+
var formatAmountForInput = (amount, decimals) => BigAmount.fromBaseUnit({ value: amount, precision: decimals }).toPrecision();
|
|
683
685
|
var parseAmount = (amount, decimals) => {
|
|
684
686
|
return BigAmount.fromPrecision({ value: amount, precision: decimals }).toBaseUnit();
|
|
685
687
|
};
|
|
@@ -689,8 +691,11 @@ var truncateAddress = (address, chars = 4) => {
|
|
|
689
691
|
};
|
|
690
692
|
|
|
691
693
|
// src/machines/guards.ts
|
|
694
|
+
var isExactOutput = (context) => !!context.buyAmountBaseUnit;
|
|
692
695
|
var hasValidInput = (context) => {
|
|
693
|
-
|
|
696
|
+
if (!context.sellAsset || !context.buyAsset) return false;
|
|
697
|
+
const amountBaseUnit = isExactOutput(context) ? context.buyAmountBaseUnit : context.sellAmountBaseUnit;
|
|
698
|
+
return !!amountBaseUnit && amountBaseUnit !== "0";
|
|
694
699
|
};
|
|
695
700
|
var hasQuote = (context) => context.quote !== null;
|
|
696
701
|
var canRetry = (context) => context.retryCount < 3;
|
|
@@ -711,6 +716,8 @@ var createInitialContext = (input) => {
|
|
|
711
716
|
buyAsset,
|
|
712
717
|
sellAmount: "",
|
|
713
718
|
sellAmountBaseUnit: void 0,
|
|
719
|
+
buyAmount: input?.buyAmount ?? "",
|
|
720
|
+
buyAmountBaseUnit: input?.buyAmountBaseUnit,
|
|
714
721
|
isSellAmountFiat: false,
|
|
715
722
|
sellAmountFiat: "",
|
|
716
723
|
selectedRate: null,
|
|
@@ -773,12 +780,14 @@ var swapMachine = setup({
|
|
|
773
780
|
quote: null
|
|
774
781
|
};
|
|
775
782
|
}),
|
|
776
|
-
assignBuyAsset: assign(({ event }) => {
|
|
783
|
+
assignBuyAsset: assign(({ context, event }) => {
|
|
777
784
|
const { asset } = event;
|
|
778
785
|
const buyChainType = getChainType(asset.chainId);
|
|
779
786
|
return {
|
|
780
787
|
buyAsset: asset,
|
|
781
788
|
isBuyAssetEvm: buyChainType === "evm",
|
|
789
|
+
buyAmount: context.buyAmount,
|
|
790
|
+
buyAmountBaseUnit: context.buyAmount ? parseAmount(context.buyAmount, asset.precision) : void 0,
|
|
782
791
|
selectedRate: null,
|
|
783
792
|
quote: null
|
|
784
793
|
};
|
|
@@ -788,7 +797,11 @@ var swapMachine = setup({
|
|
|
788
797
|
return {
|
|
789
798
|
sellAmount: amount,
|
|
790
799
|
sellAmountBaseUnit: amountBaseUnit,
|
|
791
|
-
sellAmountFiat: fiatValue
|
|
800
|
+
sellAmountFiat: fiatValue,
|
|
801
|
+
buyAmount: "",
|
|
802
|
+
buyAmountBaseUnit: void 0,
|
|
803
|
+
selectedRate: null,
|
|
804
|
+
quote: null
|
|
792
805
|
};
|
|
793
806
|
}),
|
|
794
807
|
assignSellFiatMode: assign(({ event }) => {
|
|
@@ -832,6 +845,19 @@ var swapMachine = setup({
|
|
|
832
845
|
assignReceiveAddress: assign(({ event }) => ({
|
|
833
846
|
receiveAddress: event.address
|
|
834
847
|
})),
|
|
848
|
+
assignBuyAmount: assign(({ event }) => {
|
|
849
|
+
const { amount, amountBaseUnit } = event;
|
|
850
|
+
return {
|
|
851
|
+
buyAmount: amount,
|
|
852
|
+
buyAmountBaseUnit: amountBaseUnit,
|
|
853
|
+
sellAmount: "",
|
|
854
|
+
sellAmountBaseUnit: void 0,
|
|
855
|
+
sellAmountFiat: "",
|
|
856
|
+
isSellAmountFiat: false,
|
|
857
|
+
selectedRate: null,
|
|
858
|
+
quote: null
|
|
859
|
+
};
|
|
860
|
+
}),
|
|
835
861
|
assignChainInfo: assign(({ event }) => {
|
|
836
862
|
const e = event;
|
|
837
863
|
return {
|
|
@@ -859,6 +885,8 @@ var swapMachine = setup({
|
|
|
859
885
|
buyAsset: context.buyAsset,
|
|
860
886
|
sellAmount: context.sellAmount,
|
|
861
887
|
sellAmountBaseUnit: context.sellAmountBaseUnit,
|
|
888
|
+
buyAmount: context.buyAmount,
|
|
889
|
+
buyAmountBaseUnit: context.buyAmountBaseUnit,
|
|
862
890
|
slippage: context.slippage,
|
|
863
891
|
sendAddress: context.sendAddress,
|
|
864
892
|
receiveAddress: context.receiveAddress
|
|
@@ -877,6 +905,7 @@ var swapMachine = setup({
|
|
|
877
905
|
SET_SELL_ASSET: { actions: "assignSellAsset" },
|
|
878
906
|
SET_BUY_ASSET: { actions: "assignBuyAsset" },
|
|
879
907
|
SET_SELL_AMOUNT: { actions: "assignSellAmount" },
|
|
908
|
+
SET_BUY_AMOUNT: { actions: "assignBuyAmount" },
|
|
880
909
|
SET_SELL_FIAT_MODE: { actions: "assignSellFiatMode" },
|
|
881
910
|
SET_SLIPPAGE: { actions: "assignSlippage" },
|
|
882
911
|
SELECT_RATE: { actions: "assignSelectedRate" },
|
|
@@ -2237,28 +2266,55 @@ var formatUsdValue = (cryptoAmount, precision, usdPrice) => {
|
|
|
2237
2266
|
};
|
|
2238
2267
|
|
|
2239
2268
|
// src/hooks/useSwapRates.ts
|
|
2240
|
-
import { bnOrZero } from "@shapeshiftoss/utils";
|
|
2241
2269
|
import { useQuery as useQuery3 } from "@tanstack/react-query";
|
|
2270
|
+
|
|
2271
|
+
// src/utils/rateDisplay.ts
|
|
2272
|
+
import { bnOrZero } from "@shapeshiftoss/utils";
|
|
2273
|
+
var getRateAmountBaseUnit = (rate, isExactOutput2) => (isExactOutput2 ? rate.sellAmountCryptoBaseUnit : rate.buyAmountCryptoBaseUnit) ?? "0";
|
|
2274
|
+
var sortRatesByValue = (rates, isExactOutput2) => [...rates].filter((rate) => !rate.error && getRateAmountBaseUnit(rate, isExactOutput2) !== "0").sort((a, b) => {
|
|
2275
|
+
const aAmount = bnOrZero(getRateAmountBaseUnit(a, isExactOutput2));
|
|
2276
|
+
const bAmount = bnOrZero(getRateAmountBaseUnit(b, isExactOutput2));
|
|
2277
|
+
return isExactOutput2 ? aAmount.minus(bAmount).toNumber() : bAmount.minus(aAmount).toNumber();
|
|
2278
|
+
});
|
|
2279
|
+
var getRateDiffPercent = (bestAmountBaseUnit, amountBaseUnit, isExactOutput2) => {
|
|
2280
|
+
const best = bnOrZero(bestAmountBaseUnit);
|
|
2281
|
+
const current = bnOrZero(amountBaseUnit);
|
|
2282
|
+
if (best.isZero()) return null;
|
|
2283
|
+
const diff = isExactOutput2 ? current.minus(best).div(best).times(100) : best.minus(current).div(best).times(100);
|
|
2284
|
+
return diff.gte("0.01") ? diff.toFixed(2) : null;
|
|
2285
|
+
};
|
|
2286
|
+
|
|
2287
|
+
// src/hooks/useSwapRates.ts
|
|
2242
2288
|
var ENABLED_SWAPPER_NAMES = new Set(Object.values(SwapperName));
|
|
2243
2289
|
var useSwapRates = (apiClient, params) => {
|
|
2244
2290
|
const {
|
|
2245
2291
|
sellAssetId,
|
|
2246
2292
|
buyAssetId,
|
|
2247
2293
|
sellAmountCryptoBaseUnit,
|
|
2294
|
+
buyAmountCryptoBaseUnit,
|
|
2248
2295
|
enabled = true,
|
|
2249
2296
|
allowedSwapperNames,
|
|
2250
2297
|
refetchInterval = 15e3
|
|
2251
2298
|
} = params;
|
|
2299
|
+
const isExactOutput2 = buyAmountCryptoBaseUnit !== void 0;
|
|
2300
|
+
const amountCryptoBaseUnit = isExactOutput2 ? buyAmountCryptoBaseUnit : sellAmountCryptoBaseUnit;
|
|
2252
2301
|
return useQuery3({
|
|
2253
|
-
queryKey: [
|
|
2302
|
+
queryKey: [
|
|
2303
|
+
"swapRates",
|
|
2304
|
+
sellAssetId,
|
|
2305
|
+
buyAssetId,
|
|
2306
|
+
amountCryptoBaseUnit,
|
|
2307
|
+
isExactOutput2,
|
|
2308
|
+
allowedSwapperNames
|
|
2309
|
+
],
|
|
2254
2310
|
queryFn: async () => {
|
|
2255
|
-
if (!sellAssetId || !buyAssetId || !
|
|
2311
|
+
if (!sellAssetId || !buyAssetId || !amountCryptoBaseUnit) {
|
|
2256
2312
|
return [];
|
|
2257
2313
|
}
|
|
2258
2314
|
const response = await apiClient.getRates({
|
|
2259
2315
|
sellAssetId,
|
|
2260
2316
|
buyAssetId,
|
|
2261
|
-
sellAmountCryptoBaseUnit
|
|
2317
|
+
...isExactOutput2 ? { buyAmountCryptoBaseUnit: amountCryptoBaseUnit } : { sellAmountCryptoBaseUnit: amountCryptoBaseUnit }
|
|
2262
2318
|
});
|
|
2263
2319
|
let filteredRates = response.rates.filter(
|
|
2264
2320
|
(rate) => !rate.error && rate.buyAmountCryptoBaseUnit !== "0" && ENABLED_SWAPPER_NAMES.has(rate.swapperName)
|
|
@@ -2266,16 +2322,15 @@ var useSwapRates = (apiClient, params) => {
|
|
|
2266
2322
|
if (allowedSwapperNames?.length) {
|
|
2267
2323
|
filteredRates = filteredRates.filter((rate) => allowedSwapperNames.includes(rate.swapperName));
|
|
2268
2324
|
}
|
|
2269
|
-
return
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
});
|
|
2325
|
+
return sortRatesByValue(
|
|
2326
|
+
filteredRates.map((rate, index) => ({
|
|
2327
|
+
...rate,
|
|
2328
|
+
id: rate.id ?? `${rate.swapperName}-${index}`
|
|
2329
|
+
})),
|
|
2330
|
+
isExactOutput2
|
|
2331
|
+
);
|
|
2277
2332
|
},
|
|
2278
|
-
enabled: enabled && !!sellAssetId && !!buyAssetId && !!
|
|
2333
|
+
enabled: enabled && !!sellAssetId && !!buyAssetId && !!amountCryptoBaseUnit,
|
|
2279
2334
|
staleTime: 1e4,
|
|
2280
2335
|
refetchInterval
|
|
2281
2336
|
});
|
|
@@ -2287,18 +2342,23 @@ var useSwapDisplayValues = ({
|
|
|
2287
2342
|
allowedSwapperNames,
|
|
2288
2343
|
ratesRefetchInterval
|
|
2289
2344
|
}) => {
|
|
2290
|
-
const
|
|
2291
|
-
const
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2345
|
+
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
2346
|
+
const {
|
|
2347
|
+
sellAsset,
|
|
2348
|
+
buyAsset,
|
|
2349
|
+
buyAmountBaseUnit,
|
|
2350
|
+
isSellAssetEvm,
|
|
2351
|
+
isSellAssetUtxo,
|
|
2352
|
+
isSellAssetSolana,
|
|
2353
|
+
selectedRate
|
|
2354
|
+
} = context;
|
|
2355
|
+
const { receiveAddress, isReceiveAddressBlocked, evm, bitcoin: bitcoin3, solana: solana3 } = useSwapWallet();
|
|
2298
2356
|
const evmAddress = evm.address;
|
|
2299
2357
|
const bitcoinAddress = bitcoin3.address;
|
|
2300
2358
|
const solanaAddress = solana3.address;
|
|
2301
2359
|
const buyChainType = getChainType(buyAsset.chainId);
|
|
2360
|
+
const isExactOutput2 = !!buyAmountBaseUnit;
|
|
2361
|
+
const amountBaseUnit = isExactOutput2 ? buyAmountBaseUnit : context.sellAmountBaseUnit;
|
|
2302
2362
|
const {
|
|
2303
2363
|
data: rates,
|
|
2304
2364
|
isLoading: isLoadingRates,
|
|
@@ -2306,10 +2366,12 @@ var useSwapDisplayValues = ({
|
|
|
2306
2366
|
} = useSwapRates(apiClient, {
|
|
2307
2367
|
sellAssetId: sellAsset.assetId,
|
|
2308
2368
|
buyAssetId: buyAsset.assetId,
|
|
2309
|
-
sellAmountCryptoBaseUnit: sellAmountBaseUnit,
|
|
2369
|
+
sellAmountCryptoBaseUnit: context.sellAmountBaseUnit,
|
|
2370
|
+
buyAmountCryptoBaseUnit: buyAmountBaseUnit,
|
|
2310
2371
|
allowedSwapperNames,
|
|
2311
2372
|
refetchInterval: ratesRefetchInterval,
|
|
2312
|
-
|
|
2373
|
+
// Rates need no destination, but a locked one the buy chain rejects can never be quoted
|
|
2374
|
+
enabled: !!amountBaseUnit && amountBaseUnit !== "0" && !isReceiveAddressBlocked && (isSellAssetEvm || isSellAssetUtxo || isSellAssetSolana)
|
|
2313
2375
|
});
|
|
2314
2376
|
const {
|
|
2315
2377
|
data: sellAssetBalance,
|
|
@@ -2343,6 +2405,7 @@ var useSwapDisplayValues = ({
|
|
|
2343
2405
|
const { data: buyChainInfo } = useChainInfo(buyAsset.chainId);
|
|
2344
2406
|
const displayRate = useMemo5(() => selectedRate ?? rates?.[0], [selectedRate, rates]);
|
|
2345
2407
|
const buyAmount = displayRate?.buyAmountCryptoBaseUnit;
|
|
2408
|
+
const sellAmountBaseUnit = isExactOutput2 ? displayRate?.sellAmountCryptoBaseUnit : context.sellAmountBaseUnit;
|
|
2346
2409
|
const sellChainNativeAsset = useMemo5(() => getBaseAsset(sellAsset.chainId), [sellAsset.chainId]);
|
|
2347
2410
|
const assetIdsForPrices = useMemo5(() => {
|
|
2348
2411
|
const ids = [sellAsset.assetId, buyAsset.assetId];
|
|
@@ -2400,6 +2463,8 @@ var useSwapDisplayValues = ({
|
|
|
2400
2463
|
buyChainInfo,
|
|
2401
2464
|
displayRate,
|
|
2402
2465
|
buyAmount,
|
|
2466
|
+
isExactOutput: isExactOutput2,
|
|
2467
|
+
sellAmountBaseUnit,
|
|
2403
2468
|
sellChainNativeAsset,
|
|
2404
2469
|
networkFeeDisplay,
|
|
2405
2470
|
sellUsdValue,
|
|
@@ -2423,6 +2488,8 @@ var useSwapDisplayValues = ({
|
|
|
2423
2488
|
buyChainInfo,
|
|
2424
2489
|
displayRate,
|
|
2425
2490
|
buyAmount,
|
|
2491
|
+
isExactOutput2,
|
|
2492
|
+
sellAmountBaseUnit,
|
|
2426
2493
|
sellChainNativeAsset,
|
|
2427
2494
|
networkFeeDisplay,
|
|
2428
2495
|
sellUsdValue,
|
|
@@ -2553,6 +2620,10 @@ var useSwapExecution = () => {
|
|
|
2553
2620
|
});
|
|
2554
2621
|
return;
|
|
2555
2622
|
}
|
|
2623
|
+
if (Date.now() >= quote.expiresAt) {
|
|
2624
|
+
actorRef.send({ type: "EXECUTE_ERROR", error: "Quote expired \u2014 please try again" });
|
|
2625
|
+
return;
|
|
2626
|
+
}
|
|
2556
2627
|
const txData = quote.steps[0]?.transactionData;
|
|
2557
2628
|
if (!txData) {
|
|
2558
2629
|
console.error("Quote missing transactionData in steps[0]", quote);
|
|
@@ -2662,15 +2733,27 @@ var useSwapHandlers = ({
|
|
|
2662
2733
|
},
|
|
2663
2734
|
[actorRef]
|
|
2664
2735
|
);
|
|
2736
|
+
const handleBuyAmountChange = useCallback4(
|
|
2737
|
+
(value) => {
|
|
2738
|
+
const { buyAsset } = actorRef.getSnapshot().context;
|
|
2739
|
+
const amountBaseUnit = value ? parseAmount(value, buyAsset.precision) : void 0;
|
|
2740
|
+
actorRef.send({ type: "SET_BUY_AMOUNT", amount: value, amountBaseUnit });
|
|
2741
|
+
},
|
|
2742
|
+
[actorRef]
|
|
2743
|
+
);
|
|
2665
2744
|
const handleToggleSellFiat = useCallback4(
|
|
2666
2745
|
(sellAssetUsdPrice) => {
|
|
2667
2746
|
if (!sellAssetUsdPrice) return;
|
|
2668
2747
|
const snap = actorRef.getSnapshot();
|
|
2669
|
-
const { sellAmount, sellAmountBaseUnit, sellAsset, isSellAmountFiat } = snap.context;
|
|
2748
|
+
const { sellAmount, sellAmountBaseUnit, sellAsset, isSellAmountFiat, buyAmountBaseUnit } = snap.context;
|
|
2670
2749
|
if (isSellAmountFiat) {
|
|
2671
2750
|
actorRef.send({ type: "SET_SELL_FIAT_MODE", isFiat: false });
|
|
2672
2751
|
return;
|
|
2673
2752
|
}
|
|
2753
|
+
if (buyAmountBaseUnit) {
|
|
2754
|
+
actorRef.send({ type: "SET_SELL_FIAT_MODE", isFiat: true });
|
|
2755
|
+
return;
|
|
2756
|
+
}
|
|
2674
2757
|
const fiatValue = cryptoToFiat(sellAmountBaseUnit, sellAssetUsdPrice, sellAsset.precision);
|
|
2675
2758
|
actorRef.send({
|
|
2676
2759
|
type: "SET_SELL_AMOUNT",
|
|
@@ -2746,6 +2829,7 @@ var useSwapHandlers = ({
|
|
|
2746
2829
|
handleSellAssetSelect,
|
|
2747
2830
|
handleBuyAssetSelect,
|
|
2748
2831
|
handleSellAmountChange,
|
|
2832
|
+
handleBuyAmountChange,
|
|
2749
2833
|
handleToggleSellFiat,
|
|
2750
2834
|
handleSelectRate,
|
|
2751
2835
|
handleSlippageChange,
|
|
@@ -2768,9 +2852,12 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2768
2852
|
quotingRef.current = true;
|
|
2769
2853
|
const fetchQuote = async () => {
|
|
2770
2854
|
try {
|
|
2771
|
-
|
|
2855
|
+
const isExactOutput2 = !!context.buyAmountBaseUnit;
|
|
2856
|
+
const rateToUse = context.selectedRate ?? rates?.[0];
|
|
2857
|
+
const sellAmountBaseUnit = isExactOutput2 ? rateToUse?.sellAmountCryptoBaseUnit : context.sellAmountBaseUnit;
|
|
2858
|
+
if (sellAssetBalance?.balance && sellAmountBaseUnit) {
|
|
2772
2859
|
const balanceBigInt = BigInt(sellAssetBalance.balance);
|
|
2773
|
-
const amountBigInt = BigInt(
|
|
2860
|
+
const amountBigInt = BigInt(sellAmountBaseUnit);
|
|
2774
2861
|
if (amountBigInt > balanceBigInt) {
|
|
2775
2862
|
actorRef.send({ type: "QUOTE_ERROR", error: "Insufficient balance" });
|
|
2776
2863
|
return;
|
|
@@ -2782,8 +2869,8 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2782
2869
|
return;
|
|
2783
2870
|
}
|
|
2784
2871
|
const slippageDecimal = (parsedSlippage / 100).toString();
|
|
2785
|
-
const
|
|
2786
|
-
if (!rateToUse || !
|
|
2872
|
+
const amountBaseUnit = isExactOutput2 ? context.buyAmountBaseUnit : context.sellAmountBaseUnit;
|
|
2873
|
+
if (!rateToUse || !amountBaseUnit) {
|
|
2787
2874
|
actorRef.send({ type: "QUOTE_ERROR", error: "No rate or amount available" });
|
|
2788
2875
|
return;
|
|
2789
2876
|
}
|
|
@@ -2799,7 +2886,7 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2799
2886
|
const response = await apiClient.getQuote({
|
|
2800
2887
|
sellAssetId: context.sellAsset.assetId,
|
|
2801
2888
|
buyAssetId: context.buyAsset.assetId,
|
|
2802
|
-
sellAmountCryptoBaseUnit:
|
|
2889
|
+
...isExactOutput2 ? { buyAmountCryptoBaseUnit: amountBaseUnit } : { sellAmountCryptoBaseUnit: amountBaseUnit },
|
|
2803
2890
|
sendAddress,
|
|
2804
2891
|
receiveAddress: resolvedReceiveAddress,
|
|
2805
2892
|
swapperName: rateToUse.swapperName,
|
|
@@ -2956,6 +3043,19 @@ var getAddressFormatHint = (chainId) => {
|
|
|
2956
3043
|
}
|
|
2957
3044
|
};
|
|
2958
3045
|
|
|
3046
|
+
// src/utils/receiveAddress.ts
|
|
3047
|
+
var resolveReceiveAddress = ({
|
|
3048
|
+
isLocked,
|
|
3049
|
+
defaultAddress,
|
|
3050
|
+
customAddress,
|
|
3051
|
+
walletAddress,
|
|
3052
|
+
buyChainId
|
|
3053
|
+
}) => {
|
|
3054
|
+
const isValidForBuyChain = (address) => !!address && validateAddress(address, buyChainId).valid;
|
|
3055
|
+
if (isLocked) return isValidForBuyChain(defaultAddress) ? defaultAddress : void 0;
|
|
3056
|
+
return isValidForBuyChain(customAddress) ? customAddress : walletAddress;
|
|
3057
|
+
};
|
|
3058
|
+
|
|
2959
3059
|
// src/components/ApprovalStep.tsx
|
|
2960
3060
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2961
3061
|
var ApprovalStep = () => {
|
|
@@ -3117,9 +3217,8 @@ var getSwapperColor = (swapperName) => {
|
|
|
3117
3217
|
};
|
|
3118
3218
|
|
|
3119
3219
|
// src/components/QuotesModal.tsx
|
|
3120
|
-
import { bnOrZero as bnOrZero2 } from "@shapeshiftoss/utils";
|
|
3121
3220
|
import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo6 } from "react";
|
|
3122
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3221
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3123
3222
|
var useLockBodyScroll = (isLocked) => {
|
|
3124
3223
|
useEffect6(() => {
|
|
3125
3224
|
if (!isLocked) return;
|
|
@@ -3130,13 +3229,6 @@ var useLockBodyScroll = (isLocked) => {
|
|
|
3130
3229
|
};
|
|
3131
3230
|
}, [isLocked]);
|
|
3132
3231
|
};
|
|
3133
|
-
var calculateSavingsPercent = (bestAmount, currentAmount) => {
|
|
3134
|
-
const best = bnOrZero2(bestAmount);
|
|
3135
|
-
const current = bnOrZero2(currentAmount);
|
|
3136
|
-
if (best.isZero()) return null;
|
|
3137
|
-
const diff = best.minus(current).div(best).times(100);
|
|
3138
|
-
return diff.gt(0.1) ? diff.toFixed(2) : null;
|
|
3139
|
-
};
|
|
3140
3232
|
var QuotesModal = ({
|
|
3141
3233
|
isOpen,
|
|
3142
3234
|
onClose,
|
|
@@ -3146,6 +3238,9 @@ var QuotesModal = ({
|
|
|
3146
3238
|
buyAsset,
|
|
3147
3239
|
sellAsset,
|
|
3148
3240
|
sellAmountBaseUnit,
|
|
3241
|
+
buyAmountBaseUnit,
|
|
3242
|
+
isExactOutput: isExactOutput2,
|
|
3243
|
+
sellAssetUsdPrice,
|
|
3149
3244
|
buyAssetUsdPrice
|
|
3150
3245
|
}) => {
|
|
3151
3246
|
useLockBodyScroll(isOpen);
|
|
@@ -3164,15 +3259,11 @@ var QuotesModal = ({
|
|
|
3164
3259
|
},
|
|
3165
3260
|
[onSelectRate, onClose]
|
|
3166
3261
|
);
|
|
3167
|
-
const sortedRates = useMemo6(() =>
|
|
3168
|
-
return [...rates].filter((r) => !r.error && r.buyAmountCryptoBaseUnit !== "0").sort((a, b) => {
|
|
3169
|
-
const aAmount = bnOrZero2(a.buyAmountCryptoBaseUnit);
|
|
3170
|
-
const bAmount = bnOrZero2(b.buyAmountCryptoBaseUnit);
|
|
3171
|
-
return bAmount.minus(aAmount).toNumber();
|
|
3172
|
-
});
|
|
3173
|
-
}, [rates]);
|
|
3262
|
+
const sortedRates = useMemo6(() => sortRatesByValue(rates, isExactOutput2), [rates, isExactOutput2]);
|
|
3174
3263
|
const bestRate = useMemo6(() => sortedRates[0], [sortedRates]);
|
|
3175
|
-
const
|
|
3264
|
+
const bestAmountBaseUnit = bestRate ? getRateAmountBaseUnit(bestRate, isExactOutput2) : "0";
|
|
3265
|
+
const asset = isExactOutput2 ? sellAsset : buyAsset;
|
|
3266
|
+
const usdPrice = isExactOutput2 ? sellAssetUsdPrice : buyAssetUsdPrice;
|
|
3176
3267
|
if (!isOpen) return null;
|
|
3177
3268
|
return (
|
|
3178
3269
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
@@ -3189,14 +3280,20 @@ var QuotesModal = ({
|
|
|
3189
3280
|
/* @__PURE__ */ jsxs3("div", { className: "ssw-quotes-modal-header", children: [
|
|
3190
3281
|
/* @__PURE__ */ jsxs3("div", { className: "ssw-quotes-header-content", children: [
|
|
3191
3282
|
/* @__PURE__ */ jsx3("h2", { id: "quotes-modal-title", className: "ssw-quotes-modal-title", children: "Select Route" }),
|
|
3192
|
-
/* @__PURE__ */
|
|
3283
|
+
/* @__PURE__ */ jsx3("span", { className: "ssw-quotes-modal-subtitle", children: isExactOutput2 ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
3284
|
+
sellAsset.symbol,
|
|
3285
|
+
" \u2192 ",
|
|
3286
|
+
formatAmount(buyAmountBaseUnit, buyAsset.precision),
|
|
3287
|
+
" ",
|
|
3288
|
+
buyAsset.symbol
|
|
3289
|
+
] }) : /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
3193
3290
|
formatAmount(sellAmountBaseUnit, sellAsset.precision),
|
|
3194
3291
|
" ",
|
|
3195
3292
|
sellAsset.symbol,
|
|
3196
3293
|
" \u2192",
|
|
3197
3294
|
" ",
|
|
3198
3295
|
buyAsset.symbol
|
|
3199
|
-
] })
|
|
3296
|
+
] }) })
|
|
3200
3297
|
] }),
|
|
3201
3298
|
/* @__PURE__ */ jsx3("button", { className: "ssw-quotes-modal-close", onClick: onClose, type: "button", children: /* @__PURE__ */ jsx3(
|
|
3202
3299
|
"svg",
|
|
@@ -3212,15 +3309,15 @@ var QuotesModal = ({
|
|
|
3212
3309
|
) })
|
|
3213
3310
|
] }),
|
|
3214
3311
|
/* @__PURE__ */ jsx3("div", { className: "ssw-quotes-modal-list", children: sortedRates.map((rate, index) => {
|
|
3215
|
-
const
|
|
3312
|
+
const amountBaseUnit = getRateAmountBaseUnit(rate, isExactOutput2);
|
|
3216
3313
|
const estimatedTime = rate.estimatedExecutionTimeMs;
|
|
3217
3314
|
const isBest = index === 0;
|
|
3218
3315
|
const isSelected = selectedRate?.id === rate.id;
|
|
3219
3316
|
const swapperIcon = getSwapperIcon(rate.swapperName);
|
|
3220
3317
|
const swapperColor = getSwapperColor(rate.swapperName);
|
|
3221
|
-
const
|
|
3222
|
-
const usdValue = formatUsdValue(
|
|
3223
|
-
const
|
|
3318
|
+
const formattedAmount = formatAmount(amountBaseUnit, asset.precision);
|
|
3319
|
+
const usdValue = formatUsdValue(amountBaseUnit, asset.precision, usdPrice);
|
|
3320
|
+
const diffPercent = isBest ? null : getRateDiffPercent(bestAmountBaseUnit, amountBaseUnit, isExactOutput2);
|
|
3224
3321
|
const estimatedSeconds = estimatedTime ? Math.round(estimatedTime / 1e3) : 0;
|
|
3225
3322
|
const hasTime = estimatedSeconds > 0;
|
|
3226
3323
|
return /* @__PURE__ */ jsxs3(
|
|
@@ -3243,9 +3340,9 @@ var QuotesModal = ({
|
|
|
3243
3340
|
/* @__PURE__ */ jsxs3("div", { className: "ssw-quote-row-name-row", children: [
|
|
3244
3341
|
/* @__PURE__ */ jsx3("span", { className: "ssw-quote-row-name", children: rate.swapperName }),
|
|
3245
3342
|
isBest && /* @__PURE__ */ jsx3("span", { className: "ssw-quote-row-best", children: "Best" }),
|
|
3246
|
-
|
|
3247
|
-
"-",
|
|
3248
|
-
|
|
3343
|
+
diffPercent && /* @__PURE__ */ jsxs3("span", { className: "ssw-quote-row-diff", children: [
|
|
3344
|
+
isExactOutput2 ? "+" : "-",
|
|
3345
|
+
diffPercent,
|
|
3249
3346
|
"%"
|
|
3250
3347
|
] })
|
|
3251
3348
|
] }),
|
|
@@ -3258,9 +3355,9 @@ var QuotesModal = ({
|
|
|
3258
3355
|
] }),
|
|
3259
3356
|
/* @__PURE__ */ jsxs3("div", { className: "ssw-quote-row-right", children: [
|
|
3260
3357
|
/* @__PURE__ */ jsxs3("span", { className: "ssw-quote-row-amount", children: [
|
|
3261
|
-
|
|
3358
|
+
formattedAmount,
|
|
3262
3359
|
" ",
|
|
3263
|
-
/* @__PURE__ */ jsx3("span", { className: "ssw-quote-row-symbol", children:
|
|
3360
|
+
/* @__PURE__ */ jsx3("span", { className: "ssw-quote-row-symbol", children: asset.symbol })
|
|
3264
3361
|
] }),
|
|
3265
3362
|
/* @__PURE__ */ jsx3("span", { className: "ssw-quote-row-usd", children: usdValue })
|
|
3266
3363
|
] })
|
|
@@ -3276,7 +3373,7 @@ var QuotesModal = ({
|
|
|
3276
3373
|
};
|
|
3277
3374
|
|
|
3278
3375
|
// src/components/QuoteSelector.tsx
|
|
3279
|
-
import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3376
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3280
3377
|
var QuoteSelector = ({
|
|
3281
3378
|
rates,
|
|
3282
3379
|
selectedRate,
|
|
@@ -3284,7 +3381,10 @@ var QuoteSelector = ({
|
|
|
3284
3381
|
buyAsset,
|
|
3285
3382
|
sellAsset,
|
|
3286
3383
|
sellAmountBaseUnit,
|
|
3384
|
+
buyAmountBaseUnit,
|
|
3385
|
+
isExactOutput: isExactOutput2,
|
|
3287
3386
|
isLoading,
|
|
3387
|
+
sellAssetUsdPrice,
|
|
3288
3388
|
buyAssetUsdPrice
|
|
3289
3389
|
}) => {
|
|
3290
3390
|
const [isModalOpen, setIsModalOpen] = useState3(false);
|
|
@@ -3314,12 +3414,17 @@ var QuoteSelector = ({
|
|
|
3314
3414
|
return null;
|
|
3315
3415
|
}
|
|
3316
3416
|
const displayRate = selectedRate ?? bestRate;
|
|
3317
|
-
const buyAmount = displayRate.buyAmountCryptoBaseUnit ?? "0";
|
|
3318
3417
|
const swapperIcon = getSwapperIcon(displayRate.swapperName);
|
|
3319
3418
|
const swapperColor = getSwapperColor(displayRate.swapperName);
|
|
3320
|
-
const
|
|
3321
|
-
const
|
|
3322
|
-
|
|
3419
|
+
const asset = isExactOutput2 ? sellAsset : buyAsset;
|
|
3420
|
+
const amountBaseUnit = getRateAmountBaseUnit(displayRate, isExactOutput2);
|
|
3421
|
+
const formattedAmount = formatAmount(amountBaseUnit, asset.precision);
|
|
3422
|
+
const usdValue = formatUsdValue(
|
|
3423
|
+
amountBaseUnit,
|
|
3424
|
+
asset.precision,
|
|
3425
|
+
isExactOutput2 ? sellAssetUsdPrice : buyAssetUsdPrice
|
|
3426
|
+
);
|
|
3427
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
3323
3428
|
/* @__PURE__ */ jsxs4("button", { className: "ssw-quote-selector", onClick: handleOpenModal, type: "button", children: [
|
|
3324
3429
|
/* @__PURE__ */ jsxs4("div", { className: "ssw-quote-left", children: [
|
|
3325
3430
|
/* @__PURE__ */ jsxs4("div", { className: "ssw-quote-provider", children: [
|
|
@@ -3345,8 +3450,8 @@ var QuoteSelector = ({
|
|
|
3345
3450
|
] }),
|
|
3346
3451
|
/* @__PURE__ */ jsxs4("div", { className: "ssw-quote-right", children: [
|
|
3347
3452
|
/* @__PURE__ */ jsxs4("div", { className: "ssw-quote-amount-row", children: [
|
|
3348
|
-
/* @__PURE__ */ jsx4("span", { className: "ssw-quote-amount", children:
|
|
3349
|
-
/* @__PURE__ */ jsx4("span", { className: "ssw-quote-symbol", children:
|
|
3453
|
+
/* @__PURE__ */ jsx4("span", { className: "ssw-quote-amount", children: formattedAmount }),
|
|
3454
|
+
/* @__PURE__ */ jsx4("span", { className: "ssw-quote-symbol", children: asset.symbol })
|
|
3350
3455
|
] }),
|
|
3351
3456
|
alternativeRatesCount > 0 && /* @__PURE__ */ jsxs4("span", { className: "ssw-quote-more", children: [
|
|
3352
3457
|
"+",
|
|
@@ -3378,6 +3483,9 @@ var QuoteSelector = ({
|
|
|
3378
3483
|
buyAsset,
|
|
3379
3484
|
sellAsset,
|
|
3380
3485
|
sellAmountBaseUnit,
|
|
3486
|
+
buyAmountBaseUnit,
|
|
3487
|
+
isExactOutput: isExactOutput2,
|
|
3488
|
+
sellAssetUsdPrice,
|
|
3381
3489
|
buyAssetUsdPrice
|
|
3382
3490
|
}
|
|
3383
3491
|
)
|
|
@@ -3386,11 +3494,12 @@ var QuoteSelector = ({
|
|
|
3386
3494
|
|
|
3387
3495
|
// src/components/ReceiveAddressRow.tsx
|
|
3388
3496
|
import { useCallback as useCallback7, useLayoutEffect, useMemo as useMemo8, useRef as useRef5, useState as useState4 } from "react";
|
|
3389
|
-
import { Fragment as
|
|
3497
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3390
3498
|
var ReceiveAddressRow = ({
|
|
3391
3499
|
receiveAddress,
|
|
3392
3500
|
isResolving,
|
|
3393
3501
|
buyChainId,
|
|
3502
|
+
isLocked,
|
|
3394
3503
|
onSetCustomReceiveAddress
|
|
3395
3504
|
}) => {
|
|
3396
3505
|
const [isEditing, setIsEditing] = useState4(false);
|
|
@@ -3398,7 +3507,7 @@ var ReceiveAddressRow = ({
|
|
|
3398
3507
|
const [hasInteracted, setHasInteracted] = useState4(false);
|
|
3399
3508
|
const inputRef = useRef5(null);
|
|
3400
3509
|
const needsAddress = !receiveAddress;
|
|
3401
|
-
const showInput = needsAddress && !isResolving || isEditing;
|
|
3510
|
+
const showInput = !isLocked && (needsAddress && !isResolving || isEditing);
|
|
3402
3511
|
const showAttention = needsAddress && !isResolving;
|
|
3403
3512
|
useLayoutEffect(() => {
|
|
3404
3513
|
if (isEditing) inputRef.current?.focus();
|
|
@@ -3418,6 +3527,7 @@ var ReceiveAddressRow = ({
|
|
|
3418
3527
|
[trimmedDraft, buyChainId]
|
|
3419
3528
|
);
|
|
3420
3529
|
const formatHint = useMemo8(() => getAddressFormatHint(buyChainId), [buyChainId]);
|
|
3530
|
+
const chainName = useMemo8(() => getChainName(buyChainId), [buyChainId]);
|
|
3421
3531
|
const startEditing = useCallback7(() => {
|
|
3422
3532
|
setDraft(receiveAddress ?? "");
|
|
3423
3533
|
setHasInteracted(false);
|
|
@@ -3441,36 +3551,48 @@ var ReceiveAddressRow = ({
|
|
|
3441
3551
|
}, [onSetCustomReceiveAddress]);
|
|
3442
3552
|
const showReset = !!draft || isEditing;
|
|
3443
3553
|
if (!showInput) {
|
|
3444
|
-
return /* @__PURE__ */ jsxs5(
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
"
|
|
3450
|
-
{
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3554
|
+
return /* @__PURE__ */ jsxs5(
|
|
3555
|
+
"div",
|
|
3556
|
+
{
|
|
3557
|
+
className: `ssw-receive-row ssw-receive-row-resolved${showAttention ? " ssw-receive-row-invalid" : ""}`,
|
|
3558
|
+
children: [
|
|
3559
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-receive-label", children: "Receive address" }),
|
|
3560
|
+
/* @__PURE__ */ jsx5("div", { className: "ssw-receive-resolved-value", children: isResolving ? /* @__PURE__ */ jsx5("span", { className: "ssw-balance-skeleton" }) : showAttention ? (
|
|
3561
|
+
// Locked only - an unlocked row with no address shows the input instead
|
|
3562
|
+
/* @__PURE__ */ jsxs5("span", { className: "ssw-receive-error", children: [
|
|
3563
|
+
"Not valid for ",
|
|
3564
|
+
chainName
|
|
3565
|
+
] })
|
|
3566
|
+
) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3567
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-receive-address", children: truncateAddress(receiveAddress ?? "", 6) }),
|
|
3568
|
+
!isLocked && /* @__PURE__ */ jsx5(
|
|
3569
|
+
"button",
|
|
3457
3570
|
{
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3571
|
+
className: "ssw-receive-edit-btn",
|
|
3572
|
+
onClick: startEditing,
|
|
3573
|
+
type: "button",
|
|
3574
|
+
"aria-label": "Edit receive address",
|
|
3575
|
+
children: /* @__PURE__ */ jsxs5(
|
|
3576
|
+
"svg",
|
|
3577
|
+
{
|
|
3578
|
+
width: "14",
|
|
3579
|
+
height: "14",
|
|
3580
|
+
viewBox: "0 0 24 24",
|
|
3581
|
+
fill: "none",
|
|
3582
|
+
stroke: "currentColor",
|
|
3583
|
+
strokeWidth: "2",
|
|
3584
|
+
children: [
|
|
3585
|
+
/* @__PURE__ */ jsx5("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
3586
|
+
/* @__PURE__ */ jsx5("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
3587
|
+
]
|
|
3588
|
+
}
|
|
3589
|
+
)
|
|
3468
3590
|
}
|
|
3469
3591
|
)
|
|
3470
|
-
}
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3592
|
+
] }) })
|
|
3593
|
+
]
|
|
3594
|
+
}
|
|
3595
|
+
);
|
|
3474
3596
|
}
|
|
3475
3597
|
return /* @__PURE__ */ jsxs5(
|
|
3476
3598
|
"div",
|
|
@@ -3554,39 +3676,23 @@ var ReceiveAddressRow = ({
|
|
|
3554
3676
|
};
|
|
3555
3677
|
|
|
3556
3678
|
// src/components/InputStep.tsx
|
|
3557
|
-
import { Fragment as
|
|
3679
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3558
3680
|
var InputStep = ({
|
|
3559
3681
|
displayValues,
|
|
3560
3682
|
onOpenTokenModal,
|
|
3561
3683
|
onSellAmountChange,
|
|
3684
|
+
onBuyAmountChange,
|
|
3562
3685
|
onToggleSellFiat,
|
|
3563
3686
|
onSwapTokens,
|
|
3564
3687
|
onSelectRate,
|
|
3565
3688
|
onButtonClick,
|
|
3566
3689
|
isBuyAssetLocked,
|
|
3690
|
+
isBuyAmountLocked,
|
|
3691
|
+
isReceiveAddressLocked,
|
|
3567
3692
|
allowShapeshiftRedirect
|
|
3568
3693
|
}) => {
|
|
3569
3694
|
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
3570
3695
|
const isQuoting = SwapMachineCtx.useSelector((s) => s.matches("quoting"));
|
|
3571
|
-
const {
|
|
3572
|
-
rates,
|
|
3573
|
-
isLoadingRates,
|
|
3574
|
-
ratesError,
|
|
3575
|
-
sellAssetBalance,
|
|
3576
|
-
buyAssetBalance,
|
|
3577
|
-
isSellBalanceLoading,
|
|
3578
|
-
isBuyBalanceLoading,
|
|
3579
|
-
sellUsdValue,
|
|
3580
|
-
sellAssetUsdPrice,
|
|
3581
|
-
buyUsdValue,
|
|
3582
|
-
sellChainInfo,
|
|
3583
|
-
buyChainInfo,
|
|
3584
|
-
buyAmount,
|
|
3585
|
-
buyAssetUsdPrice,
|
|
3586
|
-
networkFeeDisplay,
|
|
3587
|
-
sellBalanceFiatValue,
|
|
3588
|
-
buyBalanceFiatValue
|
|
3589
|
-
} = displayValues;
|
|
3590
3696
|
const {
|
|
3591
3697
|
sendAddress,
|
|
3592
3698
|
receiveAddress,
|
|
@@ -3596,22 +3702,48 @@ var InputStep = ({
|
|
|
3596
3702
|
bitcoin: bitcoin3,
|
|
3597
3703
|
solana: solana3
|
|
3598
3704
|
} = useSwapWallet();
|
|
3599
|
-
const
|
|
3600
|
-
sellAsset,
|
|
3601
|
-
buyAsset,
|
|
3602
|
-
selectedRate,
|
|
3603
|
-
sellAmount,
|
|
3604
|
-
sellAmountBaseUnit,
|
|
3605
|
-
isSellAmountFiat,
|
|
3606
|
-
sellAmountFiat,
|
|
3607
|
-
isSellAssetEvm,
|
|
3608
|
-
isSellAssetUtxo,
|
|
3609
|
-
isSellAssetSolana
|
|
3610
|
-
} = context;
|
|
3611
|
-
const buyChainId = buyAsset.chainId;
|
|
3705
|
+
const buyChainId = context.buyAsset.chainId;
|
|
3612
3706
|
const hasAnyWalletAddress = !!evm.address || !!bitcoin3.address || !!solana3.address;
|
|
3613
3707
|
const hasActiveWallet = !!receiveAddress || hasAnyWalletAddress || isReceiveAddressResolving;
|
|
3614
|
-
const isUnsupportedChain = !isSellAssetEvm && !isSellAssetUtxo && !isSellAssetSolana;
|
|
3708
|
+
const isUnsupportedChain = !context.isSellAssetEvm && !context.isSellAssetUtxo && !context.isSellAssetSolana;
|
|
3709
|
+
const amountBaseUnit = displayValues.isExactOutput ? context.buyAmountBaseUnit : context.sellAmountBaseUnit;
|
|
3710
|
+
const isSellAmountReadOnly = displayValues.isExactOutput && isBuyAmountLocked;
|
|
3711
|
+
const isSellAmountPending = displayValues.isExactOutput && displayValues.isLoadingRates;
|
|
3712
|
+
const isBuyAmountPending = !displayValues.isExactOutput && displayValues.isLoadingRates;
|
|
3713
|
+
const sellAmountCrypto = useMemo9(
|
|
3714
|
+
() => displayValues.sellAmountBaseUnit ? formatAmount(displayValues.sellAmountBaseUnit, context.sellAsset.precision, 6) : "",
|
|
3715
|
+
[displayValues.sellAmountBaseUnit, context.sellAsset.precision]
|
|
3716
|
+
);
|
|
3717
|
+
const buyAmountValue = useMemo9(() => {
|
|
3718
|
+
if (displayValues.isExactOutput) return context.buyAmount;
|
|
3719
|
+
if (!displayValues.buyAmount) return "";
|
|
3720
|
+
return formatAmount(displayValues.buyAmount, context.buyAsset.precision);
|
|
3721
|
+
}, [
|
|
3722
|
+
displayValues.isExactOutput,
|
|
3723
|
+
displayValues.buyAmount,
|
|
3724
|
+
context.buyAmount,
|
|
3725
|
+
context.buyAsset.precision
|
|
3726
|
+
]);
|
|
3727
|
+
const sellAmountValue = useMemo9(() => {
|
|
3728
|
+
if (!displayValues.isExactOutput) {
|
|
3729
|
+
return context.isSellAmountFiat ? context.sellAmountFiat : context.sellAmount;
|
|
3730
|
+
}
|
|
3731
|
+
if (!context.isSellAmountFiat) return sellAmountCrypto;
|
|
3732
|
+
return cryptoToFiat(
|
|
3733
|
+
displayValues.sellAmountBaseUnit,
|
|
3734
|
+
displayValues.sellAssetUsdPrice ?? "",
|
|
3735
|
+
context.sellAsset.precision
|
|
3736
|
+
);
|
|
3737
|
+
}, [
|
|
3738
|
+
displayValues.isExactOutput,
|
|
3739
|
+
displayValues.sellAmountBaseUnit,
|
|
3740
|
+
displayValues.sellAssetUsdPrice,
|
|
3741
|
+
context.isSellAmountFiat,
|
|
3742
|
+
context.sellAmountFiat,
|
|
3743
|
+
context.sellAmount,
|
|
3744
|
+
context.sellAsset.precision,
|
|
3745
|
+
sellAmountCrypto
|
|
3746
|
+
]);
|
|
3615
3747
|
const { text: buttonText, disabled: isButtonDisabled } = useMemo9(() => {
|
|
3616
3748
|
if (isUnsupportedChain) {
|
|
3617
3749
|
if (!allowShapeshiftRedirect) return { text: "Route not supported", disabled: true };
|
|
@@ -3619,39 +3751,43 @@ var InputStep = ({
|
|
|
3619
3751
|
}
|
|
3620
3752
|
if (!sendAddress) return { text: "Connect Wallet", disabled: false };
|
|
3621
3753
|
if (!receiveAddress) return { text: "Enter receive address", disabled: true };
|
|
3622
|
-
|
|
3623
|
-
if (
|
|
3624
|
-
if (
|
|
3625
|
-
if (
|
|
3754
|
+
const drivingAmount = displayValues.isExactOutput ? context.buyAmountBaseUnit : context.sellAmount;
|
|
3755
|
+
if (!drivingAmount || drivingAmount === "0") return { text: "Enter an amount", disabled: true };
|
|
3756
|
+
if (displayValues.isLoadingRates) return { text: "Finding rates...", disabled: true };
|
|
3757
|
+
if (displayValues.ratesError) return { text: "No routes available", disabled: true };
|
|
3758
|
+
if (!displayValues.rates?.length) return { text: "No routes found", disabled: true };
|
|
3626
3759
|
return { text: "Swap", disabled: false };
|
|
3627
3760
|
}, [
|
|
3628
3761
|
isUnsupportedChain,
|
|
3629
3762
|
allowShapeshiftRedirect,
|
|
3630
3763
|
sendAddress,
|
|
3631
3764
|
receiveAddress,
|
|
3632
|
-
sellAmount,
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3765
|
+
context.sellAmount,
|
|
3766
|
+
displayValues.isExactOutput,
|
|
3767
|
+
context.buyAmountBaseUnit,
|
|
3768
|
+
displayValues.isLoadingRates,
|
|
3769
|
+
displayValues.ratesError,
|
|
3770
|
+
displayValues.rates
|
|
3636
3771
|
]);
|
|
3637
|
-
return /* @__PURE__ */ jsxs6(
|
|
3772
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
3638
3773
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-swap-container", children: [
|
|
3639
3774
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-token-section ssw-sell", children: [
|
|
3640
3775
|
/* @__PURE__ */ jsx6("div", { className: "ssw-section-header", children: /* @__PURE__ */ jsx6("span", { className: "ssw-section-label", children: "Sell" }) }),
|
|
3641
3776
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-input-row", children: [
|
|
3642
|
-
isSellAmountFiat && /* @__PURE__ */ jsx6("span", { className: "ssw-fiat-prefix", children: "$" }),
|
|
3777
|
+
context.isSellAmountFiat && /* @__PURE__ */ jsx6("span", { className: "ssw-fiat-prefix", children: "$" }),
|
|
3643
3778
|
/* @__PURE__ */ jsx6(
|
|
3644
3779
|
"input",
|
|
3645
3780
|
{
|
|
3646
3781
|
type: "text",
|
|
3647
|
-
className: "ssw-amount-input"
|
|
3648
|
-
placeholder: "0",
|
|
3649
|
-
value:
|
|
3782
|
+
className: `ssw-amount-input${isSellAmountReadOnly ? " ssw-amount-input-locked" : ""}${isSellAmountPending ? " ssw-amount-input-pending" : ""}`,
|
|
3783
|
+
placeholder: isSellAmountPending ? "..." : "0",
|
|
3784
|
+
value: sellAmountValue,
|
|
3785
|
+
readOnly: isSellAmountReadOnly,
|
|
3650
3786
|
onChange: (e) => {
|
|
3651
3787
|
const raw = e.target.value.replace(/[^0-9.]/g, "");
|
|
3652
3788
|
const parts = raw.split(".");
|
|
3653
3789
|
const sanitized = parts.length > 2 ? parts[0] + "." + parts.slice(1).join("") : raw;
|
|
3654
|
-
onSellAmountChange(sanitized, sellAssetUsdPrice);
|
|
3790
|
+
onSellAmountChange(sanitized, displayValues.sellAssetUsdPrice);
|
|
3655
3791
|
}
|
|
3656
3792
|
}
|
|
3657
3793
|
),
|
|
@@ -3662,10 +3798,17 @@ var InputStep = ({
|
|
|
3662
3798
|
onClick: () => onOpenTokenModal("sell"),
|
|
3663
3799
|
type: "button",
|
|
3664
3800
|
children: [
|
|
3665
|
-
sellAsset.icon ? /* @__PURE__ */ jsx6(
|
|
3801
|
+
context.sellAsset.icon ? /* @__PURE__ */ jsx6(
|
|
3802
|
+
"img",
|
|
3803
|
+
{
|
|
3804
|
+
src: context.sellAsset.icon,
|
|
3805
|
+
alt: context.sellAsset.symbol,
|
|
3806
|
+
className: "ssw-token-icon"
|
|
3807
|
+
}
|
|
3808
|
+
) : /* @__PURE__ */ jsx6("div", { className: "ssw-token-icon-placeholder", children: context.sellAsset.symbol.charAt(0) }),
|
|
3666
3809
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-token-info", children: [
|
|
3667
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-token-symbol", children: sellAsset.symbol }),
|
|
3668
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-token-chain", children: sellChainInfo?.name ?? sellAsset.networkName ?? sellAsset.name })
|
|
3810
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-token-symbol", children: context.sellAsset.symbol }),
|
|
3811
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-token-chain", children: displayValues.sellChainInfo?.name ?? context.sellAsset.networkName ?? context.sellAsset.name })
|
|
3669
3812
|
] }),
|
|
3670
3813
|
/* @__PURE__ */ jsx6(
|
|
3671
3814
|
"svg",
|
|
@@ -3684,14 +3827,14 @@ var InputStep = ({
|
|
|
3684
3827
|
)
|
|
3685
3828
|
] }),
|
|
3686
3829
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-section-footer", children: [
|
|
3687
|
-
sellAssetUsdPrice ? /* @__PURE__ */ jsxs6(
|
|
3830
|
+
!displayValues.sellAssetUsdPrice ? /* @__PURE__ */ jsx6("span", { className: "ssw-usd-value" }) : /* @__PURE__ */ jsxs6(
|
|
3688
3831
|
"button",
|
|
3689
3832
|
{
|
|
3690
3833
|
type: "button",
|
|
3691
3834
|
className: "ssw-usd-value ssw-usd-value-toggle",
|
|
3692
|
-
onClick: () => onToggleSellFiat(sellAssetUsdPrice),
|
|
3835
|
+
onClick: () => onToggleSellFiat(displayValues.sellAssetUsdPrice),
|
|
3693
3836
|
children: [
|
|
3694
|
-
/* @__PURE__ */ jsx6("span", { children: isSellAmountFiat ? `\u2248 ${
|
|
3837
|
+
/* @__PURE__ */ jsx6("span", { children: context.isSellAmountFiat ? `\u2248 ${sellAmountCrypto || "0"} ${context.sellAsset.symbol}` : displayValues.sellUsdValue }),
|
|
3695
3838
|
/* @__PURE__ */ jsx6(
|
|
3696
3839
|
"svg",
|
|
3697
3840
|
{
|
|
@@ -3707,13 +3850,14 @@ var InputStep = ({
|
|
|
3707
3850
|
)
|
|
3708
3851
|
]
|
|
3709
3852
|
}
|
|
3710
|
-
)
|
|
3711
|
-
hasAnyWalletAddress && (isSellBalanceLoading ? /* @__PURE__ */ jsx6("span", { className: "ssw-balance-skeleton" }) : sellAssetBalance ? /* @__PURE__ */ jsxs6("span", { className: "ssw-balance", children: [
|
|
3853
|
+
),
|
|
3854
|
+
hasAnyWalletAddress && (displayValues.isSellBalanceLoading ? /* @__PURE__ */ jsx6("span", { className: "ssw-balance-skeleton" }) : displayValues.sellAssetBalance ? /* @__PURE__ */ jsxs6("span", { className: "ssw-balance", children: [
|
|
3712
3855
|
"Balance: ",
|
|
3713
|
-
sellAssetBalance.balanceFormatted,
|
|
3714
|
-
sellBalanceFiatValue && /* @__PURE__ */ jsxs6("span", { className: "ssw-balance-fiat", children: [
|
|
3715
|
-
"
|
|
3716
|
-
|
|
3856
|
+
displayValues.sellAssetBalance.balanceFormatted,
|
|
3857
|
+
displayValues.sellBalanceFiatValue && /* @__PURE__ */ jsxs6("span", { className: "ssw-balance-fiat", children: [
|
|
3858
|
+
" ",
|
|
3859
|
+
"(",
|
|
3860
|
+
displayValues.sellBalanceFiatValue,
|
|
3717
3861
|
")"
|
|
3718
3862
|
] })
|
|
3719
3863
|
] }) : null)
|
|
@@ -3747,10 +3891,15 @@ var InputStep = ({
|
|
|
3747
3891
|
"input",
|
|
3748
3892
|
{
|
|
3749
3893
|
type: "text",
|
|
3750
|
-
className: "ssw-amount-input"
|
|
3751
|
-
placeholder: "0",
|
|
3752
|
-
value:
|
|
3753
|
-
readOnly:
|
|
3894
|
+
className: `ssw-amount-input${isBuyAmountLocked ? " ssw-amount-input-locked" : ""}${isBuyAmountPending ? " ssw-amount-input-pending" : ""}`,
|
|
3895
|
+
placeholder: isBuyAmountPending ? "..." : "0",
|
|
3896
|
+
value: buyAmountValue,
|
|
3897
|
+
readOnly: isBuyAmountLocked,
|
|
3898
|
+
onChange: (e) => {
|
|
3899
|
+
const raw = e.target.value.replace(/[^0-9.]/g, "");
|
|
3900
|
+
const parts = raw.split(".");
|
|
3901
|
+
onBuyAmountChange(parts.length > 2 ? parts[0] + "." + parts.slice(1).join("") : raw);
|
|
3902
|
+
}
|
|
3754
3903
|
}
|
|
3755
3904
|
),
|
|
3756
3905
|
/* @__PURE__ */ jsxs6(
|
|
@@ -3761,10 +3910,17 @@ var InputStep = ({
|
|
|
3761
3910
|
disabled: isBuyAssetLocked,
|
|
3762
3911
|
type: "button",
|
|
3763
3912
|
children: [
|
|
3764
|
-
buyAsset.icon ? /* @__PURE__ */ jsx6(
|
|
3913
|
+
context.buyAsset.icon ? /* @__PURE__ */ jsx6(
|
|
3914
|
+
"img",
|
|
3915
|
+
{
|
|
3916
|
+
src: context.buyAsset.icon,
|
|
3917
|
+
alt: context.buyAsset.symbol,
|
|
3918
|
+
className: "ssw-token-icon"
|
|
3919
|
+
}
|
|
3920
|
+
) : /* @__PURE__ */ jsx6("div", { className: "ssw-token-icon-placeholder", children: context.buyAsset.symbol.charAt(0) }),
|
|
3765
3921
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-token-info", children: [
|
|
3766
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-token-symbol", children: buyAsset.symbol }),
|
|
3767
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-token-chain", children: buyChainInfo?.name ?? buyAsset.networkName ?? buyAsset.name })
|
|
3922
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-token-symbol", children: context.buyAsset.symbol }),
|
|
3923
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-token-chain", children: displayValues.buyChainInfo?.name ?? context.buyAsset.networkName ?? context.buyAsset.name })
|
|
3768
3924
|
] }),
|
|
3769
3925
|
!isBuyAssetLocked && /* @__PURE__ */ jsx6(
|
|
3770
3926
|
"svg",
|
|
@@ -3783,13 +3939,13 @@ var InputStep = ({
|
|
|
3783
3939
|
)
|
|
3784
3940
|
] }),
|
|
3785
3941
|
/* @__PURE__ */ jsxs6("div", { className: "ssw-section-footer", children: [
|
|
3786
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-usd-value", children: buyUsdValue }),
|
|
3787
|
-
hasAnyWalletAddress && (isBuyBalanceLoading ? /* @__PURE__ */ jsx6("span", { className: "ssw-balance-skeleton" }) : buyAssetBalance ? /* @__PURE__ */ jsxs6("span", { className: "ssw-balance", children: [
|
|
3942
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-usd-value", children: displayValues.buyUsdValue }),
|
|
3943
|
+
hasAnyWalletAddress && (displayValues.isBuyBalanceLoading ? /* @__PURE__ */ jsx6("span", { className: "ssw-balance-skeleton" }) : displayValues.buyAssetBalance ? /* @__PURE__ */ jsxs6("span", { className: "ssw-balance", children: [
|
|
3788
3944
|
"Balance: ",
|
|
3789
|
-
buyAssetBalance.balanceFormatted,
|
|
3790
|
-
buyBalanceFiatValue && /* @__PURE__ */ jsxs6("span", { className: "ssw-balance-fiat", children: [
|
|
3945
|
+
displayValues.buyAssetBalance.balanceFormatted,
|
|
3946
|
+
displayValues.buyBalanceFiatValue && /* @__PURE__ */ jsxs6("span", { className: "ssw-balance-fiat", children: [
|
|
3791
3947
|
" (",
|
|
3792
|
-
buyBalanceFiatValue,
|
|
3948
|
+
displayValues.buyBalanceFiatValue,
|
|
3793
3949
|
")"
|
|
3794
3950
|
] })
|
|
3795
3951
|
] }) : null)
|
|
@@ -3801,26 +3957,30 @@ var InputStep = ({
|
|
|
3801
3957
|
receiveAddress,
|
|
3802
3958
|
isResolving: isReceiveAddressResolving,
|
|
3803
3959
|
buyChainId,
|
|
3960
|
+
isLocked: isReceiveAddressLocked,
|
|
3804
3961
|
onSetCustomReceiveAddress: setCustomReceiveAddress
|
|
3805
3962
|
}
|
|
3806
3963
|
)
|
|
3807
3964
|
] }),
|
|
3808
|
-
|
|
3965
|
+
amountBaseUnit && amountBaseUnit !== "0" && (displayValues.rates?.length || displayValues.isLoadingRates) && /* @__PURE__ */ jsx6("div", { className: "ssw-quotes", children: /* @__PURE__ */ jsx6(
|
|
3809
3966
|
QuoteSelector,
|
|
3810
3967
|
{
|
|
3811
|
-
rates: rates ?? [],
|
|
3812
|
-
selectedRate,
|
|
3968
|
+
rates: displayValues.rates ?? [],
|
|
3969
|
+
selectedRate: context.selectedRate,
|
|
3813
3970
|
onSelectRate,
|
|
3814
|
-
buyAsset,
|
|
3815
|
-
sellAsset,
|
|
3816
|
-
sellAmountBaseUnit,
|
|
3817
|
-
|
|
3818
|
-
|
|
3971
|
+
buyAsset: context.buyAsset,
|
|
3972
|
+
sellAsset: context.sellAsset,
|
|
3973
|
+
sellAmountBaseUnit: displayValues.sellAmountBaseUnit ?? "0",
|
|
3974
|
+
buyAmountBaseUnit: context.buyAmountBaseUnit ?? "0",
|
|
3975
|
+
isExactOutput: displayValues.isExactOutput,
|
|
3976
|
+
isLoading: displayValues.isLoadingRates,
|
|
3977
|
+
sellAssetUsdPrice: displayValues.sellAssetUsdPrice,
|
|
3978
|
+
buyAssetUsdPrice: displayValues.buyAssetUsdPrice
|
|
3819
3979
|
}
|
|
3820
3980
|
) }),
|
|
3821
|
-
networkFeeDisplay && /* @__PURE__ */ jsxs6("div", { className: "ssw-network-fee", children: [
|
|
3981
|
+
displayValues.networkFeeDisplay && /* @__PURE__ */ jsxs6("div", { className: "ssw-network-fee", children: [
|
|
3822
3982
|
/* @__PURE__ */ jsx6("span", { className: "ssw-network-fee-label", children: "Est. network fee" }),
|
|
3823
|
-
/* @__PURE__ */ jsx6("span", { className: "ssw-network-fee-value", children: networkFeeDisplay })
|
|
3983
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-network-fee-value", children: displayValues.networkFeeDisplay })
|
|
3824
3984
|
] }),
|
|
3825
3985
|
/* @__PURE__ */ jsx6(
|
|
3826
3986
|
"button",
|
|
@@ -3830,7 +3990,7 @@ var InputStep = ({
|
|
|
3830
3990
|
onClick: onButtonClick,
|
|
3831
3991
|
type: "button",
|
|
3832
3992
|
style: isQuoting ? { opacity: 0.7 } : void 0,
|
|
3833
|
-
children: isQuoting ? /* @__PURE__ */ jsxs6(
|
|
3993
|
+
children: isQuoting ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
3834
3994
|
/* @__PURE__ */ jsxs6(
|
|
3835
3995
|
"svg",
|
|
3836
3996
|
{
|
|
@@ -4017,7 +4177,7 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4017
4177
|
|
|
4018
4178
|
// src/components/StatusStep.tsx
|
|
4019
4179
|
import { useMemo as useMemo10 } from "react";
|
|
4020
|
-
import { Fragment as
|
|
4180
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4021
4181
|
var ExplorerLink = ({ url }) => /* @__PURE__ */ jsxs8("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "ssw-step-explorer-link", children: [
|
|
4022
4182
|
"View on Explorer",
|
|
4023
4183
|
/* @__PURE__ */ jsx8(
|
|
@@ -4033,7 +4193,7 @@ var ExplorerLink = ({ url }) => /* @__PURE__ */ jsxs8("a", { href: url, target:
|
|
|
4033
4193
|
}
|
|
4034
4194
|
)
|
|
4035
4195
|
] });
|
|
4036
|
-
var StatusStep = () => {
|
|
4196
|
+
var StatusStep = ({ isPayment }) => {
|
|
4037
4197
|
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
4038
4198
|
const isPolling = SwapMachineCtx.useSelector((s) => s.matches("polling_status"));
|
|
4039
4199
|
const isComplete = SwapMachineCtx.useSelector((s) => s.matches("complete"));
|
|
@@ -4051,7 +4211,7 @@ var StatusStep = () => {
|
|
|
4051
4211
|
[error]
|
|
4052
4212
|
);
|
|
4053
4213
|
return /* @__PURE__ */ jsxs8("div", { className: "ssw-step-screen", children: [
|
|
4054
|
-
isPolling && /* @__PURE__ */ jsxs8(
|
|
4214
|
+
isPolling && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
4055
4215
|
/* @__PURE__ */ jsx8("div", { className: "ssw-step-icon-circle ssw-ic-accent", children: /* @__PURE__ */ jsxs8(
|
|
4056
4216
|
"svg",
|
|
4057
4217
|
{
|
|
@@ -4072,7 +4232,7 @@ var StatusStep = () => {
|
|
|
4072
4232
|
/* @__PURE__ */ jsx8("div", { className: "ssw-step-subtitle", children: "Your swap is being processed\u2026" }),
|
|
4073
4233
|
explorerUrl && /* @__PURE__ */ jsx8(ExplorerLink, { url: explorerUrl })
|
|
4074
4234
|
] }),
|
|
4075
|
-
isComplete && /* @__PURE__ */ jsxs8(
|
|
4235
|
+
isComplete && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
4076
4236
|
/* @__PURE__ */ jsx8("div", { className: "ssw-step-icon-circle ssw-ic-success", children: /* @__PURE__ */ jsx8(
|
|
4077
4237
|
"svg",
|
|
4078
4238
|
{
|
|
@@ -4093,7 +4253,7 @@ var StatusStep = () => {
|
|
|
4093
4253
|
buyAsset.symbol
|
|
4094
4254
|
] }),
|
|
4095
4255
|
explorerUrl && /* @__PURE__ */ jsx8(ExplorerLink, { url: explorerUrl }),
|
|
4096
|
-
/* @__PURE__ */ jsx8("div", { className: "ssw-step-actions", children: /* @__PURE__ */ jsx8(
|
|
4256
|
+
!isPayment && /* @__PURE__ */ jsx8("div", { className: "ssw-step-actions", children: /* @__PURE__ */ jsx8(
|
|
4097
4257
|
"button",
|
|
4098
4258
|
{
|
|
4099
4259
|
className: "ssw-action-btn",
|
|
@@ -4103,7 +4263,7 @@ var StatusStep = () => {
|
|
|
4103
4263
|
}
|
|
4104
4264
|
) })
|
|
4105
4265
|
] }),
|
|
4106
|
-
isError && /* @__PURE__ */ jsxs8(
|
|
4266
|
+
isError && /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
4107
4267
|
/* @__PURE__ */ jsx8("div", { className: "ssw-step-icon-circle ssw-ic-error", children: /* @__PURE__ */ jsxs8(
|
|
4108
4268
|
"svg",
|
|
4109
4269
|
{
|
|
@@ -4146,10 +4306,10 @@ var StatusStep = () => {
|
|
|
4146
4306
|
};
|
|
4147
4307
|
|
|
4148
4308
|
// src/components/TokenSelectModal.tsx
|
|
4149
|
-
import { bnOrZero as
|
|
4309
|
+
import { bnOrZero as bnOrZero2 } from "@shapeshiftoss/utils";
|
|
4150
4310
|
import { useCallback as useCallback9, useEffect as useEffect8, useMemo as useMemo11, useRef as useRef6, useState as useState6 } from "react";
|
|
4151
4311
|
import { Virtuoso } from "react-virtuoso";
|
|
4152
|
-
import { Fragment as
|
|
4312
|
+
import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4153
4313
|
var VISIBLE_BUFFER = 10;
|
|
4154
4314
|
var useLockBodyScroll3 = (isLocked) => {
|
|
4155
4315
|
useEffect8(() => {
|
|
@@ -4330,7 +4490,7 @@ var TokenSelectModal = ({
|
|
|
4330
4490
|
const balance = balances[asset.assetId];
|
|
4331
4491
|
if (balance && balance.balance !== "0") {
|
|
4332
4492
|
const price = marketData?.[asset.assetId]?.price;
|
|
4333
|
-
const fiatValue = price ?
|
|
4493
|
+
const fiatValue = price ? bnOrZero2(balance.balance).div(bnOrZero2(10).pow(asset.precision)).times(bnOrZero2(price)).toNumber() : 0;
|
|
4334
4494
|
withBalance.push({ asset, fiatValue });
|
|
4335
4495
|
} else {
|
|
4336
4496
|
withoutBalance.push(asset);
|
|
@@ -4534,10 +4694,10 @@ var TokenSelectModal = ({
|
|
|
4534
4694
|
/* @__PURE__ */ jsx9("span", { className: "ssw-token-symbol", children: asset.symbol }),
|
|
4535
4695
|
/* @__PURE__ */ jsx9("span", { className: "ssw-token-name", children: chainInfo?.name ?? asset.networkName ?? asset.name })
|
|
4536
4696
|
] }),
|
|
4537
|
-
/* @__PURE__ */ jsx9("div", { className: "ssw-token-right", children: (evmAddress || bitcoinAddress || solanaAddress) && (loadingAssetIds.has(asset.assetId) ? /* @__PURE__ */ jsx9("span", { className: "ssw-token-balance-skeleton" }) : balance && balance.balance !== "0" ? /* @__PURE__ */ jsxs9(
|
|
4697
|
+
/* @__PURE__ */ jsx9("div", { className: "ssw-token-right", children: (evmAddress || bitcoinAddress || solanaAddress) && (loadingAssetIds.has(asset.assetId) ? /* @__PURE__ */ jsx9("span", { className: "ssw-token-balance-skeleton" }) : balance && balance.balance !== "0" ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
4538
4698
|
marketData?.[asset.assetId]?.price && /* @__PURE__ */ jsxs9("span", { className: "ssw-token-fiat-value", children: [
|
|
4539
4699
|
"$",
|
|
4540
|
-
|
|
4700
|
+
bnOrZero2(balance.balance).div(bnOrZero2(10).pow(asset.precision)).times(bnOrZero2(marketData[asset.assetId].price)).toNumber().toLocaleString(void 0, {
|
|
4541
4701
|
minimumFractionDigits: 2,
|
|
4542
4702
|
maximumFractionDigits: 2
|
|
4543
4703
|
})
|
|
@@ -4679,8 +4839,11 @@ var SwapWidgetContent = ({
|
|
|
4679
4839
|
showPoweredBy,
|
|
4680
4840
|
showConnectButton,
|
|
4681
4841
|
isBuyAssetLocked,
|
|
4842
|
+
isBuyAmountLocked,
|
|
4843
|
+
isReceiveAddressLocked,
|
|
4844
|
+
isPayment,
|
|
4682
4845
|
partnerCode,
|
|
4683
|
-
|
|
4846
|
+
canRedirectToShapeshift,
|
|
4684
4847
|
onSwapSuccess,
|
|
4685
4848
|
onSwapError,
|
|
4686
4849
|
sellFilters,
|
|
@@ -4704,11 +4867,12 @@ var SwapWidgetContent = ({
|
|
|
4704
4867
|
handleSellAssetSelect,
|
|
4705
4868
|
handleBuyAssetSelect,
|
|
4706
4869
|
handleSellAmountChange,
|
|
4870
|
+
handleBuyAmountChange,
|
|
4707
4871
|
handleToggleSellFiat,
|
|
4708
4872
|
handleSelectRate,
|
|
4709
4873
|
handleSlippageChange,
|
|
4710
4874
|
handleButtonClick
|
|
4711
|
-
} = useSwapHandlers({ partnerCode, allowShapeshiftRedirect });
|
|
4875
|
+
} = useSwapHandlers({ partnerCode, allowShapeshiftRedirect: canRedirectToShapeshift });
|
|
4712
4876
|
useSwapQuoting({ apiClient, rates, sellAssetBalance });
|
|
4713
4877
|
useSwapApproval();
|
|
4714
4878
|
useSwapExecution();
|
|
@@ -4804,17 +4968,20 @@ var SwapWidgetContent = ({
|
|
|
4804
4968
|
displayValues,
|
|
4805
4969
|
onOpenTokenModal: setTokenModalType,
|
|
4806
4970
|
onSellAmountChange: handleSellAmountChange,
|
|
4971
|
+
onBuyAmountChange: handleBuyAmountChange,
|
|
4807
4972
|
onToggleSellFiat: handleToggleSellFiat,
|
|
4808
4973
|
onSwapTokens: handleSwapTokens,
|
|
4809
4974
|
onSelectRate: handleSelectRate,
|
|
4810
4975
|
onButtonClick: handleButtonClick,
|
|
4811
4976
|
isBuyAssetLocked,
|
|
4812
|
-
|
|
4977
|
+
isBuyAmountLocked,
|
|
4978
|
+
isReceiveAddressLocked,
|
|
4979
|
+
allowShapeshiftRedirect: canRedirectToShapeshift
|
|
4813
4980
|
}
|
|
4814
4981
|
),
|
|
4815
4982
|
(state.matches("approval_needed") || state.matches("approving")) && /* @__PURE__ */ jsx11(ApprovalStep, {}),
|
|
4816
4983
|
state.matches("executing") && /* @__PURE__ */ jsx11(ExecutionStep, {}),
|
|
4817
|
-
(state.matches("polling_status") || state.matches("complete") || state.matches("error")) && /* @__PURE__ */ jsx11(StatusStep, {})
|
|
4984
|
+
(state.matches("polling_status") || state.matches("complete") || state.matches("error")) && /* @__PURE__ */ jsx11(StatusStep, { isPayment })
|
|
4818
4985
|
] }),
|
|
4819
4986
|
showPoweredBy && /* @__PURE__ */ jsxs11("div", { className: "ssw-powered-by", children: [
|
|
4820
4987
|
"Powered by",
|
|
@@ -4843,7 +5010,7 @@ var SwapWidgetContent = ({
|
|
|
4843
5010
|
disabledChainIds: (tokenModalType === "buy" ? buyFilters : sellFilters).disabledChainIds ?? [],
|
|
4844
5011
|
allowedChainIds: (tokenModalType === "buy" ? buyFilters : sellFilters).allowedChainIds,
|
|
4845
5012
|
allowedAssetIds: (tokenModalType === "buy" ? buyFilters : sellFilters).allowedAssetIds,
|
|
4846
|
-
allowShapeshiftRedirect
|
|
5013
|
+
allowShapeshiftRedirect: canRedirectToShapeshift
|
|
4847
5014
|
}
|
|
4848
5015
|
),
|
|
4849
5016
|
/* @__PURE__ */ jsx11(
|
|
@@ -4867,6 +5034,10 @@ var SwapWidgetCore = ({
|
|
|
4867
5034
|
showPoweredBy,
|
|
4868
5035
|
showConnectButton,
|
|
4869
5036
|
isBuyAssetLocked,
|
|
5037
|
+
defaultReceiveAddress,
|
|
5038
|
+
isReceiveAddressLocked,
|
|
5039
|
+
defaultBuyAmountCryptoBaseUnit,
|
|
5040
|
+
isBuyAmountLocked,
|
|
4870
5041
|
partnerCode,
|
|
4871
5042
|
allowShapeshiftRedirect,
|
|
4872
5043
|
onSwapSuccess,
|
|
@@ -4880,7 +5051,9 @@ var SwapWidgetCore = ({
|
|
|
4880
5051
|
const evm = useEvmSigning();
|
|
4881
5052
|
const bitcoin3 = useBitcoinSigning();
|
|
4882
5053
|
const solana3 = useSolanaSigning();
|
|
4883
|
-
const [customReceiveAddress, setCustomReceiveAddress] = useState8(
|
|
5054
|
+
const [customReceiveAddress, setCustomReceiveAddress] = useState8(
|
|
5055
|
+
defaultReceiveAddress ?? ""
|
|
5056
|
+
);
|
|
4884
5057
|
const sellChainId = SwapMachineCtx.useSelector((s) => s.context.sellAsset.chainId);
|
|
4885
5058
|
const buyChainId = SwapMachineCtx.useSelector((s) => s.context.buyAsset.chainId);
|
|
4886
5059
|
const sellChainType = getChainType(sellChainId);
|
|
@@ -4913,14 +5086,30 @@ var SwapWidgetCore = ({
|
|
|
4913
5086
|
() => addressForChain(buyChainType),
|
|
4914
5087
|
[addressForChain, buyChainType]
|
|
4915
5088
|
);
|
|
4916
|
-
const isCustomReceiveAddressValid = useMemo12(
|
|
4917
|
-
() => !!customReceiveAddress && validateAddress(customReceiveAddress, buyChainId).valid,
|
|
4918
|
-
[customReceiveAddress, buyChainId]
|
|
4919
|
-
);
|
|
4920
5089
|
const receiveAddress = useMemo12(
|
|
4921
|
-
() =>
|
|
4922
|
-
|
|
5090
|
+
() => resolveReceiveAddress({
|
|
5091
|
+
isLocked: isReceiveAddressLocked,
|
|
5092
|
+
defaultAddress: defaultReceiveAddress,
|
|
5093
|
+
customAddress: customReceiveAddress,
|
|
5094
|
+
walletAddress: walletReceiveAddress,
|
|
5095
|
+
buyChainId
|
|
5096
|
+
}),
|
|
5097
|
+
[
|
|
5098
|
+
isReceiveAddressLocked,
|
|
5099
|
+
defaultReceiveAddress,
|
|
5100
|
+
customReceiveAddress,
|
|
5101
|
+
walletReceiveAddress,
|
|
5102
|
+
buyChainId
|
|
5103
|
+
]
|
|
4923
5104
|
);
|
|
5105
|
+
useEffect10(() => {
|
|
5106
|
+
if (!isBuyAmountLocked) return;
|
|
5107
|
+
actorRef.send({
|
|
5108
|
+
type: "SET_BUY_AMOUNT",
|
|
5109
|
+
amount: defaultBuyAmountCryptoBaseUnit ? formatAmountForInput(defaultBuyAmountCryptoBaseUnit, defaultBuyAsset.precision) : "",
|
|
5110
|
+
amountBaseUnit: defaultBuyAmountCryptoBaseUnit
|
|
5111
|
+
});
|
|
5112
|
+
}, [isBuyAmountLocked, defaultBuyAmountCryptoBaseUnit, defaultBuyAsset.precision, actorRef]);
|
|
4924
5113
|
const initialSyncRef = useRef7(false);
|
|
4925
5114
|
useEffect10(() => {
|
|
4926
5115
|
if (initialSyncRef.current) return;
|
|
@@ -4928,6 +5117,11 @@ var SwapWidgetCore = ({
|
|
|
4928
5117
|
actorRef.send({ type: "SET_SELL_ASSET", asset: defaultSellAsset });
|
|
4929
5118
|
actorRef.send({ type: "SET_BUY_ASSET", asset: defaultBuyAsset });
|
|
4930
5119
|
actorRef.send({ type: "SET_SLIPPAGE", slippage: defaultSlippage });
|
|
5120
|
+
actorRef.send({
|
|
5121
|
+
type: "SET_BUY_AMOUNT",
|
|
5122
|
+
amount: defaultBuyAmountCryptoBaseUnit ? formatAmountForInput(defaultBuyAmountCryptoBaseUnit, defaultBuyAsset.precision) : "",
|
|
5123
|
+
amountBaseUnit: defaultBuyAmountCryptoBaseUnit
|
|
5124
|
+
});
|
|
4931
5125
|
}, [actorRef]);
|
|
4932
5126
|
useEffect10(() => {
|
|
4933
5127
|
actorRef.send({ type: "SET_SEND_ADDRESS", address: sendAddress });
|
|
@@ -4944,6 +5138,7 @@ var SwapWidgetCore = ({
|
|
|
4944
5138
|
sendAddress,
|
|
4945
5139
|
receiveAddress,
|
|
4946
5140
|
isReceiveAddressResolving,
|
|
5141
|
+
isReceiveAddressBlocked: isReceiveAddressLocked && !receiveAddress,
|
|
4947
5142
|
customReceiveAddress,
|
|
4948
5143
|
setCustomReceiveAddress,
|
|
4949
5144
|
evm,
|
|
@@ -4954,12 +5149,16 @@ var SwapWidgetCore = ({
|
|
|
4954
5149
|
sendAddress,
|
|
4955
5150
|
receiveAddress,
|
|
4956
5151
|
isReceiveAddressResolving,
|
|
5152
|
+
isReceiveAddressLocked,
|
|
4957
5153
|
customReceiveAddress,
|
|
4958
5154
|
evm,
|
|
4959
5155
|
bitcoin3,
|
|
4960
5156
|
solana3
|
|
4961
5157
|
]
|
|
4962
5158
|
);
|
|
5159
|
+
const hasLockedBuyAmount = isBuyAmountLocked && !!defaultBuyAmountCryptoBaseUnit;
|
|
5160
|
+
const isPayment = hasLockedBuyAmount && isReceiveAddressLocked && !!defaultReceiveAddress;
|
|
5161
|
+
const canRedirectToShapeshift = allowShapeshiftRedirect && !hasLockedBuyAmount && !isReceiveAddressLocked;
|
|
4963
5162
|
return /* @__PURE__ */ jsx11(SwapWalletProvider, { value: walletValue, children: /* @__PURE__ */ jsx11(
|
|
4964
5163
|
SwapWidgetContent,
|
|
4965
5164
|
{
|
|
@@ -4967,9 +5166,12 @@ var SwapWidgetCore = ({
|
|
|
4967
5166
|
theme,
|
|
4968
5167
|
showPoweredBy,
|
|
4969
5168
|
showConnectButton,
|
|
4970
|
-
isBuyAssetLocked,
|
|
5169
|
+
isBuyAssetLocked: isBuyAssetLocked || hasLockedBuyAmount,
|
|
5170
|
+
isBuyAmountLocked,
|
|
5171
|
+
isReceiveAddressLocked,
|
|
5172
|
+
isPayment,
|
|
4971
5173
|
partnerCode,
|
|
4972
|
-
|
|
5174
|
+
canRedirectToShapeshift,
|
|
4973
5175
|
onSwapSuccess,
|
|
4974
5176
|
onSwapError,
|
|
4975
5177
|
sellFilters,
|
|
@@ -4998,6 +5200,10 @@ var SwapWidget = (props) => {
|
|
|
4998
5200
|
showPoweredBy: props.showPoweredBy ?? true,
|
|
4999
5201
|
showConnectButton: props.showConnectButton ?? true,
|
|
5000
5202
|
isBuyAssetLocked: props.isBuyAssetLocked ?? false,
|
|
5203
|
+
defaultReceiveAddress: props.defaultReceiveAddress,
|
|
5204
|
+
isReceiveAddressLocked: props.isReceiveAddressLocked ?? false,
|
|
5205
|
+
defaultBuyAmountCryptoBaseUnit: props.defaultBuyAmountCryptoBaseUnit,
|
|
5206
|
+
isBuyAmountLocked: props.isBuyAmountLocked ?? false,
|
|
5001
5207
|
partnerCode: props.partnerCode,
|
|
5002
5208
|
allowShapeshiftRedirect: props.allowShapeshiftRedirect ?? true,
|
|
5003
5209
|
onSwapSuccess: props.onSwapSuccess,
|