Reading offers
There are two ways to read offers: through the Invia REST indexer (preferred
for most use cases) or directly from chain via getProgramAccounts. Both are
exposed on the SDK.
Via the REST indexer
The indexer normalizes each on-chain offer into a flat row, computes
status, and exposes filters by maker, mint, side, and pagination.
const { offers, limit, offset } = await invia.api.getOffers({
status: "open",
side: "sell",
paymentMint: "So11111111111111111111111111111111111111112",
limit: 50,
});Each row carries:
| Field | Type | Notes |
|---|---|---|
pda | string | Offer PDA, used as the canonical identifier |
maker | string | Base58 wallet address |
tokenMint / paymentMint | string | Mint addresses |
side | "sell" | "buy" | Maker's side of the trade |
originalSize / remainingSize | string | Raw token units, decode with fmtTokenAmount |
pricePerToken / priceScale | string / number | Sub-unit price, see Pricing |
minFill | string | Smallest accepted taker fill |
expiresAt | string | ISO 8601 |
status | "open" | "filled" | "expired" | Indexer-computed |
Single offer + fills
const offer = await invia.api.getOffer(pda);
const { fills } = await invia.api.getOfferFills(pda);The fills array is sourced from the on-chain signature scanner; payment and fee amounts are computed from the offer's price and scale at the time the fill landed.
Direct from chain
import { decodeOfferAccount } from "@invia-app/sdk";
const account = await connection.getAccountInfo(pda);
if (!account) throw new Error("offer not found");
const decoded = decodeOfferAccount(pda, account.data);decodeOfferAccount returns an OfferAccount with bigint numerics and
PublicKey addresses, ready for transaction building.
To list every open offer without the indexer:
const offers = await invia.program.fetchAllOffers();The REST indexer is cached, denormalizes status, and survives the cluster
occasionally rate-limiting getProgramAccounts. Direct chain reads are
useful for building your own indexer or for sanity-checking the published
API against the source of truth.
Pagination
let offset = 0;
const pageSize = 100;
while (true) {
const page = await invia.api.getOffers({ status: "open", limit: pageSize, offset });
if (page.offers.length === 0) break;
process(page.offers);
if (page.offers.length < pageSize) break;
offset += pageSize;
}