> ## Documentation Index
> Fetch the complete documentation index at: https://docs.panofx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Settlement on Solana

> The vendored order-engine program, the canonical transaction, and how the relay, node and indexer agree on it.

There is one Solana program, and Panofx did not write it. `order-engine` is Jupiter's RFQ fill program
(MIT), audited by Offside Labs in November 2024. It is vendored unchanged except for its program id, and CI
rebuilds it from the pinned upstream commit plus the one patch and fails on any other difference.

|            |                                                                            |
| ---------- | -------------------------------------------------------------------------- |
| Program id | `PFXzwLoUsUAC1eNBGVxbgpsrhduaMFVmqLy9oge4N5n`, the same on every cluster   |
| Upstream   | `jup-ag/rfq-webhook-toolkit` at `3aa4fce515d4b5827ee2d48f08041ea706d911cd` |
| Toolchain  | Agave 2.2.20, Rust 1.87, Anchor 0.31.1 crates                              |

## What the program does

One instruction, `fill(input_amount, output_amount, expire_at)`. The taker and the maker must both sign.
It checks `expire_at` against the cluster clock, then moves both legs by CPI: the taker's input to the
maker and the maker's output to the taker, through SPL Token or Token-2022. It refuses a Token-2022 mint
that charges a transfer fee. It holds no state and charges nothing.

Panofx's protocol fee and the keeper's gas repayment are two more `transfer_checked` instructions in the
same transaction. The maker and the taker each sign the whole message, so neither can be removed or
changed without breaking their signatures.

## The canonical transaction

The settlement transaction is canonical: `panofx-node/internal/solana/doc.go` specifies it and
`testdata/vectors.json` pins it. The relay and the web app share one TypeScript implementation,
`panofx-api/src/domain/solana/settlement.ts`, copied byte for byte into the web app and checked by CI. Every
party rebuilds the transaction from the terms and compares bytes before trusting a signature on it.

Three signers: the **maker** (the node), the **taker**, and the **fee payer** (the relay's keeper). The
taker needs no SOL. The taker repays the keeper in the pair's fee mint through the gas-fee instruction,
which also covers the rent for the taker's receiving token account when it does not exist yet.

## Order of events

1. The node signs as maker when it answers the RFQ. The RFQ carries the rest of the terms: `feePayer`, `feeMint`, `feeBps`, `treasury`, `gasFee`, `computeUnitLimit`, `computeUnitPrice`.
2. The relay checks the transaction byte for byte against the terms it asked for, simulates it, and quotes it.
3. The taker's client rebuilds the same transaction from `/v1/config` and the quote, checks it, and signs as taker.
4. The keeper signs last as fee payer and submits.

## Node identity on Solana

A node's identity with the relay is its EVM key. A node that quotes a Solana chain adds `solanaAddress` and
`solanaSignature` to its hello: an ed25519 signature over `panofx-node-hello|<nonce>|<solanaAddress>|<name>`.
A valid proof binds that key to the node; the relay stores it and rejects any Solana offer whose maker is
not the bound key. Without a valid proof the relay keeps the node's EVM corridors and drops its Solana ones.
A key already bound to another connected node is refused.

## Offer lifetime

The relay rejects a Solana offer whose deadline is under `now + MIN_OFFER_TTL_MS` (10 s) or over
`now + 120 s`. A transaction's blockhash expires after about a minute anyway, so nodes use 60.

## Indexer

The program emits no events, so the indexer reads transactions.

* **What it reads.** The program's transactions from `getSignaturesForAddress`, oldest first, at finalized commitment. Finalized transactions do not roll back, so rows are written confirmed. Failed transactions are skipped.
* **Fills.** Every top-level `fill` instruction becomes a Fill row with id `<signature>:<instruction index>`. Its resolver is the node whose bound Solana key made it, or the key itself when no node has bound it.
* **Settlements.** A fill whose transaction is exactly the canonical settlement also becomes a Settlement row. The indexer rebuilds that settlement from the fill's accounts, the compute budget, the gas-fee transfer and the chain's configuration, and it must match the landed message byte for byte.
* **Matching a quote.** First the quote whose execution sent that signature, then the quote storing the message hash as its offers hash, on the same chain only. A match settles the quote and releases the maker's reservation.
* **Cursor.** The last signature indexed and the slot indexed through. It moves up to the finalized slot when the program is idle, so an idle program does not show as lag. A listing never goes further than 150 slots before the cursor's slot.
* **Start.** An empty cursor starts at the current finalized slot. To backfill, set `indexerStartSlot` on the chain's `CHAINS` entry.
* **Health.** `/health` reports `head` and `cursor` as slots; the chain is unhealthy 300 slots (about two minutes) behind finalized. Before the first tick, the indexer checks that the RPC serves the cluster the chain id names (by genesis hash) and that the program is deployed there.
* **Not indexed.** Fills that reach the program through another program (CPI), and versioned transactions.

## Devnet

Deployed 13 September 2026 in slot 497,711,080. The deployed bytes equal a local build of the vendored
directory. The end-to-end test passed on devnet the same day: the node signed both directions with the
taker holding no SOL throughout, devnet answered `SignatureFailure` with the fee instruction removed, and
the program refused an expired fill.

| Account                        | Solana devnet (chain id 103)                                                                                                                      |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Order-engine program           | [`PFXzwLoUsUAC1eNBGVxbgpsrhduaMFVmqLy9oge4N5n`](https://explorer.solana.com/address/PFXzwLoUsUAC1eNBGVxbgpsrhduaMFVmqLy9oge4N5n?cluster=devnet)   |
| Test cNGN (Token-2022, 6 dp)   | [`6RFnYruxidpR1m9L91bs8cZKjmigEpxXB2Wv2rR8m2pu`](https://explorer.solana.com/address/6RFnYruxidpR1m9L91bs8cZKjmigEpxXB2Wv2rR8m2pu?cluster=devnet) |
| Test USDC (SPL Token, 6 dp)    | [`72GtYU66mCGJV311qh12EVGyQGkAb8TJVpxSXMPSghKx`](https://explorer.solana.com/address/72GtYU66mCGJV311qh12EVGyQGkAb8TJVpxSXMPSghKx?cluster=devnet) |
| Test USDT (SPL Token, 6 dp)    | [`An2RV3ZgsyXspuWLY2TgmjwR5UY1iYNgymrsLCTaPpCN`](https://explorer.solana.com/address/An2RV3ZgsyXspuWLY2TgmjwR5UY1iYNgymrsLCTaPpCN?cluster=devnet) |
| Treasury and upgrade authority | `HNxotR7XfmwVxq85hemdnTmwrgmyQTZir9S2U9Cq2kDn`                                                                                                    |
| Keeper (fee payer)             | `6XVEMkczPazR48FspJneiVdE7GYJ77PofQBtcfVAq8YB`                                                                                                    |

The integrator-facing shapes are under [Solana](/integrators/solana).
