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

# Products and Assets

> The 6 V5.4 shields, the asset literal each expects, and how the SDK auto-resolves it.

Each shield contract validates `params.asset` against a hardcoded literal.
Sending the wrong asset reverts with `InvalidAsset(bytes32)` even though
the **payment token (USDC) is the same for every product**. The asset is
a *what-it-covers* tag, not the payment token.

## The 6 V5.4 products

The bytes32 hashes below come from the live `/products` endpoint and match
the `PRODUCT_ID` constants in each `BaseFlashShield` deployment on Base
mainnet. `/products` returns 6 active shields. Agents should still filter by
`active === true` to be forward-compatible with future product retirements.

| Product name     | Expected `asset` | Shield type        | Duration |
| ---------------- | ---------------- | ------------------ | -------- |
| `FLASHBTC1H-001` | `BTC`            | Flash crash on BTC | 1 h      |
| `FLASHBTC24-001` | `BTC`            | Flash crash on BTC | 24 h     |
| `FLASHBTC48-001` | `BTC`            | Flash crash on BTC | 48 h     |
| `FLASHETH1H-001` | `ETH`            | Flash crash on ETH | 1 h      |
| `FLASHETH24-001` | `ETH`            | Flash crash on ETH | 24 h     |
| `FLASHETH48-001` | `ETH`            | Flash crash on ETH | 48 h     |

Each shield is fronted by a `FlashShieldAdapter` (UUPS proxy) — discover
the adapter address with `productShield(productId)` on `PolicyManagerV2`,
or just read it off `/products`.

## Recommended: pass `productName` and let the SDK resolve everything

SDK 0.6.x auto-resolves both the bytes32 `productId` hash AND the per-shield
`asset` literal from the canonical name. You don't need to compute keccak
yourself, and you can't accidentally pair `FLASHBTC1H-001` with `ETH`.

```ts theme={null}
const policy = await lumina.policies.purchase({
  productName:    'FLASHBTC1H-001',  // SDK resolves productId hash + asset='BTC'
  buyer:          '0xYourWalletAddress',
  coverageAmount: '100000000',       // $100 minimum, paid in USDC
})
```

## REST: pass `productName` to `POST /api/v1/policies`

The same shortcut works at the API level. `asset` is optional; if you
omit it, the API auto-resolves from the registry.

```bash theme={null}
curl -X POST https://lumina-api-production-ac85.up.railway.app/api/v1/policies \
  -H "x-api-key: $LUMINA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "productName":    "FLASHBTC1H-001",
    "coverageAmount": "100000000",
    "buyer":          "0xYourWalletAddress"
  }'
```

## Sandbox: switch shields with `productName`

`POST /sandbox/try` resolves the asset from `productId` (default
`FLASHBTC1H-001` → `BTC`) or accepts `productName` for friendlier
switching. See [Sandbox-first](/agents/sandbox-first) for the full
no-wallet path.

```bash theme={null}
curl -X POST https://lumina-api-production-ac85.up.railway.app/sandbox/try \
  -H "Content-Type: application/json" \
  -d '{"productName":"FLASHETH24-001"}'   # → asset auto-resolves to ETH
```

## Advanced: explicit asset override

If you want to bypass the auto-resolver (e.g. to reproduce a revert in
testing), pass the bytes32 explicitly:

```ts theme={null}
import { keccak256, toUtf8Bytes } from 'ethers'

await lumina.policies.purchase({
  productId:      keccak256(toUtf8Bytes('FLASHBTC24-001')),
  buyer:          '0xYourWalletAddress',
  coverageAmount: '100000000',
  asset:          'BTC',                       // MUST match the shield's literal
})
```

The SDK accepts symbols (`'BTC' | 'ETH'`) for the 6 active products and
encodes them to bytes32. You can also pass a 32-byte hex string directly.

## Common errors

| Error                   | Cause                                               | Fix                                                          |
| ----------------------- | --------------------------------------------------- | ------------------------------------------------------------ |
| `InvalidAsset(bytes32)` | Sent the wrong asset for that shield                | Use `productName` and let the SDK auto-resolve               |
| `unknown_product` (400) | `productName` not in the registry                   | Check the table above; only the 6 listed products are active |
| `ProductNotConfigured`  | productId hash doesn't exist on-chain               | Verify the `keccak256` preimage matches a canonical name     |
| `InvalidCoverage`       | Below `$100` minimum (`MIN_PRICE_FOR_NEW_POLICIES`) | Increase `coverageAmount` to ≥ `100000000`                   |
| `shield_paused` (422)   | Hitting the paused legacy entry from `/products`    | Filter the product list by `active === true`                 |
