mirror of
https://github.com/luxfi/bridge.git
synced 2026-09-24 00:26:46 +00:00
934 lines
39 KiB
TypeScript
934 lines
39 KiB
TypeScript
"use client";
|
|
import { shortenAddress, shortenHash } from "@/lib/utils";
|
|
import { ApiResponse } from "@/models/ApiResponse";
|
|
import CopyButton from "@/components/buttons/CopyButton";
|
|
import { ArrowRight, ChevronRight } from "lucide-react";
|
|
import useSWR from "swr";
|
|
import { StatusIcon } from "@/components/SwapHistory/StatusIcons";
|
|
import Link from "next/link";
|
|
import Image from "next/image";
|
|
import { useSettings } from "@/context/settings";
|
|
import LoadingBlocks from "@/components/LoadingBlocks";
|
|
import { SwapStatus } from "@/models/SwapStatus";
|
|
import AppSettings from "@/lib/AppSettings";
|
|
import NotFound from "@/components/NotFound";
|
|
import {
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipProvider,
|
|
TooltipTrigger,
|
|
} from "@/components/shadcn/tooltip";
|
|
import { useRouter } from "next/navigation";
|
|
import BackButton from "@/components/buttons/BackButton";
|
|
import { usePathname } from "next/navigation";
|
|
import Error500 from "@/components/Error500";
|
|
import { getTimeDifferenceFromNow } from "@/components/utils/CalcTime";
|
|
import { TransactionType } from "@/models/TransactionTypes";
|
|
|
|
type Swap = {
|
|
created_date: string;
|
|
status: string;
|
|
destination_address: string;
|
|
source_asset: string;
|
|
source_network: string;
|
|
source_exchange: string;
|
|
destination_asset: string;
|
|
destination_network: string;
|
|
destination_exchange: string;
|
|
refuel: boolean;
|
|
transactions: Transaction[];
|
|
};
|
|
|
|
type Transaction = {
|
|
from: string;
|
|
to: string;
|
|
created_date: string;
|
|
timestamp: string;
|
|
transaction_hash: string;
|
|
explorer_url: string;
|
|
confirmations: number;
|
|
max_confirmations: number;
|
|
amount: number;
|
|
usd_price: number;
|
|
usd_value: number;
|
|
type: string;
|
|
};
|
|
|
|
const options = {
|
|
month: "short" as const,
|
|
day: "numeric" as const,
|
|
hour: "numeric" as const,
|
|
minute: "numeric" as const,
|
|
};
|
|
|
|
const basePath = process.env.NEXT_PUBLIC_APP_BASE_PATH;
|
|
// const version = process.env.NEXT_PUBLIC_API_VERSION
|
|
const version = "sandbox";
|
|
|
|
export default function SearchData({ searchParam }: { searchParam: string }) {
|
|
console.log("🚀 ~ SearchData ~ searchParam:", searchParam);
|
|
|
|
const settings = useSettings();
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
const fetcher = async (url: string) => {
|
|
const res = await fetch(url);
|
|
return res.json();
|
|
};
|
|
const { data, error, isLoading } = useSWR<ApiResponse<Swap[]>>(
|
|
`${AppSettings.BridgeApiUri}/api/explorer/${searchParam}?version=${version}`,
|
|
fetcher,
|
|
{ dedupingInterval: 60000 }
|
|
);
|
|
const swap = data?.data?.[0];
|
|
|
|
const input_transaction = swap?.transactions?.find(
|
|
(t) => t?.type == TransactionType.Input
|
|
);
|
|
const output_transaction = swap?.transactions?.find(
|
|
(t) => t?.type == TransactionType.Output
|
|
);
|
|
const refuel_transaction = swap?.transactions?.find(
|
|
(t) => t?.type == TransactionType.Refuel
|
|
);
|
|
|
|
const sourceLayer = settings?.layers?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() === swap?.source_network?.toLowerCase()
|
|
);
|
|
const sourceToken = sourceLayer?.assets?.find(
|
|
(a) => a?.asset == swap?.source_asset
|
|
);
|
|
|
|
const sourceExchange =
|
|
swap?.source_exchange &&
|
|
settings?.exchanges?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() === swap.source_exchange?.toLowerCase()
|
|
);
|
|
const destinationExchange =
|
|
swap?.destination_exchange &&
|
|
settings?.exchanges?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() ===
|
|
swap.destination_exchange?.toLowerCase()
|
|
);
|
|
|
|
const destinationLayer = settings?.layers?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() ===
|
|
swap?.destination_network?.toLowerCase()
|
|
);
|
|
const destinationToken = destinationLayer?.assets?.find(
|
|
(a) => a?.asset == swap?.destination_asset
|
|
);
|
|
|
|
console.log("🚀 ~ SearchData ~ destinationExchange:", destinationExchange);
|
|
|
|
console.log("🚀 ~ SearchData ~ sourceLayer:", sourceLayer);
|
|
console.log("🚀 ~ SearchData ~ sourceToken:", sourceToken);
|
|
|
|
console.log("🚀 ~ SearchData ~ destinationToken:", destinationToken);
|
|
console.log("🚀 ~ SearchData ~ destinationLayer:", destinationLayer);
|
|
const cost =
|
|
Number(input_transaction?.amount) - Number(output_transaction?.amount);
|
|
|
|
const DestinationNativeToken = destinationLayer?.assets?.find(
|
|
(a) => a.is_native
|
|
);
|
|
// const elapsedTimeInMiliseconds = new Date(swap?.output_transaction?.created_date || '')?.getTime() - new Date(swap?.input_transaction?.created_date || '')?.getTime();
|
|
// const timeElapsed = millisToMinutesAndSeconds(elapsedTimeInMiliseconds);
|
|
const filteredData = data?.data?.filter((s) =>
|
|
s.transactions?.some((t) => t?.type == TransactionType.Input)
|
|
);
|
|
const emptyData = data?.data?.every((s) => !s.transactions.length);
|
|
if (error) return <Error500 />;
|
|
if (isLoading) return <LoadingBlocks />;
|
|
if (data?.error || emptyData) return <NotFound />;
|
|
|
|
const resultsCouldScroll = Number(filteredData?.length) > 5;
|
|
|
|
const Row: React.FC<{
|
|
swap: Swap;
|
|
index: number;
|
|
}> = ({ swap, index }) => {
|
|
const sourceLayer = settings?.layers?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() === swap.source_network?.toLowerCase()
|
|
);
|
|
const sourceToken = sourceLayer?.assets?.find(
|
|
(a) => a?.asset == swap?.source_asset
|
|
);
|
|
|
|
const sourceExchange = settings?.exchanges?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() === swap.source_exchange?.toLowerCase()
|
|
);
|
|
const destinationExchange = settings?.exchanges?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() ===
|
|
swap.destination_exchange?.toLowerCase()
|
|
);
|
|
|
|
const destinationLayer = settings?.layers?.find(
|
|
(l) =>
|
|
l.internal_name?.toLowerCase() ===
|
|
swap.destination_network?.toLowerCase()
|
|
);
|
|
const destinationToken = destinationLayer?.assets?.find(
|
|
(a) => a?.asset == swap?.destination_asset
|
|
);
|
|
|
|
const inputTransaction = swap?.transactions?.find(
|
|
(t) => t?.type == TransactionType.Input
|
|
);
|
|
const outputTransaction = swap?.transactions?.find(
|
|
(t) => t?.type == TransactionType.Output
|
|
);
|
|
|
|
if (!inputTransaction) return null;
|
|
|
|
return (
|
|
<tr
|
|
key={index}
|
|
onClick={(e) => router.push(`/${inputTransaction?.transaction_hash}`)}
|
|
className="hover:bg-level-2 hover:cursor-pointer"
|
|
>
|
|
<td className="whitespace-nowrap border-l border-r border-b border-[#404040] py-2 px-3 text-sm font-medium">
|
|
<Link
|
|
href={`/${inputTransaction?.transaction_hash}`}
|
|
onClick={(e) => e.stopPropagation()}
|
|
className="hover:text-gray-300 inline-flex items-center w-fit"
|
|
>
|
|
{shortenAddress(inputTransaction?.transaction_hash)}
|
|
</Link>
|
|
<div className="">
|
|
<StatusIcon swap={swap.status} className="mr-1" />
|
|
{new Date(swap.created_date).toLocaleString()}
|
|
</div>
|
|
</td>
|
|
<td className="whitespace-nowrap border-r border-b border-[#404040] px-3 py-2 text-sm ">
|
|
<div className="flex flex-row">
|
|
<div className="flex flex-col items-start ">
|
|
<span className="text-sm md:text-base font-normal text-socket-ternary place-items-end mb-1">
|
|
Token:
|
|
</span>
|
|
<span className="text-sm md:text-base font-normal text-socket-ternary place-items-end min-w-[70px]">
|
|
Source:
|
|
</span>
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<div className="text-sm md:text-base flex flex-row mb-1">
|
|
<div className="flex flex-row items-center ml-4">
|
|
<div className="relative h-4 w-4 md:h-5 md:w-5">
|
|
<span>
|
|
<span></span>
|
|
<Image
|
|
alt={`Source token icon ${index}`}
|
|
src={settings?.resolveImgSrc(sourceToken) || ""}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
</span>
|
|
</div>
|
|
<div className="mx-2.5">
|
|
<span className="">{inputTransaction?.amount}</span>
|
|
<span className="mx-1 ">{swap?.source_asset}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="text-sm md:text-base flex flex-row items-center ml-4">
|
|
<div className="relative h-4 w-4 md:h-5 md:w-5">
|
|
<span>
|
|
<span></span>
|
|
<Image
|
|
alt={`Source chain icon ${index}`}
|
|
src={
|
|
settings?.resolveImgSrc(
|
|
sourceExchange ? sourceExchange : sourceLayer
|
|
) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
</span>
|
|
</div>
|
|
<div className="mx-2 ">
|
|
<Link
|
|
href={`${inputTransaction?.explorer_url}`}
|
|
onClick={(e) => e.stopPropagation()}
|
|
target="_blank"
|
|
className="hover:text-gray-300 inline-flex items-center w-fit"
|
|
>
|
|
<span className="mx-0.5 hover:text-gray-300 underline">
|
|
{sourceExchange
|
|
? sourceExchange?.display_name
|
|
: sourceLayer?.display_name}
|
|
</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td className="whitespace-nowrap border-b border-[#404040] px-3 py-2 text-sm ">
|
|
<div className="flex flex-row">
|
|
<div className="flex flex-col items-start ">
|
|
<span className="text-sm md:text-base font-normal text-socket-ternary place-items-end mb-1">
|
|
Token:
|
|
</span>
|
|
<span className="text-sm md:text-base font-normal text-socket-ternary place-items-end min-w-[70px]">
|
|
Destination:
|
|
</span>
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<div className="text-sm md:text-base flex flex-row">
|
|
<div className="flex flex-row items-center ml-4 mb-1">
|
|
<div className="relative h-4 w-4 md:h-5 md:w-5">
|
|
<span>
|
|
<Image
|
|
alt={`Destination token icon ${index}`}
|
|
src={settings?.resolveImgSrc(destinationToken) || ""}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
</span>
|
|
</div>
|
|
{outputTransaction?.amount ? (
|
|
<div className="mx-2.5">
|
|
<span className=" mx-0.5">
|
|
{outputTransaction?.amount}
|
|
</span>
|
|
<span className="">{swap?.destination_asset}</span>
|
|
</div>
|
|
) : (
|
|
<span className="ml-2.5">-</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="text-sm md:text-base flex flex-row items-center ml-4">
|
|
<div className="relative h-4 w-4 md:h-5 md:w-5">
|
|
<span>
|
|
<span></span>
|
|
<Image
|
|
alt={`Destination chain icon ${index}`}
|
|
src={
|
|
settings?.resolveImgSrc(
|
|
destinationExchange
|
|
? destinationExchange
|
|
: destinationLayer
|
|
) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
</span>
|
|
</div>
|
|
<div className="mx-2 ">
|
|
<Link
|
|
href={`${outputTransaction?.explorer_url}`}
|
|
onClick={(e) => e.stopPropagation()}
|
|
target="_blank"
|
|
className={`${
|
|
!outputTransaction ? "disabled" : ""
|
|
} hover:text-gray-300 inline-flex items-center w-fit`}
|
|
>
|
|
<span
|
|
className={`${
|
|
outputTransaction?.explorer_url ? "underline" : ""
|
|
} mx-0.5 hover:text-gray-300`}
|
|
>
|
|
{destinationExchange
|
|
? destinationExchange?.display_name
|
|
: destinationLayer?.display_name}
|
|
</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td
|
|
className={
|
|
"whitespace-nowrap border-b border-[#404040] text-sm mr-4 " +
|
|
(resultsCouldScroll ? "" : "border-r ")
|
|
}
|
|
>
|
|
<ChevronRight />
|
|
</td>
|
|
</tr>
|
|
);
|
|
};
|
|
|
|
return Number(data?.data?.length) > 1 ? (
|
|
<div className="w-full px-6">
|
|
{!(
|
|
pathname === "/" ||
|
|
pathname === basePath ||
|
|
pathname === `${basePath}/`
|
|
) && (
|
|
<div className="hidden xl:block w-fit mb-3 hover:bg-level-2 hover:text-accent-foreground rounded-lg ring-offset-background transition-colors -ml-5">
|
|
<BackButton className="text-lg font-semibold" />
|
|
</div>
|
|
)}
|
|
<div className="flow-root w-full">
|
|
<div
|
|
className="p-4 mb-4 flex gap-1 rounded-lg border border-[#404040] border-1"
|
|
style={{ width: "fit-content" }}
|
|
>
|
|
<span className="font-bold mr-1 ">Address:</span>
|
|
<span className="break-all">
|
|
{swap?.destination_address}
|
|
<CopyButton
|
|
toCopy={swap?.destination_address || ""}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="inline-flex items-center ml-3 align-middle"
|
|
/>
|
|
</span>
|
|
</div>
|
|
<div
|
|
className={
|
|
resultsCouldScroll
|
|
? "overflow-y-auto h-full max-h-[55vh] 2xl:max-h-[65vh] dataTable"
|
|
: "overflow-hidden"
|
|
}
|
|
>
|
|
<div className="min-w-full pb-2 align-middle sm:rounded-lg">
|
|
<table className="border-spacing-0 w-full relative border-separate">
|
|
<thead className="sticky top-0 z-10 bg-background">
|
|
<tr>
|
|
<th
|
|
scope="col"
|
|
className="cursor-default rounded-tl-lg border-[#404040] border-l border-b border-t px-3 py-3.5 text-left text-sm font-semibold text-muted"
|
|
>
|
|
Source Tx Hash
|
|
</th>
|
|
<th
|
|
scope="col"
|
|
className="cursor-default border-[#404040] border-b border-t px-3 py-3.5 text-left text-sm font-semibold text-muted"
|
|
>
|
|
Source
|
|
</th>
|
|
<th
|
|
scope="col"
|
|
className="cursor-default border-[#404040] border-b border-t px-3 py-3.5 text-left text-sm font-semibold text-muted "
|
|
>
|
|
Destination
|
|
</th>
|
|
<th
|
|
scope="col"
|
|
className={
|
|
"border-[#404040] border-b border-t px-4 py-3.5 text-left text-sm font-semibold text-muted " +
|
|
(Number(filteredData?.length) > 5
|
|
? ""
|
|
: "border-r rounded-tr-lg ")
|
|
}
|
|
/>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{filteredData?.map((swap, index) => (
|
|
<Row swap={swap} index={index} />
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="w-full">
|
|
<div className="sm:rounded-lg w-full">
|
|
{swap && input_transaction && (
|
|
<div className="py-2 lg:py-10 pt-4 sm:px-6 lg:px-8">
|
|
{pathname !== "/" && (
|
|
<div className="hidden xl:block w-fit mb-1 hover:bg-level-2 hover:text-accent-foreground rounded ring-offset-background transition-colors -ml-5">
|
|
<BackButton />
|
|
</div>
|
|
)}
|
|
<div className="md:ml-0 md:mb-6 flex-col sm:flex-row sm:justify-between sm:items-start">
|
|
<div className="mb-4 sm:mb-0">
|
|
<div className="text-sm md:text-base sm:flex justify-between w-full">
|
|
<div className="items-center text-base mb-0.5 ">
|
|
<div className="mr-2 sm:text-xl text-base">
|
|
{swap.status == SwapStatus.Completed &&
|
|
output_transaction ? (
|
|
<div className="flex flex-col sm:flex-row">
|
|
<div>
|
|
<StatusIcon swap={swap.status} />
|
|
<span className="whitespace-nowrap align-bottom">
|
|
at
|
|
</span>
|
|
<span className="whitespace-nowrap align-bottom">
|
|
|
|
<TooltipProvider delayDuration={0}>
|
|
<Tooltip>
|
|
<TooltipTrigger className="cursor-default">
|
|
{new Date(
|
|
input_transaction?.created_date
|
|
)?.toLocaleString("en-US", options)}
|
|
.
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{new Date(swap.created_date).toUTCString()}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
</span>
|
|
</div>
|
|
<p className="sm:self-end">
|
|
<span className="sm:whitespace-nowrap sm:ml-0.5 ">
|
|
Took
|
|
</span>
|
|
<span className="">
|
|
|
|
{getTimeDifferenceFromNow(
|
|
input_transaction?.timestamp,
|
|
output_transaction?.timestamp
|
|
)}
|
|
</span>
|
|
</p>
|
|
<p className="sm:self-end">
|
|
<span className=" sm:ml-1">and cost</span>
|
|
<span className="">
|
|
|
|
{truncateDecimals(
|
|
cost,
|
|
sourceToken?.precision
|
|
)}{" "}
|
|
{swap?.source_asset}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
) : swap.status !== SwapStatus.Completed ? (
|
|
<div className="flex flex-col sm:flex-row">
|
|
<div>
|
|
<StatusIcon swap={swap.status} />
|
|
<span className="whitespace-nowrap align-bottom">
|
|
Published at
|
|
</span>
|
|
<span className="whitespace-nowrap align-bottom">
|
|
|
|
<TooltipProvider delayDuration={0}>
|
|
<Tooltip>
|
|
<TooltipTrigger className="cursor-default">
|
|
{new Date(
|
|
input_transaction?.created_date
|
|
)?.toLocaleString("en-US", options)}
|
|
.
|
|
</TooltipTrigger>
|
|
<TooltipContent>
|
|
{new Date(swap.created_date).toUTCString()}
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
</span>
|
|
</div>
|
|
<p className="sm:self-end">
|
|
<span className="">
|
|
(
|
|
{getTimeDifferenceFromNow(
|
|
input_transaction?.timestamp,
|
|
new Date().toString()
|
|
)}{" "}
|
|
ago)
|
|
</span>
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<div className="flex sm:flex-row">
|
|
<StatusIcon swap={swap.status} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col lg:flex-row items-start gap-4">
|
|
<div className="w-full p-6 grid gap-y-3 items-baseline lg:max-w-[50%] border border-muted-3 border-1 rounded-lg shadow-lg">
|
|
<div className="w-full flex items-center border-b border-muted-3 border-1">
|
|
<div className="text-2xl font-medium">From</div>
|
|
</div>
|
|
<div className="rounded-md w-full grid shadow-lg relative ">
|
|
<div className="flex justify-around">
|
|
<div className="flex-1 ">
|
|
<div className="text-base font-normal ">Asset</div>
|
|
<div className="flex items-center">
|
|
<span className="text-sm lg:text-base font-medium text-socket-table flex items-center">
|
|
<Image
|
|
alt="Source token icon"
|
|
src={settings?.resolveImgSrc(sourceToken) || ""}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md mr-0.5"
|
|
/>
|
|
{input_transaction?.amount} {swap?.source_asset}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 ">
|
|
<div className="text-base font-normal ">Source</div>
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Source chain icon"
|
|
src={
|
|
settings?.resolveImgSrc(
|
|
sourceExchange ? sourceExchange : sourceLayer
|
|
) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md mr-0.5"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ">
|
|
{sourceExchange
|
|
? sourceExchange?.display_name
|
|
: sourceLayer?.display_name}
|
|
</span>
|
|
</div>
|
|
{swap?.source_exchange && sourceExchange && (
|
|
<div>
|
|
<div className="text-base font-normal ">Via</div>
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Source chain icon"
|
|
src={settings?.resolveImgSrc(sourceLayer) || ""}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md mr-0.5"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ">
|
|
{sourceLayer?.display_name}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col mt-6">
|
|
<div className="text-base font-normal ">From Address</div>
|
|
<div className="text-sm lg:text-base font-medium text-tx-base w-full">
|
|
<div className="flex justify-between items-center hover:">
|
|
<Link
|
|
href={`${sourceLayer?.account_explorer_template?.replace(
|
|
"{0}",
|
|
input_transaction?.from
|
|
)}`}
|
|
target="_blank"
|
|
className="hover:text-gray-300 w-fit contents items-center"
|
|
>
|
|
<span className="break-all link link-underline link-underline-black">
|
|
{input_transaction?.from}
|
|
</span>
|
|
</Link>
|
|
<CopyButton
|
|
toCopy={input_transaction?.from}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="ml-2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col mt-6">
|
|
<div className="text-base font-normal ">Transaction</div>
|
|
<div className="text-sm lg:text-base font-medium text-tx-base w-full">
|
|
<div className="flex items-center justify-between hover:">
|
|
<Link
|
|
href={`${sourceLayer?.transaction_explorer_template.replace(
|
|
"{0}",
|
|
input_transaction?.transaction_hash
|
|
)}`}
|
|
target="_blank"
|
|
className="hover:text-gray-300 w-fit contents items-center second-link"
|
|
>
|
|
<span className="break-all link link-underline link-underline-black">
|
|
{shortenAddress(
|
|
input_transaction?.transaction_hash
|
|
)}
|
|
</span>
|
|
</Link>
|
|
<CopyButton
|
|
toCopy={input_transaction?.transaction_hash}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="ml-2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{input_transaction?.confirmations >=
|
|
input_transaction?.max_confirmations ? null : (
|
|
<div className="flex-1">
|
|
<div className="text-base font-normal ">
|
|
Confirmations
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ml-1">
|
|
{input_transaction?.confirmations >=
|
|
input_transaction?.max_confirmations
|
|
? input_transaction?.max_confirmations
|
|
: input_transaction?.confirmations}
|
|
/{input_transaction?.max_confirmations}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="rotate-90 lg:rotate-0 self-center">
|
|
<ArrowRight className=" w-8 h-auto" />
|
|
</div>
|
|
<div className="w-full p-6 grid gap-y-3 border border-muted-3 border-1 rounded-lg shadow-lg relative">
|
|
{swap.status == SwapStatus.BridgeTransferPending ||
|
|
swap.status == SwapStatus.UserTransferPending ? (
|
|
<span className="pendingAnim"></span>
|
|
) : null}
|
|
<div className="flex items-center border-b border-muted-3 border-1">
|
|
<div className="mr-2 text-2xl font-medium">To</div>
|
|
</div>
|
|
<div className="rounded-md w-full grid shadow-lg relative ">
|
|
<div className="flex justify-around">
|
|
<div className="flex-1">
|
|
<div className="text-base font-normal ">Asset</div>
|
|
<div className="flex items-center">
|
|
{output_transaction?.amount ? (
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Destination token icon"
|
|
src={
|
|
settings?.resolveImgSrc(destinationToken) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ml-0.5">
|
|
{output_transaction?.amount}{" "}
|
|
{swap?.destination_asset}
|
|
</span>
|
|
</div>
|
|
) : (
|
|
<span>-</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex-1">
|
|
<div className="text-base font-normal ">Destination</div>
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Destination chain icon"
|
|
src={
|
|
settings?.resolveImgSrc(
|
|
destinationExchange
|
|
? destinationExchange
|
|
: destinationLayer
|
|
) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md mr-0.5"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ">
|
|
{destinationExchange
|
|
? destinationExchange?.display_name
|
|
: destinationLayer?.display_name}
|
|
</span>
|
|
</div>
|
|
{swap?.destination_exchange && destinationExchange && (
|
|
<div>
|
|
<div className="text-base font-normal ">Via</div>
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Source chain icon"
|
|
src={
|
|
settings?.resolveImgSrc(destinationLayer) || ""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md mr-0.5"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ">
|
|
{destinationLayer?.display_name}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col mt-6">
|
|
<div className="text-base font-normal ">To Address</div>
|
|
<div className="text-sm lg:text-base font-medium text-tx-base w-full">
|
|
{output_transaction?.to ? (
|
|
<div className="flex items-center justify-between hover:">
|
|
<Link
|
|
href={`${destinationLayer?.account_explorer_template?.replace(
|
|
"{0}",
|
|
output_transaction?.to
|
|
)}`}
|
|
target="_blank"
|
|
className="hover:text-gray-300 w-fit contents items-center"
|
|
>
|
|
<span className="break-all link link-underline link-underline-black">
|
|
{output_transaction?.to}
|
|
</span>
|
|
</Link>
|
|
<CopyButton
|
|
toCopy={swap?.destination_address}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="ml-2"
|
|
/>
|
|
</div>
|
|
) : (
|
|
<span className="ml-1">-</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col mt-6">
|
|
<div className="text-base font-normal ">Transaction</div>
|
|
<div className="text-sm lg:text-base font-medium text-tx-base w-full">
|
|
{output_transaction?.transaction_hash ? (
|
|
<div className="flex items-center justify-between hover:">
|
|
<Link
|
|
href={`${destinationLayer?.transaction_explorer_template.replace(
|
|
"{0}",
|
|
output_transaction?.transaction_hash
|
|
)}`}
|
|
target="_blank"
|
|
className="hover:text-gray-300 w-fit contents items-center"
|
|
>
|
|
<span className="break-all link link-underline link-underline-black">
|
|
{shortenAddress(
|
|
output_transaction?.transaction_hash
|
|
)}
|
|
</span>
|
|
</Link>
|
|
<CopyButton
|
|
toCopy={output_transaction?.transaction_hash}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="ml-2"
|
|
/>
|
|
</div>
|
|
) : (
|
|
<span>-</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{swap?.refuel && (
|
|
<>
|
|
<div className="flex items-center ">
|
|
<div className="mr-2 text-2xl font-medium">
|
|
... and for gas
|
|
</div>
|
|
</div>
|
|
<div className="rounded-md w-full grid gap-y-3 bg-level-1 shadow-lg relative border-level-2 border">
|
|
<div className="flex justify-around">
|
|
<div className="flex-1 p-4">
|
|
<div className="text-base font-normal ">
|
|
Native Asset
|
|
</div>
|
|
<div className="flex items-center">
|
|
<div className="flex items-center">
|
|
<Image
|
|
alt="Destination token icon"
|
|
src={
|
|
settings?.resolveImgSrc(destinationToken) ||
|
|
""
|
|
}
|
|
width={20}
|
|
height={20}
|
|
decoding="async"
|
|
data-nimg="responsive"
|
|
className="rounded-md"
|
|
/>
|
|
<span className="text-sm lg:text-base font-medium text-socket-table ml-0.5">
|
|
{truncateDecimals(
|
|
refuel_transaction?.amount,
|
|
DestinationNativeToken?.precision
|
|
)}{" "}
|
|
{DestinationNativeToken?.asset}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex-1 p-4 border-level-2 border-l">
|
|
<div className="text-base font-normal ">
|
|
Transaction
|
|
</div>
|
|
{refuel_transaction?.transaction_hash ? (
|
|
<div className="flex items-center justify-between hover:">
|
|
<Link
|
|
href={`${refuel_transaction?.explorer_url}`}
|
|
target="_blank"
|
|
className="hover:text-gray-300 w-fit contents items-center"
|
|
>
|
|
<span className="break-all link link-underline link-underline-black">
|
|
{shortenHash(
|
|
refuel_transaction?.transaction_hash
|
|
)}
|
|
</span>
|
|
</Link>
|
|
<CopyButton
|
|
toCopy={refuel_transaction?.transaction_hash}
|
|
iconHeight={16}
|
|
iconClassName="order-2"
|
|
iconWidth={16}
|
|
className="ml-2"
|
|
/>
|
|
</div>
|
|
) : (
|
|
<span>-</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function truncateDecimals(
|
|
value: number | undefined,
|
|
decimals: number | undefined
|
|
) {
|
|
return Number(value?.toFixed(decimals));
|
|
}
|