Skip to content

Latest commit

 

History

History
299 lines (235 loc) · 8.62 KB

File metadata and controls

299 lines (235 loc) · 8.62 KB

Feature Implementation Summary

This document summarizes the implementation of four major features for StellarStream.

#502: Nebula-Pay Invoice Link Generator

Overview

Allows users to generate shareable payment links that embed stream parameters (amount, asset, duration) into a short UUID-based URL.

Implementation Details

Database Schema:

  • New InvoiceLink model in Prisma schema
  • Fields: slug (unique short UUID), sender, receiver, amount, tokenAddress, duration, description, pdfUrl, xdrParams, status, expiresAt
  • Indexes on slug, sender, status, createdAt for fast lookups

Service Layer:

  • InvoiceLinkService (backend/src/services/invoice-link.service.ts)
    • createInvoiceLink() - Generate draft link with encoded XDR parameters
    • getInvoiceLinkBySlug() - Retrieve link by slug (public endpoint)
    • updateInvoiceLinkStatus() - Track link lifecycle (DRAFT → SIGNED → COMPLETED)
    • listInvoiceLinks() - List all links for a sender
    • deleteInvoiceLink() - Remove a link

API Endpoints:

  • POST /api/v1/invoice-links - Create new invoice link (requires auth)
  • GET /api/v1/invoice-links/:slug - Retrieve link by slug (public)
  • GET /api/v1/invoice-links - List sender's links (requires auth)
  • PATCH /api/v1/invoice-links/:id/status - Update status
  • DELETE /api/v1/invoice-links/:id - Delete link

XDR Encoding:

  • Stream parameters encoded as base64-encoded JSON
  • Includes: receiver, amount, tokenAddress, duration, startTime
  • Frontend decodes and uses for one-click stream signing

Usage Example:

# Create invoice link
curl -X POST http://localhost:3000/api/v1/invoice-links \
  -H "Authorization: Bearer TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "receiver": "GXXXXXX...",
    "amount": "1000000000",
    "tokenAddress": "CUSDC...",
    "duration": 2592000,
    "description": "Monthly retainer",
    "pdfUrl": "https://example.com/invoice.pdf"
  }'

# Response includes shareUrl: http://localhost:5173/invoice/a1b2c3d4

#505: Nebula-SDK (TypeScript Wrapper)

Overview

Lightweight TypeScript library wrapping both smart contract calls and Warp API endpoints for external developers.

Implementation Details

Package Structure:

  • Location: /sdk (new workspace package)
  • Build tool: tsup for ESM bundling
  • Exports: Nebula class + shared types

Core Components:

  1. Types (sdk/src/types.ts)

    • Stream - Stream state interface
    • StreamStatus - Enum (ACTIVE, PAUSED, COMPLETED, CANCELED, ARCHIVED)
    • StreamEvent - Event log interface
    • StreamHistory - Combined stream + events
    • YieldData - Yield accrual data
    • CreateStreamParams, WithdrawParams, CancelStreamParams
  2. Client (sdk/src/client.ts)

    • NebulaClient class - HTTP client wrapper
    • Methods for all stream operations
    • Axios-based with configurable base URL
  3. Main Export (sdk/src/index.ts)

    • Nebula static class - Main SDK entry point
    • initialize(baseUrl) - Setup SDK
    • setAuthToken(token) - Set auth
    • Static methods: createStream(), getStream(), getStreams(), withdrawFromStream(), cancelStream(), getStreamHistory(), getYieldData(), calculateYield(), getStreamEvents(), getStats(), searchStreams()

Usage Example:

import { Nebula, StreamStatus } from '@stellarstream/nebula-sdk';

// Initialize
Nebula.initialize('https://api.stellarstream.com/api/v1');
Nebula.setAuthToken('your-jwt-token');

// Create stream
const stream = await Nebula.createStream({
  receiver: 'GXXXXXX...',
  amount: '1000000000',
  tokenAddress: 'CUSDC...',
  duration: 2592000,
  yieldEnabled: true,
});

// Get stream history
const history = await Nebula.getStreamHistory(stream.id);

// Calculate yield
const yield = await Nebula.calculateYield(stream.id, 30);

Build & Distribution:

cd sdk
npm run build  # Outputs to dist/
npm publish    # Publish to npm registry

#506: Gap-Filler Historical Re-Sync Tool

Overview

Allows manual or automated catch-up by scanning historical ledgers when the indexer goes offline.

Implementation Details

Service Layer:

  • HistoricalSyncService (backend/src/services/historical-sync.service.ts)
    • syncFromSorobanRpc(fromLedger, toLedger) - Primary sync method
    • syncFromHorizon(fromLedger, toLedger) - Fallback method
    • fetchSorobanEvents(ledger) - Query Soroban RPC
    • fetchHorizonTransactions(fromLedger, toLedger) - Query Horizon
    • parseHorizonTransaction(tx) - Extract contract events from XDR
    • upsertEvents(events) - Deduplication via unique constraint on (txHash, eventIndex)
    • getSyncState() / updateSyncState() - Track last synced ledger

CLI Script:

  • Location: backend/src/scripts/sync-historical-ledgers.ts
  • Executable via: npm run sync -- --from=LEDGER_START --to=LEDGER_END [--horizon]

Deduplication Strategy:

  • Uses Prisma upsert with unique constraint on ContractEvent(txHash, eventIndex)
  • Prevents duplicate events if sync is interrupted and restarted
  • Idempotent: safe to run multiple times

Fallback Logic:

  1. Try Soroban RPC first (faster, more recent data)
  2. If unavailable, fallback to Horizon (slower, but always available)
  3. Parse XDR from Horizon transaction metadata

Usage Examples:

# Sync ledgers 50000-51000 from Soroban RPC
npm run sync -- --from=50000 --to=51000

# Sync from Horizon (fallback)
npm run sync -- --from=50000 --to=51000 --horizon

# Sync last 1000 ledgers
CURRENT=$(curl -s https://horizon.stellar.org | jq '.history_latest_ledger')
npm run sync -- --from=$((CURRENT-1000)) --to=$CURRENT

Database Updates:

  • Synced events stored in ContractEvent table
  • SyncState table tracks lastLedgerSequence
  • Enables incremental syncs: npm run sync -- --from=$(lastLedgerSequence+1) --to=CURRENT

#507: PM2 Cluster Mode & Log Rotation

Overview

Ensures backend process resilience with cluster mode, automatic restarts, and log rotation.

Implementation Details

PM2 Configuration:

  • File: backend/ecosystem.config.cjs
  • Two apps configured:
    1. stellarstream-api - Main API server
      • Cluster mode with instances: "max" (auto-detect CPU cores)
      • Max memory: 500MB (auto-restart on spike)
      • Error/output logs with date formatting
      • Graceful shutdown (5s timeout)
    2. stellarstream-indexer - Event indexer
      • Fork mode (single instance)
      • Max memory: 300MB
      • Separate log files

Log Rotation:

  • Module: pm2-logrotate
  • Configuration:
    • Max file size: 100MB
    • Retention: 7 days
    • Compression: enabled
    • Date format: YYYY-MM-DD_HH-mm-ss

Health Monitoring:

  • Service: PM2HealthMonitor (backend/src/services/pm2-health-monitor.service.ts)
  • Checks every 30 seconds:
    • Memory usage (restart if > 500MB)
    • CPU usage (alert if > 90%)
    • Process status
  • Graceful restart on memory spike

Setup Script:

  • Location: backend/scripts/setup-pm2.sh
  • Installs PM2 globally
  • Installs pm2-logrotate
  • Configures log rotation
  • Builds project
  • Starts services
  • Enables auto-start on system boot

Usage:

# Initial setup
bash backend/scripts/setup-pm2.sh

# View status
pm2 status

# View logs
pm2 logs stellarstream-api --lines 100 --follow

# Monitor resources
pm2 monit

# Restart all
pm2 restart all

# Stop all
pm2 stop all

# Delete all
pm2 delete all

Auto-Start on Boot:

# After setup, run:
pm2 startup
pm2 save

# To disable:
pm2 unstartup

Integration Checklist

  • Database migrations created
  • Prisma schema updated
  • Service layers implemented
  • API routes created and integrated
  • SDK package scaffolded
  • CLI scripts created
  • PM2 configuration ready
  • Documentation complete

Testing Recommendations

  1. Invoice Links:

    • Create link, verify slug generation
    • Retrieve by slug, verify XDR encoding
    • Test expiration logic
    • Test status transitions
  2. SDK:

    • Test all methods with mock backend
    • Verify type exports
    • Test error handling
    • Build and publish to npm
  3. Historical Sync:

    • Sync small ledger range, verify deduplication
    • Test Horizon fallback
    • Verify sync state tracking
    • Test idempotency (run twice, same result)
  4. PM2:

    • Start services, verify cluster mode
    • Monitor memory, trigger restart
    • Check log rotation
    • Verify auto-start on reboot

Next Steps

  1. Run database migrations: npm run db:migrate
  2. Install SDK dependencies: cd sdk && npm install
  3. Build SDK: npm run build
  4. Setup PM2: bash backend/scripts/setup-pm2.sh
  5. Test invoice link endpoints
  6. Test historical sync: npm run sync -- --from=50000 --to=50100