Serein
Rust로 만든 가볍고 성능 좋은 Discord 전용 네이티브 클라이언트
Cinderous는 오픈소스·무료·프라이버시 우선 분산 메신저로, 종단 암호화·로컬 저장·서버 상태 없음
Cinderous is open-source, forever-free, privacy-first decentralized messaging. End-to-end encrypted (NIP-44 / Gift Wrap), local-first storage, zero server state — plaintext and private keys never leav
소셜TypeScript · RustGitHub @VaalRL온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
🔥 去中心化、無中央資料庫的端對端加密即時通訊軟體,結合 Nostr 與 WebRTC,重現 MSN 經典體驗(震動、音樂狀態、離線留言) | Decentralized, end-to-end encrypted messenger with no central database, built on Nostr + WebRTC and reviving the classic MSN Messenger experience (nudges, music status, offline messages).
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Life is short, connect buddies. 去中心化、無中央資料庫的即時通訊軟體。融合 Nostr 協議 與 WebRTC,高度還原早期 MSN Messenger 的經典互動體驗(震動、音樂狀態、離線留言),並以「零伺服器維護成本」為營運目標。 🔥 官方網站: | 🌐 在瀏覽器開啟(網頁版): | 💻 下載桌面版:GitHub Releases Cinderous 透過「狀態信令」與「巨量資料傳輸」雙軌混合網路,達成極致隱私與低延遲:README 전문 보기 ↗
🌐 English · English version
Life is short, connect buddies.
去中心化、無中央資料庫的即時通訊軟體。融合 Nostr 協議 與 WebRTC,高度還原早期桌面即時通訊軟體的經典互動體驗(震動、音樂狀態、離線留言),並以「零伺服器維護成本」為營運目標。
🔥 官方網站:https://vaalrl.github.io/Cinderous/ | 🌐 在瀏覽器開啟(網頁版):https://cinderous.cinderous1.workers.dev | 💻 下載桌面版:GitHub Releases
Cinderous 透過「狀態信令」與「巨量資料傳輸」雙軌混合網路,達成極致隱私與低延遲:
npub)即為全網唯一 ID,無帳號密碼。同一裝置可並存多個身分(工作/個人)。docs/SECURITY.md 殘餘)。雙軌混合網路(依連線狀態動態切換):
| 引擎 | 技術 | 定位 |
|---|---|---|
| 引擎 A:狀態與信令 | Nostr 協議(Cloudflare Workers;SQLite-backed Durable Objects) | 離線留言暫存、線上狀態廣播、WebRTC 初始 SDP 信令交換 |
| 引擎 B:巨量資料傳輸 | WebRTC 直連(P2P) | 即時互動:震動(Nudge)、動畫快遞、大檔案傳輸,繞過中繼站達成毫秒級延遲 |
資料生命週期靠 NIP-40(7 天過期)與 Ephemeral Events(Kind 20000-29999 純記憶體轉發、不寫資料庫),確保 Cloudflare 永久免費額度不被耗盡。
RelayChatBackend engine、功能高度對齊);Android 已有測試版 APK(見 Releases,Capacitor 殼,自 v0.0.14 起);🔴 它目前以 debug 憑證簽署且可被偵錯——能接上 USB 偵錯的人可讀取行程記憶體,而 session 期間私鑰必然在裡面,請勿用它處理你真正在意的對話(ADR-0335,詳見 docs/SECURITY.md)。iOS 尚未推出(另需 macOS 建置)。原生通知與背景推播待接。完整技術規格見 PRD.md,模組邊界與資料流見 ARCHITECTURE.md。
.
├── apps/
│ ├── desktop/ # Tauri + React + TypeScript(第一優先平台)
│ │ ├── src/ # React/TS 前端 UI 與瀏覽器 demo(demo.html / webrtc.html)
│ │ └── src-tauri/ # Rust:SQLite、Nostr WebSocket、WebRTC、金鑰管理
│ └── mobile/ # React Native + SQLite(輔助平台,預留)
├── packages/
│ └── core/ # 共用 TS:Nostr 事件、secp256k1 簽章、NIP-44/17/59、型別、Kind 常數
├── relay/ # Cloudflare Worker(Nostr 中繼站;Durable Objects 扇出,離線留言預留 DO SQLite)
└── docs/adr/ # 架構決策紀錄(ADR)
從核心協定到桌面/行動客戶端與企業模式皆已實作並通過測試(pnpm monorepo、TypeScript strict、全程 TDD)。摘要如下(詳見 docs/adr/ 逾 330 份決策紀錄):
核心通訊
RTCPeerConnection/ICE/TURN)語音/視訊通話、資料通道分塊檔案傳輸、雙軌降級與自動改道即時通體驗(懷舊即時通風)
企業模式(公司帳號)
組織名冊(管理者簽章)、邀請碼入職、公司帳號金鑰託管+離職接管
公司設定(歡迎詞/上下班時間、下班自動靜音)、訊息保留天數、公司儲存槽(檔案存放)
企業成員鎖公司座;桌面與行動端皆可管理(唯「企業主收儲存槽落盤」限桌面=需原生檔案系統)
測試:core 639/engine 570/desktop 714/mobile 441/relay 197/website 68/theme 37/cli 30/i18n 16/brand 4(TS 共 2,716)+ Rust,含 relay↔client 端到端整合測試與行動端 jsdom 互動測試(ADR-0328)。
可眼見:桌面客戶端可打包成安裝檔(見上「終端平台」),亦可直接在瀏覽器跑(/);另有端到端 demo.html/真實 WebRTC webrtc.html。
完整施工計畫(現況、各平台待辦、M6–M9 進階功能、相依順序):見 docs/ROADMAP.md。
使用者教學(給一般使用者:身分與鑰匙、加好友、本地密碼、換裝置三條路、搬家、常見問題):見 docs/使用手冊_User-Guide.md。
前端開發指南(給社群開發者:三層架構、重用 core/i18n、消費 ChatBackend 接自己的 UI、AGPL):見 docs/前端開發指南_Frontend-Guide.md(ADR-0074)。
需求:Node 22+、pnpm 10+(Rust 測試另需 stable toolchain)。
# 1. 取得原始碼並安裝 workspace 相依
git clone https://github.com/VaalRL/Cinderous.git && cd Cinderous
pnpm install
# 2. 驗證環境(全綠代表就緒)
pnpm -r test # 全部 TS 測試(core / engine / i18n / relay / desktop / mobile)
pnpm -r typecheck # 全部型別檢查
# 3. 起本機真實 relay,再跑桌面前端(瀏覽器開發、不需 Tauri)
pnpm --filter @cinderous/relay build:dev && pnpm --filter @cinderous/relay dev # ws://localhost:8787
pnpm --filter @cinderous/desktop dev # 前端;開 /?relay=ws://localhost:8787
想接自己的前端、加語言、做擴充或貢獻核心? 開發者入口見
.github/CONTRIBUTING.md(三層架構、環境、參與方式、規範),接前端的完整教學見docs/前端開發指南_Frontend-Guide.md。
| 任務 | 指令 |
|---|---|
| 桌面前端(懷舊即時通風格) | pnpm --filter @cinderous/desktop dev,開啟 /(另有端到端 demo /demo.html、真實 WebRTC /webrtc.html) |
| 前端建置 | pnpm --filter @cinderous/desktop build |
| 共用核心測試 | pnpm --filter @cinderous/core test |
| 中繼站測試 | pnpm --filter @cinderous/relay test |
| 本機真實 relay(開發用) | pnpm --filter @cinderous/relay build:dev && pnpm --filter @cinderous/relay dev(起 ws://localhost:8787;前端開 /?relay=ws://localhost:8787 即連真實 relay) |
| Rust 測試 | cargo test(於 apps/desktop/src-tauri/) |
| 桌面端開發(需 Tauri 工具鏈) | pnpm --filter @cinderous/desktop tauri dev |
| 中繼站本地開發 / 部署(需 wrangler) | wrangler dev / wrangler deploy(於 relay/) |
中繼站(relay/)是一個自建的最小 Nostr relay,跑在 Cloudflare Workers 上,以
Durable Object 持有所有 WebSocket 連線並做記憶體扇出。它的職責是:
message-store 邏輯已實作並測試——每收件人配額、以 #p 為索引。持久化:Cloudflare 版用 SQLite-backed Durable Object(new_sqlite_classes)、Node 自架版用內建 SQL)。WebRTC 一旦 P2P 打通,震動、檔案傳輸等資料完全走點對點,永遠不經過 relay。 Ephemeral 事件只在記憶體轉發、不落地;relay 看不到訊息明文,也看不到(經 Gift Wrap 隱藏的)社交圖譜。
# 1. 取得原始碼並安裝相依(會建立 workspace 連結,wrangler 打包時需要)
git clone <your-fork-url> cinder && cd cinder
pnpm install
# 2. 登入 Cloudflare(會開瀏覽器授權)
cd relay
npx --yes wrangler@4 login
# 3. 本地開發:在 ws://127.0.0.1:8787 起一個本機 relay
npx --yes wrangler@4 dev
# 4. 部署到 Cloudflare,取得 wss://cinder-relay.<你的帳號>.workers.dev
pnpm run deploy
⚠ 用
npx而不是pnpm dlx:pnpm 10 的建置腳本需明示同意,pnpm dlx wrangler會以ERR_PNPM_IGNORED_BUILDS中止(--allow-build在 dlx 下無效)。
部署設定在 relay/wrangler.toml:Worker 名稱、進入點 src/worker.ts、
以及 Durable Object 綁定(RELAY_ROOM → RelayRoom 類別與 migration)。wrangler 會直接打包
TypeScript,無需額外建置步驟。可在 wrangler.toml 修改 name 換成你自己的 Worker 名稱。
🔴 推上 GitHub 不會部署中繼站。 這個專案沒有任何自動部署流程——.github/workflows/
裡沒有 wrangler、也沒有 Cloudflare 憑證。中繼站永遠是由人在自己的機器上跑 pnpm run deploy
推上去的。
這表示兩件事,自架者要知道:
git status)。version 欄位(見下方「部署完怎麼確認」)。① 有多個 Cloudflare 帳號時,wrangler 會挑錯
它可能打向你另一個帳號,回一個看起來像憑證壞掉的錯誤:
Authentication error [code: 10000]
憑證沒壞,是帳號選錯了。明示帳號 ID 就好(在 Cloudflare 後台首頁右側或網址列看得到):
CLOUDFLARE_ACCOUNT_ID=<你的帳號 ID> pnpm run deploy
② 用 API token 部署時,權限要兩項不是一項
不想每次都開瀏覽器登入(或要放進自己的自動化)的話,用 API token:
CLOUDFLARE_API_TOKEN=<token> CLOUDFLARE_ACCOUNT_ID=<帳號 ID> pnpm run deploy
token 的權限要勾兩項,缺第二項會得到和上面一模一樣的 10000 錯誤:
| 權限 | 為什麼需要 |
|---|---|
| Workers Scripts: Edit | 上傳 Worker |
| User → Memberships: Read | wrangler 會查你在該帳號的角色 |
部署指令回報成功不等於站真的活著。實測兩件事:
curl https://cinder-relay.<你的子網域>.workers.dev/healthz
# 預期:ok
curl -H "Accept: application/nostr+json" https://cinder-relay.<你的子網域>.workers.dev
# 預期:一份 JSON,其中 "version" 是你剛部署的版號
/healthz 回純文字 ok。不要用首頁判斷——合體模式下首頁本來就會回網頁版,
看它回不回 HTML 是判斷不出中繼站死活的。
NIP-11 的 version 欄位是確認「線上跑的是不是我剛推的那一版」的唯一方式。
想要「一個網域、一次部署」的話,多打一個指令就好:
pnpm run deploy:unified # 在 relay/ 目錄下
它會先建置網頁前端(apps/desktop,mode=unified)再連同中繼站一起部署。兩者的差別:
| 指令 | 結果 | 適合誰 |
|---|---|---|
pnpm run deploy | 只有中繼站(預設) | 想跑一座公共錨點的人 |
pnpm run deploy:unified | 中繼站 + 網頁前端 | 自架給自己和朋友用的人 |
🔴 合體部署必須設 run_worker_first = true([env.unified.assets] 裡已經設好了)。
Cloudflare Static Assets 預設是資產優先:請求先比對資產清單,命中就直接回檔案,
Worker 的程式碼根本不會執行——而中繼站的入口 / 正好命中 index.html。少了這一行,
/ 會回 200 與一段 HTML,客戶端不會看到錯誤,只會看到握不了手的 WebSocket。
同樣的理由,合體部署後請用 GET /healthz(純文字 ok)判斷中繼站死活,不要再看 /。
relay 講標準 Nostr 的 REQ / EVENT / CLOSE 協定,可用 @cinderous/core 的 RelayClient:
import { RelayClient, createHeartbeat, generateSecretKey } from "@cinderous/core";
const ws = new WebSocket("wss://cinder-relay.<你的帳號>.workers.dev");
const sk = generateSecretKey();
const client = new RelayClient(
{ send: (data) => ws.send(data) },
{ onEvent: (subId, event) => console.log("收到", subId, event) },
);
ws.addEventListener("message", (m) => client.receive(m.data));
ws.addEventListener("open", () => {
client.subscribe("presence", [{ kinds: [20000] }]); // 訂閱上線心跳
client.publish(createHeartbeat(sk)); // 廣播自己的心跳
});
桌面/前端可把這個 wss:// 位址設定為連線端點(見 apps/desktop/src/relay-source.ts)。
Ephemeral 心跳會隨上線人數扇出,請參考 docs/adr/0006
的容量估算(免費層約可支撐數十位並行使用者,並列出心跳間隔/合併/抖動等可調旋鈕)。
離線留言需要持久化。DO 已是 SQLite-backed(wrangler.toml 的 new_sqlite_classes);於 worker.ts 把
RelayCore 接上以 DO SQLite 為後備的 MessageStore(行為已由 SDK @cinderous/client/relay 的 message-store
定義並測試:NIP-40 過期、每收件人配額、以 #p 為索引)。詳見
docs/adr/0005。
本專案的開發硬規則如下:
PRD.md,模組與資料流看 ARCHITECTURE.md。v2、new_*、*_enhanced 平行路徑。歡迎參與!送 PR 前請留意:
PRD.md(產品規格)、ARCHITECTURE.md(模組與資料流)與 docs/adr/(既有決策)。pnpm -r typecheck 與 pnpm -r test 全綠(CI 也會檢查)。docs/adr/0000-template.md)。提交即表示你同意以本專案授權(AGPL-3.0)釋出你的貢獻。
這是一套處理端到端加密與私鑰的軟體,目前仍在開發階段、尚未經過安全稽核,請勿用於高風險場景。
發現安全問題請以私下管道回報,不要開公開 issue。完整的安全政策、加密盤點、威脅模型逐項盤點與已知限制清單見 docs/SECURITY.md。
本專案採用 GNU Affero General Public License v3.0(AGPL-3.0)——詳見 LICENSE。
這代表你可以自由使用、修改與散布;但若你散布修改版,或將修改版作為網路服務(例如自架本中繼站)提供給他人, 就必須以相同授權公開你的原始碼(AGPL 第 13 條)。此選擇是為了確保所有衍生版本與自架的 relay 都對使用者保持透明、可審計,貫徹本專案的隱私與去中心化精神。
Copyright (C) 2026 Cinderous contributors.
官網使用的 Manrope 字型以 SIL Open Font License 1.1 授權,授權全文見 apps/website/src/fonts/OFL.txt。
Cinderous 是獨立的開源專案,與 Microsoft 或其他即時通訊軟體的廠商沒有任何關聯,也未獲其背書。文中提及的產品名稱與商標屬於各自的所有人。