Skip to content

Commit

Permalink
Merge branch 'main' into feat/3907-state-reconstruction-events
Browse files Browse the repository at this point in the history
  • Loading branch information
jpnovais authored Sep 18, 2024
2 parents 58dd53e + 1561fe8 commit d5cacaa
Show file tree
Hide file tree
Showing 31 changed files with 213 additions and 107 deletions.
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

0 comments on commit d5cacaa

Please sign in to comment.