{"id":13832742,"url":"https://github.com/jeffthibault/python-nostr","last_synced_at":"2025-07-09T19:31:13.775Z","repository":{"id":47392681,"uuid":"515975748","full_name":"jeffthibault/python-nostr","owner":"jeffthibault","description":"A Python library for Nostr","archived":false,"fork":false,"pushed_at":"2023-11-27T18:39:22.000Z","size":49,"stargazers_count":258,"open_issues_count":55,"forks_count":84,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-05-14T11:22:06.692Z","etag":null,"topics":["nostr","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffthibault.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-07-20T12:37:09.000Z","updated_at":"2024-05-09T05:43:29.000Z","dependencies_parsed_at":"2024-01-13T16:28:56.771Z","dependency_job_id":"69557467-9980-4111-a873-8391774dc69b","html_url":"https://github.com/jeffthibault/python-nostr","commit_stats":{"total_commits":76,"total_committers":9,"mean_commits":8.444444444444445,"dds":"0.23684210526315785","last_synced_commit":"37cb66ba2d3968b2d75cc8ad71c3550415ca47fe"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffthibault%2Fpython-nostr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffthibault%2Fpython-nostr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffthibault%2Fpython-nostr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffthibault%2Fpython-nostr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffthibault","download_url":"https://codeload.github.com/jeffthibault/python-nostr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225581832,"owners_count":17491794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nostr","python"],"created_at":"2024-08-04T11:00:29.387Z","updated_at":"2024-11-20T15:31:03.316Z","avatar_url":"https://github.com/jeffthibault.png","language":"Python","funding_links":[],"categories":["Install from Source","Libraries","网络服务"],"sub_categories":["Nostr","Client reviews and/or comparisons","网络服务_其他"],"readme":"# python-nostr\nA Python library for making [Nostr](https://github.com/nostr-protocol/nostr) clients\n\n## Usage\n**Generate a key**\n```python\nfrom nostr.key import PrivateKey\n\nprivate_key = PrivateKey()\npublic_key = private_key.public_key\nprint(f\"Private key: {private_key.bech32()}\")\nprint(f\"Public key: {public_key.bech32()}\")\n```\n\n**Connect to relays**\n```python\nimport json\nimport ssl\nimport time\nfrom nostr.relay_manager import RelayManager\n\nrelay_manager = RelayManager()\nrelay_manager.add_relay(\"wss://nostr-pub.wellorder.net\")\nrelay_manager.add_relay(\"wss://relay.damus.io\")\nrelay_manager.open_connections({\"cert_reqs\": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification\ntime.sleep(1.25) # allow the connections to open\n\nwhile relay_manager.message_pool.has_notices():\n  notice_msg = relay_manager.message_pool.get_notice()\n  print(notice_msg.content)\n  \nrelay_manager.close_connections()\n```\n\n**Publish to relays**\n```python\nimport json \nimport ssl\nimport time\nfrom nostr.event import Event\nfrom nostr.relay_manager import RelayManager\nfrom nostr.message_type import ClientMessageType\nfrom nostr.key import PrivateKey\n\nrelay_manager = RelayManager()\nrelay_manager.add_relay(\"wss://nostr-pub.wellorder.net\")\nrelay_manager.add_relay(\"wss://relay.damus.io\")\nrelay_manager.open_connections({\"cert_reqs\": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification\ntime.sleep(1.25) # allow the connections to open\n\nprivate_key = PrivateKey()\n\nevent = Event(\"Hello Nostr\")\nprivate_key.sign_event(event)\n\nrelay_manager.publish_event(event)\ntime.sleep(1) # allow the messages to send\n\nrelay_manager.close_connections()\n```\n\n**Reply to a note**\n```python\nfrom nostr.event import Event\n\nreply = Event(\n  content=\"Hey, that's a great point!\",\n)\n\n# create 'e' tag reference to the note you're replying to\nreply.add_event_ref(original_note_id)\n\n# create 'p' tag reference to the pubkey you're replying to\nreply.add_pubkey_ref(original_note_author_pubkey)\n\nprivate_key.sign_event(reply)\nrelay_manager.publish_event(reply)\n```\n\n**Send a DM**\n```python\nfrom nostr.event import EncryptedDirectMessage\n\ndm = EncryptedDirectMessage(\n  recipient_pubkey=recipient_pubkey,\n  cleartext_content=\"Secret message!\"\n)\nprivate_key.sign_event(dm)\nrelay_manager.publish_event(dm)\n```\n\n\n**Receive events from relays**\n```python\nimport json\nimport ssl\nimport time\nfrom nostr.filter import Filter, Filters\nfrom nostr.event import Event, EventKind\nfrom nostr.relay_manager import RelayManager\nfrom nostr.message_type import ClientMessageType\n\nfilters = Filters([Filter(authors=[\u003ca nostr pubkey in hex\u003e], kinds=[EventKind.TEXT_NOTE])])\nsubscription_id = \u003ca string to identify a subscription\u003e\nrequest = [ClientMessageType.REQUEST, subscription_id]\nrequest.extend(filters.to_json_array())\n\nrelay_manager = RelayManager()\nrelay_manager.add_relay(\"wss://nostr-pub.wellorder.net\")\nrelay_manager.add_relay(\"wss://relay.damus.io\")\nrelay_manager.add_subscription(subscription_id, filters)\nrelay_manager.open_connections({\"cert_reqs\": ssl.CERT_NONE}) # NOTE: This disables ssl certificate verification\ntime.sleep(1.25) # allow the connections to open\n\nmessage = json.dumps(request)\nrelay_manager.publish_message(message)\ntime.sleep(1) # allow the messages to send\n\nwhile relay_manager.message_pool.has_events():\n  event_msg = relay_manager.message_pool.get_event()\n  print(event_msg.event.content)\n  \nrelay_manager.close_connections()\n```\n\n**NIP-26 delegation**\n```python\nfrom nostr.delegation import Delegation\nfrom nostr.event import EventKind, Event\nfrom nostr.key import PrivateKey\n\n# Load your \"identity\" PK that you'd like to keep safely offline\nidentity_pk = PrivateKey.from_nsec(\"nsec1...\")\n\n# Create a new, disposable PK as the \"delegatee\" that can be \"hot\" in a Nostr client\ndelegatee_pk = PrivateKey()\n\n# the \"identity\" PK will authorize \"delegatee\" to sign TEXT_NOTEs on its behalf for the next month\ndelegation = Delegation(\n    delegator_pubkey=identity_pk.public_key.hex(),\n    delegatee_pubkey=delegatee_pk.public_key.hex(),\n    event_kind=EventKind.TEXT_NOTE,\n    duration_secs=30*24*60*60\n)\n\nidentity_pk.sign_delegation(delegation)\n\nevent = Event(\n    \"Hello, NIP-26!\",\n    tags=[delegation.get_tag()],\n)\ndelegatee_pk.sign_event(event)\n\n# ...normal broadcast steps...\n```\n\nThe resulting delegation tag can be stored as plaintext and reused as-is by the \"delegatee\" PK until the delegation token expires. There is no way to revoke a signed delegation, so current best practice is to keep the expiration time relatively short.\n\nHopefully clients will include an optional field to store the delegation tag. That would allow the \"delegatee\" PK to seamlessly post messages on the \"identity\" key's behalf, while the \"identity\" key stays safely offline in cold storage.\n\n\n## Installation\n```bash\npip install nostr\n```\n\nNote: I wrote this with Python 3.9.5.\n\n## Test Suite\nSee the [Test Suite README](test/README.md)\n\n## Disclaimer\n- This library is in very early development.\n- It might have some bugs.\n- I need to add more tests.\n\nPlease feel free to add issues, add PRs, or provide any feedback!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffthibault%2Fpython-nostr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffthibault%2Fpython-nostr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffthibault%2Fpython-nostr/lists"}