@jpool/sdk
v0.1.1
Published
TypeScript SDK for interacting with the JPool Solana liquid staking pool.
Readme
JPool TypeScript SDK
TypeScript SDK for interacting with the JPool Solana liquid staking pool.
Installation
npm install @jpool/sdk
# or
pnpm add @jpool/sdk
# or
yarn add @jpool/sdkQuick Start
import { 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')Features
- Deposit SOL - Stake SOL and receive LST pool tokens
- Withdraw SOL - Unstake SOL instantly
- Direct Staking - Stake to specific validators
- Pool Information - Query pool state, rates, and fees
- Balance Tracking - Check direct stakes and wallet bindings
Usage
Deposit SOL
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 transactionDeposit with Direct Staking
Support a specific validator while maintaining pool token liquidity:
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
})Withdraw 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 sendWithdraw Stake Account
Receive a delegated stake account instead of liquid SOL:
const { instructions, signers } = await client.withdrawStake({
from: userPublicKey,
amount: poolTokensToBurn,
})Get Direct Stakes
Query your direct stake positions:
const directStakes = await client.getDirectStakes({
wallet: userPublicKey,
})
// Or query by validator
const validatorStakes = await client.getDirectStakes({
vote: validatorVoteAccount,
})Configuration
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')API Reference
JPoolClient
Methods
poolInfo(): Promise<StakePoolInfo>- Get current pool state and statisticspoolTokenRate(poolInfo): number- Calculate lamports per pool token exchange ratereserveBalance(poolInfo): Promise<number>- Get current reserve balancedepositSol(props): Promise<{instructions, signers}>- Deposit SOL into the pooldepositStake(props): Promise<{instructions, signers}>- Deposit stake account into the poolwithdrawSol(props): Promise<{instructions, signers}>- Withdraw SOL from the poolwithdrawStake(props): Promise<{instructions, signers}>- Withdraw as stake accountgetDirectStakes(query): Promise<any>- Query direct stake recordsgetWalletBindings(query): Promise<any>- Query wallet bindings
Important Notes
Transaction Signing
All SDK 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
Pool Token Amounts
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 * rateFees
All operations have fees that are automatically deducted:
- Deposit fee: Applied when depositing SOL
- Withdrawal fee: Applied when withdrawing SOL or stake
Check current fees:
const poolInfo = await client.poolInfo()
console.log('Deposit fee:', poolInfo.solDepositFee * 100, '%')
console.log('Withdrawal fee:', poolInfo.solWithdrawalFee * 100, '%')Examples
See the example/ directory for complete working examples:
example/deposit.ts- Deposit operations and calculationsexample/withdraw.ts- Withdrawal operations and balance checking
Run examples:
npx tsx example/deposit.ts
npx tsx example/withdraw.tsConstants
import { POOL_ADDRESS, POOL_MINT_ADDRESS } from '@jpool/sdk'
console.log('Pool address:', POOL_ADDRESS.toBase58())
console.log('Pool token mint:', POOL_MINT_ADDRESS.toBase58())Links
License
MIT
