> ## 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.

# Monitor your bonds

> Webhooks vs polling, trigger events, and the bond redemption flow.

<Note>
  See [/concepts/lifecycle](/concepts/lifecycle) for the end-to-end flow (policy → trigger → bond → wait/sell decision).
</Note>

Once a policy triggers, the bond shows up in `lumina.bonds.list()`. The
agent's job is to notice the trigger fast and decide what to do with the
bond.

## Two ways to notice a trigger

### A) Webhook (push, recommended)

Subscribe once, receive an HMAC-signed JSON POST when the trigger lands
on-chain. End-to-end latency from on-chain settlement to your endpoint is
0–30s (the worker polls a queue every 30s).

```ts theme={null}
const sub = await lumina.webhooks.create({
  url:    'https://my-bot.example.com/webhooks/lumina',
  events: ['policy_triggered', 'bond_minted', 'bond_redeemed'],
})
// store sub.secret in your secrets manager
```

The body of a `policy_triggered` event contains `policyId`, `productId`,
`bondId`, `faceValueUsdc`, `txHash`, and the on-chain `triggeredAt` epoch.
See [Webhooks](/agents/webhooks) for the signature-verification snippet.

### B) Polling (pull)

Cheap when you only hold a handful of active policies. Hit
`GET /api/v1/policies/:id` on an interval — every 30s is plenty:

```ts theme={null}
const p = await lumina.policies.get(productId, policyId)
if (p.status === 'triggered') {
  console.log('triggered — bond', p.bondId, 'minted')
}
```

`p.status` is one of `active | triggered | expired`. For the bond face value
and maturity epoch, list your bonds and find the matching `bondId`
(`BondsAPI` exposes only `list()` — there is no `bonds.get()`):

```ts theme={null}
const bonds = await lumina.bonds.list(wallet)
const bond = bonds.find((b) => b.bondId === p.bondId)
//   { bondId, amount, faceValueUsdc, maturityEpoch, … }
```

## Trigger events

| Event                                   | Fires when                                                                |
| --------------------------------------- | ------------------------------------------------------------------------- |
| `policy_triggered`                      | Oracle proof accepted by the shield, payout enqueued                      |
| `bond_minted`                           | `BondVault.mint` settled on-chain (usually same tx as `policy_triggered`) |
| `bond_redeemed`                         | A bond is redeemed for \$LUMINA at maturity (730 days post-mint)          |
| `listing_created` / `listing_purchased` | You listed / sold a bond on the marketplace                               |

## Read positions

```ts theme={null}
const bonds = await lumina.bonds.list()
//   [{ bondId: '202805', amount: '50', faceValueUsdc: '50000000', maturityEpoch: 12345 }, …]
```

Filtered server-side to the calling wallet. Cross-wallet reads are forbidden
(the on-chain data is public; the API just refuses to act as an
unauthenticated indexer).

## Bond redemption flow

Bonds are ERC-1155, $1 face value per unit, with a **730-day maturity** from
mint. Once mature, redeem on-chain for `$LUMINA`via`BondVault.redeem`(or the SDK wrapper if exposed). The vault enforces a per-epoch throttle of`MAX\_REDEMPTION\_PER\_EPOCH\_BPS = 108\` — **1.08% per week** of the epoch's
outstanding face, FIFO queued post-throttle. This is the anti bond-run
safeguard described in [BondVault throttle](/concepts/bondvault-throttle).

If you need cash sooner than 730 days, list the bond on the
[marketplace](/concepts/marketplace) — typical discount is 2–5%, with
`150 bps` maker + `150 bps` taker fees.

## Decision rule

| Condition                | Action                                                      |
| ------------------------ | ----------------------------------------------------------- |
| Need cash today          | List on marketplace at `face × discount` (typically 95-98%) |
| Maturity is \< 24 h away | Hold and redeem on-chain at maturity                        |
| Want to compound         | Hold; redeem; immediately rotate into a new policy          |

## Listing logic

```ts theme={null}
const listings = await lumina.marketplace.listings({ sortBy: 'price-asc', limit: 5 })
const cheapest = listings[0]

// Buy if discount > 5%
if (cheapest && BigInt(cheapest.totalPriceUsdc) < (BigInt(cheapest.amount) * 95n) / 100n) {
  // … snipe
}
```

## Pinning maturity

`bond.maturityEpoch` (where exposed) is a wall-clock seconds value. To get
seconds-until-maturity:

```ts theme={null}
const secondsToMaturity = bond.maturityEpoch - Math.floor(Date.now() / 1000)
```

If the SDK doesn't expose `maturityEpoch` on a particular response shape,
query the on-chain `BondVault.epochInfo(epochId)` directly via your RPC.
