Skip to main content
See /concepts/lifecycle for the end-to-end flow (policy → trigger → bond → wait/sell decision).
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

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).
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 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:
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()):
const bonds = await lumina.bonds.list(wallet)
const bond = bonds.find((b) => b.bondId === p.bondId)
//   { bondId, amount, faceValueUsdc, maturityEpoch, … }

Trigger events

EventFires when
policy_triggeredOracle proof accepted by the shield, payout enqueued
bond_mintedBondVault.mint settled on-chain (usually same tx as policy_triggered)
bond_redeemedA bond is redeemed for $LUMINA at maturity (730 days post-mint)
listing_created / listing_purchasedYou listed / sold a bond on the marketplace

Read positions

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, 1facevalueperunit,witha730daymaturityfrommint.Oncemature,redeemonchainfor1 face value per unit, with a **730-day maturity** from mint. Once mature, redeem on-chain for `LUMINAviaBondVault.redeem(or the SDK wrapper if exposed). The vault enforces a per-epoch throttle ofMAX_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. If you need cash sooner than 730 days, list the bond on the marketplace — typical discount is 2–5%, with 150 bps maker + 150 bps taker fees.

Decision rule

ConditionAction
Need cash todayList on marketplace at face × discount (typically 95-98%)
Maturity is < 24 h awayHold and redeem on-chain at maturity
Want to compoundHold; redeem; immediately rotate into a new policy

Listing logic

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