Skip to content

Commit

Permalink
Enhance Redeem Tool (#953)
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinoConti authored Feb 24, 2025
1 parent 4f67b98 commit 9a54bb5
Show file tree
Hide file tree
Showing 17 changed files with 933 additions and 1,138 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@
"@radix-ui/react-toggle-group": "1.0.2",
"@radix-ui/react-tooltip": "1.0.5",
"@types/swagger-ui-react": "^4.18.3",
"@wormhole-foundation/sdk": "^1.7.0",
"@wormhole-foundation/sdk-solana": "^1.7.0",
"@wormhole-foundation/sdk-solana-core": "^1.7.0",
"@xlabs/wormhole-connect": "^1.0.0-fork.2-development",
"@wormhole-foundation/sdk": "1.10.1-beta.0",
"@wormhole-foundation/sdk-solana": "1.10.1-beta.0",
"@wormhole-foundation/sdk-solana-core": "1.10.1-beta.0",
"@xlabs/wormhole-connect": "1.0.0-fork.3-development",
"analytics": "^0.8.9",
"apexcharts": "^3.49.1",
"axios": "^1.4.0",
Expand Down
11 changes: 9 additions & 2 deletions src/components/atoms/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ReactNode } from "react";
import { CrossIcon } from "src/icons/generic";
import "./styles.scss";

interface ModalProps {
Expand All @@ -10,12 +11,18 @@ interface ModalProps {
const Modal = ({ shouldShow, setShouldShow, children }: ModalProps) => {
if (!shouldShow) return null;

const handleOverlayClick = (e: React.MouseEvent) => {
if (e.target === e.currentTarget) {
setShouldShow(false);
}
};

return (
<div className={"modal_overlay"}>
<div className={"modal_overlay"} onClick={handleOverlayClick}>
<div className={"modal_content"}>
{children}
<button className={"modal_close"} onClick={() => setShouldShow(false)}>
X
<CrossIcon />
</button>
</div>
</div>
Expand Down
35 changes: 24 additions & 11 deletions src/components/atoms/Modal/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,43 @@
}

&_content {
position: fixed;
bottom: 0;
left: 0;
right: 0;
max-width: 100%;
border-radius: 12px 12px 0 0;
box-shadow: 0 -5px 20px var(--color-gray-900);
background-color: var(--color-gray-900);
box-shadow: 20px 20px 40px var(--color-gray-900);
padding: 30px;
border-radius: 12px;
max-width: 720px;
width: 100%;
text-align: center;
position: relative;

@include desktop {
box-shadow: 20px 20px 40px var(--color-gray-900);
border-radius: 12px;
max-width: 720px;
width: 100%;
text-align: center;
position: relative;
padding: 0;
}
}

&_close {
@include centered-row;
justify-content: center;

position: absolute;
top: 10px;
right: 10px;
background-color: transparent;
border: 1px solid var(--color-white-30);
border: 0px;
border-radius: 50%;

width: 40px;
height: 40px;
width: 24px;
height: 24px;

color: var(--color-white);
background-color: var(--color-white-10);
font-size: 18px;
font-size: 14px;
cursor: pointer;

&:hover {
Expand Down
14 changes: 14 additions & 0 deletions src/icons/generic/PlayIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const PlayIcon = ({ style, width }: { style?: any; width: number }) => (
<svg
style={style}
width={width}
height={width}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M8.75 17.5V6.5L17.75 12L8.75 17.5Z" stroke="currentColor" strokeWidth="1.5" />
</svg>
);

export default PlayIcon;
10 changes: 8 additions & 2 deletions src/icons/generic/WalletIcon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
const WalletIcon = ({ width = 24 }: { width?: number }) => (
const WalletIcon = ({
width = 24,
circleColor = "#333333",
}: {
width?: number;
circleColor?: string;
}) => (
<svg
fill="none"
height={width}
viewBox="0 0 24 24"
width={width}
xmlns="http://www.w3.org/2000/svg"
>
<circle cx={12} cy={12} r={12} fill="#333333" />
<circle cx={12} cy={12} r={12} fill={circleColor} />
<rect x={6} y={9} width={12} height={9} rx={2} stroke="currentColor" strokeWidth="1.5" />
<path d="M14 13.5H15.5" stroke="currentColor" strokeWidth="1.5" />
<path
Expand Down
1 change: 1 addition & 0 deletions src/icons/generic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export { default as MoneyIcon } from "./MoneyIcon";
export { default as OverviewIcon } from "./OverviewIcon";
export { default as PercentageIcon } from "./PercentageIcon";
export { default as PieChartIcon } from "./PieChartIcon";
export { default as PlayIcon } from "./PlayIcon";
export { default as Rectangle3DIcon } from "./Rectangle3DIcon";
export { default as Rectangle3DIcon2 } from "./Rectangle3DIcon2";
export { default as SearchIcon } from "./SearchIcon";
Expand Down
88 changes: 37 additions & 51 deletions src/pages/Tx/Information/Summary/Redeem/RedeemModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { ChainId, Network } from "@wormhole-foundation/sdk";
import { CopyToClipboard } from "src/components/molecules";
import { CopyIcon } from "src/icons/generic";
import { shortAddress } from "src/utils/crypto";
import { ChainId, chainIdToChain, Network } from "@wormhole-foundation/sdk";
import { WalletIcon } from "src/icons/generic";
import { getExplorerLink } from "src/utils/wormhole";
import { BlockchainIcon } from "src/components/atoms";
import "./styles.scss";
Expand Down Expand Up @@ -29,62 +27,50 @@ const RedeemModal = ({
}: RedeemModalProps) => {
return (
<div className="redeem-modal">
<div className="redeem-modal-title">Source</div>
<div className="redeem-modal-address">
<BlockchainIcon chainId={fromChain} network={currentNetwork} />
<a
href={getExplorerLink({
network: currentNetwork,
chainId: fromChain,
value: parsedOriginAddress,
base: "address",
isNativeAddress: true,
})}
target="_blank"
rel="noopener noreferrer"
>
{shortAddress(parsedOriginAddress.toUpperCase())}
</a>
<CopyToClipboard toCopy={parsedOriginAddress}>
<CopyIcon width={24} />
</CopyToClipboard>
<div className="redeem-modal-icon">
<WalletIcon width={80} circleColor="transparent" />
</div>

<div className="redeem-modal-amount">
<span>(</span>
<span>{amountSent}</span>
<div className="redeem-modal-content">
<div className="redeem-modal-content-title">You are about to redeem</div>

<div className="redeem-modal-content-info">
{amountSent}
<a href={sourceTokenLink} target="_blank" rel="noopener noreferrer">
{sourceSymbol}
</a>
from <BlockchainIcon chainId={fromChain} network={currentNetwork} />{" "}
<a
href={sourceTokenLink}
href={getExplorerLink({
network: currentNetwork,
chainId: fromChain,
value: parsedOriginAddress,
base: "address",
isNativeAddress: true,
})}
target="_blank"
rel="noopener noreferrer"
style={{ marginLeft: 4 }}
>
{sourceSymbol}
{chainIdToChain(fromChain)}
</a>

<span>)</span>
</div>
</div>

<div className="redeem-modal-title">Target</div>
<div className="redeem-modal-address">
<BlockchainIcon chainId={toChain} network={currentNetwork} />
<a
href={getExplorerLink({
network: currentNetwork,
chainId: toChain,
value: parsedDestinationAddress,
base: "address",
isNativeAddress: true,
})}
target="_blank"
rel="noopener noreferrer"
>
{shortAddress(parsedDestinationAddress.toLocaleUpperCase())}
</a>
<CopyToClipboard toCopy={parsedDestinationAddress}>
<CopyIcon width={24} />
</CopyToClipboard>
<div className="redeem-modal-content-info">
to <BlockchainIcon chainId={toChain} network={currentNetwork} />
<a
href={getExplorerLink({
network: currentNetwork,
chainId: toChain,
value: parsedDestinationAddress,
base: "address",
isNativeAddress: true,
})}
target="_blank"
rel="noopener noreferrer"
>
{chainIdToChain(toChain)}
</a>
</div>
</div>
</div>
);
Expand Down
17 changes: 17 additions & 0 deletions src/pages/Tx/Information/Summary/Redeem/RedeemModalError.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AlertTriangle } from "src/icons/generic";

const RedeemModalError = ({ error }: { error: string }) => (
<div className="redeem-modal">
<div className="redeem-modal-error-icon">
<AlertTriangle width={80} />
</div>

<div className="redeem-modal-content">
<div className="redeem-modal-content-title">Transaction failed.</div>

<div className="redeem-modal-content-info">{error}</div>
</div>
</div>
);

export default RedeemModalError;
22 changes: 22 additions & 0 deletions src/pages/Tx/Information/Summary/Redeem/RedeemModalLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Loader } from "src/components/atoms";

const RedeemModalLoading = ({
shouldShowDisclaimer = false,
}: {
shouldShowDisclaimer: boolean;
}) => (
<div className="redeem-modal">
<Loader />

{shouldShowDisclaimer && (
<div className="redeem-modal-content">
<div className="redeem-modal-content-title">
<p>Transaction in progress, please do not clone or refresh this modal.</p>
<p>This will only take a moment.</p>
</div>
</div>
)}
</div>
);

export default RedeemModalLoading;
19 changes: 19 additions & 0 deletions src/pages/Tx/Information/Summary/Redeem/RedeemModalSuccess.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CheckCircle2 } from "src/icons/generic";

const RedeemModalSuccess = () => (
<div className="redeem-modal">
<div className="redeem-modal-success-icon">
<CheckCircle2 width={80} />
</div>

<div className="redeem-modal-content" style={{ color: "var(--color-white)" }}>
<div className="redeem-modal-content-title">
The tokens are now in the destination wallet.
</div>

<div className="redeem-modal-content-info">Transaction will be updated shortly.</div>
</div>
</div>
);

export default RedeemModalSuccess;
30 changes: 26 additions & 4 deletions src/pages/Tx/Information/Summary/Redeem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,24 @@ import { Loader } from "src/components/atoms";
import { fetchTokensConfig } from "./fetchTokensConfig";

type Props = {
txHash: string;
sourceChain: ChainId;
CustomComponent?: () => JSX.Element;
CustomError?: (props: { error: string }) => JSX.Element;
CustomLoading?: (props: { shouldShowDisclaimer: boolean }) => JSX.Element;
CustomSuccess?: () => JSX.Element;
network: Network;
sourceChain: ChainId;
txHash: string;
};

export const Redeem = ({ txHash, sourceChain, CustomComponent, network }: Props) => {
export const Redeem = ({
CustomComponent,
CustomError,
CustomLoading,
CustomSuccess,
network,
sourceChain,
txHash,
}: Props) => {
const [isLoadingConnect, setIsLoadingConnect] = useState(true);
const [config, setConfig] = useState<WormholeConnectConfig>(null);

Expand All @@ -32,7 +43,18 @@ export const Redeem = ({ txHash, sourceChain, CustomComponent, network }: Props)
chainName: chainIdToChain(sourceChain),
txHash: txHash,
customTxDetails: () => <CustomComponent />,
customLoading: () => <Loader />,
customLoading: shouldShowDisclaimer => (
<CustomLoading shouldShowDisclaimer={shouldShowDisclaimer} />
),
buttonStyles: {
backgroundColor: "var(--color-plum)",
borderRadius: "16px",
color: "var(--color-black)",
fontSize: "14px",
fontWeight: "600",
},
customError: error => <CustomError error={error} />,
customSuccess: () => <CustomSuccess />,
},
},
chains: [
Expand Down
Loading

0 comments on commit 9a54bb5

Please sign in to comment.