Skip to content

ID Model

Both feedd and orderd operate on a single shared identity space. Every message on the wire references assets and instruments by a u64 identifier derived from a deterministic canonical key.

Canonical key grammar

Canonical keys have two forms:

<category>.<namespace>:<locator>   # general form
<category>.<namespace>             # no-locator form (only where explicitly supported)

The no-locator form is used for assets where the namespace itself is sufficient to identify the entity (for example native.solana, native.btc).

Segment Role Assets Instruments
category Entity kind Asset kind (native, erc20, spl, syn) Instrument type (spot, perp)
namespace Hosting environment Chain family (evm, solana, btc) or venue (binance) Venue (binance, coinbase, hyperliquid)
locator Authoritative identifier Chain-/venue-specific identifier (see patterns below) Venue-native trading symbol

Both entity types share the same parser, the same hash function, and the same u64 output width.

Asset locator patterns

Pattern Meaning Example
(none) Namespace uniquely identifies the asset native.solana, native.btc
<chain_id> Native asset on a specific chain in a family native.evm:1
<chain_id>_<address> Contract asset on a specific chain erc20.evm:1_0xa0b86991...
<symbol> Venue custodial balance symbol syn.binance:eth

Asset key examples

Canonical key Description
native.evm:1 ETH on mainnet
erc20.evm:1_0xa0b86991... USDC on mainnet
native.evm:8453 ETH on Base
native.solana SOL
spl.solana:EPjFWdd5... USDC on Solana
native.btc BTC
syn.binance:eth ETH balance on Binance
syn.coinbase:btc BTC on Coinbase
syn.hyperliquid:spot-btc BTC spot balance on Hyperliquid

Instrument key examples

Canonical key Description
perp.binance:BTCUSDT BTC-USDT perpetual on Binance
spot.binance:BTCUSDT BTC-USDT spot on Binance
perp.bybit:BTCUSDT BTC-USDT perpetual on Bybit
spot.coinbase:BTC-USD BTC-USD spot on Coinbase
perp.hyperliquid:BTC BTC perpetual on Hyperliquid
perp.deribit:BTC-PERPETUAL BTC perpetual on Deribit

Normalization rules

Segment Rule
category MUST be lowercase
namespace MUST be lowercase
locator (assets, EVM) MUST be lowercase hex, 0x-prefixed, 40 characters
locator (assets, Solana) MUST preserve exact base58 bytes — Solana mints are case-sensitive
locator (assets, venue balances) SHOULD be lowercase for case-insensitive venues; MUST preserve exact bytes for case-sensitive venue symbols
locator (instruments) MUST preserve venue casing exactly — the exchange is the authority

ID derivation

asset_id = hash(canonical_key) → u64
inst_id  = hash(canonical_key) → u64

The hash function is deterministic: the same canonical key always produces the same u64. At 500K entities the collision probability is approximately 10⁻¹¹.

Design principles

  • Asset locators are chain-authoritative. The EVM contract address or Solana mint is a fact published by the chain, not a value assigned by this system.
  • Instrument locators are venue-authoritative. The venue-native symbol (e.g. BTCUSDT) is preserved exactly as the exchange publishes it. No normalization is applied.
  • Decomposition is metadata, not identity. An instrument's base, quote, and settlement asset breakdown is carried in metadata fields. The canonical key itself is opaque — consumers resolve it via the metadata snapshot.
  • Same asset, different locations produce different asset_id values. ETH on mainnet, ETH on Base, and ETH on Binance are three distinct assets. Risk-tier metadata links related assets through unwrap_to and risk_root_id.

Common pitfalls

  • Do not assume two assets with the same ticker are the same asset_id. syn.binance:eth and native.evm:1 are distinct entities.
  • Do not infer instrument decomposition from the venue symbol. BTCUSDT on Binance and BTC-USD on Coinbase have different quote assets. Always consult the metadata.
  • Solana mint addresses are case-sensitive. Use the canonical key as-is; do not lowercase.

Core metadata

The minimum required for both binaries to function and for consumers to interpret messages correctly.

Asset

Packed fixed-size struct (16 bytes):

offset  size  type   field
─────────────────────────────
0       8     u64    asset_id
8       1     u8     venue          0 for on-chain assets
9       1     u8     decimals
10      1     u8     status         ACTIVE | HALTED | DELISTED | PENDING
11      1     u8     _pad
12      4     u32    meta_seq
─────────────────────────────
                     16 bytes total

Instrument

Packed fixed-size struct (56 bytes):

offset  size  type   field
─────────────────────────────
0       8     u64    inst_id
8       8     u64    base_id        base / underlier asset_id
16      8     u64    quote_id       quote / denomination asset_id
24      8     u64    settle_id      settlement asset_id (= quote_id for spot)
32      4     u32    price_tick_mantissa
36      4     u32    qty_step_mantissa
40      2     i16    make_fee_bps   maker fee in basis points (negative = rebate)
42      2     i16    take_fee_bps   taker fee in basis points
44      1     i8     price_tick_exponent
45      1     i8     qty_step_exponent
46      1     u8     venue
47      1     u8     inst_type      SPOT | PERP
48      1     u8     status         ACTIVE | HALTED | DELISTED | PENDING
49      3            _pad
52      4     u32    meta_seq
─────────────────────────────
                     56 bytes total

The make_fee_bps and take_fee_bps fields are best-effort estimates, periodically refreshed by the metadata pipeline. Fee accuracy is not guaranteed — see Fees.

Tick and step encoding

Tick sizes and quantity steps are encoded as mantissa × 10^exponent, avoiding floating-point precision issues entirely.

Instrument Mantissa Exponent Resolved value
BTC-USDT perpetual (Binance) 1 -1 0.1
ETH-USDT spot (Binance) 1 -2 0.01
SHIB-USDT (Binance) 1 -8 0.00000001
BTC-USD (Coinbase) 1 0 1

Status enum

Replaces a simple boolean gate with a richer lifecycle state.

State Value Meaning
ACTIVE 1 Normal operation
HALTED 2 Temporarily suspended (exchange maintenance, circuit breaker)
DELISTED 3 Permanently removed — consumers SHOULD remove from local state
PENDING 4 Known to the system but not yet ready for use

Consumers MUST NOT submit orders or interpret prices for any entity whose status is not ACTIVE.

Fees

Fees on crypto exchanges are a function of both the instrument and the account. Maker/taker rates for the same instrument vary across accounts depending on volume tier, VIP status, and venue-specific rebate programs. Venues may change an account's tier at any time.

What the metadata pipeline provides

The metadata pipeline periodically queries upstream venues and writes the most recent fee values into the make_fee_bps and take_fee_bps fields on the instrument struct. These values are best-effort — they reflect the last successful poll and may be stale.

Fee accuracy CANNOT be guaranteed. There is inherent latency between a tier change upstream and its propagation through the metadata pipeline, and some venues do not expose per-account fee schedules programmatically at all.

What consumers SHOULD do

For fee-sensitive strategies, consumers MUST treat fill messages as the authoritative fee source:

  1. Read the actual maker/taker fee reported on each fill message returned by orderd.
  2. Maintain a local fee cache keyed by inst_id, updated from observed fills.
  3. Use the metadata fee fields as an initial estimate until fills arrive.

The metadata fees are adequate for rough pre-trade cost estimates and order routing heuristics. They are NOT suitable for P&L calculations, reconciliation, or fee accounting.

Fills are the source of truth for fees

The instrument struct fee fields are best-effort. For any strategy where fee accuracy matters, read fees from fill messages and cache them locally.


Invariants

Violations indicate a data integrity issue. Consumers SHOULD NOT use the affected entity until the violation is resolved.

  • status == ACTIVE is required before using an asset or instrument for trading or pricing
  • inst_type ∈ {SPOT, PERP}base_id, quote_id, and settle_id MUST all be non-zero
  • inst_type == SPOTsettle_id MUST equal quote_id

String table, venue registry, risk metadata, and delivery mechanics are documented in Metadata.