Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.exponent.finance/llms.txt

Use this file to discover all available pages before exploring further.

Use these instructions when your strategy vault should run a collateralized borrow position on Jupiter Lend Borrow. For Jupiter’s deposit-only Earn product, see Jupiter Lend Earn instructions. A vault interacts with Jupiter Borrow in three lifecycle phases:
  1. InitinitPosition creates the borrow position once per vaultId.
  2. Operate — semantic helpers (depositCollateral, borrowDebt, repayDebt, withdrawCollateral, plus four paired ops) move collateral and debt against an existing position.
  3. RefreshupdateExchangePrices is occasionally needed to refresh oracle state before an operate call lands.
The semantic operate helpers are the recommended path. They take positive amounts and encode the correct signed newCol / newDebt deltas internally. The low-level createJupiterBorrowOperateInstruction is available for callers that need raw signed control.

Transaction structure

Every Jupiter Borrow action goes through createVaultSyncTransaction.
import {
  createVaultSyncTransaction,
  createJupiterBorrowDepositCollateralInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";
import { Transaction, sendAndConfirmTransaction } from "@solana/web3.js";

const depositIx = createJupiterBorrowDepositCollateralInstruction(operateAccounts, 100_000_000n);

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      jupiterBorrowAction.depositCollateral({
        instruction: depositIx,
        vaultId: 1,
      }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);
PartWhat it contains
setupInstructionsSetup instructions that must run before refreshes or the sync step
preInstructionsPermissionless refresh instructions that must run before the sync step
instructionThe Squads sync transaction instruction wrapping the vault-signed Jupiter Borrow action
postInstructionsPermissionless refresh instructions that must run after the sync step

Init position

createJupiterBorrowInitPositionInstruction(accounts, args, programId?) creates the borrow position. Run once per vaultId before any operate calls.
import {
  createJupiterBorrowInitPositionInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";

const initIx = createJupiterBorrowInitPositionInstruction(initAccounts, {
  vaultId: 1,
  nextPositionId: 0,
});

jupiterBorrowAction.initPosition({ instruction: initIx });

Parameters

NameTypeDescription
accountsJupiterBorrowInitPositionAccountsInit account set
args.vaultIdnumberJupiter borrow vault id
args.nextPositionIdnumberNext position id for this vault
programIdPublicKeyOptional. Override the Jupiter Borrow program id

Operate accounts

All eight semantic operate helpers share the JupiterBorrowOperateAccounts shape. Build it once and reuse across calls in the same flow.
import type { JupiterBorrowOperateAccounts } from "@exponent-labs/exponent-sdk";
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";

const operateAccounts: JupiterBorrowOperateAccounts = {
  signer: vaultPda,                  // Squads vault PDA
  position: positionPda,             // The borrow position PDA created by initPosition
  vault: jupiterVault,               // Jupiter Borrow vault account
  supplyMint: collateralMint,
  borrowMint: debtMint,
  // ... remaining required accounts (oracles, token programs, vault PDAs).
  // See JupiterBorrowOperateAccounts in @exponent-labs/exponent-sdk for the full shape.
};
Refer to JupiterBorrowOperateAccounts in your TypeScript intellisense or in the SDK source for the complete list of required accounts. JUPITER_BORROW_ACCOUNT_INDICES exposes the on-chain index of each account if you need it for custom policy work.

Deposit collateral

createJupiterBorrowDepositCollateralInstruction(accounts, collateralAmount) increases collateral by a positive amount.
import {
  createJupiterBorrowDepositCollateralInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";

const depositIx = createJupiterBorrowDepositCollateralInstruction(operateAccounts, 100_000_000n);

jupiterBorrowAction.depositCollateral({ instruction: depositIx, vaultId: 1 });

Parameters

NameTypeDescription
accountsJupiterBorrowOperateAccountsOperate account set
collateralAmountbigint | number | string | BNPositive amount of collateral to deposit

Borrow debt

createJupiterBorrowBorrowDebtInstruction(accounts, debtAmount) increases debt by a positive amount.
import { createJupiterBorrowBorrowDebtInstruction, jupiterBorrowAction } from "@exponent-labs/exponent-sdk";

const borrowIx = createJupiterBorrowBorrowDebtInstruction(operateAccounts, 50_000_000n);

jupiterBorrowAction.borrowDebt({ instruction: borrowIx, vaultId: 1 });

Parameters

NameTypeDescription
accountsJupiterBorrowOperateAccountsOperate account set
debtAmountbigint | number | string | BNPositive amount of debt to borrow

Repay debt

createJupiterBorrowRepayDebtInstruction(accounts, debtAmount) decreases debt by a positive amount. The helper negates the value internally — pass a positive number.
import { createJupiterBorrowRepayDebtInstruction, jupiterBorrowAction } from "@exponent-labs/exponent-sdk";

const repayIx = createJupiterBorrowRepayDebtInstruction(operateAccounts, 25_000_000n);

jupiterBorrowAction.repayDebt({ instruction: repayIx, vaultId: 1 });

Parameters

NameTypeDescription
accountsJupiterBorrowOperateAccountsOperate account set
debtAmountbigint | number | string | BNPositive amount of debt to repay

Withdraw collateral

createJupiterBorrowWithdrawCollateralInstruction(accounts, collateralAmount) decreases collateral by a positive amount. The helper negates internally.
import { createJupiterBorrowWithdrawCollateralInstruction, jupiterBorrowAction } from "@exponent-labs/exponent-sdk";

const withdrawIx = createJupiterBorrowWithdrawCollateralInstruction(operateAccounts, 50_000_000n);

jupiterBorrowAction.withdrawCollateral({ instruction: withdrawIx, vaultId: 1 });

Parameters

NameTypeDescription
accountsJupiterBorrowOperateAccountsOperate account set
collateralAmountbigint | number | string | BNPositive amount of collateral to withdraw

Paired operations

Four paired helpers move collateral and debt in a single instruction. All amounts are positive — the helper applies the correct signs.
HelperNet effect
createJupiterBorrowDepositAndBorrowInstruction+collateral, +debt
createJupiterBorrowRepayAndWithdrawInstruction−collateral, −debt
createJupiterBorrowDepositAndRepayInstruction+collateral, −debt
createJupiterBorrowWithdrawAndBorrowInstruction−collateral, +debt
import {
  createJupiterBorrowDepositAndBorrowInstruction,
  createJupiterBorrowRepayAndWithdrawInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";

const depositAndBorrowIx = createJupiterBorrowDepositAndBorrowInstruction(operateAccounts, {
  collateralAmount: 100_000_000n,
  debtAmount: 50_000_000n,
});

const repayAndWithdrawIx = createJupiterBorrowRepayAndWithdrawInstruction(operateAccounts, {
  debtAmount: 25_000_000n,
  collateralAmount: 60_000_000n,
});

jupiterBorrowAction.depositAndBorrow({ instruction: depositAndBorrowIx, vaultId: 1 });
jupiterBorrowAction.repayAndWithdraw({ instruction: repayAndWithdrawIx, vaultId: 1 });

Parameters

NameTypeDescription
accountsJupiterBorrowOperateAccountsOperate account set
params.collateralAmountbigint | number | string | BNPositive collateral magnitude
params.debtAmountbigint | number | string | BNPositive debt magnitude

Action wrapper options

All operate helpers wrap with jupiterBorrowAction.<method>({ instruction, vaultId }). The wrappers accept four optional fields beyond the required two:
FieldTypeDescription
preInstructionsTransactionInstruction[]Optional. Extra refresh/setup instructions to fold into the sync transaction’s pre-block
aumAccountsAccountMeta[]Optional. AUM account metas the SDK should append for AUM tracking on this op
addressLookupTableAddressesPublicKey[]Optional. Address Lookup Table addresses to attach to the resulting V0 message
vaultIdnumberRequired for everything except initPosition. The Jupiter borrow vault id

Low-level operate

For callers that need raw signed control over newCol / newDebt, createJupiterBorrowOperateInstruction is available. The semantic helpers above are layered on top — prefer them unless you have a specific reason to encode signed deltas yourself.
import {
  createJupiterBorrowOperateInstruction,
  encodeJupiterBorrowI128Le,
} from "@exponent-labs/exponent-sdk";

const ix = createJupiterBorrowOperateInstruction(operateAccounts, {
  newCol: 100_000_000n,    // +100 collateral
  newDebt: -25_000_000n,   // −25 debt (signed)
});
encodeJupiterBorrowI128Le(value, label?) is the same signed i128 encoder the SDK uses internally for the newCol / newDebt fields and is exposed for callers writing custom policy data constraints.

Update exchange prices

createJupiterBorrowUpdateExchangePricesInstruction(accounts, args) refreshes oracle state for a Jupiter Borrow vault. Use the convenience variant when you already have an operate instruction in hand:
import {
  createJupiterBorrowUpdateExchangePricesInstruction,
  createJupiterBorrowUpdateExchangePricesInstructionFromOperateAccounts,
} from "@exponent-labs/exponent-sdk";

const refreshIx = createJupiterBorrowUpdateExchangePricesInstruction(updateAccounts, { vaultId: 1 });

// Or derive the refresh from an existing operate instruction's accounts:
const refreshFromOperateIx =
  createJupiterBorrowUpdateExchangePricesInstructionFromOperateAccounts(operateInstruction, { vaultId: 1 });

Constants

ConstantDescription
JUPITER_LEND_BORROW_PROGRAM_IDJupiter Lend Borrow program: jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi
MPL_TOKEN_METADATA_PROGRAM_IDMetaplex Token Metadata program — used by init flows
For policy authoring or custom data-constraint work, the SDK also exports JUPITER_BORROW_DISCRIMINATORS, JUPITER_BORROW_ACCOUNT_INDICES, and JUPITER_BORROW_OPERATE_OFFSETS (offsets for newCol, newDebt, transferTypeTag inside the operate instruction data). A matching policy must exist before executing. See Jupiter Lend Borrow Policy.

Full flow example

This example creates a borrow position, deposits collateral and borrows in one step, then later repays and withdraws.

Step 1: Initialize the position

import {
  createVaultSyncTransaction,
  createJupiterBorrowInitPositionInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";
import { Transaction, sendAndConfirmTransaction } from "@solana/web3.js";

const initIx = createJupiterBorrowInitPositionInstruction(initAccounts, {
  vaultId: 1,
  nextPositionId: 0,
});

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [jupiterBorrowAction.initPosition({ instruction: initIx })],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);

Step 2: Deposit collateral and borrow in one operate

import {
  createJupiterBorrowDepositAndBorrowInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";

const operateIx = createJupiterBorrowDepositAndBorrowInstruction(operateAccounts, {
  collateralAmount: 100_000_000n,
  debtAmount: 50_000_000n,
});

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      jupiterBorrowAction.depositAndBorrow({ instruction: operateIx, vaultId: 1 }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);

Step 3: Unwind with repay-and-withdraw

import {
  createJupiterBorrowRepayAndWithdrawInstruction,
  jupiterBorrowAction,
} from "@exponent-labs/exponent-sdk";

const unwindIx = createJupiterBorrowRepayAndWithdrawInstruction(operateAccounts, {
  debtAmount: 50_000_000n,
  collateralAmount: 100_000_000n,
});

const { setupInstructions, preInstructions, instruction, postInstructions } =
  await createVaultSyncTransaction({
    instructions: [
      jupiterBorrowAction.repayAndWithdraw({ instruction: unwindIx, vaultId: 1 }),
    ],
    owner: vaultPda,
    connection,
    policyPda,
    vaultPda,
    signer: wallet.publicKey,
    vaultAddress,
  });

const tx = new Transaction().add(
  ...setupInstructions,
  ...preInstructions,
  instruction,
  ...postInstructions,
);
await sendAndConfirmTransaction(connection, tx, [wallet]);