Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix(3102): feedback fixes #40

Merged
merged 10 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/bridge-ui-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:

jobs:
run-e2e-tests:
runs-on: ubuntu-22.04-16core
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion bridge-ui/src/assets/icons/swap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 8 additions & 9 deletions bridge-ui/src/components/bridge/Amount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ export function Amount() {
const { address } = useAccount();

const { setValue, getValues, setError, clearErrors, trigger, watch } = useFormContext();
const watchBalance = watch("balance") || "0";
const amount = getValues("amount");
const gasFees = getValues("gasFees") || BigInt(0);
const minFees = getValues("minFees") || BigInt(0);
const watchBalance = watch("balance");
const [amount, gasFees, minFees] = getValues(["amount", "gasFees", "minFees"]);

const { data: tokenPrices } = useTokenPrices([tokenAddress], fromChain?.id);

Expand All @@ -35,7 +33,7 @@ export function Amount() {
}
const amountToCompare =
token.type === TokenType.ETH
? parseUnits(_amount, token.decimals) + gasFees + parseUnits(minFees.toString(), 18)
? parseUnits(_amount, token.decimals) + gasFees + minFees
: parseUnits(_amount, token.decimals);

const balanceToCompare = parseUnits(watchBalance, token.decimals);
Expand Down Expand Up @@ -124,13 +122,14 @@ export function Amount() {
/>
{networkType === NetworkType.MAINNET && (
<span className="label-text flex items-center justify-end">
<PiApproximateEqualsBold /> $
<PiApproximateEqualsBold />
{amount && tokenPrices?.[tokenAddress]?.usd
? `${(Number(amount) * tokenPrices?.[tokenAddress]?.usd).toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 10,
style: "currency",
currency: "USD",
maximumFractionDigits: 4,
})}`
: "0.00"}
: "$0.00"}
</span>
)}
</>
Expand Down
29 changes: 24 additions & 5 deletions bridge-ui/src/components/bridge/Bridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { BridgeForm, Transaction } from "@/models";
import { useChainStore } from "@/stores/chainStore";
import { NetworkLayer, TokenType } from "@/config";
import { useBridge, useSwitchNetwork, useFetchHistory } from "@/hooks";
import { parseEther } from "viem";
import TokenList from "./TokenList";
import { toast } from "react-toastify";
import { ERC20Stepper } from "./ERC20Stepper";
Expand All @@ -31,13 +30,19 @@ import TransactionConfirmationModal from "./modals/TransactionConfirmationModal"
const Bridge = () => {
const [waitingTransaction, setWaitingTransaction] = useState<Transaction | undefined>();
const { handleShow, handleClose } = useContext(ModalContext);
const { fromChain, token, networkLayer } = useChainStore((state) => ({
const {
fromChain,
token,
networkLayer,
switchChain: switchChainInStore,
} = useChainStore((state) => ({
fromChain: state.fromChain,
token: state.token,
networkLayer: state.networkLayer,
switchChain: state.switchChain,
}));

const { handleSubmit, watch, reset } = useFormContext<BridgeForm>();
const { handleSubmit, watch, reset, setValue } = useFormContext<BridgeForm>();

const [amount, bridgingAllowed, claim] = watch(["amount", "bridgingAllowed", "claim"]);

Expand Down Expand Up @@ -76,6 +81,10 @@ const Bridge = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hash]);

useEffect(() => {
setValue("gasFees", fees.transactionFeeInWei);
}, [fees.transactionFeeInWei, setValue]);

// Clear tx waiting when changing account
useEffect(() => {
setWaitingTransaction(undefined);
Expand Down Expand Up @@ -123,7 +132,7 @@ const Bridge = () => {
const onSubmit = async (data: BridgeForm) => {
if (isLoading || isWaitingLoading) return;
await switchChain();
bridge(data.amount, parseEther(data.minFees), data.recipient);
bridge(data.amount, data.minFees, data.recipient);
};

return (
Expand All @@ -150,7 +159,17 @@ const Bridge = () => {
</div>

<div className="divider my-6 flex justify-center">
<SwapIcon />
<button
className="btn btn-circle w-fit transition-transform duration-200"
onClick={(e) => {
e.preventDefault();
e.currentTarget.classList.toggle("rotate-180");
switchChainInStore();
reset();
}}
>
<SwapIcon />
</button>
</div>

<ToChain />
Expand Down
5 changes: 4 additions & 1 deletion bridge-ui/src/components/bridge/BridgeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export default function BridgeLayout() {
token: configContextValue?.UNKNOWN[0],
claim: token?.type === TokenType.ETH ? "auto" : "manual",
amount: "",
minFees: "0",
minFees: 0n,
gasFees: 0n,
bridgingAllowed: false,
balance: "0",
},
});

Expand Down
6 changes: 4 additions & 2 deletions bridge-ui/src/components/bridge/FromChainDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export default function FromChainDropdown() {
style={{ width: "18px", height: "auto" }}
/>
)}
<span className="hidden md:block">{fromChain?.name}</span>
<span className="hidden md:block">
{fromChain?.name === "Linea Sepolia Testnet" ? "Linea Sepolia" : fromChain?.name}
</span>
<svg
className="size-4 text-card transition-transform"
fill="none"
Expand All @@ -62,7 +64,7 @@ export default function FromChainDropdown() {
</summary>
<ul className="menu dropdown-content absolute right-0 z-10 mt-2 min-w-max border-2 border-card bg-cardBg p-0 shadow">
<DropdownItem
title={toChain?.name || ""}
title={toChain?.name ? (toChain?.name === "Linea Sepolia Testnet" ? "Linea Sepolia" : toChain?.name) : ""}
iconPath={toChain && getChainLogoPath(toChain.id)}
onClick={switchNetworkHandler}
/>
Expand Down
9 changes: 5 additions & 4 deletions bridge-ui/src/components/bridge/ReceivedAmount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ export function ReceivedAmount({ receivedAmount }: ReceivedAmountProps) {
</span>
{networkType === NetworkType.MAINNET && (
<span className="label-text flex items-center">
<PiApproximateEqualsBold /> $
<PiApproximateEqualsBold />
{tokenPrices?.[tokenAddress]?.usd
? (Number(receivedAmount) * tokenPrices?.[tokenAddress]?.usd).toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 10,
style: "currency",
currency: "USD",
maximumFractionDigits: 4,
})
: "0.00"}
: "$0.00"}
</span>
)}
</>
Expand Down
12 changes: 8 additions & 4 deletions bridge-ui/src/components/bridge/Recipient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,24 @@ export function Recipient() {
return (
<div className="collapse rounded-none">
<input type="checkbox" className="min-h-0" onChange={toggleCheckbox} />
<div className="align-items collapse-title flex h-6 min-h-0 flex-row items-center gap-2 p-0 text-sm">
<div className="collapse-title flex h-6 min-h-1 flex-row items-center gap-2 p-0 text-sm">
<MdAdd className="size-6 text-primary" />
<span className="">To different address</span>
<Tooltip text="Input the address you want to bridge assets to on the recipient chain">
<Tooltip
text="Input the address you want to bridge assets to on the recipient chain"
className="z-[9999]"
position="bottom"
>
<MdInfo />
</Tooltip>
</div>

<div className="collapse-content p-1 !pb-1">
<div className="collapse-content p-0 !pb-1 pt-2">
<div className="form-control w-full">
<div className="flex flex-row">
<input
type="text"
className="input w-full bg-[#2D2D2D]"
className="input w-full bg-[#2D2D2D] focus:border-none focus:outline-none"
placeholder="0x..."
{...register("recipient", {
validate: (value) => !value || isAddress(value) || "Invalid address",
Expand Down
8 changes: 6 additions & 2 deletions bridge-ui/src/components/bridge/ToChainDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ export default function ToChainDropdown() {
style={{ width: "18px", height: "auto" }}
/>
)}
<span className="hidden md:block">{toChain?.name}</span>
<span className="hidden md:block">
{toChain?.name === "Linea Sepolia Testnet" ? "Linea Sepolia" : toChain?.name}
</span>
<svg
className="size-4 text-card transition-transform"
fill="none"
Expand All @@ -63,7 +65,9 @@ export default function ToChainDropdown() {
</summary>
<ul className="menu dropdown-content absolute right-0 z-10 mt-2 min-w-max border-2 border-card bg-cardBg p-0 shadow">
<DropdownItem
title={fromChain?.name || ""}
title={
fromChain?.name ? (fromChain?.name === "Linea Sepolia Testnet" ? "Linea Sepolia" : fromChain?.name) : ""
}
iconPath={fromChain && getChainLogoPath(fromChain.id)}
onClick={switchNetworkHandler}
/>
Expand Down
6 changes: 3 additions & 3 deletions bridge-ui/src/components/bridge/TokenDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ export default function TokenDetails({ token, onTokenClick, setValue, clearError
</p>
{tokenPrice ? (
<p className="text-[#C0C0C0]">
$
{(tokenPrice * Number(balance)).toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
style: "currency",
currency: "USD",
maximumFractionDigits: 4,
})}
</p>
) : null}
Expand Down
49 changes: 36 additions & 13 deletions bridge-ui/src/components/bridge/fees/Fees.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ type FeesProps = {
totalReceived: string;
fees: {
total: bigint;
executionFeeInWei: bigint;
bridgingFeeInWei: bigint;
transactionFeeInWei: bigint;
};
};

export function Fees({ totalReceived, fees: { total, executionFeeInWei, bridgingFeeInWei } }: FeesProps) {
export function Fees({ totalReceived, fees: { total, bridgingFeeInWei, transactionFeeInWei } }: FeesProps) {
// Context
const { token, networkLayer, fromChain, networkType } = useChainStore((state) => ({
token: state.token,
Expand All @@ -27,8 +27,14 @@ export function Fees({ totalReceived, fees: { total, executionFeeInWei, bridging
}));

// Form
const { watch, setError, clearErrors } = useFormContext();
const amount = watch("amount");
const {
watch,
setError,
clearErrors,
setValue,
formState: { errors },
} = useFormContext();
const [amount, claim] = watch(["amount", "claim"]);

// Wagmi
const { address, isConnected } = useAccount();
Expand All @@ -51,34 +57,51 @@ export function Fees({ totalReceived, fees: { total, executionFeeInWei, bridging
}
}, [setError, clearErrors, ethBalance, total]);

useEffect(() => {
setValue("minFees", bridgingFeeInWei);
}, [bridgingFeeInWei, setValue]);

const estimatedTime = networkLayer === NetworkLayer.L1 ? "20 mins" : "8 hrs to 32 hrs";

return (
<div className="flex flex-col gap-2 text-sm">
<FeeLine
label="Estimated Time"
value={amount && estimatedTime}
tooltip="Linea has a minimum 8 hour delay on withdrawals as a security measure.
Withdrawals can take up to 32 hours to complete"
value={amount && !errors.amount?.message && estimatedTime}
tooltip={
networkLayer === NetworkLayer.L1
? "Linea has a 20 minutes delay on deposits as a security measure."
: "Linea has a minimum 8 hour delay on withdrawals as a security measure. Withdrawals can take up to 32 hours to complete"
}
/>
<FeeLine
label="Estimated Total Fee"
value={
isConnected &&
amount &&
!errors.amount?.message &&
(networkType === NetworkType.MAINNET && ethPrice && ethPrice?.[zeroAddress]
? `$${(Number(formatEther(total)) * ethPrice[zeroAddress].usd).toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 10,
? `${(Number(formatEther(total)) * ethPrice[zeroAddress].usd).toLocaleString("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 4,
})}`
: `${formatBalance(formatEther(total))} ETH`)
: `${formatBalance(formatEther(total), 8)} ETH`)
}
tooltipClassName="before:whitespace-pre-wrap before:content-[attr(data-tip)] text-left"
tooltip={`Execution Fee: ${formatEther(executionFeeInWei)} ETH\nBridging fee: ${formatEther(bridgingFeeInWei)} ETH`}
tooltip={
claim === "auto"
? `Bridging transaction fee: ${formatBalance(formatEther(transactionFeeInWei), 8)} ETH\nAutomatic claiming Fee: ${formatBalance(formatEther(bridgingFeeInWei), 8)} ETH`
: `Bridging transaction fee: ${formatBalance(formatEther(transactionFeeInWei), 8)} ETH`
}
/>
<FeeLine
label="Total Received"
value={totalReceived && totalReceived !== "0" ? `${formatBalance(totalReceived)} ${token?.symbol}` : undefined}
value={
!errors.amount?.message && totalReceived && totalReceived !== "0"
? `${formatBalance(totalReceived)} ${token?.symbol}`
: undefined
}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type TransactionConfirmationModalProps = {
const TransactionConfirmationModal: React.FC<TransactionConfirmationModalProps> = ({ handleClose }) => {
return (
<div className="flex flex-col items-center justify-center gap-8 px-8 py-4">
<h2 className="text-xl">Trandaction confirmed!</h2>
<h2 className="text-xl">Transaction confirmed!</h2>
<div className="flex items-center justify-center gap-4">
<Link href="/" className="btn btn-primary rounded-full uppercase" onClick={handleClose}>
Start a new transaction
Expand Down
Loading
Loading