jmcore.config
jmcore.config
Base configuration classes for JoinMarket components.
This module provides Pydantic BaseModel classes that can be inherited by specific components (maker, taker, etc.) to reduce duplication and ensure consistency.
Attributes
__all__ = ['TorConfig', 'TorControlConfig', 'create_tor_control_config_from_env', 'BackendConfig', 'WalletConfig', 'DirectoryServerConfig']
module-attribute
Classes
BackendConfig
Bases: BaseModel
Configuration for Bitcoin backend connection.
Supports different backend types: - scantxoutset: Bitcoin Core RPC with scantxoutset - neutrino: Light client using BIP 157/158
Source code in jmcore/src/jmcore/config.py
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | |
Attributes
backend_config: dict[str, Any] = Field(default_factory=dict, description='Backend-specific configuration (RPC credentials, neutrino peers, etc.)')
class-attribute
instance-attribute
backend_type: str = Field(default='scantxoutset', description="Backend type: 'scantxoutset' or 'neutrino'")
class-attribute
instance-attribute
model_config = {'frozen': False}
class-attribute
instance-attribute
DirectoryServerConfig
Bases: BaseModel
Configuration for directory server instances.
Used by standalone directory servers, not by clients.
Source code in jmcore/src/jmcore/config.py
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | |
Attributes
broadcast_batch_size: int = Field(default=50, ge=1, description='Batch size for concurrent broadcasts (lower = less memory)')
class-attribute
instance-attribute
health_check_host: str = Field(default='127.0.0.1', description='Host for health check endpoint')
class-attribute
instance-attribute
health_check_port: int = Field(default=8080, ge=1, le=65535, description='Port for health check endpoint')
class-attribute
instance-attribute
host: str = Field(default='127.0.0.1', description='Host address to bind to')
class-attribute
instance-attribute
log_level: str = Field(default='INFO', description='Logging level')
class-attribute
instance-attribute
max_json_nesting_depth: int = Field(default=10, ge=1, le=100, description='Maximum nesting depth for JSON parsing')
class-attribute
instance-attribute
max_line_length: int = Field(default=65536, ge=1024, description='Maximum JSON-line message length (default: 64KB)')
class-attribute
instance-attribute
max_message_size: int = Field(default=2097152, ge=1024, description='Maximum message size in bytes (default: 2MB)')
class-attribute
instance-attribute
max_peers: int = Field(default=10000, ge=1, description='Maximum number of connected peers')
class-attribute
instance-attribute
message_burst_limit: int = Field(default=1000, ge=1, description='Maximum burst size')
class-attribute
instance-attribute
message_rate_limit: int = Field(default=500, ge=1, description='Messages per second (sustained)')
class-attribute
instance-attribute
model_config = {'frozen': False}
class-attribute
instance-attribute
motd: str = Field(default='JoinMarket Directory Server https://github.com/joinmarket-ng/joinmarket-ng', description='Message of the day sent to clients')
class-attribute
instance-attribute
network: NetworkType = Field(default=(NetworkType.MAINNET), description='Network type for the directory server')
class-attribute
instance-attribute
port: int = Field(default=5222, ge=1, le=65535, description='Port to listen on')
class-attribute
instance-attribute
rate_limit_disconnect_threshold: int = Field(default=200, ge=1, description='Disconnect after N violations')
class-attribute
instance-attribute
TorConfig
Bases: BaseModel
Configuration for Tor SOCKS proxy connection.
Used for outgoing connections to directory servers and peers.
Source code in jmcore/src/jmcore/config.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
Attributes
model_config = {'frozen': False}
class-attribute
instance-attribute
socks_host: str = Field(default='127.0.0.1', description='Tor SOCKS5 proxy host address')
class-attribute
instance-attribute
socks_port: int = Field(default=9050, ge=1, le=65535, description='Tor SOCKS5 proxy port')
class-attribute
instance-attribute
stream_isolation: bool = Field(default=True, description='Isolate connection types onto separate Tor circuits via SOCKS5 auth')
class-attribute
instance-attribute
TorControlConfig
Bases: BaseModel
Configuration for Tor control port connection.
When enabled, allows dynamic creation of ephemeral hidden services at startup using Tor's control port. This allows generating a new .onion address each time without needing to pre-configure the hidden service in torrc.
Requires Tor to be configured with: ControlPort 127.0.0.1:9051 CookieAuthentication 1 CookieAuthFile /var/lib/tor/control_auth_cookie
Environment variables (via pydantic-settings): TOR__CONTROL_HOST - Tor control host (default: 127.0.0.1) TOR__CONTROL_PORT - Tor control port (default: 9051) TOR__COOKIE_PATH - Cookie auth file path TOR__PASSWORD - Tor control password (not recommended)
Source code in jmcore/src/jmcore/config.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
Attributes
cookie_path: Path | None = Field(default=None, description='Path to Tor cookie auth file (e.g., /var/lib/tor/control_auth_cookie)')
class-attribute
instance-attribute
enabled: bool = Field(default=True, description='Enable Tor control port integration')
class-attribute
instance-attribute
host: str = Field(default='127.0.0.1', description='Tor control port host')
class-attribute
instance-attribute
model_config = {'frozen': False}
class-attribute
instance-attribute
password: SecretStr | None = Field(default=None, description='Password for HASHEDPASSWORD auth (not recommended, use cookie auth)')
class-attribute
instance-attribute
port: int = Field(default=9051, ge=1, le=65535, description='Tor control port')
class-attribute
instance-attribute
WalletConfig
Bases: BaseModel
Base wallet configuration shared by all JoinMarket wallet users.
Includes wallet seed, network settings, HD wallet structure, and backend connection details.
Source code in jmcore/src/jmcore/config.py
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
Attributes
backend_config: dict[str, Any] = Field(default_factory=dict, description='Backend-specific configuration')
class-attribute
instance-attribute
backend_type: str = Field(default='scantxoutset', description="Backend type: 'scantxoutset' or 'neutrino'")
class-attribute
instance-attribute
background_full_rescan: bool = Field(default=True, description='Run full blockchain rescan in background after smart scan. This ensures no transactions are missed while allowing fast startup.')
class-attribute
instance-attribute
bitcoin_network: NetworkType | None = Field(default=None, description='Bitcoin network for address generation (defaults to same as network)')
class-attribute
instance-attribute
connection_timeout: float = Field(default=120.0, gt=0.0, description="Timeout in seconds for Tor SOCKS5 connections. Covers TCP handshake, SOCKS5 negotiation, Tor circuit building, and PoW solving. Default 120s matches Tor's internal circuit timeout. Under PoW defense (DoS attack), connections may take significantly longer than normal (~5-15s).")
class-attribute
instance-attribute
data_dir: Path | None = Field(default=None, description='Data directory for JoinMarket files (commitment blacklist, history, etc.). Defaults to ~/.joinmarket-ng or $JOINMARKET_DATA_DIR if set')
class-attribute
instance-attribute
directory_servers: list[str] = Field(default_factory=list, description="List of directory server URLs (e.g., ['onion_host:port', ...])")
class-attribute
instance-attribute
dust_threshold: int = Field(default=DUST_THRESHOLD, ge=0, description='Dust threshold in satoshis for change outputs (default: 27300)')
class-attribute
instance-attribute
gap_limit: int = Field(default=20, ge=6, description='BIP44 gap limit for address scanning')
class-attribute
instance-attribute
mixdepth_count: int = Field(default=5, ge=1, le=10, description='Number of mixdepths in the wallet (privacy compartments)')
class-attribute
instance-attribute
mnemonic: SecretStr = Field(..., description='BIP39 mnemonic phrase for wallet seed')
class-attribute
instance-attribute
model_config = {'frozen': False}
class-attribute
instance-attribute
network: NetworkType = Field(default=(NetworkType.MAINNET), description='Protocol network for directory server handshakes')
class-attribute
instance-attribute
passphrase: SecretStr = Field(default_factory=(lambda: SecretStr('')), description='BIP39 passphrase (13th/25th word)')
class-attribute
instance-attribute
scan_lookback_blocks: int = Field(default=52560, ge=0, description='Number of blocks to look back for smart scan (default: ~1 year = 52560 blocks). Set to 0 to always scan from genesis (slow but complete).')
class-attribute
instance-attribute
smart_scan: bool = Field(default=True, description='Use smart scan for fast startup (scan from ~1 year ago instead of genesis). A full rescan runs in background to catch any older transactions.')
class-attribute
instance-attribute
socks_host: str = Field(default='127.0.0.1', description='Tor SOCKS5 proxy host')
class-attribute
instance-attribute
socks_port: int = Field(default=9050, ge=1, le=65535, description='Tor SOCKS5 proxy port')
class-attribute
instance-attribute
stream_isolation: bool = Field(default=True, description='Isolate connection types onto separate Tor circuits via SOCKS5 auth')
class-attribute
instance-attribute
Functions
set_bitcoin_network_default() -> WalletConfig
If bitcoin_network is not set, default to the protocol network.
Source code in jmcore/src/jmcore/config.py
258 259 260 261 262 263 | |
Functions
create_tor_control_config_from_env() -> TorControlConfig
Create TorControlConfig from environment variables with smart defaults.
This is a legacy function for direct env var access. Prefer using JoinMarketSettings which handles TOR__* env vars through pydantic-settings.
Environment variables (legacy format): TOR__CONTROL_HOST - Tor control host (default: 127.0.0.1) TOR__CONTROL_PORT - Tor control port (default: 9051) TOR__COOKIE_PATH - Cookie auth file path TOR__PASSWORD - Tor control password
Auto-detection: - If TOR__COOKIE_PATH is set, use it - Otherwise try common paths: /run/tor/control.authcookie, /var/run/tor/control.authcookie, /var/lib/tor/control_auth_cookie
Source code in jmcore/src/jmcore/config.py
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | |