Precision and Types
The Velocity SDK uses integer big numbers (BN) for most values. Always convert using the SDK’s precision constants and helpers.
Precision Constants
Each constant is a BN representing a power of 10. Divide a raw value by its precision constant to get the human-readable number.
| Constant | Value | Used For |
|---|---|---|
PRICE_PRECISION | 1e6 | Oracle prices, order prices |
BASE_PRECISION | 1e9 | Perp position sizes |
QUOTE_PRECISION | 1e6 | USD amounts, collateral |
Converting Between Raw and Human-Readable Values
BN → Human Number
import { BN, PRICE_PRECISION, BASE_PRECISION, QUOTE_PRECISION, convertToNumber } from "@velocity-exchange/sdk";
// Oracle price: raw 150_500_000 → 150.5 USD
const rawPrice = new BN(150_500_000);
const price = convertToNumber(rawPrice, PRICE_PRECISION);
console.log(price); // 150.5
// Position size: raw 2_500_000_000 → 2.5 SOL
const rawBase = new BN(2_500_000_000);
const size = convertToNumber(rawBase, BASE_PRECISION);
console.log(size); // 2.5
// Collateral: raw 10_000_000 → 10 USDC (or dUSDT on devnet)
const rawQuote = new BN(10_000_000);
const usd = convertToNumber(rawQuote, QUOTE_PRECISION);
console.log(usd); // 10Function convertToNumberReference ↗
Function convertToNumberReference ↗Converts a fixed-point `BN` into a human-readable JS `number` by dividing out `precision`. Correctly handles negative `bigNumber` values: `bn.js`'s `.div()`/`.mod()` truncate toward zero (matching JS `%` semantics), so the whole and fractional parts recombine with consistent sign without needing separate negative-number handling. Precision beyond what a JS `number` (IEEE-754 double) can represent exactly may be lost — this is a display/estimation helper, not for further on-chain-precision math.
| Parameter | Type | Required |
|---|---|---|
bigNumber | anyThe value to convert; `null`/`undefined` return 0 (a `BN` instance for
zero is still an object and thus truthy, so it falls through to the normal division below) | Yes |
precision | anyThe fixed-point precision to divide out; defaults to `PRICE_PRECISION` (1e6) | No |
| Returns |
|---|
number |
Human Number → BN
import { BN, BASE_PRECISION, PRICE_PRECISION } from "@velocity-exchange/sdk";
// 1 SOL in base precision
const oneSol = new BN(1).mul(BASE_PRECISION); // BN(1_000_000_000)
// $21.23 in price precision
const price = new BN(21_230_000); // 21.23 * 1e6
// Or use VelocityClient convenience helpers (available after setup):
const size = velocityClient.convertToPerpPrecision(1); // 1 base unit as BN
const px = velocityClient.convertToPricePrecision(21.23); // price as BN
const spot = velocityClient.convertToSpotPrecision(0, 100); // 100 quote-asset units as BNExample Human Number to BNReference ↗
Example Human Number to BNReference ↗Human Number to BN.Token Math Helpers
Spot balances are stored as interest-bearing scaled values. These helpers convert them to actual token amounts.
getTokenAmount converts a raw scaled spot balance into a token amount, accounting for accumulated interest since the last update. Pass the user’s scaledBalance, the spot market account (which contains the cumulative interest index), and the balance type (deposit or borrow).
import { getTokenAmount, SpotBalanceType, convertToNumber } from "@velocity-exchange/sdk";
const spotMarket = velocityClient.getSpotMarketAccount(0); // e.g. dUSDT on devnet, USDC on mainnet
const user = velocityClient.getUser();
const spotPosition = user.getUserAccount().spotPositions[0];
const tokenAmount = getTokenAmount(
spotPosition.scaledBalance,
spotMarket,
spotPosition.balanceType
);
console.log("Token amount:", tokenAmount.toString());Function getTokenAmountReference ↗
Function getTokenAmountReference ↗Calculates the spot token amount including any accumulated interest.
| Parameter | Type | Required |
|---|---|---|
balanceAmount | anyThe balance amount, typically from `SpotPosition.scaledBalance` | Yes |
spotMarket | SpotMarketAccountThe spot market account details | Yes |
balanceType | SpotBalanceTypeThe balance type to be used for calculation | Yes |
The calculated token amount, scaled by `SpotMarketConfig.precision`
| Returns |
|---|
BN |
getSignedTokenAmount wraps getTokenAmount to return a signed value: positive for deposits, negative for borrows. Use this when you need to distinguish between the two in a single number.
import { getTokenAmount, getSignedTokenAmount } from "@velocity-exchange/sdk";
const spotMarket = velocityClient.getSpotMarketAccount(0);
const spotPosition = velocityClient.getUser().getUserAccount().spotPositions[0];
const tokenAmount = getTokenAmount(
spotPosition.scaledBalance,
spotMarket,
spotPosition.balanceType
);
const signed = getSignedTokenAmount(tokenAmount, spotPosition.balanceType);
// signed > 0 means deposit, signed < 0 means borrow
console.log("Signed amount:", signed.toString());Function getSignedTokenAmountReference ↗
Function getSignedTokenAmountReference ↗Returns the signed (positive for deposit,negative for borrow) token amount based on the balance type.
| Parameter | Type | Required |
|---|---|---|
tokenAmount | anyThe token amount to convert (from `getTokenAmount`) | Yes |
balanceType | SpotBalanceTypeThe balance type to determine the sign of the token amount. | Yes |
- The signed token amount, scaled by `SpotMarketConfig.precision`
| Returns |
|---|
BN |