Skip to Content

Transactions

Every write the SDK performs goes through two injectable pieces:

  • TxHandler builds and signs transactions. It resolves the blockhash, injects the compute-budget instructions, compiles address lookup tables, and calls the wallet.
  • A TxSender broadcasts and confirms them. Four implementations ship with the SDK, each with a different retry and confirmation model.

VelocityClient creates both for you, and you can replace either through its config:

import { VelocityClient, WhileValidTxSender, TxHandler } from "@velocity-exchange/sdk"; const txHandler = new TxHandler({ connection, wallet, confirmationOptions: { commitment: "confirmed", preflightCommitment: "confirmed" }, }); const velocityClient = new VelocityClient({ connection, wallet, env: "mainnet-beta", txHandler, txSender: new WhileValidTxSender({ connection, wallet, txHandler }), txParams: { computeUnits: 600_000, computeUnitsPrice: 0 }, });
Class VelocityClientReference ↗

# VelocityClient Main entry point for interacting with Velocity Exchange from TypeScript. A single instance wraps one `authority` wallet (optionally trading on behalf of multiple sub-accounts via `authoritySubAccountMap`, or as a delegate via `includeDelegates`) and owns: - the Anchor `program` handle and RPC `connection`/`provider`, - the account subscription (`accountSubscriber`) that streams State, PerpMarket, SpotMarket, and oracle accounts (websocket, polling, or grpc — selected via `VelocityClientConfig.accountSubscription`), - the set of loaded `User` / `UserStats` objects for this authority's sub-accounts, - the `txSender` / `txHandler` used to build, sign, and send every instruction the class exposes.

Most instruction-building methods come in pairs: `doThing(...)` builds the instruction(s), wraps them in a transaction, signs, sends, and confirms; `getDoThingIx(...)` (or `getDoThingIxs(...)`) only builds and returns the raw `TransactionInstruction`(s) for callers composing their own transaction (e.g. bundling several instructions, or using a custom `txParams`/lookup-table setup).

Almost every account-touching method requires `subscribe()` to have resolved and the target sub-account's `User` to be loaded first — see `subscribe`, `addUser`, `switchActiveUser`.

PropertyTypeRequired
connection
Connection
Yes
wallet
IWallet
Yes
program
VelocityProgram
Yes
provider
AnchorProvider
Yes
env
VelocityEnv
Yes
opts
ConfirmOptions
Yes
useHotWalletAdmin
boolean
No
users
Map<string, User>
Yes
userStats
UserStats
No
userStatsAccountPublicKey
PublicKey
No
activeSubAccountId
number | undefined
Yes
userAccountSubscriptionConfig
UserSubscriptionConfig
Yes
userStatsAccountSubscriptionConfig
UserStatsSubscriptionConfig
Yes
accountSubscriber
VelocityClientAccountSubscriber
Yes
eventEmitter
StrictEventEmitter<EventEmitter, VelocityClientAccountEvents>
Yes
metricsEventEmitter
StrictEventEmitter<EventEmitter, VelocityClientMetricsEvents>
Yes
_isSubscribed
boolean
Yes
txSender
TxSender
Yes
perpMarketLastSlotCache
Map<number, number>
Yes
spotMarketLastSlotCache
Map<number, number>
Yes
mustIncludePerpMarketIndexes
Set<number>
Yes
mustIncludeSpotMarketIndexes
Set<number>
Yes
authority
PublicKey
Yes
marketLookupTables
PublicKey[]
Yes
lookupTableAccounts
AddressLookupTableAccount[]
No
includeDelegates
boolean
No
authoritySubAccountMap
Map<string, number[]>
No
skipLoadUsers
boolean
No
txVersion
TransactionVersion
Yes
txParams
TxParams
Yes
enableMetricsEvents
boolean
No
txHandler
TxHandler
Yes
isSubscribed
boolean
Whether this client has completed `subscribe()` and its underlying `accountSubscriber` is still actively streaming account updates. Most account-reading and instruction-building methods assume this is `true`; call `subscribe()` first if it is `false`. Overrides the internal subscribed flag directly, without touching `accountSubscriber`. Intended for advanced/test callers managing subscription state manually; regular callers should use `subscribe()` / `unsubscribe()` instead.
Yes
getPrePlaceOrderIxs
any
Yes
getUserMapKey
(subAccountId: number, authority: PublicKey) => string
Builds the internal `Map` key used to index `this.users` for a given sub-account/authority pair.
Yes
createUser
(subAccountId: number, accountSubscriptionConfig: UserSubscriptionConfig, authority?: PublicKey | undefined) => User
Constructs (but does not subscribe) a `User` for the given sub-account/authority.
Yes
subscribe
() => Promise<boolean>
Subscribes the client to on-chain state: loads and subscribes to the sub-account(s) implied by the constructor/`updateWallet` config (`addAndSubscribeToUsers`), subscribes the `accountSubscriber` (State, PerpMarket, SpotMarket, oracle accounts), and, if `userStats` was configured, subscribes it too. Must be called (and resolve `true`) before using most other methods on this class.
Yes
subscribeUsers
() => Promise<boolean>[]
Subscribes every currently-loaded `User` in `this.users`. Does not add new users or subscribe `accountSubscriber`/`userStats` — see `subscribe()` for full client subscription.
Yes
fetchAccounts
() => Promise<void>
Forces every loaded `User`, the `accountSubscriber`, and (if present) `userStats` to fetch fresh account data from RPC immediately, bypassing the normal websocket/polling cadence. Useful in tests (e.g. local validator) where a just-landed transaction's effects need to be visible without waiting for the next update.
Yes
unsubscribe
() => Promise<void>
Unsubscribes all loaded users, the `accountSubscriber`, and (if present) `userStats`, and sets `isSubscribed` to `false`. Does not clear `this.users` — the `User` objects remain but stop receiving updates until re-subscribed.
Yes
unsubscribeUsers
() => Promise<void>[]
Unsubscribes every currently-loaded `User` in `this.users` without clearing the map or touching `accountSubscriber`/`userStats`.
Yes
statePublicKey
PublicKey
No
getStatePublicKey
() => Promise<PublicKey>
Returns the `State` account PDA for this program, computing and caching it on first call.
Yes
signerPublicKey
PublicKey
No
getSignerPublicKey
() => PublicKey
Returns the program's PDA signer (used as the authority for vault CPIs), computing and caching it on first call. Synchronous — the signer PDA has no seeds that require an on-chain lookup.
Yes
getStateAccount
() => StateAccount
Returns the last account-subscriber-cached `State` account. Does not hit RPC.
Yes
forceGetStateAccount
() => Promise<StateAccount>
Like `getStateAccount` but forces a fresh RPC fetch first. Useful for anchor tests where an update needs to be observed immediately rather than waiting for the next subscription push.
Yes
getPerpMarketAccount
(marketIndex: number) => PerpMarketAccount | undefined
Returns the last account-subscriber-cached `PerpMarketAccount` for a market index. Does not hit RPC. The market must be one of the indexes/lookup-tables this client subscribed to.
Yes
getPerpMarketAccountOrThrow
(marketIndex: number) => PerpMarketAccount
Like `getPerpMarketAccount` but throws if the market is not loaded, for call sites that require a guaranteed account.
Yes
forceGetPerpMarketAccount
(marketIndex: number) => Promise<PerpMarketAccount | undefined>
Like `getPerpMarketAccount` but forces a fresh RPC fetch, retrying up to 10 times (one fetch per attempt) until the market account appears. Useful in anchor tests right after `initializePerpMarket` where the market may not yet be visible to the subscriber.
Yes
getPerpMarketAccounts
() => PerpMarketAccount[]
Returns all currently-loaded `PerpMarketAccount`s (does not hit RPC).
Yes
getSpotMarketAccount
(marketIndex: number) => SpotMarketAccount | undefined
Returns the last account-subscriber-cached `SpotMarketAccount` for a market index. Does not hit RPC.
Yes
getSpotMarketAccountOrThrow
(marketIndex: number) => SpotMarketAccount
Like `getSpotMarketAccount` but throws if the market is not loaded, for call sites that require a guaranteed account.
Yes
forceGetSpotMarketAccount
(marketIndex: number) => Promise<SpotMarketAccount | undefined>
Like `getSpotMarketAccount` but forces a fresh RPC fetch first. Useful for anchor tests where an update needs to be observed immediately.
Yes
getSpotMarketAccounts
() => SpotMarketAccount[]
Returns all currently-loaded `SpotMarketAccount`s (does not hit RPC).
Yes
getQuoteSpotMarketAccount
() => SpotMarketAccount
Convenience accessor for the quote spot market (`QUOTE_SPOT_MARKET_INDEX`, always index 0), i.e. the USDC market used to denominate collateral/PnL across the protocol.
Yes
getOraclePriceDataAndSlot
(oraclePublicKey: PublicKey, oracleSource: OracleSource) => DataAndSlot<OraclePriceData> | undefined
Returns the last subscriber-cached oracle price data for a given oracle account/source. Does not hit RPC.
Yes
fetchAllLookupTableAccounts
() => Promise<AddressLookupTableAccount[]>
Fetches and caches the `AddressLookupTableAccount`s for `this.marketLookupTables`, so transaction builders can include them to shrink versioned-transaction size. Subsequent calls return the cached result.
Yes
getTxVersionForNewWallet
any
Yes
updateWallet
(newWallet: IWallet, subAccountIds?: number[] | undefined, activeSubAccountId?: number | undefined, includeDelegates?: boolean | undefined, authoritySubaccountMap?: Map<string, number[]> | undefined) => Promise<...>
Swaps the wallet/authority this client transacts and subscribes as, rebuilding the Anchor `provider`/`program`, `txSender`, `txHandler`, `userStats`, and (if already subscribed) every loaded `User` for the new authority. Use this instead of constructing a new `VelocityClient` when a UI wallet-adapter connection changes. At most one of `includeDelegates`, `subAccountIds`, or `authoritySubaccountMap` may be passed (mirrors the constructor's mutual-exclusion rule); `subAccountIds` is shorthand for `authoritySubaccountMap = &#123; [newWallet.publicKey]: subAccountIds &#125;`.
Yes
emulateAccount
(emulateAuthority: PublicKey) => Promise<boolean>
Update the subscribed accounts to a given authority, while leaving the connected wallet intact. This allows a user to emulate another user's account on the UI and sign permissionless transactions with their own wallet. `authority` is repointed to `emulateAuthority` and `includeDelegates` is forced to `true`, but the connected `wallet` (and thus its signing key) is unchanged — instructions that require the emulated authority's own signature (e.g. deposits from its wallet) will still fail; only actions the connected wallet is independently authorized for (e.g. as a delegate, or read-only views) will succeed.
Yes
switchActiveUser
(subAccountId: number, authority?: PublicKey | undefined) => Promise<void>
Sets the client's `activeSubAccountId`/`authority` (the sub-account used by default when a method's `subAccountId` param is omitted). If `authority` changes, re-derives and re-subscribes `userStats` for the new authority (assumed unnecessary when only the sub-account id changes for the same authority). Does not load or subscribe the target `User` itself — call `addUser` first if it isn't already loaded.
Yes
addUser
(subAccountId: number, authority?: PublicKey | undefined, userAccount?: UserAccount | undefined) => Promise<boolean>
Loads and subscribes a `User` for a sub-account, adding it to `this.users`. If a subscribed `User` for this sub-account/authority is already loaded, returns `true` immediately without re-subscribing.
Yes
addAndSubscribeToUsers
(authority?: PublicKey | undefined) => Promise<boolean>
Adds and subscribes to users based on params set by the constructor or by updateWallet. If `authoritySubAccountMap` is non-empty, loads exactly the (authority, subAccountId) pairs it lists. Otherwise fetches every on-chain `UserAccount` owned by `authority` (defaulting to `this.wallet.publicKey`), plus (when `includeDelegates` is `true`) every account this authority is a delegate for, and loads all of them. If `activeSubAccountId` is not already set, the first loaded account becomes active. A no-op returning `true` if `skipLoadUsers` is set (e.g. no real wallet configured).
Yes
getInitializeUserAccountIxs
(subAccountId?: number | undefined, name?: string | undefined, referrerInfo?: ReferrerInfo | undefined, poolId?: number | undefined) => Promise<[TransactionInstruction[], PublicKey]>
Builds the instructions to initialize a user (sub-account) for `this.authority`, without sending a transaction. For `subAccountId === 0`, also prepends `initializeUserStats` if the authority's `UserStats` account doesn't already exist on-chain (every authority needs exactly one, created alongside its first sub-account).
Yes
initializeUserAccount
(subAccountId?: number | undefined, name?: string | undefined, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined) => Promise<[...]>
Initializes a new user (sub-account) for `this.authority` on-chain, then loads and subscribes it into `this.users` via `addUser`. See `getInitializeUserAccountIxs` for parameter semantics and the implicit `UserStats` creation for `subAccountId === 0`.
Yes
getInitializeUserStatsIx
(overrides?: { externalWallet?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Builds the `initializeUserStats` instruction for `this.authority`. Every authority needs exactly one `UserStats` account (created automatically by `getInitializeUserAccountIxs`/ `initializeUserAccount` alongside sub-account 0 if missing); call this directly only when building a custom initialization flow.
Yes
initializeSignedMsgUserOrders
(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<[string, PublicKey]>
Initializes the `SignedMsgUserOrders` account for `authority`, which caches recently-submitted off-chain signed (SignedMsg / "swift") order messages so keepers can look them up and verify duplicates on-chain. Required once per authority before that authority's signed-message orders can be placed.
Yes
getInitializeSignedMsgUserOrdersAccountIx
(authority: PublicKey, numOrders: number, overrides?: { externalWallet?: PublicKey; } | undefined) => Promise<[PublicKey, TransactionInstruction]>
Builds the `initializeSignedMsgUserOrders` instruction. See `initializeSignedMsgUserOrders` for semantics.
Yes
resizeSignedMsgUserOrders
(authority: PublicKey, numOrders: number, userSubaccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Grows an existing `SignedMsgUserOrders` account to hold more order-message slots. The program only allows growing, never shrinking.
Yes
getResizeSignedMsgUserOrdersInstruction
(authority: PublicKey, numOrders: number, userSubaccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `resizeSignedMsgUserOrders` instruction. See `resizeSignedMsgUserOrders` for semantics.
Yes
initializeSignedMsgWsDelegatesAccount
(authority: PublicKey, delegates?: PublicKey[] | undefined, txParams?: TxParams | undefined) => Promise<string>
Initializes `authority`'s `SignedMsgWsDelegates` account, which lists wallets authorized to co-sign/relay that authority's signed-message ("swift") orders over a websocket connection without holding general trading authority.
Yes
getInitializeSignedMsgWsDelegatesAccountIx
(authority: PublicKey, delegates?: PublicKey[] | undefined) => Promise<TransactionInstruction>
Builds the `initializeSignedMsgWsDelegates` instruction. See `initializeSignedMsgWsDelegatesAccount` for semantics.
Yes
initializeRevenueShare
(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Initializes the per-authority `RevenueShare` account, which accumulates that authority's lifetime referrer and builder fee-share rewards. One per authority (not per sub-account); an authority must have this before it can earn referrer or builder revenue share.
Yes
getInitializeRevenueShareIx
(authority: PublicKey, overrides?: { payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Builds the `initializeRevenueShare` instruction. See `initializeRevenueShare` for semantics.
Yes
initializeRevenueShareEscrow
(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<string>
Initializes `authority`'s `RevenueShareEscrow` account — the per-user account that tracks pending builder-fee orders and the list of builders this user has approved (`approvedBuilders`), required to place orders carrying a builder fee. On creation, `escrow.referrer` is copied from the authority's existing `UserStats.referrer`, if any.
Yes
getInitializeRevenueShareEscrowIx
(authority: PublicKey, numOrders: number, overrides?: { payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Builds the `initializeRevenueShareEscrow` instruction. See `initializeRevenueShareEscrow` for semantics.
Yes
resizeRevenueShareEscrowOrders
(authority: PublicKey, numOrders: number, txParams?: TxParams | undefined) => Promise<string>
Grows `authority`'s `RevenueShareEscrow` order slots. On-chain rejects `numOrders` smaller than the current slot count (shrinking is not supported).
Yes
getResizeRevenueShareEscrowOrdersIx
(authority: PublicKey, numOrders: number) => Promise<TransactionInstruction>
Builds the `resizeRevenueShareEscrowOrders` instruction. See `resizeRevenueShareEscrowOrders` for semantics.
Yes
changeApprovedBuilder
(builder: PublicKey, maxFeeTenthBps: number, add: boolean, txParams?: TxParams | undefined) => Promise<string>
Adds, updates, or revokes an approved builder in the caller's own `RevenueShareEscrow` (`this.wallet.publicKey` unless `overrides.authority` is set on the underlying ix). This is the *user's* opt-in that lets `builder` attach a builder fee (capped at `maxFeeTenthBps`) to orders this user places — it does not itself submit any order. `maxFeeTenthBps` is in tenths of a basis point (1 unit = 0.001%, i.e. `10_000` tenth-bps = 1%).
Yes
getChangeApprovedBuilderIx
(builder: PublicKey, maxFeeTenthBps: number, add: boolean, overrides?: { authority?: PublicKey; payer?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Builds the `changeApprovedBuilder` instruction. See `changeApprovedBuilder` for semantics; unlike the wrapper, `overrides.authority` lets you target an escrow other than the connected wallet's.
Yes
addSignedMsgWsDelegate
(authority: PublicKey, delegate: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Authorizes `delegate` on `authority`'s existing `SignedMsgWsDelegates` account (must already be initialized via `initializeSignedMsgWsDelegatesAccount`). Signed by `this.wallet.publicKey`, which must be `authority`.
Yes
getAddSignedMsgWsDelegateIx
(authority: PublicKey, delegate: PublicKey) => Promise<TransactionInstruction>
Builds the `changeSignedMsgWsDelegateStatus` instruction with `add = true`. See `addSignedMsgWsDelegate` for semantics.
Yes
removeSignedMsgWsDelegate
(authority: PublicKey, delegate: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Revokes `delegate`'s authorization on `authority`'s `SignedMsgWsDelegates` account. Signed by `this.wallet.publicKey`, which must be `authority`.
Yes
getRemoveSignedMsgWsDelegateIx
(authority: PublicKey, delegate: PublicKey) => Promise<TransactionInstruction>
Builds the `changeSignedMsgWsDelegateStatus` instruction with `add = false`. See `removeSignedMsgWsDelegate` for semantics.
Yes
getInitializeUserInstructions
any
Yes
getNextSubAccountId
() => Promise<number>
Returns the sub-account id that would be assigned to the next sub-account created for `this.wallet.publicKey` (i.e. `UserStats.numberOfSubAccountsCreated`, which increments on every `initializeUser` and never reuses ids after `deleteUser`). Prefers the already-loaded `userStats` subscription; falls back to an RPC fetch if it isn't loaded or has no cached account yet.
Yes
initializeReferrerName
(name: string) => Promise<string>
Registers `this.wallet`'s sub-account 0 as a referrer under a human-readable `name`, creating a `ReferrerNameAccount` PDA keyed by that name. Other users can then look up this authority's `referrer`/`referrerStats` public keys by name (see `getReferrerNameAccountsForAuthority`) when passing `referrerInfo` to `initializeUserAccount`. Fails if the name is already taken (PDA already initialized).
Yes
updateUserName
(name: string, subAccountId?: number | undefined) => Promise<string>
Updates the display name stored on a sub-account. Signed by `this.wallet.publicKey`, which must be the sub-account's authority.
Yes
updateUserCustomMarginRatio
(updates: { marginRatio: number; subAccountId: number; }[], txParams?: TxParams | undefined) => Promise<string>
Sets a per-sub-account custom (higher) minimum margin ratio for one or more sub-accounts in a single transaction, self-imposing a lower max leverage than the market default. Signed by `this.wallet.publicKey` for each sub-account's authority.
Yes
getUpdateUserCustomMarginRatioIx
(marginRatio: number, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `updateUserCustomMarginRatio` instruction for a single sub-account. As a side effect, ensures the target sub-account is loaded via `addUser` before building the instruction. See `updateUserCustomMarginRatio` for unit/semantics.
Yes
getUpdateUserPerpPositionCustomMarginRatioIx
(perpMarketIndex: number, marginRatio: number, subAccountId?: number | undefined, overrides?: { userAccountPublicKey?: PublicKey; authority?: PublicKey; signingAuthority?: PublicKey; } | undefined) => Promise<...>
Builds the instruction to set a custom minimum margin ratio for a single open perp position (rather than the whole sub-account), letting a position use different effective max leverage than the sub-account default. Used internally by `getPrePlaceOrderIxs` to implement per-order `positionMaxLev`.
Yes
updateUserPerpPositionCustomMarginRatio
(perpMarketIndex: number, marginRatio: number, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Sends the instruction built by `getUpdateUserPerpPositionCustomMarginRatioIx`. See that method for semantics/units.
Yes
getUpdateUserMarginTradingEnabledIx
(marginTradingEnabled: boolean, subAccountId?: number | undefined, userAccountPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the instruction to toggle a sub-account's "margin trading enabled" flag, which permits borrowing against spot collateral (multiple simultaneous spot borrows / cross-margined spot). It is incompatible with holding a position in an `Isolated`-tier perp market — enabling it while such a position is open, or opening one while it's enabled, is rejected on-chain. As a side effect, ensures the target sub-account is loaded via `addUser`.
Yes
updateUserMarginTradingEnabled
(updates: { marginTradingEnabled: boolean; subAccountId: number; }[]) => Promise<string>
Sends instructions built by `getUpdateUserMarginTradingEnabledIx` for one or more sub-accounts in a single transaction. See that method for semantics.
Yes
getUpdateUserDelegateIx
(delegate: PublicKey, overrides: { subAccountId?: number; userAccountPublicKey?: PublicKey; authority?: PublicKey; }) => Promise<TransactionInstruction>
Builds the instruction to set (or clear, with `PublicKey.default`) the delegate authority on a sub-account. The delegate can sign most trading instructions (place/cancel orders, etc.) on the sub-account's behalf, but `withdraw` always requires the true owning `authority`'s own signature (delegates can never withdraw). A delegate-initiated internal transfer of the sub-account's collateral to another of the owner's sub-accounts is possible only via `transferDepositByDelegate`, and only once the owner has separately opted in via `updateUserAllowDelegateTransfer`.
Yes
updateUserDelegate
(delegate: PublicKey, subAccountId?: number | undefined) => Promise<string>
Sends the `updateUserDelegate` instruction for `this.wallet.publicKey`'s sub-account. See `getUpdateUserDelegateIx` for full semantics.
Yes
getUpdateUserAllowDelegateTransferIx
(allowDelegateTransfer: boolean) => Promise<TransactionInstruction>
Builds the instruction to set the `allowDelegateTransfer` opt-in flag on `this.wallet.publicKey`'s `UserStats` account. This flag gates `transferDepositByDelegate` across *all* of this authority's sub-accounts — if it is `false` (the default), any delegate-initiated internal transfer attempt is rejected on-chain regardless of that sub-account's delegate. It does not affect direct deposits/withdrawals, which are unaffected by delegate status.
Yes
updateUserAllowDelegateTransfer
(allowDelegateTransfer: boolean) => Promise<string>
Sends the instruction built by `getUpdateUserAllowDelegateTransferIx`. See that method for semantics.
Yes
updateUserAdvancedLp
(updates: { advancedLp: boolean; subAccountId: number; }[]) => Promise<string>
Sends instructions built by `getUpdateAdvancedDlpIx` for one or more sub-accounts. **Currently non-functional**: the on-chain `update_user_advanced_lp` instruction handler is commented out of the program's Anchor `#[program]` module (see `programs/velocity/src/lib.rs`) and is absent from the generated IDL, so `program.instruction.updateUserAdvancedLp` does not exist and this call will throw at runtime until the instruction is re-enabled on-chain.
Yes
getUpdateAdvancedDlpIx
(advancedLp: boolean, subAccountId: number) => Promise<any>
Builds the (currently unavailable — see `updateUserAdvancedLp`) `updateUserAdvancedLp` instruction, which would flag a sub-account as an "advanced LP" participant.
Yes
updateUserReduceOnly
(updates: { reduceOnly: boolean; subAccountId: number; }[]) => Promise<string>
Sends instructions built by `getUpdateUserReduceOnlyIx` for one or more sub-accounts in a single transaction. See that method for semantics.
Yes
getUpdateUserReduceOnlyIx
(reduceOnly: boolean, subAccountId: number) => Promise<TransactionInstruction>
Builds the instruction to toggle a sub-account's reduce-only status. When reduce-only, orders on the sub-account may only decrease existing positions, never open or increase one.
Yes
updateUserPoolId
(updates: { poolId: number; subAccountId: number; }[]) => Promise<string>
Sends instructions built by `getUpdateUserPoolIdIx` for one or more sub-accounts in a single transaction. See that method for semantics.
Yes
getUpdateUserPoolIdIx
(poolId: number, subAccountId: number) => Promise<TransactionInstruction>
Builds the instruction to move a sub-account into a different isolated pool. On-chain, re-validates the sub-account still meets its initial margin requirement after the switch using only markets/oracles passed via `remaining_accounts` — the caller (this method doesn't add any) must supply those if the sub-account has open deposits/positions, or the ix will fail.
Yes
fetchAllUserAccounts
(includeIdle?: boolean | undefined) => Promise<ProgramAccount<UserAccount>[]>
Fetches every `User` account that exists on-chain for this program via `getProgramAccounts` (with a `memcmp` filter, not restricted to this client's authority). Expensive — intended for indexers/ admin tooling, not per-trade calls.
Yes
getUserAccountsForDelegate
(delegate: PublicKey) => Promise<UserAccount[]>
Fetches (via RPC `memcmp` filter, not the account subscriber) every on-chain `User` account whose `delegate` field equals `delegate`, i.e. every sub-account this wallet can trade on behalf of as a delegate.
Yes
getUserAccountsAndAddressesForAuthority
(authority: PublicKey) => Promise<ProgramAccount<UserAccount>[]>
Fetches (via RPC, not the account subscriber) every on-chain `User` account owned by `authority`, with each account's PDA address included.
Yes
getUserAccountsForAuthority
(authority: PublicKey) => Promise<UserAccount[]>
Fetches (via RPC, not the account subscriber) every on-chain `User` account owned by `authority`. Used internally by `addAndSubscribeToUsers` to discover an authority's sub-accounts.
Yes
getReferredUserStatsAccountsByReferrer
(referrer: PublicKey) => Promise<UserStatsAccount[]>
Fetches (via RPC `memcmp` filter) every `UserStats` account whose `referrer` field equals `referrer`, i.e. every authority that was referred by this referrer.
Yes
getReferrerNameAccountsForAuthority
(authority: PublicKey) => Promise<ReferrerNameAccount[]>
Fetches (via RPC `memcmp` filter) every `ReferrerNameAccount` registered by `authority` via `initializeReferrerName`.
Yes
deleteUser
(subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Deletes a sub-account owned by `this.wallet.publicKey` and unsubscribes/removes it from `this.users`. On-chain requires the sub-account to be fully closed out: no open perp/spot positions, no open orders, not bankrupt, not being liquidated, and (unless idle) sub-account 0 of a referrer cannot be deleted at all. If the protocol charges a `maxInitializeUserFee` and the account's `UserStats` is younger than ~13 days, the sub-account must also be marked `idle`.
Yes
getUserDeletionIx
(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `deleteUser` instruction. See `deleteUser` for on-chain preconditions.
Yes
forceDeleteUser
(userAccountPublicKey: PublicKey, userAccount: UserAccount, txParams?: TxParams | undefined) => Promise<string>
Keeper-only instruction: force-cancels all open orders and deletes/closes an inactive, near-zero equity user account, refunding remaining rent to `userAccount.authority`. Requires the signer (`this.wallet.publicKey`) to hold the `UserFlag` hot-role. On-chain, requires the account's total equity to be under `QUOTE_PRECISION / 20` (0.05 USDC, QUOTE_PRECISION = 1e6) and (outside `anchor-test` builds) at least ~3 months of inactivity since `lastActiveSlot`. Not for self-service account deletion — see `deleteUser` for that.
Yes
getForceDeleteUserIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<TransactionInstruction>
Builds the keeper-only `forceDeleteUser` instruction, assembling `remaining_accounts` for the account's non-empty spot positions, its revenue-share escrow (if any order carries a builder fee), and every mint/token-program needed for its open spot balances. See `forceDeleteUser` for on-chain preconditions.
Yes
deleteSignedMsgUserOrders
(txParams?: TxParams | undefined) => Promise<string>
Closes `this.wallet.publicKey`'s `SignedMsgUserOrders` account, refunding its rent to the authority. Requires the account to exist (see `isSignedMsgUserOrdersAccountInitialized`).
Yes
getSignedMsgUserOrdersDeletionIx
(authority: PublicKey) => Promise<any>
Builds the `deleteSignedMsgUserOrders` instruction, signed by `this.wallet.publicKey`. See `deleteSignedMsgUserOrders` for semantics.
Yes
isSignedMsgUserOrdersAccountInitialized
(authority: PublicKey) => Promise<boolean>
Checks if a SignedMsg User Orders account exists for the given authority. The account pubkey is derived using the program ID and authority as seeds. Makes an RPC call to check if the account exists on-chain.
Yes
reclaimRent
(subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Reclaims any lamports on a sub-account's `User` PDA in excess of the rent-exempt minimum for its current size (e.g. left over after the account was resized smaller), transferring them to `this.wallet.publicKey`.
Yes
getReclaimRentIx
(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `reclaimRent` instruction. See `reclaimRent` for semantics/preconditions.
Yes
getUser
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => User
Looks up an already-loaded `User` from `this.users` (does not fetch or subscribe).
Yes
hasUser
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => boolean
Checks whether a `User` for the given sub-account/authority is currently loaded in `this.users`, without throwing. Safe to call with unresolvable `subAccountId`/`authority` (returns `false`).
Yes
getUsers
() => User[]
Returns every currently-loaded `User`, with sub-accounts owned directly by `this.wallet.publicKey` first, followed by delegated sub-accounts (owned by other authorities this wallet delegates for).
Yes
getUserStats
() => UserStats | undefined
Returns the `UserStats` instance for `this.authority`, if one was constructed (via `config.userStats`, `updateWallet`, `emulateAccount`, or `switchActiveUser`).
Yes
getUserStatsOrThrow
() => UserStats
Like `getUserStats` but throws if there is no UserStats subscription, for call sites that require a guaranteed account.
Yes
fetchReferrerNameAccount
(name: string) => Promise<ReferrerNameAccount | undefined>
Fetches (via RPC, not the account subscriber) the `ReferrerNameAccount` registered for a given name via `initializeReferrerName`.
Yes
getUserStatsAccountPublicKey
() => PublicKey
Returns the `UserStats` account PDA for `this.authority`, computing and caching it on first call (or after `this.authority` changes, since callers like `updateWallet`/`switchActiveUser` reset the cache).
Yes
getUserAccountPublicKey
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => Promise<PublicKey>
Returns the user account PDA for an already-loaded sub-account (does not derive/compute a PDA for a sub-account that hasn't been loaded).
Yes
getUserAccount
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => UserAccount | undefined
Returns the last subscriber-cached `UserAccount` data for a loaded sub-account. Does not hit RPC.
Yes
getUserAccountOrThrow
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => UserAccount
Like `getUserAccount` but throws a named error instead of returning `undefined` when the account has not been loaded yet. Use at call sites that structurally require a loaded account.
Yes
forceGetUserAccount
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => Promise<UserAccount | undefined>
Like `getUserAccount` but forces a fresh RPC fetch first. Useful for anchor tests where an update needs to be observed immediately.
Yes
getUserAccountAndSlot
(subAccountId?: number | undefined, authority?: PublicKey | undefined) => DataAndSlot<UserAccount> | undefined
Like `getUserAccount` but also returns the slot the data was last observed at.
Yes
getSpotPosition
(marketIndex: number, subAccountId?: number | undefined) => SpotPosition | undefined
Returns a sub-account's spot balance entry for a market, if it holds one.
Yes
getQuoteAssetTokenAmount
() => BN
Convenience accessor for the active sub-account's quote (USDC) token amount.
Yes
getIsolatedPerpPositionTokenAmount
(perpMarketIndex: number, subAccountId?: number | undefined) => BN
Returns the isolated deposit token amount backing a sub-account's isolated perp position in a given market (the collateral segregated into that position via `transferIsolatedPerpPositionDeposit`, distinct from the sub-account's general/cross balances).
Yes
getTokenAmount
(marketIndex: number) => BN
Returns the active sub-account's balance in a spot market, converted from the internal scaled balance representation to actual token units.
Yes
convertToSpotPrecision
(marketIndex: number, amount: any) => BN
Converts a human-readable (UI) amount to a market's on-chain spot precision (`10^mint.decimals`). A plain `number` is scaled up via `castNumberToSpotPrecision`; a `BN` is assumed to already be a whole-token count and is scaled by the same factor.
Yes
convertToPerpPrecision
(amount: any) => BN
Converts a human-readable (UI) base-asset amount to `BASE_PRECISION` (1e9), the precision used for perp/spot order base amounts.
Yes
convertToPricePrecision
(amount: any) => BN
Converts a human-readable (UI) price to `PRICE_PRECISION` (1e6).
Yes
mustIncludeMarketsInIx
({ perpMarketIndexes, spotMarketIndexes, }: { perpMarketIndexes: number[]; spotMarketIndexes: number[]; }) => void
Each velocity instruction must include perp and spot market accounts in the ix remaining accounts. Use this function to force a subset of markets to be included in the remaining accounts for every ix built by this client going forward (accumulates into `mustIncludePerpMarketIndexes` / `mustIncludeSpotMarketIndexes`; there is no corresponding "unset" — construct a new client to reset). Useful when an instruction's own logic can't infer every market/oracle it needs (e.g. a cross-margin health check spanning markets the user has no position in yet).
Yes
cachePerpMarketSlot
any
Yes
cacheSpotMarketSlot
any
Yes
getRemainingAccounts
(params: RemainingAccountParams) => AccountMeta[]
Builds the `remaining_accounts` list (perp/spot market + oracle accounts, plus any accounts derived from the given `userAccounts`) that most instructions need appended so the on-chain handler can load the markets/oracles it touches. Always includes markets registered via `mustIncludeMarketsInIx`, in addition to whatever `params` (e.g. `userAccounts`, `writableSpotMarketIndexes`) implies. Used internally by nearly every instruction-building method on this class; exposed publicly for callers assembling custom instructions.
Yes
addPerpMarketToRemainingAccountMaps
(marketIndex: number, writable: boolean, oracleAccountMap: Map<string, AccountMeta>, spotMarketAccountMap: Map<number, AccountMeta>, perpMarketAccountMap: Map<...>) => void
Adds a perp market's account meta (and its oracle and quote spot market) into the shared maps used to de-duplicate remaining accounts across multiple markets in one instruction. The oracle is marked writable only for `prelaunch`-sourced oracles being written to.
Yes
addSpotMarketToRemainingAccountMaps
(marketIndex: number, writable: boolean, oracleAccountMap: Map<string, AccountMeta>, spotMarketAccountMap: Map<number, AccountMeta>) => void
Adds a spot market's account meta (and its oracle, if any) into the shared maps used to de-duplicate remaining accounts across multiple markets in one instruction.
Yes
addBuilderToRemainingAccounts
(builders: PublicKey[], remainingAccounts: AccountMeta[]) => void
Appends each builder's `User` (sub-account 0) and `RevenueShare` account metas to `remainingAccounts` (writable), deduping by pubkey so an authority that is both a builder and a referrer isn't pushed twice — the on-chain revenue-share account loader rejects duplicates and would abort the whole instruction.
Yes
getRemainingAccountMapsForUsers
(userAccounts: UserAccount[]) => { oracleAccountMap: Map<string, AccountMeta>; spotMarketAccountMap: Map<number, AccountMeta>; perpMarketAccountMap: Map<...>; }
Builds the deduplicated oracle/spot-market/perp-market account-meta maps needed to cover every non-empty position across a set of user accounts (e.g. taker + makers in a fill), including the quote spot market whenever a spot position has open orders. All accounts are added read-only.
Yes
getOrder
(orderId: number | undefined, subAccountId?: number | undefined) => Order | undefined
Look up an open order by its program-assigned order ID from the cached user account. `orderId` is the monotonically incrementing u32 counter that the program assigns at placement time — it is not known until the place instruction executes on-chain. Use `getOrderByUserId` when you need to look up an order by the caller-supplied `userOrderId` instead. Returns `undefined` when the order is not found (already filled, cancelled, or the account cache is stale).
Yes
getOrderByUserId
(userOrderId: number, subAccountId?: number | undefined) => Order | undefined
Look up an open order by the caller-supplied `userOrderId` from the cached user account. `userOrderId` is a 1-255 slot chosen by the caller in `OrderParams` and is stable across the life of the order — useful when you need to reference an order before the program-assigned `Order.orderId` is known (e.g. immediately after placing without waiting for confirmation). Use `getOrder` when you have the program-assigned ID. Returns `undefined` when the order is not found (already filled, cancelled, or the account cache is stale).
Yes
getAssociatedTokenAccount
(marketIndex: number, useNative?: boolean | undefined, tokenProgram?: PublicKey | undefined, authority?: PublicKey | undefined, allowOwnerOffCurve?: boolean | undefined) => Promise<...>
Resolves the token account to use for a spot market's mint. For the wrapped-SOL market with `useNative = true` (the default), returns `authority` itself (native SOL, no wrapping) rather than an SPL associated token account; for every other market (or `useNative = false`), returns the derived associated token account address (not guaranteed to exist on-chain — see `getAssociatedTokenAccountCreationIx`).
Yes
createAssociatedTokenAccountIdempotentInstruction
(account: PublicKey, payer: PublicKey, owner: PublicKey, mint: PublicKey, tokenProgram?: PublicKey | undefined) => TransactionInstruction
Builds an `CreateIdempotent` associated-token-account instruction (creates `account` if it doesn't already exist; no-ops without failing if it does), constructed manually rather than via `@solana/spl-token`'s helper.
Yes
getDepositTxnIx
(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<...>
Builds the full instruction sequence for a deposit, without sending a transaction. If `associatedTokenAccount` equals the signer and the market is wrapped SOL, transparently wraps native SOL first (creates a temporary wrapped-SOL account funded with `amount`, deposits from it, then closes it at the end of the same transaction, refunding rent to the signer) — otherwise deposits directly from `associatedTokenAccount`.
Yes
buildSwiftDepositTx
(signedOrderParams: SignedMsgOrderParams, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, depositAmount: BN, depositSpotMarketIndex: number, tradePerpMarketIndex: number, subAccountId: number, takerAssociatedTokenAccount: PublicKey, initSwiftAccoun...
Builds (but does not send) a single transaction that deposits collateral and then places a pre-signed SignedMsg ("swift") taker perp order in one atomic bundle — useful for funding a new or under-collateralized account immediately before submitting an off-chain-signed order. Optionally also initializes the taker's `SignedMsgUserOrders` account (with 8 order slots) first, if it doesn't already exist.
Yes
createDepositTxn
(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, txParams?: TxParams | undefined, initSwiftAccount?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>
Builds (via `getDepositTxnIx`) and wraps a full deposit transaction, without sending it. Optionally also initializes the depositor's `SignedMsgUserOrders` account first, if it doesn't already exist. Forces `computeUnits` to `800_000` regardless of `txParams`/`this.txParams`.
Yes
deposit
(amount: BN, marketIndex: number, associatedTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, txParams?: TxParams | undefined, initSwiftAccount?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>
Deposits collateral into a spot market for a sub-account: builds (`createDepositTxn`), signs, and sends the transaction, then caches the confirming slot for this market so subsequent instructions built by this client can use the freshest oracle/market data.
Yes
getDepositInstruction
(amount: BN, marketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, reduceOnly?: boolean | undefined, userInitialized?: boolean | undefined, overrides?: { ...; } | undefined) => Promise<...>
Builds the raw `deposit` instruction (no SOL-wrapping helpers — see `getDepositTxnIx` for the full sequence). Assembles `remaining_accounts` from the target sub-account's current positions (forcing a fresh fetch when `userInitialized` is `true`) plus the market's mint and, if the mint uses a transfer hook, its extra account metas.
Yes
checkIfAccountExists
any
Yes
getWrappedSolAccountCreationIxs
(amount: BN, includeRent?: boolean | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<{ ixs: TransactionInstruction[]; signers: Signer[]; pubkey: PublicKey; }>
Builds the instructions to create and fund a temporary wrapped-SOL token account (via `createAccountWithSeed` + `initializeAccount`, no keypair required — derived deterministically from `authority` and a random seed). The caller is responsible for closing it after use (see the `createCloseAccountInstruction` pattern in `getDepositTxnIx`).
Yes
getTokenProgramForSpotMarket
(spotMarketAccount: SpotMarketAccount) => PublicKey
Returns the correct SPL token program (classic or Token-2022) for a spot market's mint, based on its `tokenProgramFlag`.
Yes
isToken2022
(spotMarketAccount: SpotMarketAccount) => boolean
Checks whether a spot market's mint belongs to the Token-2022 program.
Yes
isTransferHook
(spotMarketAccount: SpotMarketAccount) => boolean
Checks whether a spot market's mint has a Token-2022 transfer hook, requiring extra account metas to be appended on any instruction that moves its tokens.
Yes
addTokenMintToRemainingAccounts
(spotMarketAccount: SpotMarketAccount, remainingAccounts: AccountMeta[]) => void
Appends a spot market's mint as a read-only remaining account, but only when the mint is Token-2022 (the classic SPL Token program doesn't need the mint passed for transfers). No-op for classic SPL Token mints.
Yes
addExtraAccountMetasToRemainingAccounts
(mint: PublicKey, remainingAccounts: AccountMeta[]) => Promise<void>
Resolves and appends the Token-2022 transfer-hook program's extra required account metas for a mint. Required on any instruction transferring tokens for a mint where `isTransferHook` is `true` (e.g. deposits/withdrawals/transfers involving that market).
Yes
getAssociatedTokenAccountCreationIx
(tokenMintAddress: PublicKey, associatedTokenAddress: PublicKey, tokenProgram: PublicKey) => TransactionInstruction
Builds a (non-idempotent) instruction to create an associated token account owned by `this.wallet.publicKey`, paid for by `this.wallet.publicKey`.
Yes
createInitializeUserAccountAndDepositCollateralIxs
(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, customMaxMarginRatio?: number | undefined, poolId?: number | undefined, overrid...
Builds the full instruction sequence to create a new sub-account and fund it with an initial deposit in one transaction, without sending it. Handles: initializing `UserStats` (for `subAccountId === 0`) and the `SignedMsgUserOrders` account if missing, wrapping native SOL when depositing/donating SOL, creating the depositor's associated token account for Token-2022 mints if it doesn't exist, sourcing the deposit either from a token account or (if `fromSubAccountId` is given) via an internal transfer from another of the authority's sub-accounts, an optional donation to the market's revenue pool, an optional custom margin ratio, and unwrapping any temporary SOL account at the end.
Yes
createInitializeUserAccountAndDepositCollateral
(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, txParams?: TxParams | undefined, customMaxMarginRatio?: number | undefined, poo...
Builds (via `createInitializeUserAccountAndDepositCollateralIxs`) and wraps the full initialize-and-deposit transaction, without sending it. See that method for parameter semantics.
Yes
initializeUserAccountAndDepositCollateral
(amount: BN, userTokenAccount: PublicKey, marketIndex?: number | undefined, subAccountId?: number | undefined, name?: string | undefined, fromSubAccountId?: number | undefined, referrerInfo?: ReferrerInfo | undefined, donateAmount?: any, txParams?: TxParams | undefined, customMaxMarginRatio?: number | undefined, poo...
Creates a new sub-account and deposits initial collateral into it in a single transaction, then loads and subscribes the new sub-account via `addUser`. See `createInitializeUserAccountAndDepositCollateralIxs` for full parameter semantics.
Yes
initializeUserAccountForDevnet
(subAccountId: number | undefined, name: string | undefined, marketIndex: number, tokenFaucet: TokenFaucet, amount: BN, referrerInfo?: ReferrerInfo | undefined, txParams?: TxParams | undefined) => Promise<...>
Devnet/test-only convenience: mints test tokens from a `TokenFaucet` into a fresh associated token account, then creates a new sub-account and deposits the minted amount, all in one transaction. Not usable on mainnet (no faucet exists there).
Yes
getWithdrawalIxs
(amount: BN, marketIndex: number, associatedTokenAddress: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined) => Promise<TransactionInstruction[]>
Builds the full instruction sequence for a withdrawal, without sending a transaction. If `associatedTokenAddress` equals the signer and the market is wrapped SOL, creates a temporary wrapped-SOL account to receive the withdrawal and closes it (unwrapping to native SOL) at the end of the same transaction; otherwise, creates the destination associated token account first if it doesn't already exist.
Yes
withdraw
(amount: BN, marketIndex: number, associatedTokenAddress: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<...>
Withdraws from a user account. If deposit doesn't already exist, creates a borrow (or increases an existing one) — unless `reduceOnly` is set. Always requires the sub-account's true owning authority to sign (`this.wallet.publicKey`); a delegate cannot withdraw at all, even with `allowDelegateTransfer` enabled.
Yes
withdrawAllDustPositions
(subAccountId?: number | undefined, txParams?: TxParams | undefined, opts?: { dustPositionCountCallback?: (count: number) => void; } | undefined) => Promise<string | undefined>
Fully withdraws every spot market position on a sub-account too small to be worth carrying ("dust", as determined by `User.getSpotMarketAccountsWithDustPosition`), in one transaction. Each withdrawal requests 2x the current token amount with `reduceOnly = true` so the on-chain clamp (see `withdraw`) withdraws exactly the full balance without risking a borrow, regardless of balance drift between calculation and execution.
Yes
getWithdrawIx
(amount: BN, marketIndex: number, userTokenAccount: PublicKey, reduceOnly?: boolean | undefined, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the raw `withdraw` instruction (no SOL-wrapping/ATA-creation helpers — see `getWithdrawalIxs` for the full sequence). Signed by `this.wallet.publicKey`, which must be the sub-account's true owning authority (delegates cannot withdraw).
Yes
transferDeposit
(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number, txParams?: TxParams | undefined) => Promise<string>
Transfers a spot balance directly between two sub-accounts owned by `this.wallet.publicKey` (withdraws from `fromSubAccountId`, deposits into `toSubAccountId`) without leaving the program — no token account round-trip. Signed by `this.wallet.publicKey`, which must literally be the `authority` on *both* sub-accounts (this is the owner-to-owner path; a delegate must use `transferDepositByDelegate` instead).
Yes
getTransferDepositIx
(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number) => Promise<TransactionInstruction>
Builds the `transferDeposit` instruction. See `transferDeposit` for semantics/preconditions. Uses an already-loaded `from` sub-account's cached data if available (to build `remaining_accounts` from its current positions); otherwise fetches it directly via RPC.
Yes
transferDepositByDelegate
(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number, txParams?: TxParams | undefined) => Promise<string>
Like `transferDeposit`, but signed by a *delegate* (`this.wallet.publicKey`) rather than the sub-accounts' owning authority. On-chain requires all of: - the owner has opted in via `updateUserAllowDelegateTransfer(true)` on their `UserStats` — the transfer is rejected outright otherwise, regardless of delegate status on the sub-accounts; - `this.wallet.publicKey` is set as the `delegate` on **both** `fromSubAccountId` and `toSubAccountId` (see `updateUserDelegate`) — a delegate for only one side is not sufficient; - both sub-accounts share the same owning `authority` (this only moves funds within one owner's sub-accounts, never across different owners); - neither sub-account is bankrupt, and `fromSubAccountId !== toSubAccountId`.
Yes
getTransferDepositByDelegateIx
(amount: BN, marketIndex: number, fromSubAccountId: number, toSubAccountId: number) => Promise<TransactionInstruction>
Builds the `transferDepositByDelegate` instruction. See `transferDepositByDelegate` for the full set of on-chain preconditions. Uses an already-loaded `from` sub-account's cached data if available; otherwise fetches it directly via RPC. Sub-accounts are derived under `this.authority` (the sub-accounts' owner), not `this.wallet.publicKey` (the delegate signer).
Yes
transferPools
(depositFromMarketIndex: number, depositToMarketIndex: number, borrowFromMarketIndex: number, borrowToMarketIndex: number, depositAmount: any, borrowAmount: any, fromSubAccountId: number, toSubAccountId: number, txParams?: TxParams | undefined) => Promise<...>
Moves a deposit balance and/or a borrow balance for the same underlying mint between two sub-accounts owned by `this.wallet.publicKey` that sit in *different* isolated pools, in one on-chain instruction (`transferPools`). Unlike `transferDeposit` (which only moves a single spot balance and requires same-pool markets), this requires: `depositFromMarketIndex`/ `depositToMarketIndex` to share a mint but different `poolId`s, `borrowFromMarketIndex`/ `borrowToMarketIndex` to likewise share a mint but different pool ids, and the deposit-from/ borrow-from markets to share `fromSubAccountId`'s pool while the deposit-to/borrow-to markets share `toSubAccountId`'s pool. Both sub-accounts must be re-validated against their initial margin requirement after the move.
Yes
getTransferPoolsIx
(depositFromMarketIndex: number, depositToMarketIndex: number, borrowFromMarketIndex: number, borrowToMarketIndex: number, depositAmount: any, borrowAmount: any, fromSubAccountId: number, toSubAccountId: number, isToNewSubAccount?: boolean | undefined) => Promise<...>
Builds the `transferPools` instruction. See `transferPools` for full semantics/preconditions.
Yes
transferPerpPosition
(fromSubAccountId: number, toSubAccountId: number, marketIndex: number, amount: BN, txParams?: TxParams | undefined) => Promise<string>
Moves all or part of an open perp position from one sub-account to another via the `transferPerpPosition` instruction, settling funding on both sides first. The signer (`this.wallet.publicKey`) must independently satisfy `can_sign_for_user` (be the owning `authority` or the sub-account's `delegate`) on *both* `fromSubAccountId` and `toSubAccountId` — unlike `transferDepositByDelegate`, there is no separate `allowDelegateTransfer` opt-in gate, and the two sub-accounts are not required to share the same owning authority.
Yes
getTransferPerpPositionIx
(fromSubAccountId: number, toSubAccountId: number, marketIndex: number, amount: BN) => Promise<TransactionInstruction>
Builds the `transferPerpPosition` instruction. See `transferPerpPosition` for full semantics.
Yes
specialTransferPerpPositionToVamm
(userAccountPublicKey: PublicKey, marketIndex: number, amount?: any, txParams?: TxParams | undefined) => Promise<string>
Special-account-only: transfers all or part of a position on the protocol's designated "vAMM hedger" account directly into the AMM's own inventory, offsetting the vAMM's synthetic position. On-chain requires `userAccountPublicKey`'s `specialUserStatus` to be `VammHedger`, the position's direction to already be opposite the AMM's net inventory (`amm.baseAssetAmountWithAmm`), and the transferred amount to fit within the AMM's available capacity for that direction. Not usable on a regular trading sub-account.
Yes
getSpecialTransferPerpPositionToVammIx
(userAccountPublicKey: PublicKey, marketIndex: number, amount?: any) => Promise<TransactionInstruction>
Builds the `specialTransferPerpPositionToVamm` instruction. See `specialTransferPerpPositionToVamm` for full semantics/preconditions.
Yes
depositIntoIsolatedPerpPosition
(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Deposits collateral from a token account directly into an isolated perp position's own segregated balance (as opposed to `deposit`, which credits the sub-account's general/cross balance). The position's quote spot market is derived from `perpMarketIndex`'s `quoteSpotMarketIndex`.
Yes
getDepositIntoIsolatedPerpPositionIx
(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `depositIntoIsolatedPerpPosition` instruction. See `depositIntoIsolatedPerpPosition` for semantics.
Yes
transferIsolatedPerpPositionDeposit
(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, txParams?: TxParams | undefined, trySettle?: boolean | undefined, noBuffer?: boolean | undefined) => Promise<...>
Moves collateral between an isolated perp position's segregated balance and the sub-account's general/cross balance, in the same underlying quote spot market (derived from `perpMarketIndex`). Positive `amount` moves collateral **from general into the isolated position**; negative moves it **from the isolated position back to general**. If the requested outflow from the isolated position would exceed its current deposit (i.e. it needs unrealized PnL to be realized first, or the caller wants to withdraw everything), prepends a `TRY_SETTLE` settle-PnL instruction for `perpMarketIndex` before the transfer.
Yes
getTransferIsolatedPerpPositionDepositIx
(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, noAmountBuffer?: boolean | undefined, signingAuthority?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `transferIsolatedPerpPositionDeposit` instruction (without the `TRY_SETTLE` prepend — see `transferIsolatedPerpPositionDeposit` for the full sequence). See that method for the sign/precision convention of `amount`.
Yes
withdrawFromIsolatedPerpPosition
(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined, txParams?: TxParams | undefined) => Promise<string>
Withdraws collateral out of the protocol directly from an isolated perp position's segregated balance to a token account (as opposed to `withdraw`, which draws from the sub-account's general/cross balance). See `getWithdrawFromIsolatedPerpPositionIxsBundle` for the settle-PnL and amount-clamping logic applied first.
Yes
getWithdrawFromIsolatedPerpPositionIxsBundle
(amount: BN, perpMarketIndex: number, subAccountId?: number | undefined, userTokenAccount?: PublicKey | undefined) => Promise<TransactionInstruction[]>
Builds the full instruction sequence for `withdrawFromIsolatedPerpPosition`: computes the position's claimable unrealized PnL, and clamps `amount` to the isolated deposit plus that claimable PnL — the on-chain `amount` is `u64` with no "withdraw all" sentinel (unlike the sibling `transferIsolatedPerpPositionDeposit`, whose `i64` `amount` treats `i64::MIN` as one), so passing `BN` values larger than the withdrawable balance is how a caller requests "withdraw everything". Also prepends a `TRY_SETTLE` settle-PnL instruction for `perpMarketIndex` whenever the request draws into unrealized (unsettled) PnL. Note the clamp is a build-time estimate: if the settle realizes less than the claimable PnL (e.g. the market's PnL pool is short), the withdraw can still fail on-chain with `InsufficientCollateral`.
Yes
getWithdrawFromIsolatedPerpPositionIx
(amount: BN, perpMarketIndex: number, userTokenAccount: PublicKey, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the raw `withdrawFromIsolatedPerpPosition` instruction (no settle-PnL/clamping — see `getWithdrawFromIsolatedPerpPositionIxsBundle` for the full sequence).
Yes
updateSpotMarketCumulativeInterest
(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Permissionless crank: forces a spot market to accrue interest (updating `cumulativeDepositInterest`/`cumulativeBorrowInterest` and TWAP stats) up to the current slot. The instruction's accounts impose no authority/hot-role check beyond the transaction fee payer — anyone can call this to keep a market's interest current between organic deposit/withdraw/borrow activity.
Yes
updateSpotMarketCumulativeInterestIx
(marketIndex: number) => Promise<TransactionInstruction>
Builds the `updateSpotMarketCumulativeInterest` instruction. See `updateSpotMarketCumulativeInterest` for semantics.
Yes
openPosition
(direction: PositionDirection, amount: BN, marketIndex: number, limitPrice?: any, subAccountId?: number | undefined) => Promise<string>
Opens/increases a perp position with a market order (or a limit order if `limitPrice` is given), filled immediately against the AMM/makers via `placeAndTakePerpOrder`.
Yes
sendSignedTx
(tx: VersionedTransaction | Transaction, opts?: ConfirmOptions | undefined) => Promise<string>
Submits and confirms a transaction that has already been fully signed elsewhere (e.g. by an external/hardware wallet flow), skipping this client's normal build-and-sign step entirely. Not order/instruction-specific — works for any pre-signed `Transaction`/`VersionedTransaction`.
Yes
prepareMarketOrderTxs
(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[] | undefined, txParams?: TxParams | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | undefined, positio...
Builds (without sending) the set of transactions needed to place a market order and, for legacy (non-versioned) transactions, a companion transaction that fills it against the AMM. Also builds optional companion transactions to cancel the market's existing orders first and/or settle PnL after the fill. Used by `sendMarketOrderAndGetSignedFillTx`.
Yes
sendMarketOrderAndGetSignedFillTx
(orderParams: OptionalOrderParams, userAccountPublicKey: PublicKey, userAccount: UserAccount, makerInfo?: MakerInfo | MakerInfo[] | undefined, txParams?: TxParams | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | undefined) => Prom...
Sends a market order transaction and, for legacy (non-versioned) transactions, also returns a co-signed fill transaction the caller can broadcast themselves to fill the order against the AMM (useful when the caller wants to control fill timing/submission rather than relying on a keeper). Internally builds transactions via `prepareMarketOrderTxs`, signs them all, then sends only `marketOrderTx`.
Yes
placePerpOrder
(orderParams: OptionalOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
Places a single perp order without attempting to fill it in the same instruction — the order rests until a keeper (or a `placeAndTake*`/signed-msg fill) matches it. Use `placeAndTakePerpOrder` instead if the caller wants an immediate attempt to fill against the AMM/makers.
Yes
getBuilderEscrowAccountMeta
any
Returns the RevenueShareEscrow account meta for the placing user when `orderParams` carries a builder code (`builderIdx` + `builderFeeTenthBps`), otherwise `undefined`. The on-chain handlers peek for this account last in `remaining_accounts`, so callers must push it after the market/oracle/maker accounts.
Yes
getTakerEscrowAccountMeta
any
Returns the AccountMeta for the taker's RevenueShareEscrow when a fill of the taker's order must include it: the order carries a builder code, or the taker is referred (their escrow was initialized with a referrer). Returns `undefined` when neither applies so no account meta is added to the transaction. The on-chain handlers peek for this account last in `remaining_accounts`, so callers must push it after the market/oracle/maker accounts. Throws when `takerEscrow` does not belong to `takerAuthority`.
Yes
getPlacePerpOrderIx
(orderParams: OptionalOrderParams, subAccountId?: number | undefined, depositToTradeArgs?: { isMakingNewAccount: boolean; depositMarketIndex: number; } | undefined) => Promise<...>
Builds the `placePerpOrder` instruction. See `placePerpOrder` for semantics. Automatically attaches the placing user's `RevenueShareEscrow` account when `orderParams` carries a builder code (`builderIdx`/`builderFeeTenthBps`).
Yes
updateAMMs
(marketIndexes: number[], txParams?: TxParams | undefined) => Promise<string>
Yes
getUpdateAMMsIx
(marketIndexes: number[]) => Promise<TransactionInstruction>
Yes
settleExpiredMarket
(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Admin instruction: finalizes settlement pricing for a perp market that has already been put into `Settlement` status (`market.status === MarketStatus.SETTLEMENT`), snapping the market's settlement price/oracle-twap so every position can subsequently be closed at that fixed price via `settlePNL`. Requires a warm- or cold-tier admin signer (`check_warm`).
Yes
getSettleExpiredMarketIx
(marketIndex: number) => Promise<TransactionInstruction>
Builds the `settleExpiredMarket` instruction. See `settleExpiredMarket` for semantics. Signs with `this.wallet.publicKey` when not subscribed, or the state's `coldAdmin` when subscribed — the on-chain constraint accepts either a warm- or cold-tier admin, so passing `coldAdmin` always satisfies it regardless of which tier the actual signer holds.
Yes
settleExpiredMarketPoolsToRevenuePool
(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Admin instruction: sweeps a settled (`MarketStatus.SETTLEMENT`) perp market's remaining fee pool and PnL pool balances into the quote spot market's revenue pool, once all user positions in the market have been settled out. Requires a warm- or cold-tier admin signer.
Yes
getSettleExpiredMarketPoolsToRevenuePoolIx
(perpMarketIndex: number) => Promise<TransactionInstruction>
Builds the `settleExpiredMarketPoolsToRevenuePool` instruction. See `settleExpiredMarketPoolsToRevenuePool` for semantics.
Yes
cancelOrder
(orderId?: number | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, overrides?: { withdrawIsolatedDepositAmount?: any; } | undefined) => Promise<...>
Cancel an open order and broadcast the transaction. When `orderId` is `undefined` (omitted or passed explicitly), the instruction is sent with a `null` order ID and the program cancels the most recently placed order on-chain via `get_last_order_id`. This is safe to use in a composed transaction where a place instruction runs first and the assigned order ID is not yet known. Note: when `orderId` is `undefined` and `overrides.withdrawIsolatedDepositAmount` is also provided, `getOrder` will return `undefined` (the ID is unknown client-side), causing the withdraw path to throw — supply an explicit `orderId` in that case.
Yes
getCancelOrderIx
(orderId?: number | undefined, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Build a `cancelOrder` instruction for the given order. When `orderId` is `undefined` (omitted or passed explicitly), the instruction is built with a `null` order ID (`orderId ?? null`). The program interprets a `null` ID as "cancel the user's most recently placed order" (via `get_last_order_id` on-chain). This is useful when composing a multi-instruction transaction where a place instruction precedes the cancel and the program-assigned order ID is not yet known at build time. When `orderId` is supplied, only that specific order is cancelled.
Yes
cancelOrderByUserId
(userOrderId: number, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
Cancel an open order identified by its caller-supplied `userOrderId` and broadcast the transaction.
Yes
getCancelOrderByUserIdIx
(userOrderId: number, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `cancelOrderByUserId` instruction. See `cancelOrderByUserId` for semantics.
Yes
cancelOrdersByIds
(orderIds?: number[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, user?: User | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<...>
Sends a transaction to cancel the provided order ids.
Yes
getCancelOrdersByIdsIx
(orderIds?: number[] | undefined, subAccountId?: number | undefined, user?: User | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Returns the transaction instruction to cancel the provided order ids.
Yes
cancelOrders
(marketType?: MarketType | undefined, marketIndex?: number | undefined, direction?: PositionDirection | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
Cancel all of a user's open orders matching the given (optional) filters, and broadcast the transaction. Any filter left `undefined` is not applied — calling with no filters cancels every open order on the sub-account.
Yes
getCancelOrdersIx
(marketType: MarketType | null | undefined, marketIndex: number | null | undefined, direction: PositionDirection | null | undefined, subAccountId?: number | undefined) => Promise<...>
Builds the `cancelOrders` instruction. See `cancelOrders` for filter semantics (`null`/`undefined` on any of `marketType`/`marketIndex`/`direction` means "don't filter on that field").
Yes
cancelAndPlaceOrders
(cancelOrderParams: { marketType?: MarketType; marketIndex?: number; direction?: PositionDirection; }, placeOrderParams: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<...>
Atomically cancels orders matching the given filters and places new orders in a single transaction (cancel instruction first, then place). Useful for order replacement flows (e.g. re-quoting) where the old orders must not be fillable in the gap before the new ones land.
Yes
placeOrders
(params: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined, optionalIxs?: TransactionInstruction[] | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
Places a batch of orders (perp and/or spot) in a single instruction. None are filled in-instruction — each rests until matched by a keeper or a subsequent fill/place-and-take.
Yes
preparePlaceOrdersTx
(params: OrderParams[], txParams?: TxParams | undefined, subAccountId?: number | undefined, optionalIxs?: TransactionInstruction[] | undefined, isolatedPositionDepositAmount?: any) => Promise<...>
Builds (without sending) the `placeOrders` transaction. See `placeOrders` for semantics.
Yes
getPlaceOrdersIx
(params: OptionalOrderParams[], subAccountId?: number | undefined, overrides?: { authority?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Builds the `placeOrders` instruction. See `placeOrders` for semantics. Attaches the placing user's `RevenueShareEscrow` once (not per-order) when any order in the batch carries a builder code — the on-chain handler expects a single escrow account for the whole batch.
Yes
getPlaceOrdersAndSetPositionMaxLevIx
(params: OptionalOrderParams[], positionMaxLev: number, subAccountId?: number | undefined) => Promise<TransactionInstruction[]>
Builds a `placeOrders` instruction followed by an instruction that sets a custom max-leverage margin ratio on the position for `params[0]`'s market. Unlike `placeOrders`, this bypasses the `RevenueShareEscrow` attachment for builder-coded orders (uses the raw `program.instruction` call directly) — don't use it for batches containing a builder-coded order.
Yes
placeScaleOrders
(params: ScaleOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<string>
Places multiple limit orders (`params.orderCount`, 2-32) distributed across a price range in a single instruction, none filled in-instruction — each rests until matched.
Yes
preparePlaceScaleOrdersTx
(params: ScaleOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promise<{ placeScaleOrdersTx: VersionedTransaction | Transaction; }>
Builds (without sending) the `placeScaleOrders` transaction. See `placeScaleOrders` for semantics.
Yes
getPlaceScaleOrdersIx
(params: ScaleOrderParams, subAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `placeScaleOrders` instruction. See `placeScaleOrders` for semantics.
Yes
fillPerpOrder
(userAccountPublicKey: PublicKey, user: UserAccount, order?: Pick<Order, "marketIndex" | "orderId"> | undefined, makerInfo?: MakerInfo | MakerInfo[] | undefined, txParams?: TxParams | undefined, fillerSubAccountId?: number | undefined, fillerAuthority?: PublicKey | undefined, hasBuilderFee?: boolean | undefined, tak...
Keeper instruction that fills a resting DLOB perp order against one or more makers (or the AMM/vAMM when no maker matches). Permissionless — any signer can act as filler and earns the filler reward. Does not place or cancel orders itself; it only matches an order that is already on the book.
Yes
getFillPerpOrderIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, order?: Pick<Order, "marketIndex" | "orderId"> | undefined, makerInfo?: MakerInfo | MakerInfo[] | undefined, fillerSubAccountId?: number | undefined, isSignedMsg?: boolean | undefined, fillerAuthority?: PublicKey | undefined, hasBuilderFee?: boolean | undef...
Builds the `fillPerpOrder` instruction. See `fillPerpOrder` for semantics. Assembles maker accounts and the taker's `RevenueShareEscrow` (when owed) into `remainingAccounts` in the order the on-chain handler expects: user/maker market+oracle accounts first, then each maker's `(maker, makerStats)` pair, then the taker escrow meta last.
Yes
getRevertFillIx
(fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `revertFill` instruction. Used by keepers as a same-transaction fallback after a simulated fill fails downstream (e.g. a subsequent instruction errors): it only asserts the filler's `lastActiveSlot` equals the current slot and otherwise is a no-op, letting the keeper's earlier fill CPI effects be discarded by the transaction failing cleanly rather than with a confusing downstream error.
Yes
placeSpotOrder
(_orderParams: OptionalOrderParams, _txParams?: TxParams | undefined, _subAccountId?: number | undefined) => Promise<string>
Disabled. Spot DLOB trading (order placement/matching) is turned off in this deployment — spot balances, deposits, withdrawals, and swaps remain available.
Yes
preparePlaceSpotOrderTx
(_orderParams: OptionalOrderParams, _txParams?: TxParams | undefined, _subAccountId?: number | undefined) => Promise<void>
Disabled. See `placeSpotOrder`.
Yes
getPlaceSpotOrderIx
(_orderParams: OptionalOrderParams, _subAccountId?: number | undefined, _overrides?: { authority?: PublicKey; } | undefined) => Promise<TransactionInstruction>
Disabled. See `placeSpotOrder`.
Yes
fillSpotOrder
(_userAccountPublicKey: PublicKey, _user: UserAccount, _order?: Pick<Order, "marketIndex" | "orderId"> | undefined, _fulfillmentConfig?: unknown, _makerInfo?: MakerInfo | ... 1 more ... | undefined, _txParams?: TxParams | undefined) => Promise<...>
Disabled. See `placeSpotOrder`.
Yes
getFillSpotOrderIx
(_userAccountPublicKey: PublicKey, _userAccount: UserAccount, _order?: Pick<Order, "marketIndex" | "orderId"> | undefined, _fulfillmentConfig?: unknown, _makerInfo?: MakerInfo | ... 1 more ... | undefined, _fillerPublicKey?: PublicKey | undefined) => Promise<...>
Disabled. See `placeSpotOrder`.
Yes
swap
({ swapClient, jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, v6, quote, onlyDirectRoutes, }: { swapClient?: UnifiedSwapClient | SwapClient; jupiterClient?: JupiterClient; outMarketIndex: number; inMarketIndex: n...
Swaps one spot-market token for another inside the user's velocity account: brackets the external swap provider's instructions between the program's `beginSwap`/`endSwap` instructions in a single transaction, so the swap is settled directly against the user's deposits/vault balances rather than the wallet's own token accounts. Sends and confirms the transaction.
Yes
getTitanSwapIx
({ titanClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, userAccountPublicKey, }: { titanClient: TitanClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; inAssociatedToken...
Builds the instruction list for a Titan-routed swap: creates any missing associated token accounts, wraps Titan's routing instructions between `beginSwap`/`endSwap`. See `swap` for parameter semantics; `amount` is in the "in" token's mint decimals.
Yes
getJupiterSwapIxV6
({ jupiterClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, quote, reduceOnly, userAccountPublicKey, }: { jupiterClient: JupiterClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; inAs...
Builds the instruction list for a Jupiter v6-routed swap: fetches a quote if none is passed, creates any missing associated token accounts, and wraps Jupiter's routing instructions between `beginSwap`/`endSwap`. See `swap` for parameter semantics; `amount` is in the "in" token's mint decimals.
Yes
getSwapIx
({ outMarketIndex, inMarketIndex, amountIn, inTokenAccount, outTokenAccount, limitPrice, reduceOnly, userAccountPublicKey, }: { outMarketIndex: number; inMarketIndex: number; amountIn: BN; inTokenAccount: PublicKey; outTokenAccount: PublicKey; limitPrice?: any; reduceOnly?: SwapReduceOnly; userAccountPublicKey?: Pub...
Builds the `beginSwap`/`endSwap` instruction pair that must bracket an external swap provider's routing instructions in the same transaction. `beginSwap` snapshots the token account balances and moves `amountIn` out of the in-market vault; `endSwap` reconciles the post-swap token balances back into the user's velocity deposits, enforces `limitPrice` and `reduceOnly`, and validates both spot markets' oracles are fresh/valid.
Yes
getSwapIxV2
({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, userAccountPublicKey, }: { swapClient: UnifiedSwapClient; outMarketIndex: number; inMarketIndex: number; outAssociatedTokenAccount?: PublicKey; in...
Builds the instruction list for a swap routed through a `UnifiedSwapClient` (the current preferred swap path). Creates any missing associated token accounts and wraps the client's routing instructions between `beginSwap`/`endSwap`. See `swap` for parameter semantics; `amount` is in the "in" token's mint decimals (or "out" token's decimals when `swapMode` is `ExactOut`).
Yes
stakeForMSOL
({ amount }: { amount: BN; }) => Promise<TxSigAndSlot>
Converts a portion of the user's deposited wSOL (spot market index 1) into mSOL (spot market index 2) by staking it with Marinade Finance, then swapping the resulting mSOL back into the velocity deposit via `beginSwap`/`endSwap`. Sends and confirms the transaction.
Yes
getStakeForMSOLIx
({ amount, userAccountPublicKey, }: { amount: BN; userAccountPublicKey?: PublicKey; }) => Promise<TransactionInstruction[]>
Builds the instruction list for `stakeForMSOL`: wraps a Marinade `deposit` (wSOL to mSOL) between the velocity `beginSwap`/`endSwap` pair so the mSOL lands back in the user's velocity deposit for spot market index 2. Hardcodes wSOL as market index 1 and mSOL as market index 2.
Yes
triggerOrder
(userAccountPublicKey: PublicKey, user: UserAccount, order: Order, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
Keeper instruction: activates a resting trigger order (stop/take-profit, perp or spot) once its `triggerPrice`/`triggerCondition` has been met, turning it into a fillable market/limit order. Permissionless — any signer can act as filler and earns a small keeper fee. Does not fill the order itself; a separate fill instruction (or place-and-take) is still required.
Yes
getTriggerOrderIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, order: Order, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `triggerOrder` instruction. See `triggerOrder` for semantics.
Yes
forceCancelOrders
(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
Keeper instruction: cancels a user's open, non-position-reducing orders when the user fails their initial margin requirement (reverts with `SufficientCollateral` if the user still meets it, or with `UserIsBeingLiquidated`/`UserBankrupt` if either is set). Charges the user a per-cancelled-order fee paid to the filler. Permissionless — any signer can act as filler.
Yes
getForceCancelOrdersIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `forceCancelOrders` instruction. See `forceCancelOrders` for semantics.
Yes
updateUserIdle
(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
Keeper instruction: marks a user account idle after confirming (via `validate_user_is_idle`) it has been inactive long enough — the inactivity window is shorter (accelerated) when the user's equity is below 1000 USDC (QUOTE_PRECISION, 1e6). Idle users are excluded from some keeper crank workloads. Permissionless — any signer can act as filler.
Yes
getUpdateUserIdleIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `updateUserIdle` instruction. See `updateUserIdle` for semantics.
Yes
logUserBalances
(userAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Debug/monitoring instruction: emits the user's equity, each non-zero spot position's signed token amount (native mint decimals), and each open perp position's unrealized PnL (QUOTE_PRECISION, 1e6) as program logs. Has no on-chain state effect. Exchange must not be paused.
Yes
getLogUserBalancesIx
(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `logUserBalances` instruction. See `logUserBalances` for semantics. Fetches the user account fresh from the RPC (rather than relying on a cached/passed-in account) to build `remainingAccounts`.
Yes
updateUserStatsReferrerStatus
(userAuthority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Recomputes and updates the `isReferrer` flag on a `UserStats` account from its current referrer-related fields. Permissionless — anyone can trigger the refresh for any authority.
Yes
getUpdateUserStatsReferrerStatusIx
(userAuthority: PublicKey) => Promise<TransactionInstruction>
Builds the `updateUserStatsReferrerStatus` instruction. See `updateUserStatsReferrerStatus` for semantics.
Yes
updateUserOpenOrdersCount
(userAccountPublicKey: PublicKey, user: UserAccount, txParams?: TxParams | undefined, fillerPublicKey?: PublicKey | undefined) => Promise<...>
Keeper instruction: recounts `user.orders` and rewrites `openOrders`/`hasOpenOrder`/ `openAuctions`/`hasOpenAuction` to match the account's actual order state — a repair instruction for when these cached counters have drifted. Permissionless — any signer can act as filler.
Yes
getUpdateUserOpenOrdersCountIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, fillerPublicKey?: PublicKey | undefined) => Promise<TransactionInstruction>
Builds the `updateUserOpenOrdersCount` instruction. See `updateUserOpenOrdersCount` for semantics.
Yes
placeAndTakePerpOrder
(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, successCondition?: PlaceAndTakeOrderSuccessCondition | undefined, auctionDurationPercentage?: number | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, takerEscrow?: RevenueShareEscrowAccount | undefined...
Places a perp order and immediately attempts to fill it in the same instruction against the AMM and/or the supplied `makerInfo`. `orderParams.postOnly` must be `PostOnlyParams.NONE` — the on-chain handler rejects post-only orders here (use `placeAndMakePerpOrder` instead for a post-only maker order). If the order is immediate-or-cancel (or `successCondition`/ `auctionDurationPercentage` is set) and still open after the fill attempt, it is cancelled in the same instruction.
Yes
preparePlaceAndTakePerpOrderWithAdditionalOrders
(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | undefined, exitEarlyIfSimFails?: boolean |...
Builds (without sending) a `placeAndTakePerpOrder` transaction bundled with optional bracket orders (e.g. TP/SL) in the same transaction, plus optional companion transactions to cancel the market's existing orders first and/or settle PnL after. Reuses a single recent blockhash across all built transactions to save RPC round trips.
Yes
placeAndTakePerpWithAdditionalOrders
(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, bracketOrdersParams?: OptionalOrderParams[] | undefined, txParams?: TxParams | undefined, subAccountId?: number | undefined, cancelExistingOrders?: boolean | undefined, settlePnl?: boolean | undefined, exitEarlyIfSimFails?: boolean |...
Builds, signs, and sends a `placeAndTakePerpOrder` transaction bundled with bracket orders via `preparePlaceAndTakePerpOrderWithAdditionalOrders`, and returns the signed (but unsent) companion cancel/settle-PnL transactions for the caller to broadcast separately.
Yes
getPlaceAndTakePerpOrderIx
(orderParams: OptionalOrderParams, makerInfo?: MakerInfo | MakerInfo[] | undefined, successCondition?: PlaceAndTakeOrderSuccessCondition | undefined, auctionDurationPercentage?: number | undefined, subAccountId?: number | undefined, overrides?: { ...; } | undefined, takerEscrow?: RevenueShareEscrowAccount | undefine...
Builds the `placeAndTakePerpOrder` instruction. See `placeAndTakePerpOrder` for semantics.
Yes
placeAndMakePerpOrder
(orderParams: OptionalOrderParams, takerInfo: TakerInfo, txParams?: TxParams | undefined, subAccountId?: number | undefined, takerEscrow?: RevenueShareEscrowAccount | undefined) => Promise<...>
Places a resting maker order and, in the same instruction, fills a specific counterparty taker order (`takerInfo.order`) against it. `orderParams` must be an immediate-or-cancel, post-only (not `PostOnlyParams.NONE`) limit order — the on-chain handler rejects any other shape with `InvalidOrderIOCPostOnly`.
Yes
getPlaceAndMakePerpOrderIx
(orderParams: OptionalOrderParams, takerInfo: TakerInfo, subAccountId?: number | undefined, takerEscrow?: RevenueShareEscrowAccount | undefined) => Promise<...>
Builds the `placeAndMakePerpOrder` instruction. See `placeAndMakePerpOrder` for semantics.
Yes
signSignedMsgOrderParamsMessage
(orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => SignedMsgOrderParams
Borsh-encodes a swift/signed-msg order message and signs the resulting hex-encoded buffer with `signMessage` (this client's wallet keypair by default). The returned payload is what a swift/signed-msg service or a taker-facing `placeSignedMsgTakerOrder` expects.
Yes
buildDepositAndPlaceSignedMsgOrderRequest
(depositTx: VersionedTransaction, orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => { ...; }
Bundles a pre-signed deposit transaction with a signed swift/signed-msg order message into the request shape the Swift service expects for a "deposit and place" flow (e.g. depositing new collateral and placing an order off-chain in one round trip before either lands on-chain).
Yes
encodeSignedMsgOrderParamsMessage
(orderParamsMessage: SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage, delegateSigner?: boolean | undefined) => Buffer
Borsh-encodes a swift/signed-msg order message using the program's IDL type coder. Used internally by `signSignedMsgOrderParamsMessage`; call directly if you need the raw encoded bytes without also signing them.
Yes
decodeSignedMsgOrderParamsMessage
(encodedMessage: Buffer, delegateSigner?: boolean | undefined) => SignedMsgOrderParamsMessage | SignedMsgOrderParamsDelegateMessage
Decodes a borsh-encoded swift/signed-msg order message. Zero-pads the input by 128 bytes before decoding so messages encoded by an older IDL (missing newer, all-`Option` fields) still decode instead of throwing on a too-short buffer. Note: this padding assumes any newer fields added to the message type are `Option`s — a 128+ byte non-optional field addition could still fail to decode older messages correctly.
Yes
signMessage
(message: Uint8Array<ArrayBufferLike>, keypair?: Keypair | undefined) => Buffer
Signs arbitrary bytes with a raw ed25519 detached signature (not a Solana transaction signature) — the primitive used to sign swift/signed-msg order messages.
Yes
placeSignedMsgTakerOrder
(signedSignedMsgOrderParams: SignedMsgOrderParams, marketIndex: number, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined, txParams?: TxParams | undefined...
Submits a previously off-chain-signed swift/signed-msg taker order on-chain: verifies the ed25519 signature via the sysvar-instructions program and records the order in the taker's `SignedMsgUserOrders` account (see `initializeSignedMsgUserOrders`, required beforehand). This only registers the order — it does not place or fill it against the market; a keeper (or `placeAndMakeSignedMsgPerpOrder`) still performs the actual place/fill.
Yes
getPlaceSignedMsgTakerPerpOrderIxs
(signedSignedMsgOrderParams: SignedMsgOrderParams, marketIndex: number, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined) => Promise<...>
Builds the two instructions for `placeSignedMsgTakerOrder`: an ed25519-signature-verify instruction (must be placed at the sysvar-instructions index this function assumes — see `precedingIxs`/`overrideCustomIxIndex`) followed by the `placeSignedMsgTakerOrder` program instruction. See `placeSignedMsgTakerOrder` for semantics.
Yes
placeAndMakeSignedMsgPerpOrder
(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array<ArrayBufferLike>, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, orderParams: OptionalOrderParams, txParams?: TxParams | undefined, subAccountId?: number | undefined...
Verifies and registers a taker's off-chain signed swift/signed-msg order (same as `placeSignedMsgTakerOrder`) and, in the same transaction, places a maker order and fills the taker order against it in one shot — the signed-msg analog of `placeAndMakePerpOrder`. `orderParams` (the maker order) is subject to the same IOC/post-only/limit requirement as `placeAndMakePerpOrder`.
Yes
getPlaceAndMakeSignedMsgPerpOrderIxs
(signedSignedMsgOrderParams: SignedMsgOrderParams, signedMsgOrderUuid: Uint8Array<ArrayBufferLike>, takerInfo: { taker: PublicKey; takerStats: PublicKey; takerUserAccount: UserAccount; signingAuthority: PublicKey; }, orderParams: OptionalOrderParams, subAccountId?: number | undefined, precedingIxs?: TransactionInstr...
Builds the instructions for `placeAndMakeSignedMsgPerpOrder`: the taker signature-verify + registration instructions from `getPlaceSignedMsgTakerPerpOrderIxs`, followed by the `placeAndMakeSignedMsgPerpOrder` program instruction. See `placeAndMakeSignedMsgPerpOrder` for semantics.
Yes
preparePlaceAndTakeSpotOrder
(_orderParams: OptionalOrderParams, _fulfillmentConfig?: unknown, _makerInfo?: MakerInfo | undefined, _txParams?: TxParams | undefined, _subAccountId?: number | undefined) => Promise<...>
Disabled. See `placeSpotOrder`.
Yes
placeAndTakeSpotOrder
(_orderParams: OptionalOrderParams, _fulfillmentConfig?: unknown, _makerInfo?: MakerInfo | undefined, _txParams?: TxParams | undefined, _subAccountId?: number | undefined) => Promise<...>
Disabled. See `placeSpotOrder`.
Yes
getPlaceAndTakeSpotOrderIx
(_orderParams: OptionalOrderParams, _fulfillmentConfig?: unknown, _makerInfo?: MakerInfo | undefined, _subAccountId?: number | undefined) => Promise<TransactionInstruction>
Disabled. See `placeSpotOrder`.
Yes
placeAndMakeSpotOrder
(_orderParams: OptionalOrderParams, _takerInfo: TakerInfo, _fulfillmentConfig?: unknown, _txParams?: TxParams | undefined, _subAccountId?: number | undefined) => Promise<...>
Disabled. See `placeSpotOrder`.
Yes
getPlaceAndMakeSpotOrderIx
(_orderParams: OptionalOrderParams, _takerInfo: TakerInfo, _fulfillmentConfig?: unknown, _subAccountId?: number | undefined) => Promise<TransactionInstruction>
Disabled. See `placeSpotOrder`.
Yes
closePosition
(marketIndex: number, limitPrice?: any, subAccountId?: number | undefined) => Promise<string>
Closes (or reduces to zero) the caller's entire perp position in `marketIndex` with a reduce-only market order (or limit order if `limitPrice` is given), filled immediately via `placeAndTakePerpOrder`.
Yes
modifyPerpOrder
(orderId: number, newBaseAmount?: any, newLimitPrice?: any, newOraclePriceOffset?: any) => Promise<string>
Modifies an open order by closing it and replacing it with a new order.
Yes
modifyPerpOrderByUserOrderId
(userOrderId: number, newBaseAmount?: any, newLimitPrice?: any, newOraclePriceOffset?: any) => Promise<string>
Modifies an open order by closing it and replacing it with a new order.
Yes
modifyOrder
(orderParams: { orderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; newOraclePriceOffset?: any; newTriggerPrice?: any; newTriggerCondition?: OrderTriggerCondition; ... 7 more ...; policy?: number; }, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promi...
Modifies an open order (spot or perp) by closing it and replacing it with a new order in one instruction. Only fields present (non-`undefined`) in `orderParams` are changed; the rest of the order is left as-is.
Yes
getModifyOrderIx
({ orderId, newDirection, newBaseAmount, newLimitPrice, newOraclePriceOffset, newTriggerPrice, newTriggerCondition, auctionDuration, auctionStartPrice, auctionEndPrice, reduceOnly, postOnly, bitFlags, maxTs, policy, }: { orderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; new...
Builds the `modifyOrder` instruction. See `modifyOrder` for field semantics/precisions.
Yes
modifyOrderByUserOrderId
(orderParams: { userOrderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: any; newOraclePriceOffset?: any; newTriggerPrice?: any; newTriggerCondition?: OrderTriggerCondition; ... 7 more ...; maxTs?: any; }, txParams?: TxParams | undefined, subAccountId?: number | undefined) => Promi...
Modifies an open order (identified by its caller-supplied `userOrderId`) by closing it and replacing it with a new order in one instruction. Note: unlike `modifyOrder`, omitted `reduceOnly`/`bitFlags` are sent as `false`/`null` respectively rather than "leave unchanged" — passing this method's `orderParams` without `reduceOnly` will explicitly clear an existing reduce-only flag on the order.
Yes
getModifyOrderByUserIdIx
({ userOrderId, newDirection, newBaseAmount, newLimitPrice, newOraclePriceOffset, newTriggerPrice, newTriggerCondition, auctionDuration, auctionStartPrice, auctionEndPrice, reduceOnly, postOnly, bitFlags, maxTs, policy, }: { userOrderId: number; newDirection?: PositionDirection; newBaseAmount?: any; newLimitPrice?: ...
Builds the `modifyOrderByUserOrderId` instruction. See `modifyOrderByUserOrderId` for field semantics/precisions, including the `reduceOnly`/`bitFlags` default-clearing note.
Yes
settlePNLs
(users: { settleeUserAccountPublicKey: PublicKey; settleeUserAccount: UserAccount; }[], marketIndexes: number[], opts?: { filterInvalidMarkets?: boolean; } | undefined, txParams?: TxParams | undefined) => Promise<...>
Keeper instruction: settles unrealized perp PnL to/from each user's quote spot balance for every `(user, marketIndex)` pair, one `settlePnl` instruction per pair in a single transaction. Permissionless — any signer can act as the settling authority. Defaults to `computeUnits: 1_400_000` if `txParams` is not supplied, since settling several users/markets in one transaction is compute-heavy.
Yes
getSettlePNLsIxs
(users: { settleeUserAccountPublicKey: PublicKey; settleeUserAccount: UserAccount; }[], marketIndexes: number[], revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
Builds one `settlePnl` instruction per `(user, marketIndex)` combination in `users` x `marketIndexes`. See `settlePNL`/`settlePNLIx` for per-instruction semantics.
Yes
settlePNL
(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, optionalIxs?: TransactionInstruction[] | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
Keeper instruction: settles a single user's unrealized perp PnL on one market to/from their quote spot balance. Reads the live oracle (falling back to the AMM's freshness check only if the live oracle is degraded); requires the market not be in `Settlement` status (use `settleExpiredMarket`/expired-position settlement for that) and the quote spot market vault balance to reconcile afterward. Permissionless — any signer can act as the settling authority.
Yes
settlePNLIx
(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndex: number, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
Builds the `settlePnl` instruction. See `settlePNL` for semantics. When `revenueShareEscrowMap` is passed, inspects the settlee's `RevenueShareEscrow` for completed, unpaid builder-fee or referral-reward orders on `marketIndex` and, if found, appends the escrow PDA plus each relevant builder/referrer authority to `remainingAccounts` so the on-chain sweep can pay them during settlement. Falls back to attaching just the escrow PDA (for lazy cleanup) when the settlee has any builder order but isn't present in the map (stale-cache case).
Yes
settleMultiplePNLs
(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined, txParams?: TxParams | undefined) => Promise<...>
Keeper instruction: settles one user's unrealized perp PnL across several markets in a single `settleMultiplePnl` instruction/transaction. Fits at most ~4 markets per transaction (see `settleMultiplePNLsMultipleTxs` for more). Permissionless — any signer can act as the settling authority.
Yes
settleMultiplePNLsMultipleTxs
(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, txParams?: TxParams | undefined, optionalIxs?: TransactionInstruction[] | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
Settles one user's unrealized perp PnL across an arbitrary number of markets by splitting `marketIndexes` into groups of 4 (more than ~4 markets' worth of accounts won't fit in a single transaction) and sending one `settleMultiplePnl` transaction per group, sequentially. Compute units scale with group size (`300_000` per market, capped at `1_400_000`).
Yes
settleMultiplePNLsIx
(settleeUserAccountPublicKey: PublicKey, settleeUserAccount: UserAccount, marketIndexes: number[], mode: SettlePnlMode, overrides?: { authority?: PublicKey; } | undefined, revenueShareEscrowMap?: RevenueShareEscrowMap | undefined) => Promise<...>
Builds the `settleMultiplePnl` instruction. See `settleMultiplePNLs` for semantics. Attaches the settlee's `RevenueShareEscrow` and any relevant builder/referrer accounts when `revenueShareEscrowMap` shows completed builder/referral orders on any of `marketIndexes` (same logic as `settlePNLIx`, generalized across markets).
Yes
getSetUserStatusToBeingLiquidatedIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<TransactionInstruction>
Builds the `setUserStatusToBeingLiquidated` instruction. See `setUserStatusToBeingLiquidated` for semantics.
Yes
setUserStatusToBeingLiquidated
(userAccountPublicKey: PublicKey, userAccount: UserAccount) => Promise<string>
Keeper instruction: flags a user account as being liquidated (sets the `beingLiquidated` status bit) without performing any liquidation itself. Used to "claim" a liquidation ahead of the actual `liquidatePerp`/`liquidateSpot` call so a concurrent liquidator can't race it; the on-chain handler re-checks the user is actually below maintenance margin before setting the flag. Permissionless — any signer can act as liquidator.
Yes
liquidatePerp
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: liquidates part or all of a user's perp position in `marketIndex` when the user is below maintenance margin (or already flagged `beingLiquidated`), transferring the position to the calling liquidator's sub-account at the oracle price (subject to `limitPrice` and the on-chain liquidation fee). Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator, taking on the position and its PnL themselves.
Yes
getLiquidatePerpIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, maxBaseAssetAmount: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
Builds the `liquidatePerp` instruction. See `liquidatePerp` for semantics.
Yes
liquidatePerpWithFill
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: liquidates a user's perp position in `marketIndex` by filling it directly against the supplied `makerInfos` (instead of transferring it to the liquidator's own sub-account as `liquidatePerp` does). Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator/filler.
Yes
getLiquidatePerpWithFillIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, makerInfos: MakerInfo[], liquidatorSubAccountId?: number | undefined) => Promise<...>
Builds the `liquidatePerpWithFill` instruction. See `liquidatePerpWithFill` for semantics.
Yes
liquidateSpot
(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: liquidates a user's spot position by transferring `liabilityMarketIndex` debt from the user to the liquidator's own sub-account in exchange for `assetMarketIndex` collateral, when the user is below maintenance margin (or already flagged `beingLiquidated`). Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator.
Yes
getLiquidateSpotIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, assetMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
Builds the `liquidateSpot` instruction. See `liquidateSpot` for semantics.
Yes
getJupiterLiquidateSpotWithSwapIxV6
({ jupiterClient, liabilityMarketIndex, assetMarketIndex, swapAmount, assetTokenAccount, liabilityTokenAccount, slippageBps, swapMode, onlyDirectRoutes, quote, userAccount, userAccountPublicKey, liquidatorSubAccountId, maxAccounts, }: { jupiterClient: JupiterClient; liabilityMarketIndex: number; assetMarketIndex: nu...
Builds a Jupiter-routed spot-liquidation-with-swap instruction set: swaps the liquidator's `assetMarketIndex` proceeds into `liabilityMarketIndex` tokens via Jupiter inside a `beginSwap`/`endSwap` flash-loan sandwich (see `getLiquidateSpotWithSwapIx`), letting the liquidator repay the user's debt without needing to already hold the liability token. Fetches a quote from `jupiterClient` when `quote` is not supplied, and idempotently creates any missing associated token accounts.
Yes
getLiquidateSpotWithSwapIx
({ liabilityMarketIndex, assetMarketIndex, swapAmount: swapAmount, assetTokenAccount, liabilityTokenAccount, userAccount, userAccountPublicKey, liquidatorSubAccountId, }: { liabilityMarketIndex: number; assetMarketIndex: number; swapAmount: BN; assetTokenAccount: PublicKey; liabilityTokenAccount: PublicKey; userAcco...
Builds the `liquidateSpotWithSwapBegin`/`...End` instruction pair that sandwiches an external swap (e.g. Jupiter) so a liquidator can repay a user's `liabilityMarketIndex` debt using proceeds from selling `assetMarketIndex` collateral within the same transaction, without pre-funding the liability token. The on-chain handler validates the liability spot market's flash-loan balance is unwound by `endSwap`. See `getJupiterLiquidateSpotWithSwapIxV6` for the Jupiter-specific wrapper that assembles the full instruction list around this pair.
Yes
liquidateBorrowForPerpPnl
(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: liquidates a user by transferring `liabilityMarketIndex` spot debt from the user to the liquidator in exchange for a matching amount of the user's positive unsettled perp PnL in `perpMarketIndex`. Only usable once the user's position size in `perpMarketIndex` is zero (the PnL must already be fully unrealized/settled-out, not backed by an open position). Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator.
Yes
getLiquidateBorrowForPerpPnlIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, liabilityMarketIndex: number, maxLiabilityTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
Builds the `liquidateBorrowForPerpPnl` instruction. See `liquidateBorrowForPerpPnl` for semantics.
Yes
liquidatePerpPnlForDeposit
(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, assetMarketIndex: number, maxPnlTransfer: BN, limitPrice?: any, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: liquidates a user by transferring negative unsettled perp PnL in `perpMarketIndex` from the user to the liquidator in exchange for `assetMarketIndex` spot collateral (the inverse of `liquidateBorrowForPerpPnl`). Only usable once the user's position size in `perpMarketIndex` is zero. Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator.
Yes
getLiquidatePerpPnlForDepositIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, perpMarketIndex: number, assetMarketIndex: number, maxPnlTransfer: BN, limitPrice?: any, liquidatorSubAccountId?: number | undefined) => Promise<...>
Builds the `liquidatePerpPnlForDeposit` instruction. See `liquidatePerpPnlForDeposit` for semantics.
Yes
resolvePerpBankruptcy
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: resolves a user's perp bankruptcy in `marketIndex` (negative equity that liquidation alone could not cover) by socializing the loss — first attempting to backstop it from the quote spot market's insurance fund, then socializing any remainder across the market's other position holders via the cumulative funding/PnL pool. Reverts if the resulting insurance payout would fully drain the insurance fund vault, or if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator.
Yes
getResolvePerpBankruptcyIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, liquidatorSubAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `resolvePerpBankruptcy` instruction. See `resolvePerpBankruptcy` for semantics. Always settles against the quote spot market (`QUOTE_SPOT_MARKET_INDEX`).
Yes
resolveSpotBankruptcy
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, txParams?: TxParams | undefined, liquidatorSubAccountId?: number | undefined) => Promise<...>
Keeper instruction: resolves a user's spot bankruptcy (negative balance in `marketIndex` that liquidation alone could not cover) by backstopping the deficit from that spot market's insurance fund. Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless — any signer can act as liquidator.
Yes
getResolveSpotBankruptcyIx
(userAccountPublicKey: PublicKey, userAccount: UserAccount, marketIndex: number, liquidatorSubAccountId?: number | undefined) => Promise<TransactionInstruction>
Builds the `resolveSpotBankruptcy` instruction. See `resolveSpotBankruptcy` for semantics. Adds the spot market's mint (and transfer-hook extra account metas, if applicable) to `remainingAccounts` for the token transfer from the insurance fund vault.
Yes
updateFundingRate
(perpMarketIndex: number, oracle: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: recomputes and applies `marketIndex`'s hourly-anchored funding rate (`cumulativeFundingRateLong`/`Short`, FUNDING_RATE_PRECISION, 1e9) from the current oracle/AMM mark-price spread, then updates the market's oracle-derived TWAP stats. No-ops (via `FundingWasNotUpdated`, which the underlying call surfaces as a failed transaction) if it is not yet time for the next update — `perp_market.market_stats.funding_period` seconds since the last update, on-the-hour aligned. Reverts if the market's funding is paused or the market is not `Active`/`ReduceOnly`. Permissionless — any signer can act as keeper.
Yes
getUpdateFundingRateIx
(perpMarketIndex: number, oracle: PublicKey) => Promise<TransactionInstruction>
Builds the `updateFundingRate` instruction. See `updateFundingRate` for semantics.
Yes
updatePrelaunchOracle
(perpMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: refreshes a `Prelaunch`-oracle-source perp market's synthetic oracle price from its own recent trading activity (used for markets without a live external price feed, e.g. pre-listing futures). Only valid when the market's `oracleSource` is `Prelaunch`. Permissionless — any signer can act as keeper.
Yes
getUpdatePrelaunchOracleIx
(perpMarketIndex: number) => Promise<TransactionInstruction>
Builds the `updatePrelaunchOracle` instruction. See `updatePrelaunchOracle` for semantics.
Yes
updatePerpBidAskTwap
(perpMarketIndex: number, makers: [PublicKey, PublicKey][], txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: estimates the market's bid/ask price from the given makers' resting DLOB orders (filtered to those within `BID_ASK_TWAP_MAX_ORACLE_DIVERGENCE_PERCENT` of the oracle price) and folds the estimate into `lastBidPriceTwap`/`lastAskPriceTwap`. Restricted: the calling wallet's `UserStats` must have `canUpdateBidAskTwap` set and at least 1000 USDC (`QUOTE_PRECISION`, 1e6) staked in the insurance fund (`ifStakedQuoteAssetAmount`), or the instruction reverts.
Yes
getUpdatePerpBidAskTwapIx
(perpMarketIndex: number, makers: [PublicKey, PublicKey][]) => Promise<TransactionInstruction>
Builds the `updatePerpBidAskTwap` instruction. See `updatePerpBidAskTwap` for semantics.
Yes
settleFundingPayment
(userAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: settles accrued funding payments into the quote balance of every perp position the target user currently holds, using each market's latest `cumulativeFundingRateLong`/`Short` (FUNDING_RATE_PRECISION, 1e9). Fetches the user account fresh from the RPC (does not rely on this client's subscription cache) to determine which markets to include. Permissionless — any signer can act as keeper.
Yes
getSettleFundingPaymentIx
(userAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `settleFundingPayment` instruction. See `settleFundingPayment` for semantics. Fetches the user account directly via `program.account.user.fetch` and includes every market the user has a non-empty position in as a writable remaining account.
Yes
triggerEvent
(eventName: keyof VelocityClientAccountEvents, data?: any) => void
Manually emits an event on this client's internal `eventEmitter`, as if it had come from the account subscriber. Intended for tests/tooling that need to simulate account-update events; not used by normal instruction-building code paths.
Yes
getOracleDataForPerpMarket
(marketIndex: number) => OraclePriceData
Reads the last-known primary oracle price for a perp market from the account subscriber's cache (no RPC call). This is the raw exchange oracle price, unadjusted by the market's MM oracle — use `getMMOracleDataForPerpMarket` when you need the price the program actually uses for fills/margin.
Yes
getMMOracleDataForPerpMarket
(marketIndex: number) => MMOraclePriceData
Resolves the effective oracle price the program uses for `marketIndex` — the market's MM (market-maker-fed) oracle when it is fresher, valid, and not too divergent from the primary exchange oracle; otherwise falls back to the primary oracle. Mirrors the on-chain `get_mm_oracle_price_data` gating so client-side price reads (mark price, margin, liquidation previews) match what a fill/settlement will actually see. Falls back to the primary oracle (`getOracleDataForPerpMarket`) when any of the following hold: - the MM oracle price is zero (uninitialized) or its computed `OracleValidity` is `NonPositive`/`TooVolatile` (per `state.oracleGuardRails`); - the primary oracle is judged more recent than the MM oracle — by sequence-id ordering when both oracles have a usable, closely-matched `sequenceId`, otherwise by slot comparison; - the MM and primary oracle prices diverge by more than 1% (`PERCENTAGE_PRECISION`, 1e6 scale). Otherwise returns the MM oracle's price/slot/confidence.
Yes
getOracleDataForSpotMarket
(marketIndex: number) => OraclePriceData
Reads the last-known oracle price for a spot market from the account subscriber's cache (no RPC call). Spot markets do not have an MM oracle — this is always the effective price used for margin/borrow-lending calculations.
Yes
initializeInsuranceFundStake
(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Creates this wallet's `InsuranceFundStake` PDA for `marketIndex`, required once before staking into that market's insurance fund for the first time. A caller may only initialize their own stake account. Reverts if insurance-fund init is paused for the market.
Yes
getInitializeInsuranceFundStakeIx
(marketIndex: number) => Promise<TransactionInstruction>
Builds the `initializeInsuranceFundStake` instruction. See `initializeInsuranceFundStake` for semantics.
Yes
getAddInsuranceFundStakeIx
(marketIndex: number, amount: BN, collateralAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `addInsuranceFundStake` instruction, transferring `amount` of the market's token from `collateralAccountPublicKey` into its insurance fund vault and minting the caller's `InsuranceFundStake` the corresponding IF shares. Reverts if `amount` is zero, the spot market is not active, insurance-fund add is paused, or a withdraw request is already in progress on the stake account. See `addInsuranceFundStake`/`getAddInsuranceFundStakeIxs` for a wrapper that also handles account creation and funding from a sub-account.
Yes
addInsuranceFundStake
({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, txParams, }: { marketIndex: number; amount: BN; collateralAccountPublicKey: PublicKey; initializeStakeAccount?: boolean; fromSubaccount?: boolean; txParams?: TxParams; }) => Promise<...>
Add to an insurance fund stake and optionally initialize the account
Yes
getAddInsuranceFundStakeIxs
({ marketIndex, amount, collateralAccountPublicKey, initializeStakeAccount, fromSubaccount, }: { marketIndex: number; amount: BN; collateralAccountPublicKey: PublicKey; initializeStakeAccount?: boolean; fromSubaccount?: boolean; }) => Promise<TransactionInstruction[]>
Get instructions to add to an insurance fund stake and optionally initialize the account
Yes
requestRemoveInsuranceFundStake
(marketIndex: number, amount: BN, txParams?: TxParams | undefined) => Promise<string>
Starts the unstaking cooldown for this wallet's insurance fund stake in `marketIndex`, locking in the number of IF shares corresponding to `amount` at the current share price. The actual withdrawal must be completed with `removeInsuranceFundStake` after `spotMarket.insuranceFund.unstakingPeriod` seconds have elapsed; only one request may be in-flight per stake account (`cancelRequestRemoveInsuranceFundStake` to reset). A caller may only act on their own stake account.
Yes
cancelRequestRemoveInsuranceFundStake
(marketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Cancels this wallet's in-progress `requestRemoveInsuranceFundStake` for `marketIndex`, clearing the pending withdraw request so the stake resumes earning normally. Reverts if no withdraw request is currently in progress. A caller may only act on their own stake account.
Yes
removeInsuranceFundStake
(marketIndex: number, collateralAccountPublicKey: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Completes a previously-requested insurance fund unstake for `marketIndex`, transferring the requested shares' worth of tokens from the insurance fund vault to `collateralAccountPublicKey` (creating it, and a temporary wrapped-SOL account if the market is SOL, when needed). Reverts if `spotMarket.insuranceFund.unstakingPeriod` has not yet elapsed since the matching `requestRemoveInsuranceFundStake`, or if the spot market's utilization is above the healthy threshold. A caller may only act on their own stake account.
Yes
updateUserQuoteAssetInsuranceStake
(authority: PublicKey, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: refreshes `authority`'s quote-market (`QUOTE_SPOT_MARKET_INDEX`) insurance fund stake bookkeeping (applies any pending rebase to the stake's share count/value) without adding or removing funds. `insuranceFundStake` and `userStats` must belong to the same authority. Permissionless — any signer can trigger the refresh for any staker.
Yes
getUpdateUserQuoteAssetInsuranceStakeIx
(authority: PublicKey) => Promise<TransactionInstruction>
Builds the `updateUserQuoteAssetInsuranceStake` instruction. See `updateUserQuoteAssetInsuranceStake` for semantics. Always targets `QUOTE_SPOT_MARKET_INDEX`.
Yes
settleRevenueToInsuranceFund
(spotMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: sweeps the market's proportional share of accumulated protocol revenue from its spot vault into its insurance fund vault. Only callable once per `spotMarket.insuranceFund.revenueSettlePeriod` seconds (on-the-hour aligned from `lastRevenueSettleTs`); reverts early with the remaining wait time otherwise. Reverts if the market has `revenueSettlePeriod <= 0` (settling to IF disabled). Permissionless — any signer can trigger the sweep.
Yes
getSettleRevenueToInsuranceFundIx
(spotMarketIndex: number) => Promise<TransactionInstruction>
Builds the `settleRevenueToInsuranceFund` instruction. See `settleRevenueToInsuranceFund` for semantics.
Yes
sweepPerpMarketFees
(perpMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Permissionless streaming-sweep keeper instruction: materializes a perp market's accrued pending fee carveouts out of the PnL pool — `pendingProtocolFee` to the market's protocol fee pool (runs first, buffer-exempt), then `pendingIfFee` to the quote spot market's revenue pool and `pendingAmmProvision` into the AMM's fee pool (both leave `feePoolBufferTarget` behind). Every drain reserves `max(netUserPnl, 0)` so user claims stay backed. This runs inline on every `settlePNL` already — this instruction lets a keeper run it on demand without settling anyone's PnL. Gates the oracle price used to value `netUserPnl` the same way `settlePNL` does (price-band + validity/divergence checks when the market has curve updates enabled).
Yes
getSweepPerpMarketFeesIx
(perpMarketIndex: number) => Promise<TransactionInstruction>
Builds the `sweepPerpMarketFees` instruction. See `sweepPerpMarketFees` for semantics.
Yes
resolvePerpPnlDeficit
(spotMarketIndex: number, perpMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: backstops a perp market's negative PnL pool from the quote spot market's insurance fund (first attempting a revenue-to-IF settlement so the vault balance is up-to-date). `spotMarketIndex` must be `QUOTE_SPOT_MARKET_INDEX`. Permissionless — any signer can trigger it.
Yes
getResolvePerpPnlDeficitIx
(spotMarketIndex: number, perpMarketIndex: number) => Promise<TransactionInstruction>
Builds the `resolvePerpPnlDeficit` instruction. See `resolvePerpPnlDeficit` for semantics.
Yes
getDepositIntoSpotMarketRevenuePoolIx
(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey) => Promise<TransactionInstruction>
Builds the `depositIntoSpotMarketRevenuePool` instruction. See `depositIntoSpotMarketRevenuePool` for semantics.
Yes
depositIntoSpotMarketRevenuePool
(marketIndex: number, amount: BN, userTokenAccountPublicKey: PublicKey) => Promise<string>
This ix will donate your funds to velocity revenue pool. It does not deposit into your user account
Yes
getPerpMarketExtendedInfo
(marketIndex: number) => PerpMarketExtendedInfo
Computes display/risk metadata for a perp market from currently-subscribed account state (no RPC call): minimum order size, maintenance margin ratio, PnL pool value, contract tier, and the maximum insurance available to the market.
Yes
getMarketFees
(marketType: MarketType, marketIndex?: number | undefined, user?: User | undefined, orderParams?: Pick<OrderParams, "builderIdx" | "builderFeeTenthBps"> | undefined) => { ...; }
Calculates taker / maker fee (as a percentage, e.g. .001 = 10 basis points) for particular marketType
Yes
getMarketIndexAndType
(name: string) => { marketIndex: number; marketType: MarketType; } | undefined
Returns the market index and type for a given market name E.g. "SOL-PERP" -> &#123; marketIndex: 0, marketType: MarketType.PERP &#125;
Yes
postPythLazerOracleUpdate
(feedIds: number[], pythMessageHex: string) => Promise<string>
Posts a signed Pyth Lazer price update on-chain for one or more feeds, prepended with the Ed25519 signature-verification instruction the handler requires. Permissionless — any signer can post a valid, correctly-signed update.
Yes
getPostPythLazerOracleUpdateIxs
(feedIds: number[], pythMessageHex: string, precedingIxs?: TransactionInstruction[] | undefined, overrideCustomIxIndex?: number | undefined) => Promise<TransactionInstruction[]>
Builds the `postPythLazerOracleUpdate` instruction pair. See `postPythLazerOracleUpdate` for semantics.
Yes
getPauseSpotMarketDepositWithdrawIx
(spotMarketIndex: number) => Promise<TransactionInstruction>
Builds the `pauseSpotMarketDepositWithdraw` instruction. See `pauseSpotMarketDepositWithdraw` for semantics.
Yes
pauseSpotMarketDepositWithdraw
(spotMarketIndex: number, txParams?: TxParams | undefined) => Promise<string>
Emergency circuit-breaker instruction: pauses deposits and withdrawals for a spot market, but only when the on-chain handler detects the spot market's vault invariant has already been violated (actual vault balance diverges from the market's tracked deposit/borrow balances, e.g. from an exploit) — it reverts with an error if the vault amount is still valid, so this cannot be used to arbitrarily pause a healthy market. Permissionless — any signer can trigger it once the invariant is broken.
Yes
updateMmOracleNative
(marketIndex: number, oraclePrice: BN, oracleSequenceId: BN) => Promise<string>
Updates a perp market's market-maker (MM) oracle price using the program's high-frequency custom native entrypoint (bypasses Anchor's account deserialization overhead — see `createNativeInstructionDiscriminatorBuffer`). Restricted to the state's configured `hotMmOracleCrank` signer in production (unchecked under the `anchor-test` feature) and can be disabled entirely via a state feature-bit-flag kill switch. See `getMMOracleDataForPerpMarket` for how this price is subsequently gated against the primary oracle before use.
Yes
getUpdateMmOracleNativeIx
(marketIndex: number, oraclePrice: BN, oracleSequenceId: BN) => Promise<TransactionInstruction>
Builds the `updateMmOracleNative` instruction. See `updateMmOracleNative` for semantics. Hand- assembles the instruction (perp market, signer, clock sysvar, state) rather than going through `this.program.instruction`, since this targets the native (non-Anchor) entrypoint.
Yes
updateAmmSpreadAdjustmentNative
(marketIndex: number, ammSpreadAdjustment: number) => Promise<string>
Updates a perp market's AMM spread adjustment using the program's high-frequency custom native entrypoint. Restricted to the state's configured `hotAmmSpreadAdjust` signer in production (unchecked under the `anchor-test` feature).
Yes
getUpdateAmmSpreadAdjustmentNativeIx
(marketIndex: number, ammSpreadAdjustment: number) => Promise<TransactionInstruction>
Builds the `updateAmmSpreadAdjustmentNative` instruction. See `updateAmmSpreadAdjustmentNative` for semantics. Hand-assembles the instruction (perp market, signer, state) rather than going through `this.program.instruction`, since this targets the native (non-Anchor) entrypoint.
Yes
getLpPoolAccount
(lpPoolId: number) => Promise<LPPoolAccount>
Fetches an LP pool account by ID directly from the RPC (not from this client's subscription cache). An LP pool ("VLP") is a basket of spot-market "constituent" tokens that mints/redeems a pool token against deposits/withdrawals and absorbs perp AMM PnL to hedge the protocol's inventory risk (see `settlePerpToLpPool`).
Yes
getConstituentTargetBaseAccount
(lpPoolId: number) => Promise<ConstituentTargetBaseAccount>
Fetches the target-base weights for an LP pool's constituents directly from the RPC. Target base is each constituent's ideal share of the pool, derived from the AMMs it backs (`updateLpConstituentTargetBase`); swap/add/remove-liquidity fees are priced off deviation from these targets.
Yes
getAmmCache
() => Promise<AmmCache>
Fetches the program's single global AMM cache account directly from the RPC — a snapshot of each hedge-enabled perp market's inventory/price/PnL used by LP pool AUM, target-base, and settlement instructions without having to reload every perp market individually.
Yes
updateLpConstituentTargetBase
(lpPoolId: number, constituents: PublicKey[], txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: recomputes each listed constituent's target-base weight from the current AMM cache (each hedge-enabled perp market's inventory relative to its constituents), used to price LP pool swap/add/remove-liquidity fees. Requires `updateAmmCache` to have run recently for the relevant markets. Permissionless — any signer can act as keeper.
Yes
getUpdateLpConstituentTargetBaseIx
(lpPoolId: number, constituents: PublicKey[]) => Promise<TransactionInstruction>
Builds the `updateLpConstituentTargetBase` instruction. See `updateLpConstituentTargetBase` for semantics.
Yes
updateLpPoolAum
(lpPool: LPPoolAccount, spotMarketIndexOfConstituents: number[], txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: recomputes an LP pool's total AUM and per-constituent value from each constituent's spot market and vault balance, refreshing `lastAumSlot`. Swaps and add/remove liquidity revert with `LpPoolAumDelayed` if this has not run within `LP_POOL_SWAP_AUM_UPDATE_DELAY` slots of the action, so it must typically precede those instructions in the same transaction (see `getAllUpdateLpPoolAumIxs`). Permissionless — any signer can act as keeper.
Yes
getUpdateLpPoolAumIxs
(lpPool: LPPoolAccount, spotMarketIndexOfConstituents: number[]) => Promise<TransactionInstruction>
Builds the `updateLpPoolAum` instruction. See `updateLpPoolAum` for semantics.
Yes
updateAmmCache
(perpMarketIndexes: number[], txParams?: TxParams | undefined) => Promise<string>
Keeper instruction: refreshes the global AMM cache's per-market inventory/price/PnL snapshot for the given hedge-enabled perp markets, feeding LP pool AUM, target-base, and settlement math. Permissionless — any signer can act as keeper.
Yes
getUpdateAmmCacheIx
(perpMarketIndexes: number[]) => Promise<TransactionInstruction>
Builds the `updateAmmCache` instruction. See `updateAmmCache` for semantics.
Yes
updateConstituentOracleInfo
(constituent: ConstituentAccount) => Promise<string>
Keeper instruction: refreshes a single LP pool constituent's cached oracle price/slot from its spot market's oracle. Called ahead of AUM/target-base updates that need a fresh price for that constituent. Permissionless — any signer can act as keeper.
Yes
getUpdateConstituentOracleInfoIx
(constituent: ConstituentAccount) => Promise<TransactionInstruction>
Builds the `updateConstituentOracleInfo` instruction. See `updateConstituentOracleInfo` for semantics.
Yes
lpPoolSwap
(inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, lpPool: PublicKey, userAuthority: PublicKey, txParams?: TxParams | undefined) => Promise<...>
Swaps `inMarketIndex` tokens for `outMarketIndex` tokens directly against an LP pool's constituent vaults (not the DLOB/AMM), paying a fee priced off each constituent's deviation from its target-base weight. Reverts if pool swaps are disabled, `inMarketIndex` equals `outMarketIndex`, or `updateLpPoolAum` has not run within `LP_POOL_SWAP_AUM_UPDATE_DELAY` slots (see `getAllLpPoolSwapIxs` for a wrapper that prepends the required AUM refresh).
Yes
getLpPoolSwapIx
(inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, lpPool: PublicKey, userAuthority: PublicKey) => Promise<TransactionInstruction>
Builds the `lpPoolSwap` instruction. See `lpPoolSwap` for semantics.
Yes
viewLpPoolSwapFees
(inMarketIndex: number, outMarketIndex: number, inAmount: BN, inTargetWeight: BN, outTargetWeight: BN, lpPool: PublicKey, constituentTargetBase: PublicKey, constituentInTokenAccount: PublicKey, constituentOutTokenAccount: PublicKey, inConstituent: PublicKey, outConstituent: PublicKey, txParams?: TxParams | undefined...
Simulation-only instruction: computes what `lpPoolSwap` would charge for the given swap without moving any funds (intended to be run via `simulateTransaction`/a view call, not actually confirmed on-chain). Useful for quoting a swap's fee before submitting it.
Yes
getViewLpPoolSwapFeesIx
(inMarketIndex: number, outMarketIndex: number, inAmount: BN, inTargetWeight: BN, outTargetWeight: BN, lpPool: PublicKey, constituentTargetBase: PublicKey, constituentInTokenAccount: PublicKey, constituentOutTokenAccount: PublicKey, inConstituent: PublicKey, outConstituent: PublicKey) => Promise<...>
Builds the `viewLpPoolSwapFees` instruction. See `viewLpPoolSwapFees` for semantics.
Yes
getCreateLpPoolTokenAccountIx
(lpPool: LPPoolAccount) => Promise<TransactionInstruction>
Builds an idempotent instruction creating this wallet's associated token account for an LP pool's mint, needed before receiving pool tokens from `lpPoolAddLiquidity`.
Yes
createLpPoolTokenAccount
(lpPool: LPPoolAccount, txParams?: TxParams | undefined) => Promise<string>
Creates this wallet's associated token account for an LP pool's mint. See `getCreateLpPoolTokenAccountIx`.
Yes
lpPoolAddLiquidity
({ inMarketIndex, inAmount, minMintAmount, lpPool, txParams, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
Deposits `inMarketIndex` tokens into an LP pool's matching constituent and mints LP pool tokens in return, priced at the pool's current AUM-derived share price. Reverts if mint/redeem is disabled, the constituent doesn't allow deposits (or is reduce-only and this isn't a reducing deposit), the pool is gated by a whitelist mint this wallet doesn't hold, or `updateLpPoolAum` has not run within `LP_POOL_SWAP_AUM_UPDATE_DELAY` slots (see `getAllLpPoolAddLiquidityIxs` for a wrapper that prepends the required AUM refresh).
Yes
getLpPoolAddLiquidityIx
({ inMarketIndex, inAmount, minMintAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction[]>
Builds the `lpPoolAddLiquidity` instruction (plus any needed wrapped-SOL / associated-token- account setup and teardown instructions). See `lpPoolAddLiquidity` for semantics.
Yes
viewLpPoolAddLiquidityFees
({ inMarketIndex, inAmount, lpPool, txParams, }: { inMarketIndex: number; inAmount: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
Simulation-only instruction: computes what `lpPoolAddLiquidity` would mint/charge for the given deposit without moving any funds (intended for `simulateTransaction`, not confirmation).
Yes
getViewLpPoolAddLiquidityFeesIx
({ inMarketIndex, inAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction>
Builds the `viewLpPoolAddLiquidityFees` instruction. See `viewLpPoolAddLiquidityFees` for semantics.
Yes
lpPoolRemoveLiquidity
({ outMarketIndex, lpToBurn, minAmountOut, lpPool, txParams, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
Burns LP pool tokens and withdraws `outMarketIndex` tokens from the pool's matching constituent in return, priced at the pool's current AUM-derived share price. Reverts if mint/redeem is disabled, the constituent doesn't allow withdrawals, or `updateLpPoolAum` has not run within `LP_POOL_SWAP_AUM_UPDATE_DELAY` slots (see `getAllLpPoolRemoveLiquidityIxs` for a wrapper that prepends the required perp settlement and AUM refresh).
Yes
getLpPoolRemoveLiquidityIx
({ outMarketIndex, lpToBurn, minAmountOut, lpPool, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction[]>
Builds the `lpPoolRemoveLiquidity` instruction (plus an idempotent associated-token-account creation instruction for a wrapped-SOL output, if needed). See `lpPoolRemoveLiquidity` for semantics.
Yes
viewLpPoolRemoveLiquidityFees
({ outMarketIndex, lpToBurn, lpPool, txParams, }: { outMarketIndex: number; lpToBurn: BN; lpPool: LPPoolAccount; txParams?: TxParams; }) => Promise<string>
Simulation-only instruction: computes what `lpPoolRemoveLiquidity` would return for the given burn without moving any funds (intended for `simulateTransaction`, not confirmation).
Yes
getViewLpPoolRemoveLiquidityFeesIx
({ outMarketIndex, lpToBurn, lpPool, }: { outMarketIndex: number; lpToBurn: BN; lpPool: LPPoolAccount; }) => Promise<TransactionInstruction>
Builds the `viewLpPoolRemoveLiquidityFees` instruction. See `viewLpPoolRemoveLiquidityFees` for semantics.
Yes
getAllLpPoolAddLiquidityIxs
({ inMarketIndex, inAmount, minMintAmount, lpPool, }: { inMarketIndex: number; inAmount: BN; minMintAmount: BN; lpPool: LPPoolAccount; }, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined, view?: boolean | undefined) => Promise<...>
Convenience wrapper that prepends the AUM refresh `lpPoolAddLiquidity` requires (an `updateConstituentOracleInfo` per constituent, then `updateLpPoolAum`) ahead of either the real add-liquidity instruction or, when `view` is set, its fee-simulation counterpart.
Yes
getAllLpPoolRemoveLiquidityIxs
({ outMarketIndex, lpToBurn, minAmountOut, lpPool, }: { outMarketIndex: number; lpToBurn: BN; minAmountOut: BN; lpPool: LPPoolAccount; }, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined, view?: boolean | undefined) => Promise<...>
Convenience wrapper that prepends what `lpPoolRemoveLiquidity` requires: settling every hedge- enabled perp market's PnL into the pool (`getAllSettlePerpToLpPoolIxs`) and refreshing AUM (`getAllUpdateLpPoolAumIxs`), ahead of either the real remove-liquidity instruction or, when `view` is set, its fee-simulation counterpart.
Yes
getAllUpdateLpPoolAumIxs
(lpPool: LPPoolAccount, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined) => Promise<TransactionInstruction[]>
Builds the full instruction set to refresh an LP pool's AUM: one `updateConstituentOracleInfo` per constituent (optional) followed by `updateLpPoolAum` across all of them.
Yes
getAllUpdateConstituentTargetBaseIxs
(perpMarketIndexes: number[], lpPool: LPPoolAccount, constituentMap: ConstituentMap, includeUpdateConstituentOracleInfo?: boolean | undefined) => Promise<...>
Builds the full instruction set to refresh an LP pool's constituent target-base weights: `updateAmmCache` for the given markets, an optional `updateConstituentOracleInfo` per constituent, `updateLpConstituentTargetBase`, then a full AUM refresh (`getAllUpdateLpPoolAumIxs`, oracle info not repeated).
Yes
getAllLpPoolSwapIxs
(lpPool: LPPoolAccount, constituentMap: ConstituentMap, inMarketIndex: number, outMarketIndex: number, inAmount: BN, minOutAmount: BN, userAuthority: PublicKey) => Promise<...>
Convenience wrapper that prepends the AUM refresh `lpPoolSwap` requires ahead of the swap instruction itself.
Yes
settlePerpToLpPool
(lpPoolId: number, perpMarketIndexes: number[]) => Promise<string>
Keeper instruction: settles quote PnL owed between one or more hedge-enabled perp markets' fee and PnL pools and the LP pool's quote constituent, bounded by the pool's settle cap. Requires `updateAmmCache` to have run recently for the given markets. Permissionless — any signer can act as keeper.
Yes
getSettlePerpToLpPoolIx
(lpPoolId: number, perpMarketIndexes: number[]) => Promise<TransactionInstruction>
Builds the `settlePerpToLpPool` instruction. See `settlePerpToLpPool` for semantics.
Yes
getAllSettlePerpToLpPoolIxs
(lpPoolId: number, marketIndexes: number[]) => Promise<TransactionInstruction[]>
Builds the full instruction set to settle perp PnL into an LP pool: `updateAmmCache` for the given markets followed by `settlePerpToLpPool`.
Yes
handleSignedTransaction
any
Below here are the transaction sending functions
Yes
handlePreSignedTransaction
any
Yes
isVersionedTransaction
any
Yes
sendTransaction
(tx: VersionedTransaction | Transaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (unless `preSigned`) and sends a transaction via this client's `txSender`, dispatching to `sendVersionedTransaction` or `send` based on whether `tx` is a `VersionedTransaction`. The shared low-level send path underlying nearly every instruction-building method on this class.
Yes
buildTransaction
(instructions: TransactionInstruction | TransactionInstruction[], txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined, recentBlockhash?: Readonly<...> | undefined, optionalIxs?: Transactio...
Assembles one or more instructions into a single unsigned transaction via `this.txHandler`, applying compute-unit/priority-fee instructions from `txParams`, resolving address lookup tables for versioned transactions, and fetching a recent blockhash if not supplied. Used by nearly every instruction-building method on this class before sending.
Yes
buildBulkTransactions
(instructions: (TransactionInstruction | TransactionInstruction[])[], txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
Builds many independent transactions in one call — each entry in `instructions` becomes its own transaction via the same path as `buildTransaction`. An entry may build to `undefined` if the underlying `txHandler` implementation skips it (e.g. empty instruction list).
Yes
buildTransactionsMap
(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
Like `buildBulkTransactions`, but keyed by caller-chosen labels instead of array position — each value in `instructionsMap` becomes its own transaction, returned under the same key.
Yes
buildAndSignTransactionsMap
(instructionsMap: Record<string, TransactionInstruction | TransactionInstruction[]>, txParams?: TxParams | undefined, txVersion?: TransactionVersion | undefined, lookupTables?: AddressLookupTableAccount[] | undefined, forceVersionedTransaction?: boolean | undefined) => Promise<...>
Like `buildTransactionsMap`, but additionally signs every built transaction with this client's wallet before returning — useful for batching several independent, pre-signed transactions (e.g. to submit separately or hand off to `sendSignedTx`).
Yes
isOrderIncreasingPosition
(orderParams: OptionalOrderParams, subAccountId?: number | undefined) => boolean
Determines whether placing `orderParams` would increase the magnitude of the sub-account's existing perp position in that market (same-direction add, or opening a new position) as opposed to reducing/flattening/flipping it. Used by `placePerpOrder`/`placeOrders`/ `preparePlaceOrdersTx` to decide whether an `isolatedPositionDepositAmount` transfer should be prepended — that transfer only makes sense when the order grows the position.
Yes

If you pass nothing, VelocityClient builds a TxHandler from its own connection and wallet, then wraps it in a RetryTxSender. Default txParams are computeUnits: 600_000 and computeUnitsPrice: 0, so by default you pay no priority fee.

Choosing a tx sender

All four senders share the same TxSender interface (send, sendVersionedTransaction, getVersionedTransaction, sendRawTransaction, simulateTransaction, plus getTimeoutCount, getTxLandRate, getSuggestedPriorityFeeMultiplier). They differ in how the transaction reaches the cluster and how long they keep trying.

SenderBroadcast behaviorDefault retrySleepDefault timeoutPick it when
RetryTxSenderSends once, then resends the same signed bytes to connection and every additionalConnections entry on a fixed interval2,000 ms35,000 msGeneral purpose. This is the default VelocityClient builds.
WhileValidTxSenderSame resend loop as RetryTxSender, and additionally records each in-flight signature’s blockhash and lastValidBlockHeight in its untilValid map2,000 ms35,000 ms (inherited from BaseTxSender; not a constructor option)You want per-transaction blockhash validity bookkeeping available to your own code, for example a UI that reports “expired” separately from “dropped”.
FastSingleTxSenderSends exactly once and relies on the RPC node’s own forwarding. Can skip confirmation, or confirm in the background so the call returns right after the sendnot applicable (no resend loop)35,000 msLatency-sensitive keepers that would rather fire again with fresh inputs than pay for a resend loop.
ForwardOnlyTxSenderNever calls sendRawTransaction on connection. Hands the base58 transaction to additionalTxSenderCallbacks and re-invokes them on an interval. connection is used only to confirm5,000 ms35,000 msSubmission is delegated to a relay or bundler (for example a Jito bundle submitter) and you still want the SDK’s confirmation and land-rate machinery.

Shared constructor options:

OptionMeaningDefault
optsConfirmOptions used for sends and confirmationsDEFAULT_CONFIRMATION_OPTS (commitment and preflightCommitment both confirmed) with maxRetries: 0, so the RPC node does not retry on top of the sender’s own loop
confirmationStrategyConfirmationStrategy.WebSocket (an onSignature subscription), Polling (getSignatureStatuses), or Combo (race both, resolve on whichever lands first)Combo
additionalConnectionsExtra connections to also broadcast to[] (and always [] for ForwardOnlyTxSender, which does not accept the option)
additionalTxSenderCallbacksCallbacks invoked with each sent transaction’s base58 encoding[]
trackTxLandRateRecord sent signatures so getTxLandRate() and getSuggestedPriorityFeeMultiplier() return real numbersoff
txLandRateLookbackWindowMinutesRolling window for the land-rate calculation10 minutes
landRateToFeeFuncMaps a land rate to a priority-fee multiplierBuilt-in: returns 1 while the land rate is at or above 0.9 or fewer than 3 samples exist, otherwise grows logarithmically, capped at 10
throwOnTimeoutErrorWhether a confirmation timeout throws TxSendErrortrue

FastSingleTxSender adds skipConfirmation (return immediately after sending), confirmInBackground (confirm without awaiting, so the returned slot is undefined), blockhashRefreshInterval (default 10,000 ms, 0 disables the loop), and blockhashCommitment (default finalized). WhileValidTxSender adds throwOnTransactionError (default true).

TxSendError carries a numeric code. A confirmation timeout uses NOT_CONFIRMED_ERROR_CODE (-1001), which is an SDK-internal code meaning “we never saw a confirmation or a definite failure”, not a Solana or program error. Treat it as unknown outcome and re-check the signature before resubmitting.

import { FastSingleTxSender } from "@velocity-exchange/sdk"; // Fire-and-forget: return as soon as the send lands, confirm in the background. const txSender = new FastSingleTxSender({ connection, wallet, confirmInBackground: true, blockhashRefreshInterval: 5_000, trackTxLandRate: true, }); const velocityClient = new VelocityClient({ connection, wallet, txSender });
Class FastSingleTxSenderReference ↗

`TxSender` optimized for low latency: sends a transaction exactly once (no resend/retry loop — relies on the RPC node's own forwarding), and can skip confirmation entirely or confirm asynchronously in the background so `sendRawTransaction` returns as soon as the send lands. Maintains its own periodically-refreshed blockhash cache (independent of `TxHandler`'s) purely for that background-refresh convenience; it is not actually consumed by `sendRawTransaction` here. Suited to latency-sensitive keeper bots that would rather fire-and-forget than pay for `RetryTxSender`'s resend loop.

PropertyTypeRequired
connection
Connection
Yes
wallet
IWallet
Yes
opts
ConfirmOptions
Yes
timeout
number
Yes
blockhashRefreshInterval
number
How often (ms) `startBlockhashRefreshLoop` refreshes `recentBlockhash`; `0` disables the refresh loop.
Yes
additionalConnections
Connection[]
Yes
timoutCount
number
Yes
recentBlockhash
Readonly<{ blockhash: string; lastValidBlockHeight: number; }>
Periodically refreshed blockhash cache (see `startBlockhashRefreshLoop`); informational only — `sendRawTransaction` does not currently read this field.
No
skipConfirmation
boolean
If `true`, `sendRawTransaction` returns immediately after sending, without waiting for or checking confirmation.
Yes
confirmInBackground
boolean
If `true` (and `skipConfirmation` is `false`), confirmation runs without being awaited — `sendRawTransaction` returns before the transaction is confirmed.
Yes
blockhashCommitment
Commitment
Commitment level used when refreshing `recentBlockhash`.
Yes
blockhashIntervalId
Timer
Handle for the interval timer started by `startBlockhashRefreshLoop`.
No
startBlockhashRefreshLoop
() => void
Starts a `setInterval` loop (if `blockhashRefreshInterval > 0`) that refreshes `this.recentBlockhash` every `blockhashRefreshInterval` ms. Fetch errors are logged and otherwise ignored (the loop keeps running with the stale cached value).
Yes
sendRawTransaction
(rawTransaction: Buffer | Uint8Array<ArrayBufferLike>, opts: ConfirmOptions) => Promise<TxSigAndSlot>
Sends a raw transaction exactly once via `connection.sendRawTransaction` (plus a best-effort broadcast to `additionalConnections`), then confirms it unless `skipConfirmation` is set — awaited normally, or fired without awaiting if `confirmInBackground` is set (in which case the returned `slot` will be `undefined`, since it isn't known yet at return time).
Yes
timeoutCount
number
Count of `confirmTransactionWebSocket`/`confirmTransactionPolling` calls that hit `timeout` without a definitive result.
Yes
confirmationStrategy
ConfirmationStrategy
Yes
additionalTxSenderCallbacks
((base58EncodedTx: string) => void)[]
Callbacks invoked with the base58-encoded raw transaction alongside `additionalConnections` broadcasts, e.g. for logging/mempool submission.
No
txHandler
TxHandler
Yes
trackTxLandRate
boolean
Whether to record each sent signature (via `txSigCache`) to compute `getTxLandRate()`.
No
throwOnTimeoutError
boolean
Whether `confirmTransactionWebSocket`/`confirmTransactionPolling` throw `TxSendError` on timeout (`true`) or return `undefined` (`false`).
Yes
throwOnTransactionError
boolean
Whether `checkConfirmationResultForError` throws the resolved on-chain error, or is a no-op.
Yes
lookbackWindowMinutes
number
Lookback window, in seconds, over which `txSigCache` entries expire for the land-rate calculation.
Yes
txSigCache
NodeCache
TTL cache of `txSig -> landed?` used to compute `getTxLandRate()` when `trackTxLandRate` is set.
No
txLandRate
number
Yes
lastPriorityFeeSuggestion
number
Yes
landRateToFeeFunc
(landRate: number) => number
Maps a land rate (0-1) to a priority-fee multiplier; defaults to `defaultLandRateToFeeFunc`.
Yes
send
(tx: Transaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (via `prepareTx`, unless `preSigned`) and sends a legacy `Transaction`.
Yes
prepareTx
(tx: Transaction, additionalSigners: Signer[], opts: ConfirmOptions, preSigned?: boolean | undefined) => Promise<Transaction>
Delegates to `TxHandler.prepareTx` to attach a recent blockhash, fee payer, and signatures.
Yes
getVersionedTransaction
(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], _additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, blockhash?: Readonly<...> | undefined) => Promise<...>
Builds (but does not send) a `VersionedTransaction` from raw instructions via `TxHandler.generateVersionedTransaction`.
Yes
sendVersionedTransaction
(tx: VersionedTransaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (unless `preSigned`) and sends a `VersionedTransaction`. When the wallet exposes a `payer` `Keypair` directly, signs in-place with `tx.sign(...)`; otherwise delegates to `TxHandler.signVersionedTx` (needed for wallet adapters without direct keypair access).
Yes
simulateTransaction
(tx: VersionedTransaction) => Promise<boolean>
Simulates a transaction via `connection.simulateTransaction` without sending it, swallowing both simulation errors and RPC-call failures into a `false` result (logged to `console.error`).
Yes
confirmTransactionWebSocket
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Waits for a transaction to confirm by subscribing to `onSignature` on `connection` and every `additionalConnections` entry simultaneously, resolving on whichever responds first. If no connection confirms within `this.timeout` and `confirmationStrategy` is `Combo`, falls back to a one-shot `getSignatureStatuses` check before giving up.
Yes
confirmTransactionPolling
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Waits for a transaction to confirm by polling `getSignatureStatuses` with exponential backoff, starting at 400ms and capping at 5000ms, until `commitment` is reached or `this.timeout` elapses.
Yes
confirmTransaction
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Confirms a transaction using whichever strategy `this.confirmationStrategy` selects: `WebSocket`/`Combo` route to `confirmTransactionWebSocket`, `Polling` to `confirmTransactionPolling`.
Yes
getTimestamp
() => number
Current time in milliseconds since epoch (thin wrapper over `Date.now()`, overridable in tests).
Yes
promiseTimeout
<T>(promises: Promise<T>[], timeoutMs: number) => Promise<T | null>
Races an array of promises against a timeout, resolving to `null` (rather than rejecting) if none settle in time. Unlike `../util/promiseTimeout`, this accepts multiple promises (used to race confirmation across `connection` plus every `additionalConnections` entry).
Yes
sendToAdditionalConnections
(rawTx: Buffer | Uint8Array<ArrayBufferLike>, opts: ConfirmOptions) => void
Best-effort broadcasts a raw transaction to every `additionalConnections` entry and invokes `additionalTxSenderCallbacks` with its base58 encoding. Failures are logged, not thrown or awaited by the caller — this never affects whether the primary send/confirm succeeds.
Yes
addAdditionalConnection
(newConnection: Connection) => void
Adds an extra RPC connection to broadcast future transactions to, unless a connection with the same RPC endpoint is already registered.
Yes
getTimeoutCount
() => number
Yes
checkConfirmationResultForError
(txSig: string, result: SignatureResult) => Promise<void>
Inspects a confirmed signature's result and, if it recorded an on-chain error, resolves the detailed program error via `throwTransactionError` and throws it. Note this check runs whenever `result.err` is set, independent of the `throwOnTransactionError` field — callers that want to suppress transaction-error throwing should avoid calling this method rather than rely on that flag here.
Yes
getTxLandRate
() => number
Computes the fraction of recently sent transactions (within `lookbackWindowMinutes`) that landed, from `txSigCache`'s current entries. Returns the last computed `txLandRate` (default 0) if `trackTxLandRate` is disabled or the cache is empty, rather than recomputing.
Yes
defaultLandRateToFeeFunc
any
Default `landRateToFeeFunc`: returns `1` (no boost) if the land rate is already at/above `BASELINE_TX_LAND_RATE` (0.9) or fewer than 3 samples have been recorded yet (too little data to react); otherwise returns a multiplier that grows logarithmically as the land rate falls further below baseline, capped at `10`.
Yes
getSuggestedPriorityFeeMultiplier
() => number
Suggests a multiplier to apply to a base priority fee, based on recent land rate — intended for callers to scale up their compute-unit price when transactions have been landing poorly.
Yes
import { ForwardOnlyTxSender } from "@velocity-exchange/sdk"; // Submission is delegated: the SDK only confirms. const txSender = new ForwardOnlyTxSender({ connection, wallet, retrySleep: 5_000, additionalTxSenderCallbacks: [ (base58EncodedTx) => myRelay.submit(base58EncodedTx), ], });
Class ForwardOnlyTxSenderReference ↗

`TxSender` that never calls `connection.sendRawTransaction` itself — instead it hands the raw transaction to `additionalTxSenderCallbacks` (e.g. a Jito/third-party bundle submitter) and re-invokes those callbacks on a `retrySleep` interval until the transaction confirms or `timeout` elapses. `connection` is used only to *confirm* the transaction (via `BaseTxSender.confirmTransaction`), never to broadcast it. `additionalConnections` is always empty for this sender (the constructor doesn't accept it) since forwarding goes exclusively through the callbacks.

Use this when transaction submission is delegated to an external forwarder/relay rather than this RPC connection, but you still want this SDK's confirmation/retry/land-rate machinery.

PropertyTypeRequired
connection
Connection
Yes
wallet
IWallet
Yes
opts
ConfirmOptions
Yes
timeout
number
Yes
retrySleep
number
Yes
additionalConnections
Connection[]
Yes
timoutCount
number
Yes
sleep
(reference: ResolveReference) => Promise<void>
Waits `retrySleep` milliseconds, exposing an early-wake `resolve` via `reference` so `sendRawTransaction`'s stop condition can cut the wait short once the transaction confirms.
Yes
sendToAdditionalConnections
(rawTx: Buffer | Uint8Array<ArrayBufferLike>, _opts: ConfirmOptions) => void
Overrides `BaseTxSender.sendToAdditionalConnections` to skip `additionalConnections` entirely (always empty for this sender) and only invoke `additionalTxSenderCallbacks` with the base58-encoded transaction — this is this sender's *only* transaction submission path.
Yes
sendRawTransaction
(rawTransaction: Buffer | Uint8Array<ArrayBufferLike>, opts: ConfirmOptions) => Promise<TxSigAndSlot>
"Sends" a raw transaction by repeatedly invoking `additionalTxSenderCallbacks` with it every `retrySleep` ms (never calling `connection.sendRawTransaction`) while concurrently waiting for confirmation via `confirmTransaction`. Re-forwarding stops as soon as confirmation resolves (successfully or by throwing) or `timeout` elapses.
Yes
timeoutCount
number
Count of `confirmTransactionWebSocket`/`confirmTransactionPolling` calls that hit `timeout` without a definitive result.
Yes
confirmationStrategy
ConfirmationStrategy
Yes
additionalTxSenderCallbacks
((base58EncodedTx: string) => void)[]
Callbacks invoked with the base58-encoded raw transaction alongside `additionalConnections` broadcasts, e.g. for logging/mempool submission.
No
txHandler
TxHandler
Yes
trackTxLandRate
boolean
Whether to record each sent signature (via `txSigCache`) to compute `getTxLandRate()`.
No
throwOnTimeoutError
boolean
Whether `confirmTransactionWebSocket`/`confirmTransactionPolling` throw `TxSendError` on timeout (`true`) or return `undefined` (`false`).
Yes
throwOnTransactionError
boolean
Whether `checkConfirmationResultForError` throws the resolved on-chain error, or is a no-op.
Yes
lookbackWindowMinutes
number
Lookback window, in seconds, over which `txSigCache` entries expire for the land-rate calculation.
Yes
txSigCache
NodeCache
TTL cache of `txSig -> landed?` used to compute `getTxLandRate()` when `trackTxLandRate` is set.
No
txLandRate
number
Yes
lastPriorityFeeSuggestion
number
Yes
landRateToFeeFunc
(landRate: number) => number
Maps a land rate (0-1) to a priority-fee multiplier; defaults to `defaultLandRateToFeeFunc`.
Yes
send
(tx: Transaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (via `prepareTx`, unless `preSigned`) and sends a legacy `Transaction`.
Yes
prepareTx
(tx: Transaction, additionalSigners: Signer[], opts: ConfirmOptions, preSigned?: boolean | undefined) => Promise<Transaction>
Delegates to `TxHandler.prepareTx` to attach a recent blockhash, fee payer, and signatures.
Yes
getVersionedTransaction
(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], _additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, blockhash?: Readonly<...> | undefined) => Promise<...>
Builds (but does not send) a `VersionedTransaction` from raw instructions via `TxHandler.generateVersionedTransaction`.
Yes
sendVersionedTransaction
(tx: VersionedTransaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (unless `preSigned`) and sends a `VersionedTransaction`. When the wallet exposes a `payer` `Keypair` directly, signs in-place with `tx.sign(...)`; otherwise delegates to `TxHandler.signVersionedTx` (needed for wallet adapters without direct keypair access).
Yes
simulateTransaction
(tx: VersionedTransaction) => Promise<boolean>
Simulates a transaction via `connection.simulateTransaction` without sending it, swallowing both simulation errors and RPC-call failures into a `false` result (logged to `console.error`).
Yes
confirmTransactionWebSocket
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Waits for a transaction to confirm by subscribing to `onSignature` on `connection` and every `additionalConnections` entry simultaneously, resolving on whichever responds first. If no connection confirms within `this.timeout` and `confirmationStrategy` is `Combo`, falls back to a one-shot `getSignatureStatuses` check before giving up.
Yes
confirmTransactionPolling
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Waits for a transaction to confirm by polling `getSignatureStatuses` with exponential backoff, starting at 400ms and capping at 5000ms, until `commitment` is reached or `this.timeout` elapses.
Yes
confirmTransaction
(signature: string, commitment?: Commitment | undefined) => Promise<RpcResponseAndContext<SignatureResult> | undefined>
Confirms a transaction using whichever strategy `this.confirmationStrategy` selects: `WebSocket`/`Combo` route to `confirmTransactionWebSocket`, `Polling` to `confirmTransactionPolling`.
Yes
getTimestamp
() => number
Current time in milliseconds since epoch (thin wrapper over `Date.now()`, overridable in tests).
Yes
promiseTimeout
<T>(promises: Promise<T>[], timeoutMs: number) => Promise<T | null>
Races an array of promises against a timeout, resolving to `null` (rather than rejecting) if none settle in time. Unlike `../util/promiseTimeout`, this accepts multiple promises (used to race confirmation across `connection` plus every `additionalConnections` entry).
Yes
addAdditionalConnection
(newConnection: Connection) => void
Adds an extra RPC connection to broadcast future transactions to, unless a connection with the same RPC endpoint is already registered.
Yes
getTimeoutCount
() => number
Yes
checkConfirmationResultForError
(txSig: string, result: SignatureResult) => Promise<void>
Inspects a confirmed signature's result and, if it recorded an on-chain error, resolves the detailed program error via `throwTransactionError` and throws it. Note this check runs whenever `result.err` is set, independent of the `throwOnTransactionError` field — callers that want to suppress transaction-error throwing should avoid calling this method rather than rely on that flag here.
Yes
getTxLandRate
() => number
Computes the fraction of recently sent transactions (within `lookbackWindowMinutes`) that landed, from `txSigCache`'s current entries. Returns the last computed `txLandRate` (default 0) if `trackTxLandRate` is disabled or the cache is empty, rather than recomputing.
Yes
defaultLandRateToFeeFunc
any
Default `landRateToFeeFunc`: returns `1` (no boost) if the land rate is already at/above `BASELINE_TX_LAND_RATE` (0.9) or fewer than 3 samples have been recorded yet (too little data to react); otherwise returns a multiplier that grows logarithmically as the land rate falls further below baseline, capped at `10`.
Yes
getSuggestedPriorityFeeMultiplier
() => number
Suggests a multiplier to apply to a base priority fee, based on recent land rate — intended for callers to scale up their compute-unit price when transactions have been landing poorly.
Yes

ForwardOnlyTxSender defaults additionalTxSenderCallbacks to an empty array. With no callbacks it never broadcasts the transaction anywhere, so it will always time out.

Blockhash handling in TxHandler

TxHandler owns blockhash resolution. By default it uses a caching fetcher that reuses a recent blockhash for 2,000 ms, which collapses per-build getLatestBlockhash calls during bursts. Blockhashes stay valid on-chain far longer than that window, so this is safe.

txHandlerConfig fieldMeaningDefault
blockhashCachingEnabledfalse forces a fresh RPC fetch on every buildtrue
blockhashCachingConfig.retryCountFetch retries3
blockhashCachingConfig.retrySleepTimeMsSleep between retries200 ms
blockhashCachingConfig.staleCacheTimeMsHow long a cached blockhash is reused2,000 ms

The commitment used for blockhash fetches comes from confirmationOptions.preflightCommitment, falling back to connection.commitment, then confirmed.

import { TxHandler } from "@velocity-exchange/sdk"; const txHandler = new TxHandler({ connection, wallet, confirmationOptions: { commitment: "confirmed", preflightCommitment: "confirmed" }, config: { blockhashCachingEnabled: true, blockhashCachingConfig: { staleCacheTimeMs: 2_000 }, }, }); // Build a v0 transaction from raw instructions. const tx = await txHandler.buildTransaction({ instructions: [ix], txVersion: 0, connection, fetchAllMarketLookupTableAccounts: () => velocityClient.fetchAllLookupTableAccounts(), txParams: { computeUnits: 400_000, computeUnitsPrice: 25_000 }, });
Class TxHandlerReference ↗

This class is responsible for creating and signing transactions.

Owns blockhash resolution (via a `BlockhashFetcher`, optionally caching), compute-budget instruction injection, address-lookup-table compilation, and wallet signing for both legacy and v0 transactions, single or batched. `TxSender` implementations delegate to a `TxHandler` instance for all of this rather than duplicating it.

PropertyTypeRequired
blockHashToLastValidBlockHeightLookup
any
Yes
returnBlockHeightsWithSignedTxCallbackData
any
Yes
connection
any
Yes
wallet
any
Yes
confirmationOptions
any
Yes
preSignedCb
any
No
onSignedCb
any
No
blockhashCommitment
any
Yes
blockHashFetcher
any
Yes
getWallet
() => IWallet
Yes
addHashAndExpiryToLookup
any
Yes
getProps
any
Yes
updateWallet
(wallet: IWallet) => void
Swaps the default wallet used for subsequent signing calls that don't pass their own.
Yes
getLatestBlockhashForTransaction
() => Promise<Readonly<{ blockhash: string; lastValidBlockHeight: number; }> | undefined>
Created this to prevent non-finalized blockhashes being used when building transactions. We want to always use finalized because otherwise it's easy to get the BlockHashNotFound error (RPC uses finalized to validate a transaction). Using an older blockhash when building transactions should never really be a problem right now. https://www.helius.dev/blog/how-to-deal-with-blockhash-errors-on-solana#why-do-blockhash-errors-occur
Yes
resolveRecentBlockhash
any
Resolves a usable recent blockhash, preferring a caller-provided one and otherwise fetching the latest. Throws if no blockhash can be obtained, since a transaction cannot be built or signed without one.
Yes
prepareTx
(tx: Transaction, additionalSigners: Signer[], wallet?: IWallet | undefined, confirmationOpts?: ConfirmOptions | undefined, preSigned?: boolean | undefined, recentBlockhash?: Readonly<...> | undefined) => Promise<...>
Applies recent blockhash and signs a given transaction. Attaches an internal `SIGNATURE_BLOCK_AND_EXPIRY` property (undocumented in the `Transaction` type, but read by `WhileValidTxSender`) recording the blockhash/expiry used, so confirmation logic can know when the transaction's blockhash has expired even for pre-built transactions.
Yes
isVersionedTransaction
any
Yes
isLegacyTransaction
any
Yes
getTxSigFromSignedTx
any
Yes
getBlockhashFromSignedTx
any
Yes
signTx
any
Yes
signVersionedTx
(tx: VersionedTransaction, additionalSigners: Signer[], recentBlockhash?: Readonly<{ blockhash: string; lastValidBlockHeight: number; }> | undefined, wallet?: IWallet | undefined) => Promise<...>
Signs a `VersionedTransaction`, optionally overwriting its blockhash first.
Yes
handleSignedTxData
any
Yes
getProcessedTransactionParams
any
Gets transaction params with extra processing applied, like using the simulated compute units or using a dynamically calculated compute unit price.
Yes
_generateVersionedTransaction
any
Yes
generateLegacyVersionedTransaction
(recentBlockhash: Readonly<{ blockhash: string; lastValidBlockHeight: number; }>, ixs: TransactionInstruction[], wallet?: IWallet | undefined) => VersionedTransaction
Builds an unsigned `VersionedTransaction` that wraps a *legacy* compiled message (no address lookup tables) — used when `forceVersionedTransaction` is requested for a `'legacy'` `txVersion`.
Yes
generateVersionedTransaction
(recentBlockhash: Readonly<{ blockhash: string; lastValidBlockHeight: number; }>, ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], wallet?: IWallet | undefined) => VersionedTransaction
Builds an unsigned v0 `VersionedTransaction`, compiling its message against the given address lookup tables.
Yes
generateLegacyTransaction
(ixs: TransactionInstruction[], recentBlockhash?: Readonly<{ blockhash: string; lastValidBlockHeight: number; }> | undefined) => Transaction
Builds an unsigned legacy `Transaction` from raw instructions. Unlike the other `generate*` methods, this does not set a fee payer.
Yes
buildBulkTransactions
(props: Omit<TxBuildingProps, "instructions"> & { instructions: (TransactionInstruction | TransactionInstruction[])[]; }) => Promise<...>
Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
Yes
buildTransaction
(props: TxBuildingProps) => Promise<Transaction | VersionedTransaction>
Builds a full transaction from raw instructions: merges caller-supplied `lookupTables` with the market lookup tables from `fetchAllMarketLookupTableAccounts`, optionally appends as many `optionalIxs` (e.g. oracle cranks) as fit under `MAX_TX_BYTE_SIZE` (dropped one-by-one and re-simulated if the batch fails simulation), resolves compute-unit limit/price (via simulation if `txParams.useSimulatedComputeUnits`), and prepends the resulting `ComputeBudgetProgram` instructions unless the caller's instructions already include them.
Yes
wrapInTx
(instruction: TransactionInstruction, computeUnits?: number | undefined, computeUnitsPrice?: number | undefined) => Transaction
Wraps a single instruction in a legacy `Transaction`, prepending compute-budget instructions as needed. Does not set a blockhash or fee payer.
Yes
getPreparedAndSignedLegacyTransactionMap
<T extends Record<string, Transaction | undefined>>(txsMap: T, wallet?: IWallet | undefined, commitment?: Commitment | undefined, recentBlockhash?: Readonly<{ blockhash: string; lastValidBlockHeight: number; }> | undefined) => Promise<...>
Get a map of signed and prepared transactions from an array of legacy transactions
Yes
getSignedTransactionMap
<T extends Record<string, Transaction | VersionedTransaction | undefined>>(txsToSignMap: T, wallet?: IWallet | undefined) => Promise<{ signedTxMap: T; signedTxData: SignedTxData[]; }>
Get a map of signed transactions from an array of transactions to sign. Signs all non-`undefined` entries in a single `wallet.signAllTransactions` batch (one wallet approval for the whole map, where the wallet supports it) rather than one signature request per transaction.
Yes
buildTransactionsMap
<T extends Record<string, TransactionInstruction | TransactionInstruction[]>>(props: Omit<TxBuildingProps, "instructions"> & { instructionsMap: T; }) => Promise<...>
Accepts multiple instructions and builds a transaction for each. Prevents needing to spam RPC with requests for the same blockhash.
Yes
buildAndSignTransactionMap
<T extends Record<string, TransactionInstruction | TransactionInstruction[]>>(props: Omit<TxBuildingProps, "instructions"> & { instructionsMap: T; }) => Promise<...>
Builds and signs transactions from a given array of instructions for multiple transactions. Builds every transaction first (`buildTransactionsMap`), then signs them all in one batch — via `getPreparedAndSignedLegacyTransactionMap` for `'legacy'` `txVersion`, otherwise `getSignedTransactionMap`.
Yes
simulateAndCalculateInstructions
(txBuildingProps: TxBuildingProps, optionalInstructions?: TransactionInstruction[] | undefined, versionedTransaction?: boolean | undefined, addressLookupTables?: AddressLookupTableAccount[] | undefined) => Promise<...>
Greedily includes as many `optionalInstructions` (e.g. oracle-crank instructions) as fit alongside `txBuildingProps.instructions` under `MAX_TX_BYTE_SIZE`, then simulates the result; if simulation fails, falls back to simulating with only the base instructions (optional ones dropped entirely) rather than trying to isolate which optional instruction caused the failure.
Yes

Compute units and priority fee params

txParams is a BaseTxParams plus a ProcessingTxParams. The base half is what ends up in the compute-budget instructions; the processing half tells the SDK how to derive those numbers.

FieldMeaning
computeUnitsCompute-unit limit to request. VelocityClient defaults to 600,000.
computeUnitsPricePriority fee in micro-lamports per compute unit. VelocityClient defaults to 0.
useSimulatedComputeUnitsSimulate the transaction and use the measured usage as the limit instead of the static value.
computeUnitsBufferMultiplierMultiplier applied to the simulated usage. Defaults to 1.2 (20% headroom).
useSimulatedComputeUnitsForCUPriceCalculationAlso derive the price from the simulated unit count. Requires useSimulatedComputeUnits and getCUPriceFromComputeUnits.
getCUPriceFromComputeUnitsFunction mapping a compute-unit count to a price in micro-lamports.
lowerBoundCuFloor applied to the derived limit.

Solana charges the priority fee on the requested limit, not on what the transaction consumes. A 600,000-unit request at 25,000 micro-lamports per unit costs the same whether the instruction burns 40,000 units or 400,000. Right-sizing computeUnits (statically or by simulation) is the cheapest priority-fee optimization available.

TransactionParamProcessor

TransactionParamProcessor.process() runs the simulation pipeline. It rebuilds the transaction with the limit forced to 1,400,000 units so simulation is not constrained by an undersized budget, simulates it with replaceRecentBlockhash: true (which avoids spurious blockHashNotFound failures from an already-stale blockhash), then multiplies the measured usage by the buffer and clamps the result to 1,400,000.

Simulation failure is not fatal. getTxSimComputeUnits catches every error and returns { success: false }, and process() then leaves the original computeUnits in place. The only cases that throw are misconfiguration: useSimulatedComputeUnitsForCUPriceCalculation without useSimulatedComputeUnits, without getCUPriceFromComputeUnits, or when the simulated unit count is unavailable.

import { TransactionParamProcessor } from "@velocity-exchange/sdk"; // Size the limit from a simulation and derive the price from the result. const velocityClient = new VelocityClient({ connection, wallet, txParams: { computeUnits: 600_000, // fallback if the simulation fails useSimulatedComputeUnits: true, computeUnitsBufferMultiplier: 1.2, lowerBoundCu: 100_000, useSimulatedComputeUnitsForCUPriceCalculation: true, getCUPriceFromComputeUnits: (computeUnits) => Math.floor(priorityFeeSubscriber.getCustomStrategyResult()), }, }); // Or size one transaction directly. const { success, computeUnits } = await TransactionParamProcessor.getTxSimComputeUnits( tx, connection, 1.2, // buffer multiplier, mandatory 100_000 // optional lower bound );
Class TransactionParamProcessorReference ↗
TypeScript docs unavailable for TransactionParamProcessor.

PriorityFeeCalculator

PriorityFeeCalculator is a smaller, reactive helper: it watches a sender’s timeout count and turns the priority fee on only after transactions start timing out, then latches it on for priorityFeeLatchDurationMs (default 10,000 ms). Its generateComputeBudgetWithPriorityFeeIx() converts a target total fee in micro-lamports into a per-unit price by dividing by the compute-unit limit.

import { PriorityFeeCalculator } from "@velocity-exchange/sdk"; const calculator = new PriorityFeeCalculator(Date.now()); const usePriorityFee = calculator.updatePriorityFee( Date.now(), velocityClient.txSender.getTimeoutCount() ); const computeBudgetIxs = calculator.generateComputeBudgetWithPriorityFeeIx( 600_000, // compute unit limit usePriorityFee, 1_000_000 // additional fee to pay, in micro-lamports );
Class PriorityFeeCalculatorReference ↗

This class determines whether a priority fee needs to be included in a transaction based on a recent history of timed out transactions.

PropertyTypeRequired
lastTxTimeoutCount
number
Yes
priorityFeeTriggered
boolean
Yes
lastTxTimeoutCountTriggered
number
Yes
priorityFeeLatchDurationMs
number
Yes
updatePriorityFee
(currentTimeMs: number, txTimeoutCount: number) => boolean
Update the priority fee state based on the current time and the current timeout count.
Yes
generateComputeBudgetIxs
(computeUnitLimit: number) => TransactionInstruction[]
This method returns a transaction instruction list that sets the compute limit on the ComputeBudget program.
Yes
calculateComputeUnitPrice
(computeUnitLimit: number, additionalFeeMicroLamports: number) => number
Calculates the compute unit price to use based on the desired additional fee to pay and the compute unit limit.
Yes
generateComputeBudgetWithPriorityFeeIx
(computeUnitLimit: number, usePriorityFee: boolean, additionalFeeMicroLamports: number) => TransactionInstruction[]
This method generates a list of transaction instructions for the ComputeBudget program, and includes a priority fee if it's required
Yes

Priority fee subscribers

For a live fee estimate rather than a reactive switch, use the priorityFee module. PriorityFeeSubscriber polls one fee source on an interval (default 10,000 ms) and exposes the latest aggregate. Every value it returns is in micro-lamports per compute unit, the unit ComputeBudgetProgram.setComputeUnitPrice expects.

Fee sources

priorityFeeMethod selects the upstream API. It defaults to PriorityFeeMethod.SOLANA.

MethodUpstream callRequired configNotes
SOLANAgetRecentPrioritizationFees on your RPCconnectionSamples are filtered to the most recent slotsToCheck slots (default 50) relative to the newest returned slot, then sorted descending by slot. Override the call itself with fetchSolanaPriorityFee to route through your own cache.
HELIUSHelius getPriorityFeeEstimate with includeAllPriorityFeeLevels: trueheliusRpcUrl, or a connection whose endpoint contains heliusReturns percentile buckets: min, low (25th), medium (50th), high (75th), veryHigh (95th), unsafeMax (100th). Read them with getHeliusPriorityFeeLevel(level), which defaults to MEDIUM.
VELOCITYVelocity’s hosted /batchPriorityFees endpointvelocityPriorityFeeEndpoint, velocityMarketsPer-market fee levels, same percentile buckets. See /batchPriorityFees.

The constructor throws if you select HELIUS without a resolvable Helius URL, or SOLANA without a connection.

addresses scopes SOLANA and HELIUS sampling to the accounts your transaction will write-lock, which is what you want: it measures congestion on the markets you are trading, not the whole cluster.

Strategies

customStrategy is any object implementing PriorityFeeStrategy.calculate(samples). Five implementations ship with the SDK.

StrategyResultEmpty sample set
AverageOverSlotsStrategyMean fee across the lookback window. This is the default customStrategy.0
AverageStrategyMean fee across all samples, without the empty guardNaN
MaxOverSlotsStrategyHighest fee in the lookback window0
MaxStrategyHighest fee across all samples, without the empty guard-Infinity
EwmaStrategyExponentially weighted moving average over slots, so recent samples dominate and larger slot gaps decay older samples faster. Half life defaults to 25 slots (roughly 10 seconds)0

Prefer the ...OverSlots variants unless you handle the empty case yourself.

Every getter (getCustomStrategyResult, getAvgStrategyResult, getMaxStrategyResult) multiplies by priorityFeeMultiplier (default 1.0) and then clamps to maxFeeMicroLamports if you set one. All three return 0 before the first successful load(). getHeliusPriorityFeeLevel clamps but does not apply the multiplier. Both the multiplier and the clamp can be changed at runtime with updatePriorityFeeMultiplier() and updateMaxPriorityFee().

import { PriorityFeeSubscriber, PriorityFeeMethod, EwmaStrategy, } from "@velocity-exchange/sdk"; const priorityFeeSubscriber = new PriorityFeeSubscriber({ connection, frequencyMs: 5_000, priorityFeeMethod: PriorityFeeMethod.SOLANA, slotsToCheck: 50, addresses: [perpMarketPublicKey, userAccountPublicKey], customStrategy: new EwmaStrategy(25), priorityFeeMultiplier: 1.5, maxFeeMicroLamports: 1_000_000, }); await priorityFeeSubscriber.subscribe(); // Micro-lamports per compute unit, multiplied and clamped. const computeUnitsPrice = Math.floor(priorityFeeSubscriber.getCustomStrategyResult()); await priorityFeeSubscriber.unsubscribe();
Class PriorityFeeSubscriberReference ↗

PriorityFeeSubscriber — polls one of three sources (Solana RPC, Helius, or the Velocity-hosted priority fee cache — see `PriorityFeeMethod`) on an interval and exposes several aggregations over the resulting samples: a simple average, a max, and a caller-supplied `customStrategy`. All `get*StrategyResult` accessors return `0` until the first successful poll, and are clamped to `maxFeeMicroLamports` (if set) after applying `priorityFeeMultiplier`. All returned fee values are in micro-lamports per compute unit, the unit Solana's `ComputeBudgetProgram.setComputeUnitPrice` expects.

PropertyTypeRequired
connection
Connection
No
frequencyMs
number
Yes
addresses
string[]
Yes
velocityMarkets
VelocityMarketInfo[]
No
customStrategy
PriorityFeeStrategy
No
averageStrategy
AverageOverSlotsStrategy
Yes
maxStrategy
MaxOverSlotsStrategy
Yes
priorityFeeMethod
PriorityFeeMethod
Yes
lookbackDistance
number
Yes
maxFeeMicroLamports
number
No
priorityFeeMultiplier
number
No
velocityPriorityFeeEndpoint
string
No
heliusRpcUrl
string
No
lastHeliusSample
HeliusPriorityFeeLevels
No
intervalId
Timeout
No
latestPriorityFee
number
Yes
lastCustomStrategyResult
number
Yes
lastAvgStrategyResult
number
Yes
lastMaxStrategyResult
number
Yes
lastSlotSeen
number
Yes
subscribe
() => Promise<void>
Starts polling at `frequencyMs` and performs one immediate `load()`. Idempotent while already subscribed.
Yes
loadForSolana
any
Yes
loadForHelius
any
Yes
loadForVelocity
any
Yes
getMaxPriorityFee
() => number | undefined
Yes
updateMaxPriorityFee
(newMaxFee: number | undefined) => void
Updates the clamp applied to all `get*StrategyResult`/`getHeliusPriorityFeeLevel` results. Pass `undefined` to remove the clamp.
Yes
getPriorityFeeMultiplier
() => number
Yes
updatePriorityFeeMultiplier
(newPriorityFeeMultiplier: number) => void
Updates the multiplier applied to `getCustomStrategyResult`/`getAvgStrategyResult`/`getMaxStrategyResult` before clamping.
Yes
updateCustomStrategy
(newStrategy: PriorityFeeStrategy) => void
Swaps the `PriorityFeeStrategy` used to compute `getCustomStrategyResult`; takes effect on the next `load()`.
Yes
getHeliusPriorityFeeLevel
(level?: HeliusPriorityLevel | undefined) => number
Only meaningful with `priorityFeeMethod: HELIUS`.
Yes
getCustomStrategyResult
() => number
Yes
getAvgStrategyResult
() => number
Yes
getMaxStrategyResult
() => number
Yes
load
() => Promise<void>
Fetches one round of samples from the configured `priorityFeeMethod` and recomputes `latestPriorityFee`/`lastAvgStrategyResult`/ `lastMaxStrategyResult`/`lastCustomStrategyResult`. Errors are caught and logged, not thrown, so a transient failure just leaves the previous values in place until the next poll.
Yes
unsubscribe
() => Promise<void>
Stops polling.
Yes
updateAddresses
(addresses: PublicKey[]) => void
Replaces the set of write-locked addresses used for SOLANA/HELIUS fee sampling; takes effect on the next `load()`.
Yes
updateMarketTypeAndIndex
(velocityMarkets: VelocityMarketInfo[]) => void
Replaces the set of markets queried when `priorityFeeMethod` is VELOCITY; takes effect on the next `load()`.
Yes

load() swallows errors and logs them, so a transient RPC failure leaves the previous values in place until the next poll. Call updateAddresses() or updateMarketTypeAndIndex() to change what is sampled; both take effect on the next poll.

PriorityFeeSubscriberMap

PriorityFeeSubscriberMap fetches per-market fee levels for many markets in one request and keeps them addressable individually, rather than collapsing them into a single aggregate. It only supports the Velocity endpoint.

import { PriorityFeeSubscriberMap } from "@velocity-exchange/sdk"; const subscriberMap = new PriorityFeeSubscriberMap({ velocityPriorityFeeEndpoint: "https://dlob.velocity.exchange", frequencyMs: 5_000, velocityMarkets: [ { marketType: "perp", marketIndex: 0 }, { marketType: "perp", marketIndex: 1 }, { marketType: "spot", marketIndex: 2 }, ], }); await subscriberMap.subscribe(); // undefined until the first successful load const fees = subscriberMap.getPriorityFees("perp", 0); console.log(fees?.medium, fees?.veryHigh);
Class PriorityFeeSubscriberMapReference ↗

PriorityFeeSubscriberMap — polls the Velocity-hosted `/batchPriorityFees` endpoint for a fixed set of markets and caches the latest per-market fee levels, keyed by market type and index. Unlike `PriorityFeeSubscriber` (single aggregated result across `PriorityFeeMethod.VELOCITY` markets), this exposes each market's fee levels independently via `getPriorityFees`.

PropertyTypeRequired
frequencyMs
number
Yes
intervalId
Timeout
No
velocityMarkets
VelocityMarketInfo[]
No
velocityPriorityFeeEndpoint
string
Yes
feesMap
Map<string, Map<number, VelocityPriorityFeeLevels>>
Yes
updateFeesMap
any
Yes
subscribe
() => Promise<void>
Performs an immediate `load()` and then polls at `frequencyMs`. Idempotent while already subscribed.
Yes
unsubscribe
() => Promise<void>
Stops polling.
Yes
load
() => Promise<void>
Fetches one batch of per-market fee levels from `/batchPriorityFees` for all `velocityMarkets` and merges the results into `feesMap`. No-ops if no markets are configured. Errors are caught and logged, not thrown — `feesMap` is left at its previous state.
Yes
updateMarketTypeAndIndex
(velocityMarkets: VelocityMarketInfo[]) => void
Replaces the set of markets to fetch fees for; takes effect on the next `load()`.
Yes
getPriorityFees
(marketType: string, marketIndex: number) => VelocityPriorityFeeLevels | undefined
Yes

Reacting to poor landing

With trackTxLandRate: true, the sender records each signature and computes a rolling land rate. Feed the suggested multiplier into your compute-unit price to back off automatically under congestion:

const txSender = new RetryTxSender({ connection, wallet, trackTxLandRate: true, txLandRateLookbackWindowMinutes: 10, }); const landRate = txSender.getTxLandRate(); // 0 to 1 const multiplier = txSender.getSuggestedPriorityFeeMultiplier(); // 1 to 10 const timeouts = txSender.getTimeoutCount(); const computeUnitsPrice = Math.floor( priorityFeeSubscriber.getCustomStrategyResult() * multiplier );
Type TxSenderReference ↗

Common interface implemented by every transaction-sending strategy (`BaseTxSender` and its subclasses).

PropertyTypeRequired
wallet
IWallet
Yes
send
(tx: Transaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (unless `preSigned`), sends, and confirms a legacy `Transaction`.
Yes
sendVersionedTransaction
(tx: VersionedTransaction, additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, preSigned?: boolean | undefined) => Promise<...>
Signs (unless `preSigned`), sends, and confirms a `VersionedTransaction`.
Yes
getVersionedTransaction
(ixs: TransactionInstruction[], lookupTableAccounts: AddressLookupTableAccount[], additionalSigners?: Signer[] | undefined, opts?: ConfirmOptions | undefined, blockhash?: Readonly<...> | undefined) => Promise<...>
Builds (but does not send or sign) an unsigned `VersionedTransaction` from raw instructions.
Yes
sendRawTransaction
(rawTransaction: Buffer | Uint8Array<ArrayBufferLike>, opts: ConfirmOptions) => Promise<TxSigAndSlot>
Sends an already-serialized, already-signed transaction and confirms it.
Yes
simulateTransaction
(tx: VersionedTransaction) => Promise<boolean>
Simulates a transaction against the cluster without sending it.
Yes
getTimeoutCount
() => number
Number of transactions sent by this sender that timed out waiting for confirmation.
Yes
getSuggestedPriorityFeeMultiplier
() => number
Multiplier this sender currently recommends applying to a base priority fee, derived from recent land/timeout behavior.
Yes
getTxLandRate
() => number
Fraction (0-1) of recently sent transactions that landed successfully.
Yes
Last updated on