feat(nostr): Add mesh-to-relay gateway for #me messages#614
feat(nostr): Add mesh-to-relay gateway for #me messages#614avillagran wants to merge 3 commits intopermissionlesstech:mainfrom
Conversation
Core changes: - Filter Nostr packets in MessageHandler to route to gateway instead of displaying in public chat - Add event ID deduplication cache to prevent multiple online devices publishing same event - Add PoW requirement notification for offline #me messages - Fix signature invalidation by signing AFTER PoW mining completes New files: - NostrProfileManager: Manages #me channel message publishing with PublishResult sealed class - NostrAccountSheet: UI for Nostr account management - NostrMeshGatewayTest: Unit tests for serializer UI/UX improvements: - Enhanced image viewer with pinch-to-zoom and pan gestures - Improved message components styling - Location channels sheet updates - About sheet enhancements
|
hi. what is "Nostr mesh packets" and what is a "gateway"? could you explain the idea behind this feature? |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7afab46dc0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!resolved && event.kind == NostrKind.METADATA && event.pubkey == pubkeyHex) { | ||
| resolved = true | ||
| try { | ||
| val profileJson = com.google.gson.JsonParser.parseString(event.content).asJsonObject | ||
| val name = profileJson.get("name")?.asString?.takeIf { it.isNotBlank() } | ||
| ?: profileJson.get("display_name")?.asString?.takeIf { it.isNotBlank() } | ||
|
|
||
| relayManager.unsubscribe(subscriptionId) | ||
|
|
||
| GlobalScope.launch(Dispatchers.Main) { | ||
| onResult(name) | ||
| } | ||
| } catch (e: Exception) { | ||
| Log.w(TAG, "Failed to parse profile for $pubkeyHex: ${e.message}") |
There was a problem hiding this comment.
Ensure profile-name resolution cleans up on JSON parse failure
If a relay sends a metadata event whose content is not valid JSON (which happens in the wild), the handler sets resolved = true and then throws, so onResult is never called and the subscription is never unsubscribed. Because resolveNostrReferences removes pendingResolutions only in the callback, that pubkey becomes permanently “pending” and the dangling subscription stays active. This means future references to the same npub will never be resolved on that device. Consider moving resolved = true after a successful parse and/or invoking onResult(null) and unsubscribe inside the catch.
Useful? React with 👍 / 👎.
Hi, the mesh-to-relay gateway lets offline users post to Nostr through nearby online peers. |
Move resolved=true after successful parse so timeout cleanup still runs if metadata content is invalid JSON. Fixes dangling subscriptions and permanently pending pubkeys.
Summary
Changes
Core
0x7E/0x00) and route toNostrMeshGatewayPublishResultsealed class, proper sign-after-mine flowUI/UX
PublishResultand show system message when PoW is required offlineTests
NostrMeshSerializerFlow
Testing