Desktop wallet

null-desktop is the NULL wallet with a full node built in. The window, the node, the wallet and an authenticated JSON-RPC server run in one process; it does not start nulld, a browser or any helper.

Install and run

The desktop wallet ships in every release archive for Linux, macOS and Windows, next to nulld. Verify the archive against SHA256SUMS, unpack it and start null-desktop. It needs a graphical desktop and an OpenGL-capable driver. Binaries are not code-signed, so macOS and Windows may warn on first launch.

Launch it without arguments. On mainnet it dials the seed nodes seed1 to seed5.nullnet.sh by itself and connects out only, so it needs no open ports.

./null-desktop

The first launch creates the application data directory and null.conf. Existing wallets and configuration files are never overwritten.

ItemLocation
Application dataLinux $XDG_DATA_HOME/null or ~/.local/share/null; macOS ~/Library/Application Support/Null; Windows %LOCALAPPDATA%\Null or %APPDATA%\Null
Settingsnull.conf in the application data directory
Chain<network>/chain/chain.redb
Wallet<network>/wallet.redb, found automatically
Address book<network>/chain/peers.dat (not written with a proxy)
RPC token<network>/desktop-rpc.token, new on every start
Log file<network>/debug.log, only when switched on

The Node screen shows these paths. The desktop wallet and a default nulld run use the same chain, so only one of them can run at a time.

Create or restore a wallet

On first launch choose one of:

  • Create a new wallet generates a 24-word recovery phrase. It is shown once. Write it down, then type back three randomly chosen words from your copy before the screen closes.
  • Import recovery phrase restores a wallet from an existing phrase, such as one from nulld create or another desktop install.

Both ask for a passphrase that encrypts the wallet on disk. Neither the phrase nor the passphrase is stored in null.conf. Later launches find the wallet and show only the unlock screen.

An unlocked wallet locks itself after 15 minutes without keyboard or pointer input; set lock_after_minutes in null.conf to change it, or 0 to turn it off. It does not lock while a request is running, while the recovery phrase is on screen, or while the miner runs. Lock by hand to stop everything.

Receive

Receive shows the newest address as a QR code with the address next to it. Show QR displays any other address of the wallet. Mainnet addresses start with null1.

Activity lists sent payments and received notes together, newest first, twenty to a page, dated in your computer's time zone. A mined reward is dated by the block that paid it. Change from your own payments is hidden unless Show change is ticked. Filter by sent, received or mined, and search by transaction id, address, label, memo or payment number such as #3. Text memos are shown on received notes.

Send

Send takes an address, a decimal NULL amount with up to eight places and an optional memo, and checks that the address belongs to the wallet's network.

  1. Review asks the wallet for the exact fee and total, choosing notes the way the payment will.
  2. Confirm queues the payment. The wallet builds, proves and submits it, and shows progress in Activity.
  3. A queued payment can be cancelled in Activity until it is proved.

The fee depends on the transaction's action class, which grows when many small notes are spent. Notes are chosen when the payment is built, so if notes arrive or other queued payments reserve some first, the final payment can differ slightly from its quote.

Consolidate inputs

Mining and many small deposits leave a wallet with lots of small notes, which makes later payments larger and more expensive. On Send, choose Consolidate inputs to combine them into larger notes at your main (index 0) address.

  1. Review the input count, number of transactions, destination and total network fee.
  2. Choose Confirm consolidation.

Each batch combines up to sixteen inputs and appears in Activity as a payment to yourself. No recipient address is needed. Wait for confirmation before spending the new notes; for a large wallet, run it again after confirmation to combine further. Pending payments keep their reserved notes. The wallet must be unlocked and scanned, and watch-only wallets cannot consolidate. The command line equivalent is nulld consolidate.

Mining

The Node screen has a Mining card with an on/off switch and a thread slider, from 1 to the number of CPUs (half by default). Mining needs an unlocked wallet and always pays the wallet's main address.

  • The switch can be turned on before the node is ready. The miner then waits without using CPU until the node has a peer and has caught up; the badge reads Waiting for sync with the reason.
  • Locking the wallet stops the miner. If mine = true is saved, it starts again on the next unlock.
  • Moving the slider while mining restarts the miner with the new thread count. Each thread needs about 1.8 GB of memory on mainnet.
  • The first start builds the coinbase proving key, which takes a few seconds.
  • The card shows the payout address, the blocks found this session and how many are in the main chain.

Rewards become spendable after 100 blocks. The switch saves mine and mining_threads to null.conf, keeping other settings and comments. See Mining for more.

Log file

The Log file card on the Node screen writes the node log to <network>/debug.log, the same lines nulld prints, dated in UTC. It applies at once and is saved as log_file. It is off by default because the log lists peer addresses and transaction ids; switch it on when reporting a problem. A log over 10 MiB is moved to debug.log.1, replacing the older one, when logging starts.

Settings

Edit null.conf (TOML) and restart to change saved settings:

null.conf

network = "main"
rpc = "127.0.0.1:18448"
connect = []
lock_after_minutes = 15
mine = false
mining_threads = 4
log_file = false
# listen = "0.0.0.0:19000"
# advertise = "203.0.113.10:19000"
# proxy = "127.0.0.1:9050"
KeyMeaning
networkmain or test
rpccombined RPC listener; loopback addresses only
connectextra peers to dial, as host:port
listenaccept peers on this address; allow the port through the firewall
advertisepublic endpoint to announce behind NAT; rejected together with proxy
proxySOCKS5 proxy for outbound peer connections, such as Tor
walletwallet file; a relative path resolves inside the network directory
lock_after_minutesidle minutes before locking; 0 disables
minemine whenever the wallet is unlocked
mining_threadsminer threads
log_filewrite debug.log

Command line flags override these for one launch; see null-desktop flags. Use separate --datadir directories and RPC ports to run several instances.

RPC

The desktop wallet serves the node and wallet JSON-RPC methods on one endpoint, 127.0.0.1:18448 by default, with the same bearer-token transport as nulld (see JSON-RPC). The token is in desktop-rpc.token in the network directory and changes on every start.

cURL

curl -H "Authorization: Bearer $(cat ~/.local/share/null/main/desktop-rpc.token)" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getblockchaininfo","params":[]}' \
  http://127.0.0.1:18448/
  • Wallet calls return REJECTED while the wallet is locked. Creating, importing, unlocking and locking happen only in the window; RPC cannot unlock the wallet. Once unlocked, any client with the token can send payments from it.
  • When a node and a wallet method share a name, the wallet method wins. Prefix the node method with node., for example node.gettransaction. help lists both sets.
  • stop shuts down the whole backend; node.stop is refused.
  • The endpoint accepts loopback bind addresses only. Pass --rpc 127.0.0.1:0 to pick a free port; the Node screen shows it.