Skip to content

Commit 328bb6a

Browse files
committed
updates
1 parent 40d42b2 commit 328bb6a

6 files changed

Lines changed: 381 additions & 24 deletions

File tree

.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
NEXT_PUBLIC_DEFAULT_RPC_URL=
2+
NEXT_PRIVATE_RPC_URL=
3+
FUNDING_PRIVATE_KEY=
4+
NEXT_PUBLIC_EXPLORER_URL=
5+
NEXT_PUBLIC_REGISTRY_RPC_URL=

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ yarn-error.log*
3131
.pnpm-debug.log*
3232

3333
# env files (can opt-in for committing if needed)
34-
.env*
34+
.env
3535

3636
# vercel
3737
.vercel

src/app/api/registry/route.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { registryStore } from '@/lib/registryStore';
2+
import { NextResponse } from 'next/server';
3+
4+
export async function GET() {
5+
console.log("Serving registry data");
6+
const data = registryStore.getData();
7+
return NextResponse.json(data);
8+
}

src/app/page.tsx

Lines changed: 169 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import { useState, useEffect, useCallback, useRef } from "react";
44
import { JsonRpcProvider, Wallet, parseUnits, formatEther } from "ethers";
55
import { HDNodeWallet } from "ethers";
66
import { TransactionRequest } from "ethers";
7+
import { FutureGateway, Gateway } from "@/types";
78

89
type TxInfo = {
910
hash: string;
1011
sendTimeMs: number;
1112
blockNumber?: number;
12-
txIndex?: number;
1313
latencyMs?: number;
1414
};
1515

@@ -61,9 +61,11 @@ export default function Home() {
6161
const [pingLatency, setPingLatency] = useState<number>(0);
6262
const [autoSend, setAutoSend] = useState(false);
6363
const isPolling = useRef(false);
64+
const [gateways, setGateways] = useState<Gateway[]>([]);
65+
const [futureGateways, setFutureGateways] = useState<FutureGateway[]>([]);
6466

6567
const ethValue = parseUnits("1", "gwei");
66-
const gasPrice = parseUnits("0.01", "gwei");
68+
const gasPrice = parseUnits("0.1", "gwei");
6769

6870
// Initialize provider and chain ID on mount
6971
useEffect(() => {
@@ -92,15 +94,25 @@ export default function Home() {
9294
updated.set(nonce, {
9395
...info,
9496
blockNumber: rcpt.blockNumber,
95-
txIndex: rcpt.index,
9697
latencyMs: Date.now() - info.sendTimeMs,
9798
});
9899
} else {
99100
stillPending.set(nonce, info);
100101
}
101102
}
102103

103-
setConfirmedTxs((prev) => new Map([...prev, ...updated]));
104+
setConfirmedTxs((prev) => {
105+
// Combine previous and new transactions
106+
const allTxs = new Map([...prev, ...updated]);
107+
108+
// Sort by nonce (descending) and take only the first 100
109+
const sortedEntries = Array.from(allTxs.entries())
110+
.sort(([nonceA], [nonceB]) => nonceB - nonceA)
111+
.slice(0, 100);
112+
113+
// Create new Map with only the latest 100 transactions
114+
return new Map(sortedEntries);
115+
});
104116

105117
setPendingTxs((prev) => {
106118
const next = new Map(prev);
@@ -162,7 +174,7 @@ export default function Home() {
162174
};
163175

164176
updateBlockNumber();
165-
const interval = setInterval(updateBlockNumber, 1500);
177+
const interval = setInterval(updateBlockNumber, 1000);
166178
return () => clearInterval(interval);
167179
}, [provider]);
168180

@@ -256,6 +268,24 @@ export default function Home() {
256268
return () => clearInterval(interval);
257269
}, [autoSend, wallet, handleSend]); // Added handleSend to dependencies
258270

271+
useEffect(() => {
272+
const fetchGateways = async () => {
273+
try {
274+
const response = await fetch("/api/registry");
275+
const data = await response.json();
276+
277+
setGateways(data.gateways);
278+
setFutureGateways(data.futureGateways);
279+
} catch (error) {
280+
console.error("Failed to fetch gateways:", error);
281+
}
282+
};
283+
284+
fetchGateways();
285+
const interval = setInterval(fetchGateways, 5000);
286+
return () => clearInterval(interval);
287+
}, []);
288+
259289
return (
260290
<div className="min-h-screen bg-[#0A0A0C] p-8 font-sans text-gray-100 flex flex-col">
261291
<div className="max-w-6xl mx-auto flex-grow w-full">
@@ -281,6 +311,94 @@ export default function Home() {
281311
</form>
282312
</div>
283313

314+
<div className="bg-[#161618] rounded-xl overflow-hidden border border-[#2A2A2E] mb-6">
315+
<table className="w-full">
316+
<thead className="bg-[#1A1A1C] border-b border-[#2A2A2E]">
317+
<tr>
318+
<th className="text-left p-4 text-sm text-gray-400 font-medium">
319+
Gateway
320+
</th>
321+
<th className="text-left p-4 text-sm text-gray-400 font-medium">
322+
Address
323+
</th>
324+
<th className="text-left p-4 text-sm text-gray-400 font-medium">
325+
Role
326+
</th>
327+
<th className="text-left p-4 text-sm text-gray-400 font-medium">
328+
Ping (sequencer)
329+
</th>
330+
</tr>
331+
</thead>
332+
<tbody>
333+
{(() => {
334+
const currentUrl = futureGateways.find(
335+
(gw) => gw.blockNumber === currentBlock
336+
)?.url;
337+
338+
const nextUrl = futureGateways.find(
339+
(gw) => gw.blockNumber > currentBlock && gw.url !== currentUrl
340+
)?.url;
341+
342+
const blocksLeft = futureGateways.filter(
343+
(gw) =>
344+
gw.url === currentUrl && gw.blockNumber >= currentBlock
345+
).length;
346+
347+
return gateways.map((gateway, i) => {
348+
const isCurrent = currentUrl === gateway.url;
349+
const isNext = nextUrl === gateway.url;
350+
351+
return (
352+
<tr
353+
key={i}
354+
className={`border-b border-[#2A2A2E] ${
355+
isCurrent ? "bg-[#2A2A2E]" : ""
356+
}`}
357+
>
358+
<td className="p-4">
359+
<p className="font-mono text-[#00FFB2]">
360+
{gateway.url}
361+
</p>
362+
</td>
363+
<td className="p-4">
364+
<p className="font-mono text-[#00FFB2]">
365+
{gateway.address}
366+
</p>
367+
</td>
368+
<td className="p-4">
369+
{isCurrent && (
370+
<span className="px-3 py-1.5 rounded-lg text-sm bg-[#00FFB2] text-[#0A0A0C] whitespace-nowrap">
371+
Leader ({blocksLeft} blocks)
372+
</span>
373+
)}
374+
{isNext && (
375+
<span className="px-3 py-1.5 rounded-lg text-xs font-medium bg-[#2A2A2E] text-[#7F5FFF] border border-[#7F5FFF]">
376+
Next
377+
</span>
378+
)}
379+
{!isCurrent && !isNext && (
380+
<span className="text-gray-400">Standby</span>
381+
)}
382+
</td>
383+
<td className="p-4">
384+
<span
385+
className={
386+
gateway.ping
387+
? "font-mono text-[#00FFB2]"
388+
: "text-gray-400"
389+
}
390+
>
391+
{gateway.ping ? `${gateway.ping}ms` : "-"}
392+
</span>
393+
</td>
394+
</tr>
395+
);
396+
});
397+
})()}
398+
</tbody>
399+
</table>
400+
</div>
401+
284402
{!wallet ? (
285403
<div className="flex justify-center items-center min-h-[200px]">
286404
<button
@@ -304,30 +422,53 @@ export default function Home() {
304422
<p className="text-gray-300">
305423
Balance:{" "}
306424
<span className="font-mono text-[#00FFB2]">
307-
{formatEther(balance)} ETH
425+
{balance === BigInt(0)
426+
? "Waiting for airdrop..."
427+
: `${formatEther(balance)} ETH`}
308428
</span>
309429
</p>
310430
</div>
311431

312432
<div className="flex flex-col gap-2 items-end">
313433
<button
314434
onClick={handleSend}
315-
className="bg-[#2A2A2E] hover:bg-[#3A3A3E] text-[#00FFB2] px-6 py-2 rounded-lg transition-colors duration-200 border border-[#00FFB2]"
435+
disabled={balance === BigInt(0)}
436+
className={`px-6 py-2 rounded-lg transition-colors duration-200 border ${
437+
balance === BigInt(0)
438+
? "bg-[#1A1A1C] text-gray-500 border-gray-500 cursor-not-allowed"
439+
: "bg-[#2A2A2E] hover:bg-[#3A3A3E] text-[#00FFB2] border-[#00FFB2]"
440+
}`}
316441
>
317442
Send TX
318443
</button>
319444
<div className="flex items-center gap-2">
320-
<label className="text-sm text-gray-300">Auto Send</label>
445+
<label
446+
className={`text-sm ${
447+
balance === BigInt(0)
448+
? "text-gray-500"
449+
: "text-gray-300"
450+
}`}
451+
>
452+
Auto Send
453+
</label>
321454
<button
322-
onClick={() => setAutoSend(!autoSend)}
455+
onClick={() =>
456+
balance > BigInt(0) && setAutoSend(!autoSend)
457+
}
323458
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors duration-200 ${
324-
autoSend ? "bg-[#00FFB2]" : "bg-[#2A2A2E]"
459+
balance === BigInt(0)
460+
? "bg-[#1A1A1C] cursor-not-allowed"
461+
: autoSend
462+
? "bg-[#00FFB2]"
463+
: "bg-[#2A2A2E]"
325464
}`}
326465
>
327466
<span
328-
className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform duration-200 ${
329-
autoSend ? "translate-x-6" : "translate-x-1"
330-
}`}
467+
className={`inline-block h-4 w-4 transform rounded-full transition-transform duration-200 ${
468+
autoSend
469+
? "translate-x-6 bg-white"
470+
: "translate-x-1 bg-gray-400"
471+
} ${balance === BigInt(0) ? "bg-gray-600" : ""}`}
331472
/>
332473
</button>
333474
</div>
@@ -350,7 +491,7 @@ export default function Home() {
350491
</p>
351492
</div>
352493
<div className="space-y-1">
353-
<p className="text-sm text-gray-400">Ping Latency</p>
494+
<p className="text-sm text-gray-400">Ping Latency (RPC)</p>
354495
<p className="text-2xl font-mono text-[#00FFB2]">
355496
{pingLatency}ms
356497
</p>
@@ -403,19 +544,21 @@ export default function Home() {
403544
Status
404545
</th>
405546
<th className="px-4 py-2 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">
406-
Block#
547+
Block #
407548
</th>
408549
<th className="px-4 py-2 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">
409-
Txn Idx
550+
Latency
410551
</th>
411-
<th className="px-4 py-2 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">
412-
Latency (ms)
552+
{/* <th className="px-4 py-2 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">
553+
Gateway
413554
</th>
555+
<th className="px-4 py-2 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">
556+
Network
557+
</th> */}
414558
</tr>
415559
</thead>
416560
<tbody className="divide-y divide-[#2A2A2E]">
417561
{[...confirmedTxs.entries(), ...pendingTxs.entries()]
418-
// sort ascending by nonce; for descending swap a and b
419562
.sort(([nonceA], [nonceB]) => nonceB - nonceA)
420563
.slice(0, 50)
421564
.map(([nonce, info]) => (
@@ -433,7 +576,7 @@ export default function Home() {
433576
rel="noopener noreferrer"
434577
className="hover:text-[#00FFB2] hover:underline"
435578
>
436-
{info.hash}
579+
{info.hash.slice(0, 10)}...
437580
</a>
438581
</td>
439582
<td className="px-4 py-2 text-sm">
@@ -451,11 +594,14 @@ export default function Home() {
451594
{info.blockNumber ?? "-"}
452595
</td>
453596
<td className="px-4 py-2 font-mono text-sm text-gray-300">
454-
{info.txIndex ?? "-"}
597+
{info.latencyMs ? info.latencyMs + "ms" : "-"}
455598
</td>
456-
<td className="px-4 py-2 font-mono text-sm text-gray-300">
457-
{info.latencyMs ?? "-"}
599+
{/* <td className="px-4 py-2 font-mono text-sm text-gray-300">
600+
-
458601
</td>
602+
<td className="px-4 py-2 font-mono text-sm text-gray-300">
603+
-
604+
</td> */}
459605
</tr>
460606
))}
461607
</tbody>

0 commit comments

Comments
 (0)