How JigsPerps works
JigsPerps is a trading terminal for Jupiter Perpetuals on Solana. It reads the protocol through Jupiter's public API, builds transactions you sign in your own wallet and shows risk before anything is sent. It is an interface: it holds no funds, runs no exchange and has no custody.
Product guide
Terminal (/app): pick a market (SOL, ETH, BTC perpetuals), read Jupiter's price and pool metrics, watch a spot reference chart, and open or manage positions. The order form validates inputs against the protocol limits (1.1× to 250×, $10 minimum collateral) and your balance before asking Jupiter for a preview. Positions, pending TP/SL requests and history sit below the chart; phones get Chart, Trade and Positions tabs.
Portfolio (/app/portfolio): open exposure and collateral, unrealized PnL before and after fees (from the positions endpoint), realized gross PnL and listed fees from the loaded trade records, filters by market, side, action and date, CSV export of the loaded page, and a journal with notes and tags stored in your browser.
Risk tools (/app/risk): position sizing from equity, risk budget and a hypothetical stop, with disclosed fee and slippage assumptions, a scenario table, and a feasibility check against wallet balances when connected.
Watchlist and alerts: star markets in the selector to pin them; create price alerts that are evaluated in your open tab against Jupiter's market price, with optional browser notifications you enable yourself.
Signing workflow
- Validate: wallet connected on mainnet-beta, inputs within limits, balance covers the input, market data fresh (a stale feed blocks risk-increasing previews; reduce and close stay available).
- Preview: the app calls Jupiter's increase or decrease route and shows the quote (average price, fees, price impact, outstanding borrow fee, liquidation estimate) with the unsigned transaction behind it.
- Confirm: the preview is valid for 30 seconds because it embeds a time-bound oracle update (the pool reports a 45-second execution window). Expired previews must be rebuilt; they are never signed.
- Sign: before the wallet prompt, the app checks that the transaction's fee payer is the connected wallet and its blockhash matches the preview metadata. Your wallet signs; seed phrases and private keys are never requested.
- Submit once:
instanttransactions go to Jupiter's execute route (which adds the keeper signature and submits);legacyones (TP/SL cancels) go to the RPC relay with retries disabled. A second click while a flow is active is refused. - Track: the signature is polled with getSignatureStatuses until it confirms, fails, or its last valid block height passes. Confirmed means the transaction landed; it does not mean the position changed.
- Reconcile: success is reported only when Jupiter lists the trade (trades by transaction id) or the TP/SL request appears on or disappears from the position. If the execution record is not visible within 90 seconds, the dialog says so and keeps refreshing positions.
Handled explicitly: user rejection, insufficient funds (Jupiter checks balances at preview time), stale previews, expired blockhashes, simulation errors surfaced by Jupiter, provider outages and rate limits (bounded backoff on reads, never on submits), request rejection, delayed execution, and wallet changes during a flow (an unsigned preview is dropped; a submitted signature keeps being tracked under its original wallet). Ambiguous submit results are reconciled by signature and never resent.
Integrations
Protocol: Jupiter Perpetuals through the public REST API at https://perps-api.jup.ag/v2. Verified on 2026-10-28 UTC: the docs page embeds the OpenAPI spec “Jupiter Perpetuals API Specification 0.0.1” whose server URL says /v1, but the schemas it describes (asset symbols, inputToken, raw USD integers) match the live /v2 endpoints; live /v1 expects mint-based bodies. The adapter therefore targets v2. No API key is documented or required; an optional JUPITER_PERPS_API_KEY is forwarded as x-api-key if Jupiter introduces keyed access. Jupiter's portal rate limits (keyless 0.5 req/s on api.jup.ag) are not documented for this host; the server caches market data for 5 s and applies bounded backoff on 429.
| Capability | Offered | Verification | Source |
|---|---|---|---|
Market discovery Three markets (SOL, ETH, BTC) from the market-stats enum and the JLP custody list. | Yes | Verified with live reads | GET /market-stats, GET /jlp-info |
Price, fees and liquidity Price, 24 h change/high/low/volume, open fee, borrow rates, utilization, available liquidity, max price impact fee. | Yes | Verified with live reads | GET /market-stats, GET /pool-info |
Wallet positions Open (and optionally closed) positions with fees, PnL before/after fees, liquidation price and attached TP/SL requests. | Yes | Verified with live reads | GET /positions |
Trade history Paginated trade records with gross PnL, fee breakdown and transaction ids; filters by market, side, action and time. | Yes | Verified with live reads | GET /trades |
Position preview Quotes include average price, fees, price impact and the protocol liquidation estimate. The API checks the wallet balance at preview time. | Yes | Built and verified unsigned | POST /positions/increase, POST /positions/decrease |
Open or increase a position An unsigned open transaction was built for a funded third-party wallet and decoded (fee payer, version, blockhash); signing and the execute route are implemented, and no funded transaction was submitted during development. | Yes | Built and verified unsigned | POST /positions/increase, POST /transaction/execute |
Partial or full close Unsigned close and partial-close transactions were built against a live position and decoded; the execute route rejects unsigned input as expected. | Yes | Built and verified unsigned | POST /positions/decrease, POST /transaction/execute |
Withdraw collateral A decrease with sizeUsdDelta 0 and collateralUsdDelta builds a withdrawal within GET /positions/collateral-limits. | Yes | Built and verified unsigned | POST /positions/decrease, GET /positions/collateral-limits |
Deposit collateral The API models deposits as an increase of the same market and side; a deposit-only path could not be verified, so it is not offered. | No | Not verified | jup-ag/cli docs/perps.md |
Take-profit / stop-loss Create, update and cancel requests were built unsigned against a live position; trigger-price bounds come back in error metadata. Only for positions at 150x or below. | Yes | Built and verified unsigned | POST/PATCH/DELETE /tpsl |
Limit orders Open limit orders are listed read-only; placing or editing them is not offered in this release. | No | Verified with live reads | GET /orders/limit |
Close all positions Documented but not offered: closing positions one at a time keeps each confirmation explicit. | No | Documented by Jupiter, not exercised | POST /positions/close-all |
Execution tracking After chain confirmation the trade record is looked up by transaction id; a position change is only reported once Jupiter lists the trade. | Yes | Verified with live reads | GET /trades?txid=, RPC getSignatureStatuses |
Candlestick history The Perps API has no candle endpoint; the chart shows spot USD candles from a public exchange API and labels them as such. | Yes | Verified with live reads | Coinbase Exchange / Kraken public market data |
Markets and collateral, from GET /jlp-info custodies and the market-stats enum: SOL-PERP (So1111…, 9 dp) ETH-PERP (7vfCXT…, 8 dp) BTC-PERP (3NZ9JM…, 8 dp) ; input tokens SOL, ETH, BTC, USDC. Leverage 1.1×–250× on every market (verified by error responses at 251×), TP/SL only at 150× or below, $10 minimum collateral for new positions, slippage default 200 bps.
Execution model: a preview transaction is version 0 with three required signatures (the user plus Jupiter's keeper/oracle signers) and an embedded Doves oracle update; simulating it later than the execution window fails with ExceedExecutionPeriod, which is why previews expire. Market increases and decreases and TP/SL create/update are instant (must go through POST /transaction/execute); TP/SL cancels are legacy.
Not verified in development: no funded mainnet transaction was submitted. Open, close, withdrawal and TP/SL transactions were built unsigned against live third-party wallets and decoded (fee payer, version, blockhash); an unfunded wallet gets insufficient_funds at preview time. The first signed execution is therefore a user-authorized step.
Permitted use: Jupiter's SDK & API License Agreement grants a limited licence for integration and asks integrators to label the API used and show “Powered by Jupiter”; uses outside the agreement need written consent (info@jup.ag). Jupiter's Terms of Use restrict the jup.ag interface in several jurisdictions (including the United States). Operators of a public deployment should confirm their own compliance before enabling trading for the public. Sources: perps-api.jup.ag/v2/docs, developers.jup.ag/docs/perps, jup-ag/cli docs/perps.md, SDK & API License Agreement, Terms of Use.
Solana RPC: the browser only talks to this site's /api/rpc relay, which forwards an allowlist of read, simulation and sendTransaction methods to the configured upstream (default: the key-free public node solana-rpc.publicnode.com; the official endpoint refuses many server IPs). Balances are read with one getMultipleAccounts over the associated token accounts.
More markets: Pacifica
Jupiter Perpetuals trades three markets (SOL, ETH, BTC against the JLP pool). For everything else, JigsPerps reads Pacifica, a Solana perpetuals orderbook, through its public API: 54 crypto perpetuals plus US stocks (NVIDIA, Tesla, Alphabet, Palantir, Robinhood, Circle, Strategy, Micron, SanDisk, Meta, SK hynix, Samsung), SpaceX as a pre-IPO market, the S&P 500, a uranium ETF and a memory-chip basket, gold, silver, platinum, copper, crude oil, natural gas, and two FX pairs. The Markets tab lists them live with the venue's mark and oracle prices, hourly funding, open interest, 24 h volume, leverage caps, order limits and the venue's own trade candles.
| Read | Source | Status |
|---|---|---|
| Market specs and prices | GET /api/v1/info + /info/prices | Verified with live reads (2026-10-28) |
| Candles | GET /api/v1/kline | Verified with live reads |
| Order placement | Signed Ed25519 operations, agent keys, on-chain deposits | Not offered here: each market links to the same market on Pacifica |
Pacifica's state-changing requests are signed with the venue's own canonical-JSON scheme and funded by deposits into its program, a separate integration from the Jupiter flow on the Trade tab. Nothing on the Markets tab is simulated; if the venue's API is unreachable the page says so instead of showing stale numbers as live.
Calculation assumptions
Position sizing (simplified linear model): riskBudget = equity × risk% / 100 (or an explicit dollar budget); stopDistance = |entry − stop| / entry; notional = riskBudget / stopDistance; initialMargin = notional / leverage. Cost-adjusted figures solve notional × (stopDistance + feeBps/10⁴ + 2 × slippageBps/10⁴) = riskBudget. Defaults: 12 bps fees (Jupiter's 0.06% base open and close fee), 10 bps slippage per leg. Inputs are validated for positive values, a non-zero stop distance, direction (long stops below entry, short stops above), and the protocol leverage range.
Scenario tables apply linear PnL on the notional for each price move and subtract the fee assumption; margin remaining ignores borrow fees that accrue hourly.
Liquidation is never derived as entry ± 1/leverage. The only liquidation figures shown are Jupiter's own: per open position from the positions endpoint and per preview from the increase/decrease quotes. The risk tool marks a scenario as beyond liquidation only when you paste such a protocol estimate.
Fees are labelled as Jupiter names them: base open/close fee, price impact fee (bps and USD), borrow fee (hourly, accrued on open positions and shown as “outstanding” in quotes). Jupiter has no funding rate between longs and shorts; the pool's base borrow rates are shown as borrow rates, never as funding.
Money math uses integer base units (bigint) for token amounts, raw 10⁶-scaled integers for USD values on the wire, and decimal.js for anything displayed or compared. PnL in history is gross (before fees) as the API reports it; fees are listed separately. Positions show both before- and after-fee PnL.
Chart data
The Jupiter Perpetuals API has no candlestick endpoint. The chart therefore shows spot USD candles from a public exchange API (Coinbase Exchange by default, Kraken as the alternative, both key-free) for SOL-USD, ETH-USD and BTC-USD. They are a reference for shape and levels, not the protocol's price: Jupiter executes against its own oracle, drawn on the chart as the dashed “Jupiter” line, and the difference to the last candle close is printed under the chart. Timeframes depend on the source (Coinbase: 1m, 5m, 15m, 1h, 6h, 1d; Kraken: 1m, 5m, 15m, 1h, 4h, 1d). If the source is unavailable the chart says so; no candles are generated.
Data limitations
- Market data is polled every 5 s and marked stale after 15 s without a successful refresh; stale data disables new risk-increasing previews.
- Trade history is paginated by the API (count plus start/end offsets); realized totals cover only the loaded records, and the API provides no lifetime summary.
- Positions, trades and limit orders are what Jupiter returns for the wallet; closed positions come back zeroed and are hidden from the open list.
- Balances come through the RPC relay with explicit coverage: a failed read shows “unknown”, never 0.
- Alerts and the journal live in this browser only. Alerts fire only while a tab with the app open is evaluating prices; there is no server-side monitoring.
- Deposit-only collateral, limit order placement and close-all are not offered (see the capability table).
- Jupiter Perpetuals is deployed on mainnet-beta only; on other clusters trading actions are disabled and the UI says so.
Configuration
Copy .env.example to .env.local. Public values: NEXT_PUBLIC_SITE_URL, NEXT_PUBLIC_SOLANA_NETWORK (mainnet-beta), NEXT_PUBLIC_X_URL. Server-only: SOLANA_RPC_URL (+ SOLANA_RPC_FALLBACK_URLS), JUPITER_PERPS_API_URL, JUPITER_PERPS_API_KEY, CANDLES_SOURCE, UPSTREAM_DOH. No secret is ever shipped to the browser; the health endpoint reports hosts without keys.
Terms and risk
Perpetual futures are leveraged, high-risk instruments; liquidation can lose the entire collateral, and borrow fees accrue while a position is open. JigsPerps provides software, not advice, and makes no claim about returns. Trading goes through Jupiter's protocol under Jupiter's terms, and users are responsible for their own eligibility under applicable law. Nothing on this site is a partnership claim; JigsPerps is not affiliated with Jupiter or the Solana Foundation.