Borrow nUSD
Deposit collateral
Initialize a borrow position and deposit a supported collateral token.
A deposit creates the owner's vault PDA if needed and transfers collateral into the canonical market vault. It does not create debt and does not require an oracle update.
Requirements
- Load the client from Project setup.
- Select a market by its unique
symbol, not its display ticker. - Read the collateral mint's configured decimals.
- Confirm the owner has enough tokens in the associated token account.
- Read the live collateral config and reject paused deposits or insufficient cap.
TypeScript example
import { BN } from "@coral-xyz/anchor";
import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js";
import { getAccount } from "@solana/spl-token";
import {
type NestClient,
ata,
borrowVaultPda,
marketBySymbol,
simulateSignSend,
toBaseUnits,
} from "../nest-client";
export async function depositCollateral(
client: NestClient,
symbol: string,
userAmount: string,
) {
const owner = client.wallet.publicKey;
const market = marketBySymbol(client, symbol);
const coreProgramId = new PublicKey(client.deployment.programs.nestCore);
const protocol = new PublicKey(client.deployment.accounts.protocol);
const collateralConfig = new PublicKey(market.collateralConfig);
const collateralMint = new PublicKey(market.mint);
const collateralVault = new PublicKey(market.collateralVault);
const collateralTokenProgram = new PublicKey(market.tokenProgram);
const ownerCollateralAccount = ata(collateralMint, owner, collateralTokenProgram);
const vault = borrowVaultPda(coreProgramId, owner, collateralConfig);
const amount = toBaseUnits(userAmount, market.decimals);
if (amount <= 0n) throw new Error("Deposit amount must be positive");
// Validate the manifest against current on-chain configuration.
const config = await client.core.account.collateralConfig.fetch(collateralConfig);
if (!config.collateralMint.equals(collateralMint)) throw new Error("Collateral mint mismatch");
if (!config.collateralVault.equals(collateralVault)) throw new Error("Collateral vault mismatch");
if (!config.tokenProgram.equals(collateralTokenProgram)) throw new Error("Token program mismatch");
if (config.collateralDecimals !== market.decimals) throw new Error("Collateral decimals mismatch");
if (config.depositsPaused) throw new Error(`${symbol} deposits are paused`);
const totalAfter = BigInt(config.totalDepositsRaw.toString()) + amount;
if (totalAfter > BigInt(config.depositCapRaw.toString())) {
throw new Error(`${symbol} deposit cap would be exceeded`);
}
const ownerToken = await getAccount(
client.connection,
ownerCollateralAccount,
"confirmed",
collateralTokenProgram,
);
if (ownerToken.amount < amount) {
throw new Error(`Insufficient ${symbol}: need ${amount}, have ${ownerToken.amount}`);
}
const transaction = new Transaction();
const existingVault = await client.core.account.vault.fetchNullable(vault);
if (!existingVault) {
transaction.add(await client.core.methods
.initializeVault()
.accountsStrict({
collateralConfig,
vault,
owner,
systemProgram: SystemProgram.programId,
})
.instruction());
}
transaction.add(await client.core.methods
.deposit(new BN(amount.toString()))
.accountsStrict({
protocol,
collateralConfig,
vault,
collateralMint,
ownerCollateralAccount,
collateralVault,
owner,
collateralTokenProgram,
})
.instruction());
const collateralBefore = existingVault
? BigInt(existingVault.collateralRaw.toString())
: 0n;
const signature = await simulateSignSend(client, transaction);
// Do not trust submission alone. Verify the position account changed.
const vaultAfter = await client.core.account.vault.fetch(vault);
const collateralAfter = BigInt(vaultAfter.collateralRaw.toString());
if (collateralAfter !== collateralBefore + amount) {
throw new Error(`Deposit verification failed for ${signature}`);
}
return { signature, vault, collateralRaw: collateralAfter };
}Errors
PausedorCollateralPaused: the protocol or market is not accepting deposits.DepositCapExceeded: the market has insufficient remaining deposit capacity.- Token-account constraint failure: mint, owner, token program, or custody vault does not match the collateral config.
- Insufficient token balance: the wallet cannot transfer the requested raw amount.
After confirmation, move to Mint nUSD.