git clone https://github.com/monty888/monstr_terminal.git
cd monstr_terminal
python3 -m venv venv
source venv/bin/activate
pip install .
to use postgres as store psycopg2 must be installed
# install wheel helper, if needed.
pip pip install wheel
# maybe required on linux
# sudo apt install postgresql automake pkg-config libtool
# maybe required on mac
# brew install postgresql automake pkg-config libtool libffi
# now actually install psycopg2
pip install psycopg2
nostr event viewer for the command line.
usage: view.py [-h] [-c CONF] [--work-dir WORK_DIR] [-r RELAY] [-u USER] [--contacts] [--no-contacts] [--view-extra VIEW_EXTRA] [-v VIA]
[--direction {both,to,from}] [-i EID] [-k KINDS] [--encrypt-kinds ENCRYPT_KINDS] [--inbox-kinds INBOX_KINDS] [-l LIMIT]
[-s SINCE] [--until UNTIL] [--hashtag HASHTAG] [--pubkey] [-t TAGS] [-p {8,12,16,20,24,28,32}] [-e] [--no-entities]
[--nip5check] [-n] [--start-mode {all,first}] [--inbox-only] [--no-inbox-only] [-o {formatted,json,content}]
[--ssl-disable-verify] [-x {never,store}] [-d]
view nostr events from the command line
options:
-h, --help show this help message and exit
-c CONF, --conf CONF name com TOML file to use for configuration, default[view.toml]
--work-dir WORK_DIR base dir for files used if full path isn't given, default[/home/monty/.nostrpy/]
-r RELAY, --relay RELAY
comma separated nostr relays to connect to, default[None]
-u USER, --user USER alias, priv_k or pub_k of user to view as. If only created from pub_k then kind 4 encrypted events will be left
encrypted, default[None]
--contacts if --as-user lookup contacts and add to view
--no-contacts if --as-user DO NOT add contacts to view
--view-extra VIEW_EXTRA
additional comma separated alias, priv_k or pub_k of user to view, default[None]
-v VIA, --via VIA additional comma separated alias(with priv_k) or priv_k that will be used as public inbox with wrapped events,
default[None]
--direction {both,to,from}
if query with author keys if we are looking for events sent from, sent to or both with those keys default[both]
-i EID, --id EID comma separated event ids will be added as e tag filter e.g with kind=42 can be used to view a chat channel,
default[None]
-k KINDS, --kinds KINDS
comma separated event kinds to output, default[1,4]
--encrypt-kinds ENCRYPT_KINDS
comma separated event kinds to be decrypted, default[4]
--inbox-kinds INBOX_KINDS
kind to use for inbox events, applied to all inboxes default[4]
-l LIMIT, --limit LIMIT
max number of events to return, default [20]
-s SINCE, --since SINCE
show events n hours previous to running, default [None]
--until UNTIL show events n hours after since, default [None]
--hashtag HASHTAG only events with t tag value will be matched, default[None]
--pubkey output event author pubkey default[False]
-t TAGS, --tags TAGS comma separated tag types to output, =* for all default[None]
-p {8,12,16,20,24,28,32}, --pow {8,12,16,20,24,28,32}
minimum amount required for events excluding contacts of user default[None]
-e, --entities output event_id and pubkeys as nostr entities
--no-entities do not output event_id and pubkeys as nostr entities
--nip5check nip5 checked and displayed green if valid
-n, --nip5 valid nip5 required for events excluding contacts of user
--start-mode {all,first}
at start wait for ALL relays to return events before starting to print or just FIRST default[all]
--inbox-only only show events that are contained in inboxes
--no-inbox-only events in and outside of inboxes will be shown
-o {formatted,json,content}, --output {formatted,json,content}
how to display events default[formatted]
--ssl-disable-verify disables checks of ssl certificates
-x {never,store}, --exit {never,store}
never - run indefinitely. store - exit after receiving stored events. default[never]
-d, --debug enable debug output
view all event as they come in:
python -m monstr_terminal.event_view
view events for a given user, also an extra user that's not in thier follows and check in additional inbox:
python -m monstr_terminal.event_view --as=<key or alias> --view=<key or alias> --via=<key or alias>
note that the view will be made by looking up the contacts event for the given key so that needs to be available on the used relays. When a user is given encrypted text will automatically be decrypted.
If you want to simply hack on the incoming events you can use the -o json
output option to get the raw json
for each event. See event_view_consumer.py
for an example.
python -m monstr_terminal.event_view --as=<key or alias> --view=<key or alias> --via=<key or alias> -o json | python view_consumer.py
post nostr events from the command line, the events can optionally be sent via an inbox (another nostr account) so that only users with keys to that account we'll be able to decrypt the events.
usage: post.py [-h] [-r RELAY] [-u USER] [-t TO_USERS] [-v VIA] [-s SUBJECT] [--tags TAGS] [-k KIND]
[--inbox-kind INBOX_KIND] [-f {encrypt,plaintext,default}] [-i] [-l] [-d]
[message ...]
post nostr events from the command line
positional arguments:
message message to post
options:
-h, --help show this help message and exit
-r RELAY, --relay RELAY
comma separated nostr relays to connect to, default [wss://nostr-
pub.wellorder.net,wss://nos.lol,wss://relay.nostr.band]
-u USER, --user USER alias, priv_k of user to post as, default [monty]
-t TO_USERS, --to_users TO_USERS
comma seperated alias, priv_k, or pub_k of user to post to, default [None]
-v VIA, --via VIA alias(with priv_k) or nsec that will be used as public inbox with wrapped events, default [None]
-s SUBJECT, --subject SUBJECT
add subject tag to post,, default[None]
--tags TAGS tags to add post in format tagname:v1,v2#tagname:v1... default [None]
-k KIND, --kind KIND kind of event to post, if not given used kind depends on format - if default or plaintext then [1]
if encrypt then [4]
--inbox-kind INBOX_KIND
if using an inbox, what kind is used for the wrapping event default [4]
-f {encrypt,plaintext,default}, --format {encrypt,plaintext,default}
format of the event content if default is selected then events of kind 4 will be encrypted and all
other kinds will be plaintext
-i, --ignore_missing don't fail on missing to_users
-l, --loop stay open to enter and receive messages
-d, --debug enable debug output
send a plain text post:
python -m monstr_terminal.poster -p --as=<key or alias> hello there
send encrypted post to another user:
python -m monstr_terminal.poster --as=<key or alias> --to=<key or alias> hello there
plain post in loop mode using a mailbox - only other users with key to the mailbox will be able to view messages:
python -m monstr_terminal.poster -pl --as=<key or alias> --via=<key or alias>
creates named aliases to keys so they can be referenced by user friendly name.
usage: alias.py [-h] [-n] [-l] [-d] [-a] [-f FILENAME] [-k KEYS] [--debug] [profile_name]
link nostr keypairs to profile names
alias.py <profile_name> view existing mapping
alias.py -n <profile_name> map new keys auto generated
alias.py -n <profile_name> <key> map new with supplied key if pub_k then view only
alias.py -d <profile_name> delete profile
alias.py -l <profile_name> <key> map existing to key, any exsting mapping overridden
positional arguments:
profile_name profile_name to perform action on
options:
-h, --help show this help message and exit
-n, --new create a new profile key pair link
-l, --link link key pair to exiting profile file, any existing mapping will be overridden
-d, --delete delete an existing profile
-a, --all lists all existing profiles
-f FILENAME, --filename FILENAME
mappings in this file, default [/home/monty/.nostrpy/keystore.db]
-k KEYS, --keys KEYS npub/nsec for the profile
--debug enable debug output
create a new key and alias monty:
python -m monstr_terminal.alias -n monty
create a new profile and link to an existing known nsec/npub
python -m monstr_terminal.alias -n monty -k nsec....
Acts as a NIP46 signer for a given key
python -m monstr_terminal.signer --help
usage: signer.py [-h] [-c CONF] [--work-dir WORK_DIR] [-r RELAY] [-a AUTH] [-v] [--no-verbose] [-d] [user]
A NIP46 server - signs events on behalf of another client
positional arguments:
user alias, priv_k or pub_k of user to view as. If only created from pub_k then kind 4 encrypted events
will be left encrypted, default[None]
options:
-h, --help show this help message and exit
-c CONF, --conf CONF name com TOML file to use for configuration, default[/home/monty/.nostrpy/signer.toml]
--work-dir WORK_DIR base dir for files used if full path isn't given, default[/home/monty/.nostrpy/]
-r RELAY, --relay RELAY
comma separated nostr relays to connect to, default[ws://localhost:8081]
-a AUTH, --auth AUTH action on receiving requests to perform signing operations all - always accept, ask - always ask or
int value to ask every n minutes, default[all]
-v, --verbose print info on each event that is requested to sign, default[False]
--no-verbose turn off verbose
-d, --debug enable debug output
basic relay implementation:
python -m monstr_terminal.run_relay --help
usage: run_relay.py [-h] [--host HOST] [--port PORT] [--endpoint ENDPOINT] [-s {sqlite,postgres,transient,none}]
[--dbfile DBFILE] [--pg_database PG_DATABASE] [--pg_user PG_USER] [--pg_password PG_PASSWORD]
[--maxsub MAXSUB] [--maxlength MAXLENGTH] [--max-before MAX_BEFORE] [--max-after MAX_AFTER] [--nip16]
[--no-nip16] [--nip20] [--no-nip20] [--nip33] [--no-nip33] [--nip40] [--no-nip40] [--nip42]
[--no-nip42] [--ssl] [--tor] [-w] [-d]
runs a nostr relay
options:
-h, --help show this help message and exit
--host HOST ip address where relay will listen, default[localhost]
--port PORT port relay will listen, default[8081]
--endpoint ENDPOINT endpoint address for the relay websocket[/]
-s {sqlite,postgres,transient,none}, --store {sqlite,postgres,transient,none}
storage type to use for received events, default[sqlite]
--dbfile DBFILE when store is sqlite the file location for the db, default[/home/monty/.nostrpy/nostr-relay.db]
--pg_database PG_DATABASE
when store is postgres the postgres db name, default[nostr-relay]
--pg_user PG_USER when store is postgres the postgres username, default[postgres]
--pg_password PG_PASSWORD
when store is postgres the postgres password
--maxsub MAXSUB maximum open subs allowed per client websocket, default[10]
--maxlength MAXLENGTH
maximum length for event content if any, default[None]
--max-before MAX_BEFORE
maximum time before current time to accept created_at of events if any (mins), default[None]
--max-after MAX_AFTER
maximum time after current time to accept created_at of events if any (mins), default[5]
--nip16 enable NIP16 - Event treatment, ephemeral and replaceable event ranges see
https://github.com/nostr-protocol/nips/blob/master/16.md, default[True]
--no-nip16 disable NIP16, default[False]
--nip20 enable NIP20 - OK command events see https://github.com/nostr-protocol/nips/blob/master/20.md,
default[True]
--no-nip20 disable NIP20, default[False]
--nip33 enable NIP33 - Parameterized Replaceable Events see https://github.com/nostr-
protocol/nips/blob/master/20.md, default[True]
--no-nip33 disable NIP33, default[False]
--nip40 enable NIP40 - Expiration Timestamp see https://github.com/nostr-protocol/nips/blob/master/40.md,
default[True]
--no-nip40 disable NIP40, default[False]
--nip42 enable NIP42 - Authentication of clients to relays see https://github.com/nostr-
protocol/nips/blob/master/42.md, default[False]
--no-nip42 disable NIP42, default[True]
--ssl run ssl ssl_key and ssl_cert will need to be defined
--tor make realy accessable over tor
-w, --wipe wipes event store and exits
-d, --debug enable debug output
The following options can currently only be set in the TOML config file:
ssl_key - key file to use when --ssl flag is set
ssl_cert - cert file to use when --ssl flag is set
tor_password - password to be used when connecting to the Tor controller
tor_service_dir - directory where Tor hidden service files will be created
run relay without storing any events
python -m monstr_terminal.run_relay --store=none
wipe the default (sqlite) db
python -m monstr_terminal.run_relay --w
builds up a local list of profiles for searching from the command line
usage: profile_search.py [-h] [-r RELAY] [-a AS_USER] [-b BOOTSTRAP] [-s SINCE] [-d]
search for nostr user profiles
options:
-h, --help show this help message and exit
-r RELAY, --relay RELAY
comma separated urls of relays to connect to - default ws://localhost:8081
-a AS_USER, --as_user AS_USER
nsec/npub/hex or alias for account viewing as - default None
-b BOOTSTRAP, --bootstrap BOOTSTRAP
nsec/npub/hex or alias for accounts used for bootstrapping - default None
-s SINCE, --since SINCE
n days to search back for profile events - default 5
-d, --debug enable debug output
start running with as alias monty attach to relay nos.lol
python profile_search.py --as=monty --relay=wss://nos.lol
on running at the > prompt type text to preform a search of seen profiles.
type 'exit' to quit
also follow commands are available:
- $count - returns count of profiles in cache
- $profile {nsec/npub} [short|long|json]- show profile meta data
- $contacts {nsec/npub} [short|long|json] - show profile meta for contacts of given key
- $posts {nsec/npup} - show last 10 post for profile