Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { SingleNetworkSelector } from "@/components/blocks/NetworkSelectors";
import { PaginationButtons } from "@/components/blocks/pagination-buttons";
import { WalletAddress } from "@/components/blocks/wallet-address";
import { Button } from "@/components/ui/button";
import { CopyTextButton } from "@/components/ui/CopyTextButton";
import { Skeleton } from "@/components/ui/skeleton";
import {
Table,
Expand Down Expand Up @@ -111,23 +110,43 @@ export function DedicatedRelayerActiveState(
/>
</div>

{/* Executors Info */}
<div className="rounded-lg border bg-card">
<div className="border-b px-4 py-4 lg:px-6">
<h2 className="font-semibold text-xl tracking-tight">
Fleet Executors
</h2>
{/* Configuration Info */}
<div className="grid gap-6 lg:grid-cols-2">
{/* Executors */}
<div className="rounded-lg border bg-card">
<div className="border-b px-4 py-4 lg:px-6">
<h2 className="font-semibold text-xl tracking-tight">Executors</h2>
</div>
<div className="p-4 lg:p-6">
<div className="flex flex-wrap gap-2">
{fleet.executors.map((address) => (
<div
key={address}
className="flex items-center gap-2 rounded-lg border bg-background px-3 py-2"
>
<WalletAddress address={address} client={client} />
</div>
))}
</div>
</div>
</div>
<div className="p-4 lg:p-6">
<div className="flex flex-wrap gap-2">
{fleet.executors.map((address) => (
<div
key={address}
className="flex items-center gap-2 rounded-lg border bg-background px-3 py-2"
>
<WalletAddress address={address} client={client} />
</div>
))}

{/* Chains */}
<div className="rounded-lg border bg-card">
<div className="border-b px-4 py-4 lg:px-6">
<h2 className="font-semibold text-xl tracking-tight">Chains</h2>
</div>
<div className="p-4 lg:p-6">
<div className="flex flex-wrap gap-2">
{fleet.chainIds.map((chainId) => (
<div
key={chainId}
className="flex items-center gap-2 rounded-lg border bg-background px-3 py-2"
>
<ChainCell chainId={chainId.toString()} client={client} />
</div>
))}
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -295,37 +314,20 @@ function SkeletonRow() {
}

function TransactionHashCell(props: { hash: string; chainId: string }) {
const { idToChain } = useAllChainsData();
const chain = idToChain.get(Number(props.chainId));

const explorerUrl = chain?.explorers?.[0]?.url;
const txHashToShow = `${props.hash.slice(0, 6)}...${props.hash.slice(-4)}`;

if (explorerUrl) {
return (
<Button asChild size="sm" variant="ghost">
<Link
className="-translate-x-2 gap-2 font-mono"
href={`${explorerUrl}/tx/${props.hash}`}
rel="noopener noreferrer"
target="_blank"
>
{txHashToShow}
<ExternalLinkIcon className="size-3.5 text-muted-foreground" />
</Link>
</Button>
);
}

return (
<CopyTextButton
className="-translate-x-2 font-mono"
copyIconPosition="right"
textToCopy={props.hash}
textToShow={txHashToShow}
tooltip="Transaction Hash"
variant="ghost"
/>
<Button asChild size="sm" variant="ghost">
<Link
className="-translate-x-2 gap-2 font-mono"
href={`https://thirdweb.com/${props.chainId}/tx/${props.hash}`}
rel="noopener noreferrer"
target="_blank"
>
{txHashToShow}
<ExternalLinkIcon className="size-3.5 text-muted-foreground" />
</Link>
</Button>
);
}

Expand Down Expand Up @@ -362,7 +364,7 @@ function TransactionFeeCell(props: { usdValue: number | null }) {
}
return (
<span className="font-mono text-sm">
${props.usdValue < 0.01 ? "<0.01" : props.usdValue.toFixed(2)}
{props.usdValue < 0.001 ? "< $0.001" : `$${props.usdValue.toFixed(3)}`}
</span>
);
}
Expand All @@ -379,7 +381,7 @@ function ChainFilter(props: {
client={props.client}
chainId={props.chainId}
onChange={(chainId) => props.setChainId(chainId)}
popoverContentClassName="z-[10001]"
popoverContentClassName="z-[10001] !w-[280px]"
align="end"
placeholder="All Chains"
className="min-w-[150px]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export function DedicatedRelayerEmptyState(
}
};

const requiredChains =
selectedTier === "product:dedicated_relayer_standard" ? 2 : 4;
const maxChains =
selectedTier === "product:dedicated_relayer_standard" ? 1 : 2;

return (
<div className={cn("flex flex-col gap-8 pt-2", props.className)}>
Expand All @@ -90,7 +90,7 @@ export function DedicatedRelayerEmptyState(
</DialogHeader>
<div className="flex flex-col gap-4">
<p className="text-muted-foreground text-sm">
Select {requiredChains} chains for your dedicated relayer.
Select up to {maxChains} chains for your dedicated relayer.
</p>
<MultiNetworkSelector
selectedChainIds={selectedChainIds}
Expand All @@ -102,7 +102,11 @@ export function DedicatedRelayerEmptyState(
<DialogFooter>
<Button
onClick={handlePurchase}
disabled={selectedChainIds.length !== requiredChains || isLoading}
disabled={
selectedChainIds.length === 0 ||
selectedChainIds.length > maxChains ||
isLoading
}
>
{isLoading ? "Processing..." : "Continue"}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export function DedicatedRelayerPageClient(
refetchInterval: 5000,
});

const isCheckingActivity = hasActivityQuery.isPending;
const totalTransactions = hasActivityQuery.data?.data.totalTransactions ?? 0;
const hasTransactions = totalTransactions > 0;

Expand Down Expand Up @@ -117,23 +118,28 @@ export function DedicatedRelayerPageClient(
<DedicatedRelayerPendingState fleet={fleet} />
)}

{fleetStatus === "active" && fleet && !hasTransactions && (
<DedicatedRelayerPendingState
fleet={fleet}
hasTransactions={hasTransactions}
/>
)}

{fleetStatus === "active" && fleet && hasTransactions && (
<DedicatedRelayerActiveState
fleet={fleet}
teamId={props.teamId}
fleetId={props.fleetId}
client={props.client}
range={dateRange}
setRange={setDateRange}
/>
)}
{fleetStatus === "active" &&
fleet &&
!hasTransactions &&
!isCheckingActivity && (
<DedicatedRelayerPendingState
fleet={fleet}
hasTransactions={hasTransactions}
/>
)}

{fleetStatus === "active" &&
fleet &&
(hasTransactions || isCheckingActivity) && (
<DedicatedRelayerActiveState
fleet={fleet}
teamId={props.teamId}
fleetId={props.fleetId}
client={props.client}
range={dateRange}
setRange={setDateRange}
/>
)}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ const TIERS: TierConfig[] = [
icon: FolderIcon,
name: "Standard",
description:
"Most suitable for small startups and apps doing less than 10,000 transactions per day",
"Most suitable for startups and applications with moderate transaction volume",
price: "$99",
isPerMonth: true,
features: [
{ icon: WalletProductIcon, label: "Single executor wallet" },
{ icon: BoxesIcon, label: "Support for up to 2 chains" },
{ icon: BoxesIcon, label: "Support for 1 chain" },
],
cta: "Select",
},
Expand All @@ -47,15 +47,15 @@ const TIERS: TierConfig[] = [
icon: FoldersIcon,
name: "Premium",
description:
"Best for large enterprise companies and apps doing 100,000+ transactions per day",
"Best for enterprise companies and applications with high transaction volume",
price: "$299",
isPerMonth: true,
features: [
{
icon: WalletProductIcon,
label: "10 executor wallets (10x throughput)",
},
{ icon: BoxesIcon, label: "Support for up to 4 chains" },
{ icon: BoxesIcon, label: "Support for up to 2 chains" },
],
cta: "Select",
isRecommended: true,
Expand All @@ -65,7 +65,7 @@ const TIERS: TierConfig[] = [
icon: FolderCogIcon,
name: "Custom",
description:
"Contact us for more throughput with custom number of chains and executor wallets",
"Contact us for applications operating at a global scale with custom requirements",
price: "Custom",
features: [
{ icon: WalletProductIcon, label: "Unlimited executor wallets" },
Expand Down
Loading