Skip to main content

Lodestar Light Client

Ethereum light clients provide a pathway for users to interact with the Ethereum blockchain in a trust-minimized manner, comparable to the level of trust required when engaging with a third-party provider like Infura or EtherScan. Not that those platforms are bad, but trust in any centralized provider goes against the ethos of blockchain. Light clients are a way that low-power devices, like cell phones, can do self validation of transactions and dApp state.

Unlike full nodes, light clients do not download and store the entire blockchain. Instead, they download only the headers of each block and employ Merkle proofs to verify transactions. This enables a quick synchronization with the network and access the latest information without using significant system resources​. This streamlined approach to accessing Ethereum is crucial, especially in scenarios where full-scale network participation is infeasible or undesired.

The evolution of light clients is emblematic of the broader trajectory of Ethereum towards becoming more accessible and resource-efficient, making blockchain technology more inclusive and adaptable to a wide array of use cases and environments. The Altair hard fork introduced sync committees to allow light-clients to synchronize to the network.

Prerequisites

Discord Eth Consensus Spec v1.4.0 ES Version Node Version Yarn

This package is part of ChainSafe's Lodestar project

Requirements for Running a Light-Client

Access to an beacon node that supports the light client specification is necessary. The client must support the following routes from the consensus API spec:

  • /eth/v1/beacon/light_client/updates
  • /eth/v1/beacon/light_client/optimistic_update
  • /eth/v1/beacon/light_client/finality_update
  • /eth/v1/beacon/light_client/bootstrap/{block_root}
  • /eth/v0/beacon/light_client/committee_root

System requirements are quite low so its possible to run a light client in the browser as part of a website. There are a few examples of this on github that you can use as reference, our prover being one of them.

You can find more information about the light-client protocol in the specification.

Getting started

Light-Client CLI Example

It is possible to start up the light-client as a standalone process.

lodestar lightclient \
--network sepolia \
--beacon-api-url https://lodestar-sepolia.chainsafe.io \
--checkpoint-root "0xccaff4b99986a7b05e06738f1828a32e40799b277fd9f9ff069be55341fe0229"

Light-Client Programmatic Example

For this example we will assume there is a running beacon node at https://lodestar-sepolia.chainsafe.io

If you are running light-client on a server/node environment there is a faster version of bls that can help with performance. It is a peerDependency and needs to be installed separately by the consumer of this package. This was done so that for browser situations there is not a hard requirement for node-only code that will cause bundling errors. On startup, if running in a node environment, and @chainsafe/blst is installed the LightClient will automatically use the faster bls bindings.

npm i -S @chainsafe/blst
import {Lightclient, LightclientEvent} from "@lodestar/light-client";
import {LightClientRestTransport} from "@lodestar/light-client/transport";
import {
getFinalizedSyncCheckpoint,
getGenesisData,
getConsoleLogger,
getApiFromUrl,
getChainForkConfigFromNetwork,
} from "@lodestar/light-client/utils";

const config = getChainForkConfigFromNetwork("sepolia");
const logger = getConsoleLogger({logDebug: Boolean(process.env.DEBUG)});
const api = getApiFromUrl({urls: ["https://lodestar-sepolia.chainsafe.io"]}, {config});

const lightclient = await Lightclient.initializeFromCheckpointRoot({
config,
logger,
transport: new LightClientRestTransport(api),
genesisData: await getGenesisData(api),
checkpointRoot: await getFinalizedSyncCheckpoint(api),
opts: {
allowForcedUpdates: true,
updateHeadersOnForcedUpdate: true,
},
});

// Wait for the lightclient to start
await lightclient.start();

logger.info("Lightclient synced");

lightclient.emitter.on(LightclientEvent.lightClientFinalityHeader, async (finalityUpdate) => {
logger.info(finalityUpdate);
});

lightclient.emitter.on(LightclientEvent.lightClientOptimisticHeader, async (optimisticUpdate) => {
logger.info(optimisticUpdate);
});

Browser Integration

If you want to use Lightclient in browser and facing some issues in building it with bundlers like webpack, vite. We suggest to use our distribution build. The support for single distribution build is started from 1.19.0 version.

Directly link the dist build with the <script /> tag with tools like unpkg or other. e.g.

<script src="https://www.unpkg.com/@lodestar/light-client@1.18.0/dist/lightclient.es.min.js" type="module">

Then the lightclient package will be exposed to globalThis, in case of browser environment that will be window. You can access the package as window.lodestar.lightclient. All named exports will also be available from this interface. e.g. window.lodestar.lightclient.transport.

NOTE: Due to top-level-await used in one of dependent library, the package will not be available right after the load. You have to use a hack to clear up that await from the event loop.

<script>
window.addEventListener("DOMContentLoaded", () => {
setTimeout(function () {
// here you can access the Lightclient
// window.lodestar.lightclient
}, 50);
});
</script>

Contributors

Read our contribution documentation, submit an issue or talk to us on our discord!

License

Apache-2.0 ChainSafe Systems