@shapeshiftoss/swap-widget 0.9.0 → 0.10.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 +95 -19
- package/dist/index.css +229 -9
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1722 -652
- package/package.json +7 -6
package/dist/index.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
// src/components/SwapWidget.tsx
|
|
2
2
|
import { useAppKitAccount as useAppKitAccount3 } from "@reown/appkit/react";
|
|
3
|
-
import { useCallback as
|
|
3
|
+
import { useCallback as useCallback14, useEffect as useEffect14, useLayoutEffect as useLayoutEffect3, useMemo as useMemo15, useRef as useRef12, useState as useState11 } from "react";
|
|
4
4
|
|
|
5
5
|
// src/api/client.ts
|
|
6
6
|
var DEFAULT_API_BASE_URL = "https://api.shapeshift.com";
|
|
7
|
+
var ApiError = class extends Error {
|
|
8
|
+
constructor(status, code, message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = "ApiError";
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var readErrorCode = async (response) => {
|
|
16
|
+
const body = await response.json().catch(() => void 0);
|
|
17
|
+
const code = body?.code;
|
|
18
|
+
return typeof code === "string" ? code : void 0;
|
|
19
|
+
};
|
|
7
20
|
var getTradeAmount = (params) => params.buyAmountCryptoBaseUnit !== void 0 ? { buyAmountCryptoBaseUnit: params.buyAmountCryptoBaseUnit } : { sellAmountCryptoBaseUnit: params.sellAmountCryptoBaseUnit };
|
|
8
21
|
var createApiClient = (config = {}) => {
|
|
9
22
|
const baseUrl = config.baseUrl ?? DEFAULT_API_BASE_URL;
|
|
@@ -33,7 +46,11 @@ var createApiClient = (config = {}) => {
|
|
|
33
46
|
clearTimeout(timeoutId);
|
|
34
47
|
});
|
|
35
48
|
if (!response.ok) {
|
|
36
|
-
throw new
|
|
49
|
+
throw new ApiError(
|
|
50
|
+
response.status,
|
|
51
|
+
await readErrorCode(response),
|
|
52
|
+
`API error: ${response.status} ${response.statusText}`
|
|
53
|
+
);
|
|
37
54
|
}
|
|
38
55
|
return response.json();
|
|
39
56
|
};
|
|
@@ -513,36 +530,35 @@ var useBitcoinSigning = () => {
|
|
|
513
530
|
);
|
|
514
531
|
};
|
|
515
532
|
|
|
516
|
-
// src/hooks/
|
|
517
|
-
import {
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
transport: custom(walletProvider)
|
|
532
|
-
});
|
|
533
|
-
}, [walletProvider, checksummedAddress]);
|
|
534
|
-
return useMemo2(
|
|
535
|
-
() => ({
|
|
536
|
-
walletClient,
|
|
537
|
-
address: checksummedAddress,
|
|
538
|
-
isConnected: !!(isConnected && checksummedAddress)
|
|
539
|
-
}),
|
|
540
|
-
[walletClient, checksummedAddress, isConnected]
|
|
533
|
+
// src/hooks/useCustomAddress.ts
|
|
534
|
+
import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
|
|
535
|
+
|
|
536
|
+
// src/utils/addressSpace.ts
|
|
537
|
+
import { CHAIN_NAMESPACE, fromChainId } from "@shapeshiftoss/caip";
|
|
538
|
+
var sharesAddressSpace = (chainId, otherChainId) => chainId === otherChainId || fromChainId(chainId).chainNamespace === CHAIN_NAMESPACE.Evm && fromChainId(otherChainId).chainNamespace === CHAIN_NAMESPACE.Evm;
|
|
539
|
+
|
|
540
|
+
// src/hooks/useCustomAddress.ts
|
|
541
|
+
var useCustomAddress = (chainId) => {
|
|
542
|
+
const [scoped, setScoped] = useState2({ address: "", chainId });
|
|
543
|
+
const chainIdRef = useRef(chainId);
|
|
544
|
+
chainIdRef.current = chainId;
|
|
545
|
+
const setAddress = useCallback2(
|
|
546
|
+
(address, forChainId = chainIdRef.current) => setScoped({ address, chainId: forChainId }),
|
|
547
|
+
[]
|
|
541
548
|
);
|
|
549
|
+
const previousChainIdRef = useRef(chainId);
|
|
550
|
+
useEffect(() => {
|
|
551
|
+
if (previousChainIdRef.current === chainId) return;
|
|
552
|
+
previousChainIdRef.current = chainId;
|
|
553
|
+
setScoped(
|
|
554
|
+
(current) => current.address && !sharesAddressSpace(current.chainId, chainId) ? { address: "", chainId } : current
|
|
555
|
+
);
|
|
556
|
+
}, [chainId]);
|
|
557
|
+
return [sharesAddressSpace(scoped.chainId, chainId) ? scoped.address : "", setAddress];
|
|
542
558
|
};
|
|
543
559
|
|
|
544
|
-
// src/hooks/
|
|
545
|
-
import { useEffect } from "react";
|
|
560
|
+
// src/hooks/useDepositPolling.ts
|
|
561
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
546
562
|
|
|
547
563
|
// src/machines/SwapMachineContext.ts
|
|
548
564
|
import { createActorContext } from "@xstate/react";
|
|
@@ -558,11 +574,11 @@ import {
|
|
|
558
574
|
bchChainId,
|
|
559
575
|
bscChainId,
|
|
560
576
|
btcChainId,
|
|
561
|
-
CHAIN_NAMESPACE,
|
|
577
|
+
CHAIN_NAMESPACE as CHAIN_NAMESPACE2,
|
|
562
578
|
cosmosChainId,
|
|
563
579
|
dogeChainId,
|
|
564
580
|
ethChainId as ethChainId2,
|
|
565
|
-
fromChainId,
|
|
581
|
+
fromChainId as fromChainId2,
|
|
566
582
|
gnosisChainId,
|
|
567
583
|
hyperEvmChainId,
|
|
568
584
|
katanaChainId,
|
|
@@ -589,6 +605,7 @@ var SwapperName = /* @__PURE__ */ ((SwapperName2) => {
|
|
|
589
605
|
SwapperName2["Relay"] = "Relay";
|
|
590
606
|
SwapperName2["Thorchain"] = "THORChain";
|
|
591
607
|
SwapperName2["Mayachain"] = "MAYAChain";
|
|
608
|
+
SwapperName2["Chainflip"] = "Chainflip";
|
|
592
609
|
return SwapperName2;
|
|
593
610
|
})(SwapperName || {});
|
|
594
611
|
var EVM_CHAIN_IDS = {
|
|
@@ -629,23 +646,23 @@ var REDIRECT_ONLY_CHAIN_IDS = {
|
|
|
629
646
|
starknet: starknetChainId
|
|
630
647
|
};
|
|
631
648
|
var isEvmChainId = (chainId) => {
|
|
632
|
-
const { chainNamespace } =
|
|
633
|
-
return chainNamespace ===
|
|
649
|
+
const { chainNamespace } = fromChainId2(chainId);
|
|
650
|
+
return chainNamespace === CHAIN_NAMESPACE2.Evm;
|
|
634
651
|
};
|
|
635
652
|
var getEvmNetworkId = (chainId) => {
|
|
636
|
-
const { chainReference } =
|
|
653
|
+
const { chainReference } = fromChainId2(chainId);
|
|
637
654
|
return parseInt(chainReference, 10);
|
|
638
655
|
};
|
|
639
656
|
var getChainType = (chainId) => {
|
|
640
|
-
const { chainNamespace } =
|
|
657
|
+
const { chainNamespace } = fromChainId2(chainId);
|
|
641
658
|
switch (chainNamespace) {
|
|
642
|
-
case
|
|
659
|
+
case CHAIN_NAMESPACE2.Evm:
|
|
643
660
|
return "evm";
|
|
644
|
-
case
|
|
661
|
+
case CHAIN_NAMESPACE2.Utxo:
|
|
645
662
|
return "utxo";
|
|
646
|
-
case
|
|
663
|
+
case CHAIN_NAMESPACE2.CosmosSdk:
|
|
647
664
|
return "cosmos";
|
|
648
|
-
case
|
|
665
|
+
case CHAIN_NAMESPACE2.Solana:
|
|
649
666
|
return "solana";
|
|
650
667
|
default:
|
|
651
668
|
return "other";
|
|
@@ -723,11 +740,13 @@ var createInitialContext = (input) => {
|
|
|
723
740
|
selectedRate: null,
|
|
724
741
|
quote: null,
|
|
725
742
|
txHash: null,
|
|
743
|
+
depositObservedAt: null,
|
|
726
744
|
approvalTxHash: null,
|
|
727
745
|
error: null,
|
|
728
746
|
errorSource: null,
|
|
729
747
|
retryCount: 0,
|
|
730
748
|
chainType: sellChainType,
|
|
749
|
+
isDepositFlow: false,
|
|
731
750
|
slippage: input?.slippage ?? "0.5",
|
|
732
751
|
sendAddress: void 0,
|
|
733
752
|
receiveAddress: void 0,
|
|
@@ -750,6 +769,15 @@ var swapMachine = setup({
|
|
|
750
769
|
const namespace = context.sellAsset.assetId.split("/")[1]?.split(":")[0];
|
|
751
770
|
return namespace === "erc20";
|
|
752
771
|
},
|
|
772
|
+
isDepositQuote: ({ context, event }) => {
|
|
773
|
+
const { quote } = event;
|
|
774
|
+
return context.isDepositFlow && !!quote?.depositAddress;
|
|
775
|
+
},
|
|
776
|
+
isDepositFlowWithoutAddress: ({ context, event }) => {
|
|
777
|
+
const { quote } = event;
|
|
778
|
+
return context.isDepositFlow && !quote?.depositAddress;
|
|
779
|
+
},
|
|
780
|
+
isRestoredDepositFunded: ({ event }) => !!event.txHash,
|
|
753
781
|
canRetry: ({ context }) => canRetry(context),
|
|
754
782
|
isQuoteError: ({ context }) => context.errorSource === "QUOTE_ERROR",
|
|
755
783
|
isApprovalError: ({ context }) => context.errorSource === "APPROVAL_ERROR",
|
|
@@ -831,6 +859,54 @@ var swapMachine = setup({
|
|
|
831
859
|
assignTxHash: assign(({ event }) => ({
|
|
832
860
|
txHash: event.txHash
|
|
833
861
|
})),
|
|
862
|
+
assignDepositFlow: assign(({ event }) => ({
|
|
863
|
+
isDepositFlow: event.isDepositFlow === true
|
|
864
|
+
})),
|
|
865
|
+
assignDepositTxHash: assign(({ event }) => {
|
|
866
|
+
const { txHash, observedAt } = event;
|
|
867
|
+
return { txHash, depositObservedAt: observedAt };
|
|
868
|
+
}),
|
|
869
|
+
assignDepositUnavailableError: assign(() => ({
|
|
870
|
+
error: "This route needs a connected wallet",
|
|
871
|
+
errorSource: "QUOTE_ERROR"
|
|
872
|
+
})),
|
|
873
|
+
assignTrackingTimeout: assign(() => ({
|
|
874
|
+
error: "Check your receive address - the provider may still settle this swap",
|
|
875
|
+
errorSource: "TRACKING_TIMEOUT"
|
|
876
|
+
})),
|
|
877
|
+
assignRestoredDeposit: assign(({ event }) => {
|
|
878
|
+
const {
|
|
879
|
+
quote,
|
|
880
|
+
sendAddress,
|
|
881
|
+
receiveAddress,
|
|
882
|
+
sellAmountBaseUnit,
|
|
883
|
+
buyAmountBaseUnit,
|
|
884
|
+
txHash,
|
|
885
|
+
depositObservedAt
|
|
886
|
+
} = event;
|
|
887
|
+
const { sellAsset, buyAsset } = quote;
|
|
888
|
+
return {
|
|
889
|
+
quote,
|
|
890
|
+
sendAddress,
|
|
891
|
+
receiveAddress,
|
|
892
|
+
txHash: txHash ?? null,
|
|
893
|
+
depositObservedAt: depositObservedAt ?? null,
|
|
894
|
+
isDepositFlow: true,
|
|
895
|
+
sellAsset,
|
|
896
|
+
buyAsset,
|
|
897
|
+
sellAmountBaseUnit,
|
|
898
|
+
sellAmount: sellAmountBaseUnit ? formatAmountForInput(sellAmountBaseUnit, sellAsset.precision) : "",
|
|
899
|
+
buyAmountBaseUnit,
|
|
900
|
+
buyAmount: buyAmountBaseUnit ? formatAmountForInput(buyAmountBaseUnit, buyAsset.precision) : "",
|
|
901
|
+
chainType: getChainType(sellAsset.chainId),
|
|
902
|
+
isSellAssetEvm: isWidgetExecutableEvmChainId(sellAsset.chainId),
|
|
903
|
+
isSellAssetUtxo: isWidgetExecutableUtxoChainId(sellAsset.chainId),
|
|
904
|
+
isSellAssetSolana: isWidgetExecutableSolanaChainId(sellAsset.chainId),
|
|
905
|
+
isBuyAssetEvm: getChainType(buyAsset.chainId) === "evm",
|
|
906
|
+
error: null,
|
|
907
|
+
errorSource: null
|
|
908
|
+
};
|
|
909
|
+
}),
|
|
834
910
|
assignExecuteError: assign(({ event }) => ({
|
|
835
911
|
error: event.error,
|
|
836
912
|
errorSource: "EXECUTE_ERROR"
|
|
@@ -871,16 +947,22 @@ var swapMachine = setup({
|
|
|
871
947
|
incrementRetryCount: assign(({ context }) => ({
|
|
872
948
|
retryCount: context.retryCount + 1,
|
|
873
949
|
error: null,
|
|
874
|
-
errorSource: null
|
|
950
|
+
errorSource: null,
|
|
951
|
+
// Every retry re-quotes or re-signs, so a carried-over hash would mark the next one funded
|
|
952
|
+
txHash: null,
|
|
953
|
+
depositObservedAt: null,
|
|
954
|
+
approvalTxHash: null
|
|
875
955
|
})),
|
|
876
956
|
resetSwapState: assign(({ context }) => ({
|
|
877
957
|
quote: null,
|
|
878
958
|
txHash: null,
|
|
959
|
+
depositObservedAt: null,
|
|
879
960
|
approvalTxHash: null,
|
|
880
961
|
error: null,
|
|
881
962
|
errorSource: null,
|
|
882
963
|
retryCount: 0,
|
|
883
964
|
selectedRate: null,
|
|
965
|
+
isDepositFlow: false,
|
|
884
966
|
sellAsset: context.sellAsset,
|
|
885
967
|
buyAsset: context.buyAsset,
|
|
886
968
|
sellAmount: context.sellAmount,
|
|
@@ -912,15 +994,34 @@ var swapMachine = setup({
|
|
|
912
994
|
SET_SEND_ADDRESS: { actions: "assignSendAddress" },
|
|
913
995
|
SET_RECEIVE_ADDRESS: { actions: "assignReceiveAddress" },
|
|
914
996
|
UPDATE_CHAIN_INFO: { actions: "assignChainInfo" },
|
|
997
|
+
RESTORE_DEPOSIT: [
|
|
998
|
+
{
|
|
999
|
+
target: "polling_status",
|
|
1000
|
+
guard: "isRestoredDepositFunded",
|
|
1001
|
+
actions: "assignRestoredDeposit"
|
|
1002
|
+
},
|
|
1003
|
+
{ target: "awaiting_deposit", actions: "assignRestoredDeposit" }
|
|
1004
|
+
],
|
|
915
1005
|
FETCH_QUOTE: {
|
|
916
1006
|
target: "quoting",
|
|
917
|
-
guard: "hasValidInput"
|
|
1007
|
+
guard: "hasValidInput",
|
|
1008
|
+
actions: "assignDepositFlow"
|
|
918
1009
|
}
|
|
919
1010
|
}
|
|
920
1011
|
},
|
|
921
1012
|
quoting: {
|
|
922
1013
|
on: {
|
|
923
1014
|
QUOTE_SUCCESS: [
|
|
1015
|
+
{
|
|
1016
|
+
target: "awaiting_deposit",
|
|
1017
|
+
guard: "isDepositQuote",
|
|
1018
|
+
actions: "assignQuote"
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
target: "error",
|
|
1022
|
+
guard: "isDepositFlowWithoutAddress",
|
|
1023
|
+
actions: "assignDepositUnavailableError"
|
|
1024
|
+
},
|
|
924
1025
|
{
|
|
925
1026
|
target: "approval_needed",
|
|
926
1027
|
guard: "isApprovalRequired",
|
|
@@ -967,13 +1068,39 @@ var swapMachine = setup({
|
|
|
967
1068
|
}
|
|
968
1069
|
}
|
|
969
1070
|
},
|
|
1071
|
+
// Both deposit states take a terminal status - a provider can settle or refund without a hash
|
|
1072
|
+
awaiting_deposit: {
|
|
1073
|
+
on: {
|
|
1074
|
+
DEPOSIT_DETECTED: { target: "polling_status", actions: "assignDepositTxHash" },
|
|
1075
|
+
DEPOSIT_EXPIRED: { target: "deposit_expired" },
|
|
1076
|
+
STATUS_CONFIRMED: { target: "complete" },
|
|
1077
|
+
STATUS_FAILED: { target: "error", actions: "assignStatusFailed" },
|
|
1078
|
+
RESET: { target: "input", actions: "resetSwapState" }
|
|
1079
|
+
}
|
|
1080
|
+
},
|
|
1081
|
+
deposit_expired: {
|
|
1082
|
+
on: {
|
|
1083
|
+
DEPOSIT_DETECTED: { target: "polling_status", actions: "assignDepositTxHash" },
|
|
1084
|
+
STATUS_CONFIRMED: { target: "complete" },
|
|
1085
|
+
STATUS_FAILED: { target: "error", actions: "assignStatusFailed" },
|
|
1086
|
+
RETRY: { target: "quoting", actions: "incrementRetryCount" },
|
|
1087
|
+
RESET: { target: "input", actions: "resetSwapState" }
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
970
1090
|
polling_status: {
|
|
971
1091
|
on: {
|
|
972
1092
|
STATUS_CONFIRMED: { target: "complete" },
|
|
973
1093
|
STATUS_FAILED: {
|
|
974
1094
|
target: "error",
|
|
975
1095
|
actions: "assignStatusFailed"
|
|
976
|
-
}
|
|
1096
|
+
},
|
|
1097
|
+
// The one deposit screen with no controls of its own, so it can't be left spinning
|
|
1098
|
+
DEPOSIT_TRACKING_TIMEOUT: {
|
|
1099
|
+
target: "error",
|
|
1100
|
+
actions: "assignTrackingTimeout"
|
|
1101
|
+
},
|
|
1102
|
+
// A deposit swap settles server-side whether or not anyone watches it
|
|
1103
|
+
RESET: { target: "input", actions: "resetSwapState" }
|
|
977
1104
|
}
|
|
978
1105
|
},
|
|
979
1106
|
complete: {
|
|
@@ -1014,6 +1141,114 @@ var swapMachine = setup({
|
|
|
1014
1141
|
// src/machines/SwapMachineContext.ts
|
|
1015
1142
|
var SwapMachineCtx = createActorContext(swapMachine);
|
|
1016
1143
|
|
|
1144
|
+
// src/utils/depositStatus.ts
|
|
1145
|
+
var resolveDepositStatusEvent = (response, hasDetectedDeposit, observedAt) => {
|
|
1146
|
+
if (!hasDetectedDeposit && response.txHash) {
|
|
1147
|
+
return { type: "DEPOSIT_DETECTED", txHash: response.txHash, observedAt };
|
|
1148
|
+
}
|
|
1149
|
+
if (response.status === "failed") return { type: "STATUS_FAILED", error: "Swap failed" };
|
|
1150
|
+
if (response.status === "confirmed") return { type: "STATUS_CONFIRMED" };
|
|
1151
|
+
};
|
|
1152
|
+
var UNFUNDED_DEPOSIT_TRACKING_MS = 60 * 60 * 1e3;
|
|
1153
|
+
var SETTLEMENT_TRACKING_MS = 24 * 60 * 60 * 1e3;
|
|
1154
|
+
var shouldKeepTrackingDeposit = ({
|
|
1155
|
+
quoteDeadline,
|
|
1156
|
+
depositObservedAt,
|
|
1157
|
+
now
|
|
1158
|
+
}) => depositObservedAt ? now <= depositObservedAt + SETTLEMENT_TRACKING_MS : now <= quoteDeadline + UNFUNDED_DEPOSIT_TRACKING_MS;
|
|
1159
|
+
|
|
1160
|
+
// src/hooks/useDepositPolling.ts
|
|
1161
|
+
var POLL_INTERVAL_MS = 1e4;
|
|
1162
|
+
var isQuoteNotFound = (error) => error instanceof ApiError && error.code === "QUOTE_NOT_FOUND";
|
|
1163
|
+
var useDepositPolling = ({ apiClient }) => {
|
|
1164
|
+
const stateValue = SwapMachineCtx.useSelector((s) => s.value);
|
|
1165
|
+
const actorRef = SwapMachineCtx.useActorRef();
|
|
1166
|
+
const pollingRef = useRef2(false);
|
|
1167
|
+
useEffect2(() => {
|
|
1168
|
+
const snap = actorRef.getSnapshot();
|
|
1169
|
+
const isDepositTracking = snap.context.isDepositFlow && (snap.matches("awaiting_deposit") || snap.matches("deposit_expired") || snap.matches("polling_status"));
|
|
1170
|
+
if (!isDepositTracking) {
|
|
1171
|
+
pollingRef.current = false;
|
|
1172
|
+
return;
|
|
1173
|
+
}
|
|
1174
|
+
if (pollingRef.current) return;
|
|
1175
|
+
pollingRef.current = true;
|
|
1176
|
+
let stopped = false;
|
|
1177
|
+
let timer;
|
|
1178
|
+
const depositObservedAt = snap.context.depositObservedAt ?? void 0;
|
|
1179
|
+
const poll = async () => {
|
|
1180
|
+
if (stopped) return;
|
|
1181
|
+
const quoteId = actorRef.getSnapshot().context.quote?.quoteId;
|
|
1182
|
+
if (quoteId) {
|
|
1183
|
+
try {
|
|
1184
|
+
const response = await apiClient.getSwapStatus({ quoteId });
|
|
1185
|
+
if (stopped) return;
|
|
1186
|
+
const event = resolveDepositStatusEvent(response, !!depositObservedAt, Date.now());
|
|
1187
|
+
if (event) {
|
|
1188
|
+
actorRef.send(event);
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
} catch (error) {
|
|
1192
|
+
if (stopped) return;
|
|
1193
|
+
if (isQuoteNotFound(error)) {
|
|
1194
|
+
actorRef.send(
|
|
1195
|
+
depositObservedAt ? { type: "DEPOSIT_TRACKING_TIMEOUT" } : { type: "DEPOSIT_EXPIRED" }
|
|
1196
|
+
);
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
const { quote } = actorRef.getSnapshot().context;
|
|
1202
|
+
if (quote && !shouldKeepTrackingDeposit({
|
|
1203
|
+
quoteDeadline: quote.expiresAt,
|
|
1204
|
+
depositObservedAt,
|
|
1205
|
+
now: Date.now()
|
|
1206
|
+
})) {
|
|
1207
|
+
actorRef.send({ type: "DEPOSIT_TRACKING_TIMEOUT" });
|
|
1208
|
+
return;
|
|
1209
|
+
}
|
|
1210
|
+
timer = setTimeout(poll, POLL_INTERVAL_MS);
|
|
1211
|
+
};
|
|
1212
|
+
poll();
|
|
1213
|
+
return () => {
|
|
1214
|
+
stopped = true;
|
|
1215
|
+
pollingRef.current = false;
|
|
1216
|
+
clearTimeout(timer);
|
|
1217
|
+
};
|
|
1218
|
+
}, [stateValue]);
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1221
|
+
// src/hooks/useEvmSigning.ts
|
|
1222
|
+
import { useAppKitAccount as useAppKitAccount2, useAppKitProvider as useAppKitProvider2 } from "@reown/appkit/react";
|
|
1223
|
+
import { useMemo as useMemo2 } from "react";
|
|
1224
|
+
import { createWalletClient, custom, getAddress, isAddress } from "viem";
|
|
1225
|
+
var useEvmSigning = () => {
|
|
1226
|
+
const { walletProvider } = useAppKitProvider2("eip155");
|
|
1227
|
+
const { address, isConnected } = useAppKitAccount2({ namespace: "eip155" });
|
|
1228
|
+
const checksummedAddress = useMemo2(() => {
|
|
1229
|
+
if (!address || !isAddress(address)) return void 0;
|
|
1230
|
+
return getAddress(address);
|
|
1231
|
+
}, [address]);
|
|
1232
|
+
const walletClient = useMemo2(() => {
|
|
1233
|
+
if (!walletProvider || !checksummedAddress) return void 0;
|
|
1234
|
+
return createWalletClient({
|
|
1235
|
+
account: checksummedAddress,
|
|
1236
|
+
transport: custom(walletProvider)
|
|
1237
|
+
});
|
|
1238
|
+
}, [walletProvider, checksummedAddress]);
|
|
1239
|
+
return useMemo2(
|
|
1240
|
+
() => ({
|
|
1241
|
+
walletClient,
|
|
1242
|
+
address: checksummedAddress,
|
|
1243
|
+
isConnected: !!(isConnected && checksummedAddress)
|
|
1244
|
+
}),
|
|
1245
|
+
[walletClient, checksummedAddress, isConnected]
|
|
1246
|
+
);
|
|
1247
|
+
};
|
|
1248
|
+
|
|
1249
|
+
// src/hooks/useSellFiatSync.ts
|
|
1250
|
+
import { useEffect as useEffect3 } from "react";
|
|
1251
|
+
|
|
1017
1252
|
// src/utils/fiatConversion.ts
|
|
1018
1253
|
import { BigAmount as BigAmount2, bn } from "@shapeshiftoss/utils";
|
|
1019
1254
|
var fiatToCrypto = (fiat, price, precision) => {
|
|
@@ -1050,7 +1285,7 @@ var useSellFiatSync = (sellAssetUsdPrice) => {
|
|
|
1050
1285
|
const sellAmountFiat = SwapMachineCtx.useSelector((s) => s.context.sellAmountFiat);
|
|
1051
1286
|
const sellAmountBaseUnit = SwapMachineCtx.useSelector((s) => s.context.sellAmountBaseUnit);
|
|
1052
1287
|
const sellPrecision = SwapMachineCtx.useSelector((s) => s.context.sellAsset.precision);
|
|
1053
|
-
|
|
1288
|
+
useEffect3(() => {
|
|
1054
1289
|
const action = computeSellFiatSyncAction({
|
|
1055
1290
|
isSellAmountFiat,
|
|
1056
1291
|
sellAmountFiat,
|
|
@@ -1072,12 +1307,12 @@ var useSellFiatSync = (sellAssetUsdPrice) => {
|
|
|
1072
1307
|
// src/hooks/useSolanaSigning.ts
|
|
1073
1308
|
import { useAppKitProvider as useAppKitProvider3 } from "@reown/appkit/react";
|
|
1074
1309
|
import { useAppKitConnection } from "@reown/appkit-adapter-solana/react";
|
|
1075
|
-
import { useCallback as
|
|
1310
|
+
import { useCallback as useCallback3, useMemo as useMemo3, useState as useState3 } from "react";
|
|
1076
1311
|
var useSolanaSigning = () => {
|
|
1077
1312
|
const { walletProvider } = useAppKitProvider3("solana");
|
|
1078
1313
|
const provider = walletProvider;
|
|
1079
1314
|
const { connection } = useAppKitConnection();
|
|
1080
|
-
const [state, setState] =
|
|
1315
|
+
const [state, setState] = useState3({
|
|
1081
1316
|
isLoading: false,
|
|
1082
1317
|
error: void 0,
|
|
1083
1318
|
signature: void 0
|
|
@@ -1097,7 +1332,7 @@ var useSolanaSigning = () => {
|
|
|
1097
1332
|
return void 0;
|
|
1098
1333
|
}
|
|
1099
1334
|
}, [provider]);
|
|
1100
|
-
const sendTransaction =
|
|
1335
|
+
const sendTransaction = useCallback3(
|
|
1101
1336
|
async (params) => {
|
|
1102
1337
|
if (!provider?.sendTransaction) {
|
|
1103
1338
|
throw new Error("Solana wallet not connected");
|
|
@@ -1129,7 +1364,7 @@ var useSolanaSigning = () => {
|
|
|
1129
1364
|
},
|
|
1130
1365
|
[provider, connection]
|
|
1131
1366
|
);
|
|
1132
|
-
const signTransaction =
|
|
1367
|
+
const signTransaction = useCallback3(
|
|
1133
1368
|
async (transaction) => {
|
|
1134
1369
|
if (!provider?.signTransaction) {
|
|
1135
1370
|
throw new Error("Solana wallet not connected or does not support signTransaction");
|
|
@@ -1151,7 +1386,7 @@ var useSolanaSigning = () => {
|
|
|
1151
1386
|
},
|
|
1152
1387
|
[provider]
|
|
1153
1388
|
);
|
|
1154
|
-
const signMessage =
|
|
1389
|
+
const signMessage = useCallback3(
|
|
1155
1390
|
async (params) => {
|
|
1156
1391
|
if (!provider?.signMessage) {
|
|
1157
1392
|
throw new Error("Solana wallet not connected or does not support signMessage");
|
|
@@ -1178,14 +1413,14 @@ var useSolanaSigning = () => {
|
|
|
1178
1413
|
},
|
|
1179
1414
|
[provider]
|
|
1180
1415
|
);
|
|
1181
|
-
const reset =
|
|
1416
|
+
const reset = useCallback3(() => {
|
|
1182
1417
|
setState({
|
|
1183
1418
|
isLoading: false,
|
|
1184
1419
|
error: void 0,
|
|
1185
1420
|
signature: void 0
|
|
1186
1421
|
});
|
|
1187
1422
|
}, []);
|
|
1188
|
-
const checkTxStatus =
|
|
1423
|
+
const checkTxStatus = useCallback3(
|
|
1189
1424
|
(signature) => {
|
|
1190
1425
|
if (!connection) {
|
|
1191
1426
|
return Promise.resolve({
|
|
@@ -1200,7 +1435,7 @@ var useSolanaSigning = () => {
|
|
|
1200
1435
|
},
|
|
1201
1436
|
[connection]
|
|
1202
1437
|
);
|
|
1203
|
-
const waitForConfirmation =
|
|
1438
|
+
const waitForConfirmation = useCallback3(
|
|
1204
1439
|
(signature, commitment = "confirmed") => {
|
|
1205
1440
|
if (!connection) {
|
|
1206
1441
|
return Promise.resolve({
|
|
@@ -1246,24 +1481,18 @@ var useSolanaSigning = () => {
|
|
|
1246
1481
|
};
|
|
1247
1482
|
|
|
1248
1483
|
// src/hooks/useStatusPolling.ts
|
|
1249
|
-
import { useEffect as
|
|
1250
|
-
var
|
|
1251
|
-
var useStatusPolling = ({
|
|
1252
|
-
apiClient,
|
|
1253
|
-
onSwapSuccess,
|
|
1254
|
-
onSwapError,
|
|
1255
|
-
refetchSellBalance,
|
|
1256
|
-
refetchBuyBalance
|
|
1257
|
-
}) => {
|
|
1484
|
+
import { useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
1485
|
+
var POLL_INTERVAL_MS2 = 5e3;
|
|
1486
|
+
var useStatusPolling = ({ apiClient }) => {
|
|
1258
1487
|
const stateValue = SwapMachineCtx.useSelector((s) => s.value);
|
|
1259
1488
|
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
1260
1489
|
const actorRef = SwapMachineCtx.useActorRef();
|
|
1490
|
+
const pollingRef = useRef3(false);
|
|
1261
1491
|
const { solana: solana3 } = useSwapWallet();
|
|
1262
1492
|
const solanaConnection = solana3.connection;
|
|
1263
|
-
|
|
1264
|
-
useEffect2(() => {
|
|
1493
|
+
useEffect4(() => {
|
|
1265
1494
|
const snap = actorRef.getSnapshot();
|
|
1266
|
-
if (!snap.matches("polling_status")) {
|
|
1495
|
+
if (!snap.matches("polling_status") || snap.context.isDepositFlow) {
|
|
1267
1496
|
pollingRef.current = false;
|
|
1268
1497
|
return;
|
|
1269
1498
|
}
|
|
@@ -1316,7 +1545,7 @@ var useStatusPolling = ({
|
|
|
1316
1545
|
actorRef.send({ type: "STATUS_FAILED", error: result.error ?? "Transaction failed" });
|
|
1317
1546
|
return;
|
|
1318
1547
|
}
|
|
1319
|
-
setTimeout(poll,
|
|
1548
|
+
setTimeout(poll, POLL_INTERVAL_MS2);
|
|
1320
1549
|
} catch (err) {
|
|
1321
1550
|
if (stopped) return;
|
|
1322
1551
|
const errorMessage = err instanceof Error ? err.message : "Unknown polling error";
|
|
@@ -1329,36 +1558,10 @@ var useStatusPolling = ({
|
|
|
1329
1558
|
pollingRef.current = false;
|
|
1330
1559
|
};
|
|
1331
1560
|
}, [stateValue]);
|
|
1332
|
-
const completionRef = useRef(false);
|
|
1333
|
-
useEffect2(() => {
|
|
1334
|
-
const snap = actorRef.getSnapshot();
|
|
1335
|
-
if (!snap.matches("complete")) {
|
|
1336
|
-
completionRef.current = false;
|
|
1337
|
-
return;
|
|
1338
|
-
}
|
|
1339
|
-
if (completionRef.current) return;
|
|
1340
|
-
completionRef.current = true;
|
|
1341
|
-
if (context.txHash) {
|
|
1342
|
-
onSwapSuccess?.(context.txHash);
|
|
1343
|
-
}
|
|
1344
|
-
refetchSellBalance?.();
|
|
1345
|
-
refetchBuyBalance?.();
|
|
1346
|
-
}, [stateValue]);
|
|
1347
|
-
const errorRef = useRef(false);
|
|
1348
|
-
useEffect2(() => {
|
|
1349
|
-
const snap = actorRef.getSnapshot();
|
|
1350
|
-
if (!snap.matches("error")) {
|
|
1351
|
-
errorRef.current = false;
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
|
-
if (errorRef.current) return;
|
|
1355
|
-
errorRef.current = true;
|
|
1356
|
-
onSwapError?.(new Error(context.error ?? "Unknown error"));
|
|
1357
|
-
}, [stateValue]);
|
|
1358
1561
|
};
|
|
1359
1562
|
|
|
1360
1563
|
// src/hooks/useSwapApproval.ts
|
|
1361
|
-
import { useEffect as
|
|
1564
|
+
import { useEffect as useEffect5, useRef as useRef4 } from "react";
|
|
1362
1565
|
import { createPublicClient as createPublicClient2, http as http2 } from "viem";
|
|
1363
1566
|
|
|
1364
1567
|
// src/constants/chains.ts
|
|
@@ -1461,8 +1664,8 @@ var useSwapApproval = () => {
|
|
|
1461
1664
|
const actorRef = SwapMachineCtx.useActorRef();
|
|
1462
1665
|
const { evm } = useSwapWallet();
|
|
1463
1666
|
const { walletClient, address: walletAddress } = evm;
|
|
1464
|
-
const approvingRef =
|
|
1465
|
-
|
|
1667
|
+
const approvingRef = useRef4(false);
|
|
1668
|
+
useEffect5(() => {
|
|
1466
1669
|
if (stateValue !== "approving" || approvingRef.current) return;
|
|
1467
1670
|
approvingRef.current = true;
|
|
1468
1671
|
const executeApproval = async () => {
|
|
@@ -1540,10 +1743,50 @@ var useSwapApproval = () => {
|
|
|
1540
1743
|
}, [stateValue]);
|
|
1541
1744
|
};
|
|
1542
1745
|
|
|
1746
|
+
// src/hooks/useSwapCallbacks.ts
|
|
1747
|
+
import { useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
1748
|
+
var useSwapCallbacks = ({
|
|
1749
|
+
onSwapSuccess,
|
|
1750
|
+
onSwapError,
|
|
1751
|
+
refetchSellBalance,
|
|
1752
|
+
refetchBuyBalance
|
|
1753
|
+
}) => {
|
|
1754
|
+
const stateValue = SwapMachineCtx.useSelector((s) => s.value);
|
|
1755
|
+
const actorRef = SwapMachineCtx.useActorRef();
|
|
1756
|
+
const completionRef = useRef5(false);
|
|
1757
|
+
useEffect6(() => {
|
|
1758
|
+
const snap = actorRef.getSnapshot();
|
|
1759
|
+
if (!snap.matches("complete")) {
|
|
1760
|
+
completionRef.current = false;
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
if (completionRef.current) return;
|
|
1764
|
+
completionRef.current = true;
|
|
1765
|
+
if (snap.context.txHash) onSwapSuccess?.(snap.context.txHash);
|
|
1766
|
+
refetchSellBalance?.();
|
|
1767
|
+
refetchBuyBalance?.();
|
|
1768
|
+
}, [stateValue]);
|
|
1769
|
+
const errorRef = useRef5(false);
|
|
1770
|
+
useEffect6(() => {
|
|
1771
|
+
const snap = actorRef.getSnapshot();
|
|
1772
|
+
if (!snap.matches("error")) {
|
|
1773
|
+
errorRef.current = false;
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
if (errorRef.current) return;
|
|
1777
|
+
errorRef.current = true;
|
|
1778
|
+
onSwapError?.(new Error(snap.context.error ?? "Unknown error"));
|
|
1779
|
+
}, [stateValue]);
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1543
1782
|
// src/hooks/useSwapDisplayValues.ts
|
|
1544
1783
|
import { bn as bn3 } from "@shapeshiftoss/utils";
|
|
1545
1784
|
import { useMemo as useMemo5 } from "react";
|
|
1546
1785
|
|
|
1786
|
+
// src/utils/ratesPolling.ts
|
|
1787
|
+
var RATES_CONSUMING_STATES = /* @__PURE__ */ new Set(["idle", "input", "quoting", "error", "deposit_expired"]);
|
|
1788
|
+
var shouldPollRates = (stateValue) => typeof stateValue === "string" && RATES_CONSUMING_STATES.has(stateValue);
|
|
1789
|
+
|
|
1547
1790
|
// src/hooks/useAssets.ts
|
|
1548
1791
|
import { ASSET_NAMESPACE, fromAssetId } from "@shapeshiftoss/caip";
|
|
1549
1792
|
import { useQuery } from "@tanstack/react-query";
|
|
@@ -1663,12 +1906,12 @@ var useAssetSearch = (query, chainId) => {
|
|
|
1663
1906
|
|
|
1664
1907
|
// src/hooks/useBalances.ts
|
|
1665
1908
|
import { useAppKitConnection as useAppKitConnection2 } from "@reown/appkit-adapter-solana/react";
|
|
1666
|
-
import { ASSET_NAMESPACE as ASSET_NAMESPACE2, CHAIN_NAMESPACE as
|
|
1909
|
+
import { ASSET_NAMESPACE as ASSET_NAMESPACE2, CHAIN_NAMESPACE as CHAIN_NAMESPACE3, fromAssetId as fromAssetId2 } from "@shapeshiftoss/caip";
|
|
1667
1910
|
import { Connection, PublicKey } from "@solana/web3.js";
|
|
1668
1911
|
import { useQueries, useQueryClient } from "@tanstack/react-query";
|
|
1669
1912
|
import { getBalance, readContract } from "@wagmi/core";
|
|
1670
1913
|
import PQueue from "p-queue";
|
|
1671
|
-
import { useCallback as
|
|
1914
|
+
import { useCallback as useCallback4, useMemo as useMemo4 } from "react";
|
|
1672
1915
|
import { erc20Abi as erc20Abi2 } from "viem";
|
|
1673
1916
|
import { useConfig } from "wagmi";
|
|
1674
1917
|
var CONCURRENCY_LIMIT = 5;
|
|
@@ -1685,7 +1928,7 @@ var parseAssetIdMultiChain = (assetId) => {
|
|
|
1685
1928
|
const { chainNamespace, chainReference, assetNamespace, assetReference } = fromAssetId2(assetId);
|
|
1686
1929
|
const chainId = assetId.split("/")[0];
|
|
1687
1930
|
const chainType = isWidgetExecutableEvmChainId(chainId) ? "evm" : isWidgetExecutableUtxoChainId(chainId) ? "utxo" : isWidgetExecutableSolanaChainId(chainId) ? "solana" : void 0;
|
|
1688
|
-
if (chainType === "evm" && chainNamespace ===
|
|
1931
|
+
if (chainType === "evm" && chainNamespace === CHAIN_NAMESPACE3.Evm) {
|
|
1689
1932
|
const evmChainId = Number(chainReference);
|
|
1690
1933
|
if (assetNamespace === ASSET_NAMESPACE2.erc20) {
|
|
1691
1934
|
return {
|
|
@@ -1696,10 +1939,10 @@ var parseAssetIdMultiChain = (assetId) => {
|
|
|
1696
1939
|
}
|
|
1697
1940
|
return { chainType: "evm", evmChainId };
|
|
1698
1941
|
}
|
|
1699
|
-
if (chainType === "utxo" && chainNamespace ===
|
|
1942
|
+
if (chainType === "utxo" && chainNamespace === CHAIN_NAMESPACE3.Utxo) {
|
|
1700
1943
|
return { chainType: "utxo", chainReference };
|
|
1701
1944
|
}
|
|
1702
|
-
if (chainType === "solana" && chainNamespace ===
|
|
1945
|
+
if (chainType === "solana" && chainNamespace === CHAIN_NAMESPACE3.Solana) {
|
|
1703
1946
|
if (assetNamespace === ASSET_NAMESPACE2.splToken) {
|
|
1704
1947
|
return { chainType: "solana", tokenAddress: assetReference };
|
|
1705
1948
|
}
|
|
@@ -2112,7 +2355,7 @@ var useMultiChainBalances = (evmAddress, utxoAddress, solanaAddress, assetIds, a
|
|
|
2112
2355
|
});
|
|
2113
2356
|
return loading;
|
|
2114
2357
|
}, [evmQueries, utxoQueries, solanaQueries, groupedAssets]);
|
|
2115
|
-
const refetch =
|
|
2358
|
+
const refetch = useCallback4(() => {
|
|
2116
2359
|
queryClient2.invalidateQueries({
|
|
2117
2360
|
predicate: (query) => {
|
|
2118
2361
|
const key = query.queryKey;
|
|
@@ -2120,7 +2363,7 @@ var useMultiChainBalances = (evmAddress, utxoAddress, solanaAddress, assetIds, a
|
|
|
2120
2363
|
}
|
|
2121
2364
|
});
|
|
2122
2365
|
}, [queryClient2]);
|
|
2123
|
-
const refetchSpecific =
|
|
2366
|
+
const refetchSpecific = useCallback4(
|
|
2124
2367
|
(targetAssetIds) => {
|
|
2125
2368
|
queryClient2.invalidateQueries({
|
|
2126
2369
|
predicate: (query) => {
|
|
@@ -2355,15 +2598,8 @@ var useSwapDisplayValues = ({
|
|
|
2355
2598
|
ratesRefetchInterval
|
|
2356
2599
|
}) => {
|
|
2357
2600
|
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
2358
|
-
const
|
|
2359
|
-
|
|
2360
|
-
buyAsset,
|
|
2361
|
-
buyAmountBaseUnit,
|
|
2362
|
-
isSellAssetEvm,
|
|
2363
|
-
isSellAssetUtxo,
|
|
2364
|
-
isSellAssetSolana,
|
|
2365
|
-
selectedRate
|
|
2366
|
-
} = context;
|
|
2601
|
+
const isPollingRates = SwapMachineCtx.useSelector((s) => shouldPollRates(s.value));
|
|
2602
|
+
const { sellAsset, buyAsset, buyAmountBaseUnit, selectedRate } = context;
|
|
2367
2603
|
const { receiveAddress, isReceiveAddressBlocked, evm, bitcoin: bitcoin3, solana: solana3 } = useSwapWallet();
|
|
2368
2604
|
const evmAddress = evm.address;
|
|
2369
2605
|
const bitcoinAddress = bitcoin3.address;
|
|
@@ -2383,7 +2619,7 @@ var useSwapDisplayValues = ({
|
|
|
2383
2619
|
allowedSwapperNames,
|
|
2384
2620
|
refetchInterval: ratesRefetchInterval,
|
|
2385
2621
|
// Rates need no destination, but a locked one the buy chain rejects can never be quoted
|
|
2386
|
-
enabled: !!amountBaseUnit && amountBaseUnit !== "0" && !isReceiveAddressBlocked
|
|
2622
|
+
enabled: isPollingRates && !!amountBaseUnit && amountBaseUnit !== "0" && !isReceiveAddressBlocked
|
|
2387
2623
|
});
|
|
2388
2624
|
const {
|
|
2389
2625
|
data: sellAssetBalance,
|
|
@@ -2515,7 +2751,7 @@ var useSwapDisplayValues = ({
|
|
|
2515
2751
|
};
|
|
2516
2752
|
|
|
2517
2753
|
// src/hooks/useSwapExecution.ts
|
|
2518
|
-
import { useEffect as
|
|
2754
|
+
import { useEffect as useEffect7, useRef as useRef6 } from "react";
|
|
2519
2755
|
import { getAddress as getAddress2 } from "viem";
|
|
2520
2756
|
var executeEvm = async (txData, walletClient, walletAddress) => {
|
|
2521
2757
|
if (!walletClient || !walletAddress) throw new Error("No wallet connected");
|
|
@@ -2617,8 +2853,8 @@ var useSwapExecution = () => {
|
|
|
2617
2853
|
const actorRef = SwapMachineCtx.useActorRef();
|
|
2618
2854
|
const { evm, bitcoin: bitcoin3, solana: solana3 } = useSwapWallet();
|
|
2619
2855
|
const { walletClient, address: walletAddress } = evm;
|
|
2620
|
-
const executingRef =
|
|
2621
|
-
|
|
2856
|
+
const executingRef = useRef6(false);
|
|
2857
|
+
useEffect7(() => {
|
|
2622
2858
|
if (stateValue !== "executing" || executingRef.current) return;
|
|
2623
2859
|
executingRef.current = true;
|
|
2624
2860
|
const executeSwap = async () => {
|
|
@@ -2684,7 +2920,7 @@ var useSwapExecution = () => {
|
|
|
2684
2920
|
|
|
2685
2921
|
// src/hooks/useSwapHandlers.ts
|
|
2686
2922
|
import { useAppKit } from "@reown/appkit/react";
|
|
2687
|
-
import { useCallback as
|
|
2923
|
+
import { useCallback as useCallback5 } from "react";
|
|
2688
2924
|
|
|
2689
2925
|
// src/utils/redirect.ts
|
|
2690
2926
|
var SHAPESHIFT_APP_URL = "https://app.shapeshift.com";
|
|
@@ -2709,25 +2945,25 @@ var useSwapHandlers = ({
|
|
|
2709
2945
|
const actorRef = SwapMachineCtx.useActorRef();
|
|
2710
2946
|
const { evm, bitcoin: bitcoin3, solana: solana3 } = useSwapWallet();
|
|
2711
2947
|
const { open: openAppKit } = useAppKit();
|
|
2712
|
-
const handleSwapTokens =
|
|
2948
|
+
const handleSwapTokens = useCallback5(() => {
|
|
2713
2949
|
const snap = actorRef.getSnapshot();
|
|
2714
2950
|
actorRef.send({ type: "SET_SELL_ASSET", asset: snap.context.buyAsset });
|
|
2715
2951
|
actorRef.send({ type: "SET_BUY_ASSET", asset: snap.context.sellAsset });
|
|
2716
2952
|
actorRef.send({ type: "SET_SELL_AMOUNT", amount: "", amountBaseUnit: void 0, fiatValue: "" });
|
|
2717
2953
|
}, [actorRef]);
|
|
2718
|
-
const handleSellAssetSelect =
|
|
2954
|
+
const handleSellAssetSelect = useCallback5(
|
|
2719
2955
|
(asset) => {
|
|
2720
2956
|
actorRef.send({ type: "SET_SELL_ASSET", asset });
|
|
2721
2957
|
},
|
|
2722
2958
|
[actorRef]
|
|
2723
2959
|
);
|
|
2724
|
-
const handleBuyAssetSelect =
|
|
2960
|
+
const handleBuyAssetSelect = useCallback5(
|
|
2725
2961
|
(asset) => {
|
|
2726
2962
|
actorRef.send({ type: "SET_BUY_ASSET", asset });
|
|
2727
2963
|
},
|
|
2728
2964
|
[actorRef]
|
|
2729
2965
|
);
|
|
2730
|
-
const handleSellAmountChange =
|
|
2966
|
+
const handleSellAmountChange = useCallback5(
|
|
2731
2967
|
(value, sellAssetUsdPrice) => {
|
|
2732
2968
|
const snap = actorRef.getSnapshot();
|
|
2733
2969
|
const { sellAsset, isSellAmountFiat } = snap.context;
|
|
@@ -2745,7 +2981,7 @@ var useSwapHandlers = ({
|
|
|
2745
2981
|
},
|
|
2746
2982
|
[actorRef]
|
|
2747
2983
|
);
|
|
2748
|
-
const handleBuyAmountChange =
|
|
2984
|
+
const handleBuyAmountChange = useCallback5(
|
|
2749
2985
|
(value) => {
|
|
2750
2986
|
const { buyAsset } = actorRef.getSnapshot().context;
|
|
2751
2987
|
const amountBaseUnit = value ? parseAmount(value, buyAsset.precision) : void 0;
|
|
@@ -2753,7 +2989,7 @@ var useSwapHandlers = ({
|
|
|
2753
2989
|
},
|
|
2754
2990
|
[actorRef]
|
|
2755
2991
|
);
|
|
2756
|
-
const handleToggleSellFiat =
|
|
2992
|
+
const handleToggleSellFiat = useCallback5(
|
|
2757
2993
|
(sellAssetUsdPrice) => {
|
|
2758
2994
|
if (!sellAssetUsdPrice) return;
|
|
2759
2995
|
const snap = actorRef.getSnapshot();
|
|
@@ -2777,19 +3013,19 @@ var useSwapHandlers = ({
|
|
|
2777
3013
|
},
|
|
2778
3014
|
[actorRef]
|
|
2779
3015
|
);
|
|
2780
|
-
const handleSelectRate =
|
|
3016
|
+
const handleSelectRate = useCallback5(
|
|
2781
3017
|
(rate) => {
|
|
2782
3018
|
actorRef.send({ type: "SELECT_RATE", rate });
|
|
2783
3019
|
},
|
|
2784
3020
|
[actorRef]
|
|
2785
3021
|
);
|
|
2786
|
-
const handleSlippageChange =
|
|
3022
|
+
const handleSlippageChange = useCallback5(
|
|
2787
3023
|
(value) => {
|
|
2788
3024
|
actorRef.send({ type: "SET_SLIPPAGE", slippage: value });
|
|
2789
3025
|
},
|
|
2790
3026
|
[actorRef]
|
|
2791
3027
|
);
|
|
2792
|
-
const redirectToShapeShift =
|
|
3028
|
+
const redirectToShapeShift = useCallback5(() => {
|
|
2793
3029
|
const snap = actorRef.getSnapshot();
|
|
2794
3030
|
const sellAmountBaseUnit = snap.context.sellAmount ? parseAmount(snap.context.sellAmount, snap.context.sellAsset.precision) : void 0;
|
|
2795
3031
|
const url = buildShapeShiftTradeUrl({
|
|
@@ -2800,42 +3036,45 @@ var useSwapHandlers = ({
|
|
|
2800
3036
|
});
|
|
2801
3037
|
window.open(url, "_blank", "noopener,noreferrer");
|
|
2802
3038
|
}, [actorRef, partnerCode]);
|
|
2803
|
-
const handleButtonClick =
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
if (
|
|
2819
|
-
const
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
3039
|
+
const handleButtonClick = useCallback5(
|
|
3040
|
+
(action) => {
|
|
3041
|
+
if (action === "deposit") {
|
|
3042
|
+
actorRef.send({ type: "FETCH_QUOTE", isDepositFlow: true });
|
|
3043
|
+
return;
|
|
3044
|
+
}
|
|
3045
|
+
if (action === "quote") {
|
|
3046
|
+
actorRef.send({ type: "FETCH_QUOTE" });
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
if (action === "redirect") {
|
|
3050
|
+
if (!allowShapeshiftRedirect) return;
|
|
3051
|
+
redirectToShapeShift();
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
if (action !== "connect") return;
|
|
3055
|
+
const snap = actorRef.getSnapshot();
|
|
3056
|
+
if (snap.context.isSellAssetUtxo && !bitcoin3.isConnected) {
|
|
3057
|
+
openAppKit({ namespace: "bip122" });
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
if (snap.context.isSellAssetSolana && !solana3.isConnected) {
|
|
3061
|
+
openAppKit({ namespace: "solana" });
|
|
3062
|
+
return;
|
|
3063
|
+
}
|
|
3064
|
+
if (snap.context.isSellAssetEvm && !evm.isConnected) {
|
|
3065
|
+
openAppKit({ namespace: "eip155" });
|
|
3066
|
+
}
|
|
3067
|
+
},
|
|
3068
|
+
[
|
|
3069
|
+
actorRef,
|
|
3070
|
+
bitcoin3.isConnected,
|
|
3071
|
+
solana3.isConnected,
|
|
3072
|
+
evm.isConnected,
|
|
3073
|
+
openAppKit,
|
|
3074
|
+
allowShapeshiftRedirect,
|
|
3075
|
+
redirectToShapeShift
|
|
3076
|
+
]
|
|
3077
|
+
);
|
|
2839
3078
|
return {
|
|
2840
3079
|
handleSwapTokens,
|
|
2841
3080
|
handleSellAssetSelect,
|
|
@@ -2851,21 +3090,31 @@ var useSwapHandlers = ({
|
|
|
2851
3090
|
};
|
|
2852
3091
|
|
|
2853
3092
|
// src/hooks/useSwapQuoting.ts
|
|
2854
|
-
import { useEffect as
|
|
3093
|
+
import { useEffect as useEffect8, useRef as useRef7 } from "react";
|
|
3094
|
+
|
|
3095
|
+
// src/utils/depositFlow.ts
|
|
3096
|
+
var isExternalPaymentRate = (rate) => rate.supportsExternalPayment === true;
|
|
3097
|
+
var shouldUseDepositFlow = ({
|
|
3098
|
+
rate,
|
|
3099
|
+
hasWalletForSellChain
|
|
3100
|
+
}) => !hasWalletForSellChain && !!rate && isExternalPaymentRate(rate);
|
|
3101
|
+
var pickDepositRate = (rates, swapperName) => rates?.find((rate) => rate.swapperName === swapperName && isExternalPaymentRate(rate)) ?? rates?.find(isExternalPaymentRate);
|
|
3102
|
+
|
|
3103
|
+
// src/hooks/useSwapQuoting.ts
|
|
2855
3104
|
var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
2856
3105
|
const stateValue = SwapMachineCtx.useSelector((s) => s.value);
|
|
2857
3106
|
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
2858
3107
|
const actorRef = SwapMachineCtx.useActorRef();
|
|
2859
3108
|
const { sendAddress, receiveAddress } = useSwapWallet();
|
|
2860
|
-
const quotingRef =
|
|
2861
|
-
|
|
3109
|
+
const quotingRef = useRef7(false);
|
|
3110
|
+
useEffect8(() => {
|
|
2862
3111
|
const snap = actorRef.getSnapshot();
|
|
2863
3112
|
if (!snap.matches("quoting") || quotingRef.current) return;
|
|
2864
3113
|
quotingRef.current = true;
|
|
2865
3114
|
const fetchQuote = async () => {
|
|
2866
3115
|
try {
|
|
2867
3116
|
const isExactOutput2 = !!context.buyAmountBaseUnit;
|
|
2868
|
-
const rateToUse = context.selectedRate ?? rates?.[0];
|
|
3117
|
+
const rateToUse = context.selectedRate ?? (context.isDepositFlow ? pickDepositRate(rates, context.quote?.swapperName) : rates?.[0]);
|
|
2869
3118
|
const sellAmountBaseUnit = isExactOutput2 ? rateToUse?.sellAmountCryptoBaseUnit : context.sellAmountBaseUnit;
|
|
2870
3119
|
if (sellAssetBalance?.balance && sellAmountBaseUnit) {
|
|
2871
3120
|
const balanceBigInt = BigInt(sellAssetBalance.balance);
|
|
@@ -2887,11 +3136,13 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2887
3136
|
return;
|
|
2888
3137
|
}
|
|
2889
3138
|
if (!sendAddress) {
|
|
2890
|
-
actorRef.send({
|
|
3139
|
+
actorRef.send({
|
|
3140
|
+
type: "QUOTE_ERROR",
|
|
3141
|
+
error: context.isDepositFlow ? "No refund address available" : "No wallet address available"
|
|
3142
|
+
});
|
|
2891
3143
|
return;
|
|
2892
3144
|
}
|
|
2893
|
-
|
|
2894
|
-
if (!resolvedReceiveAddress) {
|
|
3145
|
+
if (!receiveAddress) {
|
|
2895
3146
|
actorRef.send({ type: "QUOTE_ERROR", error: "No receive address available" });
|
|
2896
3147
|
return;
|
|
2897
3148
|
}
|
|
@@ -2900,7 +3151,7 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2900
3151
|
buyAssetId: context.buyAsset.assetId,
|
|
2901
3152
|
...isExactOutput2 ? { buyAmountCryptoBaseUnit: amountBaseUnit } : { sellAmountCryptoBaseUnit: amountBaseUnit },
|
|
2902
3153
|
sendAddress,
|
|
2903
|
-
receiveAddress
|
|
3154
|
+
receiveAddress,
|
|
2904
3155
|
swapperName: rateToUse.swapperName,
|
|
2905
3156
|
slippageTolerancePercentageDecimal: slippageDecimal
|
|
2906
3157
|
});
|
|
@@ -2917,25 +3168,31 @@ var useSwapQuoting = ({ apiClient, rates, sellAssetBalance }) => {
|
|
|
2917
3168
|
};
|
|
2918
3169
|
|
|
2919
3170
|
// src/utils/addressValidation.ts
|
|
2920
|
-
import { CHAIN_NAMESPACE as
|
|
3171
|
+
import { CHAIN_NAMESPACE as CHAIN_NAMESPACE4, CHAIN_REFERENCE, fromChainId as fromChainId3 } from "@shapeshiftoss/caip";
|
|
2921
3172
|
import { PublicKey as PublicKey2 } from "@solana/web3.js";
|
|
2922
3173
|
import { bech32, bech32m } from "bech32";
|
|
2923
3174
|
import bs58check from "bs58check";
|
|
2924
3175
|
import { decode as decodeCashAddr } from "cashaddrjs";
|
|
2925
3176
|
import { isAddress as isAddress2 } from "viem";
|
|
2926
3177
|
var VERSION_BYTES = {
|
|
2927
|
-
bitcoinP2PKH: 0,
|
|
2928
|
-
bitcoinP2SH: 5,
|
|
2929
|
-
litecoinP2PKH: 48,
|
|
2930
|
-
litecoinP2SH: 50,
|
|
2931
|
-
litecoinP2SHLegacy: 5,
|
|
2932
|
-
dogecoinP2PKH: 30,
|
|
2933
|
-
dogecoinP2SH: 22
|
|
2934
|
-
|
|
2935
|
-
|
|
3178
|
+
bitcoinP2PKH: [0],
|
|
3179
|
+
bitcoinP2SH: [5],
|
|
3180
|
+
litecoinP2PKH: [48],
|
|
3181
|
+
litecoinP2SH: [50],
|
|
3182
|
+
litecoinP2SHLegacy: [5],
|
|
3183
|
+
dogecoinP2PKH: [30],
|
|
3184
|
+
dogecoinP2SH: [22],
|
|
3185
|
+
zcashP2PKH: [28, 184],
|
|
3186
|
+
zcashP2SH: [28, 189],
|
|
3187
|
+
tron: [65]
|
|
3188
|
+
};
|
|
3189
|
+
var HASH160_LENGTH = 20;
|
|
3190
|
+
var isValidBase58Check = (address, versionPrefixes) => {
|
|
2936
3191
|
try {
|
|
2937
3192
|
const decoded = bs58check.decode(address);
|
|
2938
|
-
return
|
|
3193
|
+
return versionPrefixes.some(
|
|
3194
|
+
(prefix) => decoded.length === prefix.length + HASH160_LENGTH && prefix.every((byte, index) => decoded[index] === byte)
|
|
3195
|
+
);
|
|
2939
3196
|
} catch {
|
|
2940
3197
|
return false;
|
|
2941
3198
|
}
|
|
@@ -2964,8 +3221,12 @@ var isValidSegwit = (address, expectedHrp) => {
|
|
|
2964
3221
|
if (prefix !== expectedHrp) continue;
|
|
2965
3222
|
if (words.length === 0) continue;
|
|
2966
3223
|
const witnessVersion = words[0];
|
|
3224
|
+
if (witnessVersion > 16) continue;
|
|
2967
3225
|
if (witnessVersion === 0 && codec !== bech32) continue;
|
|
2968
3226
|
if (witnessVersion >= 1 && codec !== bech32m) continue;
|
|
3227
|
+
const program = codec.fromWords(words.slice(1));
|
|
3228
|
+
if (program.length < 2 || program.length > 40) continue;
|
|
3229
|
+
if (witnessVersion === 0 && program.length !== 20 && program.length !== 32) continue;
|
|
2969
3230
|
return true;
|
|
2970
3231
|
} catch {
|
|
2971
3232
|
}
|
|
@@ -2980,7 +3241,46 @@ var isValidLitecoinAddress = (address) => isValidBase58Check(address, [
|
|
|
2980
3241
|
VERSION_BYTES.litecoinP2SHLegacy
|
|
2981
3242
|
]) || isValidSegwit(address, "ltc");
|
|
2982
3243
|
var isValidDogecoinAddress = (address) => isValidBase58Check(address, [VERSION_BYTES.dogecoinP2PKH, VERSION_BYTES.dogecoinP2SH]);
|
|
2983
|
-
var
|
|
3244
|
+
var isValidZcashAddress = (address) => isValidBase58Check(address, [VERSION_BYTES.zcashP2PKH, VERSION_BYTES.zcashP2SH]);
|
|
3245
|
+
var isValidTronAddress = (address) => isValidBase58Check(address, [VERSION_BYTES.tron]);
|
|
3246
|
+
var crc16Xmodem = (data) => {
|
|
3247
|
+
let crc = 0;
|
|
3248
|
+
for (const byte of data) {
|
|
3249
|
+
crc ^= byte << 8;
|
|
3250
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
3251
|
+
crc = crc & 32768 ? (crc << 1 ^ 4129) & 65535 : crc << 1 & 65535;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
return crc;
|
|
3255
|
+
};
|
|
3256
|
+
var TON_TAG_BOUNCEABLE = 17;
|
|
3257
|
+
var TON_TAG_NON_BOUNCEABLE = 81;
|
|
3258
|
+
var isValidTonAddress = (address) => {
|
|
3259
|
+
if (/^(0|-1):[0-9a-fA-F]{64}$/.test(address)) return true;
|
|
3260
|
+
if (!/^[A-Za-z0-9+/_-]{48}$/.test(address)) return false;
|
|
3261
|
+
try {
|
|
3262
|
+
const base64 = address.replace(/-/g, "+").replace(/_/g, "/");
|
|
3263
|
+
const bytes = Uint8Array.from(atob(base64), (character) => character.charCodeAt(0));
|
|
3264
|
+
if (bytes.length !== 36) return false;
|
|
3265
|
+
if (bytes[0] !== TON_TAG_BOUNCEABLE && bytes[0] !== TON_TAG_NON_BOUNCEABLE) return false;
|
|
3266
|
+
if (bytes[1] !== 0 && bytes[1] !== 255) return false;
|
|
3267
|
+
return crc16Xmodem(bytes.subarray(0, 34)) === (bytes[34] << 8 | bytes[35]);
|
|
3268
|
+
} catch {
|
|
3269
|
+
return false;
|
|
3270
|
+
}
|
|
3271
|
+
};
|
|
3272
|
+
var isValidSuiAddress = (address) => /^0x[0-9a-fA-F]{64}$/.test(address);
|
|
3273
|
+
var STARKNET_ADDRESS_BOUND = 2n ** 251n - 256n;
|
|
3274
|
+
var isValidStarknetAddress = (address) => {
|
|
3275
|
+
if (!/^0x[0-9a-fA-F]{1,64}$/.test(address)) return false;
|
|
3276
|
+
const value = BigInt(address);
|
|
3277
|
+
return value > 0n && value < STARKNET_ADDRESS_BOUND;
|
|
3278
|
+
};
|
|
3279
|
+
var isValidNearAddress = (address) => {
|
|
3280
|
+
if (/^[0-9a-f]{64}$/.test(address)) return true;
|
|
3281
|
+
return /^(?=.{2,64}$)[a-z0-9]+([-_.][a-z0-9]+)*$/.test(address);
|
|
3282
|
+
};
|
|
3283
|
+
var UTXO_VALIDATORS = {
|
|
2984
3284
|
[CHAIN_REFERENCE.BitcoinMainnet]: {
|
|
2985
3285
|
check: isValidBitcoinAddress,
|
|
2986
3286
|
label: "Bitcoin",
|
|
@@ -3000,6 +3300,11 @@ var UTXO_VALIDATORS = {
|
|
|
3000
3300
|
check: isValidDogecoinAddress,
|
|
3001
3301
|
label: "Dogecoin",
|
|
3002
3302
|
hint: "D..."
|
|
3303
|
+
},
|
|
3304
|
+
[CHAIN_REFERENCE.ZcashMainnet]: {
|
|
3305
|
+
check: isValidZcashAddress,
|
|
3306
|
+
label: "Zcash",
|
|
3307
|
+
hint: "t1... or t3..."
|
|
3003
3308
|
}
|
|
3004
3309
|
};
|
|
3005
3310
|
var COSMOS_SDK_VALIDATORS = {
|
|
@@ -3010,22 +3315,22 @@ var COSMOS_SDK_VALIDATORS = {
|
|
|
3010
3315
|
var validateAddress = (address, chainId) => {
|
|
3011
3316
|
if (!address) return { valid: false, error: "Address is required" };
|
|
3012
3317
|
const invalid = (label) => ({ valid: false, error: `Invalid ${label} address` });
|
|
3013
|
-
const { chainNamespace, chainReference } =
|
|
3318
|
+
const { chainNamespace, chainReference } = fromChainId3(chainId);
|
|
3014
3319
|
switch (chainNamespace) {
|
|
3015
|
-
case
|
|
3320
|
+
case CHAIN_NAMESPACE4.Evm: {
|
|
3016
3321
|
return isAddress2(address, { strict: false }) ? { valid: true } : invalid("EVM");
|
|
3017
3322
|
}
|
|
3018
|
-
case
|
|
3323
|
+
case CHAIN_NAMESPACE4.Utxo: {
|
|
3019
3324
|
const utxo = UTXO_VALIDATORS[chainReference];
|
|
3020
3325
|
if (!utxo) return { valid: false, error: "Unsupported UTXO chain" };
|
|
3021
3326
|
return utxo.check(address) ? { valid: true } : invalid(utxo.label);
|
|
3022
3327
|
}
|
|
3023
|
-
case
|
|
3328
|
+
case CHAIN_NAMESPACE4.CosmosSdk: {
|
|
3024
3329
|
const cosmosSdk = COSMOS_SDK_VALIDATORS[chainReference];
|
|
3025
3330
|
if (!cosmosSdk) return { valid: false, error: "Unsupported CosmosSdk chain" };
|
|
3026
3331
|
return isValidBech32(address, cosmosSdk.hrp) ? { valid: true } : invalid(cosmosSdk.label);
|
|
3027
3332
|
}
|
|
3028
|
-
case
|
|
3333
|
+
case CHAIN_NAMESPACE4.Solana: {
|
|
3029
3334
|
try {
|
|
3030
3335
|
new PublicKey2(address);
|
|
3031
3336
|
return { valid: true };
|
|
@@ -3033,39 +3338,122 @@ var validateAddress = (address, chainId) => {
|
|
|
3033
3338
|
return invalid("Solana");
|
|
3034
3339
|
}
|
|
3035
3340
|
}
|
|
3341
|
+
case CHAIN_NAMESPACE4.Tron:
|
|
3342
|
+
return isValidTronAddress(address) ? { valid: true } : invalid("Tron");
|
|
3343
|
+
case CHAIN_NAMESPACE4.Sui:
|
|
3344
|
+
return isValidSuiAddress(address) ? { valid: true } : invalid("Sui");
|
|
3345
|
+
case CHAIN_NAMESPACE4.Ton:
|
|
3346
|
+
return isValidTonAddress(address) ? { valid: true } : invalid("TON");
|
|
3347
|
+
case CHAIN_NAMESPACE4.Near: {
|
|
3348
|
+
if (isValidNearAddress(address)) return { valid: true };
|
|
3349
|
+
if (isValidNearAddress(address.toLowerCase())) {
|
|
3350
|
+
return { valid: false, error: "Invalid NEAR address - must be lowercase" };
|
|
3351
|
+
}
|
|
3352
|
+
return invalid("NEAR");
|
|
3353
|
+
}
|
|
3354
|
+
case CHAIN_NAMESPACE4.Starknet:
|
|
3355
|
+
return isValidStarknetAddress(address) ? { valid: true } : invalid("Starknet");
|
|
3036
3356
|
default:
|
|
3037
3357
|
return { valid: false, error: "Unsupported chain type" };
|
|
3038
3358
|
}
|
|
3039
3359
|
};
|
|
3040
3360
|
var getAddressFormatHint = (chainId) => {
|
|
3041
|
-
const { chainNamespace, chainReference } =
|
|
3361
|
+
const { chainNamespace, chainReference } = fromChainId3(chainId);
|
|
3042
3362
|
switch (chainNamespace) {
|
|
3043
|
-
case
|
|
3363
|
+
case CHAIN_NAMESPACE4.Evm:
|
|
3044
3364
|
return "0x...";
|
|
3045
|
-
case
|
|
3365
|
+
case CHAIN_NAMESPACE4.Utxo:
|
|
3046
3366
|
return UTXO_VALIDATORS[chainReference]?.hint ?? "Enter address";
|
|
3047
|
-
case
|
|
3367
|
+
case CHAIN_NAMESPACE4.CosmosSdk: {
|
|
3048
3368
|
const cosmosSdk = COSMOS_SDK_VALIDATORS[chainReference];
|
|
3049
3369
|
return cosmosSdk ? `${cosmosSdk.hrp}1...` : "Enter address";
|
|
3050
3370
|
}
|
|
3051
|
-
case
|
|
3371
|
+
case CHAIN_NAMESPACE4.Solana:
|
|
3052
3372
|
return "Enter Solana address";
|
|
3373
|
+
case CHAIN_NAMESPACE4.Tron:
|
|
3374
|
+
return "T...";
|
|
3375
|
+
case CHAIN_NAMESPACE4.Ton:
|
|
3376
|
+
return "UQ... or EQ...";
|
|
3377
|
+
case CHAIN_NAMESPACE4.Sui:
|
|
3378
|
+
case CHAIN_NAMESPACE4.Starknet:
|
|
3379
|
+
return "0x...";
|
|
3380
|
+
case CHAIN_NAMESPACE4.Near:
|
|
3381
|
+
return "name.near or 64 hex chars";
|
|
3053
3382
|
default:
|
|
3054
3383
|
return "Enter address";
|
|
3055
3384
|
}
|
|
3056
3385
|
};
|
|
3057
3386
|
|
|
3387
|
+
// src/utils/pendingDeposit.ts
|
|
3388
|
+
var STORAGE_KEY = "ssw:pendingDeposit";
|
|
3389
|
+
var isRestorableAsset = (value) => {
|
|
3390
|
+
const asset = value;
|
|
3391
|
+
return typeof asset?.chainId === "string" && typeof asset.precision === "number";
|
|
3392
|
+
};
|
|
3393
|
+
var isPendingDeposit = (value) => {
|
|
3394
|
+
const candidate = value;
|
|
3395
|
+
const quote = candidate?.quote;
|
|
3396
|
+
return !!quote?.depositAddress && typeof quote.quoteId === "string" && typeof quote.expiresAt === "number" && typeof quote.sellAmountCryptoBaseUnit === "string" && typeof quote.buyAmountAfterFeesCryptoBaseUnit === "string" && isRestorableAsset(quote.sellAsset) && isRestorableAsset(quote.buyAsset) && typeof candidate?.refundAddress === "string" && typeof candidate.receiveAddress === "string" && // A funded deposit without its observation time has no settlement window to resume
|
|
3397
|
+
(!candidate.txHash || typeof candidate.depositObservedAt === "number");
|
|
3398
|
+
};
|
|
3399
|
+
var clearPendingDeposit = () => {
|
|
3400
|
+
try {
|
|
3401
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
3402
|
+
} catch {
|
|
3403
|
+
}
|
|
3404
|
+
};
|
|
3405
|
+
var savePendingDeposit = (deposit) => {
|
|
3406
|
+
try {
|
|
3407
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(deposit));
|
|
3408
|
+
} catch {
|
|
3409
|
+
}
|
|
3410
|
+
};
|
|
3411
|
+
var loadPendingDeposit = (now) => {
|
|
3412
|
+
try {
|
|
3413
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
3414
|
+
if (!raw) return;
|
|
3415
|
+
const parsed = JSON.parse(raw);
|
|
3416
|
+
const isRestorable = isPendingDeposit(parsed) && shouldKeepTrackingDeposit({
|
|
3417
|
+
quoteDeadline: parsed.quote.expiresAt,
|
|
3418
|
+
depositObservedAt: parsed.depositObservedAt,
|
|
3419
|
+
now
|
|
3420
|
+
});
|
|
3421
|
+
if (!isRestorable) {
|
|
3422
|
+
clearPendingDeposit();
|
|
3423
|
+
return;
|
|
3424
|
+
}
|
|
3425
|
+
return parsed;
|
|
3426
|
+
} catch {
|
|
3427
|
+
clearPendingDeposit();
|
|
3428
|
+
}
|
|
3429
|
+
};
|
|
3430
|
+
|
|
3058
3431
|
// src/utils/receiveAddress.ts
|
|
3059
3432
|
var resolveReceiveAddress = ({
|
|
3060
3433
|
isLocked,
|
|
3061
3434
|
defaultAddress,
|
|
3435
|
+
defaultAddressChainId,
|
|
3062
3436
|
customAddress,
|
|
3063
3437
|
walletAddress,
|
|
3064
3438
|
buyChainId
|
|
3065
3439
|
}) => {
|
|
3066
3440
|
const isValidForBuyChain = (address) => !!address && validateAddress(address, buyChainId).valid;
|
|
3067
|
-
if (isLocked)
|
|
3068
|
-
|
|
3441
|
+
if (isLocked) {
|
|
3442
|
+
const isUsable = sharesAddressSpace(defaultAddressChainId, buyChainId) && isValidForBuyChain(defaultAddress);
|
|
3443
|
+
return isUsable ? defaultAddress : void 0;
|
|
3444
|
+
}
|
|
3445
|
+
if (isValidForBuyChain(customAddress)) return customAddress;
|
|
3446
|
+
return isValidForBuyChain(walletAddress) ? walletAddress : void 0;
|
|
3447
|
+
};
|
|
3448
|
+
|
|
3449
|
+
// src/utils/sendAddress.ts
|
|
3450
|
+
var resolveSendAddress = ({
|
|
3451
|
+
customAddress,
|
|
3452
|
+
walletAddress,
|
|
3453
|
+
sellChainId
|
|
3454
|
+
}) => {
|
|
3455
|
+
if (walletAddress && validateAddress(walletAddress, sellChainId).valid) return walletAddress;
|
|
3456
|
+
return validateAddress(customAddress, sellChainId).valid ? customAddress : void 0;
|
|
3069
3457
|
};
|
|
3070
3458
|
|
|
3071
3459
|
// src/components/ApprovalStep.tsx
|
|
@@ -3165,10 +3553,373 @@ var ApprovalStep = () => {
|
|
|
3165
3553
|
] });
|
|
3166
3554
|
};
|
|
3167
3555
|
|
|
3556
|
+
// src/components/DepositStep.tsx
|
|
3557
|
+
import { buildPaymentUri } from "@shapeshiftoss/utils";
|
|
3558
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useId, useMemo as useMemo7, useRef as useRef8, useState as useState4 } from "react";
|
|
3559
|
+
|
|
3560
|
+
// src/utils/countdown.ts
|
|
3561
|
+
var formatCountdown = (msRemaining) => {
|
|
3562
|
+
const totalSeconds = Math.max(0, Math.floor(msRemaining / 1e3));
|
|
3563
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
3564
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
3565
|
+
const seconds = totalSeconds % 60;
|
|
3566
|
+
const paddedSeconds = seconds.toString().padStart(2, "0");
|
|
3567
|
+
if (hours === 0) return `${minutes}:${paddedSeconds}`;
|
|
3568
|
+
return `${hours}:${minutes.toString().padStart(2, "0")}:${paddedSeconds}`;
|
|
3569
|
+
};
|
|
3570
|
+
|
|
3571
|
+
// src/components/QrCode.tsx
|
|
3572
|
+
import qrcodeGenerator from "qrcode-generator";
|
|
3573
|
+
import { useMemo as useMemo6 } from "react";
|
|
3574
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
3575
|
+
var LOGO_SCALE = 0.2;
|
|
3576
|
+
var QrCode = ({ value, logo, size = 180 }) => {
|
|
3577
|
+
const { path, dimension } = useMemo6(() => {
|
|
3578
|
+
const qr = qrcodeGenerator(0, "H");
|
|
3579
|
+
qr.addData(value);
|
|
3580
|
+
qr.make();
|
|
3581
|
+
const count = qr.getModuleCount();
|
|
3582
|
+
const margin = 4;
|
|
3583
|
+
const segments = [];
|
|
3584
|
+
for (let row = 0; row < count; row++) {
|
|
3585
|
+
for (let col = 0; col < count; col++) {
|
|
3586
|
+
if (qr.isDark(row, col)) segments.push(`M${col + margin} ${row + margin}h1v1h-1z`);
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
return { path: segments.join(""), dimension: count + margin * 2 };
|
|
3590
|
+
}, [value]);
|
|
3591
|
+
const logoBox = useMemo6(() => {
|
|
3592
|
+
const width = dimension * LOGO_SCALE;
|
|
3593
|
+
const padding = width * 0.12;
|
|
3594
|
+
const plate = width + padding * 2;
|
|
3595
|
+
const offset = (dimension - plate) / 2;
|
|
3596
|
+
return { width, plate, offset, inset: offset + padding, radius: plate * 0.22 };
|
|
3597
|
+
}, [dimension]);
|
|
3598
|
+
return /* @__PURE__ */ jsxs2(
|
|
3599
|
+
"svg",
|
|
3600
|
+
{
|
|
3601
|
+
className: "ssw-qr",
|
|
3602
|
+
width: size,
|
|
3603
|
+
height: size,
|
|
3604
|
+
viewBox: `0 0 ${dimension} ${dimension}`,
|
|
3605
|
+
role: "img",
|
|
3606
|
+
"aria-label": "Deposit address QR code",
|
|
3607
|
+
children: [
|
|
3608
|
+
/* @__PURE__ */ jsx2("rect", { width: dimension, height: dimension, fill: "#ffffff" }),
|
|
3609
|
+
/* @__PURE__ */ jsx2("path", { d: path, fill: "#000000" }),
|
|
3610
|
+
logo && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
3611
|
+
/* @__PURE__ */ jsx2(
|
|
3612
|
+
"rect",
|
|
3613
|
+
{
|
|
3614
|
+
x: logoBox.offset,
|
|
3615
|
+
y: logoBox.offset,
|
|
3616
|
+
width: logoBox.plate,
|
|
3617
|
+
height: logoBox.plate,
|
|
3618
|
+
rx: logoBox.radius,
|
|
3619
|
+
fill: "#ffffff"
|
|
3620
|
+
}
|
|
3621
|
+
),
|
|
3622
|
+
/* @__PURE__ */ jsx2(
|
|
3623
|
+
"image",
|
|
3624
|
+
{
|
|
3625
|
+
x: logoBox.inset,
|
|
3626
|
+
y: logoBox.inset,
|
|
3627
|
+
width: logoBox.width,
|
|
3628
|
+
height: logoBox.width,
|
|
3629
|
+
href: logo,
|
|
3630
|
+
preserveAspectRatio: "xMidYMid meet"
|
|
3631
|
+
}
|
|
3632
|
+
)
|
|
3633
|
+
] })
|
|
3634
|
+
]
|
|
3635
|
+
}
|
|
3636
|
+
);
|
|
3637
|
+
};
|
|
3638
|
+
|
|
3639
|
+
// src/components/DepositStep.tsx
|
|
3640
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
3641
|
+
var CopyField = ({ label, display, value }) => {
|
|
3642
|
+
const [hasCopied, setHasCopied] = useState4(false);
|
|
3643
|
+
const handleCopy = useCallback6(() => {
|
|
3644
|
+
if (!navigator.clipboard) return;
|
|
3645
|
+
navigator.clipboard.writeText(value).then(() => {
|
|
3646
|
+
setHasCopied(true);
|
|
3647
|
+
setTimeout(() => setHasCopied(false), 2e3);
|
|
3648
|
+
}).catch(() => {
|
|
3649
|
+
});
|
|
3650
|
+
}, [value]);
|
|
3651
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-field", children: [
|
|
3652
|
+
/* @__PURE__ */ jsx3("span", { className: "ssw-deposit-field-label", children: label }),
|
|
3653
|
+
/* @__PURE__ */ jsxs3(
|
|
3654
|
+
"button",
|
|
3655
|
+
{
|
|
3656
|
+
className: "ssw-deposit-value",
|
|
3657
|
+
onClick: handleCopy,
|
|
3658
|
+
type: "button",
|
|
3659
|
+
"aria-label": `Copy ${label.toLowerCase()}`,
|
|
3660
|
+
children: [
|
|
3661
|
+
/* @__PURE__ */ jsx3("span", { children: display }),
|
|
3662
|
+
/* @__PURE__ */ jsx3("span", { className: "ssw-deposit-copy", children: hasCopied ? "Copied" : "Copy" })
|
|
3663
|
+
]
|
|
3664
|
+
}
|
|
3665
|
+
)
|
|
3666
|
+
] });
|
|
3667
|
+
};
|
|
3668
|
+
var DepositStep = () => {
|
|
3669
|
+
const context = SwapMachineCtx.useSelector((s) => s.context);
|
|
3670
|
+
const isExpired = SwapMachineCtx.useSelector((s) => s.matches("deposit_expired"));
|
|
3671
|
+
const isRequoting = SwapMachineCtx.useSelector((s) => s.matches("quoting"));
|
|
3672
|
+
const actorRef = SwapMachineCtx.useActorRef();
|
|
3673
|
+
const { quote, sendAddress, receiveAddress } = context;
|
|
3674
|
+
const [msRemaining, setMsRemaining] = useState4(() => quote ? quote.expiresAt - Date.now() : 0);
|
|
3675
|
+
const [isAmountInQr, setIsAmountInQr] = useState4(false);
|
|
3676
|
+
const [isQrInfoOpen, setIsQrInfoOpen] = useState4(false);
|
|
3677
|
+
const [isQrInfoDismissed, setIsQrInfoDismissed] = useState4(false);
|
|
3678
|
+
const qrInfoId = useId();
|
|
3679
|
+
const qrControlsRef = useRef8(null);
|
|
3680
|
+
useEffect9(() => {
|
|
3681
|
+
if (!quote || isRequoting) return;
|
|
3682
|
+
const tick = () => {
|
|
3683
|
+
const remaining = quote.expiresAt - Date.now();
|
|
3684
|
+
setMsRemaining(remaining);
|
|
3685
|
+
if (remaining <= 0 && !isExpired) actorRef.send({ type: "DEPOSIT_EXPIRED" });
|
|
3686
|
+
};
|
|
3687
|
+
tick();
|
|
3688
|
+
const interval = setInterval(tick, 1e3);
|
|
3689
|
+
return () => clearInterval(interval);
|
|
3690
|
+
}, [quote, isExpired, isRequoting, actorRef]);
|
|
3691
|
+
const handleNewSwap = useCallback6(() => actorRef.send({ type: "RESET" }), [actorRef]);
|
|
3692
|
+
const handleNewQuote = useCallback6(() => actorRef.send({ type: "RETRY" }), [actorRef]);
|
|
3693
|
+
const handleShowAddressOnly = useCallback6(() => {
|
|
3694
|
+
setIsAmountInQr(false);
|
|
3695
|
+
setIsQrInfoOpen(false);
|
|
3696
|
+
}, []);
|
|
3697
|
+
const handleShowWithAmount = useCallback6(() => {
|
|
3698
|
+
setIsAmountInQr(true);
|
|
3699
|
+
setIsQrInfoOpen(false);
|
|
3700
|
+
}, []);
|
|
3701
|
+
const handleToggleQrInfo = useCallback6(() => {
|
|
3702
|
+
setIsQrInfoDismissed(false);
|
|
3703
|
+
setIsQrInfoOpen((isOpen) => !isOpen);
|
|
3704
|
+
}, []);
|
|
3705
|
+
const handleResetQrInfo = useCallback6(() => {
|
|
3706
|
+
setIsQrInfoOpen(false);
|
|
3707
|
+
setIsQrInfoDismissed(false);
|
|
3708
|
+
}, []);
|
|
3709
|
+
const handleQrInfoMouseLeave = useCallback6(() => setIsQrInfoDismissed(false), []);
|
|
3710
|
+
useEffect9(() => {
|
|
3711
|
+
const handleKeyDown = (event) => {
|
|
3712
|
+
if (event.key !== "Escape") return;
|
|
3713
|
+
setIsQrInfoOpen(false);
|
|
3714
|
+
if (qrControlsRef.current?.matches(":hover, :focus-within")) setIsQrInfoDismissed(true);
|
|
3715
|
+
};
|
|
3716
|
+
const handlePointerDown = (event) => {
|
|
3717
|
+
if (qrControlsRef.current?.contains(event.target)) return;
|
|
3718
|
+
setIsQrInfoOpen(false);
|
|
3719
|
+
};
|
|
3720
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
3721
|
+
document.addEventListener("pointerdown", handlePointerDown);
|
|
3722
|
+
return () => {
|
|
3723
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
3724
|
+
document.removeEventListener("pointerdown", handlePointerDown);
|
|
3725
|
+
};
|
|
3726
|
+
}, []);
|
|
3727
|
+
const paymentUri = useMemo7(() => {
|
|
3728
|
+
if (!quote?.depositAddress) return;
|
|
3729
|
+
try {
|
|
3730
|
+
return buildPaymentUri({
|
|
3731
|
+
address: quote.depositAddress,
|
|
3732
|
+
asset: quote.sellAsset,
|
|
3733
|
+
amountCryptoPrecision: formatAmountForInput(
|
|
3734
|
+
quote.sellAmountCryptoBaseUnit,
|
|
3735
|
+
quote.sellAsset.precision
|
|
3736
|
+
)
|
|
3737
|
+
});
|
|
3738
|
+
} catch {
|
|
3739
|
+
return;
|
|
3740
|
+
}
|
|
3741
|
+
}, [quote]);
|
|
3742
|
+
if (!quote?.depositAddress) return null;
|
|
3743
|
+
const isStillWatching = shouldKeepTrackingDeposit({
|
|
3744
|
+
quoteDeadline: quote.expiresAt,
|
|
3745
|
+
depositObservedAt: void 0,
|
|
3746
|
+
now: quote.expiresAt - msRemaining
|
|
3747
|
+
});
|
|
3748
|
+
const sellAmount = formatAmountForInput(quote.sellAmountCryptoBaseUnit, quote.sellAsset.precision);
|
|
3749
|
+
const buyAmount = formatAmount(quote.buyAmountAfterFeesCryptoBaseUnit, quote.buyAsset.precision);
|
|
3750
|
+
const canIncludeAmount = !!paymentUri && paymentUri !== quote.depositAddress;
|
|
3751
|
+
if (isRequoting) {
|
|
3752
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ssw-step-screen", children: [
|
|
3753
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-step-icon-circle ssw-ic-accent", children: /* @__PURE__ */ jsxs3(
|
|
3754
|
+
"svg",
|
|
3755
|
+
{
|
|
3756
|
+
className: "ssw-spinner",
|
|
3757
|
+
width: "32",
|
|
3758
|
+
height: "32",
|
|
3759
|
+
viewBox: "0 0 24 24",
|
|
3760
|
+
fill: "none",
|
|
3761
|
+
stroke: "currentColor",
|
|
3762
|
+
strokeWidth: "2",
|
|
3763
|
+
children: [
|
|
3764
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10", opacity: "0.25" }),
|
|
3765
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 2a10 10 0 0 1 10 10" })
|
|
3766
|
+
]
|
|
3767
|
+
}
|
|
3768
|
+
) }),
|
|
3769
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-step-title", children: "Requesting New Quote" })
|
|
3770
|
+
] });
|
|
3771
|
+
}
|
|
3772
|
+
if (isExpired) {
|
|
3773
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ssw-step-screen", children: [
|
|
3774
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-step-icon-circle ssw-ic-error", children: /* @__PURE__ */ jsxs3(
|
|
3775
|
+
"svg",
|
|
3776
|
+
{
|
|
3777
|
+
width: "32",
|
|
3778
|
+
height: "32",
|
|
3779
|
+
viewBox: "0 0 24 24",
|
|
3780
|
+
fill: "none",
|
|
3781
|
+
stroke: "currentColor",
|
|
3782
|
+
strokeWidth: "2",
|
|
3783
|
+
children: [
|
|
3784
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
|
|
3785
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 7v5l3 2" })
|
|
3786
|
+
]
|
|
3787
|
+
}
|
|
3788
|
+
) }),
|
|
3789
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-step-title", children: "Quote Expired" }),
|
|
3790
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-step-subtitle", children: "Don't send to the previous address. Request a new quote to continue." }),
|
|
3791
|
+
/* @__PURE__ */ jsx3("div", { className: "ssw-deposit-watching", children: isStillWatching ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3792
|
+
/* @__PURE__ */ jsxs3(
|
|
3793
|
+
"svg",
|
|
3794
|
+
{
|
|
3795
|
+
className: "ssw-spinner",
|
|
3796
|
+
width: "14",
|
|
3797
|
+
height: "14",
|
|
3798
|
+
viewBox: "0 0 24 24",
|
|
3799
|
+
fill: "none",
|
|
3800
|
+
stroke: "currentColor",
|
|
3801
|
+
strokeWidth: "2",
|
|
3802
|
+
children: [
|
|
3803
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10", opacity: "0.25" }),
|
|
3804
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 2a10 10 0 0 1 10 10" })
|
|
3805
|
+
]
|
|
3806
|
+
}
|
|
3807
|
+
),
|
|
3808
|
+
/* @__PURE__ */ jsx3("span", { children: "Already sent? Still watching for your deposit - this screen will update." })
|
|
3809
|
+
] }) : /* @__PURE__ */ jsx3("span", { children: "Already sent? The provider may still settle or refund it - check your receive and refund addresses." }) }),
|
|
3810
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-step-actions", children: [
|
|
3811
|
+
/* @__PURE__ */ jsx3("button", { className: "ssw-action-btn", onClick: handleNewQuote, type: "button", children: "Request New Quote" }),
|
|
3812
|
+
/* @__PURE__ */ jsx3("button", { className: "ssw-action-btn ssw-secondary", onClick: handleNewSwap, type: "button", children: "New Swap" })
|
|
3813
|
+
] })
|
|
3814
|
+
] });
|
|
3815
|
+
}
|
|
3816
|
+
return /* @__PURE__ */ jsxs3("div", { className: "ssw-deposit", children: [
|
|
3817
|
+
/* @__PURE__ */ jsx3("span", { className: "ssw-deposit-title", children: "Awaiting Deposit" }),
|
|
3818
|
+
/* @__PURE__ */ jsx3(
|
|
3819
|
+
QrCode,
|
|
3820
|
+
{
|
|
3821
|
+
value: canIncludeAmount && isAmountInQr && paymentUri ? paymentUri : quote.depositAddress,
|
|
3822
|
+
logo: getChainIcon(quote.sellAsset.chainId)
|
|
3823
|
+
}
|
|
3824
|
+
),
|
|
3825
|
+
canIncludeAmount && /* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-qr-controls", ref: qrControlsRef, children: [
|
|
3826
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-qr-mode", role: "group", "aria-label": "QR code contents", children: [
|
|
3827
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-pressed": !isAmountInQr, onClick: handleShowAddressOnly, children: "Address only" }),
|
|
3828
|
+
/* @__PURE__ */ jsx3("button", { type: "button", "aria-pressed": isAmountInQr, onClick: handleShowWithAmount, children: "With amount" })
|
|
3829
|
+
] }),
|
|
3830
|
+
/* @__PURE__ */ jsx3(
|
|
3831
|
+
"button",
|
|
3832
|
+
{
|
|
3833
|
+
type: "button",
|
|
3834
|
+
className: "ssw-deposit-qr-info",
|
|
3835
|
+
"aria-label": "About the QR code options",
|
|
3836
|
+
"aria-describedby": qrInfoId,
|
|
3837
|
+
onClick: handleToggleQrInfo,
|
|
3838
|
+
onBlur: handleResetQrInfo,
|
|
3839
|
+
onMouseLeave: handleQrInfoMouseLeave,
|
|
3840
|
+
children: /* @__PURE__ */ jsxs3(
|
|
3841
|
+
"svg",
|
|
3842
|
+
{
|
|
3843
|
+
width: "14",
|
|
3844
|
+
height: "14",
|
|
3845
|
+
viewBox: "0 0 24 24",
|
|
3846
|
+
fill: "none",
|
|
3847
|
+
stroke: "currentColor",
|
|
3848
|
+
strokeWidth: "2",
|
|
3849
|
+
children: [
|
|
3850
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "10" }),
|
|
3851
|
+
/* @__PURE__ */ jsx3("path", { d: "M12 16v-4M12 8h.01" })
|
|
3852
|
+
]
|
|
3853
|
+
}
|
|
3854
|
+
)
|
|
3855
|
+
}
|
|
3856
|
+
),
|
|
3857
|
+
/* @__PURE__ */ jsxs3(
|
|
3858
|
+
"span",
|
|
3859
|
+
{
|
|
3860
|
+
id: qrInfoId,
|
|
3861
|
+
role: "tooltip",
|
|
3862
|
+
className: `ssw-deposit-qr-tooltip${isQrInfoOpen ? " ssw-open" : ""}${isQrInfoDismissed ? " ssw-dismissed" : ""}`,
|
|
3863
|
+
children: [
|
|
3864
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
3865
|
+
/* @__PURE__ */ jsx3("strong", { children: "Address only:" }),
|
|
3866
|
+
" Enter the exact amount in your wallet."
|
|
3867
|
+
] }),
|
|
3868
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
3869
|
+
/* @__PURE__ */ jsx3("strong", { children: "With amount:" }),
|
|
3870
|
+
" Also fills in the amount, if your wallet supports it."
|
|
3871
|
+
] })
|
|
3872
|
+
]
|
|
3873
|
+
}
|
|
3874
|
+
)
|
|
3875
|
+
] }),
|
|
3876
|
+
/* @__PURE__ */ jsx3(
|
|
3877
|
+
CopyField,
|
|
3878
|
+
{
|
|
3879
|
+
label: "Send exactly",
|
|
3880
|
+
display: `${sellAmount} ${quote.sellAsset.symbol}`,
|
|
3881
|
+
value: sellAmount
|
|
3882
|
+
}
|
|
3883
|
+
),
|
|
3884
|
+
/* @__PURE__ */ jsx3(
|
|
3885
|
+
CopyField,
|
|
3886
|
+
{
|
|
3887
|
+
label: "To this address",
|
|
3888
|
+
display: truncateAddress(quote.depositAddress, 8),
|
|
3889
|
+
value: quote.depositAddress
|
|
3890
|
+
}
|
|
3891
|
+
),
|
|
3892
|
+
/* @__PURE__ */ jsxs3("span", { className: "ssw-deposit-countdown", children: [
|
|
3893
|
+
"Expires in ",
|
|
3894
|
+
formatCountdown(msRemaining)
|
|
3895
|
+
] }),
|
|
3896
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-summary", children: [
|
|
3897
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-row", children: [
|
|
3898
|
+
/* @__PURE__ */ jsx3("span", { children: "You get" }),
|
|
3899
|
+
/* @__PURE__ */ jsxs3("span", { children: [
|
|
3900
|
+
"~",
|
|
3901
|
+
buyAmount,
|
|
3902
|
+
" ",
|
|
3903
|
+
quote.buyAsset.symbol
|
|
3904
|
+
] })
|
|
3905
|
+
] }),
|
|
3906
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-row", children: [
|
|
3907
|
+
/* @__PURE__ */ jsx3("span", { children: "Receive address" }),
|
|
3908
|
+
/* @__PURE__ */ jsx3("span", { children: truncateAddress(receiveAddress ?? "", 6) })
|
|
3909
|
+
] }),
|
|
3910
|
+
/* @__PURE__ */ jsxs3("div", { className: "ssw-deposit-row", children: [
|
|
3911
|
+
/* @__PURE__ */ jsx3("span", { children: "Refund address" }),
|
|
3912
|
+
/* @__PURE__ */ jsx3("span", { children: truncateAddress(sendAddress ?? "", 6) })
|
|
3913
|
+
] })
|
|
3914
|
+
] }),
|
|
3915
|
+
/* @__PURE__ */ jsx3("button", { className: "ssw-action-btn ssw-secondary", onClick: handleNewSwap, type: "button", children: "New Swap" })
|
|
3916
|
+
] });
|
|
3917
|
+
};
|
|
3918
|
+
|
|
3168
3919
|
// src/components/ExecutionStep.tsx
|
|
3169
|
-
import { jsx as
|
|
3170
|
-
var ExecutionStep = () => /* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3920
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3921
|
+
var ExecutionStep = () => /* @__PURE__ */ jsxs4("div", { className: "ssw-step-screen", children: [
|
|
3922
|
+
/* @__PURE__ */ jsx4("div", { className: "ssw-step-icon-circle ssw-ic-accent", children: /* @__PURE__ */ jsxs4(
|
|
3172
3923
|
"svg",
|
|
3173
3924
|
{
|
|
3174
3925
|
className: "ssw-spinner",
|
|
@@ -3179,20 +3930,53 @@ var ExecutionStep = () => /* @__PURE__ */ jsxs2("div", { className: "ssw-step-sc
|
|
|
3179
3930
|
stroke: "currentColor",
|
|
3180
3931
|
strokeWidth: "2",
|
|
3181
3932
|
children: [
|
|
3182
|
-
/* @__PURE__ */
|
|
3183
|
-
/* @__PURE__ */
|
|
3933
|
+
/* @__PURE__ */ jsx4("circle", { cx: "12", cy: "12", r: "10", opacity: "0.25" }),
|
|
3934
|
+
/* @__PURE__ */ jsx4("path", { d: "M12 2a10 10 0 0 1 10 10" })
|
|
3184
3935
|
]
|
|
3185
3936
|
}
|
|
3186
3937
|
) }),
|
|
3187
|
-
/* @__PURE__ */
|
|
3188
|
-
/* @__PURE__ */
|
|
3938
|
+
/* @__PURE__ */ jsx4("div", { className: "ssw-step-title", children: "Confirm in Wallet" }),
|
|
3939
|
+
/* @__PURE__ */ jsx4("div", { className: "ssw-step-subtitle", children: "Please sign the transaction in your wallet" })
|
|
3189
3940
|
] });
|
|
3190
3941
|
|
|
3191
3942
|
// src/components/InputStep.tsx
|
|
3192
|
-
import { useMemo as
|
|
3943
|
+
import { useMemo as useMemo12 } from "react";
|
|
3944
|
+
|
|
3945
|
+
// src/utils/inputCta.ts
|
|
3946
|
+
var getUnsupportedCta = (allowShapeshiftRedirect) => allowShapeshiftRedirect ? { text: "Proceed on ShapeShift", disabled: false, action: "redirect" } : { text: "Route not supported", disabled: true, action: "none" };
|
|
3947
|
+
var getInputCta = ({
|
|
3948
|
+
isDepositRoute,
|
|
3949
|
+
hasWalletForSellChain,
|
|
3950
|
+
isSellChainTypeConnected,
|
|
3951
|
+
isUnsupportedChain,
|
|
3952
|
+
allowShapeshiftRedirect,
|
|
3953
|
+
hasReceiveAddress: hasReceiveAddress2,
|
|
3954
|
+
hasSendAddress: hasSendAddress2,
|
|
3955
|
+
hasAmount,
|
|
3956
|
+
isLoadingRates,
|
|
3957
|
+
hasRates,
|
|
3958
|
+
hasRatesError
|
|
3959
|
+
}) => {
|
|
3960
|
+
if (isUnsupportedChain && !isDepositRoute) return getUnsupportedCta(allowShapeshiftRedirect);
|
|
3961
|
+
if (!hasAmount) return { text: "Enter an amount", disabled: true, action: "none" };
|
|
3962
|
+
if (isLoadingRates) return { text: "Finding rates...", disabled: true, action: "none" };
|
|
3963
|
+
if (hasRatesError) return { text: "No routes available", disabled: true, action: "none" };
|
|
3964
|
+
if (!hasRates) return { text: "No routes found", disabled: true, action: "none" };
|
|
3965
|
+
if (isDepositRoute) {
|
|
3966
|
+
if (!hasReceiveAddress2) return { text: "Enter receive address", disabled: true, action: "none" };
|
|
3967
|
+
if (!hasSendAddress2) return { text: "Enter refund address", disabled: true, action: "none" };
|
|
3968
|
+
return { text: "Continue without a wallet", disabled: false, action: "deposit" };
|
|
3969
|
+
}
|
|
3970
|
+
if (!hasWalletForSellChain) {
|
|
3971
|
+
if (isSellChainTypeConnected) return getUnsupportedCta(allowShapeshiftRedirect);
|
|
3972
|
+
return { text: "Connect Wallet", disabled: false, action: "connect" };
|
|
3973
|
+
}
|
|
3974
|
+
if (!hasReceiveAddress2) return { text: "Enter receive address", disabled: true, action: "none" };
|
|
3975
|
+
return { text: "Swap", disabled: false, action: "quote" };
|
|
3976
|
+
};
|
|
3193
3977
|
|
|
3194
3978
|
// src/components/QuoteSelector.tsx
|
|
3195
|
-
import { useCallback as
|
|
3979
|
+
import { useCallback as useCallback8, useMemo as useMemo9, useState as useState5 } from "react";
|
|
3196
3980
|
|
|
3197
3981
|
// src/constants/swappers.ts
|
|
3198
3982
|
var SWAPPER_ICONS = {
|
|
@@ -3229,10 +4013,10 @@ var getSwapperColor = (swapperName) => {
|
|
|
3229
4013
|
};
|
|
3230
4014
|
|
|
3231
4015
|
// src/components/QuotesModal.tsx
|
|
3232
|
-
import { useCallback as
|
|
3233
|
-
import { Fragment, jsx as
|
|
4016
|
+
import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo8 } from "react";
|
|
4017
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3234
4018
|
var useLockBodyScroll = (isLocked) => {
|
|
3235
|
-
|
|
4019
|
+
useEffect10(() => {
|
|
3236
4020
|
if (!isLocked) return;
|
|
3237
4021
|
const originalOverflow = document.body.style.overflow;
|
|
3238
4022
|
document.body.style.overflow = "hidden";
|
|
@@ -3256,7 +4040,7 @@ var QuotesModal = ({
|
|
|
3256
4040
|
buyAssetUsdPrice
|
|
3257
4041
|
}) => {
|
|
3258
4042
|
useLockBodyScroll(isOpen);
|
|
3259
|
-
const handleBackdropClick =
|
|
4043
|
+
const handleBackdropClick = useCallback7(
|
|
3260
4044
|
(e) => {
|
|
3261
4045
|
if (e.target === e.currentTarget) {
|
|
3262
4046
|
onClose();
|
|
@@ -3264,22 +4048,22 @@ var QuotesModal = ({
|
|
|
3264
4048
|
},
|
|
3265
4049
|
[onClose]
|
|
3266
4050
|
);
|
|
3267
|
-
const handleSelectRate =
|
|
4051
|
+
const handleSelectRate = useCallback7(
|
|
3268
4052
|
(rate) => {
|
|
3269
4053
|
onSelectRate(rate);
|
|
3270
4054
|
onClose();
|
|
3271
4055
|
},
|
|
3272
4056
|
[onSelectRate, onClose]
|
|
3273
4057
|
);
|
|
3274
|
-
const sortedRates =
|
|
3275
|
-
const bestRate =
|
|
4058
|
+
const sortedRates = useMemo8(() => sortRatesByValue(rates, isExactOutput2), [rates, isExactOutput2]);
|
|
4059
|
+
const bestRate = useMemo8(() => sortedRates[0], [sortedRates]);
|
|
3276
4060
|
const bestAmountBaseUnit = bestRate ? getRateAmountBaseUnit(bestRate, isExactOutput2) : "0";
|
|
3277
4061
|
const asset = isExactOutput2 ? sellAsset : buyAsset;
|
|
3278
4062
|
const usdPrice = isExactOutput2 ? sellAssetUsdPrice : buyAssetUsdPrice;
|
|
3279
4063
|
if (!isOpen) return null;
|
|
3280
4064
|
return (
|
|
3281
4065
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
3282
|
-
/* @__PURE__ */
|
|
4066
|
+
/* @__PURE__ */ jsx5(
|
|
3283
4067
|
"div",
|
|
3284
4068
|
{
|
|
3285
4069
|
className: "ssw-quotes-modal-backdrop",
|
|
@@ -3288,17 +4072,17 @@ var QuotesModal = ({
|
|
|
3288
4072
|
role: "dialog",
|
|
3289
4073
|
"aria-modal": "true",
|
|
3290
4074
|
"aria-labelledby": "quotes-modal-title",
|
|
3291
|
-
children: /* @__PURE__ */
|
|
3292
|
-
/* @__PURE__ */
|
|
3293
|
-
/* @__PURE__ */
|
|
3294
|
-
/* @__PURE__ */
|
|
3295
|
-
/* @__PURE__ */
|
|
4075
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "ssw-quotes-modal", children: [
|
|
4076
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quotes-modal-header", children: [
|
|
4077
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quotes-header-content", children: [
|
|
4078
|
+
/* @__PURE__ */ jsx5("h2", { id: "quotes-modal-title", className: "ssw-quotes-modal-title", children: "Select Route" }),
|
|
4079
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-quotes-modal-subtitle", children: isExactOutput2 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3296
4080
|
sellAsset.symbol,
|
|
3297
4081
|
" \u2192 ",
|
|
3298
4082
|
formatAmount(buyAmountBaseUnit, buyAsset.precision),
|
|
3299
4083
|
" ",
|
|
3300
4084
|
buyAsset.symbol
|
|
3301
|
-
] }) : /* @__PURE__ */
|
|
4085
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3302
4086
|
formatAmount(sellAmountBaseUnit, sellAsset.precision),
|
|
3303
4087
|
" ",
|
|
3304
4088
|
sellAsset.symbol,
|
|
@@ -3307,7 +4091,7 @@ var QuotesModal = ({
|
|
|
3307
4091
|
buyAsset.symbol
|
|
3308
4092
|
] }) })
|
|
3309
4093
|
] }),
|
|
3310
|
-
/* @__PURE__ */
|
|
4094
|
+
/* @__PURE__ */ jsx5("button", { className: "ssw-quotes-modal-close", onClick: onClose, type: "button", children: /* @__PURE__ */ jsx5(
|
|
3311
4095
|
"svg",
|
|
3312
4096
|
{
|
|
3313
4097
|
width: "20",
|
|
@@ -3316,11 +4100,11 @@ var QuotesModal = ({
|
|
|
3316
4100
|
fill: "none",
|
|
3317
4101
|
stroke: "currentColor",
|
|
3318
4102
|
strokeWidth: "2",
|
|
3319
|
-
children: /* @__PURE__ */
|
|
4103
|
+
children: /* @__PURE__ */ jsx5("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
3320
4104
|
}
|
|
3321
4105
|
) })
|
|
3322
4106
|
] }),
|
|
3323
|
-
/* @__PURE__ */
|
|
4107
|
+
/* @__PURE__ */ jsx5("div", { className: "ssw-quotes-modal-list", children: sortedRates.map((rate, index) => {
|
|
3324
4108
|
const amountBaseUnit = getRateAmountBaseUnit(rate, isExactOutput2);
|
|
3325
4109
|
const estimatedTime = rate.estimatedExecutionTimeMs;
|
|
3326
4110
|
const isBest = index === 0;
|
|
@@ -3332,15 +4116,15 @@ var QuotesModal = ({
|
|
|
3332
4116
|
const diffPercent = isBest ? null : getRateDiffPercent(bestAmountBaseUnit, amountBaseUnit, isExactOutput2);
|
|
3333
4117
|
const estimatedSeconds = estimatedTime ? Math.round(estimatedTime / 1e3) : 0;
|
|
3334
4118
|
const hasTime = estimatedSeconds > 0;
|
|
3335
|
-
return /* @__PURE__ */
|
|
4119
|
+
return /* @__PURE__ */ jsxs5(
|
|
3336
4120
|
"button",
|
|
3337
4121
|
{
|
|
3338
4122
|
className: `ssw-quote-row ${isSelected ? "ssw-selected" : ""} ${isBest ? "ssw-best" : ""}`,
|
|
3339
4123
|
onClick: () => handleSelectRate(rate),
|
|
3340
4124
|
type: "button",
|
|
3341
4125
|
children: [
|
|
3342
|
-
/* @__PURE__ */
|
|
3343
|
-
swapperIcon ? /* @__PURE__ */
|
|
4126
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quote-row-left", children: [
|
|
4127
|
+
swapperIcon ? /* @__PURE__ */ jsx5("img", { src: swapperIcon, alt: rate.swapperName, className: "ssw-quote-row-icon" }) : /* @__PURE__ */ jsx5(
|
|
3344
4128
|
"div",
|
|
3345
4129
|
{
|
|
3346
4130
|
className: "ssw-quote-row-icon-placeholder",
|
|
@@ -3348,30 +4132,30 @@ var QuotesModal = ({
|
|
|
3348
4132
|
children: rate.swapperName.charAt(0)
|
|
3349
4133
|
}
|
|
3350
4134
|
),
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
3353
|
-
/* @__PURE__ */
|
|
3354
|
-
isBest && /* @__PURE__ */
|
|
3355
|
-
diffPercent && /* @__PURE__ */
|
|
4135
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quote-row-info", children: [
|
|
4136
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quote-row-name-row", children: [
|
|
4137
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-quote-row-name", children: rate.swapperName }),
|
|
4138
|
+
isBest && /* @__PURE__ */ jsx5("span", { className: "ssw-quote-row-best", children: "Best" }),
|
|
4139
|
+
diffPercent && /* @__PURE__ */ jsxs5("span", { className: "ssw-quote-row-diff", children: [
|
|
3356
4140
|
isExactOutput2 ? "+" : "-",
|
|
3357
4141
|
diffPercent,
|
|
3358
4142
|
"%"
|
|
3359
4143
|
] })
|
|
3360
4144
|
] }),
|
|
3361
|
-
hasTime && /* @__PURE__ */
|
|
4145
|
+
hasTime && /* @__PURE__ */ jsxs5("span", { className: "ssw-quote-row-time", children: [
|
|
3362
4146
|
"~",
|
|
3363
4147
|
estimatedSeconds,
|
|
3364
4148
|
"s"
|
|
3365
4149
|
] })
|
|
3366
4150
|
] })
|
|
3367
4151
|
] }),
|
|
3368
|
-
/* @__PURE__ */
|
|
3369
|
-
/* @__PURE__ */
|
|
4152
|
+
/* @__PURE__ */ jsxs5("div", { className: "ssw-quote-row-right", children: [
|
|
4153
|
+
/* @__PURE__ */ jsxs5("span", { className: "ssw-quote-row-amount", children: [
|
|
3370
4154
|
formattedAmount,
|
|
3371
4155
|
" ",
|
|
3372
|
-
/* @__PURE__ */
|
|
4156
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-quote-row-symbol", children: asset.symbol })
|
|
3373
4157
|
] }),
|
|
3374
|
-
/* @__PURE__ */
|
|
4158
|
+
/* @__PURE__ */ jsx5("span", { className: "ssw-quote-row-usd", children: usdValue })
|
|
3375
4159
|
] })
|
|
3376
4160
|
]
|
|
3377
4161
|
},
|
|
@@ -3385,7 +4169,7 @@ var QuotesModal = ({
|
|
|
3385
4169
|
};
|
|
3386
4170
|
|
|
3387
4171
|
// src/components/QuoteSelector.tsx
|
|
3388
|
-
import { Fragment as
|
|
4172
|
+
import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3389
4173
|
var QuoteSelector = ({
|
|
3390
4174
|
rates,
|
|
3391
4175
|
selectedRate,
|
|
@@ -3399,27 +4183,27 @@ var QuoteSelector = ({
|
|
|
3399
4183
|
sellAssetUsdPrice,
|
|
3400
4184
|
buyAssetUsdPrice
|
|
3401
4185
|
}) => {
|
|
3402
|
-
const [isModalOpen, setIsModalOpen] =
|
|
3403
|
-
const bestRate =
|
|
3404
|
-
const alternativeRatesCount =
|
|
3405
|
-
const handleOpenModal =
|
|
4186
|
+
const [isModalOpen, setIsModalOpen] = useState5(false);
|
|
4187
|
+
const bestRate = useMemo9(() => rates[0], [rates]);
|
|
4188
|
+
const alternativeRatesCount = useMemo9(() => Math.max(0, rates.length - 1), [rates]);
|
|
4189
|
+
const handleOpenModal = useCallback8(() => {
|
|
3406
4190
|
if (rates.length > 0) {
|
|
3407
4191
|
setIsModalOpen(true);
|
|
3408
4192
|
}
|
|
3409
4193
|
}, [rates.length]);
|
|
3410
|
-
const handleCloseModal =
|
|
4194
|
+
const handleCloseModal = useCallback8(() => {
|
|
3411
4195
|
setIsModalOpen(false);
|
|
3412
4196
|
}, []);
|
|
3413
|
-
const handleSelectRate =
|
|
4197
|
+
const handleSelectRate = useCallback8(
|
|
3414
4198
|
(rate) => {
|
|
3415
4199
|
onSelectRate(rate);
|
|
3416
4200
|
},
|
|
3417
4201
|
[onSelectRate]
|
|
3418
4202
|
);
|
|
3419
4203
|
if (isLoading) {
|
|
3420
|
-
return /* @__PURE__ */
|
|
3421
|
-
/* @__PURE__ */
|
|
3422
|
-
/* @__PURE__ */
|
|
4204
|
+
return /* @__PURE__ */ jsx6("div", { className: "ssw-quote-selector ssw-loading", children: /* @__PURE__ */ jsxs6("div", { className: "ssw-quote-loading", children: [
|
|
4205
|
+
/* @__PURE__ */ jsx6("div", { className: "ssw-spinner-small" }),
|
|
4206
|
+
/* @__PURE__ */ jsx6("span", { children: "Finding best rates..." })
|
|
3423
4207
|
] }) });
|
|
3424
4208
|
}
|
|
3425
4209
|
if (!bestRate) {
|
|
@@ -3436,18 +4220,18 @@ var QuoteSelector = ({
|
|
|
3436
4220
|
asset.precision,
|
|
3437
4221
|
isExactOutput2 ? sellAssetUsdPrice : buyAssetUsdPrice
|
|
3438
4222
|
);
|
|
3439
|
-
return /* @__PURE__ */
|
|
3440
|
-
/* @__PURE__ */
|
|
3441
|
-
/* @__PURE__ */
|
|
3442
|
-
/* @__PURE__ */
|
|
3443
|
-
swapperIcon ? /* @__PURE__ */
|
|
4223
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
4224
|
+
/* @__PURE__ */ jsxs6("button", { className: "ssw-quote-selector", onClick: handleOpenModal, type: "button", children: [
|
|
4225
|
+
/* @__PURE__ */ jsxs6("div", { className: "ssw-quote-left", children: [
|
|
4226
|
+
/* @__PURE__ */ jsxs6("div", { className: "ssw-quote-provider", children: [
|
|
4227
|
+
swapperIcon ? /* @__PURE__ */ jsx6(
|
|
3444
4228
|
"img",
|
|
3445
4229
|
{
|
|
3446
4230
|
src: swapperIcon,
|
|
3447
4231
|
alt: displayRate.swapperName,
|
|
3448
4232
|
className: "ssw-quote-provider-icon"
|
|
3449
4233
|
}
|
|
3450
|
-
) : /* @__PURE__ */
|
|
4234
|
+
) : /* @__PURE__ */ jsx6(
|
|
3451
4235
|
"div",
|
|
3452
4236
|
{
|
|
3453
4237
|
className: "ssw-quote-provider-icon-placeholder",
|
|
@@ -3455,21 +4239,21 @@ var QuoteSelector = ({
|
|
|
3455
4239
|
children: displayRate.swapperName.charAt(0)
|
|
3456
4240
|
}
|
|
3457
4241
|
),
|
|
3458
|
-
/* @__PURE__ */
|
|
3459
|
-
displayRate === bestRate && /* @__PURE__ */
|
|
4242
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-quote-provider-name", children: displayRate.swapperName }),
|
|
4243
|
+
displayRate === bestRate && /* @__PURE__ */ jsx6("span", { className: "ssw-quote-best-tag", children: "Best" })
|
|
3460
4244
|
] }),
|
|
3461
|
-
/* @__PURE__ */
|
|
4245
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-quote-usd", children: usdValue })
|
|
3462
4246
|
] }),
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3465
|
-
/* @__PURE__ */
|
|
3466
|
-
/* @__PURE__ */
|
|
4247
|
+
/* @__PURE__ */ jsxs6("div", { className: "ssw-quote-right", children: [
|
|
4248
|
+
/* @__PURE__ */ jsxs6("div", { className: "ssw-quote-amount-row", children: [
|
|
4249
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-quote-amount", children: formattedAmount }),
|
|
4250
|
+
/* @__PURE__ */ jsx6("span", { className: "ssw-quote-symbol", children: asset.symbol })
|
|
3467
4251
|
] }),
|
|
3468
|
-
alternativeRatesCount > 0 && /* @__PURE__ */
|
|
4252
|
+
alternativeRatesCount > 0 && /* @__PURE__ */ jsxs6("span", { className: "ssw-quote-more", children: [
|
|
3469
4253
|
"+",
|
|
3470
4254
|
alternativeRatesCount,
|
|
3471
4255
|
" more",
|
|
3472
|
-
/* @__PURE__ */
|
|
4256
|
+
/* @__PURE__ */ jsx6(
|
|
3473
4257
|
"svg",
|
|
3474
4258
|
{
|
|
3475
4259
|
width: "12",
|
|
@@ -3478,13 +4262,13 @@ var QuoteSelector = ({
|
|
|
3478
4262
|
fill: "none",
|
|
3479
4263
|
stroke: "currentColor",
|
|
3480
4264
|
strokeWidth: "2.5",
|
|
3481
|
-
children: /* @__PURE__ */
|
|
4265
|
+
children: /* @__PURE__ */ jsx6("path", { d: "M9 18l6-6-6-6" })
|
|
3482
4266
|
}
|
|
3483
4267
|
)
|
|
3484
4268
|
] })
|
|
3485
4269
|
] })
|
|
3486
4270
|
] }),
|
|
3487
|
-
/* @__PURE__ */
|
|
4271
|
+
/* @__PURE__ */ jsx6(
|
|
3488
4272
|
QuotesModal,
|
|
3489
4273
|
{
|
|
3490
4274
|
isOpen: isModalOpen,
|
|
@@ -3505,8 +4289,8 @@ var QuoteSelector = ({
|
|
|
3505
4289
|
};
|
|
3506
4290
|
|
|
3507
4291
|
// src/components/ReceiveAddressRow.tsx
|
|
3508
|
-
import { useCallback as
|
|
3509
|
-
import { Fragment as
|
|
4292
|
+
import { useCallback as useCallback9, useLayoutEffect, useMemo as useMemo10, useRef as useRef9, useState as useState6 } from "react";
|
|
4293
|
+
import { Fragment as Fragment5, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3510
4294
|
var ReceiveAddressRow = ({
|
|
3511
4295
|
receiveAddress,
|
|
3512
4296
|
isResolving,
|
|
@@ -3514,10 +4298,10 @@ var ReceiveAddressRow = ({
|
|
|
3514
4298
|
isLocked,
|
|
3515
4299
|
onSetCustomReceiveAddress
|
|
3516
4300
|
}) => {
|
|
3517
|
-
const [isEditing, setIsEditing] =
|
|
3518
|
-
const [draft, setDraft] =
|
|
3519
|
-
const [hasInteracted, setHasInteracted] =
|
|
3520
|
-
const inputRef =
|
|
4301
|
+
const [isEditing, setIsEditing] = useState6(false);
|
|
4302
|
+
const [draft, setDraft] = useState6("");
|
|
4303
|
+
const [hasInteracted, setHasInteracted] = useState6(false);
|
|
4304
|
+
const inputRef = useRef9(null);
|
|
3521
4305
|
const needsAddress = !receiveAddress;
|
|
3522
4306
|
const showInput = !isLocked && (needsAddress && !isResolving || isEditing);
|
|
3523
4307
|
const showAttention = needsAddress && !isResolving;
|
|
@@ -3529,33 +4313,33 @@ var ReceiveAddressRow = ({
|
|
|
3529
4313
|
setHasInteracted(false);
|
|
3530
4314
|
setIsEditing(false);
|
|
3531
4315
|
}, [buyChainId]);
|
|
3532
|
-
const trimmedDraft =
|
|
3533
|
-
const validation =
|
|
4316
|
+
const trimmedDraft = useMemo10(() => draft.trim(), [draft]);
|
|
4317
|
+
const validation = useMemo10(() => {
|
|
3534
4318
|
if (!trimmedDraft || !hasInteracted) return { valid: true, error: void 0 };
|
|
3535
4319
|
return validateAddress(trimmedDraft, buyChainId);
|
|
3536
4320
|
}, [trimmedDraft, hasInteracted, buyChainId]);
|
|
3537
|
-
const canAccept =
|
|
4321
|
+
const canAccept = useMemo10(
|
|
3538
4322
|
() => !!trimmedDraft && validateAddress(trimmedDraft, buyChainId).valid,
|
|
3539
4323
|
[trimmedDraft, buyChainId]
|
|
3540
4324
|
);
|
|
3541
|
-
const formatHint =
|
|
3542
|
-
const chainName =
|
|
3543
|
-
const startEditing =
|
|
4325
|
+
const formatHint = useMemo10(() => getAddressFormatHint(buyChainId), [buyChainId]);
|
|
4326
|
+
const chainName = useMemo10(() => getChainName(buyChainId), [buyChainId]);
|
|
4327
|
+
const startEditing = useCallback9(() => {
|
|
3544
4328
|
setDraft(receiveAddress ?? "");
|
|
3545
4329
|
setHasInteracted(false);
|
|
3546
4330
|
setIsEditing(true);
|
|
3547
4331
|
}, [receiveAddress]);
|
|
3548
|
-
const handleChange =
|
|
4332
|
+
const handleChange = useCallback9((value) => {
|
|
3549
4333
|
setDraft(value);
|
|
3550
4334
|
setHasInteracted(true);
|
|
3551
4335
|
}, []);
|
|
3552
|
-
const handleAccept =
|
|
4336
|
+
const handleAccept = useCallback9(() => {
|
|
3553
4337
|
if (!validateAddress(trimmedDraft, buyChainId).valid) return;
|
|
3554
4338
|
onSetCustomReceiveAddress(trimmedDraft);
|
|
3555
4339
|
setIsEditing(false);
|
|
3556
4340
|
setHasInteracted(false);
|
|
3557
4341
|
}, [trimmedDraft, buyChainId, onSetCustomReceiveAddress]);
|
|
3558
|
-
const handleReset =
|
|
4342
|
+
const handleReset = useCallback9(() => {
|
|
3559
4343
|
onSetCustomReceiveAddress("");
|
|
3560
4344
|
setDraft("");
|
|
3561
4345
|
setHasInteracted(false);
|
|
@@ -3563,132 +4347,284 @@ var ReceiveAddressRow = ({
|
|
|
3563
4347
|
}, [onSetCustomReceiveAddress]);
|
|
3564
4348
|
const showReset = !!draft || isEditing;
|
|
3565
4349
|
if (!showInput) {
|
|
3566
|
-
return /* @__PURE__ */
|
|
4350
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ssw-receive-row-resolved", children: [
|
|
4351
|
+
/* @__PURE__ */ jsx7("span", { className: "ssw-receive-label", children: "Receive address" }),
|
|
4352
|
+
/* @__PURE__ */ jsx7("div", { className: "ssw-receive-resolved-value", children: isResolving ? /* @__PURE__ */ jsx7("span", { className: "ssw-balance-skeleton" }) : showAttention ? (
|
|
4353
|
+
// Locked only - an unlocked row with no address shows the input instead
|
|
4354
|
+
/* @__PURE__ */ jsxs7("span", { className: "ssw-receive-error", children: [
|
|
4355
|
+
"Not valid for ",
|
|
4356
|
+
chainName
|
|
4357
|
+
] })
|
|
4358
|
+
) : /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
4359
|
+
/* @__PURE__ */ jsx7("span", { className: "ssw-receive-address", children: truncateAddress(receiveAddress ?? "", 6) }),
|
|
4360
|
+
!isLocked && /* @__PURE__ */ jsx7(
|
|
4361
|
+
"button",
|
|
4362
|
+
{
|
|
4363
|
+
className: "ssw-receive-edit-btn",
|
|
4364
|
+
onClick: startEditing,
|
|
4365
|
+
type: "button",
|
|
4366
|
+
"aria-label": "Edit receive address",
|
|
4367
|
+
children: /* @__PURE__ */ jsxs7(
|
|
4368
|
+
"svg",
|
|
4369
|
+
{
|
|
4370
|
+
width: "14",
|
|
4371
|
+
height: "14",
|
|
4372
|
+
viewBox: "0 0 24 24",
|
|
4373
|
+
fill: "none",
|
|
4374
|
+
stroke: "currentColor",
|
|
4375
|
+
strokeWidth: "2",
|
|
4376
|
+
children: [
|
|
4377
|
+
/* @__PURE__ */ jsx7("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
4378
|
+
/* @__PURE__ */ jsx7("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
4379
|
+
]
|
|
4380
|
+
}
|
|
4381
|
+
)
|
|
4382
|
+
}
|
|
4383
|
+
)
|
|
4384
|
+
] }) })
|
|
4385
|
+
] });
|
|
4386
|
+
}
|
|
4387
|
+
return /* @__PURE__ */ jsxs7("div", { className: "ssw-receive-row-input", children: [
|
|
4388
|
+
/* @__PURE__ */ jsx7("div", { className: "ssw-receive-header", children: /* @__PURE__ */ jsx7("span", { className: "ssw-receive-label", children: "Receive address" }) }),
|
|
4389
|
+
/* @__PURE__ */ jsxs7(
|
|
3567
4390
|
"div",
|
|
3568
4391
|
{
|
|
3569
|
-
className: `ssw-receive-
|
|
4392
|
+
className: `ssw-receive-input-wrapper${!validation.valid && hasInteracted ? " ssw-invalid" : ""}`,
|
|
3570
4393
|
children: [
|
|
3571
|
-
/* @__PURE__ */
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
4394
|
+
/* @__PURE__ */ jsx7(
|
|
4395
|
+
"input",
|
|
4396
|
+
{
|
|
4397
|
+
ref: inputRef,
|
|
4398
|
+
type: "text",
|
|
4399
|
+
className: "ssw-receive-input",
|
|
4400
|
+
placeholder: formatHint,
|
|
4401
|
+
value: draft,
|
|
4402
|
+
onChange: (e) => handleChange(e.target.value),
|
|
4403
|
+
spellCheck: false,
|
|
4404
|
+
autoComplete: "off",
|
|
4405
|
+
"aria-label": "Receive address"
|
|
4406
|
+
}
|
|
4407
|
+
),
|
|
4408
|
+
/* @__PURE__ */ jsxs7("div", { className: "ssw-receive-inline-actions", children: [
|
|
4409
|
+
/* @__PURE__ */ jsx7(
|
|
3581
4410
|
"button",
|
|
3582
4411
|
{
|
|
3583
|
-
className: "ssw-receive-
|
|
3584
|
-
onClick:
|
|
4412
|
+
className: "ssw-receive-icon-btn ssw-receive-accept",
|
|
4413
|
+
onClick: handleAccept,
|
|
4414
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4415
|
+
disabled: !canAccept,
|
|
3585
4416
|
type: "button",
|
|
3586
|
-
"aria-label": "
|
|
3587
|
-
children: /* @__PURE__ */
|
|
4417
|
+
"aria-label": "Accept address",
|
|
4418
|
+
children: /* @__PURE__ */ jsx7(
|
|
3588
4419
|
"svg",
|
|
3589
4420
|
{
|
|
3590
|
-
width: "
|
|
3591
|
-
height: "
|
|
4421
|
+
width: "16",
|
|
4422
|
+
height: "16",
|
|
3592
4423
|
viewBox: "0 0 24 24",
|
|
3593
4424
|
fill: "none",
|
|
3594
4425
|
stroke: "currentColor",
|
|
3595
|
-
strokeWidth: "2",
|
|
3596
|
-
children:
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
4426
|
+
strokeWidth: "2.5",
|
|
4427
|
+
children: /* @__PURE__ */ jsx7("path", { d: "M20 6L9 17l-5-5" })
|
|
4428
|
+
}
|
|
4429
|
+
)
|
|
4430
|
+
}
|
|
4431
|
+
),
|
|
4432
|
+
showReset && /* @__PURE__ */ jsx7(
|
|
4433
|
+
"button",
|
|
4434
|
+
{
|
|
4435
|
+
className: "ssw-receive-icon-btn ssw-receive-reset",
|
|
4436
|
+
onClick: handleReset,
|
|
4437
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4438
|
+
type: "button",
|
|
4439
|
+
"aria-label": "Reset address",
|
|
4440
|
+
children: /* @__PURE__ */ jsx7(
|
|
4441
|
+
"svg",
|
|
4442
|
+
{
|
|
4443
|
+
width: "16",
|
|
4444
|
+
height: "16",
|
|
4445
|
+
viewBox: "0 0 24 24",
|
|
4446
|
+
fill: "none",
|
|
4447
|
+
stroke: "currentColor",
|
|
4448
|
+
strokeWidth: "2.5",
|
|
4449
|
+
children: /* @__PURE__ */ jsx7("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
3600
4450
|
}
|
|
3601
4451
|
)
|
|
3602
4452
|
}
|
|
3603
4453
|
)
|
|
3604
|
-
] })
|
|
4454
|
+
] })
|
|
3605
4455
|
]
|
|
3606
4456
|
}
|
|
3607
|
-
)
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
4457
|
+
),
|
|
4458
|
+
!validation.valid && hasInteracted && validation.error && /* @__PURE__ */ jsx7("span", { className: "ssw-receive-error", children: validation.error })
|
|
4459
|
+
] });
|
|
4460
|
+
};
|
|
4461
|
+
|
|
4462
|
+
// src/components/RefundAddressRow.tsx
|
|
4463
|
+
import { useCallback as useCallback10, useLayoutEffect as useLayoutEffect2, useMemo as useMemo11, useRef as useRef10, useState as useState7 } from "react";
|
|
4464
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4465
|
+
var RefundAddressRow = ({
|
|
4466
|
+
refundAddress,
|
|
4467
|
+
sellChainId,
|
|
4468
|
+
onSetCustomRefundAddress
|
|
4469
|
+
}) => {
|
|
4470
|
+
const [isEditing, setIsEditing] = useState7(false);
|
|
4471
|
+
const [draft, setDraft] = useState7("");
|
|
4472
|
+
const [hasInteracted, setHasInteracted] = useState7(false);
|
|
4473
|
+
const inputRef = useRef10(null);
|
|
4474
|
+
const showInput = !refundAddress || isEditing;
|
|
4475
|
+
useLayoutEffect2(() => {
|
|
4476
|
+
if (isEditing) inputRef.current?.focus();
|
|
4477
|
+
}, [isEditing]);
|
|
4478
|
+
useLayoutEffect2(() => {
|
|
4479
|
+
setDraft("");
|
|
4480
|
+
setHasInteracted(false);
|
|
4481
|
+
setIsEditing(false);
|
|
4482
|
+
}, [sellChainId]);
|
|
4483
|
+
const trimmedDraft = useMemo11(() => draft.trim(), [draft]);
|
|
4484
|
+
const validation = useMemo11(() => {
|
|
4485
|
+
if (!trimmedDraft || !hasInteracted) return { valid: true, error: void 0 };
|
|
4486
|
+
return validateAddress(trimmedDraft, sellChainId);
|
|
4487
|
+
}, [trimmedDraft, hasInteracted, sellChainId]);
|
|
4488
|
+
const canAccept = useMemo11(
|
|
4489
|
+
() => !!trimmedDraft && validateAddress(trimmedDraft, sellChainId).valid,
|
|
4490
|
+
[trimmedDraft, sellChainId]
|
|
4491
|
+
);
|
|
4492
|
+
const formatHint = useMemo11(() => getAddressFormatHint(sellChainId), [sellChainId]);
|
|
4493
|
+
const chainName = useMemo11(() => getChainName(sellChainId), [sellChainId]);
|
|
4494
|
+
const startEditing = useCallback10(() => {
|
|
4495
|
+
setDraft(refundAddress ?? "");
|
|
4496
|
+
setHasInteracted(false);
|
|
4497
|
+
setIsEditing(true);
|
|
4498
|
+
}, [refundAddress]);
|
|
4499
|
+
const handleChange = useCallback10((value) => {
|
|
4500
|
+
setDraft(value);
|
|
4501
|
+
setHasInteracted(true);
|
|
4502
|
+
}, []);
|
|
4503
|
+
const handleAccept = useCallback10(() => {
|
|
4504
|
+
if (!validateAddress(trimmedDraft, sellChainId).valid) return;
|
|
4505
|
+
onSetCustomRefundAddress(trimmedDraft);
|
|
4506
|
+
setIsEditing(false);
|
|
4507
|
+
setHasInteracted(false);
|
|
4508
|
+
}, [trimmedDraft, sellChainId, onSetCustomRefundAddress]);
|
|
4509
|
+
const handleReset = useCallback10(() => {
|
|
4510
|
+
onSetCustomRefundAddress("");
|
|
4511
|
+
setDraft("");
|
|
4512
|
+
setHasInteracted(false);
|
|
4513
|
+
setIsEditing(false);
|
|
4514
|
+
}, [onSetCustomRefundAddress]);
|
|
4515
|
+
if (!showInput) {
|
|
4516
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ssw-receive-row-resolved", children: [
|
|
4517
|
+
/* @__PURE__ */ jsx8("span", { className: "ssw-receive-label", children: "Refund address" }),
|
|
4518
|
+
/* @__PURE__ */ jsxs8("div", { className: "ssw-receive-resolved-value", children: [
|
|
4519
|
+
/* @__PURE__ */ jsx8("span", { className: "ssw-receive-address", children: truncateAddress(refundAddress ?? "", 6) }),
|
|
4520
|
+
/* @__PURE__ */ jsx8(
|
|
4521
|
+
"button",
|
|
3617
4522
|
{
|
|
3618
|
-
className:
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
4523
|
+
className: "ssw-receive-edit-btn",
|
|
4524
|
+
onClick: startEditing,
|
|
4525
|
+
type: "button",
|
|
4526
|
+
"aria-label": "Edit refund address",
|
|
4527
|
+
children: /* @__PURE__ */ jsxs8(
|
|
4528
|
+
"svg",
|
|
4529
|
+
{
|
|
4530
|
+
width: "14",
|
|
4531
|
+
height: "14",
|
|
4532
|
+
viewBox: "0 0 24 24",
|
|
4533
|
+
fill: "none",
|
|
4534
|
+
stroke: "currentColor",
|
|
4535
|
+
strokeWidth: "2",
|
|
4536
|
+
children: [
|
|
4537
|
+
/* @__PURE__ */ jsx8("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
|
|
4538
|
+
/* @__PURE__ */ jsx8("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
|
|
4539
|
+
]
|
|
4540
|
+
}
|
|
4541
|
+
)
|
|
4542
|
+
}
|
|
4543
|
+
)
|
|
4544
|
+
] })
|
|
4545
|
+
] });
|
|
4546
|
+
}
|
|
4547
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ssw-receive-row-input", children: [
|
|
4548
|
+
/* @__PURE__ */ jsx8("div", { className: "ssw-receive-header", children: /* @__PURE__ */ jsx8("span", { className: "ssw-receive-label", children: "Refund address" }) }),
|
|
4549
|
+
/* @__PURE__ */ jsxs8(
|
|
4550
|
+
"div",
|
|
4551
|
+
{
|
|
4552
|
+
className: `ssw-receive-input-wrapper${!validation.valid && hasInteracted ? " ssw-invalid" : ""}`,
|
|
4553
|
+
children: [
|
|
4554
|
+
/* @__PURE__ */ jsx8(
|
|
4555
|
+
"input",
|
|
4556
|
+
{
|
|
4557
|
+
ref: inputRef,
|
|
4558
|
+
type: "text",
|
|
4559
|
+
className: "ssw-receive-input",
|
|
4560
|
+
placeholder: formatHint,
|
|
4561
|
+
value: draft,
|
|
4562
|
+
onChange: (e) => handleChange(e.target.value),
|
|
4563
|
+
spellCheck: false,
|
|
4564
|
+
autoComplete: "off",
|
|
4565
|
+
"aria-label": "Refund address"
|
|
4566
|
+
}
|
|
4567
|
+
),
|
|
4568
|
+
/* @__PURE__ */ jsxs8("div", { className: "ssw-receive-inline-actions", children: [
|
|
4569
|
+
/* @__PURE__ */ jsx8(
|
|
4570
|
+
"button",
|
|
4571
|
+
{
|
|
4572
|
+
className: "ssw-receive-icon-btn ssw-receive-accept",
|
|
4573
|
+
onClick: handleAccept,
|
|
4574
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4575
|
+
disabled: !canAccept,
|
|
4576
|
+
type: "button",
|
|
4577
|
+
"aria-label": "Accept refund address",
|
|
4578
|
+
children: /* @__PURE__ */ jsx8(
|
|
4579
|
+
"svg",
|
|
3637
4580
|
{
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
children: /* @__PURE__ */
|
|
3645
|
-
"svg",
|
|
3646
|
-
{
|
|
3647
|
-
width: "16",
|
|
3648
|
-
height: "16",
|
|
3649
|
-
viewBox: "0 0 24 24",
|
|
3650
|
-
fill: "none",
|
|
3651
|
-
stroke: "currentColor",
|
|
3652
|
-
strokeWidth: "2.5",
|
|
3653
|
-
children: /* @__PURE__ */ jsx5("path", { d: "M20 6L9 17l-5-5" })
|
|
3654
|
-
}
|
|
3655
|
-
)
|
|
4581
|
+
width: "16",
|
|
4582
|
+
height: "16",
|
|
4583
|
+
viewBox: "0 0 24 24",
|
|
4584
|
+
fill: "none",
|
|
4585
|
+
stroke: "currentColor",
|
|
4586
|
+
strokeWidth: "2.5",
|
|
4587
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6L9 17l-5-5" })
|
|
3656
4588
|
}
|
|
3657
|
-
)
|
|
3658
|
-
|
|
3659
|
-
|
|
4589
|
+
)
|
|
4590
|
+
}
|
|
4591
|
+
),
|
|
4592
|
+
(!!draft || isEditing) && /* @__PURE__ */ jsx8(
|
|
4593
|
+
"button",
|
|
4594
|
+
{
|
|
4595
|
+
className: "ssw-receive-icon-btn ssw-receive-reset",
|
|
4596
|
+
onClick: handleReset,
|
|
4597
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4598
|
+
type: "button",
|
|
4599
|
+
"aria-label": "Reset refund address",
|
|
4600
|
+
children: /* @__PURE__ */ jsx8(
|
|
4601
|
+
"svg",
|
|
3660
4602
|
{
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
{
|
|
3669
|
-
width: "16",
|
|
3670
|
-
height: "16",
|
|
3671
|
-
viewBox: "0 0 24 24",
|
|
3672
|
-
fill: "none",
|
|
3673
|
-
stroke: "currentColor",
|
|
3674
|
-
strokeWidth: "2.5",
|
|
3675
|
-
children: /* @__PURE__ */ jsx5("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
3676
|
-
}
|
|
3677
|
-
)
|
|
4603
|
+
width: "16",
|
|
4604
|
+
height: "16",
|
|
4605
|
+
viewBox: "0 0 24 24",
|
|
4606
|
+
fill: "none",
|
|
4607
|
+
stroke: "currentColor",
|
|
4608
|
+
strokeWidth: "2.5",
|
|
4609
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
3678
4610
|
}
|
|
3679
4611
|
)
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
}
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
}
|
|
3687
|
-
|
|
4612
|
+
}
|
|
4613
|
+
)
|
|
4614
|
+
] })
|
|
4615
|
+
]
|
|
4616
|
+
}
|
|
4617
|
+
),
|
|
4618
|
+
!validation.valid && hasInteracted && validation.error ? /* @__PURE__ */ jsx8("span", { className: "ssw-receive-error", children: validation.error }) : /* @__PURE__ */ jsxs8("span", { className: "ssw-receive-hint", children: [
|
|
4619
|
+
"Your ",
|
|
4620
|
+
chainName,
|
|
4621
|
+
" address - funds return here if the swap fails"
|
|
4622
|
+
] })
|
|
4623
|
+
] });
|
|
3688
4624
|
};
|
|
3689
4625
|
|
|
3690
4626
|
// src/components/InputStep.tsx
|
|
3691
|
-
import { Fragment as
|
|
4627
|
+
import { Fragment as Fragment6, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3692
4628
|
var InputStep = ({
|
|
3693
4629
|
displayValues,
|
|
3694
4630
|
onOpenTokenModal,
|
|
@@ -3707,8 +4643,11 @@ var InputStep = ({
|
|
|
3707
4643
|
const isQuoting = SwapMachineCtx.useSelector((s) => s.matches("quoting"));
|
|
3708
4644
|
const {
|
|
3709
4645
|
sendAddress,
|
|
4646
|
+
walletSendAddress,
|
|
4647
|
+
setCustomRefundAddress,
|
|
3710
4648
|
receiveAddress,
|
|
3711
4649
|
isReceiveAddressResolving,
|
|
4650
|
+
isReceiveAddressBlocked,
|
|
3712
4651
|
setCustomReceiveAddress,
|
|
3713
4652
|
evm,
|
|
3714
4653
|
bitcoin: bitcoin3,
|
|
@@ -3722,11 +4661,11 @@ var InputStep = ({
|
|
|
3722
4661
|
const isSellAmountReadOnly = displayValues.isExactOutput && isBuyAmountLocked;
|
|
3723
4662
|
const isSellAmountPending = displayValues.isExactOutput && displayValues.isLoadingRates;
|
|
3724
4663
|
const isBuyAmountPending = !displayValues.isExactOutput && displayValues.isLoadingRates;
|
|
3725
|
-
const sellAmountCrypto =
|
|
4664
|
+
const sellAmountCrypto = useMemo12(
|
|
3726
4665
|
() => displayValues.sellAmountBaseUnit ? formatAmount(displayValues.sellAmountBaseUnit, context.sellAsset.precision, 6) : "",
|
|
3727
4666
|
[displayValues.sellAmountBaseUnit, context.sellAsset.precision]
|
|
3728
4667
|
);
|
|
3729
|
-
const buyAmountValue =
|
|
4668
|
+
const buyAmountValue = useMemo12(() => {
|
|
3730
4669
|
if (displayValues.isExactOutput) return context.buyAmount;
|
|
3731
4670
|
if (!displayValues.buyAmount) return "";
|
|
3732
4671
|
return formatAmount(displayValues.buyAmount, context.buyAsset.precision);
|
|
@@ -3736,7 +4675,7 @@ var InputStep = ({
|
|
|
3736
4675
|
context.buyAmount,
|
|
3737
4676
|
context.buyAsset.precision
|
|
3738
4677
|
]);
|
|
3739
|
-
const sellAmountValue =
|
|
4678
|
+
const sellAmountValue = useMemo12(() => {
|
|
3740
4679
|
if (!displayValues.isExactOutput) {
|
|
3741
4680
|
return context.isSellAmountFiat ? context.sellAmountFiat : context.sellAmount;
|
|
3742
4681
|
}
|
|
@@ -3756,24 +4695,40 @@ var InputStep = ({
|
|
|
3756
4695
|
context.sellAsset.precision,
|
|
3757
4696
|
sellAmountCrypto
|
|
3758
4697
|
]);
|
|
3759
|
-
const
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
4698
|
+
const selectedRate = context.selectedRate ?? displayValues.rates?.[0];
|
|
4699
|
+
const isDepositFlowAvailable = shouldUseDepositFlow({
|
|
4700
|
+
rate: selectedRate,
|
|
4701
|
+
hasWalletForSellChain: !!walletSendAddress
|
|
4702
|
+
});
|
|
4703
|
+
const isSellChainTypeConnected = context.isSellAssetEvm ? evm.isConnected : context.isSellAssetUtxo ? bitcoin3.isConnected : context.isSellAssetSolana ? solana3.isConnected : false;
|
|
4704
|
+
const needsAnAddress = !receiveAddress && !isReceiveAddressResolving || isDepositFlowAvailable && !sendAddress;
|
|
4705
|
+
const {
|
|
4706
|
+
text: buttonText,
|
|
4707
|
+
disabled: isButtonDisabled,
|
|
4708
|
+
action: buttonAction
|
|
4709
|
+
} = useMemo12(() => {
|
|
3766
4710
|
const drivingAmount = displayValues.isExactOutput ? context.buyAmountBaseUnit : context.sellAmount;
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
4711
|
+
return getInputCta({
|
|
4712
|
+
isDepositRoute: isDepositFlowAvailable,
|
|
4713
|
+
hasWalletForSellChain: !!walletSendAddress,
|
|
4714
|
+
isSellChainTypeConnected,
|
|
4715
|
+
isUnsupportedChain,
|
|
4716
|
+
allowShapeshiftRedirect,
|
|
4717
|
+
hasReceiveAddress: !!receiveAddress,
|
|
4718
|
+
hasSendAddress: !!sendAddress,
|
|
4719
|
+
hasAmount: !!drivingAmount && drivingAmount !== "0",
|
|
4720
|
+
isLoadingRates: displayValues.isLoadingRates,
|
|
4721
|
+
hasRates: !!displayValues.rates?.length,
|
|
4722
|
+
hasRatesError: !!displayValues.ratesError
|
|
4723
|
+
});
|
|
3772
4724
|
}, [
|
|
4725
|
+
isDepositFlowAvailable,
|
|
4726
|
+
walletSendAddress,
|
|
4727
|
+
isSellChainTypeConnected,
|
|
3773
4728
|
isUnsupportedChain,
|
|
3774
4729
|
allowShapeshiftRedirect,
|
|
3775
|
-
sendAddress,
|
|
3776
4730
|
receiveAddress,
|
|
4731
|
+
sendAddress,
|
|
3777
4732
|
context.sellAmount,
|
|
3778
4733
|
displayValues.isExactOutput,
|
|
3779
4734
|
context.buyAmountBaseUnit,
|
|
@@ -3781,13 +4736,13 @@ var InputStep = ({
|
|
|
3781
4736
|
displayValues.ratesError,
|
|
3782
4737
|
displayValues.rates
|
|
3783
4738
|
]);
|
|
3784
|
-
return /* @__PURE__ */
|
|
3785
|
-
/* @__PURE__ */
|
|
3786
|
-
/* @__PURE__ */
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
/* @__PURE__ */
|
|
3789
|
-
context.isSellAmountFiat && /* @__PURE__ */
|
|
3790
|
-
/* @__PURE__ */
|
|
4739
|
+
return /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
4740
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-swap-container", children: [
|
|
4741
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-token-section ssw-sell", children: [
|
|
4742
|
+
/* @__PURE__ */ jsx9("div", { className: "ssw-section-header", children: /* @__PURE__ */ jsx9("span", { className: "ssw-section-label", children: "Sell" }) }),
|
|
4743
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-input-row", children: [
|
|
4744
|
+
context.isSellAmountFiat && /* @__PURE__ */ jsx9("span", { className: "ssw-fiat-prefix", children: "$" }),
|
|
4745
|
+
/* @__PURE__ */ jsx9(
|
|
3791
4746
|
"input",
|
|
3792
4747
|
{
|
|
3793
4748
|
type: "text",
|
|
@@ -3803,26 +4758,26 @@ var InputStep = ({
|
|
|
3803
4758
|
}
|
|
3804
4759
|
}
|
|
3805
4760
|
),
|
|
3806
|
-
/* @__PURE__ */
|
|
4761
|
+
/* @__PURE__ */ jsxs9(
|
|
3807
4762
|
"button",
|
|
3808
4763
|
{
|
|
3809
4764
|
className: "ssw-token-btn",
|
|
3810
4765
|
onClick: () => onOpenTokenModal("sell"),
|
|
3811
4766
|
type: "button",
|
|
3812
4767
|
children: [
|
|
3813
|
-
context.sellAsset.icon ? /* @__PURE__ */
|
|
4768
|
+
context.sellAsset.icon ? /* @__PURE__ */ jsx9(
|
|
3814
4769
|
"img",
|
|
3815
4770
|
{
|
|
3816
4771
|
src: context.sellAsset.icon,
|
|
3817
4772
|
alt: context.sellAsset.symbol,
|
|
3818
4773
|
className: "ssw-token-icon"
|
|
3819
4774
|
}
|
|
3820
|
-
) : /* @__PURE__ */
|
|
3821
|
-
/* @__PURE__ */
|
|
3822
|
-
/* @__PURE__ */
|
|
3823
|
-
/* @__PURE__ */
|
|
4775
|
+
) : /* @__PURE__ */ jsx9("div", { className: "ssw-token-icon-placeholder", children: context.sellAsset.symbol.charAt(0) }),
|
|
4776
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-token-info", children: [
|
|
4777
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-token-symbol", children: context.sellAsset.symbol }),
|
|
4778
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-token-chain", children: displayValues.sellChainInfo?.name ?? context.sellAsset.networkName ?? context.sellAsset.name })
|
|
3824
4779
|
] }),
|
|
3825
|
-
/* @__PURE__ */
|
|
4780
|
+
/* @__PURE__ */ jsx9(
|
|
3826
4781
|
"svg",
|
|
3827
4782
|
{
|
|
3828
4783
|
width: "16",
|
|
@@ -3831,23 +4786,23 @@ var InputStep = ({
|
|
|
3831
4786
|
fill: "none",
|
|
3832
4787
|
stroke: "currentColor",
|
|
3833
4788
|
strokeWidth: "2",
|
|
3834
|
-
children: /* @__PURE__ */
|
|
4789
|
+
children: /* @__PURE__ */ jsx9("path", { d: "M9 18l6-6-6-6" })
|
|
3835
4790
|
}
|
|
3836
4791
|
)
|
|
3837
4792
|
]
|
|
3838
4793
|
}
|
|
3839
4794
|
)
|
|
3840
4795
|
] }),
|
|
3841
|
-
/* @__PURE__ */
|
|
3842
|
-
!displayValues.sellAssetUsdPrice ? /* @__PURE__ */
|
|
4796
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-section-footer", children: [
|
|
4797
|
+
!displayValues.sellAssetUsdPrice ? /* @__PURE__ */ jsx9("span", { className: "ssw-usd-value" }) : /* @__PURE__ */ jsxs9(
|
|
3843
4798
|
"button",
|
|
3844
4799
|
{
|
|
3845
4800
|
type: "button",
|
|
3846
4801
|
className: "ssw-usd-value ssw-usd-value-toggle",
|
|
3847
4802
|
onClick: () => onToggleSellFiat(displayValues.sellAssetUsdPrice),
|
|
3848
4803
|
children: [
|
|
3849
|
-
/* @__PURE__ */
|
|
3850
|
-
/* @__PURE__ */
|
|
4804
|
+
/* @__PURE__ */ jsx9("span", { children: context.isSellAmountFiat ? `\u2248 ${sellAmountCrypto || "0"} ${context.sellAsset.symbol}` : displayValues.sellUsdValue }),
|
|
4805
|
+
/* @__PURE__ */ jsx9(
|
|
3851
4806
|
"svg",
|
|
3852
4807
|
{
|
|
3853
4808
|
width: "12",
|
|
@@ -3857,16 +4812,16 @@ var InputStep = ({
|
|
|
3857
4812
|
stroke: "currentColor",
|
|
3858
4813
|
strokeWidth: "2",
|
|
3859
4814
|
"aria-hidden": "true",
|
|
3860
|
-
children: /* @__PURE__ */
|
|
4815
|
+
children: /* @__PURE__ */ jsx9("path", { d: "M7 16V4M7 4L3 8M7 4l4 4M17 8v12M17 20l4-4M17 20l-4-4" })
|
|
3861
4816
|
}
|
|
3862
4817
|
)
|
|
3863
4818
|
]
|
|
3864
4819
|
}
|
|
3865
4820
|
),
|
|
3866
|
-
hasAnyWalletAddress && (displayValues.isSellBalanceLoading ? /* @__PURE__ */
|
|
4821
|
+
hasAnyWalletAddress && (displayValues.isSellBalanceLoading ? /* @__PURE__ */ jsx9("span", { className: "ssw-balance-skeleton" }) : displayValues.sellAssetBalance ? /* @__PURE__ */ jsxs9("span", { className: "ssw-balance", children: [
|
|
3867
4822
|
"Balance: ",
|
|
3868
4823
|
displayValues.sellAssetBalance.balanceFormatted,
|
|
3869
|
-
displayValues.sellBalanceFiatValue && /* @__PURE__ */
|
|
4824
|
+
displayValues.sellBalanceFiatValue && /* @__PURE__ */ jsxs9("span", { className: "ssw-balance-fiat", children: [
|
|
3870
4825
|
" ",
|
|
3871
4826
|
"(",
|
|
3872
4827
|
displayValues.sellBalanceFiatValue,
|
|
@@ -3875,14 +4830,14 @@ var InputStep = ({
|
|
|
3875
4830
|
] }) : null)
|
|
3876
4831
|
] })
|
|
3877
4832
|
] }),
|
|
3878
|
-
/* @__PURE__ */
|
|
4833
|
+
/* @__PURE__ */ jsx9("div", { className: "ssw-swap-divider", children: /* @__PURE__ */ jsx9(
|
|
3879
4834
|
"button",
|
|
3880
4835
|
{
|
|
3881
4836
|
className: "ssw-swap-btn",
|
|
3882
4837
|
onClick: isBuyAssetLocked ? void 0 : onSwapTokens,
|
|
3883
4838
|
disabled: isBuyAssetLocked,
|
|
3884
4839
|
type: "button",
|
|
3885
|
-
children: /* @__PURE__ */
|
|
4840
|
+
children: /* @__PURE__ */ jsx9(
|
|
3886
4841
|
"svg",
|
|
3887
4842
|
{
|
|
3888
4843
|
width: "16",
|
|
@@ -3891,15 +4846,15 @@ var InputStep = ({
|
|
|
3891
4846
|
fill: "none",
|
|
3892
4847
|
stroke: "currentColor",
|
|
3893
4848
|
strokeWidth: "2",
|
|
3894
|
-
children: /* @__PURE__ */
|
|
4849
|
+
children: /* @__PURE__ */ jsx9("path", { d: "M12 5v14M5 12l7 7 7-7" })
|
|
3895
4850
|
}
|
|
3896
4851
|
)
|
|
3897
4852
|
}
|
|
3898
4853
|
) }),
|
|
3899
|
-
/* @__PURE__ */
|
|
3900
|
-
/* @__PURE__ */
|
|
3901
|
-
/* @__PURE__ */
|
|
3902
|
-
/* @__PURE__ */
|
|
4854
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-token-section ssw-buy", children: [
|
|
4855
|
+
/* @__PURE__ */ jsx9("div", { className: "ssw-section-header", children: /* @__PURE__ */ jsx9("span", { className: "ssw-section-label", children: "Buy" }) }),
|
|
4856
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-input-row", children: [
|
|
4857
|
+
/* @__PURE__ */ jsx9(
|
|
3903
4858
|
"input",
|
|
3904
4859
|
{
|
|
3905
4860
|
type: "text",
|
|
@@ -3914,7 +4869,7 @@ var InputStep = ({
|
|
|
3914
4869
|
}
|
|
3915
4870
|
}
|
|
3916
4871
|
),
|
|
3917
|
-
/* @__PURE__ */
|
|
4872
|
+
/* @__PURE__ */ jsxs9(
|
|
3918
4873
|
"button",
|
|
3919
4874
|
{
|
|
3920
4875
|
className: `ssw-token-btn${isBuyAssetLocked ? " ssw-token-btn-locked" : ""}`,
|
|
@@ -3922,19 +4877,19 @@ var InputStep = ({
|
|
|
3922
4877
|
disabled: isBuyAssetLocked,
|
|
3923
4878
|
type: "button",
|
|
3924
4879
|
children: [
|
|
3925
|
-
context.buyAsset.icon ? /* @__PURE__ */
|
|
4880
|
+
context.buyAsset.icon ? /* @__PURE__ */ jsx9(
|
|
3926
4881
|
"img",
|
|
3927
4882
|
{
|
|
3928
4883
|
src: context.buyAsset.icon,
|
|
3929
4884
|
alt: context.buyAsset.symbol,
|
|
3930
4885
|
className: "ssw-token-icon"
|
|
3931
4886
|
}
|
|
3932
|
-
) : /* @__PURE__ */
|
|
3933
|
-
/* @__PURE__ */
|
|
3934
|
-
/* @__PURE__ */
|
|
3935
|
-
/* @__PURE__ */
|
|
4887
|
+
) : /* @__PURE__ */ jsx9("div", { className: "ssw-token-icon-placeholder", children: context.buyAsset.symbol.charAt(0) }),
|
|
4888
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-token-info", children: [
|
|
4889
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-token-symbol", children: context.buyAsset.symbol }),
|
|
4890
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-token-chain", children: displayValues.buyChainInfo?.name ?? context.buyAsset.networkName ?? context.buyAsset.name })
|
|
3936
4891
|
] }),
|
|
3937
|
-
!isBuyAssetLocked && /* @__PURE__ */
|
|
4892
|
+
!isBuyAssetLocked && /* @__PURE__ */ jsx9(
|
|
3938
4893
|
"svg",
|
|
3939
4894
|
{
|
|
3940
4895
|
width: "16",
|
|
@@ -3943,19 +4898,19 @@ var InputStep = ({
|
|
|
3943
4898
|
fill: "none",
|
|
3944
4899
|
stroke: "currentColor",
|
|
3945
4900
|
strokeWidth: "2",
|
|
3946
|
-
children: /* @__PURE__ */
|
|
4901
|
+
children: /* @__PURE__ */ jsx9("path", { d: "M9 18l6-6-6-6" })
|
|
3947
4902
|
}
|
|
3948
4903
|
)
|
|
3949
4904
|
]
|
|
3950
4905
|
}
|
|
3951
4906
|
)
|
|
3952
4907
|
] }),
|
|
3953
|
-
/* @__PURE__ */
|
|
3954
|
-
/* @__PURE__ */
|
|
3955
|
-
hasAnyWalletAddress && (displayValues.isBuyBalanceLoading ? /* @__PURE__ */
|
|
4908
|
+
/* @__PURE__ */ jsxs9("div", { className: "ssw-section-footer", children: [
|
|
4909
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-usd-value", children: displayValues.buyUsdValue }),
|
|
4910
|
+
hasAnyWalletAddress && (displayValues.isBuyBalanceLoading ? /* @__PURE__ */ jsx9("span", { className: "ssw-balance-skeleton" }) : displayValues.buyAssetBalance ? /* @__PURE__ */ jsxs9("span", { className: "ssw-balance", children: [
|
|
3956
4911
|
"Balance: ",
|
|
3957
4912
|
displayValues.buyAssetBalance.balanceFormatted,
|
|
3958
|
-
displayValues.buyBalanceFiatValue && /* @__PURE__ */
|
|
4913
|
+
displayValues.buyBalanceFiatValue && /* @__PURE__ */ jsxs9("span", { className: "ssw-balance-fiat", children: [
|
|
3959
4914
|
" (",
|
|
3960
4915
|
displayValues.buyBalanceFiatValue,
|
|
3961
4916
|
")"
|
|
@@ -3963,18 +4918,34 @@ var InputStep = ({
|
|
|
3963
4918
|
] }) : null)
|
|
3964
4919
|
] })
|
|
3965
4920
|
] }),
|
|
3966
|
-
!isUnsupportedChain && hasActiveWallet && /* @__PURE__ */
|
|
3967
|
-
|
|
4921
|
+
(!isUnsupportedChain && hasActiveWallet || isDepositFlowAvailable) && /* @__PURE__ */ jsxs9(
|
|
4922
|
+
"div",
|
|
3968
4923
|
{
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
4924
|
+
className: `ssw-address-group${needsAnAddress ? " ssw-attention" : ""}${isReceiveAddressBlocked ? " ssw-address-group-invalid" : ""}`,
|
|
4925
|
+
children: [
|
|
4926
|
+
/* @__PURE__ */ jsx9(
|
|
4927
|
+
ReceiveAddressRow,
|
|
4928
|
+
{
|
|
4929
|
+
receiveAddress,
|
|
4930
|
+
isResolving: isReceiveAddressResolving,
|
|
4931
|
+
buyChainId,
|
|
4932
|
+
isLocked: isReceiveAddressLocked,
|
|
4933
|
+
onSetCustomReceiveAddress: setCustomReceiveAddress
|
|
4934
|
+
}
|
|
4935
|
+
),
|
|
4936
|
+
isDepositFlowAvailable && /* @__PURE__ */ jsx9(
|
|
4937
|
+
RefundAddressRow,
|
|
4938
|
+
{
|
|
4939
|
+
refundAddress: sendAddress,
|
|
4940
|
+
sellChainId: context.sellAsset.chainId,
|
|
4941
|
+
onSetCustomRefundAddress: setCustomRefundAddress
|
|
4942
|
+
}
|
|
4943
|
+
)
|
|
4944
|
+
]
|
|
3974
4945
|
}
|
|
3975
4946
|
)
|
|
3976
4947
|
] }),
|
|
3977
|
-
amountBaseUnit && amountBaseUnit !== "0" && (displayValues.rates?.length || displayValues.isLoadingRates) && /* @__PURE__ */
|
|
4948
|
+
amountBaseUnit && amountBaseUnit !== "0" && (displayValues.rates?.length || displayValues.isLoadingRates) && /* @__PURE__ */ jsx9("div", { className: "ssw-quotes", children: /* @__PURE__ */ jsx9(
|
|
3978
4949
|
QuoteSelector,
|
|
3979
4950
|
{
|
|
3980
4951
|
rates: displayValues.rates ?? [],
|
|
@@ -3990,20 +4961,20 @@ var InputStep = ({
|
|
|
3990
4961
|
buyAssetUsdPrice: displayValues.buyAssetUsdPrice
|
|
3991
4962
|
}
|
|
3992
4963
|
) }),
|
|
3993
|
-
displayValues.networkFeeDisplay && /* @__PURE__ */
|
|
3994
|
-
/* @__PURE__ */
|
|
3995
|
-
/* @__PURE__ */
|
|
4964
|
+
displayValues.networkFeeDisplay && /* @__PURE__ */ jsxs9("div", { className: "ssw-network-fee", children: [
|
|
4965
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-network-fee-label", children: "Est. network fee" }),
|
|
4966
|
+
/* @__PURE__ */ jsx9("span", { className: "ssw-network-fee-value", children: displayValues.networkFeeDisplay })
|
|
3996
4967
|
] }),
|
|
3997
|
-
/* @__PURE__ */
|
|
4968
|
+
/* @__PURE__ */ jsx9(
|
|
3998
4969
|
"button",
|
|
3999
4970
|
{
|
|
4000
|
-
className: `ssw-action-btn ${
|
|
4971
|
+
className: `ssw-action-btn ${buttonAction === "redirect" ? "ssw-secondary" : ""}`,
|
|
4001
4972
|
disabled: isButtonDisabled || isQuoting,
|
|
4002
|
-
onClick: onButtonClick,
|
|
4973
|
+
onClick: () => onButtonClick(buttonAction),
|
|
4003
4974
|
type: "button",
|
|
4004
4975
|
style: isQuoting ? { opacity: 0.7 } : void 0,
|
|
4005
|
-
children: isQuoting ? /* @__PURE__ */
|
|
4006
|
-
/* @__PURE__ */
|
|
4976
|
+
children: isQuoting ? /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
4977
|
+
/* @__PURE__ */ jsxs9(
|
|
4007
4978
|
"svg",
|
|
4008
4979
|
{
|
|
4009
4980
|
className: "ssw-spinner",
|
|
@@ -4015,24 +4986,37 @@ var InputStep = ({
|
|
|
4015
4986
|
strokeWidth: "2",
|
|
4016
4987
|
style: { display: "inline-block", verticalAlign: "middle", marginRight: "6px" },
|
|
4017
4988
|
children: [
|
|
4018
|
-
/* @__PURE__ */
|
|
4019
|
-
/* @__PURE__ */
|
|
4989
|
+
/* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "10", opacity: "0.25" }),
|
|
4990
|
+
/* @__PURE__ */ jsx9("path", { d: "M12 2a10 10 0 0 1 10 10" })
|
|
4020
4991
|
]
|
|
4021
4992
|
}
|
|
4022
4993
|
),
|
|
4023
4994
|
"Fetching Quote\u2026"
|
|
4024
4995
|
] }) : buttonText
|
|
4025
4996
|
}
|
|
4026
|
-
)
|
|
4997
|
+
),
|
|
4998
|
+
isUnsupportedChain && isDepositFlowAvailable && allowShapeshiftRedirect && buttonAction !== "redirect" && /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
4999
|
+
/* @__PURE__ */ jsx9("div", { className: "ssw-or-divider", "aria-hidden": "true", children: /* @__PURE__ */ jsx9("span", { children: "or" }) }),
|
|
5000
|
+
/* @__PURE__ */ jsx9(
|
|
5001
|
+
"button",
|
|
5002
|
+
{
|
|
5003
|
+
className: "ssw-action-btn ssw-secondary",
|
|
5004
|
+
disabled: isQuoting,
|
|
5005
|
+
onClick: () => onButtonClick("redirect"),
|
|
5006
|
+
type: "button",
|
|
5007
|
+
children: "Proceed on ShapeShift"
|
|
5008
|
+
}
|
|
5009
|
+
)
|
|
5010
|
+
] })
|
|
4027
5011
|
] });
|
|
4028
5012
|
};
|
|
4029
5013
|
|
|
4030
5014
|
// src/components/SettingsModal.tsx
|
|
4031
|
-
import { useCallback as
|
|
4032
|
-
import { jsx as
|
|
5015
|
+
import { useCallback as useCallback11, useEffect as useEffect11, useState as useState8 } from "react";
|
|
5016
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4033
5017
|
var SLIPPAGE_PRESETS = ["0.1", "0.5", "1.0"];
|
|
4034
5018
|
var useLockBodyScroll2 = (isLocked) => {
|
|
4035
|
-
|
|
5019
|
+
useEffect11(() => {
|
|
4036
5020
|
if (!isLocked) return;
|
|
4037
5021
|
const originalOverflow = document.body.style.overflow;
|
|
4038
5022
|
document.body.style.overflow = "hidden";
|
|
@@ -4044,9 +5028,9 @@ var useLockBodyScroll2 = (isLocked) => {
|
|
|
4044
5028
|
var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
4045
5029
|
const slippage = SwapMachineCtx.useSelector((s) => s.context.slippage);
|
|
4046
5030
|
useLockBodyScroll2(isOpen);
|
|
4047
|
-
const [customSlippage, setCustomSlippage] =
|
|
4048
|
-
const [isCustom, setIsCustom] =
|
|
4049
|
-
const handlePresetClick =
|
|
5031
|
+
const [customSlippage, setCustomSlippage] = useState8("");
|
|
5032
|
+
const [isCustom, setIsCustom] = useState8(!SLIPPAGE_PRESETS.includes(slippage));
|
|
5033
|
+
const handlePresetClick = useCallback11(
|
|
4050
5034
|
(preset) => {
|
|
4051
5035
|
setIsCustom(false);
|
|
4052
5036
|
setCustomSlippage("");
|
|
@@ -4054,7 +5038,7 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4054
5038
|
},
|
|
4055
5039
|
[onSlippageChange]
|
|
4056
5040
|
);
|
|
4057
|
-
const handleCustomChange =
|
|
5041
|
+
const handleCustomChange = useCallback11(
|
|
4058
5042
|
(value) => {
|
|
4059
5043
|
const sanitized = value.replace(/[^0-9.]/g, "");
|
|
4060
5044
|
const parts = sanitized.split(".");
|
|
@@ -4068,7 +5052,7 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4068
5052
|
},
|
|
4069
5053
|
[onSlippageChange]
|
|
4070
5054
|
);
|
|
4071
|
-
const handleBackdropClick =
|
|
5055
|
+
const handleBackdropClick = useCallback11(
|
|
4072
5056
|
(e) => {
|
|
4073
5057
|
if (e.target === e.currentTarget) {
|
|
4074
5058
|
onClose();
|
|
@@ -4082,7 +5066,7 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4082
5066
|
const isVeryHighSlippage = currentSlippageNum > 5;
|
|
4083
5067
|
return (
|
|
4084
5068
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
4085
|
-
/* @__PURE__ */
|
|
5069
|
+
/* @__PURE__ */ jsx10(
|
|
4086
5070
|
"div",
|
|
4087
5071
|
{
|
|
4088
5072
|
className: "ssw-modal-backdrop",
|
|
@@ -4091,10 +5075,10 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4091
5075
|
role: "dialog",
|
|
4092
5076
|
"aria-modal": "true",
|
|
4093
5077
|
"aria-labelledby": "settings-modal-title",
|
|
4094
|
-
children: /* @__PURE__ */
|
|
4095
|
-
/* @__PURE__ */
|
|
4096
|
-
/* @__PURE__ */
|
|
4097
|
-
/* @__PURE__ */
|
|
5078
|
+
children: /* @__PURE__ */ jsxs10("div", { className: "ssw-settings-modal", children: [
|
|
5079
|
+
/* @__PURE__ */ jsxs10("div", { className: "ssw-modal-header", children: [
|
|
5080
|
+
/* @__PURE__ */ jsx10("h2", { id: "settings-modal-title", className: "ssw-modal-title", children: "Settings" }),
|
|
5081
|
+
/* @__PURE__ */ jsx10("button", { className: "ssw-modal-close", onClick: onClose, type: "button", children: /* @__PURE__ */ jsx10(
|
|
4098
5082
|
"svg",
|
|
4099
5083
|
{
|
|
4100
5084
|
width: "20",
|
|
@@ -4103,20 +5087,20 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4103
5087
|
fill: "none",
|
|
4104
5088
|
stroke: "currentColor",
|
|
4105
5089
|
strokeWidth: "2",
|
|
4106
|
-
children: /* @__PURE__ */
|
|
5090
|
+
children: /* @__PURE__ */ jsx10("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
4107
5091
|
}
|
|
4108
5092
|
) })
|
|
4109
5093
|
] }),
|
|
4110
|
-
/* @__PURE__ */
|
|
4111
|
-
/* @__PURE__ */
|
|
4112
|
-
/* @__PURE__ */
|
|
4113
|
-
/* @__PURE__ */
|
|
5094
|
+
/* @__PURE__ */ jsx10("div", { className: "ssw-settings-content", children: /* @__PURE__ */ jsxs10("div", { className: "ssw-settings-section", children: [
|
|
5095
|
+
/* @__PURE__ */ jsxs10("div", { className: "ssw-settings-label", children: [
|
|
5096
|
+
/* @__PURE__ */ jsx10("span", { children: "Slippage Tolerance" }),
|
|
5097
|
+
/* @__PURE__ */ jsx10(
|
|
4114
5098
|
"button",
|
|
4115
5099
|
{
|
|
4116
5100
|
className: "ssw-info-btn",
|
|
4117
5101
|
type: "button",
|
|
4118
5102
|
title: "Maximum price difference you're willing to accept",
|
|
4119
|
-
children: /* @__PURE__ */
|
|
5103
|
+
children: /* @__PURE__ */ jsxs10(
|
|
4120
5104
|
"svg",
|
|
4121
5105
|
{
|
|
4122
5106
|
width: "14",
|
|
@@ -4126,16 +5110,16 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4126
5110
|
stroke: "currentColor",
|
|
4127
5111
|
strokeWidth: "2",
|
|
4128
5112
|
children: [
|
|
4129
|
-
/* @__PURE__ */
|
|
4130
|
-
/* @__PURE__ */
|
|
5113
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5114
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 16v-4M12 8h.01" })
|
|
4131
5115
|
]
|
|
4132
5116
|
}
|
|
4133
5117
|
)
|
|
4134
5118
|
}
|
|
4135
5119
|
)
|
|
4136
5120
|
] }),
|
|
4137
|
-
/* @__PURE__ */
|
|
4138
|
-
SLIPPAGE_PRESETS.map((preset) => /* @__PURE__ */
|
|
5121
|
+
/* @__PURE__ */ jsxs10("div", { className: "ssw-slippage-options", children: [
|
|
5122
|
+
SLIPPAGE_PRESETS.map((preset) => /* @__PURE__ */ jsxs10(
|
|
4139
5123
|
"button",
|
|
4140
5124
|
{
|
|
4141
5125
|
className: `ssw-slippage-btn ${!isCustom && slippage === preset ? "ssw-selected" : ""}`,
|
|
@@ -4148,8 +5132,8 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4148
5132
|
},
|
|
4149
5133
|
preset
|
|
4150
5134
|
)),
|
|
4151
|
-
/* @__PURE__ */
|
|
4152
|
-
/* @__PURE__ */
|
|
5135
|
+
/* @__PURE__ */ jsxs10("div", { className: `ssw-slippage-custom ${isCustom ? "ssw-selected" : ""}`, children: [
|
|
5136
|
+
/* @__PURE__ */ jsx10(
|
|
4153
5137
|
"input",
|
|
4154
5138
|
{
|
|
4155
5139
|
type: "text",
|
|
@@ -4162,11 +5146,11 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4162
5146
|
}
|
|
4163
5147
|
}
|
|
4164
5148
|
),
|
|
4165
|
-
/* @__PURE__ */
|
|
5149
|
+
/* @__PURE__ */ jsx10("span", { className: "ssw-slippage-suffix", children: "%" })
|
|
4166
5150
|
] })
|
|
4167
5151
|
] }),
|
|
4168
|
-
isHighSlippage && /* @__PURE__ */
|
|
4169
|
-
/* @__PURE__ */
|
|
5152
|
+
isHighSlippage && /* @__PURE__ */ jsxs10("div", { className: `ssw-slippage-warning ${isVeryHighSlippage ? "ssw-error" : ""}`, children: [
|
|
5153
|
+
/* @__PURE__ */ jsx10(
|
|
4170
5154
|
"svg",
|
|
4171
5155
|
{
|
|
4172
5156
|
width: "16",
|
|
@@ -4175,10 +5159,10 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4175
5159
|
fill: "none",
|
|
4176
5160
|
stroke: "currentColor",
|
|
4177
5161
|
strokeWidth: "2",
|
|
4178
|
-
children: /* @__PURE__ */
|
|
5162
|
+
children: /* @__PURE__ */ jsx10("path", { d: "M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0zM12 9v4M12 17h.01" })
|
|
4179
5163
|
}
|
|
4180
5164
|
),
|
|
4181
|
-
/* @__PURE__ */
|
|
5165
|
+
/* @__PURE__ */ jsx10("span", { children: isVeryHighSlippage ? "Very high slippage. Your transaction may be frontrun." : "High slippage may result in unfavorable rates." })
|
|
4182
5166
|
] })
|
|
4183
5167
|
] }) })
|
|
4184
5168
|
] })
|
|
@@ -4188,11 +5172,11 @@ var SettingsModal = ({ isOpen, onClose, onSlippageChange }) => {
|
|
|
4188
5172
|
};
|
|
4189
5173
|
|
|
4190
5174
|
// src/components/StatusStep.tsx
|
|
4191
|
-
import { useMemo as
|
|
4192
|
-
import { Fragment as
|
|
4193
|
-
var ExplorerLink = ({ url }) => /* @__PURE__ */
|
|
4194
|
-
|
|
4195
|
-
/* @__PURE__ */
|
|
5175
|
+
import { useMemo as useMemo13 } from "react";
|
|
5176
|
+
import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5177
|
+
var ExplorerLink = ({ url, label }) => /* @__PURE__ */ jsxs11("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "ssw-step-explorer-link", children: [
|
|
5178
|
+
label,
|
|
5179
|
+
/* @__PURE__ */ jsx11(
|
|
4196
5180
|
"svg",
|
|
4197
5181
|
{
|
|
4198
5182
|
width: "12",
|
|
@@ -4201,7 +5185,7 @@ var ExplorerLink = ({ url }) => /* @__PURE__ */ jsxs8("a", { href: url, target:
|
|
|
4201
5185
|
fill: "none",
|
|
4202
5186
|
stroke: "currentColor",
|
|
4203
5187
|
strokeWidth: "2",
|
|
4204
|
-
children: /* @__PURE__ */
|
|
5188
|
+
children: /* @__PURE__ */ jsx11("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6M15 3h6v6M10 14L21 3" })
|
|
4205
5189
|
}
|
|
4206
5190
|
)
|
|
4207
5191
|
] });
|
|
@@ -4211,20 +5195,33 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4211
5195
|
const isComplete = SwapMachineCtx.useSelector((s) => s.matches("complete"));
|
|
4212
5196
|
const isError = SwapMachineCtx.useSelector((s) => s.matches("error"));
|
|
4213
5197
|
const { send } = SwapMachineCtx.useActorRef();
|
|
4214
|
-
const {
|
|
4215
|
-
|
|
5198
|
+
const {
|
|
5199
|
+
sellAsset,
|
|
5200
|
+
buyAsset,
|
|
5201
|
+
quote,
|
|
5202
|
+
txHash,
|
|
5203
|
+
error,
|
|
5204
|
+
errorSource,
|
|
5205
|
+
retryCount,
|
|
5206
|
+
isSellAssetUtxo,
|
|
5207
|
+
isSellAssetSolana,
|
|
5208
|
+
isDepositFlow
|
|
5209
|
+
} = context;
|
|
5210
|
+
const explorerLabel = isDepositFlow ? "View deposit" : "View on Explorer";
|
|
5211
|
+
const hasStoppedTracking = errorSource === "TRACKING_TIMEOUT";
|
|
5212
|
+
const explorerUrl = useMemo13(() => {
|
|
4216
5213
|
if (!txHash) return void 0;
|
|
4217
5214
|
if (isSellAssetUtxo) return `https://mempool.space/tx/${txHash}`;
|
|
4218
5215
|
if (isSellAssetSolana) return `https://solscan.io/tx/${txHash}`;
|
|
4219
5216
|
return `${sellAsset.explorerTxLink ?? "https://etherscan.io/tx/"}${txHash}`;
|
|
4220
5217
|
}, [txHash, isSellAssetUtxo, isSellAssetSolana, sellAsset.explorerTxLink]);
|
|
4221
|
-
const truncatedError =
|
|
5218
|
+
const truncatedError = useMemo13(
|
|
4222
5219
|
() => error && error.length > 100 ? `${error.slice(0, 100)}\u2026` : error,
|
|
4223
5220
|
[error]
|
|
4224
5221
|
);
|
|
4225
|
-
return /* @__PURE__ */
|
|
4226
|
-
isPolling && /* @__PURE__ */
|
|
4227
|
-
/* @__PURE__ */
|
|
5222
|
+
return /* @__PURE__ */ jsxs11("div", { className: "ssw-step-screen", children: [
|
|
5223
|
+
isPolling && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
5224
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-icon-circle ssw-ic-accent", children: /* @__PURE__ */ jsxs11(
|
|
4228
5225
|
"svg",
|
|
4229
5226
|
{
|
|
4230
5227
|
className: "ssw-spinner",
|
|
@@ -4235,17 +5232,26 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4235
5232
|
stroke: "currentColor",
|
|
4236
5233
|
strokeWidth: "2",
|
|
4237
5234
|
children: [
|
|
4238
|
-
/* @__PURE__ */
|
|
4239
|
-
/* @__PURE__ */
|
|
5235
|
+
/* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "10", opacity: "0.25" }),
|
|
5236
|
+
/* @__PURE__ */ jsx11("path", { d: "M12 2a10 10 0 0 1 10 10" })
|
|
4240
5237
|
]
|
|
4241
5238
|
}
|
|
4242
5239
|
) }),
|
|
4243
|
-
/* @__PURE__ */
|
|
4244
|
-
/* @__PURE__ */
|
|
4245
|
-
explorerUrl && /* @__PURE__ */
|
|
5240
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-title", children: isDepositFlow ? "Swap in Progress" : "Confirming Transaction" }),
|
|
5241
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-subtitle", children: isDepositFlow ? `Deposit received. Waiting for ${quote?.swapperName ?? "the provider"} to send your ${buyAsset.symbol}.` : "Your swap is being processed\u2026" }),
|
|
5242
|
+
explorerUrl && /* @__PURE__ */ jsx11(ExplorerLink, { url: explorerUrl, label: explorerLabel }),
|
|
5243
|
+
isDepositFlow && !isPayment && /* @__PURE__ */ jsx11("div", { className: "ssw-step-actions", children: /* @__PURE__ */ jsx11(
|
|
5244
|
+
"button",
|
|
5245
|
+
{
|
|
5246
|
+
className: "ssw-action-btn ssw-secondary",
|
|
5247
|
+
onClick: () => send({ type: "RESET" }),
|
|
5248
|
+
type: "button",
|
|
5249
|
+
children: "New Swap"
|
|
5250
|
+
}
|
|
5251
|
+
) })
|
|
4246
5252
|
] }),
|
|
4247
|
-
isComplete && /* @__PURE__ */
|
|
4248
|
-
/* @__PURE__ */
|
|
5253
|
+
isComplete && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
5254
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-icon-circle ssw-ic-success", children: /* @__PURE__ */ jsx11(
|
|
4249
5255
|
"svg",
|
|
4250
5256
|
{
|
|
4251
5257
|
width: "32",
|
|
@@ -4254,18 +5260,18 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4254
5260
|
fill: "none",
|
|
4255
5261
|
stroke: "currentColor",
|
|
4256
5262
|
strokeWidth: "2.5",
|
|
4257
|
-
children: /* @__PURE__ */
|
|
5263
|
+
children: /* @__PURE__ */ jsx11("path", { d: "M20 6L9 17l-5-5" })
|
|
4258
5264
|
}
|
|
4259
5265
|
) }),
|
|
4260
|
-
/* @__PURE__ */
|
|
4261
|
-
/* @__PURE__ */
|
|
5266
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-title", children: "Swap Complete!" }),
|
|
5267
|
+
/* @__PURE__ */ jsxs11("div", { className: "ssw-step-subtitle", children: [
|
|
4262
5268
|
"Swapped ",
|
|
4263
5269
|
sellAsset.symbol,
|
|
4264
5270
|
" for ",
|
|
4265
5271
|
buyAsset.symbol
|
|
4266
5272
|
] }),
|
|
4267
|
-
explorerUrl && /* @__PURE__ */
|
|
4268
|
-
!isPayment && /* @__PURE__ */
|
|
5273
|
+
explorerUrl && /* @__PURE__ */ jsx11(ExplorerLink, { url: explorerUrl, label: explorerLabel }),
|
|
5274
|
+
!isPayment && /* @__PURE__ */ jsx11("div", { className: "ssw-step-actions", children: /* @__PURE__ */ jsx11(
|
|
4269
5275
|
"button",
|
|
4270
5276
|
{
|
|
4271
5277
|
className: "ssw-action-btn",
|
|
@@ -4275,26 +5281,33 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4275
5281
|
}
|
|
4276
5282
|
) })
|
|
4277
5283
|
] }),
|
|
4278
|
-
isError && /* @__PURE__ */
|
|
4279
|
-
/* @__PURE__ */
|
|
4280
|
-
"
|
|
5284
|
+
isError && /* @__PURE__ */ jsxs11(Fragment7, { children: [
|
|
5285
|
+
/* @__PURE__ */ jsx11(
|
|
5286
|
+
"div",
|
|
4281
5287
|
{
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
5288
|
+
className: `ssw-step-icon-circle ${hasStoppedTracking ? "ssw-ic-accent" : "ssw-ic-error"}`,
|
|
5289
|
+
children: /* @__PURE__ */ jsxs11(
|
|
5290
|
+
"svg",
|
|
5291
|
+
{
|
|
5292
|
+
width: "32",
|
|
5293
|
+
height: "32",
|
|
5294
|
+
viewBox: "0 0 24 24",
|
|
5295
|
+
fill: "none",
|
|
5296
|
+
stroke: "currentColor",
|
|
5297
|
+
strokeWidth: "2",
|
|
5298
|
+
children: [
|
|
5299
|
+
/* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5300
|
+
/* @__PURE__ */ jsx11("path", { d: hasStoppedTracking ? "M12 7v5l3 2" : "M15 9l-6 6M9 9l6 6" })
|
|
5301
|
+
]
|
|
5302
|
+
}
|
|
5303
|
+
)
|
|
4292
5304
|
}
|
|
4293
|
-
)
|
|
4294
|
-
/* @__PURE__ */
|
|
4295
|
-
/* @__PURE__ */
|
|
4296
|
-
/* @__PURE__ */
|
|
4297
|
-
|
|
5305
|
+
),
|
|
5306
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-title", children: hasStoppedTracking ? "Still Processing" : "Transaction Failed" }),
|
|
5307
|
+
/* @__PURE__ */ jsx11("div", { className: "ssw-step-subtitle", children: truncatedError ?? "Something went wrong" }),
|
|
5308
|
+
hasStoppedTracking && explorerUrl && /* @__PURE__ */ jsx11(ExplorerLink, { url: explorerUrl, label: explorerLabel }),
|
|
5309
|
+
/* @__PURE__ */ jsxs11("div", { className: "ssw-step-actions", children: [
|
|
5310
|
+
!hasStoppedTracking && retryCount < 3 && /* @__PURE__ */ jsx11(
|
|
4298
5311
|
"button",
|
|
4299
5312
|
{
|
|
4300
5313
|
className: "ssw-action-btn",
|
|
@@ -4303,13 +5316,13 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4303
5316
|
children: "Retry"
|
|
4304
5317
|
}
|
|
4305
5318
|
),
|
|
4306
|
-
/* @__PURE__ */
|
|
5319
|
+
/* @__PURE__ */ jsx11(
|
|
4307
5320
|
"button",
|
|
4308
5321
|
{
|
|
4309
5322
|
className: "ssw-action-btn ssw-secondary",
|
|
4310
5323
|
onClick: () => send({ type: "RESET" }),
|
|
4311
5324
|
type: "button",
|
|
4312
|
-
children: "
|
|
5325
|
+
children: "New Swap"
|
|
4313
5326
|
}
|
|
4314
5327
|
)
|
|
4315
5328
|
] })
|
|
@@ -4319,12 +5332,12 @@ var StatusStep = ({ isPayment }) => {
|
|
|
4319
5332
|
|
|
4320
5333
|
// src/components/TokenSelectModal.tsx
|
|
4321
5334
|
import { bnOrZero as bnOrZero2 } from "@shapeshiftoss/utils";
|
|
4322
|
-
import { useCallback as
|
|
5335
|
+
import { useCallback as useCallback12, useEffect as useEffect12, useMemo as useMemo14, useRef as useRef11, useState as useState9 } from "react";
|
|
4323
5336
|
import { Virtuoso } from "react-virtuoso";
|
|
4324
|
-
import { Fragment as
|
|
5337
|
+
import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4325
5338
|
var VISIBLE_BUFFER = 10;
|
|
4326
5339
|
var useLockBodyScroll3 = (isLocked) => {
|
|
4327
|
-
|
|
5340
|
+
useEffect12(() => {
|
|
4328
5341
|
if (!isLocked) return;
|
|
4329
5342
|
const originalOverflow = document.body.style.overflow;
|
|
4330
5343
|
document.body.style.overflow = "hidden";
|
|
@@ -4361,10 +5374,10 @@ var TokenSelectModal = ({
|
|
|
4361
5374
|
allowShapeshiftRedirect
|
|
4362
5375
|
}) => {
|
|
4363
5376
|
useLockBodyScroll3(isOpen);
|
|
4364
|
-
const [searchQuery, setSearchQuery] =
|
|
4365
|
-
const [chainSearchQuery, setChainSearchQuery] =
|
|
4366
|
-
const [selectedChainId, setSelectedChainId] =
|
|
4367
|
-
const [visibleRange, setVisibleRange] =
|
|
5377
|
+
const [searchQuery, setSearchQuery] = useState9("");
|
|
5378
|
+
const [chainSearchQuery, setChainSearchQuery] = useState9("");
|
|
5379
|
+
const [selectedChainId, setSelectedChainId] = useState9(null);
|
|
5380
|
+
const [visibleRange, setVisibleRange] = useState9({
|
|
4368
5381
|
startIndex: 0,
|
|
4369
5382
|
endIndex: 20
|
|
4370
5383
|
});
|
|
@@ -4375,15 +5388,15 @@ var TokenSelectModal = ({
|
|
|
4375
5388
|
const { address: solanaAddress } = useSolanaSigning();
|
|
4376
5389
|
const sellAssetId = SwapMachineCtx.useSelector((s) => s.context.sellAsset.assetId);
|
|
4377
5390
|
const buyAssetId = SwapMachineCtx.useSelector((s) => s.context.buyAsset.assetId);
|
|
4378
|
-
const currentAssetIds =
|
|
4379
|
-
const chainInfoMap =
|
|
5391
|
+
const currentAssetIds = useMemo14(() => [sellAssetId, buyAssetId], [sellAssetId, buyAssetId]);
|
|
5392
|
+
const chainInfoMap = useMemo14(() => {
|
|
4380
5393
|
const map = /* @__PURE__ */ new Map();
|
|
4381
5394
|
for (const chain of chains) {
|
|
4382
5395
|
map.set(chain.chainId, chain);
|
|
4383
5396
|
}
|
|
4384
5397
|
return map;
|
|
4385
5398
|
}, [chains]);
|
|
4386
|
-
const allowedAssetChainIds =
|
|
5399
|
+
const allowedAssetChainIds = useMemo14(() => {
|
|
4387
5400
|
if (!allowedAssetIds || allowedAssetIds.length === 0) return void 0;
|
|
4388
5401
|
const chainIds = /* @__PURE__ */ new Set();
|
|
4389
5402
|
for (const asset of allAssets) {
|
|
@@ -4393,7 +5406,7 @@ var TokenSelectModal = ({
|
|
|
4393
5406
|
}
|
|
4394
5407
|
return Array.from(chainIds);
|
|
4395
5408
|
}, [allowedAssetIds, allAssets]);
|
|
4396
|
-
const filteredChains =
|
|
5409
|
+
const filteredChains = useMemo14(() => {
|
|
4397
5410
|
let enabledChains = chains.filter(
|
|
4398
5411
|
(chain) => isWidgetSupportedChainId(chain.chainId) && !disabledChainIds.includes(chain.chainId)
|
|
4399
5412
|
);
|
|
@@ -4417,7 +5430,7 @@ var TokenSelectModal = ({
|
|
|
4417
5430
|
allowedAssetChainIds,
|
|
4418
5431
|
allowShapeshiftRedirect
|
|
4419
5432
|
]);
|
|
4420
|
-
const filteredAssets =
|
|
5433
|
+
const filteredAssets = useMemo14(() => {
|
|
4421
5434
|
let assets = allAssets.filter(
|
|
4422
5435
|
(asset) => isWidgetSupportedChainId(asset.chainId) && !disabledAssetIds.includes(asset.assetId) && !disabledChainIds.includes(asset.chainId)
|
|
4423
5436
|
);
|
|
@@ -4452,14 +5465,14 @@ var TokenSelectModal = ({
|
|
|
4452
5465
|
allowedChainIds,
|
|
4453
5466
|
allowShapeshiftRedirect
|
|
4454
5467
|
]);
|
|
4455
|
-
const initialAssetPrecisions =
|
|
5468
|
+
const initialAssetPrecisions = useMemo14(() => {
|
|
4456
5469
|
const precisions = {};
|
|
4457
5470
|
for (const asset of filteredAssets.slice(0, 30)) {
|
|
4458
5471
|
precisions[asset.assetId] = asset.precision;
|
|
4459
5472
|
}
|
|
4460
5473
|
return precisions;
|
|
4461
5474
|
}, [filteredAssets]);
|
|
4462
|
-
const initialAssetIds =
|
|
5475
|
+
const initialAssetIds = useMemo14(
|
|
4463
5476
|
() => filteredAssets.slice(0, 30).map((a) => a.assetId),
|
|
4464
5477
|
[filteredAssets]
|
|
4465
5478
|
);
|
|
@@ -4474,16 +5487,16 @@ var TokenSelectModal = ({
|
|
|
4474
5487
|
initialAssetIds,
|
|
4475
5488
|
initialAssetPrecisions
|
|
4476
5489
|
);
|
|
4477
|
-
|
|
5490
|
+
useEffect12(() => {
|
|
4478
5491
|
if (isOpen && currentAssetIds.length > 0) {
|
|
4479
5492
|
refetchSpecific?.(currentAssetIds);
|
|
4480
5493
|
}
|
|
4481
5494
|
}, [isOpen, currentAssetIds, refetchSpecific]);
|
|
4482
5495
|
const { data: marketData } = useAllMarketData();
|
|
4483
|
-
const balanceSortDoneRef =
|
|
4484
|
-
const sortedAssetsRef =
|
|
4485
|
-
const prevFilteredRef =
|
|
4486
|
-
const sortedAssets =
|
|
5496
|
+
const balanceSortDoneRef = useRef11(false);
|
|
5497
|
+
const sortedAssetsRef = useRef11(filteredAssets);
|
|
5498
|
+
const prevFilteredRef = useRef11(filteredAssets);
|
|
5499
|
+
const sortedAssets = useMemo14(() => {
|
|
4487
5500
|
const filterChanged = filteredAssets !== prevFilteredRef.current;
|
|
4488
5501
|
if (filterChanged) {
|
|
4489
5502
|
prevFilteredRef.current = filteredAssets;
|
|
@@ -4514,17 +5527,17 @@ var TokenSelectModal = ({
|
|
|
4514
5527
|
sortedAssetsRef.current = result;
|
|
4515
5528
|
return result;
|
|
4516
5529
|
}, [filteredAssets, balances, marketData]);
|
|
4517
|
-
const visibleRangeAssetIds =
|
|
5530
|
+
const visibleRangeAssetIds = useMemo14(() => {
|
|
4518
5531
|
const start = Math.max(0, visibleRange.startIndex - VISIBLE_BUFFER);
|
|
4519
5532
|
const end = Math.min(sortedAssets.length, visibleRange.endIndex + VISIBLE_BUFFER);
|
|
4520
5533
|
return sortedAssets.slice(start, end).map((a) => a.assetId);
|
|
4521
5534
|
}, [sortedAssets, visibleRange]);
|
|
4522
|
-
|
|
5535
|
+
useEffect12(() => {
|
|
4523
5536
|
if (visibleRangeAssetIds.length > 0) {
|
|
4524
5537
|
refetchSpecific?.(visibleRangeAssetIds);
|
|
4525
5538
|
}
|
|
4526
5539
|
}, [visibleRangeAssetIds, refetchSpecific]);
|
|
4527
|
-
const handleAssetSelect =
|
|
5540
|
+
const handleAssetSelect = useCallback12(
|
|
4528
5541
|
(asset) => {
|
|
4529
5542
|
onSelect(asset);
|
|
4530
5543
|
onClose();
|
|
@@ -4533,10 +5546,10 @@ var TokenSelectModal = ({
|
|
|
4533
5546
|
},
|
|
4534
5547
|
[onSelect, onClose]
|
|
4535
5548
|
);
|
|
4536
|
-
const handleChainSelect =
|
|
5549
|
+
const handleChainSelect = useCallback12((chainId) => {
|
|
4537
5550
|
setSelectedChainId(chainId);
|
|
4538
5551
|
}, []);
|
|
4539
|
-
const handleBackdropClick =
|
|
5552
|
+
const handleBackdropClick = useCallback12(
|
|
4540
5553
|
(e) => {
|
|
4541
5554
|
if (e.target === e.currentTarget) {
|
|
4542
5555
|
onClose();
|
|
@@ -4548,7 +5561,7 @@ var TokenSelectModal = ({
|
|
|
4548
5561
|
const isLoading = isLoadingAssets || isLoadingChains;
|
|
4549
5562
|
return (
|
|
4550
5563
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
4551
|
-
/* @__PURE__ */
|
|
5564
|
+
/* @__PURE__ */ jsx12(
|
|
4552
5565
|
"div",
|
|
4553
5566
|
{
|
|
4554
5567
|
className: "ssw-modal-backdrop",
|
|
@@ -4557,10 +5570,10 @@ var TokenSelectModal = ({
|
|
|
4557
5570
|
role: "dialog",
|
|
4558
5571
|
"aria-modal": "true",
|
|
4559
5572
|
"aria-labelledby": "token-modal-title",
|
|
4560
|
-
children: /* @__PURE__ */
|
|
4561
|
-
/* @__PURE__ */
|
|
4562
|
-
/* @__PURE__ */
|
|
4563
|
-
/* @__PURE__ */
|
|
5573
|
+
children: /* @__PURE__ */ jsxs12("div", { className: "ssw-modal", children: [
|
|
5574
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-modal-header", children: [
|
|
5575
|
+
/* @__PURE__ */ jsx12("h2", { id: "token-modal-title", className: "ssw-modal-title", children: "Select Token" }),
|
|
5576
|
+
/* @__PURE__ */ jsx12("button", { className: "ssw-modal-close", onClick: onClose, type: "button", children: /* @__PURE__ */ jsx12(
|
|
4564
5577
|
"svg",
|
|
4565
5578
|
{
|
|
4566
5579
|
width: "20",
|
|
@@ -4569,14 +5582,14 @@ var TokenSelectModal = ({
|
|
|
4569
5582
|
fill: "none",
|
|
4570
5583
|
stroke: "currentColor",
|
|
4571
5584
|
strokeWidth: "2",
|
|
4572
|
-
children: /* @__PURE__ */
|
|
5585
|
+
children: /* @__PURE__ */ jsx12("path", { d: "M18 6L6 18M6 6l12 12" })
|
|
4573
5586
|
}
|
|
4574
5587
|
) })
|
|
4575
5588
|
] }),
|
|
4576
|
-
/* @__PURE__ */
|
|
4577
|
-
/* @__PURE__ */
|
|
4578
|
-
/* @__PURE__ */
|
|
4579
|
-
/* @__PURE__ */
|
|
5589
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-modal-content", children: [
|
|
5590
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-chain-sidebar", children: [
|
|
5591
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-search-wrapper", children: [
|
|
5592
|
+
/* @__PURE__ */ jsxs12(
|
|
4580
5593
|
"svg",
|
|
4581
5594
|
{
|
|
4582
5595
|
className: "ssw-search-icon",
|
|
@@ -4587,12 +5600,12 @@ var TokenSelectModal = ({
|
|
|
4587
5600
|
stroke: "currentColor",
|
|
4588
5601
|
strokeWidth: "2",
|
|
4589
5602
|
children: [
|
|
4590
|
-
/* @__PURE__ */
|
|
4591
|
-
/* @__PURE__ */
|
|
5603
|
+
/* @__PURE__ */ jsx12("circle", { cx: "11", cy: "11", r: "8" }),
|
|
5604
|
+
/* @__PURE__ */ jsx12("path", { d: "m21 21-4.35-4.35" })
|
|
4592
5605
|
]
|
|
4593
5606
|
}
|
|
4594
5607
|
),
|
|
4595
|
-
/* @__PURE__ */
|
|
5608
|
+
/* @__PURE__ */ jsx12(
|
|
4596
5609
|
"input",
|
|
4597
5610
|
{
|
|
4598
5611
|
type: "text",
|
|
@@ -4603,24 +5616,24 @@ var TokenSelectModal = ({
|
|
|
4603
5616
|
}
|
|
4604
5617
|
)
|
|
4605
5618
|
] }),
|
|
4606
|
-
/* @__PURE__ */
|
|
4607
|
-
/* @__PURE__ */
|
|
5619
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-chain-list", children: [
|
|
5620
|
+
/* @__PURE__ */ jsx12(
|
|
4608
5621
|
"button",
|
|
4609
5622
|
{
|
|
4610
5623
|
className: `ssw-chain-item ${selectedChainId === null ? "ssw-selected" : ""}`,
|
|
4611
5624
|
onClick: () => handleChainSelect(null),
|
|
4612
5625
|
type: "button",
|
|
4613
|
-
children: /* @__PURE__ */
|
|
5626
|
+
children: /* @__PURE__ */ jsx12("span", { className: "ssw-chain-name", children: "All Chains" })
|
|
4614
5627
|
}
|
|
4615
5628
|
),
|
|
4616
|
-
filteredChains.map((chain) => /* @__PURE__ */
|
|
5629
|
+
filteredChains.map((chain) => /* @__PURE__ */ jsxs12(
|
|
4617
5630
|
"button",
|
|
4618
5631
|
{
|
|
4619
5632
|
className: `ssw-chain-item ${selectedChainId === chain.chainId ? "ssw-selected" : ""}`,
|
|
4620
5633
|
onClick: () => handleChainSelect(chain.chainId),
|
|
4621
5634
|
type: "button",
|
|
4622
5635
|
children: [
|
|
4623
|
-
chain.icon ? /* @__PURE__ */
|
|
5636
|
+
chain.icon ? /* @__PURE__ */ jsx12("img", { src: chain.icon, alt: chain.name, className: "ssw-chain-icon" }) : /* @__PURE__ */ jsx12(
|
|
4624
5637
|
"div",
|
|
4625
5638
|
{
|
|
4626
5639
|
className: "ssw-chain-icon-placeholder",
|
|
@@ -4628,16 +5641,16 @@ var TokenSelectModal = ({
|
|
|
4628
5641
|
children: chain.name.charAt(0)
|
|
4629
5642
|
}
|
|
4630
5643
|
),
|
|
4631
|
-
/* @__PURE__ */
|
|
5644
|
+
/* @__PURE__ */ jsx12("span", { className: "ssw-chain-name", children: chain.name })
|
|
4632
5645
|
]
|
|
4633
5646
|
},
|
|
4634
5647
|
chain.chainId
|
|
4635
5648
|
))
|
|
4636
5649
|
] })
|
|
4637
5650
|
] }),
|
|
4638
|
-
/* @__PURE__ */
|
|
4639
|
-
/* @__PURE__ */
|
|
4640
|
-
/* @__PURE__ */
|
|
5651
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-token-panel", children: [
|
|
5652
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-search-wrapper", children: [
|
|
5653
|
+
/* @__PURE__ */ jsxs12(
|
|
4641
5654
|
"svg",
|
|
4642
5655
|
{
|
|
4643
5656
|
className: "ssw-search-icon",
|
|
@@ -4648,12 +5661,12 @@ var TokenSelectModal = ({
|
|
|
4648
5661
|
stroke: "currentColor",
|
|
4649
5662
|
strokeWidth: "2",
|
|
4650
5663
|
children: [
|
|
4651
|
-
/* @__PURE__ */
|
|
4652
|
-
/* @__PURE__ */
|
|
5664
|
+
/* @__PURE__ */ jsx12("circle", { cx: "11", cy: "11", r: "8" }),
|
|
5665
|
+
/* @__PURE__ */ jsx12("path", { d: "m21 21-4.35-4.35" })
|
|
4653
5666
|
]
|
|
4654
5667
|
}
|
|
4655
5668
|
),
|
|
4656
|
-
/* @__PURE__ */
|
|
5669
|
+
/* @__PURE__ */ jsx12(
|
|
4657
5670
|
"input",
|
|
4658
5671
|
{
|
|
4659
5672
|
type: "text",
|
|
@@ -4665,10 +5678,10 @@ var TokenSelectModal = ({
|
|
|
4665
5678
|
}
|
|
4666
5679
|
)
|
|
4667
5680
|
] }),
|
|
4668
|
-
/* @__PURE__ */
|
|
4669
|
-
/* @__PURE__ */
|
|
4670
|
-
/* @__PURE__ */
|
|
4671
|
-
] }) : sortedAssets.length === 0 ? /* @__PURE__ */
|
|
5681
|
+
/* @__PURE__ */ jsx12("div", { className: "ssw-token-list", children: isLoading ? /* @__PURE__ */ jsxs12("div", { className: "ssw-loading", children: [
|
|
5682
|
+
/* @__PURE__ */ jsx12("div", { className: "ssw-spinner" }),
|
|
5683
|
+
/* @__PURE__ */ jsx12("span", { children: "Loading assets..." })
|
|
5684
|
+
] }) : sortedAssets.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "ssw-empty", children: "No tokens found" }) : /* @__PURE__ */ jsx12(
|
|
4672
5685
|
Virtuoso,
|
|
4673
5686
|
{
|
|
4674
5687
|
data: sortedAssets,
|
|
@@ -4677,15 +5690,15 @@ var TokenSelectModal = ({
|
|
|
4677
5690
|
itemContent: (_, asset) => {
|
|
4678
5691
|
const chainInfo = chainInfoMap.get(asset.chainId);
|
|
4679
5692
|
const balance = balances?.[asset.assetId];
|
|
4680
|
-
return /* @__PURE__ */
|
|
5693
|
+
return /* @__PURE__ */ jsxs12(
|
|
4681
5694
|
"button",
|
|
4682
5695
|
{
|
|
4683
5696
|
className: "ssw-token-item",
|
|
4684
5697
|
onClick: () => handleAssetSelect(asset),
|
|
4685
5698
|
type: "button",
|
|
4686
5699
|
children: [
|
|
4687
|
-
/* @__PURE__ */
|
|
4688
|
-
asset.icon ? /* @__PURE__ */
|
|
5700
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-token-icon-wrapper", children: [
|
|
5701
|
+
asset.icon ? /* @__PURE__ */ jsx12("img", { src: asset.icon, alt: asset.symbol, className: "ssw-token-icon" }) : /* @__PURE__ */ jsx12(
|
|
4689
5702
|
"div",
|
|
4690
5703
|
{
|
|
4691
5704
|
className: "ssw-token-icon-placeholder",
|
|
@@ -4693,7 +5706,7 @@ var TokenSelectModal = ({
|
|
|
4693
5706
|
children: asset.symbol?.charAt(0) ?? "?"
|
|
4694
5707
|
}
|
|
4695
5708
|
),
|
|
4696
|
-
chainInfo?.icon && /* @__PURE__ */
|
|
5709
|
+
chainInfo?.icon && /* @__PURE__ */ jsx12(
|
|
4697
5710
|
"img",
|
|
4698
5711
|
{
|
|
4699
5712
|
src: chainInfo.icon,
|
|
@@ -4702,19 +5715,19 @@ var TokenSelectModal = ({
|
|
|
4702
5715
|
}
|
|
4703
5716
|
)
|
|
4704
5717
|
] }),
|
|
4705
|
-
/* @__PURE__ */
|
|
4706
|
-
/* @__PURE__ */
|
|
4707
|
-
/* @__PURE__ */
|
|
5718
|
+
/* @__PURE__ */ jsxs12("div", { className: "ssw-token-info", children: [
|
|
5719
|
+
/* @__PURE__ */ jsx12("span", { className: "ssw-token-symbol", children: asset.symbol }),
|
|
5720
|
+
/* @__PURE__ */ jsx12("span", { className: "ssw-token-name", children: chainInfo?.name ?? asset.networkName ?? asset.name })
|
|
4708
5721
|
] }),
|
|
4709
|
-
/* @__PURE__ */
|
|
4710
|
-
marketData?.[asset.assetId]?.price && /* @__PURE__ */
|
|
5722
|
+
/* @__PURE__ */ jsx12("div", { className: "ssw-token-right", children: (evmAddress || bitcoinAddress || solanaAddress) && (loadingAssetIds.has(asset.assetId) ? /* @__PURE__ */ jsx12("span", { className: "ssw-token-balance-skeleton" }) : balance && balance.balance !== "0" ? /* @__PURE__ */ jsxs12(Fragment8, { children: [
|
|
5723
|
+
marketData?.[asset.assetId]?.price && /* @__PURE__ */ jsxs12("span", { className: "ssw-token-fiat-value", children: [
|
|
4711
5724
|
"$",
|
|
4712
5725
|
bnOrZero2(balance.balance).div(bnOrZero2(10).pow(asset.precision)).times(bnOrZero2(marketData[asset.assetId].price)).toNumber().toLocaleString(void 0, {
|
|
4713
5726
|
minimumFractionDigits: 2,
|
|
4714
5727
|
maximumFractionDigits: 2
|
|
4715
5728
|
})
|
|
4716
5729
|
] }),
|
|
4717
|
-
/* @__PURE__ */
|
|
5730
|
+
/* @__PURE__ */ jsx12("span", { className: "ssw-token-balance", children: balance.balanceFormatted })
|
|
4718
5731
|
] }) : null) })
|
|
4719
5732
|
]
|
|
4720
5733
|
}
|
|
@@ -4733,7 +5746,7 @@ var TokenSelectModal = ({
|
|
|
4733
5746
|
// src/components/WalletProvider.tsx
|
|
4734
5747
|
import { useAppKit as useAppKit2 } from "@reown/appkit/react";
|
|
4735
5748
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4736
|
-
import { useCallback as
|
|
5749
|
+
import { useCallback as useCallback13, useEffect as useEffect13, useState as useState10 } from "react";
|
|
4737
5750
|
import { WagmiProvider } from "wagmi";
|
|
4738
5751
|
|
|
4739
5752
|
// src/config/appkit.ts
|
|
@@ -4802,28 +5815,28 @@ var initializeAppKit = (projectId) => {
|
|
|
4802
5815
|
};
|
|
4803
5816
|
|
|
4804
5817
|
// src/components/WalletProvider.tsx
|
|
4805
|
-
import { jsx as
|
|
5818
|
+
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4806
5819
|
var queryClient = new QueryClient();
|
|
4807
5820
|
var AppKitWalletProvider = ({ projectId, children }) => {
|
|
4808
|
-
const [wagmiConfig, setWagmiConfig] =
|
|
5821
|
+
const [wagmiConfig, setWagmiConfig] = useState10(
|
|
4809
5822
|
() => isAppKitInitialized() ? getActiveWagmiConfig() : void 0
|
|
4810
5823
|
);
|
|
4811
|
-
|
|
5824
|
+
useEffect13(() => {
|
|
4812
5825
|
if (projectId && !isAppKitInitialized()) initializeAppKit(projectId);
|
|
4813
5826
|
if (isAppKitInitialized()) setWagmiConfig(getActiveWagmiConfig());
|
|
4814
5827
|
}, [projectId]);
|
|
4815
5828
|
if (!wagmiConfig) return null;
|
|
4816
|
-
return /* @__PURE__ */
|
|
5829
|
+
return /* @__PURE__ */ jsx13(WagmiProvider, { config: wagmiConfig, children: /* @__PURE__ */ jsx13(QueryClientProvider, { client: queryClient, children }) });
|
|
4817
5830
|
};
|
|
4818
5831
|
var ConnectWalletButton = () => {
|
|
4819
5832
|
const { open } = useAppKit2();
|
|
4820
|
-
const {
|
|
4821
|
-
const handleClick =
|
|
5833
|
+
const { walletSendAddress } = useSwapWallet();
|
|
5834
|
+
const handleClick = useCallback13(() => {
|
|
4822
5835
|
open();
|
|
4823
5836
|
}, [open]);
|
|
4824
|
-
if (!
|
|
4825
|
-
return /* @__PURE__ */
|
|
4826
|
-
/* @__PURE__ */
|
|
5837
|
+
if (!walletSendAddress) {
|
|
5838
|
+
return /* @__PURE__ */ jsxs13("button", { onClick: handleClick, type: "button", className: "ssw-connect-btn", children: [
|
|
5839
|
+
/* @__PURE__ */ jsxs13(
|
|
4827
5840
|
"svg",
|
|
4828
5841
|
{
|
|
4829
5842
|
width: "16",
|
|
@@ -4833,19 +5846,19 @@ var ConnectWalletButton = () => {
|
|
|
4833
5846
|
stroke: "currentColor",
|
|
4834
5847
|
strokeWidth: "2",
|
|
4835
5848
|
children: [
|
|
4836
|
-
/* @__PURE__ */
|
|
4837
|
-
/* @__PURE__ */
|
|
5849
|
+
/* @__PURE__ */ jsx13("path", { d: "M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" }),
|
|
5850
|
+
/* @__PURE__ */ jsx13("path", { d: "M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" })
|
|
4838
5851
|
]
|
|
4839
5852
|
}
|
|
4840
5853
|
),
|
|
4841
5854
|
"Connect"
|
|
4842
5855
|
] });
|
|
4843
5856
|
}
|
|
4844
|
-
return /* @__PURE__ */
|
|
5857
|
+
return /* @__PURE__ */ jsx13("button", { onClick: handleClick, type: "button", className: "ssw-connect-btn ssw-connected", children: truncateAddress(walletSendAddress) });
|
|
4845
5858
|
};
|
|
4846
5859
|
|
|
4847
5860
|
// src/components/SwapWidget.tsx
|
|
4848
|
-
import { jsx as
|
|
5861
|
+
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4849
5862
|
var SwapWidgetContent = ({
|
|
4850
5863
|
apiClient,
|
|
4851
5864
|
theme = "dark",
|
|
@@ -4865,8 +5878,11 @@ var SwapWidgetContent = ({
|
|
|
4865
5878
|
ratesRefetchInterval
|
|
4866
5879
|
}) => {
|
|
4867
5880
|
const state = SwapMachineCtx.useSelector((s) => s);
|
|
4868
|
-
const
|
|
4869
|
-
const
|
|
5881
|
+
const actorRef = SwapMachineCtx.useActorRef();
|
|
5882
|
+
const isRequotingDeposit = state.matches("quoting") && state.context.isDepositFlow && !!state.context.quote;
|
|
5883
|
+
const canEditSettings = state.matches("idle") || state.matches("input") || state.matches("error") || state.matches("deposit_expired");
|
|
5884
|
+
const [tokenModalType, setTokenModalType] = useState11(null);
|
|
5885
|
+
const [isSettingsOpen, setIsSettingsOpen] = useState11(false);
|
|
4870
5886
|
const themeMode = typeof theme === "string" ? theme : theme.mode;
|
|
4871
5887
|
const themeConfig = typeof theme === "object" ? theme : void 0;
|
|
4872
5888
|
const displayValues = useSwapDisplayValues({
|
|
@@ -4889,9 +5905,31 @@ var SwapWidgetContent = ({
|
|
|
4889
5905
|
useSwapQuoting({ apiClient, rates, sellAssetBalance });
|
|
4890
5906
|
useSwapApproval();
|
|
4891
5907
|
useSwapExecution();
|
|
4892
|
-
useStatusPolling({ apiClient
|
|
5908
|
+
useStatusPolling({ apiClient });
|
|
5909
|
+
useDepositPolling({ apiClient });
|
|
5910
|
+
useSwapCallbacks({ onSwapSuccess, onSwapError, refetchSellBalance, refetchBuyBalance });
|
|
4893
5911
|
useSellFiatSync(displayValues.sellAssetUsdPrice);
|
|
4894
|
-
const
|
|
5912
|
+
const hasSavedDepositRef = useRef12(false);
|
|
5913
|
+
useEffect14(() => {
|
|
5914
|
+
const snap = actorRef.getSnapshot();
|
|
5915
|
+
const { quote, sendAddress, receiveAddress, isDepositFlow, txHash, depositObservedAt } = snap.context;
|
|
5916
|
+
const isTrackingDeposit = isDepositFlow && (snap.matches("awaiting_deposit") || snap.matches("deposit_expired") || snap.matches("polling_status"));
|
|
5917
|
+
if (isTrackingDeposit && quote?.depositAddress && sendAddress && receiveAddress) {
|
|
5918
|
+
savePendingDeposit({
|
|
5919
|
+
quote,
|
|
5920
|
+
refundAddress: sendAddress,
|
|
5921
|
+
receiveAddress,
|
|
5922
|
+
sellAmountBaseUnit: snap.context.sellAmountBaseUnit,
|
|
5923
|
+
buyAmountBaseUnit: snap.context.buyAmountBaseUnit,
|
|
5924
|
+
txHash: txHash ?? void 0,
|
|
5925
|
+
depositObservedAt: depositObservedAt ?? void 0
|
|
5926
|
+
});
|
|
5927
|
+
hasSavedDepositRef.current = true;
|
|
5928
|
+
return;
|
|
5929
|
+
}
|
|
5930
|
+
if (hasSavedDepositRef.current) clearPendingDeposit();
|
|
5931
|
+
}, [state.value]);
|
|
5932
|
+
const widgetStyle = useMemo15(() => {
|
|
4895
5933
|
if (!themeConfig) return void 0;
|
|
4896
5934
|
const style = {};
|
|
4897
5935
|
if (themeConfig.accentColor) {
|
|
@@ -4938,24 +5976,24 @@ var SwapWidgetContent = ({
|
|
|
4938
5976
|
}
|
|
4939
5977
|
return Object.keys(style).length > 0 ? style : void 0;
|
|
4940
5978
|
}, [themeConfig]);
|
|
4941
|
-
return /* @__PURE__ */
|
|
5979
|
+
return /* @__PURE__ */ jsxs14(
|
|
4942
5980
|
"div",
|
|
4943
5981
|
{
|
|
4944
5982
|
className: `ssw-widget ${themeMode === "light" ? "ssw-light" : "ssw-dark"}${themeConfig?.buttonVariant === "outline" ? " ssw-btn-outline" : ""}`,
|
|
4945
5983
|
style: widgetStyle,
|
|
4946
5984
|
children: [
|
|
4947
|
-
/* @__PURE__ */
|
|
4948
|
-
/* @__PURE__ */
|
|
4949
|
-
/* @__PURE__ */
|
|
4950
|
-
showConnectButton && /* @__PURE__ */
|
|
4951
|
-
/* @__PURE__ */
|
|
5985
|
+
/* @__PURE__ */ jsxs14("div", { className: "ssw-header", children: [
|
|
5986
|
+
/* @__PURE__ */ jsx14("span", { className: "ssw-header-title", children: "Swap" }),
|
|
5987
|
+
/* @__PURE__ */ jsxs14("div", { className: "ssw-header-actions", children: [
|
|
5988
|
+
showConnectButton && /* @__PURE__ */ jsx14(ConnectWalletButton, {}),
|
|
5989
|
+
canEditSettings && /* @__PURE__ */ jsx14(
|
|
4952
5990
|
"button",
|
|
4953
5991
|
{
|
|
4954
5992
|
className: "ssw-settings-btn",
|
|
4955
5993
|
onClick: () => setIsSettingsOpen(true),
|
|
4956
5994
|
type: "button",
|
|
4957
5995
|
title: "Settings",
|
|
4958
|
-
children: /* @__PURE__ */
|
|
5996
|
+
children: /* @__PURE__ */ jsxs14(
|
|
4959
5997
|
"svg",
|
|
4960
5998
|
{
|
|
4961
5999
|
width: "20",
|
|
@@ -4965,8 +6003,8 @@ var SwapWidgetContent = ({
|
|
|
4965
6003
|
stroke: "currentColor",
|
|
4966
6004
|
strokeWidth: "2",
|
|
4967
6005
|
children: [
|
|
4968
|
-
/* @__PURE__ */
|
|
4969
|
-
/* @__PURE__ */
|
|
6006
|
+
/* @__PURE__ */ jsx14("circle", { cx: "12", cy: "12", r: "3" }),
|
|
6007
|
+
/* @__PURE__ */ jsx14("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
|
|
4970
6008
|
]
|
|
4971
6009
|
}
|
|
4972
6010
|
)
|
|
@@ -4974,8 +6012,8 @@ var SwapWidgetContent = ({
|
|
|
4974
6012
|
)
|
|
4975
6013
|
] })
|
|
4976
6014
|
] }),
|
|
4977
|
-
/* @__PURE__ */
|
|
4978
|
-
(state.matches("idle") || state.matches("input") || state.matches("quoting")) && /* @__PURE__ */
|
|
6015
|
+
/* @__PURE__ */ jsxs14("div", { className: "ssw-step-container", children: [
|
|
6016
|
+
(state.matches("idle") || state.matches("input") || state.matches("quoting") && !isRequotingDeposit) && /* @__PURE__ */ jsx14(
|
|
4979
6017
|
InputStep,
|
|
4980
6018
|
{
|
|
4981
6019
|
displayValues,
|
|
@@ -4992,14 +6030,15 @@ var SwapWidgetContent = ({
|
|
|
4992
6030
|
allowShapeshiftRedirect: canRedirectToShapeshift
|
|
4993
6031
|
}
|
|
4994
6032
|
),
|
|
4995
|
-
(state.matches("approval_needed") || state.matches("approving")) && /* @__PURE__ */
|
|
4996
|
-
state.matches("executing") && /* @__PURE__ */
|
|
4997
|
-
(state.matches("
|
|
6033
|
+
(state.matches("approval_needed") || state.matches("approving")) && /* @__PURE__ */ jsx14(ApprovalStep, {}),
|
|
6034
|
+
state.matches("executing") && /* @__PURE__ */ jsx14(ExecutionStep, {}),
|
|
6035
|
+
(state.matches("awaiting_deposit") || state.matches("deposit_expired") || isRequotingDeposit) && /* @__PURE__ */ jsx14(DepositStep, {}),
|
|
6036
|
+
(state.matches("polling_status") || state.matches("complete") || state.matches("error")) && /* @__PURE__ */ jsx14(StatusStep, { isPayment })
|
|
4998
6037
|
] }),
|
|
4999
|
-
showPoweredBy && /* @__PURE__ */
|
|
6038
|
+
showPoweredBy && /* @__PURE__ */ jsxs14("div", { className: "ssw-powered-by", children: [
|
|
5000
6039
|
"Powered by",
|
|
5001
6040
|
" ",
|
|
5002
|
-
/* @__PURE__ */
|
|
6041
|
+
/* @__PURE__ */ jsxs14(
|
|
5003
6042
|
"a",
|
|
5004
6043
|
{
|
|
5005
6044
|
href: "https://shapeshift.com",
|
|
@@ -5007,13 +6046,13 @@ var SwapWidgetContent = ({
|
|
|
5007
6046
|
rel: "noopener noreferrer",
|
|
5008
6047
|
className: "ssw-powered-by-link",
|
|
5009
6048
|
children: [
|
|
5010
|
-
/* @__PURE__ */
|
|
6049
|
+
/* @__PURE__ */ jsx14("svg", { width: "16", height: "16", viewBox: "0 0 57 62", fill: "currentColor", children: /* @__PURE__ */ jsx14("path", { d: "M51.67 5.1L48.97 21.3L39.37 10L51.67 5.1ZM49.03 28.27L51.43 37.14L33.06 42.2L49.03 28.27ZM9.03 23.8L18.88 10.93H35.99L46.92 23.8H9.03ZM45.66 26.99L27.85 42.53L9.7 26.99H45.66ZM15.58 10.01L6.78 21.51L4.08 5.17L15.58 10.01ZM22.57 42.2L4.02 37.15L6.56 28.48L22.57 42.2ZM25.99 46.43L22.49 50.28C19.53 47.46 16.26 44.96 12.78 42.83L25.99 46.43ZM42.98 42.77C39.5 44.94 36.24 47.47 33.29 50.32L29.72 46.42L42.98 42.77ZM55.73 0.06L36.42 7.75H18.42L0 0L4.18 25.3L0.17 38.99L10.65 45.26C15.61 48.23 20.06 51.94 23.86 56.3L27.94 60.97L32.23 56.06C35.9 51.84 40.18 48.22 44.95 45.29L55.23 38.99L51.52 25.31L55.73 0.06Z" }) }),
|
|
5011
6050
|
"ShapeShift"
|
|
5012
6051
|
]
|
|
5013
6052
|
}
|
|
5014
6053
|
)
|
|
5015
6054
|
] }),
|
|
5016
|
-
/* @__PURE__ */
|
|
6055
|
+
/* @__PURE__ */ jsx14(
|
|
5017
6056
|
TokenSelectModal,
|
|
5018
6057
|
{
|
|
5019
6058
|
isOpen: tokenModalType !== null,
|
|
@@ -5026,7 +6065,7 @@ var SwapWidgetContent = ({
|
|
|
5026
6065
|
allowShapeshiftRedirect: canRedirectToShapeshift
|
|
5027
6066
|
}
|
|
5028
6067
|
),
|
|
5029
|
-
/* @__PURE__ */
|
|
6068
|
+
/* @__PURE__ */ jsx14(
|
|
5030
6069
|
SettingsModal,
|
|
5031
6070
|
{
|
|
5032
6071
|
isOpen: isSettingsOpen,
|
|
@@ -5064,17 +6103,16 @@ var SwapWidgetCore = ({
|
|
|
5064
6103
|
const evm = useEvmSigning();
|
|
5065
6104
|
const bitcoin3 = useBitcoinSigning();
|
|
5066
6105
|
const solana3 = useSolanaSigning();
|
|
5067
|
-
const [customReceiveAddress, setCustomReceiveAddress] = useState8(
|
|
5068
|
-
defaultReceiveAddress ?? ""
|
|
5069
|
-
);
|
|
5070
6106
|
const sellChainId = SwapMachineCtx.useSelector((s) => s.context.sellAsset.chainId);
|
|
5071
6107
|
const buyChainId = SwapMachineCtx.useSelector((s) => s.context.buyAsset.chainId);
|
|
6108
|
+
const [customReceiveAddress, setCustomReceiveAddress] = useCustomAddress(buyChainId);
|
|
6109
|
+
const [customRefundAddress, setCustomRefundAddress] = useCustomAddress(sellChainId);
|
|
5072
6110
|
const sellChainType = getChainType(sellChainId);
|
|
5073
6111
|
const buyChainType = getChainType(buyChainId);
|
|
5074
6112
|
const { status: evmStatus } = useAppKitAccount3({ namespace: "eip155" });
|
|
5075
6113
|
const { status: utxoStatus } = useAppKitAccount3({ namespace: "bip122" });
|
|
5076
6114
|
const { status: solanaStatus } = useAppKitAccount3({ namespace: "solana" });
|
|
5077
|
-
const isReceiveAddressResolving =
|
|
6115
|
+
const isReceiveAddressResolving = useMemo15(() => {
|
|
5078
6116
|
const status = (() => {
|
|
5079
6117
|
if (buyChainType === "evm") return evmStatus;
|
|
5080
6118
|
if (buyChainType === "utxo") return utxoStatus;
|
|
@@ -5082,27 +6120,39 @@ var SwapWidgetCore = ({
|
|
|
5082
6120
|
})();
|
|
5083
6121
|
return status === "connecting" || status === "reconnecting";
|
|
5084
6122
|
}, [buyChainType, evmStatus, utxoStatus, solanaStatus]);
|
|
5085
|
-
const addressForChain =
|
|
5086
|
-
(chainType) => {
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
6123
|
+
const addressForChain = useCallback14(
|
|
6124
|
+
(chainType, chainId) => {
|
|
6125
|
+
const address = (() => {
|
|
6126
|
+
if (chainType === "evm") return evm.address;
|
|
6127
|
+
if (chainType === "utxo") return bitcoin3.address;
|
|
6128
|
+
if (chainType === "solana") return solana3.address;
|
|
6129
|
+
return void 0;
|
|
6130
|
+
})();
|
|
6131
|
+
return address && validateAddress(address, chainId).valid ? address : void 0;
|
|
5091
6132
|
},
|
|
5092
6133
|
[evm.address, bitcoin3.address, solana3.address]
|
|
5093
6134
|
);
|
|
5094
|
-
const
|
|
5095
|
-
() => addressForChain(sellChainType),
|
|
5096
|
-
[addressForChain, sellChainType]
|
|
6135
|
+
const walletSendAddress = useMemo15(
|
|
6136
|
+
() => addressForChain(sellChainType, sellChainId),
|
|
6137
|
+
[addressForChain, sellChainType, sellChainId]
|
|
6138
|
+
);
|
|
6139
|
+
const sendAddress = useMemo15(
|
|
6140
|
+
() => resolveSendAddress({
|
|
6141
|
+
customAddress: customRefundAddress,
|
|
6142
|
+
walletAddress: walletSendAddress,
|
|
6143
|
+
sellChainId
|
|
6144
|
+
}),
|
|
6145
|
+
[customRefundAddress, walletSendAddress, sellChainId]
|
|
5097
6146
|
);
|
|
5098
|
-
const walletReceiveAddress =
|
|
5099
|
-
() => addressForChain(buyChainType),
|
|
5100
|
-
[addressForChain, buyChainType]
|
|
6147
|
+
const walletReceiveAddress = useMemo15(
|
|
6148
|
+
() => addressForChain(buyChainType, buyChainId),
|
|
6149
|
+
[addressForChain, buyChainType, buyChainId]
|
|
5101
6150
|
);
|
|
5102
|
-
const receiveAddress =
|
|
6151
|
+
const receiveAddress = useMemo15(
|
|
5103
6152
|
() => resolveReceiveAddress({
|
|
5104
6153
|
isLocked: isReceiveAddressLocked,
|
|
5105
6154
|
defaultAddress: defaultReceiveAddress,
|
|
6155
|
+
defaultAddressChainId: defaultBuyAsset.chainId,
|
|
5106
6156
|
customAddress: customReceiveAddress,
|
|
5107
6157
|
walletAddress: walletReceiveAddress,
|
|
5108
6158
|
buyChainId
|
|
@@ -5110,12 +6160,13 @@ var SwapWidgetCore = ({
|
|
|
5110
6160
|
[
|
|
5111
6161
|
isReceiveAddressLocked,
|
|
5112
6162
|
defaultReceiveAddress,
|
|
6163
|
+
defaultBuyAsset.chainId,
|
|
5113
6164
|
customReceiveAddress,
|
|
5114
6165
|
walletReceiveAddress,
|
|
5115
6166
|
buyChainId
|
|
5116
6167
|
]
|
|
5117
6168
|
);
|
|
5118
|
-
|
|
6169
|
+
useEffect14(() => {
|
|
5119
6170
|
if (!isBuyAmountLocked) return;
|
|
5120
6171
|
actorRef.send({
|
|
5121
6172
|
type: "SET_BUY_AMOUNT",
|
|
@@ -5123,32 +6174,48 @@ var SwapWidgetCore = ({
|
|
|
5123
6174
|
amountBaseUnit: defaultBuyAmountCryptoBaseUnit
|
|
5124
6175
|
});
|
|
5125
6176
|
}, [isBuyAmountLocked, defaultBuyAmountCryptoBaseUnit, defaultBuyAsset.precision, actorRef]);
|
|
5126
|
-
const initialSyncRef =
|
|
5127
|
-
|
|
6177
|
+
const initialSyncRef = useRef12(false);
|
|
6178
|
+
useLayoutEffect3(() => {
|
|
5128
6179
|
if (initialSyncRef.current) return;
|
|
5129
6180
|
initialSyncRef.current = true;
|
|
5130
6181
|
actorRef.send({ type: "SET_SELL_ASSET", asset: defaultSellAsset });
|
|
5131
6182
|
actorRef.send({ type: "SET_BUY_ASSET", asset: defaultBuyAsset });
|
|
5132
6183
|
actorRef.send({ type: "SET_SLIPPAGE", slippage: defaultSlippage });
|
|
6184
|
+
if (defaultReceiveAddress) {
|
|
6185
|
+
setCustomReceiveAddress(defaultReceiveAddress, defaultBuyAsset.chainId);
|
|
6186
|
+
}
|
|
5133
6187
|
actorRef.send({
|
|
5134
6188
|
type: "SET_BUY_AMOUNT",
|
|
5135
6189
|
amount: defaultBuyAmountCryptoBaseUnit ? formatAmountForInput(defaultBuyAmountCryptoBaseUnit, defaultBuyAsset.precision) : "",
|
|
5136
6190
|
amountBaseUnit: defaultBuyAmountCryptoBaseUnit
|
|
5137
6191
|
});
|
|
6192
|
+
const pending = loadPendingDeposit(Date.now());
|
|
6193
|
+
if (pending) {
|
|
6194
|
+
actorRef.send({
|
|
6195
|
+
type: "RESTORE_DEPOSIT",
|
|
6196
|
+
quote: pending.quote,
|
|
6197
|
+
sendAddress: pending.refundAddress,
|
|
6198
|
+
receiveAddress: pending.receiveAddress,
|
|
6199
|
+
sellAmountBaseUnit: pending.sellAmountBaseUnit,
|
|
6200
|
+
buyAmountBaseUnit: pending.buyAmountBaseUnit,
|
|
6201
|
+
txHash: pending.txHash,
|
|
6202
|
+
depositObservedAt: pending.depositObservedAt
|
|
6203
|
+
});
|
|
6204
|
+
setCustomRefundAddress(pending.refundAddress, pending.quote.sellAsset.chainId);
|
|
6205
|
+
setCustomReceiveAddress(pending.receiveAddress, pending.quote.buyAsset.chainId);
|
|
6206
|
+
}
|
|
5138
6207
|
}, [actorRef]);
|
|
5139
|
-
|
|
6208
|
+
useEffect14(() => {
|
|
5140
6209
|
actorRef.send({ type: "SET_SEND_ADDRESS", address: sendAddress });
|
|
5141
6210
|
}, [sendAddress, actorRef]);
|
|
5142
|
-
|
|
6211
|
+
useEffect14(() => {
|
|
5143
6212
|
actorRef.send({ type: "SET_RECEIVE_ADDRESS", address: receiveAddress });
|
|
5144
6213
|
}, [receiveAddress, actorRef]);
|
|
5145
|
-
|
|
5146
|
-
if (!customReceiveAddress) return;
|
|
5147
|
-
if (!validateAddress(customReceiveAddress, buyChainId).valid) setCustomReceiveAddress("");
|
|
5148
|
-
}, [buyChainId, customReceiveAddress]);
|
|
5149
|
-
const walletValue = useMemo12(
|
|
6214
|
+
const walletValue = useMemo15(
|
|
5150
6215
|
() => ({
|
|
5151
6216
|
sendAddress,
|
|
6217
|
+
walletSendAddress,
|
|
6218
|
+
setCustomRefundAddress,
|
|
5152
6219
|
receiveAddress,
|
|
5153
6220
|
isReceiveAddressResolving,
|
|
5154
6221
|
isReceiveAddressBlocked: isReceiveAddressLocked && !receiveAddress,
|
|
@@ -5160,10 +6227,13 @@ var SwapWidgetCore = ({
|
|
|
5160
6227
|
}),
|
|
5161
6228
|
[
|
|
5162
6229
|
sendAddress,
|
|
6230
|
+
walletSendAddress,
|
|
5163
6231
|
receiveAddress,
|
|
5164
6232
|
isReceiveAddressResolving,
|
|
5165
6233
|
isReceiveAddressLocked,
|
|
5166
6234
|
customReceiveAddress,
|
|
6235
|
+
setCustomReceiveAddress,
|
|
6236
|
+
setCustomRefundAddress,
|
|
5167
6237
|
evm,
|
|
5168
6238
|
bitcoin3,
|
|
5169
6239
|
solana3
|
|
@@ -5172,7 +6242,7 @@ var SwapWidgetCore = ({
|
|
|
5172
6242
|
const hasLockedBuyAmount = isBuyAmountLocked && !!defaultBuyAmountCryptoBaseUnit;
|
|
5173
6243
|
const isPayment = hasLockedBuyAmount && isReceiveAddressLocked && !!defaultReceiveAddress;
|
|
5174
6244
|
const canRedirectToShapeshift = allowShapeshiftRedirect && !hasLockedBuyAmount && !isReceiveAddressLocked;
|
|
5175
|
-
return /* @__PURE__ */
|
|
6245
|
+
return /* @__PURE__ */ jsx14(SwapWalletProvider, { value: walletValue, children: /* @__PURE__ */ jsx14(
|
|
5176
6246
|
SwapWidgetContent,
|
|
5177
6247
|
{
|
|
5178
6248
|
apiClient,
|
|
@@ -5195,14 +6265,14 @@ var SwapWidgetCore = ({
|
|
|
5195
6265
|
) });
|
|
5196
6266
|
};
|
|
5197
6267
|
var SwapWidget = (props) => {
|
|
5198
|
-
const apiClient =
|
|
6268
|
+
const apiClient = useMemo15(
|
|
5199
6269
|
() => createApiClient({
|
|
5200
6270
|
baseUrl: props.apiBaseUrl,
|
|
5201
6271
|
partnerCode: props.partnerCode
|
|
5202
6272
|
}),
|
|
5203
6273
|
[props.apiBaseUrl, props.partnerCode]
|
|
5204
6274
|
);
|
|
5205
|
-
return /* @__PURE__ */
|
|
6275
|
+
return /* @__PURE__ */ jsx14(AppKitWalletProvider, { projectId: props.walletConnectProjectId, children: /* @__PURE__ */ jsx14(SwapMachineCtx.Provider, { children: /* @__PURE__ */ jsx14(
|
|
5206
6276
|
SwapWidgetCore,
|
|
5207
6277
|
{
|
|
5208
6278
|
defaultSellAsset: props.defaultSellAsset ?? DEFAULT_SELL_ASSET,
|