Node reference

Every node you can place, what it configures, and the rules for wiring them together.

Nine node types make up every Syncro indexer. Two are placed for you and locked; the other seven are in the palette on the left of the canvas. This page covers what each one is for, what you configure on it, and how they are allowed to connect.

The palette at a glance#

Available components
FieldTypeDescription
ProgramlockedThe Solana program to watch. Placed for you; cannot be deleted.
InstructionpaletteOne instruction of that program, with its typed data fields.
AccountpaletteAn account touched by an instruction, decoded into typed fields.
Wasm TransformpaletteAssemblyScript that reshapes values between nodes.
Postgres TablepaletteA destination table in your own database.
Trigger ConditionpaletteAn optional gate that decides whether a sink fires.
WebhookpalettePOSTs a JSON payload to a URL you own.
WebSocketpaletteBroadcasts a payload to a live topic.
DatabaselockedYour PostgreSQL connection. Placed for you; cannot be deleted.

Program#

The root of the pipeline. It holds the base58 program ID you want to index, and it is the only node whose emptiness blocks everything else — the palette stays disabled until it is filled in.

Its header also carries the import button, which is the fastest way to build a canvas: paste an Anchor IDL or a Rust struct and let Syncro create the instruction and account nodes for you.

Its only outgoing connection is to instruction nodes.

Instruction#

One instruction of the program, and the filter that selects it out of the stream.

FieldTypeDescription
Instruction NametextA label, e.g. transfer. Used in generated code and to identify the node.
DiscriminatorhexThe byte prefix that identifies this instruction in the raw data. Imported IDLs fill this in with the correct Anchor discriminator automatically.
Data Fieldslist of name + Rust typeThe instruction's arguments, in order. Each field becomes its own output handle that you can wire to a column, a payload, a transform or a condition.

Account#

An account that a matched instruction touches, decoded into fields. This is the richest node on the canvas, because account layouts vary the most.

FieldTypeDescription
Account TypeselectReuse a saved layout, pick 'Custom' to define fields inline, or save your current fields as a new named type for reuse across this indexer.
Sequence #integerThe account's position in the instruction's account list. This is how the right account is picked out — get it wrong and you decode the wrong bytes.
DiscriminatorhexPrefix bytes to skip before the payload begins. Leave it empty and nothing is skipped.
Data Fieldslist of name + Rust typeThe account layout, in order. A bytes field additionally takes a length, for fixed-size [u8; N] arrays.
System Fieldsread-onlyValues available on every Solana account regardless of layout. Wire them like any other field.
Data Sizeread-onlyComputed from your field list. A useful sanity check against the account's real size on chain.

Wasm Transform#

AssemblyScript that runs between decoding and writing. Use one when a value needs to change shape: converting lamports, formatting a timestamp, combining two fields into one, or deriving a value that does not exist on chain.

FieldTypeDescription
Inputslist of namesOne input handle each. Types are inferred from whatever you wire in, so you name the slot and the wiring supplies the type.
Outputslist of namesOne output handle each, wireable to a column, a payload or a condition.
CodeAssemblyScriptEdited in the side panel. The signature is scaffolded from your inputs and outputs, and re-patched if you rewire — your function body is preserved.

Full details, including the type mappings, are on writing transforms.

Postgres Table#

A table in your own database. Each column is a destination; the wire into it is the mapping.

FieldTypeDescription
Table NametextThe table created in your database, e.g. token_swaps.
Columnslist of name + SQL typeVARCHAR, TEXT, BIGINT, INTEGER, BOOLEAN, NUMERIC, JSONB, TIMESTAMPTZ, UUID or BYTEA. Each row shows which field currently feeds it, so a missing wire is visible at a glance.

Connect the table to the Database node to include it in the indexer. See schema & migrations for how the DDL is produced.

Trigger Condition#

An optional boolean gate in front of a webhook or WebSocket sink. Wire the values the decision depends on into its inputs, write an evaluate function that returns true to fire and false to drop, and connect its gate output to the sink.

One condition can gate several sinks. A sink with nothing wired to its gate fires on every matching event. Conditions gate triggers only — they never filter what is written to your tables. See trigger conditions.

Webhook#

POSTs a JSON payload to a URL you control every time an event gets past the gate.

FieldTypeDescription
Trigger nametextIdentifies this trigger. It also forms part of the trigger reference sent with every delivery.
Payload Inputslist of namesThe values available to your payload builder. Wire fields or transform outputs in.
Destination URLhttps URLWhere the POST goes. Must be publicly reachable; private and internal addresses are refused.
Retry count0–10, default 3How many times a failed delivery is retried, with exponential backoff.
Payload codeAssemblyScriptA buildPayload function returning the JSON string to send.
Signing secretread-onlyIssued by the platform on first save. Use it to verify the signature on every delivery.

Delivery headers, signature verification and retry semantics are on the webhooks page.

WebSocket#

Broadcasts the same kind of payload to a live topic instead of pushing it to a URL. Use it for anything that should reach a browser or a long-lived client as it happens.

FieldTypeDescription
Trigger nametextIdentifies this trigger and seeds the topic name.
Broadcast Inputslist of namesThe values available to your payload builder.
Payload codeAssemblyScriptA buildPayload function returning a JSON string.
Topicread-onlyIssued on first save. Subscribers connect to this topic by name.
Connection keyread-onlyIssued on first save. Required to subscribe; an invalid key closes the socket.

See WebSockets for the subscriber contract.

Database#

The exit of the pipeline, representing the PostgreSQL connection you gave when you created the indexer. It has nothing to configure. Table nodes connect into it, and only table nodes may. It also offers an Import SQL Schema button, which turns pasted CREATE TABLE statements into table nodes.

Connection rules#

The canvas refuses invalid wires as you draw them. The complete set:

  • Program → Instruction. Nothing else may connect to an instruction.
  • Instruction → Account. An account node can only belong to an instruction.
  • Field handles → sinks. An instruction or account data field can feed a Transform, a Postgres Table, a Webhook, a WebSocket, or a Trigger Condition.
  • Transform outputs → the same sinks. Transform output can go anywhere a field can, but never back into an instruction or account.
  • Postgres Table → Database. Only table nodes may connect to the Database node.
  • Trigger Condition → gate handles only. A condition connects to the dedicated gate input on a webhook or WebSocket node, and may gate several of them.
  • One wire per field output. Each instruction or account field handle accepts exactly one connection.