Documentation Enter app
Developer documentation

Build on the verifiable allocation layer.

@floe/sdk is how you read Floe vaults, prove a NAV with hardware attestation, compose across Sui yield venues, lend against the proven floor, and deploy your own vault — without touching the Move contracts.

pnpm add @floe/sdk @mysten/sui
Overview · Architecture

How Floe fits together.

Strategy logic runs off-chain under on-chain policy the contract enforces — plus attestation proving the executor was the registered code. NAV = idle + Σ VenueModule.value() + settled value. The enclave signs that figure; the contract verifies the signature before it accepts the number.
DepositorCuratorAgentDeveloper
@floe/sdkTypeScript surface · reads · transactions · deploy
floe core · Vault<Q,S>
custody · shares · NAV · policy & fees · circuit breaker · async redeem · agent caps
Walrus · audit Seal · privacy
VenueModule

One uniform interface — NAV = idle + Σ value()

DeepBook PredictCetus CLMM
the moat
floe_nav

Verifiable Valuation primitive — verifies a signature on-chain before accepting a figure

floe_lend

Attested-collateral money market — borrow against the proven floor

signs NAV · Vol · Collateral · Risk ↑
Nautilus enclave

AWS Nitro TEE · reproducible PCR measurement · registered on-chain

  • One uniform interface. The allocator vault speaks only VenueModule — it never knows which protocol a module wraps.
  • One attestation primitive. floe_nav verifies a TEE signature natively on-chain — structurally impossible on EVM/Solana.
  • One warm enclave attests every vault via a keeper loop; if it lags, the circuit breaker degrades vaults safely to floor-based withdrawals.
Overview · Core concepts

The six ideas everything builds on.

The proven floor

nav_lower_bound = idle + PLP×price + settled. A redeemable floor a curator can never inflate — withdrawals fall back to it, never below.

Circuit breaker

nav_is_safe gates on freshness + divergence. Deposits fail closed when unsafe; withdrawals degrade to the floor and emit NavGuardTripped.

Intent separation

Every signed value carries an intent — NAV=1, Vol=2, Collateral=3, Risk=4 — so a signature for one can never be replayed as another.

Caps & roles

OwnerCap, CuratorCap, ExecCap (with an attenuated Mandate) and a GuardianCap kill-switch. Authority is explicit and revocable on-chain.

Strata

A vault allocates across enabled strata — PLP base yield, a vertical RANGE ladder, and a delta HEDGE — each a bit flag enforced by policy.

Async redeem

ERC-7540-style: request_redeem fixes the liability at safe NAV, fulfill_redeems pays FIFO from idle, claim_redeem settles. Sync withdraw stays instant when idle covers it.

SDK · Quickstart

Connect and read a live vault.

Everything is typed. The client points at testnet by default; pass a signer only when you write.
setup.tsts
import { FloeClient, FloeVault } from "@floe/sdk";

const floe = new FloeClient({ network: "testnet" });

const v = await FloeVault.getVaultState(floe, vaultId);
v.nav;          // total assets (6dp)
v.sharePrice;   // NAV / supply (6dp)
v.navLowerBound;// the proven, redeemable floor
v.attested;     // on the hardware-attested NAV tier?
SDK · Reading vaults

One read, the whole truth.

getVaultState returns a rich, settlement-aware snapshot — not just a NAV, but exactly how certain that NAV is. navSafetyLabel drives the proof badge across the app.
state.tsts
const v = await FloeVault.getVaultState(floe, vaultId);

v.nav; v.navLowerBound; v.pctCertain;   // 0–100 % certain
v.settledTotal; v.unsettledMarks;        // certain vs soft marks
v.navSafe; v.navFresh; v.navWithinDivergence;
v.navSafetyLabel;
//  "verified" | "unattested"
//  | "degraded-stale" | "degraded-divergent"
v.plpHeld; v.plpPrice; v.idle; v.shareSupply;
v.managementFeeBps; v.performanceFeeBps;
directory.tsts
import { Registry } from "@floe/sdk";

// browse the Earn directory
const vaults = await Registry.listVaults(floe);

for (const v of vaults) {
  console.log(v.name, v.curator, v.nav, v.venues);
}
SDK · Verifiable NAV

The moat — what no other vault has.

A value is signed inside a registered AWS Nitro enclave; Floe verifies that signature on-chainbefore accepting it. The same primitive proves NAV, volatility, collateral, and risk.
attestation.tsts
import { Attestation } from "@floe/sdk";

const info = Attestation.enclaveInfo(floe);          // Enclave id + PCR0 + packages
const live = await Attestation.isEnclaveLive(floe);  // moat health check → true

// verify an enclave-signed NAV on-chain — resolves on success, throws if it can't
await Attestation.verifyNav(floe, { nav, plpPrice, vaultId, timestampMs, signatureHex });

// the same primitive, four proven intents:
await Attestation.verifyVolAttested(floe, payload);  // intent 2
await Attestation.verifyCollateral(floe, payload);   // intent 3 → powers Floe Lend
await Attestation.verifyRiskAttested(floe, payload); // intent 4
SDK · Volatility index

On-chain implied volatility.

Vol.volNow computes ATM implied vol entirely on-chain from DeepBook Predict's Block Scholes SVI oracle — synchronously composable by any protocol.
vol.tsts
import { Vol } from "@floe/sdk";

const bps = await Vol.volNow(floe);     // live BTC ATM implied vol, on-chain compute
Vol.bpsToPercent(bps);                  // e.g. 51.32
const snap = await Vol.currentVol(floe);// last on-chain snapshot { volBps, samples }
const att = await Vol.attestedVol(floe);// the enclave-signed vol tier
SDK · Venues

One interface, many protocols.

Every venue implements the same VenueModuledeploy / value / redeem. The vault sums value() across venues; that sum is what the enclave attests. Two live on testnet today (DeepBook Predict + Cetus CLMM); the interface drives more.
venues.tsts
import { DeepBookModule, CetusModule, type VenueModule } from "@floe/sdk";

// the live reference venue (DeepBook Predict — manager position)
const a = await DeepBookModule.value(floe, vaultId);  // → { venue, valueRaw, parts }

// Cetus CLMM (NFT position) implements the SAME interface
const b = await CetusModule.value(floe, vaultId);

// NAV = idle + Σ module.value(vaultId) across every venue the vault holds
SDK · Floe Lend

The market that removed the oracle.

Collateral is valued at the enclave-signed floor (CollateralPayload, intent 3) — so a borrower can't forge what their shares are worth. Zero contract deps; any attested vault's SHARE can be collateral.
lend.tsts
import { FloeLend } from "@floe/sdk";

const pool = await FloeLend.poolState(floe, poolId);   // liquidity, utilization, LTV, liqThreshold

await FloeLend.supply(floe, { poolId, amount });        // provide dUSDC liquidity

// fetch a fresh signed valuation, then lock collateral + borrow against the proven floor
const sig = await FloeLend.fetchSignedValuation(floe, { vaultId });
await FloeLend.lockAndBorrow(floe, { poolId, collateral, borrow, valuation: sig });

await FloeLend.repay(floe, { poolId, amount });
SDK · Walrus & Seal

Auditable history. Private alpha.

Every rebalance is written to Walrus as a tamper-evident blob and indexed on-chain; curator strategy parameters are Seal-encrypted and decryptable only by the holder of the matching capability.
walrus.tsts
import { Walrus } from "@floe/sdk";

await Walrus.storeSnapshot(floe, snapshot);      // tamper-evident blob
const ids = await Walrus.listBlobIds(floe, vaultId);
const hist = await Walrus.reconstructHistory(floe, vaultId);
seal.tsts
import { Seal } from "@floe/sdk";

const blob = await Seal.encryptStrategy(floe, params);
await Seal.setStrategyBlob(floe, { vaultId, blob });
const params2 = await Seal.decryptStrategyAsCurator(floe, vaultId);
SDK · Agents & authority

Delegate execution, keep the kill-switch.

A curator mints an attenuated ExecCap with a Mandate (expiry + cycle budget). Revocation is a dynamic field, so it's upgrade-safe and instant — and a GuardianCap can veto an agent or halt the vault.
agents.tsts
import { Agent } from "@floe/sdk";

const cap = await Agent.authorizeAgent(floe, { vaultId, agent, expiryMs, maxCycles });
const agents = await Agent.listAgents(floe);   // [{ agent, active, expiryMs, … }]
await Agent.revokeAgent(floe, { vaultId, agentCapId });   // instant kill-switch
Build · Deploy a vault

Deploy your own vault.

deploy() encodes policy + fees for you. Fee caps (3% mgmt / 20% perf) and the enabled strata are enforced on-chain. The vault lists in the directory under your name with provable NAV by default.
deploy-vault.tsts
import { FloeClient, FloeVault, Policy } from "@floe/sdk";

const floe = new FloeClient({ network: "testnet", signer });

const v = await FloeVault.deploy(floe, {
  asset: "…::dusdc::DUSDC",
  name: "My Vault",
  symbol: "MYV",
  policy: {
    maxPositionSize: 1_000_000_000n,
    maxLeverageBps: 30_000,
    enabledStrata: Policy.Stratum.PLP | Policy.Stratum.RANGE | Policy.Stratum.HEDGE,
    plpFloorBps: 5_000,
  },
  fees: { managementBps: 100, performanceBps: 1_500 },
});
// → { vaultId, shareType, … } now live, sourcing third-party capital
Prefer no code? The in-app deploy flow walks you through the same curator path with a guided form.
Deploy
Build · Primer

hello_vault — feel the cycle first.

Before the real engine, a throwaway single-asset Move vault: take a deposit, mint a share receipt, allow 1:1 withdrawal. No strategy, no NAV math — just the publish → call → read loop on testnet.
hello_vault.movemove
module hello_vault::hello_vault;

use sui::balance::{Self, Balance};
use sui::coin::{Self, Coin};
use sui::sui::SUI;

/// The shared vault. Anyone deposits; a matching VaultShare withdraws.
public struct Vault has key { id: UID, pool: Balance<SUI> }
public struct VaultShare has key, store { id: UID, amount: u64 }

/// Deposit SUI → mint a VaultShare receipt to the sender.
public fun deposit(vault: &mut Vault, payment: Coin<SUI>, ctx: &mut TxContext): VaultShare {
    let amount = payment.value();
    vault.pool.join(payment.into_balance());
    VaultShare { id: object::new(ctx), amount }
}

/// Surrender a VaultShare → withdraw the recorded amount of SUI.
public fun withdraw(vault: &mut Vault, share: VaultShare, ctx: &mut TxContext): Coin<SUI> {
    let VaultShare { id, amount } = share;
    object::delete(id);
    coin::take(&mut vault.pool, amount, ctx)
}
Build · API reference

One primitive, every namespace.

Each Floe product is a consumer of the same verifiable-valuation core — and a namespace in the SDK.
FloeVault

Vault reads, the rich VaultState, redemption, settlement, and curator deploy.

getVaultState()deploy()requestRedeem()fulfillRedeems()claimRedeem()settlePosition()
Registry

The Earn directory — every live vault, curator, TVL, venues, strategy.

listVaults()
Vol

On-chain implied-volatility index from the Predict SVI oracle.

volNow()currentVol()attestedVol()updateVolIndex()
Attestation

The Nautilus moat — verify enclave-signed values on-chain.

enclaveInfo()isEnclaveLive()verifyNav()verifyVolAttested()verifyCollateral()verifyRiskAttested()
FloeLend

Attested-collateral money market — borrow against the proven floor.

poolState()supply()lockAndBorrow()repay()liquidate()fetchSignedValuation()borrowAndTradePredict()
Walrus

Tamper-evident audit trail — NAV/rebalance snapshots, indexed on-chain.

storeSnapshot()readSnapshot()listBlobIds()reconstructHistory()
Seal

Strategy-parameter privacy — encrypted config, capability-gated decryption.

encryptStrategy()setStrategyBlob()getStrategyBlob()decryptStrategyAsCurator()
Agent

Attenuated, revocable agent authority over a vault.

authorizeAgent()revokeAgent()listAgents()consumeMandateCycle()
TrackRecord

Verifiable performance — APR/drawdown from attested snapshots.

computeTrackRecord()verifyTrackRecord()
Venues

The multi-venue spine — DeepBookModule & CetusModule implement one interface.

DeepBookModule.valueCetusModule.valueVenueModule()
Share / Policy / Fees

Per-vault share codegen and on-chain-enforced policy + fee encoders.

generateShareModule()Policy.StratumencodePolicy()encodeFees()
Treasury

Protocol revenue accounting.

getProtocolRevenue()
Reference · Browser vs Node

Three import targets.

The barrel pulls Node-only publish code, so the frontend imports @floe/sdk/browser — reads plus dapp-kit transaction builders, no deploy/publish.
imports.tsts
import { FloeClient, FloeVault } from "@floe/sdk";        // Node: everything
import { deploy } from "@floe/sdk/node";                   // Node: deploy, scripts, keeper
import {
  getVaultState, listVaults, buildDepositTx, buildWithdrawTx, FLOE_ADDRESSES,
} from "@floe/sdk/browser";                                // browser-safe surface only

// tx builders return a Transaction for dapp-kit's useSignAndExecuteTransaction
const tx = buildDepositTx({ vaultId, qType, sType, sender, paymentCoinId, amount });
Reference · Addresses & tour

Canonical ids, and a live tour.

Every on-chain id lives in FLOE_ADDRESSES.testnet — the runtime source of truth. Never hardcode.
addresses.tsts
import { FLOE_ADDRESSES, FLOE_VENUES, FLOE_ASSETS } from "@floe/sdk";
const A = FLOE_ADDRESSES.testnet;
A.package; A.registry; A.refVault; A.nav.enclave; A.lend.refPool;
terminalbash
# exercise every read surface against testnet
pnpm exec tsx examples/sdk-tour.ts