Getting started

This page takes a token from no price to a live price you can read: create its feed, add its pools, keep it fresh, read it.

The program is not deployed to devnet or mainnet yet. Everything below runs today on a local validator that clones the real DEX programs and pool accounts from mainnet.

1. Run the local chain

cd engine
scripts/build.sh                 # builds target/deploy/jika.so and the IDL
scripts/localnet.sh up           # Agave test validator on http://127.0.0.1:51899
node sdk/bootstrap.mjs           # feeds for USDC, TERMINAL, USELESS and two pump.fun tokens
node sdk/keeper.mjs              # one update per feed every 10 seconds

2. Create a feed

One feed per mint, at PDA ["feed", mint]. Anyone can create it; a second one for the same mint fails.

import { createFeedIx } from "./sdk/jika.mjs"

const tx = new Transaction().add(createFeedIx({ payer: payer.publicKey, mint }))
await sendAndConfirmTransaction(connection, tx, [payer])

The USDC feed must exist before any pool quoted in USDC can be added anywhere.

3. Add its pools

Each feed takes up to 8 pools from the seven supported DEX programs. The program checks the owner, the layout and both mints.

import { addVenueIx } from "./sdk/jika.mjs"

for (const pool of pools) {
  await sendAndConfirmTransaction(connection, new Transaction().add(addVenueIx({ mint, pool })), [payer])
}

A new pool starts with zero weight. It earns weight by keeping its depth for about 10 minutes.

4. Update it

import { updateIx } from "./sdk/jika.mjs"

const tx = new Transaction()
  .add(ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000 }))
  .add(await updateIx(connection, mint))
await sendAndConfirmTransaction(connection, tx, [payer])

updateIx reads the feed and each pool from chain and passes every account the program needs, in order. A feed is live after 600 credited slots, about 4 to 5 minutes of updates.

5. Read it

From a client, simulate read and decode the return data:

import { readIx, decodePriceView, tickToPrice, bandFraction } from "./sdk/jika.mjs"

const ix = readIx({ mint, maxAgeSlots: 150n, maxConfTicks: 300 })
// simulate, then decode the transaction's return data
const view = decodePriceView(returnData)
const solPerToken = tickToPrice(view.steadyTick, view.baseDecimals)
const band = bandFraction(view.confTicks) // 0.012 means plus or minus 1.2%

From a program, see Integration.

What the local run produced

FeedVenuesPrice in SOLPrice in USDBand
USDCWhirlpool, Raydium CLMM, AMM v4, DLMM, PumpSwap0.00826306 (SOL = $121.02)plus or minus 0.01%
TERMINALPumpSwap, 2 DLMM0.0000119386$0.00144482plus or minus 1.28%
USELESSCPMM, Whirlpool, DLMM, DLMM vs USDC0.00201630$0.244014plus or minus 0.19%
a live pump.fun curvecurve2.73478e-7$0.0000330965plus or minus 6.05%
a graduated tokencomplete curve, PumpSwap8.04054e-7$0.0000973071plus or minus 4.90%
NextIntegration