Commit graph

237 commits

Author SHA1 Message Date
4811fcf352 feat(nip17): support gift-wrapped private direct messages
Some checks failed
ci.yml / feat(nip17): support gift-wrapped private direct messages (pull_request) Failing after 0s
ci.yml / feat(nip17): support gift-wrapped private direct messages (push) Failing after 0s
v1.1.0-aio.2
Generalize the AUTH-gated, recipient-only delivery rule from NIP-04 to
also cover NIP-17 kind 1059 gift wraps. When the relay is configured to
require AUTH for kind 1059, only the AUTH'd recipient named in the
event's `p` tag receives it; otherwise gift wraps broadcast like any
regular event.

- relay/event.py: add `is_seal`, `is_gift_wrap`, `is_private_message`
  helpers (kinds 13, 1059)
- relay/client_connection.py: rename `_is_direct_message_for_other` ->
  `_is_private_event_for_other`; key off `is_private_message` so the
  same gating applies to kinds 4 and 1059
- relay/relay.py: advertise NIPs 17, 44, 59 in NIP-11 supported_nips
- README: document NIP-17/44/59 transport-level support
- tests/test_nip17.py: unit tests for kind classification, AUTH-gated
  1059 delivery (recipient vs non-recipient vs unauthenticated), and
  regression coverage for kind 4 gating

NIP-44 (encryption) and NIP-59 (wrap/seal) are client-side concerns;
the relay treats payloads as opaque ciphertext and stores kind 1059
like any regular event.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 13:59:14 +02:00
b74af2628e fix(nostrrelay): populate size field for event storage accounting
Some checks failed
CI / lint (push) Has been cancelled
CI / tests (push) Has been cancelled
v1.1.0-aio.1
Changes:
- relay/event.py: Add `size: int = 0` field to NostrEvent model
- relay/client_connection.py: Set `event.size = event.size_bytes` when creating events from WebSocket messages

The size field has existed in the database schema since migration m001 but was never populated, causing:
  - Incorrect storage accounting (always 0)
  - Broken storage quota enforcement
  - Failed event pruning when storage limits reached

The size field is internal relay metadata and is excluded from the nostr_dict() output, maintaining NIP-01 compliance. The size_bytes property calculates the actual byte size of the event's JSON representation.

Fixes: Database constraint violation when inserting events without the required size column value.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 23:53:37 +01:00
8d6f482de0 Fix critical filter logic bugs preventing event propagation in Nostr relay
Some checks failed
CI / lint (push) Waiting to run
CI / tests (push) Blocked by required conditions
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v0.0.2
- Fix inverted logic in _can_add_filter() method that was preventing new
subscription filters from being added
  - Fix REQ message handling to properly clear existing filters before
adding new ones
  - Fix inverted condition check when validating filter addition
capacity
  - Add debug logging to track filter matching and broadcast failures

  These bugs were causing customer order events (NIP-15) to be received
by the relay but not
  forwarded to nostrclient/nostrmarket, requiring server restarts or
manual refresh to process orders.
  The fix ensures proper event propagation: Customer → Relay →
nostrclient → nostrmarket → Invoice.

  Root cause: The _can_add_filter() method returned true when filters >=
max instead of when
  filters < max, and the validation check used the wrong conditional,
effectively blocking all
  new filter subscriptions after initial connection.
2026-01-06 23:05:22 +01:00
Patrick Mulligan
5e95b309fe make format
Some checks failed
CI / lint (push) Has been cancelled
CI / tests (push) Has been cancelled
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v0.0.1
2025-11-17 00:01:21 +01:00
Patrick Mulligan
8547864254 docs: Update README with complete NIP-09 deletion support
Updated NIP-09 section to document full implementation including:
  - 'e' tags for deleting regular events by event ID
  - 'a' tags for deleting addressable events by address format (kind:pubkey:d-identifier)

  This reflects the implementation added in commits 3ba3318 and 538fe42 which brought the relay into full NIP-09 compliance.
2025-11-17 00:01:21 +01:00
Patrick Mulligan
dcc3204735 Fix NIP-09 deletion for parameterized replaceable events (NIP-33)
Fixed bug where deleting a parameterized replaceable event (e.g., kind 31922)
using an 'a' tag would incorrectly delete ALL events of that kind instead of
just the specific event with the matching d-tag.

**Root Cause:**
NostrFilter's 'd' field uses a Pydantic Field alias "#d". When creating a filter
with `NostrFilter(d=[value])`, Pydantic ignores it because the parameter name
doesn't match the alias.

**Fix:**
Changed filter creation to use the alias:
```python
NostrFilter(authors=[...], kinds=[...], **{"#d": [d_tag]})
```

**Testing:**
- Created two tasks with different d-tags
- Deleted only one task
- Verified only the specified task was marked as deleted in the database
- Confirmed the other task remained unaffected

This ensures proper NIP-09 deletion behavior for NIP-33 parameterized
replaceable events using 'a' tag format (kind:pubkey:d-identifier).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 00:01:21 +01:00
Patrick Mulligan
8bfd792548 Add NIP-09 support for parameterized replaceable events (NIP-33)
Extended NIP-09 deletion event handling to support both regular events
and parameterized replaceable events (NIP-33).

**Previous behavior:**
- Only handled 'e' tags (regular event IDs)
- Did not support 'a' tags for addressable/replaceable events

**New behavior:**
- Handles both 'e' tags (event IDs) and 'a' tags (event addresses)
- Parses 'a' tag format: kind:pubkey:d-identifier
- Validates deletion author matches event address pubkey (NIP-09 requirement)
- Creates appropriate filters for each deletion type

**Implementation:**
- Added parsing for 'a' tag event addresses
- Extract kind, pubkey, and d-tag from address format
- Build NostrFilter with authors, kinds, and d-tag parameters
- Collect all event IDs to delete from both 'e' and 'a' tags
- Mark matching events as deleted in single operation

This enables proper deletion of parameterized replaceable events like
calendar events (kind 31922-31924), long-form content (kind 30023),
and other addressable event kinds.

Implements NIP-09: https://github.com/nostr-protocol/nips/blob/master/09.md
Supports NIP-33: https://github.com/nostr-protocol/nips/blob/master/33.md
2025-11-17 00:01:21 +01:00
Vlad Stan
c4efb87b70
chore: bump version (#41)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v1.1.0
2025-11-13 12:44:22 +02:00
dni ⚡
a53d2d7767
refactor: get rid of secp lib (#40) 2025-11-04 10:30:43 +02:00
dni ⚡
35584a230f
chore: add uv, linting, fixes (#39)
* chore: add uv, linting, fixes
2025-10-30 10:43:27 +01:00
PatMulligan
15079c3e58
fix(nostrrelay): use schema-qualified table name in delete_events (#38) 2025-10-27 09:54:29 +02:00
PatMulligan
22df5868de
FEAT: Implement NIP-01 Addressable Events Support (#33)
* Implement NIP-16 parameterized replaceable events

Add support for parameterized replaceable events (kinds 30000-39999) to
properly
handle Nostr marketplace product and stall updates according to NIP-16
specification.

Changes:
- Add is_parameterized_replaceable_event property to NostrEvent
- Implement automatic deletion of previous versions when new
parameterized replaceable event is received
- Add 'd' tag filtering support to NostrFilter for parameterized
replacement logic
- Update SQL query generation to handle 'd' tag joins

Fixes issue where product updates would create duplicate entries instead
of
replacing previous versions, ensuring only the latest version remains
visible.

* Refactor event handling for addressable events

Renamed the property is_parameterized_replaceable_event to is_addressable_event in NostrEvent to align with NIP-01 specifications (previously NIP-16). Updated the client_connection.py to utilize the new property for extracting 'd' tag values for addressable replacement, ensuring proper event handling in the relay system.

* Refactor tag filtering logic in NostrFilter

Updated the tag filtering mechanism to ensure that the filter only fails if the specified tags ('e' and 'p') are not found. This change improves clarity and maintains functionality by allowing for more precise control over event filtering.

* update readme

* Fix addressable event deletion and SQL schema issues

- Fix Pydantic field alias usage for d tag filtering (use #d instead of
d)
- Remove nostrrelay schema prefixes from SQL table references
- Implement subquery approach for DELETE operations with JOINs
- Resolve SQLite DELETE syntax incompatibility with JOIN statements
- Ensure NIP-33 compliance: only delete events with matching d tag
values
2025-09-10 16:40:40 +03:00
PatMulligan
687d7b89c1
Fix REQ message handling to support multiple filter subscriptions (#34)
This fix addresses an issue where REQ messages with multiple filters
were being rejected by the relay. Notably: The nostrmarket extension's
"Refresh from Nostr" functionality sends a single REQ message containing
4 different filter subscriptions:
- Direct Messages (kinds: [4])
- Stalls (kinds: [30017])
- Products (kinds: [30018])
- Profile (kinds: [0])

Changes:
- Changed validation from `len(data) != 3` to `len(data) < 3` to allow
multiple filters
- Added loop to process all filters in a single REQ message (data[2:])
- Accumulate responses from all filters before returning

This ensures compatibility with clients that batch multiple subscription
filters in a single REQ message, which is a valid pattern according to
NIP-01.
2025-09-10 16:35:25 +03:00
21M4TW
5a1a400f45
-Two issues were dicovered in get_config_for_all_active_relays which led (#32)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v1.0.1
to errors while loading relay configuration from the DB and that also
caused the loaded meta information to be invalid. Mandatory fields for
NostrRelay were not selected by the query, and a dictionary
representation of the meta object should not be returned as it causes
some members such as require_auth_filter and event_requires_auth to not
be accessible, leading to breaking exceptions.
2025-06-16 11:59:13 +03:00
Vlad Stan
3dc066fbd4
[fix] Ws api tests (#31)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v1.0.0
2024-11-11 15:25:25 +02:00
dni ⚡
73054fd5ce
feat: update to v1.0.0 (#30) 2024-11-08 15:32:04 +02:00
Bitkarrot
2bdbbb274d
Update client_connection.py (#29)
omit return none, in ref to https://github.com/lnbits/nostrrelay/issues/27
2024-10-14 09:39:48 +03:00
dni ⚡
cc6752003a
feat: improve codequality and CI (#25)
* feat: improve codequality and CI
2024-08-30 13:20:23 +02:00
dni ⚡
28121184c3
fix: properly start/stop tasks (#22)
https://github.com/lnbits/nostrclient/pull/28
2024-06-26 10:29:04 +02:00
Arc
94d383baff
Merge pull request #24 from lnbits/advanceddescription
Added advanced description
2024-05-17 12:16:47 +01:00
benarc
6d4f561e4e typo 2024-05-17 12:15:11 +01:00
benarc
d448ba6fa5 Added advanced description 2024-05-15 13:21:42 +01:00
dni ⚡
349bfa49d1
chore: rename websocketUpdater (#21)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v0.26.0
* chore: rename `websocketUpdater`
https://github.com/lnbits/lnbits/pull/2377
2024-04-12 12:11:03 +02:00
Vlad Stan
43eed0df35
fix: repository 2024-03-21 15:35:19 +02:00
Vlad Stan
94ae34158c
fix: admin check (#20)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v0.25.2
2024-03-21 11:29:36 +02:00
Tiago Vasconcelos
473614f8be
allow custom path (#17)
Some checks failed
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
v0.25.1
* allow custom path

---------

Co-authored-by: dni  <office@dnilabs.com>
2023-09-26 16:56:21 +02:00
dni ⚡
0215986a59
release workflow (#18) 2023-09-26 16:55:51 +02:00
Tiago Vasconcelos
3c45acc4d5 copy changes
more copy
clean debugging... prints! lol
clean console logs
fix get users

Only get users that explicitly have been allowed or blocked
UI
UI-2
prevent getting all accounts (false, false is default)
remove client side filtering


remove prints
2023-07-26 11:28:20 +03:00
Vlad Stan
07a07fc079 fix: do not remove README from archive v0.25 2023-04-19 14:41:14 +03:00
Vlad Stan
ccf620d476 feat: check account for REQ v0.24 2023-04-06 18:14:35 +03:00
Vlad Stan
dc50d3493d fix: is free to join if cost_to_join == 0 2023-04-06 18:14:12 +03:00
Vlad Stan
8ed361230b refactor: prepare for pay check 2023-04-06 17:33:09 +03:00
Vlad Stan
fddc8a1d22 refactor: field name 2023-04-06 17:31:49 +03:00
Vlad Stan
1a1875e177 fix: duplicate event 2023-04-06 17:31:26 +03:00
Vlad Stan
f19fb4a18e fix: delete account 2023-04-06 16:59:15 +03:00
Vlad Stan
f7fb926c52 fix: port value v0.23.2 2023-03-17 17:24:33 +02:00
Vlad Stan
28c0947afb fix: invoice can have undefined tag v0.23.1 2023-03-17 15:24:17 +02:00
Vlad Stan
527afa0c8c feat: wait for paid invoce v0.23 2023-03-17 15:06:59 +02:00
Vlad Stan
3aa4875558 chore: code format 2023-03-17 15:06:09 +02:00
Vlad Stan
30ffcf7f55 fix: show wss & invoice generation v0.22 2023-03-15 21:19:31 +02:00
Vlad Stan
218b324347 chore: code format 2023-03-15 21:19:31 +02:00
Vlad Stan
6e1b5dd0bb fix: copy button 2023-03-15 21:19:31 +02:00
Vlad Stan
67dda89c81 fix: separate relay update from activete/deactivate 2023-03-15 21:19:31 +02:00
Vlad Stan
63be2b5b2d feat: show wss URL 2023-03-15 21:19:31 +02:00
Vlad Stan
5e313c0282 chore: code format 2023-03-15 21:17:51 +02:00
Vlad Stan
16b9d93dca fix: use Spec for PaymentSpec v0.21 2023-02-22 11:39:35 +02:00
Vlad Stan
8df0dc2f52 chore: code clean-up 2023-02-22 11:39:35 +02:00
Vlad Stan
dd9dbbe818 fix: return generic Relay Info 2023-02-21 16:20:19 +02:00
Vlad Stan
f4d4706237 chore: remove test path 2023-02-21 16:20:19 +02:00
Vlad Stan
8c860f851a feat: update supported NIPs 2023-02-21 16:20:19 +02:00