SatsWire Install Guide: Jam for JoinMarket
A practical setup guide for Jam, JoinMarket, Bitcoin Core, Tor, and local-only privacy workflows.
Score Notes
Why this confidence score?
This score is an editorial signal based on source quality, corroboration, citations, and review status. It is not a guarantee of truth.
SatsWire Install Guide: Jam for JoinMarket
Jam is a modern web interface for JoinMarket, a Bitcoin privacy tool that helps users create collaborative transactions, provide liquidity, and earn sats by participating as market makers. The plain-English pitch is simple: your sats, your node, your privacy, your profit. Jam is not a custodial exchange, not a company-run mixer, and not a magic cloak. It is a user interface for a peer-to-peer Bitcoin liquidity market. Jam’s own site describes it as “a modern interface for JoinMarket,” with no central coordinator and no central point of failure. (Privacy for Yourself and Others)
Jam is also beta software. Treat it like sharp machinery: powerful, useful, but not something to blindly throw your whole stack into on day one. The official docs explicitly warn that Jam is beta, even though JoinMarket itself is more established. (Jam Docs)
What Jam Does
Jam gives normal users a cleaner way to use JoinMarket. Under the hood, JoinMarket coordinates Bitcoin users into collaborative transactions. These transactions can break simple chain-analysis assumptions, especially the Common Input Ownership Heuristic, because multiple participants contribute inputs into one transaction. Jam defaults to collaborative transactions for sending and sweeping, creating equal-output CoinJoins. (Jam Docs)
Jam also lets you operate in two broad roles:
Taker — you use other people’s liquidity to create a collaborative transaction. You pay miner fees and maker fees.
Maker — you provide liquidity to the JoinMarket order book. Other users can take your offer, and you may earn sats for waiting around with useful liquidity. The margins are usually thin, and earnings depend on market conditions, offer competitiveness, and liquidity size. (Jam Docs)
In Jam terms, your sats are separated into jars, which are privacy buckets. Jam uses five jars by default, and you can only spend from one jar at a time to avoid degrading your own privacy model. (Jam Docs)
How Jam Works
At a high level, Jam is the cockpit. JoinMarket is the engine. Bitcoin Core is the chain interface. Tor is the privacy network layer. The order book is the marketplace.
The flow looks like this:
Browser
↓
Jam UI
↓
JoinMarket wallet daemon / orderbook watcher
↓
Tor + JoinMarket peer network
↓
Bitcoin Core RPC
↓
Bitcoin network
When you send through Jam, Jam talks to JoinMarket services, selects suitable makers from the market, constructs a collaborative Bitcoin transaction, and broadcasts it through your Bitcoin Core setup. When you run Earn mode, your node stays online as a maker and advertises liquidity offers. Makers set their own fees, takers decide whether to accept them, and everyone still pays normal on-chain miner fees. (Jam Docs)
Jam also supports scheduled sweep behavior. The scheduler can create multiple collaborative transactions using randomized intervals and amounts, which helps reduce timing analysis compared with a single obvious movement. (Jam Docs)
Before You Install
You need one of the following:
- A packaged Bitcoin node system such as Umbrel, Citadel, RaspiBlitz, MyNode, Start9, or RaspiBolt.
- Or a manual Linux/Docker setup with Bitcoin Core already synced.
- A password manager.
- A small test amount of bitcoin.
- Patience. Privacy tooling punishes the rushed.
Old Bitcoin setup discipline still applies: use official sources, verify what you can, and do not download wallet or node software from random mirrors. That old miner-guide instinct is still correct in the modern privacy stack.
Recommended Install Path: Full-Node App Store
The easiest path is to install Jam through a supported node platform. The official installation docs list Umbrel, Citadel, RaspiBlitz, MyNode, Start9, and RaspiBolt as supported packaging routes. (Jam Docs)
Umbrel
- Open your Umbrel node dashboard.
- Go to
umbrel.localin your browser. - Open the app store.
- Search for
Jam. - Click Install.
- Launch Jam once installation completes.
Citadel
- Open your Citadel node dashboard.
- Go to
citadel.local. - Open the Citadel app store.
- Search for
Jam. - Click Install.
- If prompted, use
citadelas the username and the password provided by Citadel. (Jam Docs)
RaspiBlitz
Jam can be installed through the RaspiBlitz WebUI on newer RaspiBlitz versions. It can also be installed from the command line:
patch
config.scripts/bonus.joinmarket-webui.sh on
Then display connection details with:
config.scripts/bonus.joinmarket-webui.sh menu
MyNode
- Open your MyNode dashboard.
- Go to
mynode.local. - Open the Marketplace.
- Install JoinMarket first, if needed.
- Search for
Jam. - Click Install.
Start9
- Open your Start9 / EmbassyOS dashboard.
- Open the Marketplace.
- Search for
Jam. - Click Install.
- Launch Jam from the service page.
Manual Docker Install
Manual installation gives you more control, but also more rope to hang yourself with. The official docs list three manual approaches: standalone Docker image, connecting Jam to a local JoinMarket instance, or connecting Jam to a remote JoinMarket instance. The Docker standalone route is the simplest because the image bundles JoinMarket and Tor and starts the required subservices. (Jam Docs)
Prerequisites
You need:
Bitcoin Core
Docker
A reachable Bitcoin Core RPC endpoint
Set a Jam version variable. Check the current GitHub release before production use; the GitHub repository currently lists v0.4.1 - Happy Honeydew as the latest visible release in the repository page I checked. (GitHub)
export jam_version="v0.4.1"
Generate strong passwords:
openssl rand -base64 32
openssl rand -base64 32
Create a persistent Docker volume:
docker volume create jmdatadir
Docker: Remote Bitcoin Core Node
Use this when Bitcoin Core runs on another machine, such as a dedicated node on your LAN:
docker run --rm -it \
--env JM_RPC_HOST="192.168.1.10" \
--env JM_RPC_PORT="8332" \
--env JM_RPC_USER="BTC_RPC_USERNAME" \
--env JM_RPC_PASSWORD="BTC_RPC_PASSWORD" \
--env APP_USER="jam" \
--env APP_PASSWORD="CHANGE_THIS_LONG_RANDOM_PASSWORD" \
--env ENSURE_WALLET="true" \
--env REMOVE_LOCK_FILES="true" \
--env RESTORE_DEFAULT_CONFIG="true" \
--volume jmdatadir:/root/.joinmarket \
--publish "127.0.0.1:8080:80" \
ghcr.io/joinmarket-webui/jam-standalone:${jam_version}
Then open:
http://localhost:8080
The official docs publish 8080:80; binding to 127.0.0.1:8080:80 is the safer local-only variant. Do not expose Jam directly to the public internet. Use an SSH tunnel or a properly secured private network if you need remote access.
Docker: Bitcoin Core on the Same Host
When Bitcoin Core runs on the same machine as Docker, add Docker’s host gateway and point Jam at host.docker.internal:
docker run --rm -it \
--add-host=host.docker.internal:host-gateway \
--env JM_RPC_HOST="host.docker.internal" \
--env JM_RPC_PORT="8332" \
--env JM_RPC_USER="BTC_RPC_USERNAME" \
--env JM_RPC_PASSWORD="BTC_RPC_PASSWORD" \
--env APP_USER="jam" \
--env APP_PASSWORD="CHANGE_THIS_LONG_RANDOM_PASSWORD" \
--env ENSURE_WALLET="true" \
--env REMOVE_LOCK_FILES="true" \
--env RESTORE_DEFAULT_CONFIG="true" \
--volume jmdatadir:/root/.joinmarket \
--publish "127.0.0.1:8080:80" \
ghcr.io/joinmarket-webui/jam-standalone:${jam_version}
Then open:
http://localhost:8080
Manual UI-Only Install Against Existing JoinMarket
Use this path only when you already run Bitcoin Core, Tor, and JoinMarket.
Jam expects JoinMarket services such as jmwalletd and ob-watcher. The official docs recommend binding these services to 127.0.0.1, not 0.0.0.0, so they are not exposed across your LAN. (Jam Docs)
Create a self-signed certificate inside your JoinMarket working directory:
cd ~/.joinmarket
mkdir ssl
cd ssl
openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes \
-out cert.pem -keyout key.pem \
-subj "/C=US/ST=Local/L=Local/O=SatsWire/OU=Node/CN=localhost"
Start jmwalletd from your JoinMarket root directory:
cd ~/joinmarket-clientserver
. jmvenv/bin/activate
python3 scripts/jmwalletd.py
Start the orderbook watcher:
cd ~/joinmarket-clientserver
. jmvenv/bin/activate
python3 scripts/obwatch/ob-watcher.py --host=127.0.0.1
Run Jam UI through Docker:
docker run --rm -it \
--add-host=host.docker.internal:host-gateway \
--env JAM_JMWALLETD_HOST="host.docker.internal" \
--env JAM_JMWALLETD_API_PORT="28183" \
--env JAM_JMWALLETD_WEBSOCKET_PORT="28283" \
--env JAM_JMOBWATCH_PORT="62601" \
--publish "127.0.0.1:3000:80" \
ghcr.io/joinmarket-webui/jam-ui-only:${jam_version}
Then open:
http://localhost:3000
First Use
After Jam opens, log in with the APP_USER and APP_PASSWORD you configured. Create a new wallet or import an existing JoinMarket wallet.
Write down the seed phrase offline before adding meaningful funds. Jam’s FAQ says the wallet password encrypts the wallet file, but the mnemonic seed is what recovers funds on another device. That password is not an extra mnemonic word. (Jam Docs)
Start with a small test deposit. Let it confirm. Learn the interface before you start moving real value. Privacy software is not the place to freestyle with rent money.
Basic Use
Receive
Use the Receive screen to generate a fresh Bitcoin address. Jam defaults to Bech32 addresses. Avoid address reuse; it harms privacy.
Send
Use Send when you want to make a payment from one jar. Jam will attempt a collaborative transaction by default. You are the taker, so you pay maker fees and mining fees.
Sweep
Use Sweep when you want to move all funds from a jar, or all funds from the wallet. Jam’s sweep behavior can use multiple scheduled collaborative transactions. This can take longer than a normal transaction, so do not panic if it is not instant.
Earn
Use Earn when you want to run as a maker. You choose offer parameters, keep your wallet active, and wait for takers. Competitive offers matter. If your offer is too expensive, nobody may take it. Fidelity bonds can improve your chance of being selected, but bonded funds are timelocked and cannot be moved until expiry. (Jam Docs)
Operating Rules
Keep the machine online if you are earning. The browser tab does not have to remain open, but the wallet must stay active, and the rest of the setup must keep running. This applies to taker activity such as Send/Sweep and maker activity such as Earn. (Jam Docs)
Check fees before sending. Collaborative transactions are larger than simple Bitcoin spends, so they can cost more in miner fees. Maker fees also vary by market conditions.
Use your own Bitcoin Core node. The whole point is reducing trust. A privacy stack glued to someone else’s node is like wearing a mask and handing out your home address.
Do not expose Jam to the public internet. Keep it local, behind VPN, or behind an SSH tunnel. No random open ports. No cowboy dashboard on 0.0.0.0.
Troubleshooting
“No connection to gateway”
Check that Bitcoin Core is running, fully synced, and accepting RPC requests:
bitcoin-cli getblockchaininfo
Check whether the backend API responds:
curl --insecure https://127.0.0.1:28183/api/v1/session
For standalone Docker logs:
docker ps
docker exec -it <container_id> bash
tail -n 200 -f /var/log/jam/jmwalletd_stdout.log
tail -n 200 -f /var/log/jam/jmwalletd_stderr.log
Jam’s FAQ points to Bitcoin Core sync/RPC, backend reachability, logs, service restart, and full node reboot as the core troubleshooting path. (Jam Docs)
Wallet locked error
You may see:
wallet.jmdat cannot be created/opened, it is locked.
Do not start deleting files like a caffeinated raccoon. First confirm that your seed phrase is written down. Then follow the Jam FAQ guidance for removing the stale wallet lock file. (Jam Docs)
Collaborative transaction takes too long
A single collaborative transaction usually takes minutes, but Tor issues, unresponsive participants, source commitment issues, slow block production, or sudden fee changes can delay it. Jam’s FAQ gives rough expectations of under 15 minutes for a single collaborative transaction and potentially hours or days for scheduled sweeps. (Jam Docs)
Your offer does not show in the order book
Wait, refresh, and compare your offer against the market. There is no one universal order book view; nodes may see offers differently depending on message channels and directory nodes. Also, if your fee is wildly above market, the market will ignore you with brutal honesty.
Security Notes
- Verify releases where possible.
- Use strong unique passwords.
- Back up the mnemonic seed offline.
- Keep Jam local-only unless you know exactly what you are doing.
- Start with small amounts.
- Keep Bitcoin Core, Docker, and your node OS patched.
- Do not use privacy tools to conceal criminal proceeds. Privacy is normal. Crime is crime. Do not confuse the two.
Final Verdict
Jam is the friendlier face of JoinMarket: a browser-based control panel for collaborative Bitcoin transactions, liquidity provision, order-book inspection, scheduled sweeps, PayJoin support, and maker/taker privacy workflows. It is not beginner-proof, but it is far more approachable than raw JoinMarket command-line work. The clean SatsWire take: install it through your node app store if possible; use Docker only if you understand your Bitcoin Core RPC path; test small; keep it local; and never trust a privacy tool you have not learned to operate.