概要
分散型チャットアプリ。Bluetooth Mesh によるオフライン通信と Nostr によるグローバル接続をサポートし、アカウントや中央サーバーは不要。エンドツーエンド暗号化でプライバシーを保護し、地理位置情報に基づくチャンネルと IRC スタイルのコマンドを提供。
README プレビュー
\n\n## bitchat\n\nA decentralized peer-to-peer messaging app with dual transport architecture: local Bluetooth mesh networks for offline communication and internet-based Nostr protocol for global reach. No accounts, no phone numbers, no central servers. It's the side-groupchat.\n\n[bitchat.free](http://bitchat.free)\n\n📲 [App Store](https://apps.apple.com/us/app/bitchat-mesh/id6748219622)\n\n## License\n\nThis project is released into the public domain. See the [LICENSE](LICENSE) file for details.\n\n## Features\n\n- **Dual Transport Architecture**: Bluetooth mesh for offline + Nostr protocol for internet-based messaging\n- **Location-Based Channels**: Geographic chat rooms using geohash coordinates over global Nostr relays\n- **Intelligent Message Routing**: Automatically chooses best transport (Bluetooth → Nostr fallback)\n- **Decentralized Mesh Network**: Automatic peer discovery and multi-hop message relay over Bluetooth LE\n- **Privacy First**: No accounts, no phone numbers, no persistent identifiers\n- **Private Message End-to-End Encryption**: [Noise Protocol](https://noiseprotocol.org) for mesh, NIP-17 for Nostr\n- **IRC-Style Commands**: Familiar `/slap`, `/msg`, `/who` style interface\n- **Universal App**: Native support for iOS and macOS\n- **Emergency Wipe**: Triple-tap to instantly clear all data\n- **Performance Optimizations**: LZ4 message compression, adaptive battery modes, and optimized networking\n\n## [Technical Architecture](https://deepwiki.com/permissionlesstech/bitchat)\n\nBitChat uses a **hybrid messaging architecture** with two complementary transport layers:\n\n### Bluetooth Mesh Network (Offline)\n\n- **Local Communication**: Direct peer-to-peer within Bluetooth range\n- **Multi-hop Relay**: Messages route through nearby devices (max 7 hops)\n- **No Internet Required**: Works completely offline in disaster scenarios\n- **Noise Protocol Encryption**: End-to-end encryption with forward secrecy\n- **Binary Protocol**: Compact packet format
FAQ (4)
トラブル対応Xcode 27 で 'ambiguous use of words' または swift-secp256k1 プラグインの検証エラーにより bitchat の macOS ビルドが失敗する場合の修正方法
ピン留めされている 21-DOT-DEV/swift-secp256k1 依存関係を 0.24.0 以降にアップグレードしてください — メンテナーは Xcode 27 / Swift 6.4 のプラグイン検証失敗を修正するために 0.24.0 をリリースしました。その後、Package.resolved を更新し、xcodebuild -project bitchat.xcodeproj -scheme "bitchat (macOS)" -configuration Debug build でリビルドしてください。
根本原因: ピン留めされている 0.21.1 は、UInt256.swift 内のカスタム var words が Swift 6.4 の Swift.BinaryInteger.words と衝突するため('ambiguous use of words')、コンパイルに失敗します。一方、0.23.2 は、SharedSourcesPlugin が Xcode 27 にバンドルされている SwiftPM では利用できない @available(_PackageDescription 6.0) API を使用しているため、xcodebuild のプラグイン検証に失敗します。
アップグレードできない場合の回避策: swift-secp256k1 0.23.2 をローカルにベンダー化してください — localPackages/swift-secp256k1 にコピーし、Plugins/ ディレクトリを削除し、その Package.swift 内の P256K/ZKP ターゲットから .plugin(name: "SharedSourcesPlugin", capability: .buildTool()) ターゲットと plugins: ["SharedSourcesPlugin"] を削除し(Sources/Shared/* を両方のターゲットのソースディレクトリにフラット化し)、Package.swift を .package(path: "localPackages/swift-secp256k1") に向け、project.pbxproj 内の XCRemoteSwiftPackageReference を XCLocalSwiftPackageReference に置き換え、Package.resolved を削除してください。これにより、ビルドはエラー 0 件で成功します。
トラブル対応deliveredFrameCount が最大 12 であるはずが 16 になってしまう、SimulatedMeshTests の不安定な失敗を修正するにはどうすればよいですか?
このフレークは、テストハーネスがシミュレート時間のみを進めるのに対し、announce-admission ロジックが実時間の Date() を使用していることが原因です。負荷のかかった CI ランナーでは、0.15 s のスロットルウィンドウが経過する可能性があり、4 つの余分な announce フレームが生成され、mesh.deliveredFrameCount - baseline が 12 から 16 に増加します。シミュレートされたメッシュから実時間への依存を取り除くことでこれを修正します。具体的には、announce スロットルにテストのシミュレートクロックを注入/使用するか、ベースラインを記録する前にメッシュを静かな状態にドレインして、実時間駆動の announce トラフィックが測定デルタから除外されるようにします。関連する修正は PR #1622/#1649 で追跡されており、#1651 ではベースラインの前にメッシュトラフィックをドレインし、ストームバジェットをテスト対象のリレー動作に制限しています。
トラブル対応Androidから送信された大きな圧縮メッセージがiOSでサイレントに失敗して表示されないのはなぜか、また、ペイロードサイズの不一致はどのように修正されるのか?
これは、Android が AppConstants.Protocol.MAX_PAYLOAD_LENGTH = 10 MiB までの展開後ペイロードを許可するのに対し、iOS が FileTransferLimits.maxFramedFileBytes ≈ 1.13 MiB を超えるフレームを拒否するために発生します。そのため、高圧縮された Android のメッセージは 2~5 MiB に展開され、iOS によってサイレントにドロップされる可能性があります。
修正方法:
1. iOS クライアントを、PR「Accept compressed payloads up to Android's 10 MiB decompressed ceiling」を含むビルドに更新します。これにより、iOS の受信側の展開後ペイロード上限が Android と一致します。
2. グローバルな展開後ペイロード上限を超えるフレームの送出を拒否するエンコード側の強制 PR を適用し、送信側がデコーダーに拒否されるメッセージを作成できないようにします。
3. 一時的な回避策として、Android から古い iOS クライアントへ送信する際は、非圧縮/元のペイロードを約 1.13 MiB 未満に抑えてください。
50,000:1 の圧縮率ガードは別のものであり、この不一致を防ぐことはできません。これは、iOS がそのガードが適用される前に、ワイヤ上で宣言された originalSize に基づいて割り当てを行うためです。
トラブル対応GitHub Actions のワークフロートークンがプルリクエストを作成または更新できない場合、どのように修正すればよいですか?
デフォルトのワークフロートークンにはPRを開く権限がありません。compare URLを開き、ソースブランチとして automation/georelay-data を選択して、手動でPRを作成してください:
https://github.com/permissionlesstech/bitchat/compare/main...automation/georelay-data?expand=1
その後、PRを通常のレビューに提出してください。リポジトリがトークンを引き続きブロックする場合は、変更のないブランチを個人のフォークにプッシュし、main に対してクロスフォークPRを開いてください。自動実行では、ワークフロートークンに pull-requests: write(必要な場合は contents: write も)を付与するか、PR作成権限を持つPAT/アプリトークンを使用してください。