Skip to main content
Build a custom data sink. A target drains batches from the pipe and is responsible for persisting them.
Config fields:
  • write: (required) Async function ({ read, logger }) => Promise<void>. Iterate the stream by calling read() and consuming { data, ctx } batches. The function returns when the stream ends.
  • fork: (optional) (previousBlocks: BlockCursor[]) => Promise<BlockCursor | null>. Called when the source detects a chain reorg. Return the last safe cursor to roll back to, or null if no common ancestor can be determined (the stream will throw). See Fork handling. You don’t need this callback when the source is configured to read only finalized blocks.

The write context

Per-batch context (ctx)

Each { data, ctx } yielded by read() carries the same BatchContext that transformers receive. Fields:

Example

Resuming from a persisted cursor

Stateful targets typically persist a cursor and resume from it on restart: