Skip to main content

Construction

import { LuminaClient } from '@lumina-org/sdk'

const lumina = new LuminaClient({
  apiKey: process.env.LUMINA_API_KEY!,
  apiUrl: 'https://lumina-api-production-ac85.up.railway.app',  // optional, this is the default
})
Construction is synchronous and never makes a network call. Call .health() to verify the API is reachable.

Constructor signature

new LuminaClient({
  apiKey: string,          // required; pass "" for onboard / sandbox / health
  apiUrl?: string,         // defaults to https://lumina-api-production-ac85.up.railway.app
})

lumina.health()

Returns API status, on-chain block height, and the canonical contract address book. Public — no API key required.
const health = await lumina.health()
//   {
//     status: 'ok',
//     chain: { chainId: 8453, blockNumber: 21345678 },
//     contracts: { bondVault, coverRouter, luminaOracleV2, marketplace, … },
//     version: 'V5.4',
//   }

lumina.getContracts()

Cached, health-derived address book. First call hits /health; subsequent calls return the cached map for the lifetime of the LuminaClient instance.
const c = await lumina.getContracts()
c.bondVault           // BondVault SET C address
c.coverRouter         // CoverRouter address
c.luminaOracleV2      // LuminaOracleV2 (TWAP) address
c.marketplace         // LuminaBondMarketplace address
Introduced in 0.5.2; unchanged in 0.6.0. Prefer this over hard-coding addresses in your bot — redeployments propagate without an SDK bump.

Sub-resources

PropertyClassEndpoints
lumina.productsProductsAPIGET /products, GET /products/:id, GET /products/:id/quote
lumina.policiesPoliciesAPIGET/POST /api/v1/policies, GET /policies/:prod/:id
lumina.bondsBondsAPIGET /api/v1/bonds, POST /api/v1/bonds/redeem
lumina.marketplaceMarketplaceAPIGET /api/v1/marketplace/listings
lumina.agentAgentAPIPOST /api/v1/agent/onboard, GET/DELETE /api/v1/agent/keys
lumina.webhooksWebhooksAPIPOST/GET/DELETE /api/v1/webhooks
lumina.sandboxSandboxAPIGET /sandbox/info, POST /sandbox/try

Errors

Every non-2xx response throws LuminaError:
import { LuminaError } from '@lumina-org/sdk'

try {
  await lumina.policies.purchase({ … })
} catch (err) {
  if (err instanceof LuminaError) {
    err.status   // HTTP status code (number)
    err.code     // API error code (string), e.g. 'invalid_api_key'
    err.message  // human-readable message
  }
}
Network-level errors (connection refused, timeout) are also wrapped as LuminaError with status === 0 and code === 'network_error'.

Custom fetch (advanced)

Both Node 18+ and modern browsers ship globalThis.fetch, which is what the SDK uses. There’s no override hook on the client itself; if you need to intercept requests (for instrumentation, mock-in-test, etc.) overwrite globalThis.fetch before constructing the client.