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

# Market Rates

> Resolve an asset's USD spot rate and stamp the dollar notional onto a trace

## Overview

A trace that records a swap of `0.5 ETH` tells you the size in tokens but not in dollars. Comparing that against a `1200 USDC` trade, or alerting when a trade exceeds a dollar threshold, means knowing the rate at the moment the action happened — not the rate at the time you look.

Mirador's rate hint ties an asset symbol and quantity to a trace. The backend `ratehint` plugin resolves the USD spot rate and stamps both the rate and the resulting notional onto the trace:

* `RateHintAdded` → `RateTrackingStarted`
* `RateAdded` (the resolved rate and notional) *or* `RateNotFound`
* `RateTrackingFinished` (terminal)

Unlike the transaction hints, this one resolves in one step and does not track an external state machine — it prices a quantity at the time the hint arrives.

<Note>
  Rate hints are emitted over OpenTelemetry only. There is no Web SDK method — no `Web3Plugin`, no `trace.market.*` namespace. Emit the reserved span event described below.
</Note>

## Recording a Rate Hint

Add the `mirador.market.asset.ratehint` event to the active span with a symbol and a quantity.

<CodeGroup>
  ```typescript TypeScript theme={null}
  span.addEvent('mirador.market.asset.ratehint', {
    'asset.symbol': 'ETH',
    'asset.quantity': 0.5,
  });
  ```

  ```go Go theme={null}
  span.AddEvent("mirador.market.asset.ratehint", trace.WithAttributes(
      attribute.String("asset.symbol", "ETH"),
      attribute.Float64("asset.quantity", 0.5),
  ))
  ```

  ```python Python theme={null}
  span.add_event("mirador.market.asset.ratehint", {
      "asset.symbol": "ETH",
      "asset.quantity": 0.5,
  })
  ```
</CodeGroup>

### Attributes

| Attribute        | Type                               | Required | Description                                                 |
| ---------------- | ---------------------------------- | -------- | ----------------------------------------------------------- |
| `asset.symbol`   | string                             | Yes      | Crypto symbol (`ETH`, `USDC`) or ISO 4217 fiat code (`GBP`) |
| `asset.quantity` | double, integer, or numeric string | Yes      | Order size in units of `asset.symbol`; must be positive     |
| `asset.kind`     | string                             | No       | `crypto` or `fiat`; inferred from the symbol when omitted   |

`asset.symbol` is upper-cased server-side, so casing does not matter. `asset.quantity` keeps its fractional part and accepts a numeric string for SDKs that cannot express a double.

<Note>
  `asset.kind` is passed through as-is and lowercased. Any value other than `crypto` or `fiat` is treated as unspecified, and the market service falls back to inferring the kind from the symbol — an unrecognized value does not invalidate the hint. Prefer `crypto`, `fiat`, or nothing at all.
</Note>

## What Gets Stamped

On a successful resolution, `RateAdded` carries the rate and notional, and the following attribute bag is stamped inside the synthetic `ratehint` span:

| Attribute                          | Type   | Description                                  |
| ---------------------------------- | ------ | -------------------------------------------- |
| `mirador.market.rate.symbol`       | string | Canonical symbol the market service returned |
| `mirador.market.rate.pair`         | string | The quoted pair, e.g. `ETH/USD`              |
| `mirador.market.rate.quantity`     | double | The quantity you submitted                   |
| `mirador.market.rate.asset_kind`   | string | `crypto`, `fiat`, or `unspecified`           |
| `mirador.market.rate.usd_per_unit` | double | USD value of one unit of the symbol          |
| `mirador.market.rate.usd_notional` | double | `quantity × usd_per_unit`                    |

`RateAdded` also records `rate_as_of` for source freshness and the resolution `source` (`cache`, `coingecko`, or `exchangerate`).

<Tip>
  These attributes are dotted and platform-namespaced specifically so automation rules and derived metrics can read them. Pricing slippage or trade size in dollars is a query over `mirador.market.rate.usd_notional`.
</Tip>

## Terminal Statuses

`RateTrackingFinished` closes the lifecycle with one of:

| Status        | Meaning                                                      |
| ------------- | ------------------------------------------------------------ |
| `SUCCESS`     | A rate was resolved and stamped                              |
| `UNAVAILABLE` | The rate source was unreachable, or no quote arrived in time |
| `UNSUPPORTED` | The symbol could not be resolved to a USD rate               |

`UNAVAILABLE` is transient and worth retrying on a later trace; `UNSUPPORTED` means the symbol will not resolve. Both emit `RateNotFound` before the terminal event, so a missing rate is always visible in the trace rather than silently absent.

## End-to-End Example

```typescript theme={null}
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('trading');

await tracer.startActiveSpan('swap-flow', async (span) => {
  try {
    // 1. Price the input side of the swap in dollars
    span.addEvent('mirador.market.asset.ratehint', {
      'asset.symbol': 'ETH',
      'asset.quantity': 0.5,
      'asset.kind': 'crypto',
    });

    // 2. Execute the swap and hint the transaction as usual
    const tx = await executeSwap();
    span.addEvent('mirador.web3.evm.txhint', {
      'tx.hash': tx.hash,
      'chain.id': 8453,
    });
  } finally {
    span.end();
  }
});
```

The trace now carries both the onchain settlement and the dollar value of what was traded.

## Pricing Both Sides

A rate hint prices one asset. Emit one per asset when you want both sides of a trade in dollars — one action per event is the rule for every hint.

```typescript theme={null}
span.addEvent('mirador.market.asset.ratehint', {
  'asset.symbol': 'ETH',
  'asset.quantity': 0.5,
});

span.addEvent('mirador.market.asset.ratehint', {
  'asset.symbol': 'USDC',
  'asset.quantity': 1200,
});
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Enrichment Hints" icon="wand-magic-sparkles" href="/opentelemetry/enrichment-hints">
    The full reserved-event catalog and attribute contract
  </Card>

  <Card title="Stripe Payments" icon="credit-card" href="/concepts/stripe-payments">
    Track payments through charge and payout
  </Card>

  <Card title="Metrics over OTLP" icon="chart-simple" href="/opentelemetry/metrics">
    Export metrics alongside your traces
  </Card>

  <Card title="Automation Rules" icon="bolt" href="/automations/rules">
    Alert on notional thresholds
  </Card>
</CardGroup>
