Skip to main content
@inflexion/sdk is the typed access layer over the live deployment. It is the only layer that holds a signer, and the only one that can answer the load-bearing question — “what dollar premium will I be charged on this position if I sign in the next block?” — by combining a fresh on-chain FairValueOracle read with the position’s geometry. Everything in this section is built on the foundation, five stakeholder surfaces, and EIP-712 quote helpers described below.
The SDK wraps the live Arbitrum Sepolia deployment (chainId 421614, fresh full redeploy 2026-06-05) and exposes it as one ergonomic object: a single factory call wires a read client and an optional write client into all five surfaces at once. No contract address is ever passed in — every address loads from the on-chain address registry.

The two design properties

These run through the whole package. If you remember nothing else about the SDK, remember these two — they are what make it safe to use from a wallet-less server, a degraded-RPC browser tab, or a UI that loads against a backing that is momentarily unreachable.

Reads are graceful

Anything that needs a reverting oracle, an absent rich event, or an unreachable history source returns a typed degraded envelope — never throws.

Writes degrade, never crash at construction

With no walletClient, the SDK still constructs. Writes either throw a clear error on call or return a deferred result carrying the unsigned tx — the only place a missing signer surfaces.

1 — Reads degrade gracefully

Every read that can fail returns a typed degraded envelope instead of throwing. There are three shapes, and the type system forces you to handle the failure branch before you can touch the data:
The reason is drawn from a closed union, DegradeReason ∈ { oracle-degraded, no-rpc, rich-events-absent, no-history-source, vol-uninitialized, market-unknown, position-unknown }. This is the discipline that lets the UI render a typed “pending” or “oracle degraded” state instead of catching an exception — a degraded read is a value, not a thrown error.
The SDK never fabricates history. History surfaces are served live from the subgraph via the hosted API. Should a history source be momentarily unreachable, ApiPending even names the API route and the exact query that would be sent — so the UI can show “coming from <route>” and degrade with zero re-derivation. See degradation for the full cheat-sheet.

2 — Writes throw or defer without a wallet

The factory always constructs, even with no signer (makeWalletClient returns undefined rather than crashing). What happens when you then call a write depends on the surface — and the difference is deliberate:
lp.buyProtection, lp.settle, lp.poke, and mm.cancelNonces throw a clear error on call. These are direct, user-driven transactions: there is no sensible “deferred” semantics for “buy this protection now”, so a missing signer is treated as a hard, explicit error at the call site — never at construction.
Most write methods also have a build* sibling (depositor.buildDeposit, mm.buildCancelNoncesTx, …) that returns raw { to, data, value } calldata for full external-signing control. See guardrails for the write-safety model.

The foundation + five surfaces + quote helpers

The SDK is the foundation (addresses, ABIs, viem client factory, shared types, tuple decoders, resolveMarket, the CvammPricing TS port under cvamm) plus five stakeholder surfaces plus the re-exported EIP-712 quote helpers.

The foundation

Imported flat from the package root and re-exported wholesale:
  • Addresses, decimals, units — import { core, stylus, libs, tokens, demo, chainlink, uniswap, npm, CHAIN_ID } from '@inflexion/sdk'. dUSDC = 6 decimals (the numéraire — every premium, amount, V0, maxIL, and collateral figure is a 6-dec raw bigint, 1 dUSDC = 1_000_000n); dWETH = 18; Chainlink feeds = 8; WAD = 1e18 for ratios. See addresses & units and decimals & units.
  • ABIs + a viem client factory — makePublicClient / makeWalletClient with env-fallback RPC and key resolution.
  • Shared types + tuple decoders — the degradation envelopes above, plus decoders for the compact on-chain structs.
  • resolveMarket — recovers a swap’s marketId (a SwapRecord carries none on-chain) by reproducing keccak256(abi.encodePacked(token0, token1, fee, uint32(expiry − createdAt))).
  • The cvamm math port — namespaced to avoid clobbering type names; the permanent, parity-locked off-chain mirror of the deployed CvammPricing load library (see below and cvamm port).

The five surfaces

One factory call wires all five at once. Each carries exactly one stakeholder’s claim — and claims are never merged:

LpClient

Buy in-range IL protection (Claim A). Price (previewPremium), buy (buyProtection, routed best-of pool vs MM), track (getProtectionStatus), and settle. Carries noBadDebtFull: true, qualified.

DepositorClient

Passive / active underwriting (Claim B). Deposit to the senior or junior tranche, read vault state and your position, withdraw under cooldown. Every result carries capitalNotGuaranteed: true.

MmClient

Path-B market making. Price a market, get the geometry-free “pool load to beat”, sign firm EIP-712 quotes (with I10 + below-pool guards), stream a requote loop, read the book and capacity.

DataClient

The data moat. One live surface (getCurrentLoadSurface) plus the typed-pending history surfaces for the five behavioral signals. Read-only.

GreeksEngine + HedgeSuggester

Read-only analytics (the fifth surface). Greeks (δ/γ/vega/θ) and a three-leg hedge suggestion, all derived from the protocol’s own deployed math — no parallel pricing model, and it never submits a transaction.
The factory returns { publicClient, walletClient?, chainId, lp, depositor, mm, data, greeks, hedge }.
Claim A and Claim B are separate claims that the SDK never merges. Claim A — LPs are always paid; no bad debt in FULL (I1), qualified — lives on the LP surface only. Claim B — depositor/MM capital is not guaranteed — lives on the depositor surface only. Both are exported verbatim as LP_CLAIM_A / DEPOSITOR_CLAIM_B so the UI renders the right one in the right place.

The quote helpers

The EIP-712 SignedQuote machinery is owned by the engine (the single source of truth) and re-exported through @inflexion/sdk and @inflexion/sdk/quote. The field order, types, and domain must match InflexionCore.SIGNED_QUOTE_TYPEHASH exactly or createSwap / createSwapRouted rejects the signature. Helpers include signQuote, quoteDigest, verifyQuote / recoverQuoteSigner, encodeQuote / decodeQuote, plus the SignedQuoteTypes / quoteDomain building blocks used for browser (wagmi) signing. Full reference: quote signing and the MM client.

How the SDK surfaces the three pillars

The SDK is not a new pricing system — it is the typed window onto the three pillars. The mapping is exact and worth holding:
1

Pillar 1 — on-chain published FairValue (the truth)

The SDK reads the exact closed-form Φ-sum from the Stylus FairValueOracle (fairPremium / fairRate) and never reimplements it off-chain. It only re-evaluates the deterministic, pure load stack client-side via the parity-locked cvamm TS port — the single duplication the architecture permits, and only because the deployed CvammPricing library is delegatecall-only (a direct eth_call reverts).
2

Pillar 2 — the cvAMM pool (the floor of liquidity)

DepositorClient is the surface onto the always-on, signature-free Path-A underwriter (ConvexityVault) — deposits, tranche state, and the load-decomposed pool floor. The pool’s “load to beat” is also a first-class MM signal via mm.getPoolLoadToBeat / streamPoolLoadToBeat.
3

Pillar 3 — MM competition (the ceiling of price)

MmClient produces firm EIP-712 signed quotes with no last look (the I10 + below-pool guards live in mm.signQuote). On the LP side, lp.previewPremium and lp.buyProtection route the cheaper of pool vs MM: createSwapRouted picks the best-of on-chain and falls back to the pool on a missing or bad quote — it never reverts on a bad MM quote.

One-call construction

createInflexionSdk(config) wires one public (read) client + one optional wallet (write) client into all five surfaces. With no arguments at all, it still constructs: env-resolved RPC and key, with graceful degradation if either is absent.
In the browser pattern, walletClient.account is used directly — wagmi’s useWalletClient() already carries .account and .chain, so you pass no explicit account. The full config table and resolution order live in getting started.
No address is ever passed to the factory. Every contract address loads from the deployment registry. Import the symbols you need (core, tokens, demo, …) rather than hardcoding — see addresses & units.

What is live today

The SDK is fully usable against the live deployment. Direct RPC surfaces are served from the chain; history and aggregate surfaces are served live from the subgraph via the hosted API:
Graceful degradation is a design property, not the current state. All history and aggregate surfaces (getLoadSurfaceHistory, getQuoteCompetition, getNavHistory, …) are served live from the subgraph via the hosted API. If a backing (the SUBGRAPH_URL, the RPC, or a telemetry sink) is ever unset or unreachable, these methods return ApiPending, which names the route and the exact query that would be sent — the UI renders “coming from <route>” and the SDK never fabricates history. See degradation. On the free hosting tier the backend sleeps after ~15 min idle, so the first call after a quiet period may incur a cold start.
Structures ship from day one; the full DYNAMICS (pool-vs-MM spread as a forward-vol signal) mature with multiple competing MMs and volume. The dataset begins at the single redeploy; the off-chain telemetry halves begin at the first interaction logged.What Inflexion offers today is the architecture and the first public view into the microstructure of the DeFi LP volatility-risk premium — not yet a mature dataset:
  • Structures are present day-one. All five non-circular behavioral signals are defined and queryable from launch.
  • Dynamics mature with volume. The richer signal — the pool-vs-MM spread read as a forward-vol indicator — only sharpens once multiple market makers compete and real flow accumulates.
  • The dataset begins at the single redeploy, and the off-chain telemetry halves begin at the first interaction logged. History is served live from the subgraph via the API; if a backing (subgraph URL / RPC / telemetry) is absent, surfaces degrade to a typed pending state — never an error.

The claims, stated correctly

The SDK carries these as first-class, never-merged flags. They are reproduced here because every consumer of the SDK must state them with their full qualifying clauses.
LPs are always paid with no bad debt in FULL mode — qualified: capped payoff + solvent USDC + oracle/settlement liveness.The no-bad-debt guarantee is exact only under the full clause:
  • FULL collateralization — the underwriter has posted exactly MaxIL per swap, locked for the life of the position.
  • Capped payoff — the payout is min(realized_IL, MaxIL). The cap is load-bearing: it is what makes payout ≤ collateral hold by construction.
  • Solvent USDC — the collateral numeraire (dUSDC) holds its peg and remains redeemable.
  • Oracle / settlement liveness — the price oracle stays live and settle() runs within the protocol’s settlement window.
  • No rehypothecation breach — locked collateral stays instantly liquid; it is never routed to utilization-gated venues.
Stated without these qualifiers, the guarantee is not correct.
Depositor capital is NOT guaranteed: the junior tranche is first-loss; the senior tranche is structurally protected from underwriting loss only, not systemic tail.Underwriting capital — whether supplied to the pooled cvAMM vault (Path A) or posted directly by a market maker (Path B) — is at risk:
  • Junior tranche — first-loss. Junior depositors absorb underwriting losses first and buffer the senior tranche.
  • Senior tranche — protected from underwriting loss, exposed to the systemic tail. The senior tranche is structurally shielded from ordinary underwriting loss while junior capital buffers, but it still takes the systemic tail once the junior buffer is exhausted.
No-bad-debt is a guarantee to the LP being paid (see the FULL-mode payout clause), not a guarantee that depositor or MM capital is preserved.

Where to go next

Getting started

Install, the full InflexionSdkConfig field table, and the construction/degradation resolution order.

Addresses & units

The address symbols, decimals (dUSDC = 6, dWETH = 18, feeds = 8, WAD = 1e18), and sqrtPriceX96 conversions.

LP client

Price, buy (routed best-of), track, and settle in-range IL protection.

Depositor client

Underwrite via the cvAMM tranches; vault state and position reads carry Claim B.

MM client

Per-market firm quotes, the pool load to beat, the requote loop, and capacity.

Data client

The live load surface and the five behavioral signals of the data moat.

Greeks & hedge

Read-only greeks and the three-leg hedge — derived from the protocol’s own math.

Degradation & guardrails

The full envelope cheat-sheet and the write-safety model.
For the live contract addresses, see the deployments reference. Network: Arbitrum Sepolia · chainId 421614 · deploy block 274081134 (subgraph startBlock) · deployed 2026-06-05

Core protocol

Stylus & libraries

Oracles

Uniswap

Demo tokens / pool / LP

Lifecycle swaps

Live create→settle lifecycle (2026-06-05, short 300s fee-500 market 0xb8bbd684f213d5833886ade7b531a6949d85522249881a2b5d46a5cc76e439c2):
  • Path A (cvAMM convexity) — swapId 1, LP tokenId 3220 · V0 $270,531.28 · MaxIL $1,669.24 · premium $9.70 (0.58% of MaxIL) · settled payout $148.64 from ConvexityVault.
  • Path B (MM routing) — swapId 2, LP tokenId 3221 · MM beat cvAMM ($8.93 vs $13.80) · MaxIL $3,215.65 · MM collateral locked $3,215.65 · settled payout $245.66 from MM collateral.