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. 1

    Choose the Linux ZIP

    For Intel / AMD computers, choose the file ending in x86_64-unknown-linux-gnu.zip. For ARM64, choose aarch64-unknown-linux-gnu.zip. These builds need glibc 2.35 or newer (Ubuntu 22.04 or a comparable distribution).

  2. 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. 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. 1

    Choose the macOS ZIP

    For Apple silicon (M-series), choose the file ending in aarch64-apple-darwin.zip. For an Intel Mac, choose x86_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. 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. 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. 1

    Choose the Windows ZIP

    Choose the file ending in x86_64-pc-windows-msvc.zip for an Intel / AMD 64-bit PC. Right-click the ZIP and choose Extract All…, then open PowerShell in the folder containing monokulo.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. 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. 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:

SystemConfig fileData 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

OpenWrt 25.12 with LuCIA CPU we build for: aarch64_cortex-a53The router’s root passwordA Monero node it can reach

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. 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. 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. 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. 4

    Install Monokulo

    System › Software

    Click Update lists… and wait for it to finish. Type monokulo into 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. 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. 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. 1

    Connect to the router

    From a computer on your network, log in as root. Stock OpenWrt is at 192.168.1.1 unless you changed it.

    ssh root@192.168.1.1
  2. 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. 3

    Install Monokulo

    One package: the program and the LuCI page. It starts straight away.

    apk update
    apk add monokulo
  4. 4

    Open Monokulo

    Go to http://192.168.1.1:8081 and 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-secrets

Keep 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 restart

Updating

System › Software: click Update lists…, then look in the Updates tab. Or in a terminal:

apk update && apk upgrade monokulo

Settings, 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 secrets

Package 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