> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nilemarkets.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Registries

> Pairs and tenors are onchain registries — not compile-time enums. Admins can add new markets and maturities via a single admin transaction; every consumer reads the live registry and surfaces new entries automatically.

Nile Markets has two dimensions an operator may want to extend without a protocol upgrade:

1. **Which currency pairs are tradable** — e.g. adding GBP/USD after launch
2. **Which maturities are tradable** — e.g. adding a 2-week tenor on top of the defaults

Both are **onchain registries**. Admins add new entries with a single admin transaction; every
consumer (app, CLI, agent tooling, analytics, indexer) reads the live registry and surfaces new
entries automatically.

## Why Dynamic

Hardcoding pairs or tenors into the contract as enums would force a redeploy every time the
product adds a market or maturity. That is operationally painful and makes experimentation slow.
A registry in contract state flips the model:

* **Cheap extension** — one admin transaction, no code upgrade
* **Zero-downtime** — existing markets and maturities keep trading while the new one is added
* **Self-describing** — `getAllPairs()` / `getEnabledTenors()` *are* the source of truth; no
  out-of-band announcement needed
* **Immutable per-position snapshot** — each open position locks in its maturity as uint32 seconds
  at open time, so changes to the registry never retroactively affect existing trades

## The Two Registries

### Pair Registry

**Where it lives:** the `OracleModule` contract maintains the canonical set via
`registerPair(pairId, pythFeedId, pythExponent)`, with `getAllPairs()` returning the current set.

**What gets wired up when a pair is registered:**

* Pyth price feed (spot source)
* Per-pair fixing time (16:00 UTC by default for every pair — the WM/Reuters London fix — with per-pair admin overrides available)
* Per-pair forward publisher schedule
* Position-open gate in `PositionManager`

See [Supported Pairs](/nile-markets/supported-pairs) for the currently-registered set.

### Tenor Registry

**Where it lives:** the `Config` contract maintains the set via `registerTenor(uint32 seconds)`,
with `getEnabledTenors()` returning the live list.

**The identifier is the seconds value.** There is no enum layer — `86400` *is* the 1-day tenor,
`7776000` *is* the 3-month tenor. This lets admins register any duration they want (2 weeks,
9 months, whatever) without touching a schema.

See [Tenors](/nile-markets/tenors) for the default set.

## How the Flow Works

<Steps>
  <Step title="Admin adds an entry to the shared config JSON">
    The protocol's `defaults.json` is the single source of truth for the bundled ("known at build
    time") set. Adding a new entry here ensures the SDK, CLI, and analytics pick up the new
    label on their next rebuild.
  </Step>

  <Step title="Admin runs a registration script">
    A Foundry script (for pairs or tenors) calls the onchain registry from the admin key. This is
    the only transaction required — no new contract deploy, no migration.
  </Step>

  <Step title="Every consumer picks up the new entry automatically">
    Apps, the CLI, the MCP/x402 endpoints, the subgraph, and the oracle all read the live registry
    and merge it with their bundled cache. New entries appear immediately with a fallback label
    (e.g. `"<seconds>s"` for tenors) until the SDK is rebuilt.
  </Step>

  <Step title="Forward publisher restart">
    The forward-price publisher reads the enabled tenor set **once at startup** and iterates the
    frozen list. Admins adding a new tenor must restart the publisher so it begins publishing
    forwards for the new maturity. Until then, the UI shows the new tenor but disables it with a
    "pending publisher restart" message. Keeper has no equivalent gate — it processes whatever
    positions exist regardless of maturity.
  </Step>
</Steps>

## What Gets Cached vs Checked Onchain

<Columns cols={2}>
  <Card title="Bundled (first-paint)" icon="package">
    **What:** the pair/tenor list and labels from `defaults.json`, embedded into the SDK and CLI
    at build time.

    **Why:** no RPC hop to render the first screen of the app; offline-friendly for agent
    tooling; stable labels for analytics.

    **Caveat:** bundled data lags onchain by one SDK/CLI release.
  </Card>

  <Card title="Onchain (source of truth)" icon="database">
    **What:** `OracleModule.getAllPairs()` and `Config.getEnabledTenors()`.

    **Why:** the live registry. Any pair or tenor an admin has registered will be here, even if
    it post-dates the local SDK build.

    **How consumers use it:** merge with the bundled cache; fall back to a
    `"<seconds>s"` label for unknown tenors or the raw pairId hex for unknown pairs.
  </Card>
</Columns>

## What Is NOT Dynamic (Yet)

* **Per-(pair, tenor) fixing-time overrides** — today the fixing time is per-pair (not per-(pair,
  tenor)). All tenors on EUR/USD settle at the EUR/USD fixing time; all tenors on USD/JPY settle
  at the USD/JPY fixing time. Per-tenor variation is planned but not required at current scale.
* **Per-tenor risk parameters** — initial margin, maintenance margin, trading fee, and liquidation
  penalty are global (protocol-wide). Per-pair or per-tenor variation may come in a later
  milestone if risk data warrants it.
* **Dynamic publisher reload** — the forward publisher reads the tenor set at startup and does
  not refresh on a per-tick basis. This is a deliberate choice: the restart-to-activate model is
  simpler to reason about, and adding a new tenor is rare enough that the operational overhead
  is negligible.

## Related Pages

* [Supported Pairs](/nile-markets/supported-pairs) — current pair registry
* [Tenors](/nile-markets/tenors) — current tenor registry
* [Protocol Architecture](/nile-markets/architecture) — how `OracleModule` and `Config` fit in
* [Forwards vs Perpetuals](/nile-markets/forwards-vs-perpetuals) — why the maturity matters at all
