Quickstart

Go from an empty account to a running indexer writing rows to your Postgres.

This walkthrough builds a real indexer: it watches one program, decodes one instruction, and writes a row to your database every time that instruction executes. Budget about ten minutes.

Before you start#

  • A PostgreSQL database you can reach from the internet. Any managed Postgres works. You will paste its connection string, and Syncro writes your decoded rows into it.
  • A Solana program ID to index, and ideally its Anchor IDL — with an IDL the canvas can be built for you in one paste.
  • Credits on your account. A deploy with a zero balance is rejected before the worker boots.

Build and deploy#

  1. Create the indexer

    From Indexers → New Indexer, give it a name and paste your PostgreSQL connection string. Those two fields are the only required ones — the RPC provider, API key, commitment level and runtime version all have sensible defaults you can change later. Submitting takes you straight to the canvas.

  2. Enter the program ID

    The canvas opens with two locked nodes already placed: a Program node on the left and a Database node on the right. Everything you build runs between them.

    Type the base58 program ID into the Program node. Until you do, the entire component palette stays disabled — the platform has nothing to subscribe to yet.

  3. Import the program interface

    Click the upload icon in the Program node header and paste your Anchor IDL. Syncro parses it, derives the 8-byte discriminators, and shows you a preview of the instruction and account nodes it will create. Accept it and the canvas fills in.

    No IDL? Paste a Rust struct instead, or place an Instruction node by hand and type in the field names and types yourself.

  4. Add a destination table

    Drag a Postgres Table node onto the canvas, name it, and add the columns you want. Then drag from a field handle on your instruction or account node to a column — that wire is the mapping. A field wired straight to a column needs no code at all.

    Finally, connect the table node to the Database node. Only table nodes may connect there, and nothing is created in your database until you deploy.

  5. Write one transform

    Every deploy requires at least one compiled transform, so add a Wasm Transform node even if your mapping is simple. Name its inputs and outputs, wire them up, then open the code panel — the editor scaffolds a function signature that matches your wiring.

    transform.ts
    export function transform(
      amount: u64,
      authority: string,
      signature: string,
    ): TransferRow {
      const row = new TransferRow();
      row.signature = signature;
      row.owner = authority;
      // Lamports are integers on chain; store the human amount as text so no
      // precision is lost on the way into NUMERIC.
      row.amount = amount.toString();
      return row;
    }

    Compile from the editor. The AssemblyScript compiler runs in your browser, so errors come back immediately rather than after a deploy.

  6. Save, then deploy

    Press Ctrl S to save, then hit Finalize & Deploy. Syncro shows you what the deploy will do to your version history, runs its preflight checks, and — if your schema requires it — asks you to confirm the exact SQL it will run against your database.

  7. Watch it run

    You are redirected to the logs view with a divider drawn at the deploy point. The status moves from deploying to active once the worker pod is healthy, and rows start appearing in your table as matching transactions land.

Where to go next#

  • Node reference — every component you can place, and the rules for wiring them.
  • Writing transforms — the type system between Rust, AssemblyScript and Postgres.
  • Webhooks — push events to your own services as they are decoded.