phasis.
Phasis Docs
Developers

Core concepts

Account model, value encoding, trade intents, and book sides — the fundamentals every Phasis SDK integration must understand.

Account model

Phasis uses a registry-resident account model. There is one account per wallet address, stored as a child object inside the shared AccountRegistry.

Key facts

  • No per-account shared object. The account is embedded in the registry; there is no separate object address to track per user.
  • Lookup by owner. Use findAccountId(client, registryId, ownerAddress) to retrieve the account's object ID from AccountRegistry.account_index.
  • Auth via sender. Move entries resolve the caller's account from ctx.sender() — no capability object to manage.

Account fields

FieldTypeDescription
owneraddressThe controlling wallet address
balance_quoteCoin<Quote>Free USDC (not escrowed by resting bids)
locked_marginu64Total margin lock across all assets (USDC raw, 6 decimals)
lock_by_assetVecMap<u8, u64>Per-asset margin lock breakdown (asset code → USDC raw)
positionsVecMap<ID, Position>Active positions keyed by series ID
pending_by_orderVecMap<PendingKey, PendingOrder>Resting limit orders
quote_lockedu64USDC reserved by resting bids (counted against free balance, not escrowed)
fee_paidu64Cumulative fees paid (analytics)

Free balance (withdrawable)

// All values are USDC raw (6 decimals)
const free = account.balanceQuote - account.lockedMargin - account.quoteLocked;

Use accountFreeQuote(account) from the SDK for this calculation.

Account NAV

  • Cash NAV: account.balanceQuote — resting bids do not escrow principal, so the cash component equals the balance alone.
  • Mark-to-market NAV: requires a fresh StressSnapshot and is computed on-chain via vault_api::account_nav_quote_v2 (devInspect).
  • Total NAV: cash + mark-to-market = value if all positions closed at fair prices.

Value encoding

The protocol uses fixed-point encoding throughout. Getting these scales right is critical — a factor-of-1e9 error is the most common integration bug.

Price — UD30x9

Prices are unsigned 30-integer 9-fractional fixed-point values.

  • Raw type in Move: u128 (newtype UD30x9)
  • Human unit: USDC per contract
  • Raw = human × 1,000,000,000
// Examples
const price_0_001 = 1_000_000n;          // $0.001
const price_0_05  = 50_000_000n;         // $0.05
const price_1_00  = 1_000_000_000n;      // $1.00
const price_100   = 100_000_000_000n;    // $100.00

// Encode for SDK calls
const limitPrice = BigInt(Math.round(humanPrice * 1e9));

// Decode from SDK reads
const humanPrice = Number(rawPrice) / 1e9;

Strike — also UD30x9

Strikes use the same UD30x9 encoding as prices.

// BTC $70,000 strike
const strike = 70_000n * 1_000_000_000n;  // 70_000_000_000_000n

Quantity — 1e6 (contract decimals)

Quantities represent numbers of option contracts. Each contract covers one unit of underlying.

  • Raw type in Move: u64
  • Human unit: number of contracts
  • Raw = human × 1,000,000
// Examples
const qty_1      = 1_000_000n;    // 1 contract
const qty_2_5    = 2_500_000n;    // 2.5 contracts
const qty_100    = 100_000_000n;  // 100 contracts

// Encode
const qty = BigInt(Math.round(humanQty * 1e6));

// Decode
const humanQty = Number(rawQty) / 1e6;

USDC amounts — 6 decimals

USDC deposits and withdrawals use standard 6-decimal encoding (consistent with the USDC coin type).

const deposit_10_usdc  = 10_000_000n;   // 10 USDC
const deposit_100_usdc = 100_000_000n;  // 100 USDC

Margin — USDC 6-decimal (fp9 internal)

Margin locks are stored internally in fp9 (1e9 scale) but exposed at the account level in USDC 6-decimal units. The SDK reader functions return already-converted values at 6-decimal scale.


Trade intents and book sides

The Phasis book is a standard price-time-priority limit order book where BID = buy side and ASK = sell side. Option semantics map onto book sides as follows:

IntentBook sideMeaning
OpenLongBIDBuy to open a long position
CloseShortBIDBuy to close an existing short
OpenShortASKSell to open a short position
CloseLongASKSell to close an existing long

TradeIntent enum

import { TradeIntent } from '@phasis-lab/sdk';

TradeIntent.OpenLong   // 'open_long'
TradeIntent.CloseLong  // 'close_long'
TradeIntent.OpenShort  // 'open_short'
TradeIntent.CloseShort // 'close_short'

intentToSide helper

import { intentToSide, TradeIntent, DeepBookSide } from '@phasis-lab/sdk';

// Convert intent to the u8 book side expected by the Move entry
const side = intentToSide(TradeIntent.OpenLong, null);
// → DeepBookSide.BID (0)

// If the account already has a position, pass its netIsShort field
const side = intentToSide(TradeIntent.CloseLong, position.netIsShort);
// → DeepBookSide.ASK (1)

DeepBookSide constants

import { DeepBookSide } from '@phasis-lab/sdk';

DeepBookSide.BID  // 0 — buy side
DeepBookSide.ASK  // 1 — sell side

OrderType constants

import { OrderType } from '@phasis-lab/sdk';

OrderType.NO_RESTRICTION     // 0 — rest if not immediately matched (default)
OrderType.IMMEDIATE_OR_CANCEL // 1 — fill what's available, cancel remainder
OrderType.FILL_OR_KILL       // 2 — fill entirely or abort
OrderType.POST_ONLY          // 3 — rest only; abort if it would match immediately

Asset codes

Assets are identified by a u8 code in Move and in the SDK:

CodeAsset
0SUI
1BTC
2ETH

Connect a Wallet

No Sui wallet detected in this browser.

Install Sui Wallet

Phasis supports any wallet that implements the Sui Wallet Standard.