Skip to content

Commit 255e640

Browse files
authored
Merge pull request #26 from SocketDotTech/fixes
🛠 feat: displaying refuel amounts; initiating routes when error is thrown
2 parents 647e159 + 0999dc8 commit 255e640

File tree

15 files changed

+301
-118
lines changed

15 files changed

+301
-118
lines changed

src/components/Output.tsx

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ export const Output = ({
6565
const customDestNetworks = useSelector(
6666
(state: any) => state.customSettings.destNetworks
6767
);
68-
const customSourceNetworks = useSelector(
69-
(state: any) => state.customSettings.sourceNetworks
70-
);
7168
const defaultDestNetwork = useSelector(
7269
(state: any) => state.customSettings.defaultDestNetwork
7370
);
7471
const defaultDestTokenAddress = useSelector(
7572
(state: any) => state.customSettings.defaultDestToken
7673
);
74+
const sameChainSwapsEnabled = useSelector(
75+
(state: any) => state.customSettings.sameChainSwapsEnabled
76+
);
7777

7878
// Hack to check if it's the first render
7979
const [firstRender, setFirstRender] = useState<boolean>(false);
@@ -112,9 +112,15 @@ export const Output = ({
112112
const [firstNetworkRender, setFirstRenderNetwork] = useState<boolean>(false);
113113
useEffect(() => {
114114
if (supportedNetworks?.length) {
115-
const networksSubset = supportedNetworks.filter(
116-
(x: Network) => x.chainId !== sourceChainId
117-
);
115+
let networksSubset;
116+
if (sameChainSwapsEnabled) {
117+
// do not exclude the source chain from dest chain list if same chain swaps are enabled
118+
networksSubset = supportedNetworks;
119+
} else {
120+
networksSubset = supportedNetworks.filter(
121+
(x: Network) => x.chainId !== sourceChainId
122+
);
123+
}
118124
setSupportedNetworksSubset(networksSubset);
119125

120126
if (firstNetworkRender) {
@@ -145,13 +151,21 @@ export const Output = ({
145151

146152
// To set the tokens on load & when the source token changes
147153
function fallbackToUSDC() {
148-
return (
149-
allDestTokens.filter(
150-
(x: Currency) =>
151-
(x?.chainAgnosticId?.toLowerCase() || x.symbol.toLowerCase()) ===
152-
"usdc"
153-
)?.[0] ?? allDestTokens[0]
154-
);
154+
// USDC token
155+
const usdc = allDestTokens.filter(
156+
(x: Currency) =>
157+
(x?.chainAgnosticId?.toLowerCase() || x.symbol.toLowerCase()) === "usdc"
158+
)?.[0];
159+
160+
// If same chains are selected, and if the source token is same as usdc, set the dest token to the first token from the list
161+
if (
162+
sourceChainId === destChainId &&
163+
usdc?.address === sourceToken?.address
164+
) {
165+
return allDestTokens[0];
166+
}
167+
168+
return usdc ?? allDestTokens[0];
155169
}
156170

157171
useEffect(() => {
@@ -173,24 +187,29 @@ export const Output = ({
173187
_token = fallbackToUSDC();
174188
}
175189
} else {
176-
// Check if the current dest token exists in the new token list. If yes, retain the same token. Else, change it.
177-
const destTokenExists =
178-
destToken &&
179-
allDestTokens.find(
180-
(x: Currency) =>
181-
x.address.toLowerCase() === destToken?.address?.toLowerCase()
182-
);
183-
184-
if (!destTokenExists) {
185-
// Check if corresponding token is available - This will work only for Socket's token list
186-
if (sourceToken.chainAgnosticId) {
187-
_token = allDestTokens.filter(
190+
if (sourceToken?.address === destToken?.address) {
191+
_token = fallbackToUSDC();
192+
} else {
193+
// Check if the current dest token exists in the new token list. If yes, retain the same token. Else, change it.
194+
const destTokenExists =
195+
destToken &&
196+
allDestTokens.find(
188197
(x: Currency) =>
189-
x?.chainAgnosticId?.toLowerCase() ===
190-
sourceToken.chainAgnosticId.toLowerCase()
191-
)?.[0];
192-
} else {
193-
_token = fallbackToUSDC();
198+
x.address.toLowerCase() === destToken?.address?.toLowerCase()
199+
);
200+
201+
if (!destTokenExists) {
202+
// Check if corresponding token is available - This will work only for Socket's token list
203+
if (sourceToken.chainAgnosticId && sourceChainId !== destChainId) {
204+
_token =
205+
allDestTokens.filter(
206+
(x: Currency) =>
207+
x?.chainAgnosticId?.toLowerCase() ===
208+
sourceToken.chainAgnosticId.toLowerCase()
209+
)?.[0] ?? fallbackToUSDC();
210+
} else {
211+
_token = fallbackToUSDC();
212+
}
194213
}
195214
}
196215
}
@@ -225,6 +244,7 @@ export const Output = ({
225244
activeToken={destToken}
226245
tokens={allDestTokens}
227246
noTokens={noTokens}
247+
tokenToDisable={sourceChainId === destChainId && sourceToken}
228248
/>
229249
</div>
230250
);

src/components/Refuel.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import { Popover } from "./common/Popover";
1010
export const Refuel = () => {
1111
const [isChecked, setIsChecked] = useState(false);
1212
const destChainId = useSelector((state: any) => state.networks.destChainId);
13+
const sourceChainId = useSelector(
14+
(state: any) => state.networks.sourceChainId
15+
);
1316
const mappedChainData = useMappedChainData();
1417
const dispatch = useDispatch();
1518

@@ -21,7 +24,7 @@ export const Refuel = () => {
2124
}, [isChecked]);
2225

2326
useEffect(() => {
24-
if (destChainId === 1) {
27+
if (destChainId === 1 || destChainId === sourceChainId) {
2528
setIsChecked(false);
2629
dispatch(enableRefuel(false));
2730
}
@@ -48,6 +51,10 @@ export const Refuel = () => {
4851
<span className="skt-w text-red-500">
4952
Refuel isn't supported on Ethereum
5053
</span>
54+
) : destChainId === sourceChainId ? (
55+
<span className="skt-w text-red-500">
56+
Refuel isn't supported for same chain swaps
57+
</span>
5158
) : (
5259
`Get Gas for transactions on ${mappedChainData?.[destChainId]?.name}`
5360
)}
@@ -58,7 +65,7 @@ export const Refuel = () => {
5865
small
5966
isChecked={isChecked}
6067
setIsChecked={setIsChecked}
61-
disabled={destChainId === 1}
68+
disabled={destChainId === 1 || destChainId === sourceChainId}
6269
/>
6370
</div>
6471
);

src/components/RouteDetails/ReviewModal.tsx

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useDispatch, useSelector } from "react-redux";
22
import { ReactNode, useContext, useEffect, useState } from "react";
33
import { CustomizeContext } from "../../providers/CustomizeProvider";
4-
import { BRIDGE_DISPLAY_NAMES } from "../../consts/";
4+
import { BRIDGE_DISPLAY_NAMES, UserTxType } from "../../consts/";
55

66
// components
77
import { Button } from "../common/Button";
@@ -35,6 +35,7 @@ export const ReviewModal = ({
3535
const selectedRoute = useSelector((state: any) => state.routes.selectedRoute);
3636
const [showTxDetails, setShowTxDetails] = useState<boolean>(false);
3737
const [quoteUpdated, setQuoteUpdated] = useState<boolean>(false);
38+
const [isSameChainSwap, setIsSameChainSwap] = useState<boolean>(false);
3839

3940
const customSettings = useContext(CustomizeContext);
4041
const { borderRadius } = customSettings.customization;
@@ -96,12 +97,17 @@ export const ReviewModal = ({
9697

9798
// Extracting Bridge Step from fundMove userTx
9899
const fundMovrData = selectedRoute?.route?.userTxs.filter(
99-
(item) => item.userTxType === "fund-movr"
100+
(item) => item.userTxType === UserTxType.FUND_MOVR
100101
)[0];
101102
const bridgeData =
102103
fundMovrData?.steps &&
103104
fundMovrData?.steps.filter((step) => step.type === "bridge")[0];
104105

106+
// Extracting the Swap step from userTxs
107+
const swapData = selectedRoute?.route?.userTxs.filter(
108+
(item) => item.userTxType === UserTxType.DEX_SWAP
109+
)?.[0];
110+
105111
// Bridge Fee
106112
const bridgeFee = bridgeData?.protocolFees.feesInUsd;
107113
const bridgeFeeInToken = formatCurrencyAmount(
@@ -111,6 +117,13 @@ export const ReviewModal = ({
111117
);
112118
const bridgeFeeTokenSymbol = bridgeData?.protocolFees.asset.symbol;
113119

120+
useEffect(() => {
121+
setIsSameChainSwap(
122+
selectedRoute?.path?.fromToken?.chainId ===
123+
selectedRoute?.path?.toToken?.chainId
124+
);
125+
}, [selectedRoute]);
126+
114127
return (
115128
<Modal
116129
title="Review Quote"
@@ -135,45 +148,56 @@ export const ReviewModal = ({
135148
/>
136149

137150
<div className="skt-w p-3 flex flex-col gap-3 mt-1">
138-
<RouteDetailRow
139-
label="Bridge Name"
140-
value={
141-
BRIDGE_DISPLAY_NAMES[
142-
selectedRoute?.route?.usedBridgeNames?.[0]
143-
] || selectedRoute?.route?.usedBridgeNames?.[0]
144-
}
145-
/>
146-
<RouteDetailRow
147-
label="Estimated Bridging Time"
148-
value={timeInMinutes(selectedRoute?.route?.serviceTime)}
149-
/>
151+
{!isSameChainSwap ? (
152+
<>
153+
<RouteDetailRow
154+
label="Bridge Name"
155+
value={
156+
BRIDGE_DISPLAY_NAMES[
157+
selectedRoute?.route?.usedBridgeNames?.[0]
158+
] || selectedRoute?.route?.usedBridgeNames?.[0]
159+
}
160+
/>
161+
<RouteDetailRow
162+
label="Estimated Bridging Time"
163+
value={timeInMinutes(selectedRoute?.route?.serviceTime)}
164+
/>
165+
<RouteDetailRow label="Bridge Fee">
166+
<FeeDisplay
167+
feeInToken={bridgeFeeInToken}
168+
feeInUsd={bridgeFee}
169+
tokenSymbol={bridgeFeeTokenSymbol}
170+
/>
171+
</RouteDetailRow>
172+
</>
173+
) : (
174+
<RouteDetailRow
175+
label="Dex Name"
176+
value={swapData?.protocol?.displayName}
177+
/>
178+
)}
150179
<RouteDetailRow label="Source Gas Fee">
151180
<FeeDisplay
152181
feeInToken={sourceFeesInToken}
153182
feeInUsd={sourceFeesInUSD}
154183
tokenSymbol={sourceNativeToken?.symbol}
155184
/>
156185
</RouteDetailRow>
157-
{!!destFeesInToken && (
158-
<RouteDetailRow label="Dest Gas Fee">
159-
<FeeDisplay
160-
feeInToken={destFeesInToken}
161-
feeInUsd={destFeesInUSD}
162-
tokenSymbol={destNativeToken?.symbol}
186+
{!!destFeesInToken && !isSameChainSwap && (
187+
<>
188+
<RouteDetailRow label="Dest Gas Fee">
189+
<FeeDisplay
190+
feeInToken={destFeesInToken}
191+
feeInUsd={destFeesInUSD}
192+
tokenSymbol={destNativeToken?.symbol}
193+
/>
194+
</RouteDetailRow>
195+
<RouteDetailRow
196+
label="Number of transactions"
197+
value={selectedRoute?.route?.totalUserTx}
163198
/>
164-
</RouteDetailRow>
199+
</>
165200
)}
166-
<RouteDetailRow label="Bridge Fee">
167-
<FeeDisplay
168-
feeInToken={bridgeFeeInToken}
169-
feeInUsd={bridgeFee}
170-
tokenSymbol={bridgeFeeTokenSymbol}
171-
/>
172-
</RouteDetailRow>
173-
<RouteDetailRow
174-
label="Number of transactions"
175-
value={selectedRoute?.route?.totalUserTx}
176-
/>
177201
</div>
178202
</div>
179203

@@ -224,7 +248,9 @@ export const ReviewModal = ({
224248
onClick={quoteUpdated ? updateSelectedRoute : openTxModal}
225249
classNames={`${quoteUpdated ? "h-12" : ""}`}
226250
>
227-
{quoteUpdated ? "Accept" : "Confirm Bridge"}
251+
{quoteUpdated
252+
? "Accept"
253+
: `Confirm ${isSameChainSwap ? "Swap" : "Bridge"}`}
228254
</Button>
229255
</div>
230256
</InnerCard>
@@ -272,7 +298,7 @@ const FeeDisplay = (props: FeeDisplayProps) => {
272298
)}
273299
{feeInUsd !== 0 && (
274300
<span className="opacity-80 font-normal">
275-
(${feeInUsd.toFixed(4)})
301+
(${feeInUsd?.toFixed(4)})
276302
</span>
277303
)}
278304
</span>

src/components/RouteDetails/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,16 @@ export const RouteDetails = () => {
150150
return `Not enough ${nativeTokenWithBalance?.symbol} for Refuel (${minReq} required)`;
151151
}
152152

153+
const sourceAmount = formatCurrencyAmount(bestRoute?.route?.fromAmount, bestRoute?.path?.fromToken?.decimals);
154+
const destAmount = formatCurrencyAmount(bestRoute?.route?.toAmount, bestRoute?.path?.toToken?.decimals);
155+
const conversion = Number(destAmount)/Number(sourceAmount);
156+
const conversionMessage = `1 ${bestRoute?.path?.fromToken?.symbol} = ${conversion?.toFixed(4)} ${bestRoute?.path?.toToken?.symbol}`;
157+
153158
return shouldFetch
154159
? isQuotesLoading
155160
? QuoteStatus.FETCHING_QUOTE
156161
: bestRoute
157-
? bridgeName
162+
? bridgeName ?? conversionMessage
158163
: QuoteStatus.NO_ROUTES_AVAILABLE
159164
: QuoteStatus.ENTER_AMOUNT;
160165
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { formatCurrencyAmount } from "../../utils/";
2+
import { useSelector } from "react-redux";
3+
4+
export const RefuelAmount = ({ src = false }: { src?: boolean }) => {
5+
const bestRoute = useSelector((state: any) => state.quotes.bestRoute);
6+
const refuel = bestRoute?.refuel;
7+
const amount = formatCurrencyAmount(
8+
src ? refuel?.fromAmount : refuel?.toAmount,
9+
src ? refuel?.fromAsset?.decimals : refuel?.toAsset?.decimals,
10+
3
11+
);
12+
13+
if (!refuel) return null;
14+
15+
return (
16+
<span className="skt-w text-widget-accent text-xs absolute left-0 -bottom-5">
17+
+ {amount} {src ? refuel?.fromAsset?.symbol : refuel?.toAsset?.symbol}
18+
</span>
19+
);
20+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { SetStateAction, useContext } from "react";
2+
import { CustomizeContext } from "../../providers/CustomizeProvider";
3+
import { Search, XCircle } from "react-feather";
4+
5+
interface SearchBarProps {
6+
handleInput: (e) => void;
7+
searchInput: string;
8+
setSearchInput: React.Dispatch<SetStateAction<string>>;
9+
}
10+
11+
export const SearchBar = (props: SearchBarProps) => {
12+
const { handleInput, searchInput, setSearchInput } = props;
13+
const customSettings = useContext(CustomizeContext);
14+
const { borderRadius } = customSettings.customization;
15+
16+
return (
17+
<div
18+
className="skt-w flex items-center px-2 w-full bg-widget-primary border border-widget-secondary-text/30 text-widget-primary text-sm overflow-hidden focus-within:border-widget-secondary-text relative"
19+
style={{ borderRadius: `calc(0.5rem * ${borderRadius})` }}
20+
>
21+
<Search className="skt-w w-5 h-5 text-widget-secondary mr-2" />
22+
<input
23+
onChange={(e) => handleInput(e.target.value)}
24+
placeholder="Search Name or Address"
25+
className="stk-w skt-w-input w-full border-none py-2 pr-7 bg-transparent overflow-x-hidden overflow-ellipsis"
26+
role="search"
27+
value={searchInput}
28+
spellCheck={false}
29+
/>
30+
31+
{!!searchInput && (
32+
<XCircle
33+
className="skt-w bg-widget-primary w-5 h-5 text-widget-secondary hover:text-secondary absolute right-3 top-.25 cursor-pointer"
34+
onClick={() => {
35+
setSearchInput("");
36+
handleInput("");
37+
}}
38+
/>
39+
)}
40+
</div>
41+
);
42+
};

0 commit comments

Comments
 (0)