@effectstream/sync
Package:
@effectstream/sync· Source
The blockchain-sync service inside an EffectStream node. Reads finalized blocks from every chain you've configured (EVM, Bitcoin, Cardano, Midnight, Avail, Celestia, NEAR…), normalizes them into a single rollup ordering, and stages the inputs the state machine consumes.
Install
bun add @effectstream/sync
# or
npm install @effectstream/sync
Usage
This package pairs with @effectstream/runtime,
which boots sync as part of start(): it calls genSyncProtocols(...)
against the syncProtocols section of your
@effectstream/config,
then drives the resulting fetcher + state pairs every block. As an app
author you declare which protocols to sync in your config; everything
else runs automatically.
If you're building a new chain integration, implement the sync-protocol
interfaces in src/sync-protocols/.
Inside EffectStream
genSyncProtocols(config) is what the runtime calls during boot. It walks
the syncProtocols section of your @effectstream/config, instantiates a
fetcher for each chain (viem for EVM, UTXORpc for Cardano, the Midnight
SDK for Midnight, etc.), and writes paginated blocks into PostgreSQL
through @effectstream/db. The state machine then drains that queue.
import { genSyncProtocols } from "@effectstream/sync";
// inside the runtime startup path:
const protocols = await genSyncProtocols(config);
// protocols.parallelEvmRPC_fast.runOne() // poll one block
Key exports
genSyncProtocols(dbConn, syncInfo)— Effection generator that instantiates a runtime fetcher + state pair for every protocol insyncInfo(fromconfig.syncProtocols). Called from the runtime's process-blocks loop.AllSyncProtocols— union type covering every supported protocol; useful when authoring config that fans out.ChainBlock, plus baseFetcher/Statetypes fromsync-protocols/base/— the wire shape per chain.
Per-chain Fetcher / SyncState classes (EvmFetcher,
BitcoinFetcher, MidnightFetcher, AvailFetcher, UtxoRpcFetcher,
NtpFetcher, CelestiaFetcher, NearFetcher, and matching *SyncState
classes) are exported but are internal to the factory wiring —
application code drives them through genSyncProtocols rather than
instantiating them directly. Reach for them only if you're writing a
custom orchestration layer.
Examples
End-to-end sync test (boots a node, reads blocks, asserts the DB):
e2e/evm/sync/.
Runnable: test/examples.test.ts.