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/suiHow Floe fits together.
VenueModule.value() + settled value. The enclave signs that figure; the contract verifies the signature before it accepts the number.@floe/sdkTypeScript surface · reads · transactions · deployVault<Q,S>One uniform interface — NAV = idle + Σ value()
Verifiable Valuation primitive — verifies a signature on-chain before accepting a figure
Attested-collateral money market — borrow against the proven floor
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_navverifies 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.
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.
Connect and read a live vault.
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?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.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;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);
}The moat — what no other vault has.
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 4On-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.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 tierOne interface, many protocols.
VenueModule — deploy / 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.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 holdsThe market that removed the oracle.
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.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 });Auditable history. Private alpha.
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);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);Delegate execution, keep the kill-switch.
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.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-switchDeploy 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.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 capitalhello_vault — feel the cycle first.
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)
}One primitive, every namespace.
FloeVaultVault reads, the rich VaultState, redemption, settlement, and curator deploy.
RegistryThe Earn directory — every live vault, curator, TVL, venues, strategy.
VolOn-chain implied-volatility index from the Predict SVI oracle.
AttestationThe Nautilus moat — verify enclave-signed values on-chain.
FloeLendAttested-collateral money market — borrow against the proven floor.
WalrusTamper-evident audit trail — NAV/rebalance snapshots, indexed on-chain.
SealStrategy-parameter privacy — encrypted config, capability-gated decryption.
AgentAttenuated, revocable agent authority over a vault.
TrackRecordVerifiable performance — APR/drawdown from attested snapshots.
VenuesThe multi-venue spine — DeepBookModule & CetusModule implement one interface.
Share / Policy / FeesPer-vault share codegen and on-chain-enforced policy + fee encoders.
TreasuryProtocol revenue accounting.
Three import targets.
@floe/sdk/browser — reads plus dapp-kit transaction builders, no deploy/publish.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 });Canonical ids, and a live tour.
FLOE_ADDRESSES.testnet — the runtime source of truth. Never hardcode.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;# exercise every read surface against testnet
pnpm exec tsx examples/sdk-tour.ts