Skip to Content

Transfers

Transfers let you move balances and positions between subaccounts owned by the same authority.

Why Use Subaccount Transfers?

Subaccounts let you isolate risk and organize trading strategies. Common use cases for transfers include:

  • Strategy isolation: Separate market making from directional trading to prevent one strategy’s losses from affecting another’s collateral
  • Risk management: Move profits from an active trading account to a safer holding account
  • Rebalancing: Redistribute collateral when one subaccount needs more margin
  • Bot separation: Isolate automated trading bots on separate subaccounts while keeping manual trades separate
  • Experimentation: Test new strategies on a subaccount with limited capital, then transfer funds if successful

All subaccounts under the same wallet share cross-margin, but transfers let you explicitly move balances and positions to reorganize your capital.

SDK Usage

Transfer a Spot Deposit Between Subaccounts

const marketIndex = 0; // e.g. USDC const amount = velocityClient.convertToSpotPrecision(marketIndex, 100); // transferDeposit(amount, marketIndex, fromSubAccountId, toSubAccountId) await velocityClient.transferDeposit(amount, marketIndex, 0, 1);
Method VelocityClient.transferDepositReference ↗
ParameterTypeRequired
amount
any
Amount to transfer, in the spot market's own token precision.
Yes
marketIndex
number
Spot market index of the balance to transfer.
Yes
fromSubAccountId
number
Sub-account id to debit.
Yes
toSubAccountId
number
Sub-account id to credit.
Yes
txParams
TxParams
Optional compute-unit/priority-fee overrides for the transaction.
No
Returns
Promise<string>

Transfer a Perp Position Between Subaccounts

import { BASE_PRECISION, BN } from "@velocity-exchange/sdk"; // transferPerpPosition(fromSubAccountId, toSubAccountId, marketIndex, amount) const amount = new BN(1).mul(BASE_PRECISION); // 1 base unit await velocityClient.transferPerpPosition(0, 1, 0, amount);
Method VelocityClient.transferPerpPositionReference ↗
ParameterTypeRequired
fromSubAccountId
number
Sub-account id to debit the position from.
Yes
toSubAccountId
number
Sub-account id to credit the position to.
Yes
marketIndex
number
Perp market index of the position to transfer.
Yes
amount
any
Signed base amount to transfer, in `BASE_PRECISION` (1e9). Must have the same sign as `fromSubAccountId`'s existing position (i.e. it only reduces/closes that position, never flips it) and a magnitude at most the position's size and a multiple of the market's step size; pass `undefined` to transfer the entire position.
Yes
txParams
TxParams
Optional compute-unit/priority-fee overrides for the transaction.
No
Returns
Promise<string>

Transfer a Deposit and a Borrow Between Subaccounts

transferPools moves a deposit position and a borrow position between two of your own subaccounts in a single instruction — useful for rebalancing collateral and debt together instead of issuing two separate transfers.

const depositAmount = velocityClient.convertToSpotPrecision(0, 100); // 100 USDC const borrowAmount = velocityClient.convertToSpotPrecision(1, 1); // 1 SOL // transferPools(depositFromMarketIndex, depositToMarketIndex, borrowFromMarketIndex, // borrowToMarketIndex, depositAmount, borrowAmount, fromSubAccountId, toSubAccountId) await velocityClient.transferPools(0, 0, 1, 1, depositAmount, borrowAmount, 0, 1);
Method VelocityClient.transferPoolsReference ↗
ParameterTypeRequired
depositFromMarketIndex
number
Spot market to debit the deposit leg from.
Yes
depositToMarketIndex
number
Spot market to credit the deposit leg to (same mint, different pool).
Yes
borrowFromMarketIndex
number
Spot market to credit (repay) the borrow leg from.
Yes
borrowToMarketIndex
number
Spot market to debit (re-open) the borrow leg on.
Yes
depositAmount
any
Deposit amount to move, in the deposit market's token precision; `undefined`/omitted moves the entire existing deposit token amount; `0` skips the deposit leg entirely.
Yes
borrowAmount
any
Borrow amount to move, in the borrow market's token precision; `undefined` moves the entire existing borrow token amount; `0` skips the borrow leg entirely.
Yes
fromSubAccountId
number
Sub-account id to debit.
Yes
toSubAccountId
number
Sub-account id to credit.
Yes
txParams
TxParams
Optional compute-unit/priority-fee overrides for the transaction.
No
Returns
Promise<string>

Transfer Collateral Into or Out of an Isolated Perp Position

transferIsolatedPerpPositionDeposit moves collateral between a subaccount’s shared cross-margin pool and one perp market’s dedicated isolated-position bucket — it does not move funds between subaccounts. Pass a positive amount to fund the isolated position from cross margin, or a negative amount to pull collateral back out of the isolated position into cross margin.

const perpMarketIndex = 0; const amount = velocityClient.convertToSpotPrecision(0, 100); // deposit 100 USDC into the isolated position // transferIsolatedPerpPositionDeposit(amount, perpMarketIndex, subAccountId?, txParams?, trySettle?, noBuffer?) await velocityClient.transferIsolatedPerpPositionDeposit(amount, perpMarketIndex); // Negative amount withdraws collateral from the isolated position back to cross margin await velocityClient.transferIsolatedPerpPositionDeposit(amount.neg(), perpMarketIndex);
Method VelocityClient.transferIsolatedPerpPositionDepositReference ↗
ParameterTypeRequired
amount
any
Signed amount to move, in the quote spot market's token precision (e.g. QUOTE_PRECISION (1e6) for USDC); positive = into the isolated position, negative = out of it. Pass `MIN_I64` to move the entire isolated deposit back to general.
Yes
perpMarketIndex
number
Perp market index of the isolated position.
Yes
subAccountId
number
Sub-account id owning the position; defaults to `this.activeSubAccountId`.
No
txParams
TxParams
Optional compute-unit/priority-fee overrides for the transaction.
No
trySettle
boolean
If `true`, always prepends the `TRY_SETTLE` instruction even if not otherwise inferred as necessary.
No
noBuffer
boolean
If `true`, sends `amount` unmodified; otherwise (default) adds a 0.5% buffer to the requested amount to absorb price movement between build and execution. Has no effect when `amount` is `MIN_I64`.
No
Returns
Promise<string>

Delegate Transfers

By default, a delegate (an address authorized via updateUserDelegate to trade on your behalf) cannot call transferDepositByDelegate — internal transfers by a delegate are opt-in. Before a delegate can move deposits between your subaccounts, the account authority must explicitly enable the allowDelegateTransfer flag on their UserStats account. The flag applies to every subaccount under that authority.

// Authority opts in, once, before any delegate can transfer deposits internally. await velocityClient.updateUserAllowDelegateTransfer(true);
Method VelocityClient.updateUserAllowDelegateTransferReference ↗
ParameterTypeRequired
allowDelegateTransfer
boolean
New value for the flag.
Yes
Returns
Promise<string>

Once opted in, a delegate can call transferDepositByDelegate with the same arguments as transferDeposit:

// velocityClient here is subscribed with the delegate wallet, not the authority. const marketIndex = 0; // e.g. USDC const amount = velocityClient.convertToSpotPrecision(marketIndex, 100); // transferDepositByDelegate(amount, marketIndex, fromSubAccountId, toSubAccountId) await velocityClient.transferDepositByDelegate(amount, marketIndex, 0, 1);
Method VelocityClient.transferDepositByDelegateReference ↗
ParameterTypeRequired
amount
any
Amount to transfer, in the spot market's own token precision.
Yes
marketIndex
number
Spot market index of the balance to transfer.
Yes
fromSubAccountId
number
Sub-account id to debit.
Yes
toSubAccountId
number
Sub-account id to credit.
Yes
txParams
TxParams
Optional compute-unit/priority-fee overrides for the transaction.
No
Returns
Promise<string>

If allowDelegateTransfer has not been enabled, the on-chain instruction rejects the transfer regardless of whether the delegate is otherwise authorized to trade on the subaccounts involved.

Last updated on