TypeScript SDK for interacting with the JPool liquid staking pool on Solana. The SDK provides the following features:
- Stake SOL and receive LST pool tokens
- Unstake SOL instantly
- Stake to specific validators
- Query pool state, rates, and fees
- Check direct stakes and wallet bindings
- Installation
- Quick Start
- Usage
- Configuration
- Important Notes
- Examples
- Constants
- API Reference
- Links
- License
npm install @jpool/sdk
# or
pnpm add @jpool/sdk
# or
yarn add @jpool/sdkimport { Connection, clusterApiUrl, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'
import { JPoolClient } from '@jpool/sdk'
// Create connection and client
const connection = new Connection(clusterApiUrl('mainnet-beta'))
const client = new JPoolClient(connection)
// Get pool information
const poolInfo = await client.poolInfo()
console.log('Total staked:', Number(poolInfo.totalLamports) / LAMPORTS_PER_SOL, 'SOL')
// Calculate exchange rate
const rate = client.poolTokenRate(poolInfo)
console.log('Exchange rate:', rate, 'lamports per pool token')Stake SOL and receive liquid pool tokens:
import { Transaction, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js'
const userPublicKey = new PublicKey('YOUR_WALLET_ADDRESS')
// Get deposit instructions
const { instructions, signers } = await client.depositSol({
from: userPublicKey,
lamports: 1 * LAMPORTS_PER_SOL,
})
// Create and configure transaction
const transaction = new Transaction().add(...instructions)
const { blockhash } = await connection.getLatestBlockhash()
transaction.recentBlockhash = blockhash
transaction.feePayer = userPublicKey
// Sign with ephemeral signers first, then with your wallet
transaction.sign(...signers)
// ... sign with wallet and send transactionStake to specific validators:
const validatorVoteAccount = new PublicKey('VALIDATOR_VOTE_ACCOUNT')
const { instructions, signers } = await client.depositSol({
from: userPublicKey,
lamports: 5 * LAMPORTS_PER_SOL,
directVote: validatorVoteAccount, // Direct stake to this validator
})Unstake pool token to receive SOL:
// Amount is in pool tokens, not SOL
const poolTokensToBurn = 10
const { instructions, signers } = await client.withdrawSol({
from: userPublicKey,
amount: poolTokensToBurn,
})
// Create transaction (same pattern as deposit)
const transaction = new Transaction().add(...instructions)
// ... configure, sign, and sendReceive a delegated stake account:
const { instructions, signers } = await client.withdrawStake({
from: userPublicKey,
amount: poolTokensToBurn,
})Query direct stake positions by wallet or validator:
// By wallet
const directStakes = await client.getDirectStakes({
wallet: userPublicKey,
})
// By validator
const validatorStakes = await client.getDirectStakes({
vote: validatorVoteAccount,
})Add custom configuration:
import { STAKE_POOL_PROGRAM_ID } from '@solana/spl-stake-pool'
const client = new JPoolClient(connection, {
poolAddress: new PublicKey('CUSTOM_POOL_ADDRESS'),
programId: STAKE_POOL_PROGRAM_ID,
refCode: 'YOUR_REFERRAL_CODE', // Optional referral tracking
})Update configuration:
// Update individual options
client.configure('refCode', 'NEW_REFERRAL_CODE')All transaction-building methods return { instructions, signers } where:
instructions: Array of transaction instructions to add to your transaction.signers: Ephemeral keypairs that must sign the transaction along with your wallet.
You must:
- Create a
Transactionand add the instructions. - Set the transaction's
recentBlockhashandfeePayer. - Sign with ephemeral signers:
transaction.sign(...signers). - Sign with your wallet (e.g., Phantom, Solflare).
- Send the transaction to the network.
When withdrawing, the amount parameter is in pool tokens, not SOL:
// Calculate SOL you'll receive
const poolInfo = await client.poolInfo()
const rate = client.poolTokenRate(poolInfo)
const expectedSOL = poolTokenAmount * rateAll operations have fees that are automatically deducted:
- Deposit fee: Applied when depositing SOL.
- Withdrawal fee: Applied when withdrawing SOL or unstaking.
Check current fees:
const poolInfo = await client.poolInfo()
console.log('Deposit fee:', poolInfo.solDepositFee * 100, '%')
console.log('Withdrawal fee:', poolInfo.solWithdrawalFee * 100, '%')See the example/ directory for complete working examples:
example/deposit.ts: Deposit operations and calculations.example/withdraw.ts: Withdrawal operations and balance checking.example/info.ts: Inspect pool state and relations.
Run examples:
npx tsx example/deposit.ts
npx tsx example/withdraw.ts
npx tsx example/info.tsimport { POOL_ADDRESS, POOL_MINT_ADDRESS } from '@jpool/sdk'
console.log('Pool address:', POOL_ADDRESS.toBase58())
console.log('Pool token mint:', POOL_MINT_ADDRESS.toBase58())| Method | Returns | Description |
|---|---|---|
poolInfo() |
Promise<StakePoolInfo> |
Get current pool state and statistics |
poolTokenRate(poolInfo) |
number |
Lamports per pool token exchange rate |
reserveBalance(poolInfo) |
Promise<number> |
Get current reserve balance in lamports |
depositSol(props) |
Promise<{ instructions, signers }> |
Deposit SOL into the pool |
depositStake(props) |
Promise<{ instructions, signers }> |
Delegate a stake account to the pool |
withdrawSol(props) |
Promise<{ instructions, signers }> |
Withdraw SOL from the pool |
withdrawStake(props) |
Promise<{ instructions, signers }> |
Withdraw as a delegated stake account |
getDirectStakes(query) |
Promise<DirectStakeRecord[]> |
Query direct stake records |
getWalletBindings(query) |
Promise<WalletBinding[]> |
Query wallet binding records |
- JPool website: https://jpool.one
- JPool documentation: https://docs.jpool.one
MIT