Monero wallet operations over LXMF/Reticulum mesh networks.
LXMFMonero proxies Monero wallet RPC calls over Reticulum using LXMF for message delivery. A "hub" with a view-only wallet connects to monerod. A "client" with a cold wallet signs transactions locally and sends them to the hub for broadcast.
Tested December 2025. Transaction hashes verifiable on Monero blockchain.
| Component | Specification |
|---|---|
| Client | MacBook Pro M1, macOS 15.2 |
| Hub | Raspberry Pi 5 (8GB), Debian 12 |
| monerod | v0.18.3.4 (Docker) |
| monero-wallet-rpc | v0.18.3.4 |
| Reticulum | 0.8.4 |
| LXMF | 0.5.4 |
| Python | 3.11 |
TCP Testnet (2 hops):
Mac (cold wallet) -> BetweenTheBorders Testnet -> Pi (hub + monerod)
reticulum.betweentheborders.com:4242
I2P (anonymous):
Mac (cold wallet) -> I2P tunnel -> Pi (hub + monerod)
kfamlmwnlw3acqfxip4x6kt53i2tr4ksp5h4qxwvxhoq7mchpolq.b32.i2p
TCP/Testnet:
TX Hash: 8f0295261a2ec04c6d4dcf0c9cc6b30278ab50caf9f6d27a61b562e6f3ebd761
Amount: 0.0001 XMR
Fee: 0.000030700000 XMR
Time: ~20 seconds total
I2P:
TX Hash: a793ff7bd6a0a4b168f72726e2027d283cc5fed0c8c3b1cd6693c6ef7a6fa8ee
Time: ~35 seconds total
| Feature | Status | Notes |
|---|---|---|
| Balance queries | Pass | 2-4 second round-trip |
| Export outputs | Pass | ~7 seconds TCP, ~18s I2P |
| Create unsigned tx | Pass | 6-7KB payloads |
| Sign transaction | Pass | Local cold wallet signing |
| Submit transaction | Pass | Broadcast confirmed on mainnet |
| Key image sync | Pass | Automatic after transaction |
| I2P transport | Pass | Full transaction verified |
| LoRa/HF transport | Pending | Not yet tested |
| Data | Size |
|---|---|
| Balance response | ~500 bytes |
| Export outputs | ~640-820 bytes |
| Unsigned tx | 6-7 KB |
| Signed tx | 12-13 KB |
+---------------------+ +---------------------+
| COLD CLIENT | | HUB |
| | | |
| - Has spend key | LXMF | - View-only wallet |
| - Signs locally |<------------------>| - Connected to |
| - Air-gapped OK | (any transport) | monerod |
| | | |
+---------------------+ +---------------------+
Transaction flow:
- Client requests balance/tx from Hub (view-only wallet)
- Hub creates unsigned transaction
- Client signs locally with spend key
- Client sends signed transaction to Hub
- Hub broadcasts to Monero network
- Client exports key images to Hub for balance sync
- Python 3.9+
- Reticulum and LXMF:
pip install rns lxmf - Monero CLI tools from https://getmonero.org/downloads/
git clone https://github.com/LFManifesto/LXMFMonero.git
cd LXMFMonero
python3 -m venv venv
source venv/bin/activate
pip install -e .Edit ~/.reticulum/config:
[interfaces]
[[RNS Testnet BetweenTheBorders]]
type = TCPClientInterface
enabled = yes
target_host = reticulum.betweentheborders.com
target_port = 4242Start daemon:
rnsd &
rnstatus # verify connectivityCold and view-only wallets must derive from the same seed.
Create cold wallet:
monero-wallet-cli --generate-new-wallet /path/to/cold-walletExport view key:
monero-wallet-cli --wallet-file /path/to/cold-wallet
# In wallet:
viewkey # note secret view key
address # note primary addressCreate view-only wallet on hub:
monero-wallet-cli --generate-from-view-key /path/to/viewonly-wallet \
--address <primary-address> \
--viewkey <secret-view-key>- Verify monerod is accessible (use unrestricted RPC port 18083):
curl -s http://127.0.0.1:18083/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"get_info"}' | jq .result.height- Start wallet-rpc with view-only wallet:
monero-wallet-rpc \
--wallet-file /path/to/viewonly-wallet \
--password '' \
--rpc-bind-port 18085 \
--disable-rpc-login \
--daemon-address 127.0.0.1:18083- Start hub:
lxmfmonero-hub --wallet-rpc http://127.0.0.1:18085/json_rpcNote the destination hash printed at startup.
- Start wallet-rpc with cold wallet (offline mode):
monero-wallet-rpc \
--wallet-file /path/to/cold-wallet \
--password '' \
--rpc-bind-port 18087 \
--disable-rpc-login \
--offline- Verify path to hub:
rnpath <hub-destination-hash>
# Expected: "Path found, destination is X hops away"- Check balance:
lxmfmonero-client --hub <hub-destination-hash> balance- Send XMR:
lxmfmonero-client --hub <hub-destination-hash> \
--cold-wallet http://127.0.0.1:18087/json_rpc \
send <destination-address> <amount>- TUI interface:
lxmfmonero-tui --hub <hub-destination-hash> \
--cold-wallet http://127.0.0.1:18087/json_rpcHub:
--identity, -i Identity file path (default: ~/.lxmfmonero/hub/identity)
--storage, -s LXMF storage path (default: ~/.lxmfmonero/hub/storage)
--wallet-rpc, -w wallet-rpc URL (default: http://127.0.0.1:18082/json_rpc)
--name, -n Display name for announcements
--announce-interval, -a Seconds between announces (0 to disable)
Client:
--identity, -i Identity file path
--storage, -s LXMF storage path
--hub, -H Hub destination hash (required)
--cold-wallet, -c Cold wallet-rpc URL (default: http://127.0.0.1:18083/json_rpc)
--timeout, -t Request timeout seconds (default: 300)
The view-only wallet is out of sync with the cold wallet. Export key images from cold wallet and import to view-only:
# Export from cold wallet
curl -s http://127.0.0.1:18087/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"export_key_images","params":{"all":true}}'
# Import to view-only wallet (on hub)
curl -s http://127.0.0.1:18085/json_rpc \
-d '{"jsonrpc":"2.0","id":"0","method":"import_key_images","params":{"signed_key_images":[...]}}'- Check Reticulum connectivity:
rnpath <hub-hash> - Verify hub is running and announcing
- Check if path exists through testnet
- Balance may include locked outputs
- Wait for outputs to unlock (10 blocks after receiving)
- Check
unlocked_balancevsbalance
- Enable monerod logging:
curl http://127.0.0.1:18083/set_log_level -d '{"level":2}'- Check monerod logs for rejection reason
- Common causes: double spend, invalid ring members, key images already spent
- Cold and view-only wallets must derive from same seed
- View-only wallet needs secret view key (not spend key)
- Cold wallet must start with
--offlineflag - View-only wallet connects to monerod on unrestricted RPC port (18083, not 18081)
- Hub has view-only access only; cannot spend funds
- Client holds spend key; signs transactions locally
- All communication encrypted by Reticulum (X25519 ECDH, AES-256)
- LXMF provides forward secrecy
- Reticulum Network Stack: https://reticulum.network/ (accessed December 2025)
- Reticulum Manual: https://markqvist.github.io/Reticulum/manual/ (accessed December 2025)
- LXMF Protocol: https://github.com/markqvist/LXMF (accessed December 2025)
- Monero: https://getmonero.org/ (accessed December 2025)
- Monero RPC Documentation: https://www.getmonero.org/resources/developer-guides/wallet-rpc.html (accessed December 2025)
MIT License - See LICENSE file
Light Fighter Manifesto L.L.C. https://lightfightermanifesto.org