From b18a010208f097ec7152c622d4ed57944e80dc74 Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Thu, 26 Feb 2026 15:46:50 -0800 Subject: [PATCH] Update readme --- README.md | 201 ++---------------------------------------------------- 1 file changed, 4 insertions(+), 197 deletions(-) diff --git a/README.md b/README.md index 26e5b0e..c9c8edd 100644 --- a/README.md +++ b/README.md @@ -1,201 +1,8 @@ # Caravel -A multi-tenant platform for hosting Nostr community relays, built on top of [zooid](./ref/zooid) — a multi-tenant relay implementation configured via TOML and an HTTP API. +A multi-tenant platform for hosting Nostr community relays, built on top of [zooid](https://github.com/coracle-social/zooid). ---- +## Project docs -## Overview - -The platform has three main components: - -1. **Backend** — Manages the zooid instance via its HTTP API, along with tenants (users), virtual relays, invoices, and billing. -2. **Tenant Dashboard** — A web app where anyone can sign up, pay for a relay via Lightning, and manage their relay's membership, metadata, access, and policies. -3. **Super Admin Dashboard** — A restricted interface for the infrastructure owner to manage tenants and their relays. - -A proof of concept exists in [`ref/metamanager`](./ref/metamanager) (backend) and [`ref/website`](./ref/website) (frontend). Zooid is included for reference in ./ref/zooid. - ---- - -## Tech Stack - -**Frontend** -- Bun -- TypeScript -- SolidJS -- Preline UI -- https://applesauce.build/ -- tanstack tools where relevant - -**Backend** -- Rust -- Sqlite - ---- - -## Database Schema - -### `tenants` -Users of the platform. Identified by their Nostr public key. - -| Field | Description | -|---|---| -| `pubkey` | Primary key — Nostr public key | -| `status` | Account status (active, suspended, etc.) | -| `tenant_nwc_url` | Tenant-provided NWC URL for recurring billing | - -### `relays` -Virtual relays linked to a tenant. - -| Field | Description | -|---|---| -| `id` | Primary key | -| `tenant` | Foreign key → tenants | -| `name` | Human-readable relay name | -| `subdomain` | Subdomain slug (e.g. `my-relay` → `my-relay.spaces.coracle.social`) | -| `schema` | zooid DB schema name (subdomain with dashes replaced by underscores; stored for reference only) | -| `icon` | Relay icon URL | -| `description` | Relay description | -| `plan` | Pricing tier: `free`, `basic`, or `growth` | -| `status` | Relay status (pending, active, suspended, etc.) | - -### `invoices` -Invoices generated for tenants, potentially covering multiple relays in a single payment. - -| Field | Description | -|---|---| -| `id` | Primary key | -| `tenant` | Foreign key → tenants | -| `amount` | Total invoice amount (sats) | -| `status` | Payment status (pending, paid, expired, etc.) | -| `created_at` | Timestamp | -| `invoice` | Lightning invoice string | - -### `invoice_items` -Line items linking an invoice to a specific relay charge. - -| Field | Description | -|---|---| -| `id` | Primary key | -| `invoice` | Foreign key → invoices | -| `relay` | Foreign key → relays | -| `amount` | Amount for this relay (sats) | -| `period_start` | Start of billing period | -| `period_end` | End of billing period | - ---- - -## Pricing Tiers - -| Tier | Price | Members | Blossom | LiveKit | -|---|---|---|---|---| -| **Free** | 0 sats/mo | Up to 10 | No | No | -| **Basic** | 10,000 sats/mo | Up to 100 | Yes | Yes | -| **Growth** | 50,000 sats/mo | Unlimited | Yes | Yes | - ---- - -## Backend - -> Do not modify zooid directly. All relay management goes through its HTTP API (`zooid/api.go`). - -### Authentication - -- All endpoints are authenticated using NIP 98 - -### Responsibilities -- Manage zooid virtual relays via the HTTP API -- Tenant and relay CRUD -- Lightning invoice generation and collection -- Billing: recurring charges, grace periods, NIP-17 DM notifications -- Async job runner for billing checks, invoice collection, and relay provisioning - -### Relay Provisioning -When a relay is created, an async worker is spawned that sends the appropriate API request to zooid to set up the virtual relay. Status updates to `active` on success and `provisioning_failed` on error. - -### Billing Logic -- Billing is monthly. Invoices batch all of a tenant's relay charges into a single payment. -- Tenants can enable **recurring billing** by providing their own NWC URL on the account page. The platform uses this to pull payments automatically. -- If recurring billing is off, invoices are sent via **NIP-17 DMs** (from the platform's Nostr key) when a subscription is due. If recurring billing is on, still send notifications when a payment is made. -- A **7-day grace period** applies before access is restricted for non-payment. - -### Environment Variables -| Variable | Description | -|---|---| -| `PLATFORM_ADMIN_PUBKEYS` | Comma-separated Nostr pubkeys with super admin access | -| `PLATFORM_SECRET` | Nostr private key used by the platform to send NIP-17 DMs | -| `NWC_URL` | Nostr Wallet Connect URL used by the platform to generate Lightning invoices | -| `NOSTR_INDEXER_RELAYS` | Relays used to fetch kind `10050` DM relay lists | -| `PLATFORM_NAME` | Platform display name (published as kind `0`) | -| `PLATFORM_DESCRIPTION` | Platform description (published as kind `0`) | -| `PLATFORM_PICTURE` | Platform picture URL (published as kind `0`) | -| `PLATFORM_MESSAGING_RELAYS` | Relays published in kind `10050` for DMs | - ---- - -## Frontend - -### Marketing Page (`/`) -- Describes the value proposition, features, and brand -- Prominent **"Get Started"** button linking to the new relay form -- A "Log In" button, replaced by a "Dashboard" button when the user is logged in - - -### Login Page (`/login`) -- Uses nonboard to log the user in - -### Tenant dashboard -- All requests are authenticated using NIP 98 against the tenant pubkey - -#### Relays Page (`/relays`) -- **My Relays** — searchable, filterable list of the user's relays -- **Add Relay** button (top right) -- Link to account page - -#### Relay Detail Page (`/relays/{id}`) -- Shows relay information (name, url, description, plan) -- Actions: edit relay, deactivate - -### New Relay Form (`/relays/new`) -- Requires Nostr login (via the `nonboard` plugin — see [`ref/website`](./ref/website)); the NIP-98 auth token is used to identify the tenant -- Fields: - - Relay name - - Subdomain (auto-generated from name, editable; displayed as `.spaces.coracle.social`) - - Icon URL - - Description - - Plan selection — shown as a comparison table (see Pricing Tiers) -- On submit (if plan is not free): generates a Lightning invoice - - User can scan QR code, click to open in wallet, or copy invoice string - - **"I've paid the invoice"** button — checks invoice status and reports to user - - On confirmed payment: redirect to tenant dashboard - -### Account Page (`/account`) -- Account status -- Complete invoice history -- Toggle for recurring billing via Nostr Wallet Connect (tenant provides their own NWC URL) - -### Super Admin Dashboard (`/admin`) -- Authenticated via NIP-98 against `PLATFORM_ADMIN_PUBKEYS` -- No link to this page from any other page - -#### Tenants Page (`/admin/tenants`) -- Searchable, filterable list of all tenants - -#### Tenant Detail Page (`/admin/tenants/{id}`) -- All their relays -- Account status -- Actions: deactivate tenant and all their relays - -#### Relays Page (`/admin/relays`) -- Searchable, filterable list of all relays -- Link to owning tenant -- Actions: update or deactivate any relay - -#### Relay Detail Page (`/admin/relays/{id}`) -- Show relay information -- Actions: edit or deactivate relay - -#### Relay Edit Form (`/admin/relays/{id}/edit`) -- Edit relay name, subdomain, icon, description, and plan - -### Relay Edit Form (`/relays/{id}/edit`) -- Edit relay name, subdomain, icon, description, and plan +- Frontend: [frontend/README.md](./frontend/README.md) +- Backend: [backend/README.md](./backend/README.md)