Skip to content

Stellar Index v0.5.0-rc.111

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Jun 14:55

[v0.5.0-rc.111] — 2026-06-18

Changed

  • Explorer nav restructured toward an entity-centric IA. The left rail is
    now Explorer entities (Home, Ledgers, Accounts, Issuers, Assets, AMM Pools) →
    Protocols (DEX/AMM, Lending, Aggregators, Bridges, Oracles, Soroswap Router) →
    External Markets → Analytics (Anomalies, Divergence, MEV) → Developers (API
    docs, SDK, Status). Secondary/marketing pages (Pricing, Methodology,
    Diagnostics, the CEX board) moved to footer + search. First slice of the
    deep-explorer build; Transactions, Contracts, and a dedicated SDEX order-book
    view land with their pages next.

Added

  • Contracts as a first-class entity — directory + interaction map. New
    GET /v1/contracts ranks the most active Soroban contracts over a recent
    window, each tagged with its owning protocol from the factory-anchored
    registry (the attribution hinge). New
    GET /v1/contracts/{id}/interactions returns the contract's cross-contract
    interaction map — other contracts that co-occur in its transactions (a proxy
    for cross-contract calls, since Soroban sub-invocations nest within one tx),
    ranked by shared-tx count and protocol-tagged. Both back the explorer's new
    /contracts directory page (top-level nav) and an interaction-map panel on
    the contract detail page (alongside the existing events + decoded-code
    panels). Lake-backed (stellar.contract_events), window-scoped to stay on
    the primary-key range.
  • Transactions page + SDEX Markets nav split/transactions (recent
    network activity, ledger-paged) and a distinct "SDEX Markets" nav entry
    (native order book) separate from "AMM Pools".
  • /bridges page — cross-chain settlement directory (Circle CCTP v2 + Rozo),
    a category landing over /v1/protocols (reuses the protocol-directory grid).

Fixed

  • Deploys silently skipped every migration — the F-1220 auto-apply was a
    no-op.
    deploy.yml passes -e "migrations_skip=false", which Ansible
    receives as the STRING "false" (truthy in Jinja), so the playbook's
    when: ... or not migrations_skip always evaluated false and SKIPPED the
    "Sync migrations" + "Apply outstanding migrations" tasks — printing
    "migrations_skip=true — skipping" even when the operator passed false. Every
    binary deploy since left schema changes unapplied, the exact "healthz 200 but
    partial outage" shape F-1220 was meant to prevent (and why the canonical
    /usr/local/share/stellarindex/migrations was empty on r1). Fixed by coercing
    with | bool in the playbook conditions. Also corrected the
    fx-history-missing runbook, which pointed operators at the stale,
    unmanaged /var/lib/stellarindex/migrations instead of the deploy-managed
    /usr/local/share/stellarindex/migrations.
  • Doc/config drift: the dashboard SPA at app.stellarindex.io was retired
    (2026-06-17) into the in-site stellarindex.io/account, but config doc-strings,
    handler comments, the OpenAPI /auth/login description, package.json, and
    three architecture docs still pointed at the dead host (one with a dead
    web/dashboard/README.md link).
    Updated to reality and regenerated the
    spec-derived artifacts.
  • Hardened against the nil-Now-class latent panic found in dashboard auth.
    A codebase sweep for the same pattern (a dependency dereferenced on a path
    that didn't guard/​default it) surfaced three latent cases, all now closed:
    lookupUSDPrice derefed the optional Prices reader unguarded on the
    populateChange24h path (the sibling populatePriceUSD guarded it) — and
    since asset-detail fields populate on child goroutines that
    middleware.Recoverer can't cover, an unguarded panic there would crash the
    whole API process; the run() helper now recovers per-goroutine. The
    statsflush and supply refresher constructors now default a nil logger like
    their siblings (both deref it on a background tick).

Fixed

  • Dashboard sign-in was completely broken — every authenticated request
    500'd.
    main.go built the dashboard auth Config without a Now clock
    and passed it raw to the session-resolver middleware; NewHandlers defaulted
    Now only on its own copy, so resolveSession nil-deref-panicked on every
    request carrying a session cookie. The magic link set the cookie correctly,
    then /v1/account/me 500'd and the dashboard never loaded — so login looked
    dead. Now is now set explicitly and the middleware defaults Now/Logger
    defensively.
  • The emailed "6-digit code" was really 5 digits + a NUL byte. It was
    derived from 3 hash bytes → 5 base32 chars, leaving the 6th position unset.
    Now derived from 4 bytes so it is a clean 6 ASCII digits — required, since
    the code is now a typed credential.

Added

  • Sign in with a 6-digit code, not just the magic link. New
    POST /v1/auth/verify-code {email, code} consumes the emailed code and mints
    the same session cookie the magic-link callback does (returns JSON, no
    redirect — the SPA calls it via credentialed fetch). The sign-in page is now
    a two-step flow (email → code) and the email leads with the code; the
    one-click link still works. Brute-force is bounded by a per-token attempt cap
    (migration 0065 adds magic_link_tokens.attempts); all code-failure modes
    return one generic 400.

Changed

  • Cross-origin session auth (F-03) — the in-site /account section now
    authenticates on the apex.
    The session cookie is issued SameSite=None
    when Secure (prod), so the explorer at stellarindex.io can send it on
    credentialed requests to the API at api.stellarindex.io; useMe + the
    account API client send credentials: include. Requires allow_credentials = true + cookie_domain = ".stellarindex.io" in the API config (set on r1).
    Replaces the prior "explorer always renders signed-out" limitation.