npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jupiter-perps-api-sdk

v0.1.0

Published

V2 TypeScript client for the Jupiter Perpetuals API.

Readme

Jupiter Perps API SDK

V2-only TypeScript client for the Jupiter Perpetuals API.

This package is standalone and dependency-light. It depends on @solana/web3.js, always sends x-perps-api-version: v2, and does not import server-side route schemas or internal Jupiter code.

Install

npm install jupiter-perps-api-sdk
import { createPerpsClient } from 'jupiter-perps-api-sdk';

const perps = createPerpsClient();

The default baseUrl is https://perps-api.jup.ag/v1. You can pass a custom baseUrl, including a /v1 URL with the v2 header or a /v2 URL.

Quickstart

Read endpoints do not require wallet signing.

import { MINTS, createPerpsClient, formatRawUsd } from 'jupiter-perps-api-sdk';

const perps = createPerpsClient();

const positions = await perps.positions.get({
  walletAddress: '<wallet-address>',
});

const solStats = await perps.markets.getStats({
  mint: MINTS.SOL,
});

const leaderboard = await perps.leaderboard.getCompetitionLeaderboard({
  walletAddresses: ['<wallet-address>'],
  startTimestamp: Math.floor(Date.now() / 1000) - 3600,
});

console.log(positions.dataList);
console.log(solStats.price);
console.log(formatRawUsd(leaderboard.dataList[0]?.livePnlUsd ?? '0'));

Client Config

const perps = createPerpsClient({
  baseUrl: 'https://perps-api.jup.ag/v1',
  fetch: customFetch,
  headers: {
    'x-client-name': 'my-app',
  },
});

Options:

  • baseUrl: API base URL. Defaults to https://perps-api.jup.ag/v1.
  • fetch: custom fetch implementation for runtimes that do not expose globalThis.fetch.
  • headers: extra headers to send with every request.

The SDK always overwrites x-perps-api-version with v2.

API Surface

await perps.positions.get({ walletAddress });
await perps.positions.getTrades({ walletAddress });
await perps.positions.getCollateralLimits({ inputMint: MINTS.USDC, positionPubkey });

await perps.markets.getStats({ mint: MINTS.SOL });
await perps.markets.getPoolInfo({ mint: MINTS.SOL });

await perps.jlp.getInfo();

await perps.leaderboard.getCompetitionLeaderboard({
  walletAddresses,
  startTimestamp,
});

await perps.trading.increasePosition(input);
await perps.trading.decreasePosition(input);
await perps.trading.closeAllPositions({ walletAddress });

await perps.trading.createLimitOrder(input);
await perps.trading.updateLimitOrder(input);
await perps.trading.getLimitOrders({ walletAddress });
await perps.trading.closeLimitOrder({ positionRequestPubkey });

await perps.trading.createTpsl(input);
await perps.trading.updateTpsl(input);
await perps.trading.cancelTpsl({ positionRequestPubkey });

await perps.trading.executeTransaction({ action, serializedTxBase64 });
await perps.trading.executeSignedTransaction({ action, transaction });
await perps.trading.signAndExecute({ action, serializedTxBase64, wallet });

Lower-level transaction helpers are also exported:

import {
  deserializeTransaction,
  serializeTransaction,
  signAndExecuteTransaction,
  signTransaction,
} from 'jupiter-perps-api-sdk';

Trading Flow

Trading endpoints return a base64 serialized Solana transaction. Your app signs the transaction with the user's wallet, then submits the signed transaction to /transaction/execute.

import { createPerpsClient } from 'jupiter-perps-api-sdk';

const perps = createPerpsClient();

const increase = await perps.trading.increasePosition({
  walletAddress: '<wallet-address>',
  asset: 'SOL',
  inputToken: 'USDC',
  inputTokenAmount: '10000000',
  side: 'long',
  leverage: '5',
  maxSlippageBps: '100',
});

if (!increase.serializedTxBase64) {
  throw new Error('No transaction returned');
}

const transaction = perps.transactions.deserialize(increase.serializedTxBase64);
const signed = await wallet.signTransaction(transaction);

const result = await perps.transactions.executeSigned({
  action: 'increase-position',
  transaction: signed,
});

console.log(result.txid);

You can use signAndExecute when your wallet object implements signTransaction.

const result = await perps.trading.signAndExecute({
  action: 'increase-position',
  serializedTxBase64: increase.serializedTxBase64,
  wallet,
});

Amounts and Units

Most numeric request fields are strings because the API works with integer raw amounts and decimal-safe values.

  • USD values are raw integers scaled by 1e6 unless a field explicitly says it is formatted.
  • Token input amounts are raw token units. For example, 10000000 USDC is 10 USDC because USDC has 6 decimals.
  • Slippage is in basis points. For example, 100 is 1%.
  • Leverage is passed as a string, such as '5'.

Formatting helpers:

import {
  formatRawUsd,
  rawAmountToDecimalString,
  rawUsdToNumber,
} from 'jupiter-perps-api-sdk';

formatRawUsd('123456789'); // "$123.46"
rawAmountToDecimalString('10000000', 6); // "10"
rawUsdToNumber('123456789'); // 123.456789

Errors

Non-2xx API responses throw PerpsApiError.

import { PerpsApiError } from 'jupiter-perps-api-sdk';

try {
  await perps.positions.get({ walletAddress: '<wallet-address>' });
} catch (error) {
  if (error instanceof PerpsApiError) {
    console.error(error.status, error.code, error.message, error.metadata);
  }

  throw error;
}

Examples

Example scripts live in the GitHub repository under examples/:

  • examples/leaderboard.ts
  • examples/open-position.ts
  • examples/close-position.ts

Run them with Bun or another TypeScript runner:

WALLETS=<wallet-address> bun examples/leaderboard.ts
WALLET_ADDRESS=<wallet-address> bun examples/open-position.ts
POSITION_PUBKEY=<position-pubkey> bun examples/close-position.ts

Set PERPS_API_URL only if you need to point at a different API base URL.

Scope

This SDK intentionally includes the public v2 read, leaderboard, trading, transaction, formatting, and polling helpers. It intentionally excludes with-fee endpoints and internal or legacy server endpoints.