Stellar Index v0.30.0
[v0.30.0] — 2026-08-08
Fixed
-
/v1/price/streamno longer interleaves aggregation windows on
one topic (cold audit 2026-08-03, r1-confirmed: three consecutive
price_updateevents carriedwindow_seconds300/3600/86400 with
materially different prices, so a client readingvalue_decimalsaw
the price flap three times per tick). The Hub topic key now includes
the window (closed:<asset>/<quote>/<window_seconds>) and the
stream accepts?window_seconds=(default 300) to pick one series.
Also fixed: subscribing with an alias spelling (?asset=nativevs
the aggregator'scrypto:XLM) silently matched nothing forever —
the handler now subscribes to every alias spelling of the pair. -
/v1/observations(+ its stream) now scans every alias spelling
of the pair — CEX observations live undercrypto:XLMwhile SDEX
legs live undernative, so a?asset=nativequery was silently
blind to the CEX rows (and vice versa). Alias results merge keeping
the newest trade per source; single-spelling pairs still do one scan. -
/v1/price/streamevents now carry the documented/v1/price
envelope shape from BOTH producers (data+as_of;flags/
sourcesonly when evaluated). Previously the aggregator bridge
emitted{asset, quote, window_seconds, value_decimal, observed_at}
and streampublish emitted{snapshot, sources, stale}— two bespoke
shapes on one endpoint, neither matching the OpenAPI example. No
fabricated flags: an absentflagsobject means "not evaluated",
never "fresh".as_ofis the bucket end, keeping cross-region
payloads byte-identical (ADR-0015). -
/v1/price/tip/streamnow shares one tip-compute loop per
distinct (asset, quote, window) across all connections via the
streaming Hub, instead of running a private 5-second query loop per
connection (cold audit 2026-08-04: "tip stream = 6 DB queries/s PER
CONNECTION — pool saturates at ~2300 streams"). Steady-state DB cost
now scales with distinct pairs being watched, not with viewer count;
producers linger 30 s after their last subscriber leaves to absorb
reconnects, and Hub resume (Last-Event-ID) now works on the tip
stream. Per-connection pre-flight verdicts (404 / withheld / 400)
and the instant first frame are unchanged. Hub-less deployments keep
the legacy per-connection producer. This is the scaling precondition
for the explorer's live-ticking pages (RT-1). -
The accounts hub's most-held chart no longer includes native XLM —
every funded account holds XLM by definition, so charting it
collapsed the issued-asset bars to slivers. -
CI's web advisory gate: pnpm override floors raised for four fresh
high GHSAs (nanoid, undici, brace-expansion, js-yaml — the prior
js-yaml range>=4.2.0 <4.3.0excluded the patched 4.3.1).
Added
- Explorer live ticks (RT-2): a shared SSE multiplexer
(web/explorer/src/lib/live/) — one refcounted EventSource per
endpoint per tab, slow reopen on hard failure (WB-04) — now powers a
live network heartbeat in the sidebar (latest closed ledger, pulsing,
linking to its /ledgers page) and live tip-price streaming on asset
pages: the headline price ticks in real time with an up/down flash
and a "live tip price · streaming" caption, degrading to the
existing 60s poll + baked value when the stream is unavailable.
The home strip's XLM cell and the market-pair headline (previously
a BUILD-frozen price captioned "as of ") stream the
same way, and /ledgers + /operations follow the network live: new
rows animate in on every ledger close while page 1 is on screen
(paging into history pauses following). The markets board follows
ledger closes with a throttled refresh and per-cell price flashes —
one SSE connection for the whole table. Animations respect
prefers-reduced-motion. - Contract activity card (insight program unit 1): every contract
page shows first-seen / last-seen ledgers, lifetime active-ledger
count, and a 30-day activity sparkline — µs reads off the
contract-keyedcontract_active_ledgersindex.