# Copyright 1999-2026 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
PYTHON_COMPAT=( python3_{11..13} )
PYTHON_REQ_USE="sqlite,ssl"
DISTUTILS_SINGLE_IMPL=1
DISTUTILS_USE_PEP517=setuptools
inherit backports desktop distutils-r1 qmake-utils
MyPN=${PN}-clientserver
BACKPORTS=(
)
DESCRIPTION="JoinMarket CoinJoin client and daemon"
HOMEPAGE="https://github.com/JoinMarket-Org/joinmarket-clientserver"
BACKPORTS_BASE_URI="${HOMEPAGE}/commit/"
SRC_URI="${HOMEPAGE}/archive/v${PV}.tar.gz -> ${P}.tar.gz
test? (
https://github.com/JoinMarket-Org/miniircd/archive/20a391f490a58ba9ef295b0d813a95a7e9337382.tar.gz -> ${PN}-miniircd.tar.gz
)
$(backports_patch_uris)
"
LICENSE="GPL-3"
SLOT="0"
KEYWORDS="~amd64 ~arm64 ~x86"
IUSE="+client +daemon gui"
REQUIRED_USE="
client? ( daemon )
gui? ( client !python_single_target_python3_12 !python_single_target_python3_13 )
test? ( client )
"
RDEPEND="
$(python_gen_cond_dep '
>=dev-python/chromalog-1.0.5[${PYTHON_USEDEP}]
>=dev-python/cryptography-3.3.2[${PYTHON_USEDEP}]
amd64? ( >=dev-python/cryptography-42.0.4[${PYTHON_USEDEP}] )
arm64? ( >=dev-python/cryptography-42.0.4[${PYTHON_USEDEP}] )
>=dev-python/service-identity-21.1.0[${PYTHON_USEDEP}]
>=dev-python/twisted-24.7.0[${PYTHON_USEDEP}]
>=dev-python/txtorcon-23.11.0[${PYTHON_USEDEP}]
client? (
>=dev-python/argon2-cffi-21.3.0[${PYTHON_USEDEP}]
>=dev-python/autobahn-20.12.3[${PYTHON_USEDEP}]
>=dev-python/fastbencode-0.3.6[${PYTHON_USEDEP}]
>=dev-python/klein-20.6.0[${PYTHON_USEDEP}]
>=dev-python/mnemonic-0.20[${PYTHON_USEDEP}]
>=dev-python/pyjwt-2.4.0[${PYTHON_USEDEP}]
>=dev-python/python-bitcointx-1.1.5[${PYTHON_USEDEP}]
>=dev-python/werkzeug-2.2.3[${PYTHON_USEDEP}]
)
daemon? (
>=dev-python/libnacl-1.8.0[${PYTHON_USEDEP}]
>=dev-python/pyopenssl-24.0.0[${PYTHON_USEDEP}]
)
gui? (
dev-python/pillow[${PYTHON_USEDEP}]
>=dev-python/pyside2-5.14.2[gui,widgets,${PYTHON_USEDEP}]
>=dev-python/qrcode-7.3.1[${PYTHON_USEDEP}]
>=dev-python/qt5reactor-0.6.3[${PYTHON_USEDEP}]
)
')
client? (
>=dev-libs/libsecp256k1-0.5.0[ecdh,recovery]
)
"
DEPEND=""
BDEPEND="
$(python_gen_cond_dep '
test? (
dev-python/freezegun[${PYTHON_USEDEP}]
dev-python/mock[${PYTHON_USEDEP}]
dev-python/pexpect[${PYTHON_USEDEP}]
>=dev-python/pytest-6.2.5[${PYTHON_USEDEP}]
!!<dev-python/pytest-twisted-1.13.4-r1[${PYTHON_USEDEP}]
)
')
gui? (
dev-qt/qtwidgets
)
test? (
net-p2p/bitcoin-core[cli,daemon,wallet]
)
"
S="${WORKDIR}/${MyPN}-${PV}"
distutils_enable_tests pytest
efmt() {
: ${1:?} ; local l ; while read -r l ; do "${!#}" "${l}" ; done < <(fmt "${@:1:$#-1}")
}
pkg_setup() {
use test && has_version -b '>=net-p2p/bitcoin-core-30.0' && efmt ewarn <<-EOF
Test failures are expected with >=net-p2p/bitcoin-core-30.0, which no
longer supports non-descriptor wallets. See ${HOMEPAGE}/issues/1841.
EOF
python-single-r1_pkg_setup
}
src_unpack() {
unpack "${P}.tar.gz" $(usev test "${PN}-miniircd.tar.gz")
use client || rm -r "${S}"/{src,test}/{jmbitcoin,jmclient} || die
use daemon || rm -r "${S}"/{src,test}/jmdaemon || die
use gui || rm -r "${S}/src/jmqtui" || die
use !test || mv miniircd-* "${S}/miniircd" || die
}
src_prepare() {
backports_apply_patches
sed -e 's|^\(Exec=\).*$|\1joinmarket-qt.py|' \
-e '/^Name=/a Categories=Network;P2P;Qt;' \
-i joinmarket-qt.desktop || die
# Gentoo is not affected by https://bugreports.qt.io/browse/QTBUG-88688
sed -e 's/\(PySide2\|PyQt5\)!=5\.15\.0,!=5\.15\.1,!=5\.15\.2,!=6\.0/\1/' \
-e 's/\s*#.*QTBUG-88688$//' \
-i pyproject.toml || die
# PySide2 no longer ships pyside2-uic in favor of 'uic -g python'
# https://bugreports.qt.io/browse/PYSIDE-1098
if use gui ; then
local UIC="$(qt5_get_bindir)/uic"
sed -e 's:\(os\.system('\''\)pyside2-uic:\1'"${UIC//:/\\:}"' -g python:' \
-i src/jmqtui/_compile.py || die
fi
# fix "ValueError: 'int' is not callable" with >=dev-python/pytest-8
sed -e 's/type="int"/type=int/' -i conftest.py || die
distutils-r1_src_prepare
}
python_test() {
ln -sfn test/regtest_joinmarket.cfg joinmarket.cfg || die
local jm_test_datadir=${T}/jm_test_home/.bitcoin
rm -rf -- "${jm_test_datadir}" || die
mkdir -p -- "${jm_test_datadir}" || die
local btcconf=${jm_test_datadir}/bitcoin.conf
cp -f -- test/bitcoin.conf "${btcconf}" || die
echo "datadir=${jm_test_datadir}" >>"${btcconf}" || die
# https://github.com/bitcoin/bitcoin/pull/28597
if has_version '>=net-p2p/bitcoin-core-26' ; then
echo 'deprecatedrpc=create_bdb' >>"${btcconf}" || die
fi
# https://github.com/bitcoin/bitcoin/pull/30493
# https://github.com/JoinMarket-Org/joinmarket-clientserver/issues/1734
if has_version '>=net-p2p/bitcoin-core-28' ; then
echo 'mempoolfullrbf=0' >>"${btcconf}" || die
fi
epytest \
test \
--nirc=2 \
--btcconf="${btcconf}" \
$(sed -n \
-e 's/^rpcuser=\(.*\)$/--btcuser=\1/p' \
-e 's/^rpcpassword=\(.*\)$/--btcpwd=\1/p' \
"${btcconf}")
}
src_install() {
distutils-r1_src_install
scripts_to_install() {
{
ls -1 scripts/*.py
find scripts/*.py "${@}" -perm /0111
use client || grep -l '\bjmclient\b' scripts/*.py
use daemon || grep -l '\bjmdaemon\b' scripts/*.py
use gui || grep -l '\bPySide2\b' scripts/*.py
} | sort | uniq -u
}
local install=( $(scripts_to_install) )
(( ${#install[@]} )) && python_domodule "${install[@]}"
local install=( $(scripts_to_install !) )
(( ${#install[@]} )) && python_doscript "${install[@]}"
dodoc -r README.md docs/{*.md,images,release-notes}
newdoc scripts{/,-}README.md
if use gui ; then
doicon docs/images/joinmarket_logo.png
domenu joinmarket-qt.desktop
fi
}
pkg_preinst() {
has_version '<net-p2p/joinmarket-0.6.2' && had_pre_0_6_2=1
has_version '<net-p2p/joinmarket-0.8.0' && had_pre_0_8_0=1
has_version '<net-p2p/joinmarket-0.9.0' && had_pre_0_9_0=1
}
pkg_postinst() {
efmt elog <<-EOF
It is always a good idea to back up your joinmarket.cfg, re-create a
default one, and then reapply your changes, as this will populate any
newly introduced config settings and update any default values. Please
see the release notes for more information and important announcements:
${HOMEPAGE}/blob/master/docs/release-notes/release-notes-${PV}.md
EOF
[[ ${had_pre_0_6_2} ]] && efmt ewarn <<-EOF
This release of JoinMarket moves the user data directory to ~/.joinmarket.
You must manually move any existing data files. See the release notes:
${HOMEPAGE}/blob/master/docs/release-notes/release-notes-0.6.2.md#move-user-data-to-home-directory
EOF
[[ ${had_pre_0_8_0} ]] && efmt ewarn <<-EOF
JoinMarket is migrating to native SegWit wallets and transactions.
Please follow the upgrade guide at:
${HOMEPAGE}/blob/master/docs/NATIVE-SEGWIT-UPGRADE.md
EOF
[[ ${had_pre_0_9_0} ]] && efmt ewarn <<-EOF
JoinMarket has introduced fidelity bonds as a means of improving Sybil attack
resistance. You must manually update your wallet to a fidelity bond wallet if
you wish to take advantage of this new privacy-enhancing feature. See the
release notes for more information.
EOF
}