Skip to main content

Spot Canister API Reference

Each Spot canister serves exactly one trading pair (base/quote). It combines a central limit order book (CLOB) with Uniswap V3-style concentrated liquidity AMM pools, unified under a single-canister architecture on the Internet Computer.

Loading markets…

Queries (Public)

No authentication required. Anonymous callers allowed.

get_reference_tick

query get_reference_tick() → opt Tick

Current market reference tick. Derived as: book mid > viable pool median > last trade tick > null.

get_routing_state

query get_routing_state() → RoutingState

Atomic snapshot of the complete routing state for external routers. Single call provides token metadata, reference tick, pool state, and order book — everything needed to simulate order execution off-chain.

get_control

query get_control() → FrozenControl

Canister control plane state: system state, token config, fee parameters, entity counts, admin principals.

get_pool

query get_pool(fee_pips: Nat32) → opt PoolState

Detailed state for a specific pool tier. Returns null if no pool exists for the given fee tier.

ParamType
fee_pipsNat32Pool fee tier: 100–10000 in steps of 100

get_pools_overview

query get_pools_overview() → vec PoolOverview

All active pools with fee tier, position count, TVL, volume, and APR.

get_market_depth

query get_market_depth(levels: Nat32, tick_bucket_size: Nat32) → MarketDepthResponse

Separated order book and pool liquidity depth.

ParamType
levelsNat32Price levels per side
tick_bucket_sizeNat32Aggregation width in ticks (0 = finest)

get_balance_sheet

query get_balance_sheet() → BalanceSheet

Complete balance sheet with invariant checks: INV-1a (balance sheet), INV-2 (user fund conservation), INV-3 (pool consistency).

get_lock_schedule

query get_lock_schedule() → LiquidityLockSummary

Liquidity lock schedule: locked vs unlocked TVL and upcoming unlock times.

get_indexer_data

query get_indexer_data() → IndexerData

Aggregate token stats and per-pool breakdowns for the indexer canister.

get_transactions

query get_transactions(limit: opt Nat32, cursor: opt Nat64) → { data: vec SpotTransactionResponse, has_more: Bool, next_cursor: opt Nat64 }

Recent trades with cursor-based pagination (newest first). limit defaults to 20 (max 100).

get_chart

query get_chart(interval: ChartInterval, before_ts: opt Nat64, limit: Nat32) → { data: vec SpotCandle, has_more: Bool, next_cursor: opt Nat64 }

Historical OHLCV candles with pagination.

get_live_candle

query get_live_candle(interval: ChartInterval) → CandleData

Current unclosed candle. CandleData = (timestamp, open_e12, high_e12, low_e12, close_e12, volume_native).

get_pool_snapshots

query get_pool_snapshots(fee_pips: Nat32, before_timestamp: opt Nat64, limit: Nat32, interval_hours: Nat32) → PoolSnapshotsResponse

Historical fee snapshots for a specific pool at any hourly interval.

get_market_snapshots

query get_market_snapshots(before_timestamp: opt Nat64, limit: Nat32, interval_hours: Nat32) → MarketSnapshotsResponse

Historical market-level snapshots for TVL charts. Aggregates all pools and the order book.

get_position

query get_position(id: PositionId) → opt PositionView

Position details by ID. Returns null if the position does not exist.

quote_order

query quote_order(side: Side, input_amount: Nat, limit_tick: opt Tick, slippage_bps: opt Nat32) → QuoteOrderResult

Simulate an order for UI preview. Does not modify state. Returns pool_swaps and book_order specs passable directly to create_orders or pass_through_trade.

ParamType
sideSide#buy or #sell
input_amountNatInput in native decimals
limit_tickopt TickWorst acceptable price tick (null = no limit)
slippage_bpsopt Nat32Max slippage in basis points (null = no constraint)

Returns

ok: {
input_amount : Nat,
output_amount : Nat,
pool_swaps : vec PoolSwapSpec, // pass to create_orders
book_order : opt BookOrderSpec, // pass to create_orders
venue_breakdown : vec VenueBreakdown, // per-venue input/output/fee
total_fees : Nat,
effective_tick : Tick,
reference_tick : Tick,
}

Queries (Authenticated)

Use the caller's principal for user-specific data. Anonymous callers return null/empty.

get_user

query get_user() → UserData

User account data: orders, positions, triggers, trading/locked balances, fees, and net flow tracking. UserData is opt { ... } — returns null if no account exists. Auth: caller

get_versions

query get_versions() → PollVersions

Version counters for cache invalidation. Primary polling endpoint (~500ms interval). Compare fields to determine which data endpoints need re-fetching. Auth: caller

get_hydration

query get_hydration(interval: ChartInterval, chart_limit: Nat32, levels: Nat32, tick_bucket_size: Nat32) → HydrateResponse

All data for initial page load in a single atomic call. Includes platform data, user data, chart history, and recent trades. Works for both logged-in and anonymous callers. Auth: caller (optional)

get_platform

query get_platform(interval: ChartInterval, levels: Nat32, tick_bucket_size: Nat32) → PlatformData

Platform data fetched conditionally when platform_version changes. Returns price, liquidity, live candle, market depth, and statistics.

get_user_activity

query get_user_activity(cursor: opt ChainCursor, limit: opt Nat32) → GetUserActivityResult

Unified activity history (orders, triggers, LP events, transfers). limit defaults to 20 (max 100). Auth: caller


Deposits & Withdrawals

deposit

deposit(token: TokenSide, amount: Nat) → DepositResult

Deposit tokens to trading balance via ICRC-2 transfer_from. Requires a prior icrc2_approve on the token ledger. Auth: caller

ParamType
tokenTokenSide#base or #quote
amountNatAmount in native decimals

withdraw

withdraw(token: TokenSide, amount: Nat) → WithdrawResult

Withdraw tokens from trading balance to wallet. Deducts before the async transfer; credits back on failure. Auth: caller

ParamType
tokenTokenSide#base or #quote
amountNatAmount in native decimals

Orders

create_orders

create_orders(
cancel_ids : vec OrderId,
book_orders : vec BookOrderSpec,
pool_swaps : vec PoolSwapSpec,
) → CreateOrdersResult

Unified order creation: optional cancels + book orders + pool swaps in a single call. Cancels execute first (freeing slots and balance), then pool swaps, then book orders. Uses pre-deposited trading balance. Auth: caller

ParamType
cancel_idsvec OrderIdOrders to cancel first (frees balance + slots)
book_ordersvec BookOrderSpecLimit orders to place on the book
pool_swapsvec PoolSwapSpecAMM swaps to execute against pool tiers

Returns

ok: {
cancel_results : vec CancelOrderResultItem, // per-cancel { order_id, result }
cancel_summary : BatchSummary, // { succeeded, failed }
swap_results : vec SwapResultItem, // per-swap { index, result: { input_amount, output_amount, fee } }
order_results : vec OrderResultItem, // per-order { index, result: { order_id } }
order_summary : BatchSummary,
available_base : Nat, // updated trading balance
available_quote : Nat,
versions : PollVersions,
}

cancel_orders

cancel_orders(order_ids: vec OrderId) → CancelOrdersResult

Batch cancel by ID. Per-order cancellation — individual failures do not block others. Auth: caller

update_order

update_order(order_id: OrderId, new_tick: Tick, new_input_amount: Nat) → UpdateOrderResult

Update an order's tick and/or input amount. Returns #replaced (new order) or #modified (in-place decrease at same tick, retains queue priority). Delta vs remaining_input is debited/refunded from trading balance. Auth: caller

ParamType
order_idOrderIdOrder to update
new_tickTickNew price tick
new_input_amountNatNew input amount

cancel_all_orders

cancel_all_orders() → CancelAllOrdersResult

Cancel all orders for the caller. Works in degraded mode. Auth: caller


Triggers

create_triggers

create_triggers(
cancel_ids : vec TriggerId,
triggers : vec TriggerSpec,
) → CreateTriggersResult

Unified trigger creation: optional cancels + batch create. Cancels execute first (freeing slots and balance), then creates. Auth: caller

ParamType
cancel_idsvec TriggerIdTriggers to cancel first
triggersvec TriggerSpecTriggers to create

cancel_triggers

cancel_triggers(trigger_ids: vec TriggerId) → CancelTriggersResult

Bulk cancel by ID. Per-trigger cancellation — individual failures do not block others. Auth: caller

cancel_all_triggers

cancel_all_triggers() → CancelAllTriggersResult

Cancel all triggers for the caller. Works in degraded mode. Auth: caller


Liquidity

add_liquidity

add_liquidity(
fee_pips : Nat32,
t_lo : Tick,
t_hi : Tick,
amt_base : Nat,
amt_quote : Nat,
initial_tick : opt Tick,
lock_until_ms : opt Nat64,
amt_base_min : Nat,
amt_quote_min : Nat,
) → LiquidityResult

Add liquidity to a new concentrated position. First LP in a pool must supply initial_tick to set the price. Excess tokens credited to trading balance. Auth: caller

ParamType
fee_pipsNat32Pool tier: 100–10000 in steps of 100
t_lo / t_hiTickLower and upper tick bounds
amt_base / amt_quoteNatDesired amounts in native decimals
initial_tickopt TickRequired for first LP in pool (sets price)
lock_until_msopt Nat64Optional lock expiry (ms since epoch)
amt_base_min / amt_quote_minNatSlippage protection minimums

increase_liquidity

increase_liquidity(
id : PositionId,
amt_base_desired : Nat,
amt_quote_desired : Nat,
amt_base_min : Nat,
amt_quote_min : Nat,
) → IncreaseLiquidityResult

Increase liquidity in an existing position. Excess tokens credited to trading balance. Auth: caller (position owner)

decrease_liquidity

decrease_liquidity(
id : PositionId,
liquidity_delta : Nat,
amt_base_min : Nat,
amt_quote_min : Nat,
) → DecreaseLiquidityResult

Decrease liquidity from an existing position. Full withdrawal auto-collects fees and deletes the position. Partial stores tokens in tokensOwed. Blocked while locked. Auth: caller (position owner)

collect_fees

collect_fees(id: PositionId) → CollectFeesResult

Collect accumulated fees and withdrawn tokens from a position into trading balance. Auth: caller (position owner)

lock_position

lock_position(id: PositionId, lock_until_ms: Nat64) → LockPositionResult

Lock a position until lock_until_ms. One-way ratchet: can only extend, never shorten. Blocks decrease_liquidity and close_all_positions while locked. Auth: caller (position owner)

transfer_position

transfer_position(position_id: PositionId, recipient: Principal) → TransferPositionResult

Transfer ownership to another user. Locked positions are transferable. Accrued fees carry over. Auth: caller (position owner)

close_all_positions

close_all_positions() → CloseAllPositionsResult

Close all positions. Full withdrawal with fees auto-collected. Locked positions skipped. Works in degraded mode. Auth: caller


Pass-Through Trade

pass_through_trade

pass_through_trade(args: PassThroughTradeArgs) → PassThroughTradeResult

Execute a trade directly from wallet using ICRC-2 approval flow. Pulls input via transfer_from, settles output and refund to wallet (or optional recipient). Always executes as a market order. No pre-deposited trading balance required. Auth: caller

Returns

ok: {
swap_results : vec SwapResultItem,
order_results : vec OrderResultItem,
output : TransferLeg, // { amount, block_index, error }
refund : TransferLeg,
versions : PollVersions,
}

Miscellaneous

release_rate_limit

release_rate_limit(target: Principal) → ApiResult<Bool>

Pay to release a rate-limited principal. Costs 11x quote ledger fee via ICRC-2 approval. Auth: caller


Types

Primitives

TypeDefinition
TickInt32Log₁.₀₀₀₁ of price
SqrtPriceX96Nat√price in Q64.96 fixed-point
LiquidityNatPool liquidity units
PositionIdNat64Monotonic position ID
OrderIdNatMonotonic order ID
TriggerIdNatMonotonic trigger ID
Sidevariant { buy; sell }Trade direction
TokenSidevariant { base; quote }Token selector
ChartIntervalvariant { min1; min15; hour1; hour4; day1 }Chart timeframe
SystemStatevariant { normal; degraded; halted }Canister state

BookOrderSpec

{
side : Side,
input_amount : Nat, // input in native decimals
limit_tick : Tick, // price tick
immediate_or_cancel : Bool, // true → unfilled portion cancelled after execution
}

PoolSwapSpec

{
side : Side,
input_amount : Nat, // input in native decimals
limit_tick : Tick, // slippage protection tick limit
fee_pips : Nat32, // pool tier: 100–10000 in steps of 100
}

TriggerSpec

{
side : Side,
trigger_tick : Tick, // activation price
input_amount : Nat, // input in native decimals
limit_tick : Tick, // slippage tolerance for resulting order
immediate_or_cancel : Bool,
reference_tick : Tick, // reference tick at creation
}

PassThroughTradeArgs

{
book_order : opt BookOrderSpec, // optional book order component
pool_swaps : vec PoolSwapSpec, // pool swap components
recipient : opt Principal, // output recipient (null → caller)
}

BatchSummary

{ succeeded : Nat32, failed : Nat32 }

PollVersions

{
platform : Nat, // trades, liquidity changes, price updates
orderbook : Nat, // limit order add/cancel (no match)
candle : Nat, // timer boundary (candle archived)
user : Nat, // user-specific changes (per caller)
}