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.
| Item | Location |
|---|---|
| Application data | Linux $XDG_DATA_HOME/null or ~/.local/share/null; macOS ~/Library/Application Support/Null; Windows %LOCALAPPDATA%\Null or %APPDATA%\Null |
| Settings | null.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.
Use --network test on the first launch, or set network = "test" in
null.conf, to use the test network. It has no public seeds; add a peer
with --connect.
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 createor 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.
- Review asks the wallet for the exact fee and total, choosing notes the way the payment will.
- Confirm queues the payment. The wallet builds, proves and submits it, and shows progress in Activity.
- 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.
- Review the input count, number of transactions, destination and total network fee.
- 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 = trueis 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"
| Key | Meaning |
|---|---|
network | main or test |
rpc | combined RPC listener; loopback addresses only |
connect | extra peers to dial, as host:port |
listen | accept peers on this address; allow the port through the firewall |
advertise | public endpoint to announce behind NAT; rejected together with proxy |
proxy | SOCKS5 proxy for outbound peer connections, such as Tor |
wallet | wallet file; a relative path resolves inside the network directory |
lock_after_minutes | idle minutes before locking; 0 disables |
mine | mine whenever the wallet is unlocked |
mining_threads | miner threads |
log_file | write 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
REJECTEDwhile 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 examplenode.gettransaction.helplists both sets. stopshuts down the whole backend;node.stopis refused.- The endpoint accepts loopback bind addresses only. Pass
--rpc 127.0.0.1:0to pick a free port; the Node screen shows it.