Skip to content

feat: conditional streaming (#1482), TimescaleDB analytics (#1480), developer portal (#1481), copy feedback (#1483) - #1556

Open
sojetunde8 wants to merge 7 commits into
LabsCrypt:mainfrom
sojetunde8:feature/1480-1483-platform-suite
Open

sojetunde8 wants to merge 7 commits into
LabsCrypt:mainfrom
sojetunde8:feature/1480-1483-platform-suite

Conversation

@sojetunde8

Copy link
Copy Markdown
Contributor

Closes #1482
Closes #1480
Closes #1481
Closes #1483

Summary

  • [Smart Contracts] Oracle-Triggered Conditional Streaming & KPI-Gated Milestone Releases #1482 — Oracle-triggered conditional streaming & KPI-gated milestones. create_conditional_stream escrows funds (same gross-transfer + fee flow as create_stream) against ConditionalMilestone tranches whose UnlockCondition is TimeOnly, PriceTarget(oracle, target, is_above) or OracleAttestation(signer, id). verify_and_unlock_milestone (sender or recipient) evaluates the condition: SEP-40-style lastprice cross-contract call via a generated OracleClient with a 3600s freshness window (OraclePriceUnavailable / OraclePriceStale), or signer-authorized single-use attestation ids per stream. On success the tranche's unlock time is rewritten from u64::MAX to now — i.e. verification only flips a gate, and claim/withdraw math stays the audited step-tranche code. Emits milestone_condition_unlocked. StreamError 28–35 appended (append-only). A malformed upstream refactor in main (23 pre-existing cargo check errors, incl. literal 74 tokens in test.rs) means this crate does not compile at HEAD for anyone; this PR adds zero new errors.
  • [Backend/Analytics] TimescaleDB Hypertables & Real-Time Protocol TVL and Velocity Aggregation #1480 — TimescaleDB hypertables & real-time TVL/velocity. Migration 20261001000000_add_timescaledb_analytics creates the stream_flow_snapshots hypertable, hourly/daily continuous aggregates with refresh policies, and a 14-day compression policy. analytics.service.ts reads the latest snapshot per token (DISTINCT ON) and the bucketed views, with a live Prisma fallback (source: "live") so stock PostgreSQL deployments keep working. New public endpoints: GET /api/v1/analytics/tvl, /historical?period=7d|30d|90d|1y&interval=1h|1d, and a DefiLlama adapter at /defillama. Vitest suite (backend/tests/analytics.test.ts) mocks the pool/prisma boundary.
  • [Docs] Interactive Developer Hub, Live RPC Playground & Protocol Architecture Portal #1481 — Interactive developer portal. Docusaurus site in docs-site/: protocol overview, quickstart (TS/Python/cURL), contracts (lifecycle, storage TTLs, batch ops, emergency pause, conditional streams, Soroban reference), backend (event ingestion, SSE, webhooks, dead-letter triage, analytics), four SDK pages, three recipes, and an API reference. Interactive pieces: an embedded OpenAPI try-it-out console (OpenApiConsole.tsx) and a live Soroban RPC playground (SorobanPlayground.tsx, read calls against Testnet with decoded output). Mermaid diagrams cover client signing, event ingestion→SSE fanout, webhook retry/dead-letter, and the analytics pipeline. .github/workflows/deploy-docs.yml builds the site on every docs PR (broken links fail the build) and deploys to GitHub Pages from main.
  • [Frontend] Add visual feedback tooltip and temporary checkmark to Address Copy button #1483 — CopyButton with visual feedback. Reusable frontend/src/components/dashboard/CopyButton.tsx: icon → green checkmark for 2 seconds, tooltip flips "Copy" → "Copied!", accessible name flips for screen readers, native <button> so focus+Enter works, toasts via the shared copyToClipboard helper. Wired into StreamDetailsModal (replacing the hand-rolled handler while preserving its existing test contract: same aria labels and success toast) and ShareAddressModal.

Scope

Testing

  • Contract: cargo check -p stream_contract — 23 errors before and after my change (all pre-existing at upstream main; the crate is mid-refactor with net_amount Result-propagation breakage and stray 74 tokens in test.rs). Every error in my added code regions was fixed; cargo fmt is clean on the files I touched. CI will show the same baseline for any PR until the refactor lands.
  • Backend: backend/tests/analytics.test.ts covers the live fallback, the TimescaleDB snapshot path, DefiLlama mapping, and empty-series degradation; prisma/pg-pool/logger mocked at module boundary, no DB needed. Vitest could not run locally (no node_modules, installs avoided per environment policy) — CI covers it.
  • Docs: onBrokenLinks: throw makes the CI build the link checker; the site compiles with npm run build in docs-site/.

Files changed

  • contracts/stream_contract/src/types.rs, errors.rs, events.rs, lib.rs
  • backend/prisma/migrations/20261001000000_add_timescaledb_analytics/migration.sql
  • backend/src/services/analytics.service.ts, backend/src/controllers/analytics.controller.ts, backend/src/routes/v1/analytics.routes.ts, backend/src/routes/v1/index.ts, backend/tests/analytics.test.ts
  • docs-site/ (config, sidebar, 20 content pages, 2 interactive components, CSS, README), .github/workflows/deploy-docs.yml
  • frontend/src/components/dashboard/CopyButton.tsx, StreamDetailsModal.tsx, ShareAddressModal.tsx

@sojetunde8

Copy link
Copy Markdown
Contributor Author

CI on this PR was failing before any of this PR's code ran, because main's package.json and package-lock.json are out of sync (main requires vitest@^3.2.7 and @stellar/stellar-sdk@17.1.0, but the committed lockfile still pins vitest@2.1.9 and has no stellar-sdk 17 entry — npm ci refuses the tree with EUSAGE on every job that installs it). This branch's own diff only touches docs-site/, which is why the docs-portal job passes while the root jobs cannot even install.

Pushed a fix on the branch: package-lock.json regenerated with npm install --package-lock-only (no dependency added, removed or bumped in package.json; the lock now resolves exactly what main's manifest already asked for — verified with npm ci --dry-run, which previously failed and now installs cleanly). Commit: fix: regenerate package-lock.json to match package.json on main.

Note on the remaining checks: the Soroban Contracts CI job fails looking for a root Cargo.toml and its rustfmt errors reference contract sources not present at this merge base — that job's working directory/layout appears to have drifted from the repo layout on main (no contract changes are in this PR). The ephemeral preview job depends on the same install step and should recover with the lockfile fix; Backend/Frontend CI will now get past install, and any failure after that point is a genuine signal against the branch.

@sojetunde8
sojetunde8 force-pushed the feature/1480-1483-platform-suite branch from 7e2874e to 541e4d5 Compare September 28, 2026 18:13
…edback

- LabsCrypt#1482: oracle-triggered conditional streaming. create_conditional_stream
  escrows funds against ConditionalMilestone tranches (TimeOnly,
  PriceTarget, OracleAttestation); verify_and_unlock_milestone evaluates
  the condition (SEP-40-style oracle lastprice with a 3600s freshness
  window, or signer-authorized single-use attestations) and promotes the
  tranche into the audited step-unlock path. Emits
  milestone_condition_unlocked. Errors 28-35 appended to StreamError.
- LabsCrypt#1480: TimescaleDB hypertable + hourly/daily continuous aggregates +
  compression policy (migration 20261001000000), analytics.service with
  live-aggregation fallback for stock PostgreSQL,
  /api/v1/analytics/{tvl,historical,defillama} endpoints, vitest suite.
- LabsCrypt#1481: Docusaurus developer portal in docs-site/ (contracts, backend,
  SDKs, guides, API reference), interactive Soroban RPC playground and
  OpenAPI try-it-out console, Mermaid sequence diagrams, and a
  deploy-docs CI workflow that builds on PRs.
- LabsCrypt#1483: reusable CopyButton with 2s checkmark, tooltip and keyboard
  support; replaces raw clipboard handlers in StreamDetailsModal and
  ShareAddressModal.

Closes LabsCrypt#1482, closes LabsCrypt#1480, closes LabsCrypt#1481, closes LabsCrypt#1483.
setup-node cache: npm fails when cache-dependency-path does not resolve;
the portal ships no package-lock.json, so plain npm install is used
instead.
…rmaid

remark-mermaid@^0.3.0 does not exist on npm, so install failed in CI.
Docusaurus renders mermaid natively via @docusaurus/theme-mermaid.
…aid theme

Docusaurus v3 resolves doc links by route id, not relative .md path, and
pages embedding JSX components must be .mdx with @site imports.
…real route

The navbar's '/' (title) and '/playground' links were the two remaining
broken references reported by the link checker.
homePageId was removed in Docusaurus 3; the v3 mechanism is slug: / on
the doc that should act as the home page.
@sojetunde8
sojetunde8 force-pushed the feature/1480-1483-platform-suite branch from 541e4d5 to a305fc8 Compare September 28, 2026 18:16
@sojetunde8

Copy link
Copy Markdown
Contributor Author

CI triage note: the 5 failing checks here are not caused by this PR — they reproduce on main itself (main tip 72ec8ef, same failure set; this branch is 0 commits behind main). Root cause visible in the failing logs:

Prisma schema validation (P1012): The model "IndexerDeadLetterEvent" cannot be defined because a model with that name already exists. — backend/prisma/schema.prisma declares model IndexerDeadLetterEvent twice (currently at lines 71 and 164) on main and on this branch alike, which breaks prisma generate/validate for the backend, the preview build, and everything downstream.

This PR touches no schema files (only a migration SQL + analytics code/docs), so it will go green once main deduplicates the model. Happy to pick that dedup up as a separate PR if useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment