Skip to content

Commit

Permalink
fix build error
Browse files Browse the repository at this point in the history
  • Loading branch information
0xrinegade committed Dec 26, 2024
1 parent b1bb734 commit 7d4e392
Show file tree
Hide file tree
Showing 23 changed files with 1,472 additions and 312 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"editor.lightbulb.enabled": "onCode",
"editor.experimental.treeSitterTelemetry": false,
"editor.experimentalInlineEdit.enabled": true
}
12 changes: 7 additions & 5 deletions app/account/[address]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import type { TransactionInfo } from '@/lib/solana';

interface AccountInfo {
address: string;
balance: number;
executable: boolean;
lamports: number;
owner: string;
executable: boolean;
rentEpoch: number;
data: Buffer;
}

export default function AccountPage() {
Expand Down Expand Up @@ -88,7 +90,7 @@ export default function AccountPage() {
<div className="grid grid-cols-2 gap-4">
<div>
<Text variant="label" className="text-sm text-gray-500">Balance</Text>
<Text variant="default">{accountInfo.balance.toFixed(9)} SOL</Text>
<Text variant="default">{(accountInfo.lamports / 1e9).toFixed(9)} SOL</Text>
</div>

<div>
Expand Down Expand Up @@ -117,8 +119,8 @@ export default function AccountPage() {
<Text variant="default" className="font-mono text-sm">{tx.signature}</Text>
</div>
<div className="text-right">
<Text variant="label" className="text-xs text-gray-500">Amount</Text>
<Text variant="default">{tx.amount.toFixed(9)} SOL</Text>
<Text variant="label" className="text-xs text-gray-500">Fee</Text>
<Text variant="default">{tx.fee.toFixed(9)} SOL</Text>
</div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/address/[address]/opengraph-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default async function Image({ params }: { params: { address: string } })

const title = 'Account Overview';
const description = account
? `Balance: ${account.balance.toFixed(4)} SOL`
? `Balance: ${(account.lamports / 1e9).toFixed(4)} SOL`
: 'Solana Account Explorer';

return new ImageResponse(
Expand Down
44 changes: 44 additions & 0 deletions app/api/block/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { NextRequest, NextResponse } from 'next/server';
import { connection } from '@/lib/solana';

export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams;
const slot = searchParams.get('slot');

if (!slot) {
return NextResponse.json(
{ error: 'Slot parameter is required' },
{ status: 400 }
);
}

try {
const slotNumber = parseInt(slot);
if (isNaN(slotNumber)) {
return NextResponse.json(
{ error: 'Invalid slot number' },
{ status: 400 }
);
}

const [block, blockTime] = await Promise.all([
connection.getBlock(slotNumber, { maxSupportedTransactionVersion: 0 }),
connection.getBlockTime(slotNumber),
]);

if (!block) {
return NextResponse.json(
{ error: 'Block not found' },
{ status: 404 }
);
}

return NextResponse.json({ block, blockTime });
} catch (error) {
console.error('Error fetching block:', error);
return NextResponse.json(
{ error: 'Failed to fetch block data' },
{ status: 500 }
);
}
}
42 changes: 42 additions & 0 deletions app/api/blocks/[slot]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { NextResponse } from 'next/server';
import { connection } from '@/lib/solana';

export async function GET(request: Request) {
try {
const slot = request.url.split('/').pop();
if (!slot) {
return NextResponse.json(
{ error: 'Slot parameter is required' },
{ status: 400 }
);
}

const slotNumber = parseInt(slot);
if (isNaN(slotNumber)) {
return NextResponse.json(
{ error: 'Invalid slot number' },
{ status: 400 }
);
}

const [block, blockTime] = await Promise.all([
connection.getBlock(slotNumber, { maxSupportedTransactionVersion: 0 }),
connection.getBlockTime(slotNumber),
]);

if (!block) {
return NextResponse.json(
{ error: 'Block not found' },
{ status: 404 }
);
}

return NextResponse.json({ block, blockTime });
} catch (error) {
console.error('Error fetching block data:', error);
return NextResponse.json(
{ error: 'Failed to fetch block data' },
{ status: 500 }
);
}
}
12 changes: 12 additions & 0 deletions app/block/[slot]/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Metadata } from 'next';

export async function generateMetadata({
params,
}: {
params: { slot: string };
}): Promise<Metadata> {
return {
title: `Block #${params.slot} | OPENSVM`,
description: `View details of Solana block #${params.slot} on OPENSVM`,
};
}
170 changes: 170 additions & 0 deletions app/block/[slot]/opengraph-image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { ImageResponse } from 'next/og';
import { connection } from '@/lib/solana';
import { formatNumber } from '@/lib/utils';

export const runtime = 'edge';
export const alt = 'Block Details';
export const size = {
width: 1200,
height: 630,
};
export const contentType = 'image/png';

export default async function Image({ params }: { params: { slot: string } }) {
try {
const slotNumber = parseInt(params.slot);
const [block, blockTime] = await Promise.all([
connection.getBlock(slotNumber, { maxSupportedTransactionVersion: 0 }),
connection.getBlockTime(slotNumber),
]);

if (!block) {
throw new Error('Block not found');
}

const totalRewards = block.rewards.reduce((acc, r) => acc + r.lamports, 0) / 1e9;

return new ImageResponse(
(
<div
style={{
height: '100%',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#000',
backgroundImage: 'linear-gradient(45deg, #000 0%, #111 100%)',
}}
>
{/* Logo */}
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
marginBottom: '20px',
}}
>
<div
style={{
width: '80px',
height: '80px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
background: 'linear-gradient(135deg, #00ffbd 0%, #00b386 100%)',
marginRight: '16px',
}}
>
<div
style={{
color: 'white',
fontSize: '40px',
fontWeight: 700,
}}
>
S
</div>
</div>
<div
style={{
fontSize: '48px',
fontWeight: 700,
background: 'linear-gradient(135deg, #00ffbd 0%, #00b386 100%)',
backgroundClip: 'text',
color: 'transparent',
}}
>
OPENSVM
</div>
</div>

{/* Content */}
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
marginTop: '20px',
padding: '0 48px',
}}
>
<div
style={{
fontSize: '32px',
fontWeight: 600,
color: 'white',
marginBottom: '10px',
textAlign: 'center',
}}
>
Block #{formatNumber(slotNumber)}
</div>
<div
style={{
fontSize: '24px',
color: '#00ffbd',
marginBottom: '20px',
textAlign: 'center',
}}
>
{blockTime ? new Date(blockTime * 1000).toLocaleString() : 'Unknown time'}
</div>
<div
style={{
fontSize: '20px',
color: '#888',
textAlign: 'center',
maxWidth: '600px',
}}
>
{formatNumber(block.transactions.length)} Transactions • {formatNumber(totalRewards)} SOL in Rewards
</div>
<div
style={{
fontSize: '16px',
color: '#666',
marginTop: '20px',
textAlign: 'center',
}}
>
Parent Slot: {formatNumber(block.parentSlot)}
</div>
</div>

{/* Footer */}
<div
style={{
position: 'absolute',
bottom: '32px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div
style={{
fontSize: '16px',
color: '#666',
}}
>
opensvm.com
</div>
</div>
</div>
),
{
width: 1200,
height: 630,
},
);
} catch (e: any) {
console.log(`${e.message}`);
return new Response(`Failed to generate the image`, {
status: 500,
});
}
}
23 changes: 23 additions & 0 deletions app/block/[slot]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Metadata } from 'next';
import BlockDetails from '@/components/BlockDetails';

interface PageProps {
params: Promise<{ slot: string }>;
}

export async function generateMetadata({
params,
}: PageProps): Promise<Metadata> {
const resolvedParams = await params;
return {
title: `Block #${resolvedParams.slot} | OPENSVM`,
description: `View details of Solana block #${resolvedParams.slot} on OPENSVM`,
};
}

export default async function BlockPage({
params,
}: PageProps) {
const resolvedParams = await params;
return <BlockDetails slot={resolvedParams.slot} />;
}
18 changes: 18 additions & 0 deletions app/block/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Block Details | OPENSVM',
description: 'View Solana block details on OPENSVM',
};

export default function BlockLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="min-h-screen bg-background">
{children}
</div>
);
}
Loading

0 comments on commit 7d4e392

Please sign in to comment.