feat(transport): Phase 1 — wire protocol v2 (NIP-44 direct) into mostrod#776
Conversation
Phase 1 of the Messaging Transport Abstraction Layer (#626), on top of mostro-core 0.13.0 (Phase 0, MostroP2P/mostro-core#152). The node now speaks the operator-configured transport — protocol v1 gift wraps (kind 1059, DEPRECATED) or protocol v2 signed kind-14 events with NIP-44 encrypted content — with zero handler changes: both transports unwrap into the same UnwrappedMessage via mostro-core's kind dispatch. - Bump mostro-core 0.12.1 -> 0.13.0 (protocol v2 transport module, PROTOCOL_VER = 2). - New `[mostro] transport` setting ("gift-wrap" | "nip44", serde default gift-wrap so existing settings.toml files keep working and the wire behavior is identical to pre-v2 daemons). - New `[expiration] dm_days` knob (default 30): kind-14 events always carry a NIP-40 expiration tag; send_dm() fills it on the nip44 transport when the caller didn't pass one. - main.rs subscribes to the configured transport's kind only; app.rs accepts only that kind and unwraps via unwrap_incoming(). - Kind-38385 info event advertises `protocol_versions` ("1" or "2") so clients pick the right wire format before sending. - docs/TRANSPORT_V2_SPEC.md: full context, v2 wire format (including the trade-key-bound identity proof), versioning, operator config, release timeline (v1 DEPRECATED in 0.18.0, removed in 0.19.0) and the phase guide (Phase 2 anti-spam gates, Phase 3 protocol docs, Phase 4 cutover). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThis PR makes transport selectable (gift-wrap vs nip44) via settings, filters and unwraps incoming events by the configured transport event kind, derives DM expirations for NIP‑44, updates send_dm to use wrap_message_with, advertises protocol_versions, and adds a Transport v2 spec plus a mostro-core bump. ChangesTransport v2 Implementation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb361db7c6
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/TRANSPORT_V2_SPEC.md`:
- Around line 95-97: Update the fenced code block showing the transport format
to include a language tag; edit the fence surrounding
"mostro-transport-v2-identity:<trade_pubkey_hex>:<message_json>" in
TRANSPORT_V2_SPEC.md and change the opening ``` to ```text so the block is
marked as plain text (satisfying MD040).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d796198a-17bb-490c-9f36-a837ec657363
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (9)
Cargo.tomldocs/TRANSPORT_V2_SPEC.mdsettings.tpl.tomlsrc/app.rssrc/config/constants.rssrc/config/types.rssrc/main.rssrc/nip33.rssrc/util.rs
Codex P2: send_dm() called Settings::get_mostro(), which panics when the global MOSTRO_CONFIG isn't initialized — turning the previously fallible call into an abort in unit tests that don't bring up the full configuration (test_send_dm only survived by test-ordering luck). Add Settings::get_transport(), which falls back to the gift-wrap default when settings are absent, mirroring the existing get_bond / get_price non-panicking accessors. The nip44 expiration path is unreachable without initialized settings (the fallback is gift-wrap), so no other panic path is introduced. Note: test_send_dm's assertion was already order-dependent on main (it expects Err, which only happens when another test has installed NOSTR_CLIENT) — unchanged by this PR. Also tag the identity-proof payload fence in the SPEC as `text` (markdownlint MD040, flagged by Codex and CodeRabbit). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Phase 1 of the Messaging Transport Abstraction Layer (#626 — full proposal), on top of mostro-core 0.13.0 (Phase 0, MostroP2P/mostro-core#152).
The daemon now speaks the operator-configured wire transport — protocol v1 gift wraps (kind 1059, DEPRECATED) or protocol v2 signed kind-14 events with NIP-44 encrypted content. A node speaks exactly one; there is no dual mode. The headline design property holds: zero handler changes — both transports unwrap into the same
UnwrappedMessagevia mostro-core's kind dispatch, so the 28 action handlers are untouched.Changes
mostro-core0.12.1 → 0.13.0 — brings thetransportmodule (Transport,wrap_message_with,unwrap_incoming) andPROTOCOL_VER = 2.[mostro] transportsetting ("gift-wrap" | "nip44", serde defaultgift-wrap): existingsettings.tomlfiles keep working unchanged, and the default wire behavior is byte-identical to pre-v2 daemons.[expiration] dm_daysknob (default 30): kind-14 events are visible to relays, so they always carry a NIP-40expirationtag —send_dm()fills it on the nip44 transport when the caller didn't pass one. NewDM_EVENT_KIND = 14constant; fallback path inget_expiration_timestamp_for_kindkept in sync.main.rs— subscription filter usestransport.event_kind()(1059 or 14).app.rs— the event loop accepts only the configured kind and unwraps viaunwrap_incoming(); everything downstream (PoW, freshness window, trade-index checks, signature-presence bail-out) applies unchanged to both transports.nip33.rs— the kind-38385 info event now advertisesprotocol_versions("1"or"2"), so clients discover which wire format a node accepts before sending anything.docs/TRANSPORT_V2_SPEC.md— the spec for the whole effort: context and threat model, the v2 wire format (visible envelope, 3-element tuple, the trade-key-bound identity proof and why the domain tag exists), versioning, operator configuration, release timeline (v1 DEPRECATED in 0.18.0, removed in 0.19.0), and the detailed phase guide to drive the remaining work (Phase 2 anti-spam gates, Phase 3 protocol docs + client migration, Phase 4 cutover).Tests
New:
dm_daysdefault/override for kind 14, andtransportdefaulting togift-wrap. Full suite: 428 passed, clippy--all-targets --all-features -D warningsclean.Notes for reviewers
transport = "nip44"is fully functional end-to-end (subscribe → unwrap → reply → expiration tag), but flipping it only makes sense once the community's clients implement protocol v2 (Phase 3) — clients discover support via theprotocol_versionstag.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
gift-wrapornip44)Documentation
Chores