Configuration: UI Settings & joinmarket.cfg - joinmarket-webui/jam GitHub Wiki

Web UI Settings

  • Hide balance
  • Display amount in sats/BTC
  • Theme: dark/light

More settings TBD.

See also this comment from waxwing.

JoinMarket Config

The config is split into the following sections: daemon, blockchain, messaging, logging, timeout, policy, payjoin, yield generator, and snicker.

The fee settings are probably the most relevant for regular users.

As per JoinMarket docs:

Several parameters are to be included with the order, currently:

  • cjfee: the amount, in percentage or satoshis, required for the Taker to pay the Maker.
  • txfee: the contribution, in satoshis, that the Maker will contribute to the overall Bitcoin transaction fee. Note: this may be deprecated in future version.
  • minsize: the minimum size of the coinjoin output, in satoshis, that the Maker will agree to.
  • maxsize: the maximum size of the coinjoin output, in satoshis, that the Maker will agree to.

The exact syntax of the messages to broadcast orders is found in the protocol doc.


[DAEMON]
no_daemon = 1
daemon_port = 27183
daemon_host = localhost
use_ssl = false

[BLOCKCHAIN]
blockchain_source = regtest
network = testnet
rpc_host = bitcoind
rpc_port = 43782
rpc_user = joinmarket2
rpc_password = joinmarket2
rpc_wallet_file = #empty?

[MESSAGING]
host = irc # or onion addr
hostid = localhost1
channel = joinmarket-pit
port = 6667
usessl = false
socks5 = false
socks5_host = tor
socks5_port = 9050

[LOGGING]
console_log_level = DEBUG
color = true

[TIMEOUT]
maker_timeout_sec = 60
unconfirm_timeout_sec = 180
confirm_timeout_hours = 6

[POLICY]
segwit = true
native = true
merge_algorithm = default
tx_fees = 3
tx_fees_factor = 0.2
absurd_fee_per_kb = 350000
max_sweep_fee_change = 0.8
max_cj_fee_abs = 42000000
max_cj_fee_rel = 0.1337
tx_broadcast = self
minimum_makers = 1
max_sats_freeze_reuse = -1
interest_rate = 0.015
bondless_makers_allowance = 0.125

taker_utxo_retries = 10 # Expert, DANGER ZONE
taker_utxo_age = 1 # Expert, DANGER ZONE
taker_utxo_amtpercent = 20 # Expert, DANGER ZONE
accept_commitment_broadcasts = 1 # Expert, DANGER ZONE
commit_file_location = cmtdata/commitments.json # Expert, DANGER ZONE

[PAYJOIN]
payjoin_version = 1 # Expert
disable_output_substitution = 0 # Expert
max_additional_fee_contribution = default # Expert
min_fee_rate = 1.1 # Expert?

onion_socks5_host = tor # Expert
onion_socks5_port = 9050 # Expert
tor_control_host = tor # Expert
tor_control_port = 9051 # Expert
onion_serving_host = 172.18.0.6 # Expert
onion_serving_port = 8080 # Expert
hidden_service_ssl = false # Expert

[YIELDGENERATOR]
ordertype = reloffer
cjfee_a = 500
cjfee_r = 0.00002
cjfee_factor = 0.1
txfee_contribution = 0
txfee_contribution_factor = 0.3
minsize = 100000
size_factor = 0.1
gaplimit = 2000 # Advanced

[SNICKER] # Not relevant for Web UI, at least for now
enabled = false # Irrelevant
lowest_net_gain = 0 # Irrelevant
servers = cn5lf...onion, # Irrelevant
polling_interval_minutes = 60 # Irrelevant

Full default joinmarket.cfg with comments, as of 2022-02-17:

[DAEMON]
#set to 1 to run the daemon service within this process;
#set to 0 if the daemon is run separately (using script joinmarketd.py)
no_daemon = 1
#port on which daemon serves; note that communication still
#occurs over this port even if no_daemon = 1
daemon_port = 27183
#currently, running the daemon on a remote host is
#*NOT* supported, so don't change this variable
daemon_host = localhost
#by default the client-daemon connection is plaintext, set to 'true' to use TLS;
#for this, you need to have a valid (self-signed) certificate installed
use_ssl = false

[BLOCKCHAIN]
# options: bitcoin-rpc, regtest, bitcoin-rpc-no-history, no-blockchain
# When using bitcoin-rpc-no-history remember to increase the gap limit to scan for more addresses, try -g 5000
# Use 'no-blockchain' to run the ob-watcher.py script in scripts/obwatch without current access
# to Bitcoin Core; note that use of this option for any other purpose is currently unsupported.
blockchain_source = bitcoin-rpc
# options: signet, testnet, mainnet
# Note: for regtest, use network = testnet
network = mainnet
rpc_host = localhost
# default ports are 8332 for mainnet, 18443 for regtest, 18332 for testnet, 38332 for signet
rpc_port =

# Use either rpc_user / rpc_password pair or rpc_cookie_file.
rpc_user = bitcoin
rpc_password = password
#rpc_cookie_file =

# rpc_wallet_file is Bitcoin Core wallet which is used for address and
# transaction monitoring (it is watchonly, no private keys are stored there).
# It must be created manually if does not exist, see docs/USAGE.md for more
# information.
rpc_wallet_file =

## SERVER 1/4) Darkscience IRC (Tor, IP)
################################################################################
[MESSAGING:server1]
channel = joinmarket-pit
port = 6697
usessl = true

# for traditional IP (default):
host = irc.darkscience.net
socks5 = false

# for Tor (recommended as clearnet alternative):
#host = darkirc6tqgpnwd3blln3yfv5ckl47eg7llfxkmtovrv7c7iwohhb6ad.onion
#socks5 = true
#socks5_host = localhost
#socks5_port = 9050

## SERVER 2/4) hackint IRC (Tor, IP)
################################################################################
[MESSAGING:server2]
channel = joinmarket-pit

# for traditional IP (default):
host = irc.hackint.org
port = 6697
usessl = true
socks5 = false

# for Tor (recommended as clearnet alternative):
#host = ncwkrwxpq2ikcngxq3dy2xctuheniggtqeibvgofixpzvrwpa77tozqd.onion
#port = 6667
#usessl = false
#socks5 = true
#socks5_host = localhost
#socks5_port = 9050

## SERVER 3/4) Anarplex IRC (Tor, IP)
################################################################################
[MESSAGING:server3]
channel = joinmarket-pit

# for traditional IP (default):
host = agora.anarplex.net
port = 14716
usessl = true
socks5 = false

# for Tor (recommended as clearnet alternative):
#host = vxecvd6lc4giwtasjhgbrr3eop6pzq6i5rveracktioneunalgqlwfad.onion
#port = 6667
#usessl = false
#socks5 = true
#socks5_host = localhost
#socks5_port = 9050

## SERVER 4/4) ILITA IRC (Tor - disabled by default)
################################################################################
#[MESSAGING:server4]
#channel = joinmarket-pit
#port = 6667
#usessl = false
#socks5 = true
#socks5_host = localhost

# for Tor (recommended):
#host = ilitafrzzgxymv6umx2ux7kbz3imyeko6cnqkvy4nisjjj4qpqkrptid.onion
#socks5_port = 9050

[LOGGING]
# Set the log level for the output to the terminal/console
# Possible choices: DEBUG / INFO / WARNING / ERROR
# Log level for the files in the logs-folder will always be DEBUG
console_log_level = INFO

# Use color-coded log messages to help distinguish log levels?:
color = true

[TIMEOUT]
maker_timeout_sec = 60
unconfirm_timeout_sec = 180
confirm_timeout_hours = 6

[POLICY]
# Use segwit style wallets and transactions
# Only set to false for old wallets, Joinmarket is now segwit only.
segwit = true

# Use native segwit (bech32) wallet. If set to false, p2sh-p2wkh
# will be used when generating the addresses for this wallet.
# Notes: 1. The default joinmarket pit is native segwit.
#        2. You cannot change the type of a pre-existing wallet.
native = true

# for dust sweeping, try merge_algorithm = gradual
# for more rapid dust sweeping, try merge_algorithm = greedy
# for most rapid dust sweeping, try merge_algorithm = greediest
# but don't forget to bump your miner fees!
merge_algorithm = default

# The fee estimate is based on a projection of how many satoshis
# per kB are needed to get in one of the next N blocks, N set here
# as the value of 'tx_fees'. This cost estimate is high if you set
# N=1, so we choose 3 for a more reasonable figure, as our default.
# You can also set your own fee/kb: any number higher than 1000 will
# be interpreted as the fee in satoshi per kB that you wish to use
# example: N=30000 will use 30000 sat/kB as a fee, while N=5
# will use the estimate from your selected blockchain source
tx_fees = 3

# Transaction fee rate variance factor, 0.2 means 20% variation around
# any manually chosen values, so if you set tx_fees=10000 and
# tx_fees_factor=0.2, it might use any value between 8000 and 12000 for
# your transactions.
tx_fees_factor = 0.2

# For users getting transaction fee estimates over an API,
# place a sanity check limit on the satoshis-per-kB to be paid.
# This limit is also applied to users using Core, even though
# Core has its own sanity check limit, which is currently
# 1,000,000 satoshis.
absurd_fee_per_kb = 350000

# In decimal, the maximum allowable change either lower or
# higher, that the fee rate used for coinjoin sweeps is
# allowed to be.
# (note: coinjoin sweeps *must estimate* fee rates;
# they cannot be exact due to the lack of change output.)
#
# Example: max_sweep_fee_change = 0.4, with tx_fees = 10000,
# means actual fee rate achieved in the sweep can be as low
# as 6000 sats/kilo-vbyte up to 14000 sats/kilo-vbyte.
#
# If this is not achieved, the transaction is aborted. For tumbler,
# it will then be retried until successful.
# WARNING: too-strict setting may result in using up a lot
# of PoDLE commitments, hence the default 0.8 (80%).
max_sweep_fee_change = 0.8

# Maximum absolute coinjoin fee in satoshi to pay to a single
# market maker for a transaction. Both the limits given in
# max_cj_fee_abs and max_cj_fee_rel must be exceeded in order
# to not consider a certain offer.
#max_cj_fee_abs = x

# Maximum relative coinjoin fee, in fractions of the coinjoin value
# e.g. if your coinjoin amount is 2 btc (200000000 satoshi) and
# max_cj_fee_rel = 0.001 (0.1%), the maximum fee allowed would
# be 0.002 btc (200000 satoshi)
#max_cj_fee_rel = x

# the range of confirmations passed to the `listunspent` bitcoind RPC call
# 1st value is the inclusive minimum, defaults to one confirmation
# 2nd value is the exclusive maximum, defaults to most-positive-bignum (Google Me!)
# leaving it unset or empty defers to bitcoind's default values, ie [1, 9999999]
#listunspent_args = []
# that's what you should do, unless you have a specific reason, eg:
#  !!! WARNING !!! CONFIGURING THIS WHILE TAKING LIQUIDITY FROM
#  !!! WARNING !!! THE PUBLIC ORDERBOOK LEAKS YOUR INPUT MERGES
#  spend from unconfirmed transactions:  listunspent_args = [0]
# display only unconfirmed transactions: listunspent_args = [0, 1]
# defend against small reorganizations:  listunspent_args = [3]
#   who is at risk of reorganization?:   listunspent_args = [0, 2]
# NB: using 0 for the 1st value with scripts other than wallet-tool could cause
# spends from unconfirmed inputs, which may then get malleated or double-spent!
# other counterparties are likely to reject unconfirmed inputs... don't do it.

# tx_broadcast: options: self, random-peer, not-self.
#
# self = broadcast transaction with your own bitcoin node.
#
# random-peer = everyone who took part in the coinjoin has a chance of broadcasting
# note: if your counterparties do not support it, you will fall back
# to broadcasting via your own node.
#
# not-self = never broadcast with your own bitcoin node.
# note: in this case if your counterparties do not broadcast for you, you
# will have to broadcast the tx manually (you can take the tx hex from the log
# or terminal) via some other channel. It is not recommended to choose this
# option when running schedules/tumbler.

tx_broadcast = random-peer

# If makers do not respond while creating a coinjoin transaction,
# the non-responding ones will be ignored. This is the minimum
# amount of makers which we are content with for the coinjoin to
# succeed. Less makers means that the whole process will restart
# after a timeout.
minimum_makers = 4

# Threshold number of satoshis below which an incoming utxo
# to a reused address in the wallet will be AUTOMATICALLY frozen.
# This avoids forced address reuse attacks; see:
# https://en.bitcoin.it/wiki/Privacy#Forced_address_reuse
#
# The default is to ALWAYS freeze a utxo to an already used address,
# whatever the value of it, and this is set with the value -1.
max_sats_freeze_reuse = -1

# Interest rate used when calculating the value of fidelity bonds created
# by locking bitcoins in timelocked addresses
# See also:
# https://gist.github.com/chris-belcher/87ebbcbb639686057a389acb9ab3e25b#determining-interest-rate-r
# Set as a real number, i.e. 1 = 100% and 0.01 = 1%
interest_rate = 0.015

# Some makers run their bots to mix their funds not just to earn money
# So to improve privacy very slightly takers dont always choose a maker based
# on his fidelity bond but allow a certain small percentage to be chosen completely
# randomly without taking into account fidelity bonds
# This parameter sets how many makers on average will be chosen regardless of bonds
# A real number, i.e. 1 = 100%, 0.125 = 1/8 = 1 in every 8 makers on average will be bondless
bondless_makers_allowance = 0.125

##############################
#THE FOLLOWING SETTINGS ARE REQUIRED TO DEFEND AGAINST SNOOPERS.
#DON'T ALTER THEM UNLESS YOU UNDERSTAND THE IMPLICATIONS.
##############################

# number of retries allowed for a specific utxo, to prevent DOS/snooping.
# Lower settings make snooping more expensive, but also prevent honest users
# from retrying if an error occurs.
taker_utxo_retries = 3

# number of confirmations required for the commitment utxo mentioned above.
# this effectively rate-limits a snooper.
taker_utxo_age = 5

# percentage of coinjoin amount that the commitment utxo must have
# as a minimum BTC amount. Thus 20 means a 1BTC coinjoin requires the
# utxo to be at least 0.2 btc.
taker_utxo_amtpercent = 20

#Set to 1 to accept broadcast PoDLE commitments from other bots, and
#add them to your blacklist (only relevant for Makers).
#There is no way to spoof these values, so the only "risk" is that
#someone fills your blacklist file with a lot of data.
accept_commitment_broadcasts = 1

#Location of your commitments.json file (stores commitments you've used
#and those you want to use in future), relative to the scripts directory.
commit_file_location = cmtdata/commitments.json

##############################
# END OF ANTI-SNOOPING SETTINGS
##############################

[PAYJOIN]
# for the majority of situations, the defaults
# need not be altered - they will ensure you don't pay
# a significantly higher fee.
# MODIFICATION OF THESE SETTINGS IS DISADVISED.

# Payjoin protocol version; currently only '1' is supported.
payjoin_version = 1

# servers can change their destination address by default (0).
# if '1', they cannot. Note that servers can explicitly request
# that this is activated, in which case we respect that choice.
disable_output_substitution = 0

# "default" here indicates that we will allow the receiver to
# increase the fee we pay by:
# 1.2 * (our_fee_rate_per_vbyte * vsize_of_our_input_type)
# (see https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#span_idfeeoutputspanFee_output)
# (and 1.2 to give breathing room)
# which indicates we are allowing roughly one extra input's fee.
# If it is instead set to an integer, then that many satoshis are allowed.
# Additionally, note that we will also set the parameter additionafeeoutputindex
# to that of our change output, unless there is none in which case this is disabled.
max_additional_fee_contribution = default

# this is the minimum satoshis per vbyte we allow in the payjoin
# transaction; note it is decimal, not integer.
min_fee_rate = 1.1

# for payjoins as sender (i.e. client) to hidden service endpoints,
# the socks5 configuration:
onion_socks5_host = localhost
onion_socks5_port = 9050

# for payjoin onion service creation:
# the tor control configuration:
tor_control_host = localhost
# or, to use a UNIX socket
# control_host = unix:/var/run/tor/control
tor_control_port = 9051
# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
# is hardcoded to 80):
onion_serving_host = 127.0.0.1
onion_serving_port = 8080

# in some exceptional case the HS may be SSL configured,
# this feature is not yet implemented in code, but here for the
# future:
hidden_service_ssl = false

[YIELDGENERATOR]
# [string, 'reloffer' or 'absoffer'], which fee type to actually use
ordertype = reloffer

# [satoshis, any integer] / absolute offer fee you wish to receive for coinjoins (cj)
cjfee_a = 500

# [fraction, any str between 0-1] / relative offer fee you wish to receive based on a cj's amount
cjfee_r = 0.00002

# [fraction, 0-1] / variance around the average fee. Ex: 200 fee, 0.2 var = fee is btw 160-240
cjfee_factor = 0.1

# [satoshis, any integer] / the average transaction fee you're adding to coinjoin transactions
# (note: this will soon be deprecated; leave at zero)
txfee_contribution = 0

# [fraction, 0-1] / variance around the average fee. Ex: 1000 fee, 0.2 var = fee is btw 800-1200
txfee_contribution_factor = 0.3

# [satoshis, any integer] / minimum size of your cj offer. Lower cj amounts will be disregarded
minsize = 100000

# [fraction, 0-1] / variance around all offer sizes. Ex: 500k minsize, 0.1 var = 450k-550k
size_factor = 0.1

gaplimit = 6

[SNICKER]

# any other value than 'true' will be treated as False,
# and no SNICKER actions will be enabled in that case:
enabled = false

# in satoshis, we require any SNICKER to pay us at least
# this much (can be negative), otherwise we will refuse
# to sign it:
lowest_net_gain = 0

# comma separated list of servers (if port is omitted as :port, it
# is assumed to be 80) which we will poll against (all, in sequence); note
# that they are allowed to be *.onion or cleartext servers, and no
# scheme (http(s) etc) needs to be added to the start.
servers = cn5lfwvrswicuxn3gjsxoved6l2gu5hdvwy5l3ev7kg6j7lbji2k7hqd.onion,

# how many minutes between each polling event to each server above:
polling_interval_minutes = 60