Skip to main content

SuperSkin Platform Services - Build Strategy

Executive Summary

This document outlines how to build SuperSkin platform features that integrate with smartbets-protocol from day 1.

Constraints:

  • ❌ Cannot modify smartbets-protocol code
  • ❌ Cannot modify gta-frontend code
  • ✅ Can consume smartbets-protocol APIs (read-only)
  • ✅ Share JWT secret for token validation
  • ✅ Use local PostgreSQL for SuperSkin-owned data

Approach: Direct integration - no mock modes, production-ready from the start.


Available smartbets-protocol APIs (Read-Only)

Based on codebase analysis, these APIs are available for SuperSkin to consume:

Authentication

EndpointMethodDescription
/api/auth/profileGETGet current user profile
JWT Token-Contains: id, walletAddress, role, permissions, wallets[]

User Data

EndpointMethodDescription
/api/users/balanceGETAvailable/locked balance, deposits, withdrawals
/api/users/positionsGETOpen positions with P&L
/api/users/betsGETBetting history with pagination

Portfolio & Analytics

EndpointMethodDescription
/api/portfolio/summaryGETTotal bets, win rate, P&L, claimable
/api/portfolio/activeGETActive bets with market details
/api/portfolio/settledGETSettled bets with results
/api/analytics/summaryGETPerformance metrics by timeframe
/api/analytics/chartGETChart data for P&L over time

Sessions

EndpointMethodDescription
/api/sessionsGETAll active sessions
/api/sessions/currentGETCurrent session details

Architecture Overview


Implementation Strategy

SmartbetsClient - User Data Access

A simple HTTP client that fetches user data from smartbets-protocol:

// clients/SmartbetsClient.ts
class SmartbetsClient {
private baseUrl: string;
private jwtSecret: string;

constructor() {
this.baseUrl = process.env.SMARTBETS_API_URL;
this.jwtSecret = process.env.JWT_SECRET; // Shared with smartbets-protocol
}

// Validate JWT locally (same secret as smartbets-protocol)
validateToken(token: string): TokenPayload {
return jwt.verify(token, this.jwtSecret, {
issuer: 'forsyt',
audience: 'forsyt-users'
});
}

// Fetch user data from smartbets-protocol
async getUserBalance(token: string): Promise<UserBalance> {
const response = await fetch(`${this.baseUrl}/api/users/balance`, {
headers: { Authorization: `Bearer ${token}` }
});
return response.json();
}

async getOpenPositions(token: string): Promise<Position[]> {
const response = await fetch(`${this.baseUrl}/api/users/positions`, {
headers: { Authorization: `Bearer ${token}` }
});
return response.json();
}

async getPortfolio(token: string): Promise<PortfolioSummary> {
const response = await fetch(`${this.baseUrl}/api/portfolio/summary`, {
headers: { Authorization: `Bearer ${token}` }
});
return response.json();
}
}

Data Ownership

SuperSkin Owns (Local PostgreSQL)

FeatureTables
Watchlistswatchlists, watchlist_items
Alertsalerts, alert_triggers, notifications
Strategiesstrategies, strategy_rules
Chatchat_sessions, chat_messages
Preferencesuser_preferences

Fetched from smartbets-protocol (Read-Only)

DataEndpoint
User Profile/api/auth/profile
Balance/api/users/balance
Positions/api/users/positions
Bets/api/users/bets
Portfolio/api/portfolio/*
Analytics/api/analytics/*

Database Schema

The superskin database stores SuperSkin-owned data. User identifiers (user_id) are UUIDs from smartbets-protocol JWT tokens - no user table needed.

-- Create database (add to docker-compose init)
CREATE DATABASE superskin;

-- Watchlists
CREATE TABLE watchlists (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL, -- From JWT token
name VARCHAR(100) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE watchlist_items (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
watchlist_id UUID REFERENCES watchlists(id) ON DELETE CASCADE,
market_id VARCHAR(100) NOT NULL,
added_at TIMESTAMPTZ DEFAULT NOW()
);

-- Alerts
CREATE TABLE alerts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
market_id VARCHAR(100) NOT NULL,
condition JSONB NOT NULL,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Chat History
CREATE TABLE chat_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE chat_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID REFERENCES chat_sessions(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Indexes
CREATE INDEX idx_watchlists_user ON watchlists(user_id);
CREATE INDEX idx_alerts_user ON alerts(user_id);
CREATE INDEX idx_chat_sessions_user ON chat_sessions(user_id);

Project Structure

services/superskin-platform/
├── src/
│ ├── clients/
│ │ └── SmartbetsClient.ts # HTTP client for smartbets-protocol
│ │
│ ├── services/
│ │ ├── WatchlistService.ts
│ │ ├── AlertService.ts
│ │ ├── StrategyService.ts
│ │ └── UserContextService.ts
│ │
│ ├── routes/
│ │ ├── watchlist.ts
│ │ ├── alerts.ts
│ │ └── context.ts
│ │
│ ├── middleware/
│ │ └── auth.ts # JWT validation
│ │
│ └── db/
│ └── postgres.ts # PostgreSQL connection

├── Dockerfile
└── package.json

Service Dependencies


JWT Token Flow

SuperSkin services validate JWT tokens using the same secret as smartbets-protocol:


Environment Configuration

# .env for superskin-platform
JWT_SECRET=your-shared-secret # Same as smartbets-protocol
SMARTBETS_API_URL=http://localhost:3001 # smartbets-protocol URL
DATABASE_URL=postgresql://superskin:dev@localhost:5433/superskin
REDIS_URL=redis://localhost:6380

Alert Flow Example


AI Chat Context Example


Implementation Checklist

Week 1-2: Foundation

  • Create superskin-platform service
  • Set up PostgreSQL schema
  • Implement SmartbetsClient
  • JWT validation middleware
  • Basic health endpoints

Week 3-4: Core Features

  • WatchlistService + CRUD endpoints
  • AlertService + CRUD endpoints
  • Alert evaluation engine
  • Integration with ai-chat-assistant

Week 5-6: Advanced

  • StrategyService
  • ChatContextService
  • WebSocket real-time updates

Docker Compose Addition

Add to docker-compose.yml:

  # PostgreSQL for SuperSkin data (separate from TimescaleDB)
superskin-db:
image: postgres:15-alpine
container_name: superskin-db
environment:
POSTGRES_DB: superskin
POSTGRES_USER: superskin
POSTGRES_PASSWORD: superskin_dev
ports:
- "5434:5432"
volumes:
- superskin_data:/var/lib/postgresql/data
- ./infrastructure/init-superskin.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U superskin -d superskin"]
interval: 10s
timeout: 5s
retries: 5

# SuperSkin Platform Service
superskin-platform:
build:
context: ./services/superskin-platform
dockerfile: Dockerfile
container_name: superskin-platform
environment:
NODE_ENV: development
DATABASE_URL: postgresql://superskin:superskin_dev@superskin-db:5432/superskin
REDIS_URL: redis://redis:6379
SMARTBETS_API_URL: ${SMARTBETS_API_URL:-http://localhost:3001}
JWT_SECRET: ${JWT_SECRET}
ports:
- "3106:3106"
depends_on:
superskin-db:
condition: service_healthy
redis:
condition: service_healthy

volumes:
superskin_data:

Next Steps

  1. Create services/superskin-platform/ service scaffold
  2. Create infrastructure/init-superskin.sql with schema
  3. Implement SmartbetsClient
  4. Build WatchlistService and AlertService
  5. Integrate with ai-chat-assistant for context enrichment