Description
Approaching 2030, as the internet revisits old network methodologies, being creepy gets you more friends.
Emotions aside, sometimes you just need to automate.
One script. No dependencies. Basic Python. Tested.
nostrfrnd.py takes a text file containing newline-separated Nostr public keys and follows them one at a time at a controlled rate.
No pip install.
No Nostr SDK.
No WebSocket package.
No crypto library hiding underneath it.
Python’s standard library doesn’t contain the pieces Nostr normally depends on, so the script carries its own implementation of the ugly parts: secp256k1 arithmetic, BIP-340 Schnorr signing, Bech32 npub / nsec handling, and WebSocket relay communication.
One file.
python3 nostrfrnd.py friends.txt
The default interval is 3 seconds per follow. Change it when needed:
python3 nostrfrnd.py friends.txt --rate 10
The input is deliberately boring:
npub1...
npub1...
npub1...
Raw 64-character hex public keys work too.
When the script starts, it asks for your Nostr private key using a hidden terminal prompt. It accepts either an nsec or raw hex private key.
The key does not need to be placed in the script, the input file, or a command-line argument.
It doesn’t blindly replace your follow list
Nostr follow lists use kind 3 events.
Those events are replaceable.
Meaning if a script publishes a kind-3 event containing only the newest person, congratulations: you may have just replaced your entire social graph with Dave.
nostrfrnd.py first queries your relays for the existing follow list, preserves the existing tags, then publishes the complete list again with the new follow appended.
It does that for each new public key.
If it cannot establish an existing follow list, it stops instead of guessing.
For a genuinely new account you can explicitly permit an empty starting list:
python3 nostrfrnd.py friends.txt --allow-empty
Dry run first
Probably wise.
python3 nostrfrnd.py friends.txt --dry-run
That reads the file, validates the keys, checks the current follow list, shows what would be added, and publishes nothing.
Use your own relays
Multiple relays can be supplied:
python3 nostrfrnd.py friends.txt \
--relay wss://nos.lol \
--relay wss://relay.damus.io
The script publishes to multiple relays and checks relay responses rather than just throwing events into the void and declaring victory.
What’s inside
One file:
nostrfrnd.py
Standard Python library only.
Internally it handles:
- Nostr kind-3 follow events
- existing follow-list retrieval
npubdecodingnsecdecoding- raw hex keys
- secp256k1 point arithmetic
- BIP-340 Schnorr signing and verification
- built-in cryptographic self-test
- RFC 6455 WebSocket communication
- relay acknowledgements
- configurable follow interval
- multiple relays
- duplicate detection
- already-followed detection
- self-follow rejection
- safe abort behavior
- dry runs
No packages bundled because there aren’t any.
The standard CacheRat product rule is to state exactly what the buyer receives, and this one is about as literal as it gets: one downloadable Python script.
Requirements
Python 3.
Internet connection.
A Nostr account.
A text file containing the public keys you want to follow.
That’s about it.
Example
python3 nostrfrnd.py nostr_people.txt --rate 3
Then:
Private key (nsec or 64-char hex; hidden):
The script checks your existing follows and starts working through the file.
Three seconds.
Friend.
Three seconds.
Friend.
Modern human interaction has finally been solved.
Use responsibly. Or don’t…
Mind rate limits bro.





