| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /**
- * Explorer data source: live indexer when up, else mock.
- */
- import {
- MOCK_BLOCKS,
- MOCK_TRANSACTIONS,
- getBlock as mockGetBlock,
- getTransaction as mockGetTx,
- } from "@/lib/explorer-mock";
- import type { MockBlock, MockTransaction } from "@/lib/explorer-types";
- const INDEXER =
- process.env.NEXT_PUBLIC_INDEXER_URL?.trim() || "http://127.0.0.1:4091";
- export type ExplorerSource = "live" | "mock";
- async function tryFetch<T>(path: string): Promise<T | null> {
- try {
- const res = await fetch(`${INDEXER}${path}`, {
- next: { revalidate: 0 },
- signal: AbortSignal.timeout(1500),
- });
- if (!res.ok) return null;
- return (await res.json()) as T;
- } catch {
- return null;
- }
- }
- export async function listTransactions(): Promise<{
- source: ExplorerSource;
- items: MockTransaction[];
- }> {
- const data = await tryFetch<{ items: MockTransaction[] }>("/v1/transactions");
- if (data?.items?.length) return { source: "live", items: data.items };
- return { source: "mock", items: [...MOCK_TRANSACTIONS] };
- }
- export async function listBlocks(): Promise<{
- source: ExplorerSource;
- items: MockBlock[];
- }> {
- const data = await tryFetch<{ items: MockBlock[] }>("/v1/blocks");
- if (data?.items?.length) return { source: "live", items: data.items };
- return { source: "mock", items: [...MOCK_BLOCKS] };
- }
- export async function fetchTransaction(
- hash: string,
- ): Promise<{ source: ExplorerSource; tx: MockTransaction | null }> {
- const live = await tryFetch<MockTransaction>(
- `/v1/transactions/${encodeURIComponent(hash)}`,
- );
- if (live && "hash" in live) return { source: "live", tx: live };
- return { source: "mock", tx: mockGetTx(hash) ?? null };
- }
- export async function fetchBlock(
- key: string,
- ): Promise<{ source: ExplorerSource; block: MockBlock | null }> {
- const live = await tryFetch<MockBlock>(
- `/v1/blocks/${encodeURIComponent(key)}`,
- );
- if (live && "height" in live) return { source: "live", block: live };
- return { source: "mock", block: mockGetBlock(key) ?? null };
- }
- export async function indexerHealth(): Promise<boolean> {
- const h = await tryFetch<{ ok?: boolean }>("/health");
- return Boolean(h?.ok);
- }
- export type HybridHealth = {
- ok?: boolean;
- mode?: string;
- privateLayer?: { ok?: boolean; chainId?: number; blockNumber?: number };
- publicLayer?: { ok?: boolean; chainId?: number; blockNumber?: number };
- sim?: { pendingAnchors?: number; postedAnchors?: number };
- };
- export async function fetchIndexerHybrid(): Promise<HybridHealth | null> {
- return tryFetch<HybridHealth>("/v1/hybrid");
- }
|