Goal
In-app voice calling between rider and driver, signaled over Nostr — similar to the implementation Amethyst recently demonstrated. Use case: rider can't find the driver at pickup, driver got lost in a parking lot, anything where text chat is too slow and an out-of-band phone call would require sharing real phone numbers (which the trusted-contact-but-not-PII model is built to avoid).
Why it matters
The whole point of the trusted-driver model is that rider and driver know each other personally but the app shouldn't force them to exchange phone numbers (e.g. a driver who's a friend-of-a-friend, or a driver who you trust enough to ride with but not enough to give your number to). A Nostr-signaled call channel preserves the existing trust model without leaking PII through to the cellular network.
Also: aligns the rider's experience with what other ride apps do, without needing a Twilio-style middlebox or sharing real numbers.
Cross-platform requirement
A call has two ends. This must work across roadflare-ios (rider) and ridestr Drivestr (driver) from day one. Companion issue to be filed in ridestr capturing the driver-app side.
Reference: Amethyst's approach
Worth studying as the starting point rather than designing from scratch:
- Their Nostr event kinds for call signaling (offer / answer / ICE candidate exchange).
- WebRTC for the actual audio channel; Nostr only for signaling.
- How they handle ringing UX, accept/decline, missed-call notification.
- Push notification / wake-up flow when the callee app is backgrounded.
Link Amethyst's PR or spec for whichever Nostr kinds they introduced once we identify them, in this issue thread.
Open design questions
- Signaling kinds. Adopt Amethyst's kinds verbatim for ecosystem compatibility, or define our own RoadFlare-namespaced kinds? Verbatim is friendlier; RoadFlare-namespaced is safer if our use case diverges.
- WebRTC implementation. Native iOS WebRTC framework (Google's, archived) vs PeerConnection libraries. Trade-off between binary size and maintenance burden.
- Audio session management on iOS. Ducking other audio, Bluetooth handling, CallKit integration (for native call-screen UX, but adds complexity). Worth evaluating CallKit specifically — it would make incoming calls behave like normal phone calls (lock-screen ring, integration with phone-app history) but requires VoIP entitlements and PushKit.
- Background wake. PushKit + VoIP push notifications can wake the app for incoming calls; adds App Store review scrutiny.
- Permissions. Microphone permission. Plan the request UX so it doesn't look like a surprise the first time someone tries to call.
- Lifetime / scope. Calls only allowed during an active ride? Or any time between followed contacts? Probably only-during-active-ride for v1 to scope down the abuse surface.
- Battery + data. WebRTC on cellular is fine for short calls; need to verify behavior on weak signal and confirm it doesn't burn battery if the call screen accidentally stays open.
- Spam/abuse prevention. Inherits from the rider/driver follow relationship gate. Could still want a per-pubkey per-day rate limit to prevent abuse if a driver flips hostile.
Effort
XL — this is a several-PR feature involving SDK protocol additions, native iOS WebRTC integration (or library evaluation), CallKit + PushKit decisions, microphone permission UX, plus parallel work on the Android side. Not a quick win.
Priority
P4 — major feature, future enhancement. Definitely not on the v1.0.x path. Worth filing now so the idea is captured and so anyone evaluating Nostr capabilities for the app has a concrete pointer to "yes, voice calling has been considered, here's the scope."
Schedule once the core ride-flow basics are stable and after deciding whether the live-ephemeral-location feature (#81) proves out the WebRTC-data-channel approach, in which case voice can ride the same channel.
Companion
Driver-app companion issue to be filed in ridestr and cross-linked.
Goal
In-app voice calling between rider and driver, signaled over Nostr — similar to the implementation Amethyst recently demonstrated. Use case: rider can't find the driver at pickup, driver got lost in a parking lot, anything where text chat is too slow and an out-of-band phone call would require sharing real phone numbers (which the trusted-contact-but-not-PII model is built to avoid).
Why it matters
The whole point of the trusted-driver model is that rider and driver know each other personally but the app shouldn't force them to exchange phone numbers (e.g. a driver who's a friend-of-a-friend, or a driver who you trust enough to ride with but not enough to give your number to). A Nostr-signaled call channel preserves the existing trust model without leaking PII through to the cellular network.
Also: aligns the rider's experience with what other ride apps do, without needing a Twilio-style middlebox or sharing real numbers.
Cross-platform requirement
A call has two ends. This must work across roadflare-ios (rider) and ridestr Drivestr (driver) from day one. Companion issue to be filed in ridestr capturing the driver-app side.
Reference: Amethyst's approach
Worth studying as the starting point rather than designing from scratch:
Link Amethyst's PR or spec for whichever Nostr kinds they introduced once we identify them, in this issue thread.
Open design questions
Effort
XL — this is a several-PR feature involving SDK protocol additions, native iOS WebRTC integration (or library evaluation), CallKit + PushKit decisions, microphone permission UX, plus parallel work on the Android side. Not a quick win.
Priority
P4 — major feature, future enhancement. Definitely not on the v1.0.x path. Worth filing now so the idea is captured and so anyone evaluating Nostr capabilities for the app has a concrete pointer to "yes, voice calling has been considered, here's the scope."
Schedule once the core ride-flow basics are stable and after deciding whether the live-ephemeral-location feature (#81) proves out the WebRTC-data-channel approach, in which case voice can ride the same channel.
Companion
Driver-app companion issue to be filed in ridestr and cross-linked.