Bitcoin Pocket Node

Full node on your phone in under 20 minutes
No days-long sync. No trusted third parties.

~13 GB
Total disk (11 GB chainstate + 2 GB blocks)
20 min
Zero to full node
v28.1
Bitcoin Core

The Problem

Running a node on a phone shouldn't take days

🐌
Traditional Sync
3–7 days
Download entire blockchain
Validate every block since 2009
~600 GB of data
⏳
AssumeUTXO
3 hours
Faster start, but still needs
full background validation
Uses more disk space
⚡
Chainstate Copy
20 min
Copy verified state from
your own trusted node
Instant full validation

Prerequisites

What you need

🖥️
Source Node
Any Bitcoin Core node
Umbrel, RaspiBlitz, etc.
unpruned preferred
+
📱
Android Phone
ARM64 (Pixel, Samsung, etc.)
~15 GB free space
same WiFi network

Both devices on the same local network. The phone copies directly from your own node - no external servers involved.

Step 1

Stop the source node & copy chainstate

📂 bitcoin/
  📂 chainstate/ ~11 GB
    UTXO database (own internal key)
  📂 blocks/index/ ~500 MB
    Block location index
  🔑 blocks/xor.dat 8 bytes
    Block file obfuscation key
  📂 blocks/ ~600 GB ✗
    NOT copied (too large)
1
Chainstate (~11 GB)
The UTXO set - every unspent output on the network. This is Bitcoin's current state.
2
XOR Key (8 bytes)
Since Core 28, xor.dat is used for block file data obfuscation - each node generates a unique key. The key must travel with the block files. (The chainstate has its own separate internal obfuscation key.)
Without this file, the block data can't be decoded correctly - bitcoind sees corrupt block files and refuses to start!
3
Block Index (~500 MB)
Maps block hashes to file locations. Needed so bitcoind knows what it has.

Step 2

The stub file trick

The block index references hundreds of blk*.dat files. If they're missing, bitcoind crashes.

But we don't need the actual block data - just the files to exist.

Solution: create empty stub files for every block file the index expects.

Bitcoind reads the stub files, finds them empty, and begins backfilling them in pruned mode - only keeping the most recent blocks and discarding old ones as it goes.
📂 blocks/
  📂 index/ copied
  📄 blk00000.dat 0 bytes
  📄 blk00001.dat 0 bytes
  📄 blk00002.dat 0 bytes
  📄 ...
  📄 blk00734.dat 0 bytes
  📄 rev00000.dat 0 bytes
  📄 rev00001.dat 0 bytes
  📄 ...
  📄 blk00734.dat tip blocks
~1,470 stub files = 0 bytes total

Step 3

Copy the tip blocks

?
Why not just chainstate?
Bitcoind needs the most recent blocks to verify the chain tip. Without them, it can't validate new incoming blocks.
4
Copy last ~10 blocks
Only the blocks in the final blk*.dat file. Usually 10-50 MB - tiny compared to 600 GB.
5
Plus matching rev*.dat
Undo data for the tip blocks. Needed for reorg handling.
The block index tells us which blk*.dat file has the chain tip. We only need that one file - everything else is stubs.
What gets copied
11 GB
Chainstate
500 MB
Block Index
~50 MB
Tip Blocks
Total: ~11.5 GB
vs 600+ GB full blockchain

Step 4

Transfer over local network

🖥️
Source Node
Umbrel / raspi / PC
📱
Phone
Pixel 7 Pro
📡
WiFi LAN Transfer
~11.5 GB over local WiFi. At 50 MB/s = ~4 minutes. At 10 MB/s = ~20 minutes. No internet needed.
🔒
Trust Model
You're copying from your own node that already validated everything. No trusted third party. Same security as running the source node.

Step 5

Start bitcoind & catch up

1
Loading block index...
Bitcoind reads the index, sees all block references. Stub files satisfy existence checks.
2
Verifying chainstate...
Quick validation of the UTXO database integrity. Takes seconds.
★
Pruning takes over
This is normal pruned node behaviour - bitcoind finds empty block files, recognises them as pruned, and continues forward keeping only recent blocks. With prune=2048 it maintains ~2 GB of recent block data. Total disk usage is ~13 GB including the 11 GB chainstate (UTXO set).
We're deliberately creating the conditions that trigger standard pruning. No hacks - just giving bitcoind a valid chainstate and letting its built-in pruning logic do the rest.
4
Catching up to chain tip
Downloads and validates only the blocks mined since the copy. Usually minutes' worth.
✓
Fully synced!
Your phone is now a fully-validating Bitcoin node. Verifies every transaction. Trusts no one.

Making it work on mobile

Challenges we solved

4
Why only 4 peers?
Default Bitcoin Core connects to 8-10 peers. On a phone, each peer costs battery and bandwidth. maxconnections=4 keeps the node fully validated while cutting resource use in half.
🔄
Orphan process survival
Android kills apps aggressively. If the app dies, bitcoind keeps running as an orphan holding the lock file. On restart, the app detects and re-attaches via RPC instead of crashing.
📱
Auto-start on boot
Phones restart nightly (GrapheneOS). A boot receiver re-launches the node automatically - zero downtime without user intervention.
📶
Metered network detection
VPN over cellular looks like WiFi to Android. We detect metered connections and warn before syncing over mobile data - blocks are ~2 MB each.
🔮
Sovereign price discovery
UTXOracle derives the BTC/USD price from on-chain transaction patterns. Zero external APIs. Updates incrementally with each new block (~4 seconds).
⚡
Built-in Electrum server
Pure Kotlin Electrum server runs alongside bitcoind, serving your wallet over localhost. BlueWallet connects directly - your keys, your node, your rules.

Result

A real node in your pocket

📱
✅ Synced
Block 937,162
4 peers connected
~13 GB total
→
Validates every transaction Enforces consensus rules
Built-in Electrum server BlueWallet compatible
UTXOracle price feed No external APIs
Auto-start on boot Metered network detection

From zero to sovereign in 20 minutes.
github.com/FreeOnlineUser/bitcoin-pocket-node

1 / 10