Original release notes
Security hardening and way more!
Added
- Improve fidelity bond recovery reliability on Neutrino by using the new forced-rescan server capability (561af745)
- Verify device signatures when finalizing fidelity bond PSBTs, making pre-funding hardware wallet compatibility tests conclusive (60a33d62)
- Authenticate directory nick ownership with negotiated signing (d3f3cce4)
Fixed
- Apply wallet environment settings during wallet creation and recovery (618ad062)
- Automatically discover existing fidelity bonds when importing an sw-fb wallet (8f866776)
- Reject forged sender identities in directory-routed messages (c08daa5f)
- Authenticate private messages and bind direct connections to handshaked nicks (e17d6775)
- Align PoDLE validation and revelation encoding with the deployed protocol (9b08c9a0)
- Derive PoDLE proof nonces without runtime RNG dependence (ff157b24)
- Require confirmed native SegWit maker liquidity (134dd1bd)
- Exclude and atomically reserve maker inputs through pending broadcast (3a76a819)
- Prevent concurrent local PoDLE reuse without rejecting same-round commitment gossip (dac27d53)
- Derive Neutrino UTXO confirmations from verified block data (3059937f)
- Revalidate every CoinJoin input immediately before broadcast (78586a6b)
- Keep CoinJoin equal and change addresses distinct in one-mixdepth wallets (9681bef8)
- Harden wallet entropy sourcing and secret file permissions (131ee2cc)
- Use operating-system randomness for adversary-visible choices (f2eb2c35)
- Validate and normalize mnemonics in standalone bond signers (80e0f729)
- Detect maker broadcasts through the Neutrino mempool tracker (65a17635)
- Apply LOGGING__LEVEL setting in jmwalletd log buffer and stderr sinks (63111038)
- Prevent stale log handlers from bypassing configured log levels (998a05f9)
- Prevent stale CoinJoin cleanup from releasing inputs owned by another round (84fb1b30)
- Bound cleanup of timed-out maker sessions and preserve signed input leases (ccf363c6)
- Keep PoDLE commitments reserved when blacklist persistence fails (ccf363c6)
- Authenticate direct peer nick bindings before routing messages (ccf363c6)
- Keep failed wallet creation retryable without orphan wallet files (09da6a51)
- Install the orderbook watcher CLI with the default profile (6ba29d83)
- Avoid fidelity bond privacy warnings for CoinJoin-private md0 funds (0cee709f)
- Use libsecp256k1 for secret PoDLE response scalar arithmetic (437a50e4)
- Reject expired fidelity bond certificates during maker selection (b3ce730f)
- Align wallet certificate expiry checks with reference semantics (1208cd7b)
- Exclude expired fidelity bond certificates from watcher values and statistics (479b238c)
- Preserve distinct fidelity bond script claims during directory aggregation (dc3a4d62)
- Show decaying bond value with a warning when its advertised certificate expires (8c32cfc3)
- Support Mempool instances that only expose the batch outspends endpoint (5b74cc09)
- Keep fidelity bond values visible during temporary block-height outages (1a94d0cf)
- Diagnose Jade CBOR transport failures before bond signing and add secure BitBox01 password handling (e43d3632)
- Stop makers that require renewal of an expired fidelity bond certificate (6d1c5eb4)
- Clean up maker resources after daemon-managed startup failures (dced45f0)
- Correct maker input totals and remove changing Connected rows from JAM earn reports (9ac71552)
- Prevent maker address reuse and cross-wallet earnings reports when history or daemon lifecycle operations fail (68347e29)
- Preserve renewed fidelity bond claims and distinguish stale or invalid bond verification from active maker eligibility (0f9da0f2)
- Fail external fidelity bond workflows when the signer adds no signature or certificate validity is unusable (92b8ed63)
- Limit the orderbook watcher web server to loopback outside container deployments by default (750b3506)
- Correct dust thresholds (9b47e774)
- Log a security error when loading a wallet with an invalid BIP39 checksum (4395beec)
- Prevent advertised onion locations from blocking maker registration (a10ab24f)
- Harden directory nick authentication against relay and concurrency failures (9c1b75cf)
- Simplify directory nick authentication wire messages (2f58c889)
- Reject out-of-order directory authentication messages (c9f8f2d7)
- Preserve odd wire codes for directory nick authentication (4bdf990f)
- Keep taker CoinJoins pending until block confirmation and report the active Bitcoin network (5dd505ce)
- Show nick authentication and ping shortnames in the orderbook watcher (fcc03cd5)
- Record direct send transactions in history file at broadcast time (15dfbaf8)
- Make daemon direct-send history records reliable across backend and multi-wallet edge cases (c828fe73)
- Make CLI direct-send history reliable when backends omit transaction IDs or history persistence fails (2dbb5b09)
- Make jm-wallet address subcommand help available without loading or unlocking a wallet (ea48cda4)
- Allow makers to merge recorded CoinJoin outputs in mixdepth 0 (b248d35c)
- Preserve exact CoinJoin provenance and reserved-input selection rules across wallet restarts (731c41dc)
- Align maker offer ranges with exact fillable liquidity and relative fee bounds (b2dada4e)
- Prevent taker rounds from selecting reserved inputs or accepting mismatched destination outputs (bcff809e)
- Keep tumbler plans aligned with spendable capacity and resume confirmation waits without replay (68145b2b)
- Nullify CoinJoin-specific fields (cj_amount, source_mixdepth) on non-collaborative deposit and send history entries (48a85278)
- Report direct-send and deposit amounts correctly across history consumers (c8f7126a)
Configuration Changes
Existing config.toml files are not updated automatically. Review the bundled template changes below and apply the relevant options manually.
--- config.toml.template (0.35.0)
+++ config.toml.template (0.36.0)
@@ -1,6 +1,11 @@
# JoinMarket-NG Configuration
# Uncomment and modify settings as needed. Defaults are sensible for most users.
# See documentation: https://joinmarket-ng.github.io/joinmarket-ng/
+#
+# Every nested setting has an equivalent environment variable. Uppercase the
+# section and key, then join them with a double underscore. For example:
+# [wallet] background_full_rescan -> WALLET__BACKGROUND_FULL_RESCAN
+# Environment variables take precedence over values in this file.
# ============================================================================
# Core Settings
@@ -160,6 +165,15 @@
# Override with a custom list if needed:
# directory_servers = ["custom1.onion:5222", "custom2.onion:5222"]
+# Directory nick authentication policy (JMP-0005):
+# "prefer_verified" authenticates when supported and falls back to legacy servers.
+# "require_verified" rejects legacy servers. "disabled" uses the legacy handshake.
+# nick_auth_mode = "prefer_verified"
+# Expected identity for each selected directory endpoint. Keys must exactly match
+# the host:port string used after directory address selection. V3 onion identities
+# are derived automatically; explicit entries are required for clearnet and test IDs.
+# nick_auth_directory_ids = { "127.0.0.1:5222" = "test:local-directory" }
+
# ============================================================================
# Wallet Settings
# ============================================================================
@@ -183,8 +197,10 @@
# See docs/technical/wallet-scanning.md.
# scan_range = 1000
-# Dust threshold in satoshis
-# dust_threshold = 27300
+# JoinMarket fixes minimum maker change at 27300 sats so makers and takers
+# coordinate on the same value. Taker-owned change uses a separate fixed
+# threshold of 2730 sats, matching the reference implementation.
+# dust_threshold = 27300 # Protocol constant, do not change
# Forced address-reuse defense (privacy). When a UTXO arrives on a wallet
# address that was previously used and is now empty, it is AUTOMATICALLY frozen
@@ -387,30 +403,24 @@
# size_factor = 0.1
# Minimum confirmations for UTXOs offered into coinjoins.
-# Default 0 lets the maker offer unconfirmed (mempool) UTXOs, which
-# improves liquidity. The PoDLE commitment lives on a separate UTXO and
-# is still gated by taker_utxo_age (taker side, default 5). Raise this
-# to 1+ if you want to trade liquidity for RBF/eviction/reorg safety.
-# min_confirmations = 0
+# Base-protocol takers reject unconfirmed maker inputs, so this must be at
+# least 1. The PoDLE commitment lives on a separate taker UTXO and is still
+# gated by taker_utxo_age (default 5).
+# min_confirmations = 1
# UTXO merge algorithm: "default", "gradual", "greedy", "random"
# merge_algorithm = "default"
# Mixdepth 0 privacy restriction.
# By default, UTXOs in mixdepth 0 are restricted to a single UTXO per CoinJoin
-# to prevent linking deposits and fidelity bonds. CoinJoin outputs (cj-out)
-# are always exempt from this restriction because they already have CoinJoin
-# privacy. Set to true to disable the restriction entirely and allow merging
-# all md0 UTXOs (experienced makers only -- reduces privacy).
+# to prevent linking deposits and fidelity bonds. Outputs with exact protocol
+# CoinJoin provenance are always exempt because they already have CoinJoin
+# privacy. Set to true to disable the restriction entirely and allow merging
+# all md0 UTXOs (experienced makers only, reduces privacy).
# allow_mixdepth_zero_merge = false
-# Fidelity bond settings
-# Set to true to run without a fidelity bond even if bonds exist in the registry.
-# This can be useful for privacy - bonds are public and linkable to your offers.
-# no_fidelity_bond = false
-
# Timeouts and intervals
-# session_timeout_sec = 300
+# session_timeout_sec = 300 # Range: 60-86400 seconds
# rescan_interval_sec = 600
# pending_tx_timeout_min = 60 # Minutes before marking unbroadcast CoinJoins as failed
# pending_tx_abandon_hours = 72 # Hours before abandoning a broadcast but unconfirmed tx
@@ -424,7 +434,7 @@
# onion_host = "" # Static hidden service address (e.g., 'mymaker...onion'). When not set, Tor control auto-generates one.
# onion_serving_host = "127.0.0.1"
# onion_serving_port = 5222
-# tor_target_host = "127.0.0.1"
+# The hidden-service target is configured as [tor] target_host above.
# Message rate limiting (protects against spam/DoS from peers)
