Skip to main content

Price Oracles

Jupiter Perps aggregates token prices from three independent onchain price oracles:

Oracle Selection Logic

  1. If the Edge oracle is not stale and its price is within a defined threshold of both Chainlink and Pyth, the Edge price is used.
  2. If the Edge oracle is stale or outside the threshold, Chainlink and Pyth prices are compared. If they are within the threshold of each other, the more recent of the two is used.
  3. If two or more oracles fail, no price update occurs.
Oracle price updates happen both during trade execution and via a dedicated keeper that runs independently. Prices used in Jupiter Perps may differ from prices on other venues. The Jupiter Perps price chart is the source of truth for trade decisions.

Migration Note

If you are using the old oracle account referenced in the custody account’s dovesOracle field, migrate to the new accounts by using the dovesAgOracle field instead.

Request Fulfillment Model

Jupiter Perps executes trade actions through keepers, in one of two ways. The jup.ag app picks the path for each action:
  1. Request and fulfillment: the trader (or API client) submits a request transaction to Solana containing all required trade parameters (size, collateral, direction, etc.). A keeper detects the request onchain, validates it, and submits a second transaction to execute the trade. The trade is only finalized when this second transaction is confirmed by the Solana network. Limit orders and TP/SL orders are executed this way when their trigger price is reached.
  2. Single transaction: the trader signs one transaction that a Jupiter keeper co-signs and submits right away, with no request account for market trades. Closing a position from jup.ag uses this path by default.

Keepers

Keepers are offchain services operated by Jupiter that continuously poll the Solana blockchain for pending trade requests. Jupiter runs two keepers in parallel. Actions processed by keepers:
  • Opening and closing positions
  • Increasing or decreasing position size
  • Depositing or withdrawing collateral
  • Creating, editing, and triggering TP/SL orders
  • Creating, editing, and triggering limit orders
On the request path, execution requires a keeper transaction, so there is a short delay between request submission and trade execution. The trade is not live until the keeper’s fulfillment transaction is confirmed.

Custody Accounts (Onchain)

Each asset in the JLP has a corresponding custody account storing all pool and fee parameters for that asset.

Beta Markets Execution Model

Beta markets do not use the request fulfillment model, the keepers, or the JLP custody accounts described above. An order is a single transaction that you sign with your Solana wallet; it is relayed to GUM, the orderbook trading engine that runs these markets, matched there, and the resulting fill is pushed back to the app. The transaction you signed is a regular Solana transaction and can be viewed on Solscan. Prices on the stock markets come from Chainlink oracles. If the engine does not confirm an order within about 8 seconds, the app shows Taking longer than expected and asks you to refresh the page to check the order’s status before submitting again. For collateral deposits and withdrawals, the app keeps checking for up to two minutes; if it still cannot confirm the update, it shows Collateral Update Pending: check your position and the transaction before trying again.

Code References

Base fee calculation

Formula and code snippet for the flat 0.06% open/close fee.

Linear price impact fee

Scalar-based fee that scales with trade size.

Additive price impact fee

Formula and custody parameters for the imbalance penalty.

Swap fee calculation

Weightage-based swap fee between JLP-held assets.

JLP mint/burn fee

Same weightage logic applied to minting and redeeming JLP, on a 0.20% base.

PnL calculation

Unrealized and realized PnL formula and pseudocode.

External References