Skip to main content

Pricing

/v1/pricing/* is a proxy through to the BlockFinaX pricing engine — a stateful off-chain service that computes Merton jump-diffusion premiums with GARCH(1,1)-integrated variance, calibrated per-pair against 20+ years of historical closes. See Concepts → Premium pricing for the model itself.

Advisory only — not enforced

The pricing engine is a reference fair-value quote, not a constraint. The on-chain contract accepts whatever premiumRate the underwriter passes to createEvent. There is no on-chain check that the rate matches the engine's quote.

The engine is most useful for:

  • New underwriters learning the protocol who want a starting number
  • Hedgers and LPs sanity-checking whether a posted premiumRate is in the ballpark of fair value
  • Self-service venues that want pricing-as-a-service for their callers

Sophisticated underwriters — investment banks, FX desks, NDF traders — typically have their own vol view, their own data, and their own NDF / options-market inputs that produce a tighter or different number. They're expected to set their own premiumRate and pass signature = "0x" to mark the event as self-priced. See Concepts → Setting your own price for the rationale and the override flow.

The optional signed attestation path (passing chainId + diamondAddress

  • creator to /v1/pricing/quote) only matters if the contract has been configured with the engine's signer address and you want the on-chain function to verify recency. Even then, it's the underwriter's choice to use it. Self-priced events skip this entirely.

POST /v1/pricing/quote

Returns a fair-value premium for an event, optionally signed for on-chain attestation.

Request

{
"pair": "USD/GHS",
"strike": 11.4,
"payoutCap": 12.0,
"expiryUnixSeconds": 1782182400,
"notional": 100,
"strikeAbove": true,

// Optional v8 attestation context — if any are provided, ALL must be
"chainId": 8453,
"diamondAddress": "0xbCC51E62C4948FD35ab505bd71804C849601e4Ef",
"creator": "0xCAB3..."
}
fieldtypenotes
pairstringE.g. USD/GHS. Must be a pair the engine has historical data for
strike, payoutCapfloatRates in normal decimal (NOT 1e6 fixed-point)
expiryUnixSecondsintFuture timestamp
notionalfloatHedger's notional in USDC (whole units)
strikeAbovebooltrue = upward hedge / call spread
chainId, diamondAddress, creatoroptionalProvide all 3 to request a signed quote

Response

{
"data": {
"premiumRate": 0.023,
"premiumUsd": 2.3,
"maxPayoutUsd": 5.26,
"premiumRateFixed6": "23000",
"attestation": null,
"breakdown": {
"pair": "USD/GHS",
"spot": 11.07,
"strike": 11.4, "payoutCap": 12.0,
"rangeWidth": 0.6,
"T_years": 0.0822, "T_days": 30,
"notional": 100,
"direction": "upward",
"coveragePercent": 1.99,
"inputs": {
"r": 0.045, // USD risk-free rate
"q": null, // local rate (null when using empirical drift)
"mu": 0.12, // empirical drift
"qEffective": -0.075, // what the kernel actually used
"sigma": 0.21, // vol with markup applied
"sigmaRealizedRaw": 0.18,
"volMarkup": 0.17
},
"method": "garman-kohlhagen-with-empirical-drift",
"pairClassification": { "tier": "frontierEM", "useEmpiricalDrift": true, "notes": null }
}
}
}

premiumRateFixed6 is the value you pass to createEvent as premiumRate.

With attestation

If you pass chainId + diamondAddress + creator, the engine signs the quote (assuming PRICING_ENGINE_PRIVATE_KEY is configured upstream). The response includes:

{
"data": {
"premiumRate": 0.023,
"premiumRateFixed6": "23000",
"attestation": {
"signature": "0xab..130-char hex..",
"quoteTimestamp": "1782182000",
"quoteNonce": "0xcdcd..64-char hex..",
"signerAddress": "0xAaAa...",
"expiresAt": "1782182120"
},
"breakdown": { ... }
}
}

Plug signature, quoteTimestamp, and quoteNonce directly into createEvent. The quote expires in 120 secondsexpiresAt is the wall-clock deadline.

Errors

StatuscodeWhen
400validation_errorMalformed input (bad address, negative strike, etc.)
400validation_errorAll-three-or-none rule on attestation fields
400validation_errorEngine rejected the quote (e.g. leverage > 100×, unsupported pair)
502upstream_errorEngine errored internally
503service_unavailableEngine unreachable (network failure)

GET /v1/pricing/health

Engine diagnostic snapshot.

{
"data": {
"usdRate": {
"rate": 0.0445,
"recordDate": "2026-05-13",
"fetchedAt": 1782181000000
},
"pricingEngineSigner": "0xAaAa...",
"pairs": [
{ "pair": "USD/GHS", "tier": "frontierEM", "useEmpiricalDrift": true, "historicalCloses": 1300 },
{ "pair": "USD/NGN", "tier": "frontierEM", "useEmpiricalDrift": true, "historicalCloses": 1300 }
]
}
}

Useful for:

  • Confirming the engine has fresh USD-rate data (the timestamp).
  • Verifying pricingEngineSigner matches what's set on-chain via setPricingEngineSigner — if they differ, the engine's signatures will be rejected.
  • Checking which pairs the engine can price (historicalCloses should be

    = 30 to produce a meaningful EWMA vol).

GET /v1/pricing/signer

Just the signer slice of /health. Returns null if the engine has no signing key configured (i.e. it's in advisory-only mode).

{ "data": { "signerAddress": "0xAaAa..." } }

Compare against the on-chain signer:

curl https://api.blockfinax.com/v1/hedge/pricing-engine-signer/8453

If they don't match, signed quotes from this engine will not be accepted by the contract — the on-chain owner needs to call setPricingEngineSigner to rotate.