Skip to content

Commit 9f37e52

Browse files
committed
better address
1 parent c4fd6e5 commit 9f37e52

File tree

6 files changed

+101
-48
lines changed

6 files changed

+101
-48
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"use client";
2+
import { CheckIcon, CopyIcon } from "lucide-react";
3+
import { useMemo } from "react";
4+
import { Button } from "@/components/ui/button";
5+
import {
6+
HoverCard,
7+
HoverCardContent,
8+
HoverCardTrigger,
9+
} from "@/components/ui/hover-card";
10+
import { useClipboard } from "@/hooks/useClipboard";
11+
import { cn } from "@/lib/utils";
12+
13+
export function SolanaAddress(props: {
14+
address: string;
15+
shortenAddress?: boolean;
16+
className?: string;
17+
}) {
18+
const shortenedAddress = useMemo(() => {
19+
return props.shortenAddress !== false
20+
? `${props.address.slice(0, 4)}...${props.address.slice(-4)}`
21+
: props.address;
22+
}, [props.address, props.shortenAddress]);
23+
24+
const lessShortenedAddress = useMemo(() => {
25+
return `${props.address.slice(0, 8)}...${props.address.slice(-8)}`;
26+
}, [props.address]);
27+
28+
const { onCopy, hasCopied } = useClipboard(props.address, 2000);
29+
30+
return (
31+
<HoverCard>
32+
<HoverCardTrigger asChild tabIndex={-1}>
33+
<Button
34+
className={cn(
35+
"flex flex-row items-center gap-2 px-0",
36+
props.className,
37+
)}
38+
onClick={(e) => e.stopPropagation()}
39+
variant="link"
40+
>
41+
<div className="flex size-5 items-center justify-center rounded-full bg-gradient-to-br from-purple-500 to-blue-500" />
42+
<span className="cursor-pointer font-mono text-sm">
43+
{shortenedAddress}
44+
</span>
45+
</Button>
46+
</HoverCardTrigger>
47+
<HoverCardContent
48+
className="w-80 border-border"
49+
onClick={(e) => {
50+
// do not close the hover card when clicking anywhere in the content
51+
e.stopPropagation();
52+
}}
53+
>
54+
<div className="space-y-4">
55+
<div className="flex items-center justify-between">
56+
<h3 className="font-semibold text-lg">Solana Public Key</h3>
57+
<Button
58+
className="flex items-center gap-2"
59+
onClick={onCopy}
60+
size="sm"
61+
variant="outline"
62+
>
63+
{hasCopied ? (
64+
<CheckIcon className="h-4 w-4" />
65+
) : (
66+
<CopyIcon className="h-4 w-4" />
67+
)}
68+
{hasCopied ? "Copied!" : "Copy"}
69+
</Button>
70+
</div>
71+
<p className="break-all rounded bg-muted p-3 text-center font-mono text-xs leading-relaxed">
72+
{lessShortenedAddress}
73+
</p>
74+
<div className="rounded-lg bg-muted/50 p-3">
75+
<p className="text-muted-foreground text-xs leading-relaxed">
76+
Solana public key for blockchain transactions.
77+
</p>
78+
</div>
79+
</div>
80+
</HoverCardContent>
81+
</HoverCard>
82+
);
83+
}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/components/server-wallets-table.client.tsx

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import type { Project } from "@/api/project/projects";
2222
import { FundWalletModal } from "@/components/blocks/fund-wallets-modal";
2323
import { SingleNetworkSelector } from "@/components/blocks/NetworkSelectors";
24+
import { SolanaAddress } from "@/components/blocks/solana-address";
2425
import { WalletAddress } from "@/components/blocks/wallet-address";
2526
import { Badge } from "@/components/ui/badge";
2627
import { Button } from "@/components/ui/button";
@@ -60,7 +61,6 @@ import { updateDefaultProjectWallet } from "../lib/vault.client";
6061
import CreateServerWallet from "../server-wallets/components/create-server-wallet.client";
6162
import type { Wallet as EVMWallet } from "../server-wallets/wallet-table/types";
6263
import { CreateSolanaWallet } from "../solana-wallets/components/create-solana-wallet.client";
63-
import { updateDefaultProjectSolanaWallet } from "../solana-wallets/lib/vault.client";
6464
import type { SolanaWallet } from "../solana-wallets/wallet-table/types";
6565

6666
type WalletChain = "evm" | "solana";
@@ -572,9 +572,7 @@ function SolanaWalletRow({
572572
</TableCell>
573573

574574
<TableCell>
575-
<code className="text-xs font-mono">
576-
{wallet.publicKey.slice(0, 8)}...{wallet.publicKey.slice(-8)}
577-
</code>
575+
<SolanaAddress address={wallet.publicKey} shortenAddress={true} />
578576
</TableCell>
579577

580578
<TableCell>
@@ -716,28 +714,6 @@ function SolanaWalletActions({
716714
teamSlug: string;
717715
client: ThirdwebClient;
718716
}) {
719-
const router = useDashboardRouter();
720-
721-
const setDefaultMutation = useMutation({
722-
mutationFn: async () => {
723-
await updateDefaultProjectSolanaWallet({
724-
project,
725-
publicKey: wallet.publicKey,
726-
});
727-
},
728-
onSuccess: () => {
729-
toast.success("Solana wallet set as default");
730-
router.refresh();
731-
},
732-
onError: (error) => {
733-
toast.error(
734-
error instanceof Error
735-
? error.message
736-
: "Failed to set default Solana wallet",
737-
);
738-
},
739-
});
740-
741717
return (
742718
<DropdownMenu>
743719
<DropdownMenuTrigger asChild>
@@ -756,14 +732,6 @@ function SolanaWalletActions({
756732
Send test transaction
757733
</Link>
758734
</DropdownMenuItem>
759-
<DropdownMenuItem
760-
onClick={() => setDefaultMutation.mutate()}
761-
disabled={setDefaultMutation.isPending}
762-
className="flex items-center gap-2 h-9 rounded-lg"
763-
>
764-
<CheckIcon className="size-4 text-muted-foreground" />
765-
Set as default
766-
</DropdownMenuItem>
767735
</DropdownMenuContent>
768736
</DropdownMenu>
769737
);

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/components/transactions-table.client.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { ThirdwebClient } from "thirdweb";
99
import { engineCloudProxy } from "@/actions/proxies";
1010
import type { Project } from "@/api/project/projects";
1111
import { PaginationButtons } from "@/components/blocks/pagination-buttons";
12+
import { SolanaAddress } from "@/components/blocks/solana-address";
1213
import { WalletAddress } from "@/components/blocks/wallet-address";
1314
import { Badge } from "@/components/ui/badge";
1415
import { Button } from "@/components/ui/button";
@@ -372,10 +373,10 @@ function SolanaTransactionsTable(props: {
372373
<SolanaStatusCell transaction={tx} />
373374
</TableCell>
374375
<TableCell>
375-
<code className="text-xs font-mono">
376-
{tx.signerAddress.slice(0, 6)}...
377-
{tx.signerAddress.slice(-4)}
378-
</code>
376+
<SolanaAddress
377+
address={tx.signerAddress}
378+
shortenAddress={true}
379+
/>
379380
</TableCell>
380381
<TableCell>
381382
<SolanaTxHashCell transaction={tx} />

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/lib/solana-utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
* @returns The Solscan URL for the transaction
66
*/
77
export function getSolscanUrl(signature: string, chainId: string): string {
8-
const network = getSolanaNetworkName(chainId);
8+
const network = chainId.split(":")[1] || "mainnet";
99

1010
// Solscan uses different subdomains for different networks
11-
switch (network) {
11+
switch (network.toLowerCase()) {
1212
case "devnet":
1313
return `https://solscan.io/tx/${signature}?cluster=devnet`;
1414
case "testnet":
@@ -19,9 +19,9 @@ export function getSolscanUrl(signature: string, chainId: string): string {
1919
}
2020

2121
/**
22-
* Get the network name from a Solana chain ID
22+
* Get the display network name from a Solana chain ID (capitalized)
2323
* @param chainId - The chain ID in format "solana:mainnet", "solana:devnet", or "solana:testnet"
24-
* @returns The network name
24+
* @returns The capitalized network name for display (e.g., "Devnet")
2525
*/
2626
export function getSolanaNetworkName(chainId: string): string {
2727
const network = chainId.split(":")[1] || "mainnet";

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/layout.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import { ChevronLeftIcon } from "lucide-react";
22
import Link from "next/link";
33

4-
export default function TransactionLayout({
4+
export default async function TransactionLayout({
55
children,
66
params,
77
}: {
88
children: React.ReactNode;
9-
params: { team_slug: string; project_slug: string };
9+
params: Promise<{ team_slug: string; project_slug: string }>;
1010
}) {
11+
const { team_slug, project_slug } = await params;
12+
1113
return (
1214
<div className="flex flex-col gap-6 p-6">
1315
<div className="flex items-center gap-2">
1416
<Link
1517
className="flex items-center gap-1 text-muted-foreground text-sm hover:text-foreground"
16-
href={`/team/${params.team_slug}/${params.project_slug}/transactions`}
18+
href={`/team/${team_slug}/${project_slug}/transactions`}
1719
>
1820
<ChevronLeftIcon className="size-4" />
1921
Back to Transactions

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/transactions/tx/[id]/solana-transaction-details-ui.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useState } from "react";
1111
import type { ThirdwebClient } from "thirdweb";
1212
import { stringify } from "thirdweb/utils";
1313
import type { Project } from "@/api/project/projects";
14+
import { SolanaAddress } from "@/components/blocks/solana-address";
1415
import { Badge } from "@/components/ui/badge";
1516
import { CopyTextButton } from "@/components/ui/CopyTextButton";
1617
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -149,9 +150,7 @@ export function SolanaTransactionDetailsUI({
149150
value={solanaStatusDetails[status].name}
150151
/>
151152
<InfoRow label="Signer Address">
152-
<code className="text-xs font-mono break-all">
153-
{signerAddress}
154-
</code>
153+
<SolanaAddress address={signerAddress} shortenAddress={false} />
155154
</InfoRow>
156155
{txSignature && (
157156
<InfoRow label="Signature">

0 commit comments

Comments
 (0)