Accept Monero, on your own computer or router
Monokulo is a self-hosted Monero payment gateway. It runs on Linux, macOS, Windows or your OpenWrt router, watches the chain with each store’s view key, and tells the store when an order is paid. It never holds a spend key, so it can never move your coins.
How it works
One program with the engine inside it, a browser dashboard, and a Monero node it can reach.
Watch-only
Each store gives Monokulo its view key, never its spend key. Payments go straight to the store’s own wallet; Monokulo just sees them arrive.
Checkout that works anywhere
A hosted checkout page and embed for static sites, a point-of-sale screen, and webhooks when an order is paid. The checkout works without JavaScript.
Fast detection
Payments show up within about a second of reaching the network, and are confirmed as blocks arrive.
Easy on the router
One static program and SQLite. The engine runs inside Monokulo on threads of its own, kept to two of the Flint 2’s four cores at low priority, so routing comes first. Checking each block’s proof of work (on by default for mainnet) takes about 256 MB of memory; turn it off on the admin page if you run your own node.
Settings in your browser
Manage stores, nodes and payment settings on Monokulo’s admin page. On OpenWrt, LuCI also controls start, stop, port, listen address and the engine’s CPUs under Services → Monokulo.
Survives upgrades
Its settings, keys and databases are kept across OpenWrt firmware upgrades.
Install Monokulo
Choose your computer or router. Every download includes the payment engine.
Install on your desktop
Download one executable, start it in a terminal, then finish setup in your browser.
Download and extract
Open the latest release and download the monokulo-… ZIP for your computer. For the newest build from main, use the latest-main prerelease. Extract the ZIP, then open a terminal in the extracted folder containing monokulo (or monokulo.exe).
Each ZIP has a matching .sha256 checksum on the release page. You don’t need Rust, Node.js or a separate engine download.
Linux
- 1
Choose the Linux ZIP
For Intel / AMD computers, choose the file ending in
x86_64-unknown-linux-gnu.zip. For ARM64, chooseaarch64-unknown-linux-gnu.zip. These builds need glibc 2.35 or newer (Ubuntu 22.04 or a comparable distribution). - 2
Create your encryption key once
In the extracted folder, generate a private key file with OpenSSL. Keep this file for every restart and update.
umask 077 openssl rand -hex 32 > monokulo.key chmod +x monokulo - 3
Start Monokulo
Run this each time you start it, from the folder containing your executable and key file.
MONOKULO_ENCRYPTION_KEY="$(cat monokulo.key)" ./monokulo
macOS
- 1
Choose the macOS ZIP
For Apple silicon (M-series), choose the file ending in
aarch64-apple-darwin.zip. For an Intel Mac, choosex86_64-apple-darwin.zip. Double-click the ZIP to extract it, then open Terminal in its folder.The executable is unsigned. If macOS blocks it after download, clear its quarantine attribute once for the binary you downloaded from the release page:
xattr -d com.apple.quarantine monokulo - 2
Create your encryption key once
Generate a private key file. Keep this file for every restart and update.
umask 077 openssl rand -hex 32 > monokulo.key chmod +x monokulo - 3
Start Monokulo
Run this each time you start it, from the folder containing your executable and key file.
MONOKULO_ENCRYPTION_KEY="$(cat monokulo.key)" ./monokulo
Windows
- 1
Choose the Windows ZIP
Choose the file ending in
x86_64-pc-windows-msvc.zipfor an Intel / AMD 64-bit PC. Right-click the ZIP and choose Extract All…, then open PowerShell in the folder containingmonokulo.exe.The executable is unsigned, so SmartScreen may show More info › Run anyway. It needs the Microsoft Visual C++ runtime; if Windows reports a missing
VCRUNTIME140.dll, install the x64 Visual C++ Redistributable from Microsoft. - 2
Create your encryption key once
Run this in PowerShell to save a random 32-byte key as 64 hex characters. Keep the file private and reuse it for every restart and update.
$keyBytes = New-Object byte[] 32 $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create() $rng.GetBytes($keyBytes) $rng.Dispose() ([BitConverter]::ToString($keyBytes) -replace '-', '').ToLowerInvariant() | Set-Content -Encoding ascii monokulo.key - 3
Start Monokulo
Run this each time you start it, from the folder containing your executable and key file.
$env:MONOKULO_ENCRYPTION_KEY = (Get-Content -Raw .\monokulo.key).Trim() .\monokulo.exe
Finish setup in your browser
Leave the terminal running and open http://127.0.0.1:8081. The first-run wizard creates your admin account. On the admin page, add a Monero node for the network you’ll accept payments on, then set up a wallet (make a new one in your browser, or bring your own view key) and add a store that takes payments into it. You can use your own reachable node or a remote node over HTTPS.
Monokulo listens on this computer only by default. To serve customers over the internet, configure its listen address in Server settings, put it behind an HTTPS reverse proxy, and set the public URL customers will use.
Press Ctrl+C to stop it. For automatic startup, run it under your system’s service manager with the same encryption key.
Where your config and data live
Monokulo’s admin page saves settings in monokulo.toml. The default locations are:
| System | Config file | Data folder |
|---|---|---|
| Linux / macOS | ~/.config/monokulo/monokulo.toml | ~/.local/share/monokulo/ |
| Windows | %APPDATA%\monokulo\monokulo.toml | %LOCALAPPDATA%\monokulo\ |
On Linux and macOS, ~ means your home folder. On Windows, paste %APPDATA%\monokulo into File Explorer’s address bar to find the config folder.
If set to absolute paths, XDG_CONFIG_HOME and XDG_DATA_HOME replace the base folders above. A Windows environment that sets HOME uses $HOME/.config and $HOME/.local/share before the Windows folders. If a default folder cannot be used, Monokulo falls back to its working directory.
To choose a config file explicitly, start with --options /path/to/monokulo.toml. Running ./monokulo --init (PowerShell: .\monokulo.exe --init) writes a template with documented defaults and prints its location. The data folder contains monokulo.db and engine.db; --database-path overrides the main database path. Your encryption key stays in the separate monokulo.key file you created, rather than in the config.
Backups and updates
Back up monokulo.key, your options file and both databases (monokulo.db and engine.db). Stop Monokulo before copying the databases. To update, stop it, extract the new ZIP, then start the new executable with your existing key and data.
Never generate a new key for an existing installation. Losing the key makes encrypted data unreadable. Keep it private: anyone with the key and database can read your stores’ details.
Install on an OpenWrt router
About ten minutes. You can do it all from the router’s web interface.
You’ll need
Built and tested on the GL.iNet Flint 2 (GL-MT6000). This is for stock OpenWrt, not a vendor’s own firmware. Any router running one of these OpenWrt releases on one of these CPUs works the same way. To check yours, run cat /etc/openwrt_release and look at DISTRIB_RELEASE and DISTRIB_ARCH.
The router can’t hold the Monero blockchain itself. Point Monokulo at a node on your network (a NAS or a desktop running monerod), or at a remote node over HTTPS.
In the web interface (LuCI)
- 1
Log in to LuCI
Open
http://192.168.1.1(your router’s address, if you changed it) and log in as root. - 2
Trust Monokulo’s signing key
System › Administration ›Repo Public Keys tab
Copy the key below into the box that says “Paste content of a file, or a URL to a key file…”, then click Add key.
-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKHn4lVmDzUwHunAtPOJcSljzQl3D zenzvL0fumdNUBCaSB7IBZ/yMYoMANYLcpJkOtgjvEhcT/8cymrT4Pj37A== -----END PUBLIC KEY-----Or paste this address instead of the key:
https://oceaneilonwy.github.io/monokulo/openwrt/monokulo.pem. It’s the same key that signs Kringle, so if you already trust that, skip this step. - 3
Add the Monokulo repository
System › Software ›Configure apk button
Find the box for
/etc/apk/repositories.d/customfeeds.list. Add this line at the end, on a line of its own, then click Save.OpenWrt 25.12 · aarch64_cortex-a53
https://oceaneilonwy.github.io/monokulo/openwrt/25.12/aarch64_cortex-a53/packages.adb - 4
Install Monokulo
System › Software
Click Update lists… and wait for it to finish. Type
monokulointo the Type to filter… box, open the Available tab, and click Install… next to monokulo. Then confirm with Install. It’s one package with the program and the LuCI page, and it starts straight away. - 5
Open Monokulo
Services › Monokulo
Reload the page first so the new menu item appears. The status should say Running. Click Open monokulo (it’s at
http://192.168.1.1:8081) and create the admin account: the first account made is the admin. - 6
Add a Monero node, then a store
On Monokulo’s admin page, add your node under the network you’ll take payments on, then set up a wallet and add a store on it.
In a terminal (SSH)
- 1
Connect to the router
From a computer on your network, log in as root. Stock OpenWrt is at
192.168.1.1unless you changed it.ssh root@192.168.1.1 - 2
Trust the key and add the repository
You only do this once.
OpenWrt 25.12 · aarch64_cortex-a53
wget -O /etc/apk/keys/monokulo.pem https://oceaneilonwy.github.io/monokulo/openwrt/monokulo.pem echo "https://oceaneilonwy.github.io/monokulo/openwrt/25.12/aarch64_cortex-a53/packages.adb" >> /etc/apk/repositories.d/customfeeds.list - 3
Install Monokulo
One package: the program and the LuCI page. It starts straight away.
apk update apk add monokulo - 4
Open Monokulo
Go to
http://192.168.1.1:8081and create the admin account, then add a Monero node and a store. Settings for how it starts are in LuCI under Services › Monokulo. If it isn’t running:service monokulo enable service monokulo start logread -e monokulo # what it said
Config, data and secrets on OpenWrt
LuCI’s service settings live in /etc/config/monokulo. Monokulo’s admin settings are saved to /srv/monokulo/monokulo.toml by default, alongside monokulo.db and engine.db. Changing the data folder in LuCI moves the location used for the config and databases.
On first start Monokulo makes an encryption key for its data, in /etc/monokulo/secrets. Firmware upgrades keep the file, but if it’s ever lost, Monokulo’s data can’t be read. Copy it somewhere safe from your computer:
scp root@192.168.1.1:/etc/monokulo/secrets monokulo-secretsKeep that file private: with it and a copy of the data folder, anyone can read your stores’ details.
Optional: let customers outside your home pay
By default Monokulo listens on your LAN only. For checkouts on the internet, it needs to listen on every interface, and the firewall needs to let its port in.
Services › Monokulo
Set Listen on to All interfaces, then Save & Apply.
Network › Firewall ›Traffic Rules tab › Add
Name Monokulo, Protocol TCP, Source zone wan, Destination zone Device (input), Destination port 8081, Action accept. Click Save, then Save & Apply.
Use Traffic Rules, not Port Forwards. Monokulo runs on the router itself, so there’s nothing to forward. Only if your ISP’s modem sits in front of the router do you forward TCP 8081 on that device.
Then set the public URL on Monokulo’s admin page (Settings) to the address customers use, for example https://pay.example.com. Behind CGNAT, or to keep your address private, serve it as a Tor onion service instead: set Listen on to This router only.
Prefer a terminal? This does the same:
uci set monokulo.main.listen=all
uci commit monokulo
uci add firewall rule
uci set firewall.@rule[-1].name=Monokulo
uci set firewall.@rule[-1].src=wan
uci set firewall.@rule[-1].proto=tcp
uci set firewall.@rule[-1].dest_port=8081
uci set firewall.@rule[-1].target=ACCEPT
uci commit firewall
service firewall reload
service monokulo restartUpdating
System › Software: click Update lists…, then look in the Updates tab. Or in a terminal:
apk update && apk upgrade monokuloSettings, secrets and databases are kept. After a firmware upgrade, repeat the install steps to put the package back; your data is still there.
Removing
System › Software: in the Installed tab, click Remove… on monokulo. Or in a terminal:
apk del monokulo
rm -rf /srv/monokulo /etc/monokulo # also delete all data and secretsPackage files
You don’t need these if you use the repository above. The package is signed with the Monokulo key, so once it’s trusted (step 2) you can also install it directly: upload it in System › Software › Upload Package…, or use apk add.
OpenWrt 25.12 · aarch64_cortex-a53
- monokulo-0.1.0-r1077.apk (12 MB): monokulo (the engine inside it) and the LuCI page
- packages.adb: the signed repository index
- monokulo.pem: the signing key, the same for every version