@ryopc/koshi
v3.0.0
Published
Terminal-native P2P decentralized SNS — serverless koshi board v3
Maintainers
Readme
🏄 koshi — Terminal-Native Decentralized SNS
Version 2.0.2 · MIT License · by game_ryo
A terminal-native, decentralized social network powered by ed25519 cryptography.
✨ Features
v2.0.2 — バグ修正・安定性向上 🎉
- 🔐 Decentralized Auth — ed25519 keypair authentication (Nostr-inspired)
- 📝 Posts — Create and view posts on the koshi board
- 👥 Follow System — Follow/unfollow other users
- ✉️ Direct Messages — Signed, private DMs
- 💬 Real-time Chat — Interactive DM chat via WebSocket
- 📡 Real-time Feed — WebSocket-powered live updates
- ✏️ Profile Editing — Update your display name, bio, and avatar
- 🛠️ Admin Controls — User management, account deletion, admin grants
- 💻 Terminal-native — Beautiful CLI with chalk colors and spinners
🆕 New in v2.0
- 🔑 Nostr Protocol Integration — Generate/manage Nostr keys (nsec/npub), push koshi posts to Nostr relays, pull events from the Nostr network, manage relay connections
- 🖧 P2P Sync (hypercore) — Peer-to-peer data synchronization using hypercore + corestore + hyperswarm. Posts and DMs replicated across connected peers
- 👥 Multi-Account Support — Manage multiple koshi identities from a single CLI. Switch between accounts with
kb switch, interactive login, account removal - ⚙️ Enhanced Config — All credentials stored in
~/.config/koshi/config.jsonwith support for per-account Nostr keys and P2P settings
📋 Table of Contents
🚀 Quick Start
# 1. Start the server (requires PostgreSQL)
DATABASE_URL=postgresql://user:pass@localhost:5432/koshi \
JWT_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))") \
node bin/server.js
# 2. Register a new account
kb register alice
# 3. Post to the koshi board
kb post "Hello, koshi! 🌊"
# 4. View your feed
kb feed
# 5. Start the real-time stream
kb realtime📦 Installation
Global Install (CLI only)
# From npm (coming soon)
npm install -g @ryopc/koshi
# Or from source
git clone https://github.com/ryopc/koshi.git
cd koshi
npm install
npm linkDependencies
- Node.js >= 18.0.0
- PostgreSQL >= 15.0 (hosted on Neon.tech in production)
💻 CLI Usage
The kb command is your gateway to the koshi board.
Commands
| Command | Description |
|---------|-------------|
| kb register <username> | Create a new account with ed25519 keypair |
| kb login <username> | Authenticate using existing keypair |
| kb whoami | Show your profile information |
| kb post <message> | Create a new post on the koshi board |
| kb feed [--limit=20] | Display your post feed |
| kb follow <username> | Follow a user |
| kb unfollow <username> | Unfollow a user |
| kb dm <username> <message> | Send a direct message |
| kb dms [--unread] | View your direct messages |
| kb chat <username> | Start an interactive real-time DM chat |
| kb edit-profile --display-name=... --bio=... | Update your own profile |
| kb profile [username] | View a user profile |
| kb search <query> | Search users by username |
| kb realtime | Connect to the real-time event stream |
| kb admin <command> | Admin commands (users, delete-user, grant, revoke) |
| kb help [command] | Show help |
Examples
# Register a new user
kb register alice
# Login with existing keys
kb login alice
# Post something
kb post "Just joined koshi! 🌊"
# View feed
kb feed --limit=30
# Follow someone
kb follow bob
# Send a DM
kb dm bob "Hey, how's it going?"
# Start an interactive real-time DM chat
kb chat bob
# Edit your profile
kb edit-profile --display-name="Alice" --bio="Building the terminal future"
# Search for users
kb search alice
# Live stream
kb realtime
# Admin: list all users
kb admin users
# Admin: delete a user account (requires confirmation)
kb admin delete-user bob
# Admin: grant admin privileges
kb admin grant aliceConfiguration
Credentials are stored in ~/.config/koshi/config.json and ~/.snsrc.
Environment variables:
| Variable | Default | Description |
|----------|---------|-------------|
| KOSHI_API_URL | https://koshi-api.ryopc.f5.si | API base URL |
| KOSHI_WS_URL | wss://koshi-api.ryopc.f5.si | WebSocket URL |
🖥️ Server Setup
Local Development
# 1. Clone and install
git clone https://github.com/ryopc/koshi.git
cd koshi
npm install
# 2. Set up PostgreSQL database
createdb koshi
# 3. Run database migrations
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/koshi \
JWT_SECRET=dev-secret-change-in-production \
node src/db/migrate.js
# 4. Start the server
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/koshi \
JWT_SECRET=dev-secret-change-in-production \
node bin/server.jsOr use the .env file:
cp .env.example .env
# Edit .env with your database credentials
npm run migrate
npm startEnvironment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| DATABASE_URL | ✅ | PostgreSQL connection string |
| JWT_SECRET | ✅ | Secret key for JWT signing |
| PORT | ❌ | Server port (default: 3000) |
| NODE_ENV | ❌ | development or production |
| LOG_LEVEL | ❌ | Log level (default: debug in dev, info in prod) |
📡 API Reference
Base URL
Development: http://localhost:3000/api
Production: https://koshi-api.ryopc.f5.si/api
Authentication
All authenticated endpoints require a JWT Bearer token:
Authorization: Bearer <token>Endpoints
Auth
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | /api/auth/register | No | Register a new user |
| POST | /api/auth/login | No | Login with signature |
Users
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/users/:username | No | Get user profile |
| PUT | /api/users/me | Yes | Update own profile |
| GET | /api/users/:id/followers | No | Get followers |
| GET | /api/users/:id/following | No | Get following |
| POST | /api/users/:id/follow | Yes | Follow a user |
| DELETE | /api/users/:id/follow | Yes | Unfollow a user |
| GET | /api/users/search/:query | No | Search users |
Posts
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/posts/feed | Optional | Get post feed |
| POST | /api/posts | Yes | Create a post |
| GET | /api/posts/:id | No | Get a single post |
DMs
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/dms | Yes | Get DM inbox |
| POST | /api/dms/:userId | Yes | Send a DM |
| PUT | /api/dms/:id/read | Yes | Mark DM as read |
| GET | /api/dms/unread/count | Yes | Count unread DMs |
Admin
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/admin/users | Admin | List all users |
| GET | /api/admin/users/:id | Admin | Get user details (with keys, DM count) |
| DELETE | /api/admin/users/:id | Admin | Permanently delete a user account |
| PUT | /api/admin/users/:id/admin | Admin | Grant or revoke admin privileges |
Admin privileges: Set
ADMIN_USERNAMEenvironment variable, or mark user as admin viaUPDATE users SET is_admin = TRUE WHERE username = '...';
WebSocket
Connect: ws://host:port/ws?token={jwt}
Events: message_sent, dm_received, user_online, user_offline, post_created, follow_notification
Health
| Method | Path | Description |
|--------|------|-------------|
| GET | /api/health | Health check |
☁️ Deployment
Render.com + Neon.tech (Recommended)
1. Set up Neon.tech Database
- Go to Neon.tech and create an account
- Create a new project (PostgreSQL 15)
- Get your connection string from Connection Details →
DATABASE_URL - For production, use the pooled connection string (with
?pgbouncer=true)
2. Deploy on Render.com
- Push this repo to GitHub
- Go to Render.com and connect your GitHub repo
- Render will auto-detect
render.yaml(Blueprint) and create the service - In Render dashboard, add environment variables:
DATABASE_URL— your Neon.tech connection stringJWT_SECRET— generate with:node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
- Render will auto-deploy on every push to
main
Alternative: Manual Setup on Render
If you prefer not to use Blueprint:
- Create a new Web Service on Render
- Connect your GitHub repo
- Configure:
- Name:
koshi-api - Environment:
Node - Build Command:
npm ci - Start Command:
node bin/server.js - Health Check Path:
/api/health - Pre-Deploy Command:
node src/db/migrate.js
- Name:
- Add environment variables (see above)
- Deploy!
Docker
# Build the image
docker build -t koshi-api .
# Run the container
docker run -d \
--name koshi-api \
-p 3000:3000 \
-e DATABASE_URL=postgresql://... \
-e JWT_SECRET=... \
koshi-apiDocker Compose
version: '3.8'
services:
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: koshi
POSTGRES_PASSWORD: postgres
volumes:
- pgdata:/var/lib/postgresql/data
api:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:postgres@db:5432/koshi
JWT_SECRET: change-this-in-production
depends_on:
- db
volumes:
pgdata:🔒 Security
- Ed25519 Signatures — All posts and DMs are signed for authenticity
- JWT Auth — Tokens expire after 24 hours
- Admin Auth — Admin-only endpoints protected by
requireAdminmiddleware - Rate Limiting — Auth endpoints limited to 10 req/min per IP
- SQL Injection Prevention — Parameterized queries throughout
- Input Validation — All endpoints validate input
- Helmet — Security headers enabled
- No Hardcoded Secrets — Everything via environment variables
- CORS — Restricted to CLI client origins
🧪 Development
# Run tests
npm test
# Run linter
npm run lint
# Run with auto-reload
npm run dev
# Run migration
npm run migrateProject Structure
koshi/
├── bin/
│ ├── cli.js # CLI/TUI entry point
│ └── server.js # Express + WebSocket server
├── src/
│ ├── api/
│ │ ├── auth.js # Auth routes (register/login)
│ │ ├── users.js # User management routes
│ │ ├── posts.js # Posts routes (koshi board)
│ │ ├── dms.js # Direct messages routes
│ │ └── admin.js # Admin routes (users, delete, grant)
│ ├── auth/
│ │ ├── ed25519.js # Ed25519 crypto utilities
│ │ ├── jwt.js # JWT token utilities
│ │ └── utils.js # Hex encoding utilities
│ ├── db/
│ │ ├── schema.sql # PostgreSQL schema
│ │ ├── migrate.js # Migration script
│ │ └── pool.js # Database connection pool
│ ├── middleware/
│ │ ├── auth.js # Auth middleware
│ │ └── rateLimit.js # Rate limiting middleware
│ ├── ws/
│ │ ├── index.js # WebSocket server
│ │ └── handlers.js # WebSocket message handlers
│ └── index.js # Express app setup + logger
├── package.json
├── Dockerfile
├── render.yaml # Render Blueprint (deployment config)
├── .env.example
└── .github/workflows/deploy.yml📄 License
MIT — see LICENSE.
🙏 Acknowledgments
- @noble/ed25519 — Pure JS ed25519 implementation
- tweetnacl — Cryptographic primitives
- Ink — React for CLI
- Chalk — Terminal styling
- Express — Web framework
- PostgreSQL — Database
- Render — Cloud hosting
- Neon — Serverless PostgreSQL
