diff --git a/Cargo.lock b/Cargo.lock
index aca73100..ee27affe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2386,9 +2386,9 @@ dependencies = [
[[package]]
name = "mostro-core"
-version = "0.14.3"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "976a8cfc914710e7acfe08645f1ec3467672c60d581e73963fbdd13b53a51b15"
+checksum = "ad5c310ad08889f8a142e6d31be4318ec7b45404e7de027ff80a852250efc8b0"
dependencies = [
"bitcoin",
"chrono",
diff --git a/Cargo.toml b/Cargo.toml
index 4879d99a..b2889c3e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -71,7 +71,7 @@ reqwest = { version = "0.12.1", default-features = false, features = [
"json",
"rustls-tls",
] }
-mostro-core = { version = "0.14.3", features = ["sqlx"] }
+mostro-core = { version = "0.14.5", features = ["sqlx"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
async-trait = "0.1.83"
diff --git a/README.md b/README.md
index b4e4e110..fb70f370 100644
--- a/README.md
+++ b/README.md
@@ -65,19 +65,20 @@ While @lnp2pBot works excellently, it relies on Telegram—a platform potentiall
### Developer Tools
- **Comprehensive Docs** - Architecture guides, event routing, Lightning operations, RPC reference
- **SQLite Backend** - Lightweight, embedded database with full migration support
-- **Nostr Protocol** - NIP-59 (GiftWrap), NIP-33 (replaceable events) compliance
+- **Nostr Protocol** - Protocol v2 (NIP-44 encrypted kind-14 direct messages, default) with a deprecated protocol-v1 (NIP-59 GiftWrap) opt-in, NIP-33 replaceable events
- **Observability** - Structured logging with `tracing`, configurable log levels
### Nostr Event Kinds Used by the Daemon
-Mostro uses a small set of Nostr event kinds. Some are part of the public protocol, and some are transport-only details that live inside NIP-59 GiftWrap envelopes.
+Mostro uses a small set of Nostr event kinds. Some are part of the public protocol, and some depend on the wire transport the node is configured with (see [Protocol Transport](#protocol-transport-v1-vs-v2) below). A node speaks exactly one transport: `nip44` (protocol v2, kind `14`, the default) or `gift-wrap` (protocol v1, kind `1059`, deprecated opt-in).
| Kind | Name / Constant | Used for | Notes |
| --- | --- | --- | --- |
| `0` | `Metadata` | Mostro profile metadata | Standard Nostr profile event published at startup when metadata is configured. |
-| `1` | `TextNote` | Inner rumor in NIP-59 | Transport-only. Mostro creates and reads it *inside* GiftWrap; it is not published as a standalone public event. |
-| `13` | `Seal` | Inner sealed envelope in NIP-59 | Transport-only. Mostro creates and reads it *inside* GiftWrap; it is not published as a standalone public event. |
-| `1059` | `GiftWrap` | NIP-59 outer envelope | This is the relay-visible event kind that Mostro subscribes to and publishes for wrapped messages. |
+| `14` | `DM_EVENT_KIND` | Protocol v2 direct message | **Default transport.** Signed kind-14 event with NIP-44 encrypted content, sent directly between the client's trade key and Mostro's pubkey. Carries a NIP-40 `expiration` tag (`[expiration] dm_days`). This is the relay-visible kind Mostro subscribes to when `transport = "nip44"`. |
+| `1` | `TextNote` | Inner rumor in NIP-59 | Protocol v1 only, transport-only. Mostro creates and reads it *inside* GiftWrap; it is not published as a standalone public event. |
+| `13` | `Seal` | Inner sealed envelope in NIP-59 | Protocol v1 only, transport-only. Mostro creates and reads it *inside* GiftWrap; it is not published as a standalone public event. |
+| `1059` | `GiftWrap` | NIP-59 outer envelope | Protocol v1 (**deprecated**, removed in v0.19.0). The relay-visible kind Mostro subscribes to only when the operator explicitly sets `transport = "gift-wrap"`. |
| `10002` | `RelayList` | Relay metadata | Standard Nostr relay list event published periodically by the scheduler. |
| `8383` | `DEV_FEE_AUDIT_EVENT_KIND` | Dev fee audit event | Public audit event used for transparent fee accounting. |
| `30078` | `NOSTR_EXCHANGE_RATES_EVENT_KIND` | Exchange rates | NIP-33 replaceable event for BTC/fiat rate publishing. |
@@ -86,7 +87,18 @@ Mostro uses a small set of Nostr event kinds. Some are part of the public protoc
| `38385` | `NOSTR_INFO_EVENT_KIND` | Mostro info | NIP-33 replaceable event for operator / node metadata. |
| `38386` | `NOSTR_DISPUTE_EVENT_KIND` | Disputes | NIP-33 replaceable event for dispute publications. |
-> Note: `kind 1` and `kind 13` are *inside* the `kind 1059` GiftWrap transport. They are created and verified by the wrapping/unwrapping code, but they are not emitted or consumed as standalone public relay events by the daemon.
+> Note: `kind 1` and `kind 13` are *inside* the `kind 1059` GiftWrap transport (protocol v1). They are created and verified by the wrapping/unwrapping code, but they are not emitted or consumed as standalone public relay events by the daemon. On the default `nip44` transport none of `1`/`13`/`1059` are used at all.
+
+### Protocol Transport (v1 vs v2)
+
+Mostro speaks **one** wire protocol per node, selected with `[mostro] transport` in `settings.toml`:
+
+| `transport` | Protocol | Relay-visible kind | Status |
+| --- | --- | --- | --- |
+| `"nip44"` | v2 — signed kind-14 events with NIP-44 encrypted content, sent directly between the client's trade key and Mostro | `14` | **Default.** A node with no `transport` line starts here. Rate-limitable by relays; first-contact senders can be required to grind extra PoW (`pow_first_contact`). |
+| `"gift-wrap"` | v1 — NIP-59 GiftWrap (rumor → seal → wrap) | `1059` | **Deprecated, explicit opt-in only.** Never selected automatically; write `transport = "gift-wrap"` to keep serving v1-only clients during the transition. Removed in v0.19.0 ([#786](https://github.com/MostroP2P/mostro/issues/786)). |
+
+The node advertises its protocol in the kind `38385` info event via the `protocol_version` tag (`"1"` or `"2"`) so v2-capable clients pick the matching wire format. Full details in [docs/TRANSPORT_V2_SPEC.md](docs/TRANSPORT_V2_SPEC.md).
---
@@ -305,7 +317,7 @@ Mostro is a Rust-based daemon with a modular architecture:
```mermaid
flowchart TB
subgraph "External Systems"
- Nostr[Nostr Relays
NIP-59 GiftWrap]
+ Nostr[Nostr Relays
kind 14 NIP-44 DMs
or NIP-59 GiftWrap]
LND[LND Node
Hold Invoices]
API[Price API
Yadio]
end
@@ -333,7 +345,7 @@ flowchart TB
Config[settings.toml]
end
- Nostr <-->|GiftWrap Events| App
+ Nostr <-->|Protocol messages| App
LND <-->|gRPC| Lightning
API -->|Price Feed| Order
@@ -364,7 +376,7 @@ flowchart TB
```
**Key Components**:
-- **Event Router** (`app.rs`): Unwraps NIP-59 GiftWraps, validates PoW/signatures, routes to action handlers
+- **Event Router** (`app.rs`): Unwraps incoming protocol messages (NIP-44 kind-14 by default, NIP-59 GiftWrap on the deprecated v1 transport), validates PoW/signatures, routes to action handlers
- **Action Handlers** (`app/*`): 17 modules handling order lifecycle, disputes, admin operations
- **Lightning Client** (`lightning/*`): Creates hold invoices, settles/cancels, manages payments
- **RPC Server** (`rpc/*`): gRPC interface for direct admin communication (optional)
@@ -373,7 +385,7 @@ flowchart TB
**Technology Stack**:
- **Runtime**: Tokio async executor
-- **Nostr**: `nostr-sdk` v0.43 (NIP-59 GiftWrap, NIP-33 replaceable events)
+- **Nostr**: `nostr-sdk` v0.43 (NIP-44 kind-14 direct messages, NIP-59 GiftWrap for the deprecated v1 transport, NIP-33 replaceable events)
- **Lightning**: `fedimint-tonic-lnd` v0.3 (LND gRPC client)
- **Database**: SQLite via `sqlx` v0.9 (runtime queries; migrations embedded with `sqlx::migrate!`)
- **RPC**: `tonic` + `prost` (Protocol Buffers)
@@ -631,6 +643,13 @@ expiration_seconds = 900 # 15 minutes for taker to complete payment
# Proof-of-Work requirement (0 = disabled)
pow = 0 # Set to 10-20 to prevent spam
+# Wire transport: "nip44" (protocol v2, default) or "gift-wrap" (protocol v1,
+# DEPRECATED — explicit opt-in only, removed in v0.19.0). Omit for nip44.
+transport = "nip44"
+# Extra PoW demanded from first-contact senders on the nip44 transport
+# (unset = same as `pow`). No effect on gift-wrap.
+# pow_first_contact = 16
+
# Development sustainability fee (0.30 = 30% of Mostro fee goes to dev fund)
dev_fee_percentage = 0.30 # Minimum: 0.10 (10%), Maximum: 1.0 (100%)
@@ -645,6 +664,8 @@ bitcoin_price_api_url = "https://api.yadio.io"
- `fee`: Your Mostro's fee percentage (default 0.6% split between buyer/seller)
- `dev_fee_percentage`: Portion of your fee donated to Mostro development (default 30%)
- `pow`: Increase to 10-20 if experiencing spam (higher = slower client messages)
+- `transport`: Defaults to `"nip44"` (protocol v2). Set `"gift-wrap"` **explicitly** only if you must keep serving protocol-v1 clients — it is deprecated and goes away in v0.19.0
+- `pow_first_contact`: On `nip44`, a stiffer PoW for senders not yet part of an active trade (anti-spam, checked before decryption)
- `fiat_currencies_accepted`: Restrict supported currencies (empty array = accept all)
---
@@ -889,7 +910,10 @@ client.add_relay("wss://relay.mostro.network").await?;
let order = Order { /* ... */ };
let message = Message::new(Action::NewOrder, order);
-// Send via NIP-59 GiftWrap to Mostro pubkey
+// Send as a protocol-v2 kind-14 NIP-44 direct message to Mostro's pubkey
+// (default). Check the node's `protocol_version` tag in its kind-38385
+// info event: "2" → NIP-44 kind 14, "1" → legacy NIP-59 GiftWrap.
+// mostro-core ships helpers for both wire formats.
// ...
```
@@ -1189,7 +1213,8 @@ Join the operator community:
### Technical Documentation (This Repository)
- **[Architecture Overview](docs/ARCHITECTURE.md)** - System design, module map, startup sequence
-- **[Event Routing](docs/EVENT_ROUTING.md)** - Message handling, NIP-59 GiftWrap processing
+- **[Event Routing](docs/EVENT_ROUTING.md)** - Message handling, unwrapping of protocol messages
+- **[Transport v2 Spec](docs/TRANSPORT_V2_SPEC.md)** - Protocol v2 (NIP-44 kind 14) vs deprecated v1 (NIP-59 GiftWrap), migration timeline
- **[Lightning Operations](docs/LIGHTNING_OPS.md)** - Hold invoice lifecycle, payment flows
- **[Orders & Actions](docs/ORDERS_AND_ACTIONS.md)** - Order state machine, action handlers
- **[Admin RPC & Disputes](docs/ADMIN_RPC_AND_DISPUTES.md)** - Dispute resolution, admin interface
diff --git a/docs/TRANSPORT_V2_SPEC.md b/docs/TRANSPORT_V2_SPEC.md
index c680119d..cc476864 100644
--- a/docs/TRANSPORT_V2_SPEC.md
+++ b/docs/TRANSPORT_V2_SPEC.md
@@ -124,8 +124,9 @@ There is **no dual mode**: a node speaks exactly one protocol version.
```toml
[mostro]
-# "gift-wrap" (protocol v1, DEPRECATED) | "nip44" (protocol v2)
-transport = "gift-wrap"
+# "nip44" (protocol v2, default) | "gift-wrap" (protocol v1, DEPRECATED,
+# explicit opt-in only)
+transport = "nip44"
[expiration]
# kind-14 direct messages
@@ -134,8 +135,12 @@ dm_days = 30
| `transport` | event kind | who can trade on this node |
|---|---|---|
-| `gift-wrap` *(default in 0.18.x)* | 1059 (v1) | every current client — wire behavior identical to pre-v2 daemons |
-| `nip44` | 14 (v2) | v2-capable clients only — the only mode from v0.19.0 |
+| `nip44` *(default)* | 14 (v2) | v2-capable clients only — the only mode from v0.19.0 |
+| `gift-wrap` *(deprecated, explicit opt-in only)* | 1059 (v1) | every current client — wire behavior identical to pre-v2 daemons |
+
+A node with no `transport` line starts in `nip44`. Operators who still need
+to serve protocol-v1 clients must write `transport = "gift-wrap"` explicitly
+in `settings.toml`; it is never selected automatically.
**Capability discovery:** the node advertises its protocol in the kind
`38385` instance-info event with a `protocol_version` tag (`"1"` or
@@ -153,6 +158,11 @@ with the clients that community uses.
(nothing changes for existing clients). **Protocol v1 is DEPRECATED**:
announced in release notes, protocol docs and the `protocol_version`
tag. Client developers have the 0.18.x cycle to ship v2.
+- **v0.18.5** — the daemon default flips to `transport = "nip44"`.
+ `gift-wrap` stays fully functional but only as an explicit opt-in in
+ `settings.toml` (the code path is untouched; removal is deferred to
+ v0.19.0). The mostro-core `Transport::default()` remains `gift-wrap`
+ for clients; mostrod overrides it with its own `default_transport()`.
- **v0.19.0** — protocol v2 becomes the default and only protocol.
Everything v1-related is removed from mostrod (gift-wrap path,
`"gift-wrap"` setting value, v1 acceptance). mostro-core keeps its
@@ -180,8 +190,9 @@ The bulk of the work, all additive, in mostro-core's `transport` module:
Minimal daemon integration; **zero handler changes** by design:
- `mostro-core` 0.12.1 → **0.13.0**.
-- `[mostro] transport` setting (`Transport`, serde default = `gift-wrap`)
- in `src/config/types.rs` + `settings.tpl.toml`.
+- `[mostro] transport` setting (`Transport`, serde default = `gift-wrap`
+ at the time; `nip44` since v0.18.5) in `src/config/types.rs` +
+ `settings.tpl.toml`.
- `[expiration] dm_days` knob (default 30) in `ExpirationSettings` and the
`get_expiration_timestamp_for_kind` fallback (`DM_EVENT_KIND = 14` in
`src/config/constants.rs`).
diff --git a/settings.tpl.toml b/settings.tpl.toml
index 8ad5fc4e..ce21a5df 100644
--- a/settings.tpl.toml
+++ b/settings.tpl.toml
@@ -65,15 +65,19 @@ publish_relays_interval = 60
# Requested POW
pow = 0
# Wire transport for protocol messages. A node speaks exactly one:
-# "gift-wrap" - protocol v1, NIP-59 gift wraps (kind 1059). DEPRECATED,
-# will be removed in v0.19.0 — mostrod will then run protocol
-# v2 only and this setting disappears. See
-# https://github.com/MostroP2P/mostro/issues/786
# "nip44" - protocol v2, signed kind-14 events with NIP-44 encrypted
-# content. Rate-limitable by relays; switch once the clients
-# your community uses support protocol v2.
+# content. Rate-limitable by relays. THIS IS THE DEFAULT:
+# a node with no `transport` line (or a fresh settings.toml)
+# starts in nip44.
+# "gift-wrap" - protocol v1, NIP-59 gift wraps (kind 1059). DEPRECATED and
+# OPT-IN ONLY: it is never selected automatically — you must
+# explicitly write `transport = "gift-wrap"` here to keep
+# serving protocol-v1 clients during the transition. It will
+# be removed in v0.19.0 — mostrod will then run protocol v2
+# only and this setting disappears. See
+# https://github.com/MostroP2P/mostro/issues/786
# See docs/TRANSPORT_V2_SPEC.md
-transport = "gift-wrap"
+transport = "nip44"
# Anti-spam gate for the "nip44" transport (docs/TRANSPORT_V2_SPEC.md §6
# Phase 2). Proof-of-work (leading-zero bits) demanded of a *first-contact*
# event — one whose visible sender (trade key) is not part of an active
diff --git a/src/config/settings.rs b/src/config/settings.rs
index e770923c..b86ca218 100644
--- a/src/config/settings.rs
+++ b/src/config/settings.rs
@@ -123,11 +123,12 @@ impl Settings {
MOSTRO_CONFIG.get()?.anti_abuse_bond.as_ref()
}
- /// Wire transport for protocol messages. Falls back to the default
- /// (`gift-wrap`, protocol v1) when the global settings haven't been
- /// initialized yet — `send_dm()` sits on every reply path and must
- /// degrade to v1 behavior rather than panic in unit tests that don't
- /// bring up the full configuration, mirroring [`Settings::get_bond`].
+ /// Wire transport for protocol messages. Falls back to the daemon
+ /// default (`nip44`, protocol v2 — see `default_transport`) when the
+ /// global settings haven't been initialized yet — `send_dm()` sits on
+ /// every reply path and must degrade gracefully rather than panic in
+ /// unit tests that don't bring up the full configuration, mirroring
+ /// [`Settings::get_bond`].
///
/// DEPRECATED(v0.19.0, #786): goes away with the `transport` setting —
/// v0.19.0 hardcodes the protocol-v2 (`nip44`) wire format.
@@ -137,10 +138,23 @@ impl Settings {
)]
pub fn get_transport() -> Transport {
#[allow(deprecated)]
- MOSTRO_CONFIG
- .get()
+ Self::transport_or_default(MOSTRO_CONFIG.get())
+ }
+
+ /// Selection logic behind [`Settings::get_transport`], split out so the
+ /// uninitialized (`None`) fallback is unit-testable without touching the
+ /// process-wide `MOSTRO_CONFIG`.
+ ///
+ /// DEPRECATED(v0.19.0, #786): goes away with the `transport` setting.
+ #[deprecated(
+ since = "0.18.0",
+ note = "transitional v1/v2 transport selection; removed in v0.19.0 (protocol v2 only) — see issue #786"
+ )]
+ fn transport_or_default(settings: Option<&Settings>) -> Transport {
+ #[allow(deprecated)]
+ settings
.map(|s| s.mostro.transport)
- .unwrap_or_default()
+ .unwrap_or_else(crate::config::types::default_transport)
}
/// Retrieve the multi-source price configuration from the global
@@ -236,10 +250,34 @@ mod tests {
}
#[test]
- fn transport_falls_back_to_default() {
+ #[allow(deprecated)]
+ fn transport_falls_back_to_nip44_when_uninitialized() {
+ // No global config ⇒ daemon default is protocol v2, regardless of
+ // mostro-core's `Transport::default()` (gift-wrap).
+ assert_eq!(Settings::transport_or_default(None), Transport::Nip44Direct);
+ }
+
+ #[test]
+ #[allow(deprecated)]
+ fn transport_uses_configured_value_when_initialized() {
+ let mut settings = test_settings();
+ settings.mostro.transport = Transport::GiftWrap;
+ assert_eq!(
+ Settings::transport_or_default(Some(&settings)),
+ Transport::GiftWrap
+ );
+ settings.mostro.transport = Transport::Nip44Direct;
+ assert_eq!(
+ Settings::transport_or_default(Some(&settings)),
+ Transport::Nip44Direct
+ );
+ }
+
+ #[test]
+ fn get_transport_reads_global_config() {
init_test_settings();
#[allow(deprecated)]
let transport = Settings::get_transport();
- assert_eq!(transport, Transport::default());
+ assert_eq!(transport, Transport::Nip44Direct);
}
}
diff --git a/src/config/types.rs b/src/config/types.rs
index 3a9e56f2..8e7cb0e6 100644
--- a/src/config/types.rs
+++ b/src/config/types.rs
@@ -284,10 +284,64 @@ mod tests {
#[test]
// DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
#[allow(deprecated)]
- fn transport_defaults_to_gift_wrap() {
- // v0.18.x default: wire-identical to pre-v2 daemons. The default
- // flips to nip44 in v0.19.0 (docs/TRANSPORT_V2_SPEC.md §5).
- assert_eq!(MostroSettings::default().transport, Transport::GiftWrap);
+ fn transport_defaults_to_nip44() {
+ // The daemon defaults to protocol v2; gift-wrap is opt-in only
+ // (docs/TRANSPORT_V2_SPEC.md §5).
+ assert_eq!(MostroSettings::default().transport, Transport::Nip44Direct);
+ }
+
+ #[test]
+ // DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
+ #[allow(deprecated)]
+ fn transport_omitted_in_toml_deserializes_to_nip44() {
+ // A settings.toml without a `transport` line must land on nip44 —
+ // not on mostro-core's `Transport::default()` (gift-wrap).
+ let toml = r#"
+ fee = 0.0
+ max_routing_fee = 0.002
+ max_order_amount = 1000000
+ min_payment_amount = 100
+ expiration_hours = 24
+ expiration_seconds = 900
+ user_rates_sent_interval_seconds = 3600
+ max_expiration_days = 15
+ publish_relays_interval = 60
+ pow = 0
+ publish_mostro_info_interval = 300
+ bitcoin_price_api_url = "https://api.yadio.io"
+ fiat_currencies_accepted = ["USD"]
+ max_orders_per_response = 10
+ dev_fee_percentage = 0.30
+ "#;
+ let settings: MostroSettings = toml::from_str(toml).expect("valid mostro settings");
+ assert_eq!(settings.transport, Transport::Nip44Direct);
+ }
+
+ #[test]
+ // DEPRECATED(v0.19.0, #786): delete along with the `transport` setting.
+ #[allow(deprecated)]
+ fn transport_gift_wrap_is_explicit_opt_in() {
+ // Operators can still pin protocol v1 by writing it out explicitly.
+ let toml = r#"
+ fee = 0.0
+ max_routing_fee = 0.002
+ max_order_amount = 1000000
+ min_payment_amount = 100
+ expiration_hours = 24
+ expiration_seconds = 900
+ user_rates_sent_interval_seconds = 3600
+ max_expiration_days = 15
+ publish_relays_interval = 60
+ pow = 0
+ publish_mostro_info_interval = 300
+ bitcoin_price_api_url = "https://api.yadio.io"
+ fiat_currencies_accepted = ["USD"]
+ max_orders_per_response = 10
+ dev_fee_percentage = 0.30
+ transport = "gift-wrap"
+ "#;
+ let settings: MostroSettings = toml::from_str(toml).expect("valid mostro settings");
+ assert_eq!(settings.transport, Transport::GiftWrap);
}
#[test]
@@ -542,9 +596,15 @@ pub struct MostroSettings {
/// Exchange rates update interval in seconds (default: 300 = 5 minutes)
#[serde(default = "default_exchange_rates_update_interval")]
pub exchange_rates_update_interval_seconds: u64,
- /// Wire transport for protocol messages: `"gift-wrap"` (protocol v1,
- /// NIP-59) or `"nip44"` (protocol v2, kind-14 direct). A node speaks
- /// exactly one. See docs/TRANSPORT_V2_SPEC.md.
+ /// Wire transport for protocol messages: `"nip44"` (protocol v2,
+ /// kind-14 direct — the default) or `"gift-wrap"` (protocol v1, NIP-59,
+ /// deprecated opt-in). A node speaks exactly one. See
+ /// docs/TRANSPORT_V2_SPEC.md.
+ ///
+ /// The daemon defaults to `nip44`; `gift-wrap` is only used when the
+ /// operator explicitly sets it in `settings.toml`. This deliberately
+ /// overrides mostro-core's `Transport::default()` (still `gift-wrap`
+ /// for clients' sake) via [`default_transport`].
///
/// DEPRECATED(v0.19.0, #786): transitional knob for the v1→v2 protocol
/// migration. v0.19.0 removes it and runs protocol v2 (`nip44`) only.
@@ -552,7 +612,7 @@ pub struct MostroSettings {
since = "0.18.0",
note = "transitional v1/v2 transport selection; removed in v0.19.0 (protocol v2 only) — see issue #786"
)]
- #[serde(default)]
+ #[serde(default = "default_transport")]
pub transport: Transport,
/// Proof-of-work difficulty (leading-zero bits) demanded of a
/// *first-contact* event on the protocol-v2 (`nip44`) transport — one
@@ -601,6 +661,17 @@ fn default_active_pubkeys_refresh_interval() -> u64 {
60 // 1 minute — keeps a just-taken order's keys fast-pathing promptly
}
+/// Daemon-side default wire transport: protocol v2 (`nip44`). Operators
+/// must explicitly set `transport = "gift-wrap"` in `settings.toml` to keep
+/// running the deprecated protocol-v1 path. Intentionally *not*
+/// `Transport::default()` — mostro-core keeps `gift-wrap` as its own default
+/// for client-side migration needs.
+///
+/// DEPRECATED(v0.19.0, #786): goes away with the `transport` setting.
+pub(crate) fn default_transport() -> Transport {
+ Transport::Nip44Direct
+}
+
impl Default for MostroSettings {
// DEPRECATED(v0.19.0, #786): `transport` init goes away with the field.
#[allow(deprecated)]
@@ -632,7 +703,7 @@ impl Default for MostroSettings {
website: None,
publish_exchange_rates_to_nostr: default_publish_exchange_rates(),
exchange_rates_update_interval_seconds: default_exchange_rates_update_interval(),
- transport: Transport::default(),
+ transport: default_transport(),
pow_first_contact: None,
active_pubkeys_refresh_interval: default_active_pubkeys_refresh_interval(),
}
diff --git a/src/main.rs b/src/main.rs
index 951ff5e2..6a636497 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -81,8 +81,9 @@ async fn main() -> Result<()> {
// Get mostro keys
let mostro_keys = util::get_keys()?;
- // Subscribe only to the configured transport's kind: 1059 (protocol v1
- // gift wrap) or 14 (protocol v2 NIP-44 direct). See docs/TRANSPORT_V2_SPEC.md.
+ // Subscribe only to the configured transport's kind: 14 (protocol v2
+ // NIP-44 direct, the default) or 1059 (protocol v1 gift wrap, explicit
+ // opt-in only). See docs/TRANSPORT_V2_SPEC.md.
// DEPRECATED(v0.19.0, #786): the `transport` knob disappears in v0.19.0
// and this subscription becomes unconditionally kind 14.
#[allow(deprecated)]
@@ -97,9 +98,10 @@ async fn main() -> Result<()> {
if transport == mostro_core::transport::Transport::GiftWrap {
tracing::warn!(
"transport = \"gift-wrap\" (protocol v1) is DEPRECATED and will be removed in \
- v0.19.0; mostrod will then run protocol v2 (transport = \"nip44\") only. Switch \
- once the clients your community uses support protocol v2. \
- See https://github.com/MostroP2P/mostro/issues/786"
+ v0.19.0; mostrod will then run protocol v2 (transport = \"nip44\") only. You \
+ opted into it explicitly in settings.toml — remove the line (or set \
+ transport = \"nip44\", the default) once the clients your community uses \
+ support protocol v2. See https://github.com/MostroP2P/mostro/issues/786"
);
}
let subscription = Filter::new()