Where data comes from
Every read answers from one of three sources. Pick the one that matches the question:
- Contract state decides what’s true now. LOC storage, token balances, collateral reservations, protocol configuration, transaction receipts, and contract reverts are the authority.
- The subgraph turns events into history. It indexes contract events into searchable LOC history and lists. It can run behind the chain, and contract state wins when they differ.
- SDK computations help you prepare. Contract-parity helpers used to prepare transactions follow the contract’s own math. Display helpers can keep more precision on purpose. Either way, the contract has the final say.
The differences show up in how your app behaves, so each source is worth a closer look.
Chain state
The LetterOfCredit contract stores only what it needs to enforce the rules: live LOCs, their amounts, and their expirations. Two things follow from that.
First, a LOC that resolves leaves contract storage. When a LOC is fully redeemed or canceled, the contract removes it, so a direct read of a finished LOC returns nothing, exactly as it would for an id that never existed. The history of what happened lives in events, and events are what the subgraph indexes.
Second, some facts only ever appear in events. The creation tag (the Creator’s offchain reference) and the creation timestamp exist only in the creation event, so they reach your app through the subgraph rather than a direct contract read.
The subgraph
The subgraph indexes contract events, and two of its properties matter in your code.
It runs behind the chain. The full record, LetterOfCredit, is a consistent snapshot as of what the
subgraph has indexed, including origin and how the LOC resolved. The SDK pins every read that
contributes to it to one subgraph deployment and block hash, checks that point, and carries it
through opaque pagination cursors, so later contract reads never overwrite those facts. Check
indexedAt when freshness matters; an indexed block may still be short of chain finality.
The outstanding listing answers a different question. It finds candidate ids in the subgraph and
reads each one’s live position from the contract as OutstandingLetterOfCredit. Candidates the
contract has already removed drop off the page, so a short page can still have more after it. Direct
reads of the live position are also what operations are prepared from. When the subgraph’s schema is
incompatible or its evidence is incomplete, the full-record read throws a typed compatibility error
rather than returning the live position in its place.
It’s optional configuration. Indexed reads (LOC and vault listings, history, collateral-token
discovery) need the subgraph endpoint, and without it they fail with a typed configuration error
naming subgraphUrl. Direct contract reads, such as a single live position, balances, and prices,
work without it.
SDK-computed values
The SDK computes two kinds of values on purpose. Contract-parity helpers predict what the contract will do: the SDK’s pair-price and collateral-factor math follows the contract’s integer arithmetic, with the same formula the price oracle contract uses, the same rounding down, and the same conversion order, so a preflight estimate matches the eventual onchain result. Display helpers can keep more precision than the contract, because they answer what a user should see rather than what the contract will compute.
Either way, the contract has the final say, and receipts and events are the evidence of what a transaction actually did.
Choosing a source
Most apps use the subgraph to find records and a direct contract read to confirm state before any action that moves money. Read a LOC shows the full record and the live position in practice, and Validate before signing shows the checks the SDK runs before a wallet signs.