diff --git a/components/01-atoms/BlockExplorerExternalLinkButton.tsx b/components/01-atoms/BlockExplorerExternalLinkButton.tsx new file mode 100644 index 00000000..1d29e1ff --- /dev/null +++ b/components/01-atoms/BlockExplorerExternalLinkButton.tsx @@ -0,0 +1,36 @@ +import { ExternalLinkIcon } from "@/components/01-atoms"; +import { EthereumAddress } from "@/lib/shared/types"; +import { useNetwork } from "wagmi"; + +export const BlockExplorerExternalLinkButton = ({ + address, + label, +}: { + address: EthereumAddress; + label?: string; +}) => { + const { chain } = useNetwork(); + + if (!address) return null; + + const displayEllipsedAddress = address.getEllipsedAddress(); + + const blockExplorer = `${ + chain?.blockExplorers?.default.url + }/address/${address.toString()}`; + + return ( +
+ +

{label || displayEllipsedAddress}

+
+ +
+
+
+ ); +}; diff --git a/components/01-atoms/LoadingIndicator.tsx b/components/01-atoms/LoadingIndicator.tsx index 8c1da6b7..d4765759 100644 --- a/components/01-atoms/LoadingIndicator.tsx +++ b/components/01-atoms/LoadingIndicator.tsx @@ -1,5 +1,8 @@ -import React, { HTMLProps } from "react"; +import { HTMLProps } from "react"; export const LoadingIndicator = (props: HTMLProps) => ( -
+
); diff --git a/components/01-atoms/SearchBar.tsx b/components/01-atoms/SearchBar.tsx index 8fad0a67..75d6be13 100644 --- a/components/01-atoms/SearchBar.tsx +++ b/components/01-atoms/SearchBar.tsx @@ -60,7 +60,7 @@ export const SearchBar = () => { setUserJustValidatedInput(true); } } else if (inputAddress && !authenticatedUserAddress) { - toast.error("Cannot get ENS address without connect your wallet"); + toast.error("Cannot get ENS address without connecting your wallet"); } }; diff --git a/components/01-atoms/index.ts b/components/01-atoms/index.ts index 16f5741b..f69e19c0 100644 --- a/components/01-atoms/index.ts +++ b/components/01-atoms/index.ts @@ -1,5 +1,6 @@ /** Atoms */ export * from "./ApprovedTokenCards"; +export * from "./BlockExplorerExternalLinkButton"; export * from "./ConnectWallet"; export * from "./DisconnectWallet"; export * from "./ENSAvatar"; diff --git a/components/02-molecules/EnsNameAndAddressWallet.tsx b/components/02-molecules/EnsNameAndAddressWallet.tsx index 54e29dba..0030fb13 100644 --- a/components/02-molecules/EnsNameAndAddressWallet.tsx +++ b/components/02-molecules/EnsNameAndAddressWallet.tsx @@ -1,9 +1,10 @@ import { CopyAdressButton } from "@/components/02-molecules"; -import { ENSAvatar, ExternalLinkIcon } from "@/components/01-atoms"; +import { + BlockExplorerExternalLinkButton, + ENSAvatar, +} from "@/components/01-atoms"; import { useAuthenticatedUser } from "@/lib/client/hooks/useAuthenticatedUser"; import { useEnsData } from "@/lib/client/hooks/useENSData"; -import React from "react"; -import { useNetwork } from "wagmi"; export const EnsNameAndAddressWallet = () => { const { authenticatedUserAddress } = useAuthenticatedUser(); @@ -12,14 +13,8 @@ export const EnsNameAndAddressWallet = () => { ensAddress: authenticatedUserAddress, }); - const { chain } = useNetwork(); - if (!authenticatedUserAddress) return null; - const blockExplorer = `${ - chain?.blockExplorers?.default.url - }/address/${authenticatedUserAddress?.toString()}`; - const displayAddress = authenticatedUserAddress?.getEllipsedAddress(); return ( @@ -42,20 +37,10 @@ export const EnsNameAndAddressWallet = () => { displayAddress={displayAddress} />
-
- -

- View on explorer -

-
- -
-
-
+ )} diff --git a/components/03-organisms/ApproveTokenCard.tsx b/components/03-organisms/ApproveTokenCard.tsx index 634e453f..1502b1f4 100644 --- a/components/03-organisms/ApproveTokenCard.tsx +++ b/components/03-organisms/ApproveTokenCard.tsx @@ -1,4 +1,5 @@ /* eslint-disable react-hooks/exhaustive-deps */ +import { BlockExplorerExternalLinkButton } from "@/components/01-atoms"; import { TokenCard, TokenCardActionType, @@ -13,7 +14,7 @@ import { SWAPLACE_SMART_CONTRACT_ADDRESS } from "@/lib/client/constants"; import { useAuthenticatedUser } from "@/lib/client/hooks/useAuthenticatedUser"; import { isTokenSwapApproved } from "@/lib/service/verifyTokensSwapApproval"; import { IApproveTokenSwap } from "@/lib/client/swap-utils"; -import { getTokenName } from "@/lib/client/ui-utils"; +import { getTokenContractAddress, getTokenName } from "@/lib/client/ui-utils"; import { Token } from "@/lib/shared/types"; import toast from "react-hot-toast"; import { type TransactionReceipt } from "viem"; @@ -79,13 +80,12 @@ export const ApproveTokenCard = ({ throw new Error("User is not connected to any network"); } - setTokenApprovalStatus(TokenApprovalStatus.APPROVE_IN_YOUR_WALLET); - const approved = await checkForTokenApproval(token); if (approved) { toast.success(`${getTokenName(token)} was approved for swap`); } else { + setTokenApprovalStatus(TokenApprovalStatus.APPROVE_IN_YOUR_WALLET); await askForTokenApproval(token).then((isApproved) => { if (typeof isApproved !== "undefined") { setIsApproved(true); @@ -168,42 +168,53 @@ export const ApproveTokenCard = ({ onClick={() => handleTokenApproval()} role="button" > -
- -
-
-
-

{getTokenName(token)}

+
+
+
-
- {tokenApprovalStatus === TokenApprovalStatus.CLICK_TO_APPROVE ? ( -

- CLICK TO APPROVE -

- ) : tokenApprovalStatus === - TokenApprovalStatus.APPROVE_IN_YOUR_WALLET ? ( -

- APPROVE TRANSACTION REQUEST IN YOUR WALLET -

- ) : tokenApprovalStatus === - TokenApprovalStatus.WAITING_BLOCKCHAIN_CONFIRMATION ? ( -

- WAITING FOR BLOCKCHAIN CONFIRMATION -

- ) : TokenApprovalStatus.APPROVED ? ( -
-

APPROVED

-
- ) : null} +
+
+

{getTokenName(token)}

+
+
+ {tokenApprovalStatus === TokenApprovalStatus.CLICK_TO_APPROVE ? ( +

+ CLICK TO APPROVE +

+ ) : tokenApprovalStatus === + TokenApprovalStatus.APPROVE_IN_YOUR_WALLET ? ( +

+ APPROVE TRANSACTION REQUEST IN YOUR WALLET +

+ ) : tokenApprovalStatus === + TokenApprovalStatus.WAITING_BLOCKCHAIN_CONFIRMATION ? ( +

+ WAITING FOR BLOCKCHAIN CONFIRMATION +

+ ) : TokenApprovalStatus.APPROVED ? ( +
+

APPROVED

+
+ ) : null} +
+
event.stopPropagation()} + > + +
); }; diff --git a/lib/client/ui-utils.ts b/lib/client/ui-utils.ts index 8a149e25..4298f1b2 100644 --- a/lib/client/ui-utils.ts +++ b/lib/client/ui-utils.ts @@ -3,6 +3,7 @@ import { ERC20, ERC20WithTokenAmountSelection, ERC721, + EthereumAddress, Token, TokenType, } from "../shared/types"; @@ -60,3 +61,24 @@ export const getTokenName = ( return `${token.tokenType} - Token Name Not Found`; } }; + +/** + * + * @param token + * @returns TokenContractAddress from token, returns EthereumAddress type. + */ +export const getTokenContractAddress = (token: Token): EthereumAddress => { + if (!token) throw new Error("Token not defined"); + + let address: EthereumAddress | undefined = !token.contract + ? (token as ERC721).contractMetadata?.address + : typeof token.contract === "string" + ? new EthereumAddress(token.contract) + : undefined; + + if (address === undefined) + throw new Error( + `Token contract address not defined for ${getTokenName(token)}`, + ); + return address; +}; diff --git a/styles/global.css b/styles/global.css index 7fcd2897..9bca87e3 100644 --- a/styles/global.css +++ b/styles/global.css @@ -198,7 +198,7 @@ input[type="number"] { @apply shadow-inner w-[90px] h-[90px] lg:w-[80px] lg:h-[80px] relative rounded-xl border border-[#E0E0E0] bg-[#E0E0E0] dark:bg-[#353836] dark:border-[#212322] flex flex-col shadow-token; } .card-token-small { - @apply shadow-inner mx-auto w-[44px] h-[44px] lg:w-[44px] lg:h-[44px] relative rounded-lg border-2 border-[#E0E0E0] bg-[#E0E0E0] dark:bg-[#353836] dark:border-[#212322] flex flex-col shadow-token; + @apply shadow-inner mx-auto w-[55px] h-[55px] lg:w-[55px] lg:h-[55px] relative rounded-lg border-2 border-[#E0E0E0] bg-[#E0E0E0] dark:bg-[#353836] dark:border-[#212322] flex flex-col shadow-token; } .card-token-medium { @apply shadow-inner w-[72px] h-[72px] lg:w-[72px] lg:h-[72px] relative rounded-xl border border-[#E0E0E0] bg-[#E0E0E0] dark:bg-[#353836] dark:border-[#212322] flex flex-col shadow-token;