|
| 1 | +--- |
| 2 | +sidebar_label: "Lend SDK" |
| 3 | +description: "SDK for Jupiter Lend." |
| 4 | +title: "Lend SDK" |
| 5 | +--- |
| 6 | + |
| 7 | +<head> |
| 8 | + <title>Jupiter Lend SDK</title> |
| 9 | + <meta name="twitter:card" content="summary" /> |
| 10 | +</head> |
| 11 | + |
| 12 | +The Jupiter Lend SDK provides a TypeScript interface for interacting with the Jupiter lending protocol. This documentation covers two main integration approaches: getting instruction objects for direct use and getting account contexts for Cross-Program Invocation (CPI) integrations. |
| 13 | + |
| 14 | +## Installation |
| 15 | + |
| 16 | +```bash |
| 17 | +npm install @jup-ag/lend |
| 18 | +``` |
| 19 | + |
| 20 | +## Setup |
| 21 | + |
| 22 | +```typescript |
| 23 | +import { |
| 24 | + Connection, |
| 25 | + Keypair, |
| 26 | + PublicKey, |
| 27 | + TransactionMessage, |
| 28 | + TransactionInstruction, |
| 29 | + VersionedTransaction |
| 30 | +} from "@solana/web3.js"; |
| 31 | +import { |
| 32 | + getDepositIx, getWithdrawIx, // get instructions |
| 33 | + getDepositContext, getWithdrawContext, // get context accounts for CPI |
| 34 | +} from "@jup-ag/lend/earn"; |
| 35 | +import { BN } from "bn.js"; |
| 36 | + |
| 37 | +const connection = new Connection("https://api.mainnet-beta.solana.com"); |
| 38 | +const signer = Keypair.fromSecretKey(new Uint8Array(privateKey)); |
| 39 | + |
| 40 | +// Example asset mints |
| 41 | +const usdc = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC mainnet |
| 42 | +``` |
| 43 | + |
| 44 | +--- |
| 45 | + |
| 46 | +## Instruction |
| 47 | + |
| 48 | +### Get Deposit Instruction |
| 49 | + |
| 50 | +```typescript |
| 51 | +const depositIx = await getDepositIx({ |
| 52 | + amount: new BN(1000000), // amount in token decimals (1 USDC) |
| 53 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // asset mint address |
| 54 | + signer: signer.publicKey, // signer public key |
| 55 | + connection, // Solana connection |
| 56 | + cluster: "mainnet", |
| 57 | +}); |
| 58 | +``` |
| 59 | + |
| 60 | +### Get Withdraw Instruction |
| 61 | + |
| 62 | +```typescript |
| 63 | +const withdrawIx = await getWithdrawIx({ |
| 64 | + amount: new BN(1000000), // amount in token decimals (1 USDC) |
| 65 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // asset mint address |
| 66 | + signer: signer.publicKey, // signer public key |
| 67 | + connection, // Solana connection |
| 68 | + cluster: "mainnet", |
| 69 | +}); |
| 70 | +``` |
| 71 | + |
| 72 | +### Example Instruction Usage |
| 73 | + |
| 74 | +```typescript |
| 75 | +import { |
| 76 | + Connection, |
| 77 | + Keypair, |
| 78 | + PublicKey, |
| 79 | + TransactionMessage, |
| 80 | + Transaction, |
| 81 | + TransactionInstruction, |
| 82 | + VersionedTransaction |
| 83 | +} from "@solana/web3.js"; |
| 84 | +import { |
| 85 | + getDepositIx, |
| 86 | +} from "@jup-ag/lend/earn"; |
| 87 | +import { BN } from "bn.js"; |
| 88 | + |
| 89 | +const signer = Keypair.fromSecretKey(new Uint8Array(privateKey)); |
| 90 | +const connection = new Connection('https://api.mainnet-beta.solana.com'); |
| 91 | + |
| 92 | +// Get deposit instruction |
| 93 | +const depositIx = await getDepositIx({ |
| 94 | + amount: new BN(1000000), // amount in token decimals (1 USDC) |
| 95 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // asset mint address |
| 96 | + signer: signer.publicKey, // signer public key |
| 97 | + connection, // Solana connection |
| 98 | + cluster: "mainnet", |
| 99 | +}); |
| 100 | + |
| 101 | +// Convert the raw instruction to TransactionInstruction |
| 102 | +const instruction = new TransactionInstruction({ |
| 103 | + programId: new PublicKey(depositIx.programId), |
| 104 | + keys: depositIx.keys.map((key) => ({ |
| 105 | + pubkey: new PublicKey(key.pubkey), |
| 106 | + isSigner: key.isSigner, |
| 107 | + isWritable: key.isWritable, |
| 108 | + })), |
| 109 | + data: Buffer.from(depositIx.data), |
| 110 | +}); |
| 111 | + |
| 112 | +const latestBlockhash = await connection.getLatestBlockhash(); |
| 113 | +const messageV0 = new TransactionMessage({ |
| 114 | + payerKey: signer.publicKey, |
| 115 | + recentBlockhash: latestBlockhash.blockhash, |
| 116 | + instructions: [instruction], |
| 117 | +}).compileToV0Message(); |
| 118 | + |
| 119 | +const transaction = new VersionedTransaction(messageV0); |
| 120 | +transaction.sign([signer]); |
| 121 | +const serializedTransaction = transaction.serialize(); |
| 122 | +const blockhashInfo = await connection.getLatestBlockhashAndContext({ commitment: "finalized" }); |
| 123 | + |
| 124 | +const signature = await connection.sendRawTransaction(serializedTransaction); |
| 125 | +console.log(`https://solscan.io/tx/${signature}`); |
| 126 | +``` |
| 127 | + |
| 128 | +## CPI |
| 129 | + |
| 130 | +For Anchor programs that need to make CPI calls to Jupiter Lend, use the context methods. |
| 131 | + |
| 132 | +### Deposit Context Accounts |
| 133 | + |
| 134 | +```typescript |
| 135 | +const depositContext = await getDepositContext({ |
| 136 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // asset mint address |
| 137 | + signer: signer.publicKey, // signer public key |
| 138 | + connection, |
| 139 | +}); |
| 140 | +``` |
| 141 | + |
| 142 | +<details> |
| 143 | + <summary> |
| 144 | + <div> |
| 145 | + <div> |
| 146 | + <b>Deposit Context Accounts Table</b> |
| 147 | + </div> |
| 148 | + </div> |
| 149 | + </summary> |
| 150 | + |
| 151 | +| Account | Purpose | |
| 152 | +| ---------------------------------- | ---------------------------------------- | |
| 153 | +| `signer` | User's wallet public key | |
| 154 | +| `depositorTokenAccount` | User's underlying token account (source) | |
| 155 | +| `recipientTokenAccount` | User's fToken account (destination) | |
| 156 | +| `mint` | Underlying token mint | |
| 157 | +| `lendingAdmin` | Protocol configuration PDA | |
| 158 | +| `lending` | Pool-specific configuration PDA | |
| 159 | +| `fTokenMint` | fToken mint account | |
| 160 | +| `supplyTokenReservesLiquidity` | Liquidity protocol token reserves | |
| 161 | +| `lendingSupplyPositionOnLiquidity` | Protocol's position in liquidity pool | |
| 162 | +| `rateModel` | Interest rate calculation model | |
| 163 | +| `vault` | Protocol vault holding deposited tokens | |
| 164 | +| `liquidity` | Main liquidity protocol PDA | |
| 165 | +| `liquidityProgram` | Liquidity protocol program ID | |
| 166 | +| `rewardsRateModel` | Rewards calculation model PDA | |
| 167 | +</details> |
| 168 | + |
| 169 | +### Withdraw Context Accounts |
| 170 | + |
| 171 | +```typescript |
| 172 | +const withdrawContext = await getWithdrawContext({ |
| 173 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // asset mint address |
| 174 | + signer: signer.publicKey, // signer public key |
| 175 | + connection, |
| 176 | +}); |
| 177 | +``` |
| 178 | + |
| 179 | +<details> |
| 180 | + <summary> |
| 181 | + <div> |
| 182 | + <div> |
| 183 | + <b>Withdraw Context Accounts Table</b> |
| 184 | + </div> |
| 185 | + </div> |
| 186 | + </summary> |
| 187 | +Similar to deposit context, but includes: |
| 188 | + |
| 189 | +- `ownerTokenAccount`: User's fToken account (source of fTokens to burn) |
| 190 | +- `claimAccount`: Additional account for withdrawal claim processing |
| 191 | + |
| 192 | +| Account | Purpose | |
| 193 | +| ---------------------------------- | ---------------------------------------- | |
| 194 | +| `signer` | User's wallet public key | |
| 195 | +| `ownerTokenAccount` | User's underlying token account (source) | |
| 196 | +| `recipientTokenAccount` | User's fToken account (destination) | |
| 197 | +| `claimAccount` | Additional account for withdrawal | |
| 198 | +| `mint` | Underlying token mint | |
| 199 | +| `lendingAdmin` | Protocol configuration PDA | |
| 200 | +| `lending` | Pool-specific configuration PDA | |
| 201 | +| `fTokenMint` | fToken mint account | |
| 202 | +| `supplyTokenReservesLiquidity` | Liquidity protocol token reserves | |
| 203 | +| `lendingSupplyPositionOnLiquidity` | Protocol's position in liquidity pool | |
| 204 | +| `rateModel` | Interest rate calculation model | |
| 205 | +| `vault` | Protocol vault holding deposited tokens | |
| 206 | +| `liquidity` | Main liquidity protocol PDA | |
| 207 | +| `liquidityProgram` | Liquidity protocol program ID | |
| 208 | +| `rewardsRateModel` | Rewards calculation model PDA | |
| 209 | +</details> |
| 210 | + |
| 211 | +### Example CPI Usage |
| 212 | + |
| 213 | +```typescript |
| 214 | +const depositContext = await getDepositContext({ |
| 215 | + asset: usdcMint, |
| 216 | + signer: userPublicKey, |
| 217 | +}); |
| 218 | + |
| 219 | +// Pass these accounts to your Anchor program |
| 220 | +await program.methods |
| 221 | + .yourDepositMethod(amount) |
| 222 | + .accounts({ |
| 223 | + // Your program accounts |
| 224 | + userAccount: userAccount, |
| 225 | + |
| 226 | + // Jupiter Lend accounts (from context) |
| 227 | + signer: depositContext.signer, |
| 228 | + depositorTokenAccount: depositContext.depositorTokenAccount, |
| 229 | + recipientTokenAccount: depositContext.recipientTokenAccount, |
| 230 | + lendingAdmin: depositContext.lendingAdmin, |
| 231 | + lending: depositContext.lending, |
| 232 | + fTokenMint: depositContext.fTokenMint, |
| 233 | + // ... all other accounts from context |
| 234 | + |
| 235 | + lendingProgram: new PublicKey( |
| 236 | + "jup3YeL8QhtSx1e253b2FDvsMNC87fDrgQZivbrndc9" |
| 237 | + ), |
| 238 | + }) |
| 239 | + .rpc(); |
| 240 | +``` |
| 241 | + |
| 242 | +--- |
| 243 | + |
| 244 | +## Read Functions |
| 245 | + |
| 246 | +The Jupiter Lend SDK provides several read functions to query protocol data and user positions, this can be helpful to display on your frontend. |
| 247 | + |
| 248 | +### Get All Lending Tokens |
| 249 | + |
| 250 | +Retrieves all available lending tokens in the Jupiter Lend Earn protocol. |
| 251 | + |
| 252 | +:::note |
| 253 | +The `getLendingTokens` function returns an array of `PublicKey` objects. |
| 254 | +::: |
| 255 | + |
| 256 | +```typescript |
| 257 | +import { getLendingTokens } from "@jup-ag/lend/earn"; |
| 258 | + |
| 259 | +const allTokens = await getLendingTokens({ connection }); |
| 260 | +``` |
| 261 | +```typescript |
| 262 | +[ |
| 263 | + PublicKey, |
| 264 | + PublicKey, |
| 265 | + ... |
| 266 | +] |
| 267 | +``` |
| 268 | + |
| 269 | +### Get Token Details |
| 270 | + |
| 271 | +Fetches detailed information about a specific lending token. |
| 272 | + |
| 273 | +```typescript |
| 274 | +import { getLendingTokenDetails } from "@jup-ag/lend/earn"; |
| 275 | + |
| 276 | +const tokenDetails = await getLendingTokenDetails({ |
| 277 | + lendingToken: new PublicKey("9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D"), // allTokens[x] from the previous example |
| 278 | + connection, |
| 279 | +}); |
| 280 | +``` |
| 281 | +```typescript |
| 282 | +{ |
| 283 | + id: number; // ID of jlToken, starts from 1 |
| 284 | + address: PublicKey; // Address of jlToken |
| 285 | + asset: PublicKey; // Address of underlying asset |
| 286 | + decimals: number; // Decimals of asset (same as jlToken decimals) |
| 287 | + totalAssets: BN; // Total underlying assets in the pool |
| 288 | + totalSupply: BN; // Total shares supply |
| 289 | + convertToShares: BN; // Multiplier to convert assets to shares |
| 290 | + convertToAssets: BN; // Multiplier to convert shares to assets |
| 291 | + rewardsRate: BN; // Rewards rate (1e4 decimals, 1e4 = 100%) |
| 292 | + supplyRate: BN; // Supply APY rate (1e4 decimals, 1e4 = 100%) |
| 293 | +} |
| 294 | +``` |
| 295 | + |
| 296 | +### Get User Position |
| 297 | + |
| 298 | +Retrieves a user's lending position for a specific asset: |
| 299 | + |
| 300 | +```typescript |
| 301 | +import { getUserLendingPositionByAsset } from "@jup-ag/lend/earn"; |
| 302 | + |
| 303 | +const userPosition = await getUserLendingPositionByAsset({ |
| 304 | + asset: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // The address of underlying asset or tokenDetails.asset |
| 305 | + user: signer.publicKey, // User's wallet address |
| 306 | + connection, |
| 307 | +}); |
| 308 | +``` |
| 309 | +```typescript |
| 310 | +{ |
| 311 | + lendingTokenShares: BN; // User's shares in jlToken |
| 312 | + underlyingAssets: BN; // User's underlying assets |
| 313 | + underlyingBalance: BN; // User's underlying balance |
| 314 | +} |
| 315 | +``` |
0 commit comments