Skip to main content
Create a new borrow position in a Jupiter Lend vault. You must create a position before you can deposit collateral, borrow, withdraw, or repay. The SDK returns a single instruction; the transaction uses a legacy (non-versioned) format.

Create Position

1

Import Dependencies

Import the required packages for Solana RPC communication, Jupiter Lend borrow SDK, and transaction building.
import {
  Connection,
  Keypair,
  Transaction,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import { getInitPositionIx } from "@jup-ag/lend/borrow";
import fs from "fs";
import path from "path";
@solana/web3.js provides RPC connection and transaction types. @jup-ag/lend/borrow exposes getInitPositionIx for creating a new position in a vault.
2

Load Keypair and Initialise Connection

Load the signer keypair and create the Solana RPC connection.
const KEYPAIR_PATH = "/path/to/your/keypair.json";
const RPC_URL = "https://api.mainnet-beta.solana.com";
const VAULT_ID = 1;

function loadKeypair(keypairPath: string): Keypair {
  const fullPath = path.resolve(keypairPath);
  const secret = JSON.parse(fs.readFileSync(fullPath, "utf8"));
  return Keypair.fromSecretKey(new Uint8Array(secret));
}

const userKeypair = loadKeypair(KEYPAIR_PATH);
const connection = new Connection(RPC_URL, { commitment: "confirmed" });
const signer = userKeypair.publicKey;
Set VAULT_ID to the target vault (market). Vault IDs are protocol-specific; check Jupiter or the vault list for your market.
3

Build Create Position Instruction

Call the SDK to get the instruction that creates a new position and returns the new position ID (nftId).
const { ix, nftId } = await getInitPositionIx({
  vaultId: VAULT_ID,
  connection,
  signer,
});
getInitPositionIx mints a position NFT for the vault. Save nftId; you use it as positionId for Deposit, Borrow, Withdraw, and Repay.
4

Build and Sign Transaction

Build a legacy transaction with the create-position instruction.
const latestBlockhash = await connection.getLatestBlockhash();
const transaction = new Transaction({
  feePayer: signer,
  ...latestBlockhash,
});
transaction.add(ix);
5

Send and Confirm Transaction

Sign and send the transaction, then confirm.
const signature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [userKeypair]
);

console.log("Create position successful! Position ID (nftId):", nftId);
console.log("Signature:", signature);
Use the printed nftId as POSITION_ID in Deposit, Borrow, Withdraw, and Repay scripts.
A position is an NFT that represents your borrow account in one vault. One position holds collateral (supply) and debt (borrow) in that vault. You need one position per vault before you can deposit or borrow.
You can skip a separate Create Position step by using getOperateIx with positionId: 0. The SDK batches init position and the first operate (deposit or borrow) in a single transaction. The returned nftId is your new position ID for future operations. See Deposit for an example.
After creating a position, Deposit collateral, then Borrow. Use Withdraw to remove collateral and Repay to reduce debt.

Full code example

import {
    Connection,
    Keypair,
    Transaction,
    sendAndConfirmTransaction,
} from "@solana/web3.js";
import { getInitPositionIx } from "@jup-ag/lend/borrow";
import fs from "fs";
import path from "path";

const KEYPAIR_PATH = "/path/to/your/keypair.json"; // Path to your local keypair file (update this path)
const RPC_URL = "https://api.mainnet-beta.solana.com"; // RPC endpoint
const VAULT_ID = 1; // Target vault (market); check protocol docs for vault IDs

function loadKeypair(keypairPath: string): Keypair {
    const fullPath = path.resolve(keypairPath);
    const secret = JSON.parse(fs.readFileSync(fullPath, "utf8"));
    return Keypair.fromSecretKey(new Uint8Array(secret));
}

// 1. Load user keypair and establish connection
const userKeypair = loadKeypair(KEYPAIR_PATH);
const connection = new Connection(RPC_URL, { commitment: "confirmed" });
const signer = userKeypair.publicKey;

// 2. Get create-position instruction from SDK
const { ix, nftId } = await getInitPositionIx({
    vaultId: VAULT_ID,
    connection,
    signer,
});

// 3. Build the transaction with latest blockhash and add create-position instruction
// This prepares the transaction ready to be signed and sent (legacy transaction)
const latestBlockhash = await connection.getLatestBlockhash();
const transaction = new Transaction({
    feePayer: signer,
    ...latestBlockhash,
});
transaction.add(ix);

// 4. Sign and send the transaction
const signature = await sendAndConfirmTransaction(connection, transaction, [userKeypair]);
console.log("Create position successful! Position ID (nftId):", nftId);
console.log("Signature:", signature);