# UI Guidelines

> **Note:** This section is still being built and is a work in progress.

All values are rendered from API responses. Partner front-ends never compute leverage, margin, P\&L, or liquidation values — they display what Dimes returns.

***

### 1. Leverage Slider

The leverage input for position creation. Respects the market's `leverage.max_bps` and `leverage.step_bps`, and updates the quote in real-time as the user adjusts.

> **This component is optional.** Partners may implement their own input mechanism (dropdown, stepper, buttons, etc.). The only requirement is that the selected leverage value is passed to the `/quotes` endpoint as `leverage_bps`.

#### Closed view

Just the slider rail with dot stops, "Leverage" label, and the current multiplier. Hovering the "?" shows a tooltip: *" Leverage auto-decays as resolution approaches."*

<figure><img src="/files/CHuOdn8R5YX41KnR5wqT" alt=""><figcaption></figcaption></figure>

#### Open view

When the user drags above 1x, the bottom section expands to show Entry Price, Shares, Position Value, and Liquidation Price. These values come from the quote response.

<figure><img src="/files/Yzk80YeEsPTGguWf7iJk" alt=""><figcaption></figcaption></figure>

**API fields used:** `leverage.max_bps` and `leverage.step_bps` (slider configuration), full quote response for expanded details.

#### Minimal code to integrate leverage without the slider

{% tabs %}
{% tab title="REST API" %}

```javascript
// Capture leverage from any input you prefer
const leverageBps = 50000; // 5x

// Pass to quote endpoint — this is the only requirement
const quote = await fetch(`${BASE_URL}/prediction-markets/quotes`, {
  method: "POST",
  headers: userHeaders,
  body: JSON.stringify({
    market_ticker: "will-btc-hit-100k-2025",
    effective_side: "yes",
    leverage_bps: leverageBps,
    notional_amount_usd_pips: "250000000",
    slippage_bps: 300,
  }),
}).then(res => res.json());

// Display from the quote response:
// quote.notional_amount_usd → position size
// quote.liquidation_price_usd → liquidation price
// quote.origination_fee_usd → combined origination fee
// quote.protocol_origination_fee_usd → protocol component
// quote.partner_origination_fee_usd → partner component (hide if 0 bps)
// quote.polymarket_trading_fee_bps → venue trading fee rate (0 on Kalshi)
// quote.total_user_amount_usd → total cost to user
```

{% endtab %}

{% tab title="React Hook" %}

```tsx
import {useMarket} from "@dimes-dot-fi/sdk/react";

function LeverageSlider({ticker}: { ticker: string }) {
  const {data: market} = useMarket(ticker);
  const leverage = market?.leverage;
  // Use leverage.minBps, leverage.maxBps, leverage.stepBps
  // to configure your slider
}
```

{% endtab %}
{% endtabs %}

***

### 1b. Quote Flow — Draft then Promote

Quotes (`POST /quotes`) expire in 15 seconds. This is enough time to submit a transaction but too short for a user to review numbers, decide, and open their wallet. The recommended UX uses a two-step flow:

1. **Get a draft** — call `POST /draft-quotes` with the same body as `/quotes`. Display the response (fees, entry price, liquidation price, total cost) and let the user review at their pace. Draft quotes have no expiry.
2. **Promote on click** — when the user clicks "Create Position", call `POST /promoted-quotes/{draft_quote_id}`. This returns a fully signed quote with the same parameters. Immediately open the wallet for signing — no need to re-display the numbers.
3. **Countdown during signing** — start the 15-second countdown only after the promoted quote arrives, while the wallet is open. The `signature_expiry` field gives the deadline.

**Detecting a draft vs real quote:** draft quotes return `signature_expiry: "0"` and `contract_signature: ""`. Use this to show a static "Quote ready" state instead of a countdown.

**Error handling:** if promotion fails (market conditions changed), show the error and offer a "Refresh Quote" button that re-fetches the draft.

API details: [API Reference — Promote draft quote](/for-developers/api-reference.md#promote-draft-quote).

{% tabs %}
{% tab title="REST API" %}
Use the draft-then-promote endpoints described above (`POST /draft-quotes` followed by `POST /promoted-quotes/{id}`).
{% endtab %}

{% tab title="React Hook" %}

```tsx
import {useQuote} from "@dimes-dot-fi/sdk/react";

function QuoteFlow({marketTicker}: { marketTicker: string }) {
  const {state, execute, reset} = useQuote();

  // state.phase: "idle" | "loading-draft" | "draft-ready" | "promoting" | "promoted" | "error"
  // state.draft: the draft offer (when phase is "draft-ready" or later)
  // state.offer: the promoted offer (when phase is "promoted")
}
```

{% endtab %}
{% endtabs %}

***

### 2. Position Card

The core component for monitoring open positions. Displays real-time position state with a margin health indicator.

#### Open position

<figure><img src="/files/XBItV0PNFWvTHNi7x2nf" alt=""><figcaption></figcaption></figure>

**Required elements:**

* Margin buffer in dollars (`risk.margin_buffer_usd`)
* Health ring driven by `risk.health_pct` — green above 60%, amber 30–60%, red below 30%
* Effective side (Yes / No), Entry Price, Liquidation Price
* P\&L with ROE percentage, color-coded green/red
* Starting leverage and effective leverage
* Time to resolution countdown
* Close Position action

{% tabs %}
{% tab title="REST API" %}
Use `GET /prediction-markets/positions?status=open` and the field mapping below.
{% endtab %}

{% tab title="React Hook" %}

```tsx
import {usePositions} from "@dimes-dot-fi/sdk/react";
import {isOpenPosition} from "@dimes-dot-fi/sdk";

function PositionCards() {
  const {data: positions} = usePositions({status: "open"});

  return positions?.map((p) => {
    if (isOpenPosition(p)) {
      // p.current.unrealizedPnlUsd, p.risk.currentLiquidationPriceUsd, etc.
    }
  });
}
```

{% endtab %}
{% endtabs %}

**API fields used:**

| UI element         | API field                                                  |
| ------------------ | ---------------------------------------------------------- |
| Margin buffer      | `risk.margin_buffer_usd`                                   |
| Liquidation buffer | `risk.liquidation_buffer_bps`                              |
| Health ring        | `risk.health_pct`                                          |
| P\&L               | `current.unrealized_pnl_usd`, `current.unrealized_pnl_bps` |
| Mark price         | `current.mark_price_usd`                                   |
| Entry leverage     | `entry.leverage_bps`                                       |
| Effective leverage | `effective_leverage_bps`                                   |
| Fees accrued       | `fees.accrued_lifetime_fee_usd`                            |
| Time to resolution | `timing.time_to_close_minutes`                             |

#### Settled position

When a position closes, the card transitions to a settled state.

**Settled-specific fields:**

| UI element    | API field                 |
| ------------- | ------------------------- |
| Close reason  | `close_reason`            |
| Realized P\&L | `result.realized_pnl_usd` |
| Proceeds      | `result.proceeds_usd`     |
| Total fees    | `fees.total_fees_usd`     |
| Closed at     | `result.closed_at`        |

***

### 3. Liquidation Chart

An overlay on the market price chart showing the user's liquidation price, entry price, and current mark price as horizontal reference lines.

<figure><img src="/files/iocijNuPKxdUBKPwyKcf" alt=""><figcaption></figcaption></figure>

**Required elements:**

* Dashed line at entry price (muted)
* Solid line at current mark price (green)
* Solid line at liquidation price (red) with a subtle red fill below
* Price labels on each line
* Summary metrics below: liquidation price, distance to liquidation, margin health

**API fields used:**

| UI element         | API field                     |
| ------------------ | ----------------------------- |
| Entry line         | `entry.price_usd`             |
| Current price line | `current.mark_price_usd`      |
| Liquidation line   | `risk.liquidation_price_usd`  |
| Buffer distance    | `risk.liquidation_buffer_bps` |
| Margin health      | `risk.health_pct`             |

### 4. Interactive View

The interactive reference below lets you explore each component in context. Drag the leverage slider to see the expanded view update in real-time, or drag the liquidation line on the chart to see implied leverage recalculate. All values shown are simulated. In production, these are populated by your API responses.

{% embed url="<https://components.dimes.fi/>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.dimes.fi/for-developers/ui-guidelines.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
