Back to Freedom.Tech Back
All JoinMarket-NG releasesAll versions
Release Tue, Aug 11, 2026 7 min read

JoinMarket-NG 0.36.0

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)