Compare commits

..
Author SHA1 Message Date
jack 3afacca7f6 fix(iOS App): resolve merge artifacts in scenePhase handler\n- Remove duplicate didEnterBackground state\n- Fix switch/if braces and logic for foreground restart gating 2025-09-11 18:36:15 +02:00
ddadccc554 Update bitchat/BitchatApp.swift
Co-authored-by: asmo <asmogo@protonmail.com>
2025-09-11 18:31:55 +02:00
74589539c3 Update bitchat/BitchatApp.swift
Co-authored-by: asmo <asmogo@protonmail.com>
2025-09-11 18:31:28 +02:00
860c06c1b1 Update BitchatApp.swift
Co-authored-by: asmo <asmogo@protonmail.com>
2025-09-11 16:42:21 +02:00
789bbf6862 Update BitchatApp.swift
Co-authored-by: asmo <asmogo@protonmail.com>
2025-09-11 16:42:13 +02:00
10be302854 Update BitchatApp.swift
Co-authored-by: asmo <asmogo@protonmail.com>
2025-09-11 16:42:04 +02:00
jack 4894a0b04e geo: disable background sampling + notifications\n- Gate sampling to foreground only (beginGeohashSampling, watchers)\n- Suppress geohash activity notifications unless app is active\n- Stop sampling explicitly on background scene phase 2025-09-11 13:35:36 +02:00
jack 36b5fdabc4 UI: scope Tor restart messages to geohash channels; skip initial foreground restart on cold launch to avoid confusing system message in #mesh 2025-09-11 13:29:17 +02:00
jack 5020190164 Always queue subscriptions and flush on connection; avoid immediate sends
- Prevents early send/cancel churn at launch and during reconnects
- If relays are already connected, flush immediately; otherwise pending until connected
2025-09-11 12:33:03 +02:00
jack b0f6568ff5 On launch, queue Nostr subscriptions without initiating connects; let centralized connect handle it
- In subscribe(), if no connections exist, just list relays and queue subs
- Avoids early send/cancel churn before connect() runs post-Tor-ready
2025-09-11 12:29:19 +02:00
jack f7b78452d0 Make Nostr connect single-sourced; defer DM subscription until connected
- Remove duplicate connect call from ChatViewModel; let scene-based flow connect
- Setup DM subscription once on first connection via  sink
- Reduce early subscription send/cancel noise after Tor restarts
2025-09-11 12:24:36 +02:00
jack ca10724e64 Gate Nostr init/subscription logs until Tor is ready
- ChatViewModel: await Tor readiness before initializing Nostr and logging
- Only log GeoDM subscription when Tor is ready to avoid early noise
2025-09-11 12:21:49 +02:00
jack 1a353b216d Defer Nostr setup logs until Tor is ready; fix subscribe coalescing and reconnect generation
- Move "Connecting to Nostr relays" log after awaitReady()
- Log "Queuing subscription" when Tor not ready; only coalesce when handler exists
- Clear coalescer on unsubscribe
- Cancel stale reconnect timers using connectionGeneration
- Remove app-level TorDidBecomeReady reset to avoid duplicate reconnects
- Debounce path-change restarts
2025-09-11 12:18:49 +02:00
jack 96992c0a59 Embed Tor via tor_api; deterministic restart + Nostr gating; add Tor notifications
- Run Tor via tor_api in a dedicated thread with OwningControllerFD
- Cleanly stop Tor on background; restart on .active (single instance)
- Avoid fallback to tor_main/dlopen; add is-running check to prevent duplicates
- Fix argv lifetime in C glue to avoid strcmp crash on start
- Gate Nostr connect/subscribe/send until Tor is fully ready
- Rebuild URLSession + reset relays after Tor readiness (scene-based)
- Remove TorDidBecomeReady double-reset and appDidBecomeActive resubscribe
- Add TorWillRestart/TorDidBecomeReady notifications and chat system messages
- Debounce path-change restarts; ACTIVE poke first; coalesce subs; cancel stale reconnect timers
- Project: add CTorHost.c and TorNotifications.swift to targets; fix libz.tbd path
2025-09-11 12:14:55 +02:00
jack 08d1fa7653 Relays: treat repeated -1011 handshake failures as permanent; skip reconnects
- Classify NSURLErrorBadServerResponse as permanent and stop retrying
- Filter permanently-failed relays from subscribe/connect attempts
- Avoid reconnect scheduling for permanently failed relays
2025-09-10 14:21:32 +02:00
jack 8dad90685d UI: show Tor system messages only in geohash channels (not mesh)
- Gate "starting tor..." and readiness/timeout messages to geohash view
- Add helper addGeohashOnlySystemMessage() to avoid posting to mesh timeline
- Persist system messages in geohash backing store via addPublicSystemMessage()
2025-09-10 13:57:53 +02:00
jack 7f829dcbaa iOS: deterministic Tor recovery + 100% gating; BLE-first; session rebuild
- Restart/wake Tor on foreground via ControlPort (ACTIVE/SHUTDOWN),
  avoid restarts during bootstrap; add NWPathMonitor to trigger checks
- Use NWConnection control polling for GETINFO; remove blocking CFStream
  readers to avoid QoS inversions; compute readiness from SOCKS + 100%
- Rebuild TorURLSession on resume; reset Nostr connections to rebind
- Gate all internet after full bootstrap; keep BLE mesh startup fast
- Fix Swift 6 capture issues; hop UI updates to @MainActor
- Remove Tor progress spam; persist initial "starting tor..." system message
2025-09-10 13:45:03 +02:00
jack 37d655d065 feat(tor): Tor-by-default scaffold and integration
- Add TorManager with static/dlopen start, torrc generation, SOCKS probe
- Add TorURLSession; route Nostr/Web fetches via SOCKS proxy
- Add chat system messages for Tor status; show progress (macOS) and ready
- Disable ControlPort bootstrap monitor on iOS; keep it on macOS
- Make Tor waits non-blocking; avoid main-actor stalls on startup
- Queue & flush Nostr subscriptions on relay connect; skip duplicates
- Always rewrite torrc at launch to fix iOS container path mismatches
- Link libz; add project wiring for tor-nolzma.xcframework
- Minor fixes: SOCKS probe resumeOnce guard, entitlement for network.server (macOS)
2025-09-07 13:52:07 +02:00
2426 changed files with 9990 additions and 169911 deletions
@@ -1,12 +0,0 @@
---
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/Swift.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1757258659000000000
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/Swift.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 14166264
- mtime: 1754189697000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2261306
sdk_relative: true
version: 1
...
@@ -1,16 +0,0 @@
---
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1757258662000000000
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 18068
- mtime: 1754189697000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2261306
sdk_relative: true
- mtime: 1754191141000000000
path: 'usr/lib/swift/SwiftOnoneSupport.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 1224
sdk_relative: true
version: 1
...
@@ -1,16 +0,0 @@
---
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/_Concurrency.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1757258669000000000
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/_Concurrency.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 699544
- mtime: 1754189697000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2261306
sdk_relative: true
- mtime: 1754192470000000000
path: 'usr/lib/swift/_Concurrency.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 364219
sdk_relative: true
version: 1
...
@@ -1,16 +0,0 @@
---
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftmodule'
dependencies:
- mtime: 1757258664000000000
path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/26.0/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftmodule'
size: 83568
- mtime: 1754189697000000000
path: 'usr/lib/swift/Swift.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 2261306
sdk_relative: true
- mtime: 1754192532000000000
path: 'usr/lib/swift/_StringProcessing.swiftmodule/arm64e-apple-macos.swiftinterface'
size: 24507
sdk_relative: true
version: 1
...
-20
View File
@@ -1,20 +0,0 @@
# Prevent Github Languages stats skewing:
# Binaries and assets
**/*.xcframework/** linguist-vendored
**/*.xcassets/** linguist-vendored
# Generated files
**/*.pbxproj linguist-generated
**/*.storyboard linguist-generated
Package.resolved linguist-generated
# Downloaded CSVs
relays/online_relays_gps.csv linguist-vendored
# Docs
**/*.md linguist-documentation
# Configs
Configs/*.xcconfig linguist-documentation
**/*.plist linguist-documentation
-40
View File
@@ -1,40 +0,0 @@
name: Fetch GeoRelays Data
on:
schedule:
- cron: '0 6 * * 0'
workflow_dispatch:
permissions:
contents: write
jobs:
update-relay-data:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch GeoRelays
run: |
wget https://raw.githubusercontent.com/permissionlesstech/georelays/refs/heads/main/nostr_relays.csv
mv nostr_relays.csv ./relays/online_relays_gps.csv
- name: Check for changes
id: git-check
run: |
git diff --exit-code || echo "changes=true" >> $GITHUB_OUTPUT
- name: Commit and push changes
if: steps.git-check.outputs.changes == 'true'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add relays/online_relays_gps.csv
git commit -m "Automated update of relay data - $(date -u)"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-27
View File
@@ -1,27 +0,0 @@
name: Build & Test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
name: Run Swift Tests
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Swift
uses: swift-actions/setup-swift@v2
- name: Build the package
run: swift build
- name: Run Tests
run: swift test --parallel
+4 -5
View File
@@ -9,6 +9,9 @@ plans/
CLAUDE.md CLAUDE.md
AGENTS.md AGENTS.md
## User settings
xcuserdata/
## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint *.xcscmblueprint
*.xccheckout *.xccheckout
@@ -54,8 +57,7 @@ iOSInjectionProject/
## Xcode project ## Xcode project
*.xcodeproj/project.xcworkspace/ *.xcodeproj/project.xcworkspace/
## Xcode User settings *.xcodeproj/xcshareddata/
xcuserdata/
## Python ## Python
__pycache__/ __pycache__/
@@ -73,6 +75,3 @@ TestResult.xcresult/
*.xcresult/ *.xcresult/
build.log build.log
*.log *.log
# Local configs
Local.xcconfig
+3 -3
View File
@@ -37,7 +37,7 @@ This three-message pattern provides:
#### NoiseEncryptionService #### NoiseEncryptionService
The main service managing all Noise operations: The main service managing all Noise operations:
```swift ```swift
final class NoiseEncryptionService { class NoiseEncryptionService {
private let staticIdentityKey: Curve25519.KeyAgreement.PrivateKey private let staticIdentityKey: Curve25519.KeyAgreement.PrivateKey
private let sessionManager: NoiseSessionManager private let sessionManager: NoiseSessionManager
private let channelEncryption = NoiseChannelEncryption() private let channelEncryption = NoiseChannelEncryption()
@@ -47,7 +47,7 @@ final class NoiseEncryptionService {
#### NoiseSession #### NoiseSession
Individual session state for each peer: Individual session state for each peer:
```swift ```swift
final class NoiseSession { class NoiseSession {
private var handshakeState: NoiseHandshakeState? private var handshakeState: NoiseHandshakeState?
private var sendCipher: NoiseCipherState? private var sendCipher: NoiseCipherState?
private var receiveCipher: NoiseCipherState? private var receiveCipher: NoiseCipherState?
@@ -58,7 +58,7 @@ final class NoiseSession {
#### NoiseSessionManager #### NoiseSessionManager
Thread-safe session management: Thread-safe session management:
```swift ```swift
final class NoiseSessionManager { class NoiseSessionManager {
private var sessions: [String: NoiseSession] = [:] private var sessions: [String: NoiseSession] = [:]
private let sessionsQueue = DispatchQueue(label: "noise.sessions", attributes: .concurrent) private let sessionsQueue = DispatchQueue(label: "noise.sessions", attributes: .concurrent)
} }
-4
View File
@@ -1,4 +0,0 @@
#include "Release.xcconfig"
// Optional include of local configs
#include? "Local.xcconfig"
-5
View File
@@ -1,5 +0,0 @@
// Your Apple Developer Team ID - https://stackoverflow.com/a/18727947
DEVELOPMENT_TEAM = ABC123
// Unique bundle id to be able to register and run locally
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat.$(DEVELOPMENT_TEAM)
-11
View File
@@ -1,11 +0,0 @@
MARKETING_VERSION = 1.4.4
CURRENT_PROJECT_VERSION = 1
IPHONEOS_DEPLOYMENT_TARGET = 16.0
MACOSX_DEPLOYMENT_TARGET = 13.0
SWIFT_VERSION = 5.0
DEVELOPMENT_TEAM = L3N5LHJD5Y
CODE_SIGN_STYLE = Automatic
PRODUCT_BUNDLE_IDENTIFIER = chat.bitchat
+12
View File
@@ -0,0 +1,12 @@
Place Tor.xcframework here
Instructions
- Obtain a prebuilt Tor Apple xcframework (iCepa/Onion Browser lineage) or build your own minimal client-only Tor.
- Rename it (if needed) to `Tor.xcframework` and drop it in this `Frameworks/` directory.
- Regenerate the Xcode project if you use XcodeGen (`project.yml` already references `Frameworks/Tor.xcframework`).
- Build the app; `TorManager` will automatically bootstrap Tor and route all networking through it.
Notes
- For iOS, the framework will be embedded and code-signed automatically.
- For macOS, it will be linked and embedded as well (you may prefer a system tor for smaller bundles).
@@ -4,36 +4,6 @@
<dict> <dict>
<key>AvailableLibraries</key> <key>AvailableLibraries</key>
<array> <array>
<dict>
<key>BinaryPath</key>
<string>tor-nolzma.framework/tor-nolzma</string>
<key>LibraryIdentifier</key>
<string>macos-arm64</string>
<key>LibraryPath</key>
<string>tor-nolzma.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>tor-nolzma.framework/tor-nolzma</string>
<key>LibraryIdentifier</key>
<string>ios-arm64-simulator</string>
<key>LibraryPath</key>
<string>tor-nolzma.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict> <dict>
<key>BinaryPath</key> <key>BinaryPath</key>
<string>tor-nolzma.framework/tor-nolzma</string> <string>tor-nolzma.framework/tor-nolzma</string>
@@ -48,6 +18,20 @@
<key>SupportedPlatform</key> <key>SupportedPlatform</key>
<string>ios</string> <string>ios</string>
</dict> </dict>
<dict>
<key>BinaryPath</key>
<string>tor-nolzma.framework/tor-nolzma</string>
<key>LibraryIdentifier</key>
<string>macos-arm64</string>
<key>LibraryPath</key>
<string>tor-nolzma.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>macos</string>
</dict>
</array> </array>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>XFWK</string> <string>XFWK</string>

Some files were not shown because too many files have changed in this diff Show More