83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
|
|
/**
|
||
|
|
* SolaceScan Explorer (Blockscout v2) client for Chain 138.
|
||
|
|
*
|
||
|
|
* Base URL: https://api.explorer.d-bis.org (CORS *)
|
||
|
|
* Fallback: https://explorer.d-bis.org/api/v2 (same data, different host)
|
||
|
|
*
|
||
|
|
* We hit the `api.*` subdomain by default because it returns clean JSON
|
||
|
|
* without the Next.js HTML wrapper.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { httpJson } from './http';
|
||
|
|
import { endpoints } from '../config/endpoints';
|
||
|
|
|
||
|
|
const api = (path: string) => `${endpoints.explorer.apiBaseUrl}/api/v2${path}`;
|
||
|
|
|
||
|
|
export interface ExplorerStats {
|
||
|
|
total_blocks: number;
|
||
|
|
total_transactions: number;
|
||
|
|
total_addresses: number;
|
||
|
|
latest_block: number;
|
||
|
|
average_block_time: number;
|
||
|
|
gas_prices: { average: number; fast?: number; slow?: number };
|
||
|
|
network_utilization_percentage: number;
|
||
|
|
transactions_today: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getExplorerStats(): Promise<ExplorerStats> {
|
||
|
|
return httpJson<ExplorerStats>(api('/stats'));
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ExplorerBlock {
|
||
|
|
height: number;
|
||
|
|
hash: string;
|
||
|
|
timestamp: string;
|
||
|
|
tx_count: number;
|
||
|
|
gas_used: string;
|
||
|
|
gas_limit: string;
|
||
|
|
size: number;
|
||
|
|
miner: { hash: string };
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getLatestBlocks(): Promise<ExplorerBlock[]> {
|
||
|
|
return httpJson<ExplorerBlock[]>(api('/main-page/blocks'));
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ExplorerTx {
|
||
|
|
hash: string;
|
||
|
|
block_number: number;
|
||
|
|
timestamp: string;
|
||
|
|
from: { hash: string };
|
||
|
|
to: { hash: string } | null;
|
||
|
|
value: string; // wei
|
||
|
|
gas_used: string;
|
||
|
|
gas_price: string;
|
||
|
|
status: 'ok' | 'error' | null;
|
||
|
|
method: string | null;
|
||
|
|
fee: { value: string };
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PagedTxResponse { items: ExplorerTx[]; next_page_params?: unknown }
|
||
|
|
|
||
|
|
export async function getLatestTransactions(limit = 20): Promise<ExplorerTx[]> {
|
||
|
|
const data = await httpJson<PagedTxResponse>(api('/transactions'));
|
||
|
|
return (data.items ?? []).slice(0, limit);
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function getAddressTransactions(address: string, limit = 20): Promise<ExplorerTx[]> {
|
||
|
|
const data = await httpJson<PagedTxResponse>(api(`/addresses/${address}/transactions`));
|
||
|
|
return (data.items ?? []).slice(0, limit);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function explorerTxUrl(hash: string): string {
|
||
|
|
return `${endpoints.explorer.baseUrl}/tx/${hash}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function explorerAddressUrl(address: string): string {
|
||
|
|
return `${endpoints.explorer.baseUrl}/address/${address}`;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function explorerBlockUrl(height: number): string {
|
||
|
|
return `${endpoints.explorer.baseUrl}/block/${height}`;
|
||
|
|
}
|