npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rizzclub/platform

v0.2.6

Published

Internal platform library for building RIZZ Chat Experiences with AI, Wallet integration, and persistent storage on Cloudflare Workers

Readme

@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 TypeScript License: 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

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

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:

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:

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:

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:

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:

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:

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:

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

🆔 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:

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

Configuration

Production Setup (Cloudflare Workers)

wrangler.jsonc:

{
  "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

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

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

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

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

createPlatform(context: PlatformContext, options?: PlatformOptions): RizzClubPlatform

PlatformContext:

interface PlatformContext {
  env: {
    BOT_TOKEN: string;
    BOT_ID?: string;
    RIZZCLUB_API_KEY?: string;
    KV_NAMESPACE?: KVNamespace;
  };
  request: Request;
  waitUntil: (promise: Promise<any>) => void;
}

PlatformOptions:

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:

import type {
  PlatformServices,
  PlatformContext,
  PlatformOptions,
  Platform,
  KVStorage,
  AIService,
  WalletService,
  DBService,
  SchedulerService,
  PromptRequest,
  PromptResponse,
  WalletInfo,
  TokenInfo,
  ScheduledTask
} from '@rizzclub/platform';

Development

Building

npm run build     # Compile TypeScript
npm run dev       # Watch mode
npm run clean     # Clean dist/

Testing

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

License

MIT © RizzClub


Built with ❤️ for the conversational AI community