import type { Plugin, PluginAPI } from "@lumeweb/interface-relay"; import { ConsensusCommitteeHashesRequest, ConsensusCommitteePeriodRequest, createDefaultClient, getConsensusOptimisticUpdate, } from "@lumeweb/libethsync/node"; import { RPCRequestRaw } from "@lumeweb/libethsync/client"; import axios from "axios"; const EXECUTION_RPC_URL = "https://solemn-small-frost.discover.quiknode.pro/dbbe3dc75a8b828611df3f12722de5cc88214947/"; const CONSENSUS_RPC_URL = "https://www.lightclientdata.org"; interface ExecutionRequest { method: string; params: any[]; } const executionClient = axios.create({ baseURL: EXECUTION_RPC_URL }); const plugin: Plugin = { name: "eth", async plugin(api: PluginAPI): Promise { const client = createDefaultClient(CONSENSUS_RPC_URL); await client.sync(); api.registerMethod("consensus_committee_hashes", { cacheable: false, async handler( request: ConsensusCommitteeHashesRequest, ): Promise { if (!(request?.start && typeof request.start === "number")) { throw new Error('start required and must be a number"'); } if (!(request?.count && typeof request.count === "number")) { throw new Error('count required and must be a number"'); } let hashes: Uint8Array = new Uint8Array(); for (let i = 0; i < 4; i++) { try { hashes = client.store.getCommitteeHashes( request.start, request.count, ); } catch (e) { if (i === 3) { return e; } await client.sync(); } } return hashes; }, }); api.registerMethod("consensus_committee_period", { cacheable: false, async handler( request: ConsensusCommitteePeriodRequest, ): Promise { if ( !( request?.period && (typeof request.period == "number" || request.period === "latest") ) ) { throw new Error('period required and must be a number or "latest"'); } if (!client.isSynced) { await client.sync(); } let committee; for (let i = 0; i < 4; i++) { try { committee = client.store.getCommittee( request.period === "latest" ? client.latestPeriod : request.period, ); } catch (e) { if (i === 3) { return e; } await client.sync(); } } try { committee = client.store.getCommittee( request.period === "latest" ? client.latestPeriod : request.period, ); } catch { await client.sync(); } return committee; }, }); api.registerMethod("execution_request", { cacheable: false, async handler(request: RPCRequestRaw): Promise { const ret = (await executionClient.post("/", request)).data; return { ...ret, id: request.id ?? ret.id }; }, }); api.registerMethod("consensus_optimistic_update", { cacheable: false, async handler(): Promise { return getConsensusOptimisticUpdate(); }, }); }, }; export default plugin;