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:
- Init —
initPosition creates the borrow position once per vaultId.
- Operate — semantic helpers (
depositCollateral, borrowDebt, repayDebt, withdrawCollateral, plus four paired ops) move collateral and debt against an existing position.
- Refresh —
updateExchangePrices 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]);
| Part | What it contains |
|---|
setupInstructions | Setup instructions that must run before refreshes or the sync step |
preInstructions | Permissionless refresh instructions that must run before the sync step |
instruction | The Squads sync transaction instruction wrapping the vault-signed Jupiter Borrow action |
postInstructions | Permissionless 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowInitPositionAccounts | Init account set |
args.vaultId | number | Jupiter borrow vault id |
args.nextPositionId | number | Next position id for this vault |
programId | PublicKey | Optional. 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowOperateAccounts | Operate account set |
collateralAmount | bigint | number | string | BN | Positive 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowOperateAccounts | Operate account set |
debtAmount | bigint | number | string | BN | Positive 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowOperateAccounts | Operate account set |
debtAmount | bigint | number | string | BN | Positive 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowOperateAccounts | Operate account set |
collateralAmount | bigint | number | string | BN | Positive 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.
| Helper | Net 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
| Name | Type | Description |
|---|
accounts | JupiterBorrowOperateAccounts | Operate account set |
params.collateralAmount | bigint | number | string | BN | Positive collateral magnitude |
params.debtAmount | bigint | number | string | BN | Positive debt magnitude |
Action wrapper options
All operate helpers wrap with jupiterBorrowAction.<method>({ instruction, vaultId }). The wrappers accept four optional fields beyond the required two:
| Field | Type | Description |
|---|
preInstructions | TransactionInstruction[] | Optional. Extra refresh/setup instructions to fold into the sync transaction’s pre-block |
aumAccounts | AccountMeta[] | Optional. AUM account metas the SDK should append for AUM tracking on this op |
addressLookupTableAddresses | PublicKey[] | Optional. Address Lookup Table addresses to attach to the resulting V0 message |
vaultId | number | Required 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
| Constant | Description |
|---|
JUPITER_LEND_BORROW_PROGRAM_ID | Jupiter Lend Borrow program: jupr81YtYssSyPt8jbnGuiWon5f6x9TcDEFxYe3Bdzi |
MPL_TOKEN_METADATA_PROGRAM_ID | Metaplex 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]);