API reference
Every public symbol — signatures, parameters, return shapes, gotchas.
@automark/sdk — LLM Reference
This file is structured for AI coding assistants. It catalogues every public symbol with signatures, parameters, return shape, and common gotchas. If you are an LLM assisting a user with this SDK, read this file before writing code that calls the SDK.
---
Package shape
- Name:
@automark/sdk - Peer dep:
@mysten/sui ^1.30.0 - ESM only (
"type": "module") - Subpath exports:
@automark/sdk— barrel (re-exports everything below)@automark/sdk/vault—Vaultclass + creation types@automark/sdk/market—Marketclass (builder-facing wrapper over Oracle)@automark/sdk/oracle—Oracleclass (lower-level Predict vocabulary)@automark/sdk/duration—seconds,minutes,hours,dayshelpers@automark/sdk/math—usdFromRaw,usdToRaw,bigintMin/Max/Clamp,USD_SCALE_RAW@automark/sdk/network—getNetworkConfig, default RPC + predict-server URLs@automark/sdk/permissions— permission bits + helpers@automark/sdk/errors— Move-abort parser + code map@automark/sdk/types—VaultState,MarketKey,RangeKey, etc
Tree-shaking is significantly better via subpath imports.
---
Mental model (read this first)
1. The SDK is a tx builder + a state reader. It never signs and never submits. The caller provides a wallet adapter. 2. All on-chain quantities are bigint. Convert with BigInt(x) from a string or number when in doubt. The SDK serializes to tx.pure.u64() internally. 3. Methods append to a Transaction passed in. They return void. The caller composes PTBs by chaining several method calls on the same tx, then submits once. 4. Vault instances are obtained via Vault.fetch() (async). The constructor is private — the static fetch ensures the instance always carries a real on-chain snapshot. 5. Strikes are scaled 1e9. Quantity is raw (no implicit decimals). Currency quantities are raw (e.g. dUSDC × 1e6). 6. Trade ops (mintBinary/mintRange) call into a strategy template package, not directly into the vault. You need strategyPackageId + strategyModule (the latter defaults to "strategy"). You can derive them from vault.parseStrategyType(). 7. PM custody is a 2-step convention: pmDeposit → mint* in the same PTB; redeem* → pmWithdraw in the closing PTB. Otherwise capital sits idle in the PredictManager and falls out of NAV. 8. Market and Oracle describe the same thing in two vocabularies. Oracle matches the Move/Predict naming. Market is a wrapper with builder-facing strike helpers (strikeNear, strikeAbove, etc.). Pick whichever feels right for your layer — both can drive mintBinary/mintRange.
---
API — Vault class
Construction
Vault.fetch(id, { suiClient }) → Promise<Vault>
Reads the vault on-chain. Captures packageId, shareType, quoteType from the objectType (these never change). All getters reflect the snapshot.
const vault = await Vault.fetch("0xVAULT_ID", { suiClient });Throws if id does not resolve to a Move object or if the type does not match 0x...::vault::Vault<P, Q>.
vault.refresh({ suiClient }) → Promise<void>
Re-reads on-chain state and mutates the instance in place. Use after a tx that touched the vault. Does not re-fetch the type.
---
Read-only getters (post-fetch)
| Getter | Type | Notes | |
|---|---|---|---|
id | string | Vault object ID | |
packageId | string | From the objectType | |
shareType | string | Full ${pkg}::${mod}::${STRUCT} | |
quoteType | string | E.g. dUSDC type | |
rawState | VaultState | The full struct (see @automark/sdk/types) | |
quoteBalance | bigint | Idle quote balance in the vault | |
plpBalance | bigint | PLP supplied balance | |
totalShares | bigint | Outstanding share supply | |
nav | bigint | NAV in quote terms (last snapshot) | |
navPerShare | bigint | NAV / totalShares (last snapshot) | |
aggregateExposure | bigint | Sum of notional across positions | |
highWaterMark | bigint | For performance-fee accounting | |
lastSnapshotTs | bigint | Unix seconds | |
pendingDepositsTotal | bigint | Queued, not yet processed | |
pendingWithdrawalSharesTotal | bigint | Queued, in shares | |
accruedFeesQuote | bigint | Crystallizable balance | |
lastCrystallizationTs | bigint | 24h cooldown anchor | |
predictManagerId | `string \ | null` | Null if vault never minted |
authorizedWitnessType | string | ${pkg}::${mod}::${Struct} of the strategy witness | |
strategyPermissions | bigint | Bitwise OR of PERMISSIONS.* | |
paused | boolean | Vault-wide pause | |
pauseReason | number | u8 from vault.move | |
pauseTs | `bigint \ | null` | When paused, null otherwise |
strategyPaused | boolean | Strategy-specific pause | |
governanceAdmin | string | Address | |
emergencyAdmin | string | Address | |
trackedMarketKeys | MarketKey[] | Open binary positions | |
trackedRangeKeys | RangeKey[] | Open range positions | |
navParams | NavParams | Intervals/cooldowns | |
riskParams | RiskParamsState | Caps (max position bps, exposure, drawdown, share concentration) | |
feeParams | FeeParamsState | Performance/management/entry/exit fees + platform split | |
uniqueOracleIds | string[] | Deduplicated + sorted, derived from tracked_*_keys |
Computed getters (derived — no extra RPC)
| Getter | Type | Notes | ||
|---|---|---|---|---|
isFrozen | boolean | `paused \ | \ | strategyPaused` |
maxSinglePosition | bigint | nav × max_position_bps / 10_000 — cap for one new position | ||
maxAggregateExposure | bigint | nav × max_aggregate_exposure_bps / 10_000 — total exposure cap | ||
exposureHeadroom | bigint | maxAggregateExposure − aggregateExposure, clamped to >= 0n. Size new positions against this | ||
openPositionsCount | number | Count of open positions (binary + range) | ||
canMintBinary / canRedeemBinary / canMintRange / canRedeemRange / canSupplyPlp / canWithdrawPlp / canPmDeposit / canPmWithdraw | boolean | Per-permission convenience checks against strategyPermissions | ||
grantedPermissions | PermissionName[] | Decomposed list of the strategy's permission bits |
---
Tx builders (instance methods)
All take a Transaction as first argument, mutate it in place, return void.
vault.refreshNavSnapshot(tx, refs?) → void
Auto-picks between the simple path (1 moveCall) and the with-positions path (2+N moveCalls).
- No positions → emits
update_nav_snapshot. - Has positions → emits
begin_nav_snapshot+ N×add_oracle_to_snapshot+finalize_nav_snapshot, where N =uniqueOracleIds.length.
vault.refreshNavSnapshot(tx, { predictPackageId, predictObjectId });Throws:
refsmissing while vault has positionspredict_manager_idnull whiletracked_keysnon-empty (inconsistent state)- More than 10 unique oracles (split into multiple PTBs)
vault.updateNavSnapshot(tx) → void
Direct shortcut to update_nav_snapshot. Will abort on-chain with E_INVALID_PARAM if the vault has positions. Prefer refreshNavSnapshot unless you know there are none.
vault.crystallizeFees(tx, opts?) → void
Adds crystallize_fees (and optionally a NAV refresh beforehand). Permissionless.
opts.includeNavRefresh(defaulttrue) prependsrefreshNavSnapshot.opts.refsrequired if the vault has positions ANDincludeNavRefreshis true.
vault.crystallizeFees(tx, { refs: { predictPackageId, predictObjectId } });On-chain cooldown: 24h between crystallizations. Aborts with E_TOO_EARLY if called sooner.
vault.mintBinary(tx, params) → void
Calls ${strategyPackageId}::${strategyModule}::mint_binary. Defaults strategyModule to "strategy".
vault.mintBinary(tx, {
strategyPackageId, strategyModule: "strategy",
predictPackageId, predictObjectId, oracleId,
strike: 60_000_000_000n, // raw, 1e9 scale
isUp: true, // "closes above"
quantity: 100_000_000n, // raw contracts
});Throws: vault has no predict_manager_id.
Common on-chain failures (use parseMoveAbort):
E_POSITION_TOO_LARGE— exceedsmax_position_bps × NAVE_EXPOSURE_LIMIT_EXCEEDED— aggregate exposure capE_VAULT_PAUSED/E_STRATEGY_PAUSEDE_INSUFFICIENT_PERMISSIONS— strategy doesn't haveMINT_BINARYbitE_WRONG_PREDICT_MANAGER—predict_manager_idmismatch
vault.mintRange(tx, params) → void
Same shape as mintBinary but with lowerStrike + higherStrike instead of strike + isUp.
Throws additionally: higherStrike <= lowerStrike.
vault.pmDeposit(tx, params) → void
Moves quote from vault → PredictManager.balance. Call before mintBinary/mintRange in the same PTB.
vault.pmDeposit(tx, { strategyPackageId, amount: 500_000_000n });vault.pmWithdraw(tx, params) → void
Inverse of pmDeposit. Call after redeem* to bring proceeds back to the vault.
vault.parseStrategyType() → { packageId, module }
Parses authorizedWitnessType (format ${pkg}::${module}::${struct}) to derive the strategy package + module. Saves you from hardcoding.
Throws: format doesn't have exactly 3 ::-separated parts.
---
Static helpers (Vault.* — no instance needed)
These build Transaction objects from scratch — the creation flow is sequential, each tx signed independently.
Vault.publishShareTokenTx({ modules, dependencies, sender }) → Transaction
Publishes the share-token Move package. After execution, call Vault.parsePublishedShareToken(res, moduleName, structName) on the response.
Vault.parsePublishedShareToken(res, moduleName, structName) → PublishedShareToken
Returns { sharePackageId, shareType, treasuryCapId, currencyReceivingId }.
Throws on missing package, missing TreasuryCap, or missing Currency receiving object.
Vault.publishStrategyTx({ modules, dependencies, sender }) → Transaction
Publishes the strategy template package. After execution, call Vault.parsePublishedStrategy(res, moduleName, structName).
Vault.parsePublishedStrategy(res, moduleName, structName) → PublishedStrategy
Returns { strategyPackageId, witnessType }. witnessType is ready to pass into Vault.create.
Vault.finalizeShareRegistrationTx(params) → Transaction
Promotes Currency<P> to a shared object via 0x2::coin_registry::finalize_registration. Requires currencyReceivingVersion + currencyReceivingDigest (TTO receiving ref).
Vault.create(params) → Transaction
Atomic PTB: predict::create_manager + vault::create_vault. See CreateVaultParams interface for the full param shape.
After execution, use Vault.parseCreatedVault(res) (recommended) or Vault.parseCreatedVaultId(res).
Vault.crystallizeFeesTx({ sender, vaultPackageId, shareType, quoteType, vaultId, includeNavRefresh? }) → Transaction
Standalone-tx version of crystallizeFees (when you don't want to bother fetching the Vault first). includeNavRefresh (default true) prepends update_nav_snapshot — only safe for vaults without positions; pass false and refresh NAV separately for vaults with positions.
Vault.parseCrystallizedFees(res) → { totalQuote, platformShare, creatorShare } | null
Returns the FeesCrystallized event data, or null when the event was not emitted (e.g. cooldown still active).
Vault.parseCreatedVaultId(res) → string | null
Quick way to grab the vault ID. Returns null on no match.
Vault.parseCreatedVault(res) → { vaultId, vaultPackageId, predictManagerId, strategyPackageId, strategyModuleName, shareType } | null
Full breakdown — combines objectChanges (vault + package) with the VaultCreated event (predict manager + witness type, with strategy package/module inferred). strategyPackageId/strategyModuleName are null when the witness lives in the vault's own module.
Returns null on unexpected shape.
---
API — @automark/sdk/market
Market is the builder-facing wrapper over Oracle. Same underlying object, vocabulary tuned for strategy authors who think in markets/strikes/forwards rather than Predict object IDs.
Static constructors
Market.find(opts: MarketFindOpts) → Promise<Market>
Find a single market by asset + expiry filter. Throws if no candidate matches.
const btc = await Market.find({
asset: "BTC",
expiryAfterMs: Date.now() + 5 * 60 * 1000,
client: suiClient,
});MarketFindOpts extends OracleFindOpts and adds client?: SuiClient + predictPackageId?: string — both optional, but client is needed if you plan to call .price() later. Store it on the Market via find/list/byId so .price() can reuse it.
Market.list(opts?: MarketListOpts) → Promise<Market[]>
List all active markets, optionally filtered by asset. Sorted ascending by expiry.
Market.byId(id, opts?: MarketByIdOpts) → Promise<Market | null>
Look up by oracle id. Returns null if not found in the active set.
Instance properties (readonly)
| Property | Type | Notes | |
|---|---|---|---|
id | string | Oracle object ID — pass directly to mintBinary/mintRange | |
asset | string | E.g. "BTC", "ETH" | |
expiresAtMs | number | Unix ms epoch | |
minStrike | bigint | Lowest valid strike on this market's grid | |
tickSize | bigint | Spacing between adjacent strikes | |
status | string | "active" while open, "settled" after settle | |
activatedAtMs | `number \ | null` | When it transitioned from pending to active |
maxStrike | bigint | minStrike + tickSize × 100_000 (computed getter) |
Instance methods
market.price(opts?: MarketPriceOpts) → Promise<MarketPrice>
Live spot / forward / SVI sigma via on-chain DevInspect. ~200-400ms typical, gasless. Requires a SuiClient (passed at find/list/byId time, or via opts.client).
const p = await btc.price();
// MarketPrice: { spotUsd, forwardUsd, spotRaw, forwardRaw, sviSigmaRaw, atMs }market.strikeNear(target: bigint | number) → bigint
Snap a target price to the nearest strike on this market's grid. Accepts USD (67_500) or raw u64 (67_500_000_000_000n). Clamps to [minStrike, maxStrike].
market.strikeAbove(reference, { pctBps }) → bigint
Strike at reference × (1 + pctBps/10_000), snapped to grid. pctBps in basis points (300 = 3%).
market.strikeBelow(reference, { pctBps }) → bigint
Strike at reference × (1 − pctBps/10_000), snapped to grid.
market.strikeAtSigma(snap, { k, direction, atMs? }) → bigint
Strike at forward ± k × σ × √T, snapped to grid. snap has forwardRaw + sviSigmaRaw (from price()). Falls back to ATM when T ≤ 0 or σ = 0. atMs defaults to Date.now(); pass explicitly in plugin ticks for deterministic logic.
const p = await btc.price();
const upper = btc.strikeAtSigma(p, { k: 1, direction: "up", atMs: ctx.now });
const lower = btc.strikeAtSigma(p, { k: 1, direction: "down", atMs: ctx.now });---
API — @automark/sdk/oracle
Oracle is the lower-level wrapper using Predict/Move vocabulary. Use it when you want oracle-level concepts (status, activation, settlement) without the strike-helper sugar. Internally, Market delegates to Oracle.
Static methods
Oracle.listActive(opts?: OracleListOpts) → Promise<OracleSummary[]>
All oracles with status === "active", optionally filtered by asset + time. Sorted by expiry ascending.
const opts: OracleListOpts = {
asset: "BTC", // case-insensitive
expiryAfterMs: Date.now() + 5 * 60 * 1000, // optional floor
expiringWithinMs: 7 * 24 * 3600 * 1000, // optional ceiling (mutex w/ expiringBetweenMs)
expiringBetweenMs: [from, to], // optional absolute range (mutex w/ expiringWithinMs)
network: "testnet", // default; resolves predictServerUrl
predictServerUrl: "https://...", // override
signal: ctrl.signal, // optional AbortSignal
};Throws on invalid filter combinations (both expiringWithinMs + expiringBetweenMs, expiringWithinMs ≤ 0, expiringBetweenMs[0] >= expiringBetweenMs[1]).
Oracle.findActive(opts: OracleFindOpts) → Promise<OracleSummary>
Single oracle by asset + filters. Throws if no candidate matches.
OracleFindOpts extends OracleListOpts and adds pick?: "nearest" | "furthest" (default "nearest").
Oracle.getById(id: string, opts?: OracleFetchBase) → Promise<OracleSummary | null>
Look up by oracle ID (case-insensitive). Returns null if not in the active set.
Oracle.getSnapshot(opts: OracleSnapshotOpts) → Promise<OracleSnapshot>
Live spot / forward / SVI sigma via on-chain DevInspect. Requires id + client + predictPackageId (or network).
Types
interface OracleSummary {
id: string;
predictId: string;
asset: string;
expiresAtMs: number;
status: "active" | "settled" | string;
activatedAtMs: number | null;
minStrike: bigint;
tickSize: bigint;
}
interface OracleSnapshot {
id: string;
spotUsd: number; // 4-decimal display
forwardUsd: number; // SVI center
spotRaw: bigint; // u64 scale 1e9
forwardRaw: bigint;
sviSigmaRaw: bigint; // u64 scale 1e9; for sigma × sqrt(T) math
atMs: number;
}---
API — @automark/sdk/duration
export function seconds(n: number): number; // n * 1_000
export function minutes(n: number): number; // n * 60_000
export function hours(n: number): number; // n * 3_600_000
export function days(n: number): number; // n * 86_400_000Plain ms math, but reads as intent. Accepts fractions (seconds(0.5) === 500).
Common use:
await Market.list({ asset: "BTC", expiringWithinMs: days(7), client });
await ctx.state.setWithTTL("ban", 1, hours(2));---
API — @automark/sdk/math
export const USD_SCALE_RAW = 1_000_000_000n; // 1 USD in u64 scale
export function bigintMin(a: bigint, b: bigint): bigint;
export function bigintMax(a: bigint, b: bigint): bigint;
export function bigintClamp(value: bigint, min: bigint, max: bigint): bigint; // throws if min > max
export function usdFromRaw(raw: bigint): number; // 4-decimal precision; for display only
export function usdToRaw(usd: number): bigint; // safe for ≤9 fractional digitsbigintClamp throws on min > max instead of silently swapping or returning — a swapped pair is almost always a bug.
usdFromRaw is for display: round-tripping usdFromRaw → usdToRaw will lose precision past 4 decimals.
---
API — @automark/sdk/network
export type SuiNetwork = "testnet" | "mainnet" | "devnet";
export interface NetworkConfig {
vaultPackageId: string;
predictPackageId: string;
predictObjectId: string;
quoteType: string; // e.g. dUSDC type on testnet
platformTreasury: string;
}
export const NETWORK_CONFIG: Record<SuiNetwork, NetworkConfig | null>;
export const DEFAULT_RPC_URLS: Record<SuiNetwork, string>;
export const DEFAULT_PREDICT_SERVER_URLS: Record<SuiNetwork, string | null>;
export function getNetworkConfig(network: SuiNetwork): NetworkConfig; // throws if not configured
export function getDefaultRpcUrl(network: SuiNetwork): string;
export function getDefaultPredictServerUrl(network: SuiNetwork): string; // throws if not published upstreamTestnet is fully configured today. Mainnet/devnet entries return null from NETWORK_CONFIG and throw from getNetworkConfig until published.
Usage:
import { getNetworkConfig } from "@automark/sdk/network";
const cfg = getNetworkConfig("testnet");
// cfg.predictPackageId, cfg.predictObjectId, cfg.quoteType, ...---
API — @automark/sdk/permissions
export const PERMISSIONS = {
MINT_BINARY: 1 << 0, // 1
REDEEM_BINARY: 1 << 1, // 2
MINT_RANGE: 1 << 2, // 4
REDEEM_RANGE: 1 << 3, // 8
SUPPLY_PLP: 1 << 4, // 16
WITHDRAW_PLP: 1 << 5, // 32
PM_DEPOSIT: 1 << 6, // 64
PM_WITHDRAW: 1 << 7, // 128
} as const;
export const PERMISSIONS_WHITELIST = 255; // bits 0-7
hasPermission(perms: number | bigint, perm: PermissionBit): boolean
combinePermissions(...perms: PermissionBit[]): number
decomposePermissions(perms: number | bigint): PermissionName[]Accepts bigint (the on-chain representation) and number interchangeably. decomposePermissions ignores unknown bits defensively (e.g. bit 8+).
---
API — @automark/sdk/errors
parseMoveAbort(err: unknown): { code: number; name: VaultErrorName | null; raw: string } | null
parseMoveAbortCode(message: string): number | null
getErrorName(code: number): VaultErrorName | null
export const VAULT_ERROR_CODES = {
E_VAULT_PAUSED: 1, E_STRATEGY_PAUSED: 2, E_UNAUTHORIZED: 3,
E_NOT_OPERATOR: 4, E_ZERO_DEPOSIT: 5, E_ZERO_SHARES: 6,
E_INSUFFICIENT_SHARES: 7, E_SNAPSHOT_TOO_EARLY: 8, E_SNAPSHOT_STALE: 9,
E_TOO_EARLY: 10, E_UPGRADE_ALREADY_PENDING: 11,
E_UPGRADE_TIMELOCK_NOT_ELAPSED: 12, E_NO_UPGRADE_PENDING: 13,
E_INVALID_PARAM: 14, E_PARAM_CHANGE_NOT_ALLOWED: 15, E_ADMIN_CONFLICT: 16,
E_LIQUIDATION_INSUFFICIENT: 17, E_WRONG_PREDICT_MANAGER: 18,
E_WRONG_ORACLE: 19, E_POSITION_TOO_LARGE: 20,
E_EXPOSURE_LIMIT_EXCEEDED: 21, E_MAX_POSITIONS_EXCEEDED: 22,
E_INSUFFICIENT_PERMISSIONS: 23, E_SHARE_DECIMALS_NOT_6: 24,
E_SHARE_SYMBOL_EMPTY: 25, E_SHARE_CURRENCY_NO_TREASURY: 26,
E_SHARE_CURRENCY_MISMATCH: 27, E_WRONG_WITNESS: 30,
};parseMoveAbort returns null for non-MoveAbort errors (network, user reject, RPC). The app handles those separately.
Usage pattern:
try {
await wallet.signAndExecuteTransaction({ transaction: tx });
} catch (err) {
const info = parseMoveAbort(err);
if (!info) throw err; // not a Move abort — bubble up
if (info.name === "E_SNAPSHOT_TOO_EARLY") return "wait before retrying";
// ...
}---
API — @automark/sdk/types
export interface VaultState {
quote_balance: bigint;
plp_balance: bigint;
total_shares: bigint;
nav: bigint;
nav_per_share: bigint;
aggregate_exposure: bigint;
high_water_mark: bigint;
last_snapshot_ts: bigint;
pending_deposits_total: bigint;
pending_withdrawal_shares_total: bigint;
accrued_fees_quote: bigint;
last_crystallization_ts: bigint;
predict_manager_id: string | null;
authorized_witness_type: string;
strategy_permissions: bigint;
paused: boolean;
pause_reason: number;
pause_ts: bigint | null;
strategy_paused: boolean;
governance_admin: string;
emergency_admin: string;
tracked_market_keys: MarketKey[];
tracked_range_keys: RangeKey[];
nav_params: NavParams;
risk_params: RiskParamsState;
fee_params: FeeParamsState;
raw_fields: unknown;
}
export interface MarketKey {
oracle_id: string;
expiry: bigint;
strike: bigint;
direction: number; // 0=UP, 1=DOWN
is_up: boolean;
}
export interface RangeKey {
oracle_id: string;
expiry: bigint;
lower_strike: bigint;
higher_strike: bigint;
}
export interface NavParams {
snapshot_interval_seconds: bigint;
deposit_cooldown_seconds: bigint;
withdrawal_cooldown_seconds: bigint;
}
// On-chain state caps (set at construction, mutable via governance upgrade).
export interface RiskParamsState {
max_position_bps: bigint;
max_aggregate_exposure_bps: bigint;
max_drawdown_bps: bigint;
max_share_concentration_bps: bigint;
}
export interface FeeParamsState {
performance_fee_bps: bigint;
management_fee_bps_annual: bigint;
entry_fee_bps: bigint;
exit_fee_bps: bigint;
platform_split_bps: bigint;
}
export interface PMPositionSummary {
oracle_id: string;
strike: bigint;
is_up: boolean;
minted_quantity: bigint;
redeemed_quantity: bigint;
open_quantity: bigint;
total_cost: bigint;
total_payout: bigint;
realized_pnl: bigint;
status: string;
}
export interface OracleState {
is_settled: boolean;
settlement_price: bigint | null;
expiry: bigint;
}
// SDK input shapes (camelCase variants used at Vault.create time)
export interface RiskParams {
maxPositionBps: number;
maxAggregateExposureBps: number;
maxDrawdownBps: number;
maxShareConcentrationBps: number;
}
export interface FeeParams {
performanceFeeBps: number;
managementFeeBpsAnnual: number;
entryFeeBps: number;
exitFeeBps: number;
platformSplitBps: number;
}
export interface NavParamsInput {
snapshotIntervalSeconds: number;
depositCooldownSeconds: number;
withdrawalCooldownSeconds: number;
}---
Common patterns
Atomic mint with auto-funded PM
const vault = await Vault.fetch(vaultId, { suiClient });
const { packageId, module } = vault.parseStrategyType();
const tx = new Transaction();
vault.pmDeposit(tx, { strategyPackageId: packageId, strategyModule: module, amount });
vault.mintBinary(tx, {
strategyPackageId: packageId, strategyModule: module,
predictPackageId, predictObjectId, oracleId,
strike, isUp: true, quantity,
});
await wallet.signAndExecuteTransaction({ transaction: tx });
await vault.refresh({ suiClient }); // sync state for next readDiscover market + size strike by sigma
import { Market, days } from "@automark/sdk";
const btc = await Market.find({
asset: "BTC",
expiringWithinMs: days(7),
client: suiClient,
});
const p = await btc.price();
const upper = btc.strikeAtSigma(p, { k: 1, direction: "up", atMs: Date.now() });
// upper is now snapped to the on-chain grid and ready for mintBinaryMulti-oracle NAV refresh with cap awareness
const vault = await Vault.fetch(vaultId, { suiClient });
const oracles = vault.uniqueOracleIds;
if (oracles.length > 10) {
// Split into chunks of ≤10. Two PTBs, each calling refreshNavSnapshot
// on a Vault instance with a tracked_keys subset would require splitting
// upstream — currently the SDK throws above 10 to force this decision.
throw new Error("Too many oracles for a single refresh; split upstream");
}
const tx = new Transaction();
vault.refreshNavSnapshot(tx, { predictPackageId, predictObjectId });
await wallet.signAndExecuteTransaction({ transaction: tx });Display vault with permission decomposition
import { Vault, decomposePermissions } from "@automark/sdk";
const vault = await Vault.fetch(vaultId, { suiClient });
const perms = decomposePermissions(vault.strategyPermissions);
// → ["MINT_BINARY", "REDEEM_BINARY", "PM_DEPOSIT", "PM_WITHDRAW"]
return {
name: vault.authorizedWitnessType,
navPerShare: Number(vault.navPerShare) / 1e9,
totalShares: Number(vault.totalShares) / 1e6,
permissions: perms,
paused: vault.isFrozen,
};---
Things the SDK does NOT do (today)
- No LP-facing builders yet (
requestDeposit,requestWithdrawal, cancels, process_*). Use rawtx.moveCallagainstvault::request_depositetc until they ship. - No separate
Strategyclass. Operator-facing trade ops (mintBinary/mintRange/pmDeposit/pmWithdraw) live as instance methods onVault. - No
replace_strategy/ governance helpers. - No React hooks. Wrap
Vault.fetchin your ownuseQuery/useEffect. - No keeper scheduler. Use
vault.rawState+ your own scheduler to driveprocess_pending_*. - No tx signing. Pass the
Transactionto a wallet adapter (@mysten/dapp-kit, Suiet, Slush, etc). - No batch reads.
Vault.fetchManyis on the roadmap — for now,Promise.all([fetch(a), fetch(b), ...]).
---
When the user asks for X, suggest Y
| Asks for | Suggest |
|---|---|
| "Show me vault TVL / shares / pause" | Vault.fetch + getters (nav, totalShares, paused) |
| "Find a BTC market expiring next week" | Market.find({ asset: "BTC", expiringWithinMs: days(7), client }) |
| "Get live spot/forward of a market" | await market.price() (needs client passed earlier or here) |
| "Sane strike, x% above forward" | market.strikeAbove(p.forwardRaw, { pctBps: 300 }) |
| "Sane strike, k-sigma away" | market.strikeAtSigma(p, { k: 1, direction: "up", atMs: ctx.now }) |
| "Place a trade" | Vault.fetch + Market.find + pmDeposit + mintBinary/mintRange in one PTB |
| "Settle accumulated fees" | vault.crystallizeFees(tx, { refs }) or Vault.crystallizeFeesTx(...) for a standalone tx |
| "Refresh NAV" | vault.refreshNavSnapshot(tx, { refs }) — auto-handles both paths |
| "Deploy a new vault" | Sequence: publishShareTokenTx → finalizeShareRegistrationTx → publishStrategyTx (if separate) → create |
| "Parse this tx error" | parseMoveAbort(err) — returns { code, name, raw } or null |
| "Check whether the strategy can do X" | hasPermission(vault.strategyPermissions, PERMISSIONS.X) |
| "Show oracle dependencies for NAV refresh" | vault.uniqueOracleIds |
| "Convert raw u64 strike to USD for display" | usdFromRaw(strikeRaw) |
| "Get the testnet predict-server URL" | getDefaultPredictServerUrl("testnet") |