-
Notifications
You must be signed in to change notification settings - Fork 14
How to setup a headless node for Bisq Connect apps
Most people don't need this page. Building from source is the advanced / last-resort option — for development or platforms without a packaged build. For an always-on node, the easy paths are a one-click Umbrel app, a Docker image downloadable from Bisq packages, or Bisq2 Desktop — see all ways to run your own node in the main guide.
This guide walks you through building and running a headless Bisq2 Trusted Node from source — a background process (no Desktop UI) that your Bisq Connect mobile app connects to. Useful for development, or servers/platforms not covered by the packaged options above.
- A computer or server (Linux, macOS, or Windows)
- Java 21 installed (Download here)
- Git installed
- Familiarity with the terminal / command line
Note: This page builds the node from source. Prebuilt/packaged options now exist too — see the callout at the top (Umbrel App Store, Docker, or Bisq2 Desktop).
git clone https://github.com/bisq-network/bisq2.git
cd bisq2Each Bisq Connect release is prepared to work against a specific version of Bisq2. Before building, you need to switch to the branch prepared for Bisq Connect.
git checkout for-mobile-based-on-2.1.10
./gradlew apps:api-app:clean apps:api-app:installDistThe build output will be at:
apps/api-app/build/install/api-app/
Before configuring, decide how your mobile device will connect. There are several configurations across two transport types (Clearnet and Tor), varying by TLS encryption, session handling, authorization, and Tor client auth.
| ID | TLS | Sessions | Auth | Real Devices | Description |
|---|---|---|---|---|---|
| C1 | Off | Off | Off | Emulator only | Plain HTTP, no security. For local dev/testing only. |
| C2 | Off | On | On | Emulator only | HTTP with session tokens and auth headers. Dev/testing only. |
| C3 | On | Off | Off | Yes | HTTPS with certificate pinning. Encrypted but no session management. |
| C4 | On | On | On | Yes | Full clearnet security: HTTPS + sessions + auth. Recommended for LAN. |
| C5 | On | On (no expiry) | On | Yes | Same as C4 but sessions never expire (TTL=-1). Convenient for always-on setups. |
Why is TLS mandatory for LAN? Real mobile devices on your WiFi cannot reach
localhost— the node must bind to a LAN IP. When bound this way, pairing tokens and session credentials travel over your local network, so TLS is required to prevent cleartext interception. C1 and C2 (no TLS) only work on emulators running on the same machine as the node, wherelocalhostis reachable.
| ID | TLS | Sessions | Auth | Description |
|---|---|---|---|---|
| T1 | Off | Off | Off | Plain Tor onion service, no extra security. Tor encryption only. |
| T2 | Off | On | On | Tor + session tokens + auth headers. Recommended for Tor. |
Note: Tor v3 client authentication and TLS over Tor are not yet implemented. These features may be added in a future release.
| Speed | Privacy | Works Remotely | Real Device Support | Recommended For | |
|---|---|---|---|---|---|
| C1–C2 | Fast | None | No | Emulator only | Development / testing |
| C3 | Fast | Good | No | Yes (Android + iOS) | Quick LAN setup |
| C4–C5 | Fast | Good | No | Yes (Android + iOS) | Daily home use |
| T1 | Slower | High | Yes | Yes (Android + iOS) | Basic remote access |
| T2 | Slower | High | Yes | Yes (Android + iOS) | Recommended for Tor |
Our recommendation: Use C4 (LAN + TLS + sessions) for home use and T2 (Tor + sessions + auth) for remote access. Both provide strong security with good usability.
The configuration file is located at:
bisq2/apps/api-app/src/main/resources/api_app.conf
Edit the application.api section based on your chosen mode. Below are the three main profiles:
The fastest way to test locally with an emulator. Not suitable for real devices on LAN — use Profile B instead.
application {
api {
accessTransportType = "CLEAR"
pairing {
ttlInSeconds = 3600
writePairingQrCodeToDisk = true
}
server {
websocketEnabled = true
bind {
host = "127.0.0.1"
port = 8090
}
tls {
required = false
}
security {
supportSessionHandling = false
authorizationRequired = false
}
}
}
}Warning: Without TLS, pairing tokens and session credentials are sent in cleartext. This only works with emulators on the same machine (localhost). For real devices, TLS is mandatory — see Profile B.
Encrypted connections with certificate pinning. Your mobile app will verify the server's identity via a SHA-256 fingerprint embedded in the QR code.
application {
api {
accessTransportType = "CLEAR"
pairing {
ttlInSeconds = 3600
writePairingQrCodeToDisk = true
}
server {
websocketEnabled = true
bind {
host = "192.168.1.100" # Your LAN IP — see instructions below
port = 8090
}
tls {
required = true
keystore {
password = "changeme_min8chars" # Min 8 chars
}
certificate {
san = ["127.0.0.1", "192.168.1.100"] # Add your LAN IP here!
}
}
security {
supportSessionHandling = true
authorizationRequired = true
session {
ttlInMinutes = 60 # Set to -1 to disable session expiry
}
}
}
}
}Important: Set bind.host to your computer's LAN IP address and add it to the tls.certificate.san list. The self-signed certificate will include these addresses as Subject Alternative Names, and the mobile app verifies the connection against them.
To find your LAN IP:
Linux:
hostname -I | awk '{print $1}'macOS:
ipconfig getifaddr en0Windows:
ipconfig(Look for "IPv4 Address" under your active network adapter, e.g. 192.168.1.100)
Maximum privacy. Your node publishes a Tor onion service and the mobile app connects through Tor automatically.
application {
api {
accessTransportType = "TOR"
pairing {
ttlInSeconds = 3600
writePairingQrCodeToDisk = true
}
server {
websocketEnabled = true
bind {
host = "127.0.0.1" # Keep localhost — Tor onion service forwards to loopback
port = 8090
}
tor {
onionServicePort = 80
}
tls {
required = false # Not needed over Tor (already encrypted)
}
security {
supportSessionHandling = true
authorizationRequired = true
session {
ttlInMinutes = 60
}
}
}
}
}The node will automatically:
- Bootstrap Tor (2–5 minutes on first run)
- Generate a
.onionaddress - Embed the onion address in the pairing QR code / pairing token
JAVA_OPTS="-Dapplication.appName=bisq2_http_prod \
-Dapplication.devMode=false \
-Dapplication.network.supportedTransportTypes.0=TOR" \
apps/api-app/build/install/api-app/bin/api-appFor LAN-only (no Tor):
JAVA_OPTS="-Dapplication.appName=bisq2_http_prod \
-Dapplication.devMode=false \
-Dapplication.network.supportedTransportTypes.0=CLEAR" \
apps/api-app/build/install/api-app/bin/api-appWhat happens next:
- The node starts up and joins the Bisq Easy p2p network
- If using Tor: Tor bootstraps (2–5 minutes the first time) and your onion address is generated
- The WebSocket server starts on the configured port (default: 8090)
- A pairing QR code is generated (and saved to disk as a pairing token)
Keep this terminal window open — your node needs to stay running for your mobile app to connect.
The QR code is your single trust anchor — it contains everything your mobile app needs to connect securely:
- The WebSocket URL (LAN IP or
.onionaddress) - A TLS certificate fingerprint (if TLS is enabled)
- A Tor client auth secret (if client auth is enabled)
- A one-time pairing code (expires after 5 minutes)
If writePairingQrCodeToDisk = true in your config, the QR code data is written to:
Linux:
cat ~/.local/share/<appName>/pairing_qr_code.txtmacOS:
cat ~/Library/Application\ Support/<appName>/pairing_qr_code.txtWindows:
type %USERPROFILE%\.local\share\<appName>\pairing_qr_code.txtReplace <appName> with your configured app name (e.g. bisq2_http_prod).
This file contains a Base64-encoded string. You can:
- Convert it to a scannable QR code image using any QR code generator tool, or
- Transfer the string to the mobile device and paste it directly in the app
Security note: The pairing QR code expires after 5 minutes. The node generates a new one periodically or when the previous token has been used. If the code expires or is no longer valid, you will find the new one in the same file.
Next step: Go to Pair Your Mobile Device in the main Bisq Connect Guide.
- Another program is using port 8090
- Edit
api_app.confand changeport = 8090to another port (e.g.8091) - Rebuild and restart your trusted node
- Generate a new QR code (the port is embedded in it)
- Tor takes 2–5 minutes to bootstrap the first time
- Check your internet connection
- Make sure ports are not blocked by your firewall
- Check the node's terminal output for error messages
See the Troubleshooting section in the main Bisq Connect Guide.
If you want to serve multiple users (e.g., family members), run separate node instances with different app names and ports. This is recommended because a paired device has control over all profiles on its node instance (except the first profile).
For example, one for Alice and one for Bob:
- Alice:
appName=bisq2_alice, port8090 - Bob:
appName=bisq2_bob, port8091
Each instance gets its own data directory automatically based on appName:
# Terminal 1 — Alice's node
JAVA_OPTS="-Dapplication.appName=bisq2_alice \
-Dapplication.devMode=false \
-Dapplication.network.supportedTransportTypes.0=TOR" \
apps/api-app/build/install/api-app/bin/api-app
# Terminal 2 — Bob's node
JAVA_OPTS="-Dapplication.appName=bisq2_bob \
-Dapplication.devMode=false \
-Dapplication.websocket.server.port=8091 \
-Dapplication.network.supportedTransportTypes.0=TOR" \
apps/api-app/build/install/api-app/bin/api-appEach node will:
- Have its own data directory (
~/.local/share/bisq2_alice/,~/.local/share/bisq2_bob/, etc.) - Generate its own Tor onion address
- Produce its own pairing QR code
- Operate completely independently
Share the corresponding QR code / pairing token with each user. Alice scans Alice's, Bob scans Bob's.
To ensure your Bisq Trusted Node starts automatically when your computer boots:
-
Linux: Use
systemd(systemctl) -
macOS: Use a
launchdplist - Windows: Use Task Scheduler