Integration

Your program reads a JIKA price with one CPI to read. This page shows the call and the three decisions that make it safe: how old, how wide, and in which unit.

The call

// Cargo.toml: jika = { path = "...", features = ["cpi"] }
let view = jika::cpi::read(
    CpiContext::new(
        ctx.accounts.jika_program.to_account_info(),
        jika::cpi::accounts::Read {
            feed: ctx.accounts.feed.to_account_info(),
            quote_feed: None, // Some(usdc_feed) for a dollar price
        },
    ),
    150, // max_age_slots: refuse a price older than ~60 seconds
    300, // max_conf_ticks: refuse a band wider than ~3%
)?
.get();

// value of `amount` raw units of the token, in lamports
let value = (amount as u128 * view.price_q64) >> 64;

The feed address is the PDA ["feed", mint] under program 3EgkAd9FSZhofeh7MZVPk7QdSVKQUCuz8qyYQ2xabzdP. An absent optional account is passed as the program id.

Decision 1: how old

max_age_slots is the oldest last_update_slot you accept, counted back from the current slot. A slot is about 0.4 seconds. If the feed is older, read fails with Stale and your instruction fails with it.

Pick it together with your keeper: with an update every 10 seconds (25 slots), 150 slots allows five missed updates.

Decision 2: how wide

max_conf_ticks is the widest band you accept, in ticks (1 tick = 1 basis point). If the band is wider, read fails with TooUncertain.

The band widens when pools disagree, when the spot jumps away from the steady price (a spike in progress), or when the token is too thin to take 1 SOL. On TERMINAL, a 5% spike pushed the band to 8.98%, so a reader asking for 300 ticks refused during the spike.

Decision 3: which unit

Prices are in SOL by default (lamports per base raw unit). For dollars, pass the USDC feed as quote_feed: the result is the ratio of the two steady prices, and the two bands are added.

What to value with

FieldUse it for
price_q64 / steady_tickValuing collateral, marking positions, settling
spot_tickSeeing where the pools are right now; never for valuing
conf_ticksGating, and margins: lend less as the band widens
depthSizing: do not lend more against a token than its depth can absorb
top_share_bpsRefusing a feed that one pool dominates

Keepers

If money depends on a feed, run a keeper: one update per feed every 10 seconds, about 0.043 SOL a day per feed. With it, spikes cannot move the steady price and holding the market costs hundreds of times the token's depth. Without it, keep exposure below the walk cost measured in Security and trust.

Checklist

  • Derive the feed PDA from the mint yourself; do not take a feed address from the user.
  • Always pass both limits; never pass u32::MAX as the band limit for money.
  • Value at the steady price, gate on the band.
  • Handle NotLive, Stale and TooUncertain as "no price right now", not as zero.
NextAPI reference