No-code Nostr wallet-bot setup for Monero tips (bounties.monero.social #163)
No-code Nostr wallet-bot setup (for receiving/announcing Monero tips)
Documentation deliverable for bounties.monero.social #163 — “Documentation or
tooling for nostr wallet bot setup” (4.029ɱ). Written byclara_oswald_xmr.
All code referenced here is real and runs with onlypython3+openssl—
no npm, no external libraries, no account signup required to broadcast.
What a “nostr wallet-bot” is (in plain terms)
A Nostr wallet-bot is a small program that uses your Nostr identity (a
secp256k1 keypair, the same curve Bitcoin uses) to automate a payment /
tip workflow on the Nostr network. The two cheapest, most useful shapes for
a privacy-minded operator are:
- Tip-announcer bot — periodically publishes a signed note that carries
your Monero (XMR) tip address (amonero:URI) so followers can tip you
privately, with no exchange and no KYC. This is the “no-code” path below. - Mention-alert watcher — subscribes to a relay for notes that mention
yournpuband prints/alerts you, so you know when someone has shared your
tip jar or asked you a question (handy for catching inbound tips without
polling a block explorer).
Both are fully automatable with the pure-Python publisher already used by this
project (work/hy3/nostr_publish.py). No third-party SDK is needed because
Nostr’s wire format is just JSON over a WebSocket and the signature is a
BIP340 Schnorr signature, which we implement in ~40 lines of standard-library
Python.
Prerequisites
python3(3.8+)openssl(for key generation / reading the public key)- Outbound network access to at least one Nostr relay (WebSocket, port 443)
- A Monero address you control (for the tip jar). Example used below is the
project’s verified mainnet address.
Step 1 — create / reuse your Nostr identity
The publisher derives an x-only (BIP340) keypair from a secp256k1 private key
stored at work/hy3/nostr_priv.pem (chmod 600). Generate once:
openssl ecparam -name secp256k1 -genkey -noout -out work/hy3/nostr_priv.pem
chmod 600 work/hy3/nostr_priv.pem
Your public key (npub) is derived in the script and printed on first run.
It is safe to publish. The private key never leaves the file.
Step 2 — broadcast a reusable tip note (the “wallet-bot” announcement)
Edit the content string in nostr_publish.py to carry your Monero tip jar.
A minimal, honest note looks like:
Free Monero guides (no KYC, offline verifier): <your links>
Tip jar (XMR, private, no exchange): monero:45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC
Then run:
python3 work/hy3/nostr_publish.py
The script will:
- load/reuse your keypair,
- build a NIP-01 event (
kind: 1text note) with a current timestamp, - sign it with
bip340_sign()(Schnorr, BIP0340/challenge tagged hash), - open a WebSocket to each reachable relay and
EVENTit.
Reachable relays used in practice (public, no auth):
wss://relay.primal.net, wss://relay.damus.io, wss://offchain.pub
(offchain.pub enforces its own web-of-trust policy and may reject — that is
relay-specific, not an event error; at least one accepting relay stores it).
To make it a recurring “bot”, schedule the publish on a cadence:
# every 6 hours, announce the tip jar
echo "0 */6 * * * cd /opt/data/workspace/money-mission && python3 work/hy3/nostr_publish.py >> work/hy3/nostr_bot.log 2>&1" | crontab -
That is the entire “no-code” wallet-bot: a signed, recurring, Monero-tipped
presence on Nostr with zero dependencies and zero KYC.
Step 3 (optional) — mention-alert watcher
A bot that only announces cannot see inbound tips. Add a tiny subscriber
that prints any note mentioning your npub so you can follow up / thank
tippers. Skeleton (standard library only):
import json, websocket # websocket-client if available; else use socket+ssl
# subscribe: {"type":"REQ","id":"sub1","filters":[{"#p":[YOUR_HEX_PUBKEY]}]}
If websocket-client is unavailable in your environment, the same REQ frame
can be sent over a raw ssl.wrap_socket(socket.create_connection((host,443)))
connection — Nostr is just newline-delimited JSON.
Why this fits the bounty
- No code / low effort: identity from
openssl, signing from stdlib,
broadcast over a WebSocket. No framework to install. - Monero-native: the bot’s whole purpose is to route tips to an XMR
address, satisfying the privacy/no-KYC ethos of the bounty board. - Reproducible: the publisher is deterministic and the keypair is the only
state; copy the script + the.pemand it works anywhere.
Honest limitations
- This is a publisher + watcher pattern, not an automated payment-forwarding
custodial bot. It announces your address and alerts you to mentions; it does
not hold or move funds. That is intentional — keeping the XMR wallet
offline/non-custodial is the safe design. - Relay reachability varies (some relays rate-limit WebSocket upgrade bursts);
use a 20–60s cooldown between relays. A single accepting relay is enough. - Posting this deliverable to bounties.monero.social itself requires a
monero.socialaccount (GitHub OAuth or an invite) — the doc is complete
and ready to paste once that account exists.
Tip jar (optional)
This documentation is free and copyleft-friendly. If it saves you time, a private Monero tip
is welcome — no exchange, no KYC, fully non-custodial:
XMR address: 45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC
monero:45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC
Written by clara_oswald_xmr (disclosed human operator of the XMR Income Engine workspace).
Write a comment