Skip to Content

Events

Protocol events are emitted in transaction logs. The SDK provides an EventSubscriber that can listen, deserialize, and emit events to your app in real-time.

Event Types

Event TypeDescription
DepositRecordA user depositing or withdrawing funds from the protocol
FundingPaymentRecordA user paying or receiving funding payments
LiquidationRecordA user being liquidated
OrderRecordA user placing an order (includes all order parameters)
OrderActionRecordA user action on an order: place, cancel, or fill
FundingRateRecordThe funding rate changing for a market
NewUserRecordA new user account being created
DeleteUserRecordA user account being deleted
SettlePnlRecordA user settling their perp PnL
InsuranceFundRecordThe insurance fund balance changing
SpotInterestRecordSpot interest accruing
InsuranceFundStakeRecordA user staking or unstaking from the insurance fund
AmmCurveChangedThe AMM curve parameters updating
SwapRecordA Jupiter or Titan swap executed through a Velocity account
SpotMarketVaultDepositRecordAn external deposit landing directly in a spot market vault
SignedMsgOrderRecordA signed (Swift) order being placed
LPMintRedeemRecordA user minting or redeeming VLP (Velocity LP) tokens
LPSettleRecordA VLP pool settling PnL against its constituents
LPSwapRecordA swap between constituents inside a VLP pool
LPBorrowLendDepositRecordA VLP pool borrow/lend deposit or withdrawal against a constituent
PerpMarketFeeSweepRecordA streaming sweep of a perp market’s fee ledger into the insurance, protocol, and AMM fee pools
ProtocolFeeWithdrawRecordAn admin withdrawal from a perp or spot market’s protocol fee pool
RevenueShareSettleRecordA builder/referrer revenue-share settlement for a market
TransferFeeAndPnlPoolRecordAn admin transfer between a perp market’s fee pool and PnL pool

CurveRecord was renamed to AmmCurveChanged (the fields also changed). LPRecord (vAMM/BAMM LP shares) no longer exists — passive liquidity now flows through the VLP module, whose activity is split across LPMintRedeemRecord, LPSettleRecord, LPSwapRecord, and LPBorrowLendDepositRecord. PerpMarketFeeSweepRecord, ProtocolFeeWithdrawRecord, RevenueShareSettleRecord, and TransferFeeAndPnlPoolRecord have long been emitted on-chain but were only recently registered in the SDK’s event map — older SDK versions silently dropped them from EventSubscriber.

Subscribing to Events

Create an EventSubscriber and pass the event types you want to receive. The newEvent emitter fires for every incoming event that matches your filter.

import { EventSubscriber } from "@velocity-exchange/sdk"; const options = { eventTypes: [ "DepositRecord", "FundingPaymentRecord", "LiquidationRecord", "OrderRecord", "OrderActionRecord", "FundingRateRecord", "NewUserRecord", "SettlePnlRecord", "InsuranceFundRecord", "SpotInterestRecord", "InsuranceFundStakeRecord", "AmmCurveChanged", "PerpMarketFeeSweepRecord", "ProtocolFeeWithdrawRecord", "RevenueShareSettleRecord", "TransferFeeAndPnlPoolRecord", ], maxTx: 4096, maxEventsPerType: 4096, orderBy: "blockchain", orderDir: "asc", commitment: "confirmed", logProviderConfig: { type: "websocket" }, }; const eventSubscriber = new EventSubscriber(connection, velocityClient.program, options); await eventSubscriber.subscribe(); // `newEvent` is the only real-time emitter: it fires for every incoming event eventSubscriber.eventEmitter.on("newEvent", (event) => { console.log(event.eventType, event); });

Leaving eventTypes unset falls back to DefaultEventSubscriptionOptions, which includes every event type above plus SwapRecord, SpotMarketVaultDepositRecord, SignedMsgOrderRecord, DeleteUserRecord, and the four LP* VLP events.

Filtering Events

You can filter events by market index, event type, or action using the isVariant helper function. This is useful for focusing on specific markets or event types in your bot.

import { isVariant } from "@velocity-exchange/sdk"; // Example: Filter for perp fills on a specific market const marketIndex = 0; const isPerpFill = (event) => { if (event.eventType !== "OrderActionRecord") return false; if (event.marketIndex !== marketIndex) return false; if (!isVariant(event.marketType, "perp")) return false; if (!isVariant(event.action, "fill")) return false; return true; }; eventSubscriber.eventEmitter.on("newEvent", (event) => { if (isPerpFill(event)) console.log("Perp fill on market", marketIndex, event); });

Common filter patterns for bots:

// Filter by market index only eventSubscriber.eventEmitter.on("newEvent", (event) => { if (event.marketIndex === 0) { console.log("Event on market 0:", event); } }); // Filter by event type eventSubscriber.eventEmitter.on("newEvent", (event) => { if (event.eventType === "DepositRecord") { console.log("Deposit event:", event); } }); // Filter for liquidations eventSubscriber.eventEmitter.on("newEvent", (event) => { if (event.eventType === "LiquidationRecord") { console.log("Liquidation:", event); } }); // Filter for protocol fee-sweep activity on a perp market eventSubscriber.eventEmitter.on("newEvent", (event) => { if (event.eventType === "PerpMarketFeeSweepRecord") { console.log("Fee sweep:", event); } });

Querying Stored Events

The EventSubscriber keeps a rolling buffer of recent events in memory. You can query these at any time without waiting for a new event to arrive.

Retrieve all stored events of a given type:

// Returns all events of this type currently in memory (snapshotted into an array) const eventType = "OrderActionRecord"; const events = eventSubscriber.getEventsArray(eventType); // Prefer getEventList() when iterating without copying — it returns the // live, size-bounded EventList the subscriber inserts into directly. const eventList = eventSubscriber.getEventList(eventType);

Retrieve all events from a specific transaction:

const txSig = "3dq5PtQ3VnNTkQRrHhQ1nRACWZaFVvSBKs1RLXM8WvCqLHTzTuVGc7XER5awoLFLTdJ4kqZiNmo7e8b3pXaEGaoo"; const events = eventSubscriber.getEventsByTx(txSig);
Last updated on