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

@elmntl/jlpd-sdk

v0.1.6

Published

SDK for JLP.D (JLP Deconstructed) by Elemental

Readme

JLP.D SDK

SDK for interacting with the JLP.D (JLP Deconstructed) protocol on Solana.

Installation

# Using npm
npm install git+https://github.com/elementalfund/jlpd-sdk.git

# Using yarn
yarn add git+https://github.com/elementalfund/jlpd-sdk.git

Or add directly to package.json:

{
  "dependencies": {
    "jlpd-sdk": "git+https://github.com/elementalfund/jlpd-sdk.git"
  }
}

Peer Dependencies

| Package | Version | |---|---| | @coral-xyz/anchor | ^0.32.1 | | @solana/web3.js | ^1.95.0 | | @solana/spl-token | ^0.4.0 |

Quick Start

import { Connection } from "@solana/web3.js";
import { JlpdClient } from "jlpd-sdk";

// Connect to Solana mainnet
const connection = new Connection("https://api.mainnet-beta.solana.com");
const client = JlpdClient.mainnet(connection);

Architecture

The SDK uses the Anchor IDL (@coral-xyz/anchor 0.32.1) for instruction serialization. All instruction builders call program.methods.<instruction>().accounts({}).instruction() under the hood, which ensures correct serialization from the on-chain IDL.

The JlpdClient exposes an Anchor Program instance for advanced use:

// Access the typed Anchor program directly
const program = client.program;

// Build instructions manually if needed
const ix = await program.methods
  .deposit(new BN(1_000_000_000))
  .accounts({ user: walletPublicKey, jlpVault: client.vaultPda, /* ... */ })
  .instruction();

You can also create a standalone program instance:

import { createProgram } from "jlpd-sdk";
import type { JlpDProgram } from "jlpd-sdk";

const program = createProgram(connection);

Available Pools

| Pool | Description | | ---------- | ----------- | | "SOL" | Solana | | "USDC" | USD Coin | | "JupUSD" | Jupiter USD | | "BTC" | Bitcoin | | "ETH" | Ethereum |


User Operations

Deposit

Deposit tokens and receive vault shares (jvX tokens).

import { BN } from "@coral-xyz/anchor";

const pool = client.pool("SOL");

const tx = await pool.deposit({
  user: walletPublicKey,
  amount: new BN(1_000_000_000), // 1 SOL (9 decimals)
});

// Sign and send transaction with your wallet
const signature = await wallet.sendTransaction(tx, connection);

Withdraw

Burn vault shares and receive tokens back.

const tx = await pool.withdraw({
  user: walletPublicKey,
  shares: new BN(500_000_000), // Amount of jvX shares to burn
});

const signature = await wallet.sendTransaction(tx, connection);

Reading Data

Get Vault Info

const vault = await client.fetchVault();

console.log("Admin:", vault.admin.toBase58());
console.log("Manager:", vault.manager.toBase58());

Get Pool (STV) Info

const stv = await client.fetchStv(MINTS.SOL);

console.log("Price per share:", stv.pps.toString());
console.log("Total fees accrued:", stv.accruedFeesJlx.toString());

Get Exchange Rate

const rate = await client.fetchExchangeRate("SOL");

console.log("Exchange rate:", rate.rate); // e.g., 1.05 means 5% yield
console.log("Is fresh:", rate.isFresh);

Calculate APY

Calculate annualized return based on PPS (price per share) growth over time.

// You need a starting PPS and timestamp (e.g., from when user deposited)
const startPps = new BN("1000000000"); // 1.0 (9 decimals)
const startTime = 1706140800; // Unix timestamp when PPS was recorded

// Calculate compound APY
const apy = await client.calculateApy("SOL", startPps, startTime);
console.log(`APY: ${(apy * 100).toFixed(2)}%`); // e.g., "APY: 12.50%"

// Or calculate simple APY (non-compounded)
const simpleApy = await client.calculateSimpleApy("SOL", startPps, startTime);
console.log(`Simple APY: ${(simpleApy * 100).toFixed(2)}%`);

Note: Store the user's PPS and timestamp when they deposit to calculate their personal returns later.


Manager Operations

These operations require manager permissions.

Jupiter Earn (Deposit/Withdraw to Jupiter Lend)

const pool = client.pool("SOL");

// Deposit base tokens to Jupiter Lend
const depositTx = await pool.jupEarn({
  manager: managerPublicKey,
  direction: "Deposit",
  amount: new BN(1_000_000_000),
});

// Withdraw from Jupiter Lend
const withdrawTx = await pool.jupEarn({
  manager: managerPublicKey,
  direction: "Withdraw",
  amount: new BN(1_000_000_000),
});

Move Tokens Between STV and Vault

const pool = client.pool("SOL");

// Move jlX tokens to vault (for JLP conversion)
const toVaultTx = await pool.moveJlx({
  manager: managerPublicKey,
  direction: "ToVault",
  jlxAmount: new BN(1_000_000_000),
});

// Move jlX tokens back from vault to STV
const fromVaultTx = await pool.moveJlx({
  manager: managerPublicKey,
  direction: "FromVault",
  jlxAmount: new BN(1_000_000_000),
});

Claim Fees

const pool = client.pool("SOL");

const tx = await pool.claimFees({
  manager: managerPublicKey,
});

Settle Yield

Distributes JLP yield across all pools. Requires fetching the current JLP price.

import { fetchJlpRate, MINTS } from "jlpd-sdk";

// Fetch current JLP price from Jupiter
const jlpRate = await fetchJlpRate(MINTS.JLP.toBase58());

// Settle yield
const admin = client.admin();
const tx = await admin.settleYield({
  manager: managerPublicKey,
  jlpRate,
});

Swap Operations

Swap jlX to/from JLP

const swap = client.swap();

// Get a quote first
const quote = await swap.quoteJlxJlp({
  pool: "SOL",
  direction: "JlxToJlp", // or "JlpToJlx"
  amountIn: new BN(1_000_000_000),
  slippageBps: 30, // 0.3% slippage
});

console.log("Expected output:", quote.outAmount.toString());
console.log("Price impact:", quote.priceImpactPct, "%");

// Execute the swap
const tx = await swap.swapJlxJlp({
  manager: managerPublicKey,
  pool: "SOL",
  direction: "JlxToJlp",
  amountIn: new BN(1_000_000_000),
  expectedOut: quote.outAmount,
  quote,
});

Swap Between jlX Types

const swap = client.swap();

// Get a quote
const quote = await swap.quoteJlxJlx({
  fromPool: "SOL",
  toPool: "USDC",
  amountIn: new BN(1_000_000_000),
  slippageBps: 30,
});

// Execute the swap
const tx = await swap.swapJlxJlx({
  manager: managerPublicKey,
  fromPool: "SOL",
  toPool: "USDC",
  amountIn: new BN(1_000_000_000),
  minOut: quote.minOutAmount,
  quote,
});

Token Decimals Reference

| Token | Decimals | Example | | ------ | -------- | ----------------------- | | SOL | 9 | 1 SOL = 1_000_000_000 | | USDC | 6 | 1 USDC = 1_000_000 | | JupUSD | 6 | 1 JupUSD = 1_000_000 | | BTC | 8 | 1 BTC = 100_000_000 | | ETH | 8 | 1 ETH = 100_000_000 |


Working with BN (Big Numbers)

Solana uses big integers for token amounts. Use the BN class:

import { BN } from "@coral-xyz/anchor";

// Create from number (small amounts only)
const small = new BN(1000);

// Create from string (recommended for large amounts)
const large = new BN("1000000000000");

// Arithmetic
const sum = a.add(b);
const diff = a.sub(b);
const product = a.mul(b);
const quotient = a.div(b);

// Comparison
a.gt(b); // greater than
a.lt(b); // less than
a.eq(b); // equal
a.isZero();

// Convert to display string
const displayAmount = amount.toString();

Error Handling

import { JlpdClientError } from "jlpd-sdk";

try {
  const tx = await pool.deposit({
    user: walletPublicKey,
    amount: new BN(0), // Invalid amount
  });
} catch (error) {
  if (error instanceof JlpdClientError) {
    console.error("SDK Error:", error.message);
  } else {
    console.error("Unexpected error:", error);
  }
}

Low-Level Instruction Builders

For direct transaction construction (e.g., from a backend server), the SDK exports individual instruction builders. Each takes an Anchor Program instance as the first argument.

import {
  createProgram,
  createDepositInstruction,
  createWithdrawInstruction,
  createInitOrUpdateVaultInstruction,
  createUpdateStvInstruction,
  createJupEarnInstruction,
  createMoveJlxInstruction,
  createSwapJlxJlxInstruction,
  createSwapJlxJlpInstruction,
  createSettleYieldInstruction,
  createClaimFeesInstruction,
} from "jlpd-sdk";

const program = createProgram(connection);

// Example: build a deposit instruction
const ix = await createDepositInstruction(
  program,
  new BN(1_000_000_000),
  {
    user: userPubkey,
    jlpVault: vaultPda,
    stv: stvPda,
    baseMint: MINTS.SOL,
    jlMint: jlSolMint,
    jvMint: jvSolMint,
    userBaseAta: userSolAta,
    userJvxAta: userJvSolAta,
    stvBaseAta: stvSolAta,
    stvJlxAta: stvJlSolAta,
    tokenProgram: TOKEN_PROGRAM_ID,
  },
  remainingAccounts, // optional exchange rate accounts
);

Some accounts are auto-resolved by Anchor from the IDL (PDAs and known addresses) and should be omitted from .accounts():

| Instruction | Auto-resolved accounts | |---|---| | initOrUpdateJlpVault | jlpVault (PDA), systemProgram | | initializeStv | stv (PDA), stvJlxAta (PDA), systemProgram, associatedTokenProgram, rent | | jupEarnDepositWithdraw | tokenProgram |


Constants

import { MINTS, JLPD_PROGRAM_ID } from "jlpd-sdk";

// Token mints
MINTS.SOL; // Native SOL mint
MINTS.USDC; // USDC mint
MINTS.JLP; // JLP token mint
MINTS.WBTC; // Wrapped BTC mint
MINTS.WETH; // Wrapped ETH mint

// Program ID
JLPD_PROGRAM_ID; // Main program address

Full Example: Deposit Flow

import { Connection, PublicKey } from "@solana/web3.js";
import { BN } from "@coral-xyz/anchor";
import { JlpdClient } from "jlpd-sdk";

async function deposit(walletPublicKey: PublicKey, wallet: any) {
  // 1. Create client
  const connection = new Connection("https://api.mainnet-beta.solana.com");
  const client = JlpdClient.mainnet(connection);

  // 2. Get pool context
  const pool = client.pool("SOL");

  // 3. Check current exchange rate (optional)
  const rate = await client.fetchExchangeRate("SOL");
  console.log(`Current yield: ${((rate.rate - 1) * 100).toFixed(2)}%`);

  // 4. Build deposit transaction
  const tx = await pool.deposit({
    user: walletPublicKey,
    amount: new BN(1_000_000_000), // 1 SOL
  });

  // 5. Send transaction
  const signature = await wallet.sendTransaction(tx, connection);
  console.log("Transaction sent:", signature);

  // 6. Confirm transaction
  await connection.confirmTransaction(signature, "confirmed");
  console.log("Deposit confirmed!");
}

Support

For issues or questions, contact the Elemental team.