Accept Zano payments in BTCPay Server. Privacy-focused cryptocurrency with confidential transactions and integrated addresses.
Warning
This plugin shares a single Zano wallet across all stores in the BTCPay Server instance. Use this plugin only if you are not sharing your instance.
When a customer creates an invoice, the plugin generates a unique integrated address (containing an embedded payment ID) for each payment. A background poller checks the wallet every 15 seconds for incoming payments matching pending invoices, tracks confirmations, and settles invoices based on your configured threshold.
| Environment variable | Required | Description | Example |
|---|---|---|---|
BTCPAY_ZANO_DAEMON_URI |
Yes | URI of the zanod RPC interface | http://127.0.0.1:11211 |
BTCPAY_ZANO_WALLET_DAEMON_URI |
Yes | URI of the simplewallet RPC interface | http://127.0.0.1:11212 |
BTCPAY_ZANO_WALLET_DAEMON_WALLETDIR |
No | Directory where wallet files are stored (for auto-loading on startup) | /wallet |
BTCPAY_ZANO_EXTRA_ASSETS |
No | Confidential Assets to accept in addition to native ZANO. See Confidential Assets below. | USDZ|<asset_id>|6|USD Zano|pegged_usd |
Beyond native ZANO, the plugin can accept any Zano Confidential Asset (USDz, BTCz, custom tokens, etc.). Each extra asset is registered as its own BTCPay payment method (e.g. ZANOUSDZ) sharing the daemon and wallet configured above.
Extra assets are declared via the BTCPAY_ZANO_EXTRA_ASSETS environment variable. Multiple assets are separated by ;; fields within each asset are separated by |:
TICKER|asset_id|decimals|DisplayName|rate_mode|rate_param
TICKER— short symbol (uppercase in the final crypto code; e.g.USDZ→ payment methodZANOUSDZ). Must not beZANO.asset_id— 64-hex Zano asset ID. Must not equal the native ZANO asset ID.decimals— atomic-unit divisibility (integer, 0–18).DisplayName(optional) — shown in the store wallet nav and checkout. Falls back to the ticker.rate_mode(optional) — how BTCPay converts invoice currency → asset amount. One of:none(default) — no automatic rate; configure manually in BTCPay's rate rules.pegged_usd—<CODE>_X = USD_X(1:1 USD stablecoin).fixed_usd— fixed price in USD (rate_param= USD price, e.g.0.50).coingecko— (accepted but currently a no-op) BTCPay's rate-rule parser rejects hyphenated coingecko ids; until that's worked around, this mode records the coin id but emits no default rule. Merchants must configure the rate manually in BTCPay's UI.
rate_param(required forfixed_usdandcoingecko) — see above.
BTCPAY_ZANO_EXTRA_ASSETS=USDZ|0123...cdef|6|USD Zano|pegged_usd;;BTCZ|fedc...4567|12|Wrapped BTC|coingecko|wrapped-bitcoin
Registers two extra payment methods in addition to native ZANO:
ZANOUSDZ— "USD Zano", 6 decimals, pegged 1:1 to USD.ZANOBTCZ— "Wrapped BTC", 12 decimals, priced via CoinGecko'swrapped-bitcoinfeed.
Each extra asset appears under Store Settings > Zano with its own enable/disable toggle and confirmation-threshold setting. The checkout badge shows the asset ticker, and the payment URI includes &asset_id=… so customer wallets can pre-select the correct asset.
- Assets share the single daemon/wallet configured via
BTCPAY_ZANO_DAEMON_URI/BTCPAY_ZANO_WALLET_DAEMON_URI. One wallet, many assets. - Adding, removing, or changing an extra asset requires a BTCPay Server restart (payment-method registration is performed once at startup).
- If
BTCPAY_ZANO_EXTRA_ASSETSis malformed, only the extras are disabled — native ZANO continues to work.
zanod --rpc-bind-ip=0.0.0.0 --rpc-bind-port=11211Create or open a wallet, then start simplewallet with RPC enabled:
simplewallet --wallet-file /path/to/wallet \
--password "your-password" \
--daemon-address 127.0.0.1:11211 \
--rpc-bind-port 11212For receive-only setups, create a watch-only wallet first:
simplewallet --generate-new-wallet /path/to/wallet
# Then from the wallet prompt:
save_watch_only /path/to/watch-only-wallet passwordIn BTCPay Server, go to Server Settings > Plugins and install the Zano plugin. Then configure the environment variables above and restart.
Go to Store Settings > Zano to enable it and set your preferred confirmation threshold.
A Docker image with zanod and simplewallet is available:
docker pull pavelravaga/zano:2.2.0.455Run the daemon:
docker run -d --name zanod \
-p 11211:11211 \
-v zano_data:/data \
pavelravaga/zano:2.2.0.455Run the wallet:
docker run -d --name zano_wallet \
-p 11212:11212 \
-v zano_wallet:/wallet \
--entrypoint simplewallet \
pavelravaga/zano:2.2.0.455 \
--rpc-bind-ip=0.0.0.0 --rpc-bind-port=11212 \
--daemon-address=zanod:11211 \
--wallet-file=/wallet/wallet --password=""- .NET 8.0 SDK
- Git
- Docker and Docker Compose
git clone --recurse-submodules https://github.com/hyle-team/btcpayserver-zano-plugin
cd btcpayserver-zano-plugin
dotnet build btcpay-zano-plugin.slndotnet test BTCPayServer.Plugins.UnitTestsdocker compose -f BTCPayServer.Plugins.IntegrationTests/docker-compose.yml run testsStart the dev dependencies:
cd BTCPayServer.Plugins.IntegrationTests/
docker compose up -d devCreate appsettings.dev.json in btcpayserver/BTCPayServer:
{
"DEBUG_PLUGINS": "../../Plugins/Zano/bin/Debug/net8.0/BTCPayServer.Plugins.Zano.dll",
"ZANO_DAEMON_URI": "http://127.0.0.1:11211",
"ZANO_WALLET_DAEMON_URI": "http://127.0.0.1:11212"
}Then run BTCPay Server with the plugin loaded.
- Address generation: Integrated addresses with random 8-byte payment IDs (unique per invoice)
- Payment detection: Polls
get_bulk_paymentsevery 15 seconds - Fee: Fixed 0.01 ZANO per transaction
- Divisibility: 12 decimal places
- Rate source: CoinGecko (
ZANO_BTC) - Confirmations: Configurable (0, 1, 10, or custom)