npm package: @rizzclub/platform
Description: Internal platform library for building RIZZ Chat Experiences with AI, Wallet integration, and persistent storage on Cloudflare Workers
Author: RizzClub
Latest version: 0.2.6

# @rizzclub/platform

> **Internal platform library for building RIZZ Chat Experiences**

**⚠️ Note**: This package is primarily for internal RizzClub use. While publicly available, it's designed specifically for our chat experience ecosystem and may have breaking changes between versions.

A unified platform library for building production-grade conversational experiences with AI capabilities, Solana wallet integration, scheduled tasks, and persistent storage. Works seamlessly across multiple messaging platforms (Telegram, WhatsApp, SMS, Web) in both production (Cloudflare Workers) and development (mock) environments.

[![npm version](https://img.shields.io/npm/v/@rizzclub/platform.svg)](https://www.npmjs.com/package/@rizzclub/platform)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features

- 🤖 **AI Integration**: Intelligent responses from Anthropic Claude, OpenAI GPT, or Google Gemini
- 💰 **Solana Wallet**: Accept payments, send withdrawals, and manage user wallets with Web3 support
- 📦 **KV Storage**: Persistent key-value storage for user data, conversation state, and configuration
- 🗄️ **Database**: Schemaless document store with MongoDB-like query syntax
- ⏰ **Scheduler**: Run tasks on schedules (cron) or one-time at specific times
- 🎨 **UGC System**: Sell packs, subscription feeds, and bundles with time-locked content
- 🆔 **Identity System**: Unified authentication with Google OAuth and rizzUserId
- 🌐 **Multi-Platform**: Telegram, WhatsApp, SMS, and Web chat experiences
- ⚡ **Cloudflare Native**: Optimized for Cloudflare Workers edge computing
- 🧪 **Mock Support**: In-memory implementations for local testing
- 📘 **TypeScript First**: Full type safety and IntelliSense support
- 🔄 **Unified API**: Same code works across all platforms and environments

## Supported Platforms

Build consistent chat experiences across:

- **Telegram** - Rich bot interactions with inline keyboards and media
- **WhatsApp** - Business messaging with templates and media support
- **SMS** - Text-based conversations and two-way messaging
- **Web** - Embedded chat widgets and web-based conversations

## Quick Start

### Installation

```bash
npm install @rizzclub/platform @rizzclub/channels
```

**Required Packages:**
- `@rizzclub/platform` - Platform services (KV, AI, Wallet, DB, Scheduler)
- `@rizzclub/channels` - Multi-platform bot framework (Telegram, WhatsApp, Web, SMS)

### Basic Example

```typescript
import { createBotHandler, TelegramAdapter } from '@rizzclub/channels';
import { createPlatform } from '@rizzclub/platform';

export default createBotHandler(async (bot, env) => {
  // Initialize platform with dependency injection
  const platform = createPlatform({ env });
  const { kv, ai, wallet } = platform.getServices();

  // Save user conversation state
  bot.command('start', async (ctx) => {
    await kv.put(`user:${ctx.from.id}`, {
      platform: 'telegram',
      username: ctx.from.username,
      conversationState: 'active'
    });
    await ctx.reply('👋 Welcome to RIZZ Chat Experience!');
  });

  // AI-powered conversation
  bot.on('message:text', async (ctx) => {
    const answer = await ai.ask(ctx.message.text, {
      provider: 'anthropic'
    });
    await ctx.reply(answer);
  });

  // Accept payments across platforms
  bot.command('pay', async (ctx) => {
    const paymentUrl = await wallet.generatePaymentToken(
      ctx.from.id.toString(),
      0.1, // 0.1 SOL
      'Premium access',
      env.BOT_ID
    );
    await ctx.reply(`💳 Pay here: ${paymentUrl}`);
  });
}, {
  '/': (env) => new TelegramAdapter({ token: env.BOT_TOKEN })
});
```

## Services

### 🤖 AI Service

Integrate conversational AI capabilities with support for multiple providers.

**Available Providers:**
- **Anthropic Claude** (claude-3-5-sonnet, claude-3-opus, etc.)
- **OpenAI GPT** (gpt-4, gpt-3.5-turbo, etc.)
- **Google Gemini** (gemini-pro, gemini-ultra, etc.)

**Example:**

```typescript
const { ai } = platform.getServices();

// Simple conversation
const answer = await ai.ask('How can I help you today?', {
  provider: 'anthropic',
  maxTokens: 500
});

// Advanced prompt with context
const response = await ai.prompt({
  prompt: 'Explain blockchain to a beginner',
  provider: 'openai',
  model: 'gpt-4',
  temperature: 0.7,
  maxTokens: 300
});

console.log(response.text);
console.log('Tokens used:', response.tokensUsed);
```

**Use Cases:**
- Natural conversation flow
- Customer support automation
- Content generation
- Question answering
- Multi-language support
- Personalized recommendations

### 💰 Wallet Service

Enable payment acceptance, withdrawals, and Web3 wallet management across all chat platforms.

**Features:**
- Accept SOL and SPL token payments
- Send withdrawals to user wallets
- Link/unlink Solana wallets
- Deposit fund management
- Transaction webhooks
- Cross-platform payment links

**Example:**

```typescript
import { TOKENS } from '@rizzclub/platform/wallet';

const { wallet } = platform.getServices();

// Request SOL payment
const solPaymentUrl = await wallet.generatePaymentToken(
  userId,
  1.5, // Amount in SOL
  'Premium subscription',
  botId
);

// Request USDC payment
const usdcPaymentUrl = await wallet.generatePaymentToken(
  userId,
  10, // Amount in USDC
  'Service fee',
  botId,
  undefined, // botName
  TOKENS.USDC.mint,
  TOKENS.USDC.symbol,
  TOKENS.USDC.decimals
);

// Get wallet info
const walletInfo = await wallet.getWallet(userId);
if (walletInfo) {
  console.log(`Balance: ${walletInfo.balance} SOL`);
  console.log(`Address: ${walletInfo.address}`);
}
```

**Supported Tokens:**
- **SOL** (native Solana)
- **USDC** (USD Coin)
- **USDT** (Tether)
- Custom SPL tokens

### 📦 KV Storage

Persistent key-value storage for conversation state, user preferences, and configuration.

**API:**

```typescript
const { kv } = platform.getServices();

// Store conversation state
await kv.put(`conversation:${userId}`, {
  platform: 'whatsapp',
  lastMessage: 'Hello',
  context: { topic: 'support', lang: 'en' }
});

// Store with expiration (session management)
await kv.put(`session:${sessionId}`, sessionData, {
  expirationTtl: 3600, // 1 hour
  metadata: { platform: 'web' }
});

// Retrieve state
const conversation = await kv.get(`conversation:${userId}`, 'json');

// List by prefix
const sessions = await kv.list({ prefix: 'session:', limit: 10 });
```

**Use Cases:**
- Conversation state management
- User preferences across platforms
- Session tracking
- Message history
- Cache frequently accessed data
- Platform-specific configurations

### 🗄️ Database Service

Schemaless document store for structured data with MongoDB-like queries.

**Example:**

```typescript
const { db } = platform.getServices();
const conversations = db.collection('conversations');

// Store conversation
await conversations.insert({
  userId: 'user123',
  platform: 'telegram',
  messages: [],
  metadata: {
    startedAt: Date.now(),
    language: 'en'
  }
});

// Query across platforms
const activeConvos = await conversations.find({
  'metadata.startedAt': { $gt: Date.now() - 86400000 }
});

// Update conversation
await conversations.update(
  { userId: 'user123' },
  { $push: { messages: newMessage } }
);
```

### ⏰ Scheduler Service

Schedule tasks for reminders, notifications, and recurring events across all platforms.

**Example:**

```typescript
const { scheduler } = platform.getServices();

// Schedule one-time reminder
await scheduler.scheduleTask({
  name: 'payment-reminder',
  webhookUrl: 'https://your-chat-bot.com/webhook/reminder',
  webhookSecret: env.WEBHOOK_SECRET,
  scheduledTime: new Date('2025-12-25T09:00:00Z'),
  metadata: { userId: 'user123', platform: 'whatsapp' }
});

// Schedule daily broadcast
await scheduler.scheduleTask({
  name: 'daily-updates',
  webhookUrl: 'https://your-chat-bot.com/webhook/broadcast',
  webhookSecret: env.WEBHOOK_SECRET,
  cron: '0 9 * * *', // Every day at 9 AM
  timezone: 'America/New_York'
});
```

**Use Cases:**
- Scheduled notifications
- Reminder systems
- Daily/weekly broadcasts
- Appointment confirmations
- Follow-up messages
- Time-based campaigns

### 📁 Assets Service

Store and serve files (images, videos, documents) via Cloudflare R2 with public CDN URLs.

**Example:**

```typescript
const { assets } = platform.getServices();

// Upload an image
const result = await assets.upload(
  'users/123/avatar.jpg',
  imageBuffer,
  { contentType: 'image/jpeg', metadata: { userId: '123' } }
);
console.log(result.url); // https://assets.rizz.club/users/123/avatar.jpg

// List files
const files = await assets.list({ prefix: 'users/123/', limit: 10 });

// Check if file exists
const exists = await assets.exists('users/123/avatar.jpg');

// Delete a file
await assets.delete('users/123/avatar.jpg');
```

**Use Cases:**
- User avatars and profile images
- Bot-generated content storage
- File uploads from chat
- Media galleries
- Document storage
- Temporary file hosting

### 🎨 UGC Service

Sell digital content with one-time packs, subscription feeds, and bundles with time-locked assets.

**Features:**
- **Packs**: One-time purchasable content collections
- **Feeds**: Subscription-based drip content with time-locked assets
- **Bundles**: Package deals combining packs and feeds
- **Time-locked Content**: Release assets on schedules (daily, weekly, monthly)
- **Ownership Tracking**: Manage user purchases and subscriptions

**Example:**

```typescript
const { ugc } = platform.getServices();

// Create a pack (one-time purchase)
const pack = await ugc.createPack({
  title: 'Premium Templates Pack',
  description: '50 professional templates',
  price: 0.5, // SOL
  currency: 'SOL',
  assets: [
    {
      type: 'image',
      url: 'https://cdn.example.com/template1.png',
      title: 'Business Template',
      metadata: { format: 'PNG', size: '1920x1080' }
    }
  ]
});

// Create a subscription feed (recurring content)
const feed = await ugc.createFeed({
  title: 'Daily Fitness Tips',
  description: 'New workout every day',
  tiers: [
    {
      name: 'Basic',
      price: 0.1,
      billingCycle: 'monthly',
      features: ['Daily tips', 'Weekly videos']
    }
  ],
  schedule: {
    frequency: 'daily',
    time: '09:00',
    timezone: 'America/New_York'
  }
});

// Add time-locked asset to feed
await ugc.addFeedAsset(feed.id, {
  type: 'video',
  url: 'https://cdn.example.com/workout.mp4',
  releaseDate: new Date('2025-11-01'),
  title: 'Advanced HIIT Workout'
});

// Check user's purchased packs
const userPacks = await ugc.getUserPacks(userId);

// Subscribe user to feed
await ugc.subscribeFeed(userId, feed.id, 'Basic');
```

**See full documentation:** [UGC.md](./UGC.md)

### 🆔 Identity Service

Unified authentication system with Google OAuth and universal user IDs (rizzUserId) across platforms.

**Features:**
- **Google OAuth**: Seamless sign-in with Google accounts
- **rizzUserId**: Universal user identifier across all platforms
- **White-labeled Auth**: Custom branding for authentication pages
- **Cross-Platform**: Link accounts across Telegram, WhatsApp, Web, SMS

**Example:**

```typescript
import { createPlatform } from '@rizzclub/platform';

const platform = createPlatform({ env, request, waitUntil: ctx.waitUntil });

// Generate OAuth login URL
const authUrl = `https://auth.rizz.club/?client=${env.BOT_ID}&redirect=${callbackUrl}`;
await ctx.reply(`🔐 Sign in: ${authUrl}`);

// Handle OAuth callback (after user signs in)
const urlParams = new URL(request.url).searchParams;
if (urlParams.get('auth') === 'success') {
  const rizzUserId = urlParams.get('rizzUserId'); // Universal user ID
  const email = urlParams.get('email');
  const name = urlParams.get('name');
  const picture = urlParams.get('picture');

  // Store user info with rizzUserId
  await kv.put(`user:${rizzUserId}`, {
    email,
    name,
    picture,
    platforms: {
      telegram: ctx.from.id,
      web: rizzUserId
    }
  });
}

// Use rizzUserId for cross-platform data
const userData = await kv.get(`user:${rizzUserId}`, 'json');
```

**Key Concepts:**
- **rizzUserId**: Unique identifier that remains constant across all platforms
- **White-labeled**: Auth pages display your bot's logo, name, and colors
- **Centralized**: Single authentication endpoint for all your bots

**See full documentation:** [auth/README.md](../rizzinfra/auth/README.md)

## Configuration

### Production Setup (Cloudflare Workers)

**wrangler.jsonc:**

```json
{
  "name": "my-chat-experience",
  "main": "src/index.ts",
  "compatibility_date": "2024-01-01",
  "kv_namespaces": [
    {
      "binding": "KV_NAMESPACE",
      "id": "your-kv-namespace-id"
    }
  ],
  "vars": {
    "BOT_TOKEN": "your-bot-token",
    "BOT_ID": "my-chat-bot"
  },
  "secrets": {
    "RIZZCLUB_API_KEY": "Get from https://rizz.club"
  }
}
```

**Environment Variables:**
- `BOT_TOKEN` - Your messaging platform token (required)
- `BOT_ID` - Unique identifier for your chat experience (required)
- `RIZZCLUB_API_KEY` - API key for AI, Wallet, and Scheduler services
- `KV_NAMESPACE` - Cloudflare KV namespace binding (auto-injected)

### Development/Testing

```typescript
const platform = createPlatform(
  {
    env: {
      BOT_TOKEN: 'test-token',
      BOT_ID: 'test-bot',
      RIZZCLUB_API_KEY: 'test-key'
    },
    request: mockRequest,
    waitUntil: () => {}
  },
  {
    mock: true,
    debug: true
  }
);
```

## Complete Examples

### Multi-Platform AI Assistant

```typescript
import { createBotHandler, TelegramAdapter } from '@rizzclub/channels';
import { createPlatform } from '@rizzclub/platform';

export default createBotHandler(async (bot, env) => {
  // Initialize platform with dependency injection
  const platform = createPlatform({ env });
  const { ai, kv } = platform.getServices();

  bot.command('start', async (ctx) => {
    await kv.put(`user:${ctx.from.id}`, {
      platform: 'telegram',
      preferences: { language: 'en' }
    });
    await ctx.reply('👋 Welcome! Ask me anything!');
  });

  bot.on('message:text', async (ctx) => {
    try {
      // Get conversation context
      const context = await kv.get(`conversation:${ctx.from.id}`, 'json') || [];

      // Get AI response with context
      const answer = await ai.ask(ctx.message.text, {
        provider: 'anthropic',
        maxTokens: 500
      });

      // Save conversation
      context.push({
        question: ctx.message.text,
        answer,
        timestamp: Date.now()
      });
      await kv.put(`conversation:${ctx.from.id}`, context.slice(-10));

      await ctx.reply(answer);
    } catch (error) {
      await ctx.reply('❌ Sorry, I encountered an error. Please try again.');
    }
  });
}, {
  '/': (env) => new TelegramAdapter({ token: env.BOT_TOKEN })
});
```

### Cross-Platform Payment System

```typescript
import { createBotHandler, TelegramAdapter } from '@rizzclub/channels';
import { createPlatform } from '@rizzclub/platform';
import { TOKENS } from '@rizzclub/platform/wallet';

export default createBotHandler(async (bot, env) => {
  // Initialize platform with dependency injection
  const platform = createPlatform({ env });
  const { wallet, kv } = platform.getServices();

  bot.command('link', async (ctx) => {
    const linkUrl = await wallet.generateLinkToken(
      ctx.from.id.toString(),
      env.BOT_ID,
      'RIZZ Chat'
    );
    await ctx.reply(`🔗 Link your wallet:\n${linkUrl}`);
  });

  bot.command('balance', async (ctx) => {
    const walletInfo = await wallet.getWallet(ctx.from.id.toString());
    if (!walletInfo) {
      await ctx.reply('❌ No wallet linked. Use /link first.');
      return;
    }

    await ctx.reply(
      `💰 Your Balance:\n` +
      `SOL: ${walletInfo.balance}\n` +
      `Address: ${walletInfo.address.slice(0, 8)}...`
    );
  });

  bot.command('premium', async (ctx) => {
    const paymentUrl = await wallet.generatePaymentToken(
      ctx.from.id.toString(),
      0.1, // 0.1 SOL
      'Premium Chat Features',
      env.BOT_ID
    );

    await ctx.reply(
      `✨ Upgrade to Premium\n\n` +
      `Features:\n` +
      `• Unlimited AI conversations\n` +
      `• Priority support\n` +
      `• Cross-platform sync\n\n` +
      `Pay: ${paymentUrl}`
    );
  });
}, {
  '/': (env) => new TelegramAdapter({ token: env.BOT_TOKEN }),
  '/webhook/payment': async (env, request) => {
    // Handle payment webhook
    const platform = createPlatform({ env });
    const { kv } = platform.getServices();
    const payload = await request.json();

    if (payload.status === 'completed') {
      const user = await kv.get(`user:${payload.userId}`, 'json') || {};
      user.premium = true;
      await kv.put(`user:${payload.userId}`, user);

      // Send notification via Telegram adapter
      const bot = new TelegramAdapter({ token: env.BOT_TOKEN });
      await bot.sendMessage(payload.userId, '🎉 Premium activated!');
    }

    return new Response('OK', { status: 200 });
  }
});
```

### Scheduled Multi-Platform Broadcasts

```typescript
import { createBotHandler, TelegramAdapter } from '@rizzclub/channels';
import { createPlatform } from '@rizzclub/platform';

export default createBotHandler(async (bot, env) => {
  // Initialize platform with dependency injection
  const platform = createPlatform({ env });
  const { scheduler, db } = platform.getServices();
  const users = db.collection('users');

  bot.command('subscribe', async (ctx) => {
    await users.insert({
      userId: ctx.from.id.toString(),
      platform: 'telegram',
      subscribed: true,
      preferences: { updates: true }
    });

    // Schedule daily updates
    await scheduler.scheduleTask({
      name: `daily-${ctx.from.id}`,
      webhookUrl: `${env.BOT_URL}/webhook/daily`,
      webhookSecret: env.WEBHOOK_SECRET,
      cron: '0 9 * * *', // 9 AM daily
      metadata: { userId: ctx.from.id }
    });

    await ctx.reply('✅ Subscribed to daily updates!');
  });
}, {
  '/': (env) => new TelegramAdapter({ token: env.BOT_TOKEN }),
  '/webhook/daily': async (env, request) => {
    // Handle daily broadcast webhook
    const platform = createPlatform({ env });
    const { db } = platform.getServices();
    const users = db.collection('users');
    const allUsers = await users.find({ subscribed: true });

    const bot = new TelegramAdapter({ token: env.BOT_TOKEN });
    for (const user of allUsers) {
      await bot.sendMessage(user.userId, '📰 Your daily update!');
    }

    return new Response('OK', { status: 200 });
  }
});
```

## API Reference

### Platform Initialization

```typescript
createPlatform(context: PlatformContext, options?: PlatformOptions): RizzClubPlatform
```

**PlatformContext:**
```typescript
interface PlatformContext {
  env: {
    BOT_TOKEN: string;
    BOT_ID?: string;
    RIZZCLUB_API_KEY?: string;
    KV_NAMESPACE?: KVNamespace;
  };
  request: Request;
  waitUntil: (promise: Promise<any>) => void;
}
```

**PlatformOptions:**
```typescript
interface PlatformOptions {
  mock?: boolean;        // Use mock implementations
  debug?: boolean;       // Enable debug logging
  apiKey?: string;       // Override API key
  sessionToken?: string; // For mock mode with auth
}
```

### Platform Types

The platform field supports:
- `'telegram'` - Telegram messaging
- `'whatsapp'` - WhatsApp Business
- `'sms'` - SMS messaging
- `'web'` - Web chat experiences

## TypeScript Support

Full TypeScript support with complete type definitions:

```typescript
import type {
  PlatformServices,
  PlatformContext,
  PlatformOptions,
  Platform,
  KVStorage,
  AIService,
  WalletService,
  DBService,
  SchedulerService,
  PromptRequest,
  PromptResponse,
  WalletInfo,
  TokenInfo,
  ScheduledTask
} from '@rizzclub/platform';
```

## Development

### Building

```bash
npm run build     # Compile TypeScript
npm run dev       # Watch mode
npm run clean     # Clean dist/
```

### Testing

```bash
npm run type-check  # TypeScript validation
```

## Troubleshooting

**"RIZZCLUB_API_KEY not configured"**
- Get your API key from https://rizz.club
- Add it to your wrangler.jsonc secrets

**"KV_NAMESPACE not found"**
- Create a KV namespace: `npx wrangler kv:namespace create KV_NAMESPACE`
- Add the binding to wrangler.jsonc

**"Mock mode not working"**
- Pass `{ mock: true }` in options
- Check that you're using the development environment

## Roadmap

### Current (v0.0.3)
- ✅ Multi-platform support (Telegram, WhatsApp, SMS, Web)
- ✅ KV Storage
- ✅ AI Service (Anthropic, OpenAI, Gemini)
- ✅ Wallet Service (SOL + SPL tokens)
- ✅ Database Service (MongoDB-like)
- ✅ Scheduler Service (cron + one-time)
- ✅ Mock implementations
- ✅ TypeScript support

### Future
- 📧 Email notifications
- 📊 Analytics and metrics
- 🔐 Enhanced authentication
- 🌐 Multi-chain wallet support
- 📱 Push notifications
- 🎨 Rich media handling
- 🔄 Cross-platform conversation sync

## Connect

- 🌐 [Website](https://rizz.club)
- 🐦 [Twitter](https://twitter.com/rizzclub)
- 💬 [Telegram](https://t.me/rizzclub)

## License

MIT © RizzClub

---

**Built with ❤️ for the conversational AI community**