Skip to Content
Symmio Trading-SDK — the SDK surface for builders on Arbitrum
CoreInventoryOverview

Inventory

The inventory service is the custody backend behind the lowcap Pools. It holds the per-market token and collateral inventory that backs trading, and reports the system-wide TVL those balances add up to.

It is a separate vendor from both the solver and the listing backend — its own deployment, its own base URL, its own OpenAPI spec (https://inventory85.enigma.bz/openapi.json, which the package’s generated client is built from). Nothing in this slice is on-chain: like Pools, it is REST bookkeeping.

There are no contract calls in this slice. Both reads here are REST calls against the inventory service — nothing here signs, sends, simulates, or reads a contract.

A pools page is several vendors, not one

A pools screen looks like a single product and is assembled from three independent backends. Knowing which figure belongs to which vendor is what keeps a discrepancy from reading as a bug:

FigureOwner
Catalog rows — per-pool tvl, apr, liquidityListing backend (getListingMarkets)
Headline system TVLInventory service (getInventoryTvl)
One pool’s TVL over timeThe same service, per market (getInventoryTvlHistory)
Per-market revenue totalsThe solver (getSolverRevenue)
Per-market volume and open-interest capsThe solver again, on separate endpoints (Solvers)

Separate deployments mean separate refresh cadences and separate failure modes. A UI that treats them as one surface blocks the whole page on its slowest service, and reads a mismatch between the headline TVL and the catalog’s tvl column as an arithmetic error rather than as what it is — see Not the sum of the catalog.

Availability

The inventory service is configured at chain level and optional: SymmioChainConfig.inventory, a SymmioInventoryConfig. Like the Pools listing backend, no solver capability gates it — a chain either carries an inventory block or it does not. That is why resolveInventoryService takes a bare chainId.

Today only Arbitrum carries one (inventory: { url: "https://inventory85.enigma.bz" }).

import { getInventoryTvl, supportsInventoryService } from "@symmio/trading-core"; if (supportsInventoryService(config, chainId)) { const tvl = await getInventoryTvl(config, { chainId }); }

resolveInventoryService throws where the chain has no service — it deliberately does not fall back to another chain’s deployment, because reading a different system’s TVL would surface as a wrong number rather than as an error. supportsInventoryService is the non-throwing twin: use it for enabled gates and UI so the TVL card hides instead of erroring where the service does not exist.

SymmioInventoryConfig.url is the service’s host root — no path segment, no trailing slash (https://inventory85.enigma.bz). The generated client’s own paths already begin with /api/v1, so appending /api here would request /api/api/v1/markets/tvl-aggregate and 404.

Values are 18-decimal USD bigints

The service reports its value fields as decimal strings at 18 decimals — INVENTORY_VALUE_DECIMALS — independent of any token’s own decimals and of the collateral’s. The SDK keeps them as bigint at that scale so nothing is lost, and formats nothing for you:

import { INVENTORY_VALUE_DECIMALS } from "@symmio/trading-core"; import { formatUnits } from "@symmio/utils/decimal"; // `formatUnits` from @symmio/utils returns a chainable Decimal, not a string. const headline = `$${formatUnits(tvl, INVENTORY_VALUE_DECIMALS).toFixed(2)}`;

The scale is the same 18 decimals the listing backend uses, but the unit is not. A descaled listing rate is a percentage (1e18 = 1%); every inventory value is a plain USD amount, so 1e18 is $1. Do not carry a formatting helper across from one to the other without checking which of the two you are holding.

What this slice wraps

Deliberately two reads. The generated client covers the service’s whole spec — orders, swaps, deposits, withdrawals, transfers, market positions and their PnL, per-market TVL and its history, funding-rate reads and simulation, health checks, error codes — but that client is internal to the package and is not exported. The public surface is exactly getInventoryTvl and getInventoryTvlHistory, their query factories, toInventoryTvl and toInventoryTvlPoint, the two resolver functions, and INVENTORY_VALUE_DECIMALS.

Every wrapper is a normalized type, an error code, and a compatibility promise, so they get added when a flow needs one rather than in bulk. Nothing else on the spec — the custodial deposit and withdrawal endpoints included — is reachable from @symmio/trading-core today.

Reads

Config

Helpers

The mapper getInventoryTvl runs on the way out. Reach for it only when you hold a raw service response yourself — a proxy route, a fixture, a rehydrated payload.

INVENTORY_VALUE_DECIMALS — the fixed-point scale every value in this slice carries — has no page of its own; it is documented on getInventoryTvl alongside the value it scales.

Query options

Both reads ship a matching options factory and key builder for TanStack Query — getInventoryTvlQueryOptions / getInventoryTvlQueryKey and getInventoryTvlHistoryQueryOptions / getInventoryTvlHistoryQueryKey. The resolved chain config’s fingerprint is folded into each key, so a createConfig override pointed at the staging deployment never serves production’s cached figure. See getInventoryTvl and getInventoryTvlHistory for the exact calls.

Errors

  • INVENTORY_NOT_CONFIGURED — a SymmError with kind: "config": the resolved chain has no inventory service. Raised before any network call.
  • FETCH_INVENTORY_TVL_FAILED — the TVL request failed. An axios failure arrives as a SymmApiError with status, statusText, responseData, url and method (a failure with no response carries status: 0 / statusText: "Unknown"); anything else is a plain SymmError with kind: "api".
  • FETCH_INVENTORY_TVL_HISTORY_FAILED — the per-market history request failed, with the same shape. This includes the 404 on environments where that route is not deployed yet, so treat it as “no chart” rather than a page-level failure.
  • getInventoryTvl — the read, its scale contract, and toInventoryTvl.
  • getInventoryTvlHistory — the same figure per market, over time.
  • resolveInventoryService — the availability check the read runs first.
  • Pools — the listing backend that owns the catalog this service backs.
  • Solvers — the third vendor on a pools page.
  • @symmio/trading-reactuseInventoryTvl and useInventoryTvlHistory are the React bindings over these reads.
  • Errors — the SymmError / SymmApiError hierarchy these codes belong to.
Last updated on