From 729f36e993e23f8e88a0d00f78615580c0c8e933 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 10:29:46 +0200 Subject: [PATCH 01/54] refactor: extract `relay_info_response` --- helpers.py | 12 ++++++++++++ views.py | 12 +++--------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/helpers.py b/helpers.py index 5f2b065..169c65c 100644 --- a/helpers.py +++ b/helpers.py @@ -1,6 +1,7 @@ from urllib.parse import urlparse from bech32 import bech32_decode, convertbits +from starlette.responses import JSONResponse def normalize_public_key(pubkey: str) -> str: @@ -23,3 +24,14 @@ def normalize_public_key(pubkey: str) -> str: def extract_domain(url: str) -> str: return urlparse(url).netloc + + +def relay_info_response(relay_public_data: dict) -> JSONResponse: + return JSONResponse( + content=relay_public_data, + headers={ + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "*", + "Access-Control-Allow-Methods": "GET", + }, + ) \ No newline at end of file diff --git a/views.py b/views.py index 7d11b17..f170afb 100644 --- a/views.py +++ b/views.py @@ -3,13 +3,14 @@ from http import HTTPStatus from fastapi import Depends, Request from fastapi.exceptions import HTTPException from fastapi.templating import Jinja2Templates -from starlette.responses import HTMLResponse, JSONResponse +from starlette.responses import HTMLResponse from lnbits.core.models import User from lnbits.decorators import check_user_exists from . import nostrrelay_ext, nostrrelay_renderer from .crud import get_public_relay +from .helpers import relay_info_response templates = Jinja2Templates(directory="templates") @@ -32,14 +33,7 @@ async def nostrrelay(request: Request, relay_id: str): ) if request.headers.get("accept") == "application/nostr+json": - return JSONResponse( - content=relay_public_data, - headers={ - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Headers": "*", - "Access-Control-Allow-Methods": "GET", - }, - ) + return relay_info_response(relay_public_data) return nostrrelay_renderer().TemplateResponse( "nostrrelay/public.html", {"request": request, "relay": relay_public_data} From 8d316c4887a05cdcb5eb1849df81295f0c362c8f Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 10:31:20 +0200 Subject: [PATCH 02/54] feat: add `redirect_paths` --- __init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/__init__.py b/__init__.py index b5d8407..64d30c7 100644 --- a/__init__.py +++ b/__init__.py @@ -20,6 +20,16 @@ nostrrelay_static_files = [ } ] +redirect_paths = [ + { + "from_path": "/", + "redirect_to_path": "/api/v1/relay-info", + "header_filters": [{ + "accept": "application/nostr+json" + }] + } +] + scheduled_tasks: List[asyncio.Task] = [] def nostrrelay_renderer(): From d66184c077ce6232210e54d69ade75f29a2e4aed Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 10:31:42 +0200 Subject: [PATCH 03/54] feat: add `/api/v1/relay-info` endpoint --- views_api.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/views_api.py b/views_api.py index 2700378..4f9a3fa 100644 --- a/views_api.py +++ b/views_api.py @@ -5,6 +5,7 @@ from fastapi import Depends, Request, WebSocket from fastapi.exceptions import HTTPException from loguru import logger from pydantic.types import UUID4 +from starlette.responses import JSONResponse from lnbits.core.services import create_invoice from lnbits.decorators import ( @@ -29,7 +30,7 @@ from .crud import ( update_account, update_relay, ) -from .helpers import extract_domain, normalize_public_key +from .helpers import extract_domain, normalize_public_key, relay_info_response from .models import BuyOrder, NostrAccount, NostrPartialAccount from .relay.client_manager import NostrClientConnection, NostrClientManager from .relay.relay import NostrRelay @@ -124,6 +125,18 @@ async def api_get_relays( status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Cannot fetch relays", ) +@nostrrelay_ext.get("/api/v1/relay-info") +async def api_get_relay_info( request: Request, +) -> JSONResponse: + + if request.headers.get("accept") == "application/nostr+json": + return relay_info_response({}) + + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, + detail="Cannot fetch relays info", + ) + @nostrrelay_ext.get("/api/v1/relay/{relay_id}") From ffb017700338b47294d735afeaecf1d17fd37563 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 10:32:08 +0200 Subject: [PATCH 04/54] chore: code format --- README.md | 79 ++-- config.json | 2 +- manifest.json | 14 +- tests/fixture/clients.json | 737 ++++++++++++++++++------------------- tests/fixture/events.json | 433 +++++++++++----------- 5 files changed, 623 insertions(+), 642 deletions(-) diff --git a/README.md b/README.md index 8317f2a..7955288 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Nostr Relay ### One click and spin up your own Nostr relay. Share with the world, or use privately. + **Configure**: + - Free Plan: with limitted storage (limit can be changed) - Paid Plan: `pay to join` and `pay for storage` - Storage Limit (can buy more) @@ -11,57 +13,61 @@ - Optional Auth for `Events` and `Filters` ## Supported NIPs - - [x] **NIP-01**: Basic protocol flow - - [x] **NIP-02**: Contact List and Petnames - - `kind: 3`: delete past contact lists as soon as the relay receives a new one - - [x] **NIP-04**: Encrypted Direct Message - - if `AUTH` enabled: send only to the intended target - - [x] **NIP-09**: Event Deletion - - [x] **NIP-11**: Relay Information Document - - >**Note**: the endpoint is NOT on the root level of the domain. It also includes a path (eg https://lnbits.link/nostrrelay/) - - [ ] **NIP-12**: Generic Tag Queries - - todo - - [x] **NIP-15**: End of Stored Events Notice - - [x] **NIP-16**: Event Treatment - - [x] Regular Events - - [x] Replaceable Events - - [x] Ephemeral Events - - [x] **NIP-20**: Command Results - - todo: use correct prefixes - - [x] **NIP-22**: Event created_at Limits - - [ ] **NIP-26**: Delegated Event Signing - - not planned - - [x] **NIP-28** Public Chat - - `kind: 41`: handled similar to `kind 0` metadata events - - [ ] **NIP-33**: Parameterized Replaceable Events - - todo - - [ ] **NIP-40**: Expiration Timestamp - - todo - - [x] **NIP-42**: Authentication of clients to relays - - todo: use correct prefix - - [ ] **NIP-50**: Search Capability - - todo +- [x] **NIP-01**: Basic protocol flow +- [x] **NIP-02**: Contact List and Petnames + - `kind: 3`: delete past contact lists as soon as the relay receives a new one +- [x] **NIP-04**: Encrypted Direct Message + - if `AUTH` enabled: send only to the intended target +- [x] **NIP-09**: Event Deletion +- [x] **NIP-11**: Relay Information Document + - > **Note**: the endpoint is NOT on the root level of the domain. It also includes a path (eg https://lnbits.link/nostrrelay/) +- [ ] **NIP-12**: Generic Tag Queries + - todo +- [x] **NIP-15**: End of Stored Events Notice +- [x] **NIP-16**: Event Treatment + - [x] Regular Events + - [x] Replaceable Events + - [x] Ephemeral Events +- [x] **NIP-20**: Command Results + - todo: use correct prefixes +- [x] **NIP-22**: Event created_at Limits +- [ ] **NIP-26**: Delegated Event Signing + - not planned +- [x] **NIP-28** Public Chat + - `kind: 41`: handled similar to `kind 0` metadata events +- [ ] **NIP-33**: Parameterized Replaceable Events + - todo +- [ ] **NIP-40**: Expiration Timestamp + - todo +- [x] **NIP-42**: Authentication of clients to relays + - todo: use correct prefix +- [ ] **NIP-50**: Search Capability + - todo ## Create Relay + Creating a new relay is straightforward. Just click `New Relay` then enter the Relay Info. + > **Note**: admin users can select a relay id. Regular users will be assigned a generated relay id. -The relay can be activated/deactivated. +> The relay can be activated/deactivated. - **New Relay Dialog** - - ![image](https://user-images.githubusercontent.com/2951406/219601417-9292d5b9-d96c-4ff6-a6fd-6c8b37b9872d.png) + - ![image](https://user-images.githubusercontent.com/2951406/219601417-9292d5b9-d96c-4ff6-a6fd-6c8b37b9872d.png) ## Configure Relay + Find your Relay in the list and click the expand button (`+`) to configure it. ### Relay Info + This tab contains data according to `NIP-11` (Relay Information Document). + > **Note**: the `domain` is added automatically and shoud be corrected manually if needed. This value is used for `NIP-42` (Authentication of clients to relays) - **Relay Info Tab** - ![image](https://user-images.githubusercontent.com/2951406/219601945-f3987de0-ed0c-48d5-b31e-44d8356cfa9a.png) - ### Payment By default the relay is free to access, but it can be configured to ask for payments. @@ -76,8 +82,7 @@ Click on the Relay ID (or visit `https://{your_domain}/nostrrelay/${relay_id}`) Here the entry and storage fees can be paid. - **Relay Public Page** - - ![image](https://user-images.githubusercontent.com/2951406/219610594-ec2984ca-2c09-4187-91c3-96a25e8b5722.png) - + - ![image](https://user-images.githubusercontent.com/2951406/219610594-ec2984ca-2c09-4187-91c3-96a25e8b5722.png) ### Config @@ -90,14 +95,13 @@ Some configurations are not standard (`NIPs`) but they help control what clients - **Config Tab** - ![image](https://user-images.githubusercontent.com/2951406/219611794-57066899-5bc3-4439-ad98-af6fd4130ee9.png) - ### Accounts Allows the Relay operator to `Block` or `Allow` certain accounts. If an account is `allowed` then it is not required to `pay to join`. -When an account is `blocked` it does not matter if it `paid to join` or if it is `allowed`. +When an account is `blocked` it does not matter if it `paid to join` or if it is `allowed`. - **Accounts Tab** - ![image](https://user-images.githubusercontent.com/2951406/219615500-8ca98580-dc3d-4163-b321-ae9279d47a98.png) @@ -105,6 +109,7 @@ When an account is `blocked` it does not matter if it `paid to join` or if it i ## Development Create Symbolic Link: + ``` ln -s /Users/my-user/git-repos/nostr-relay-extension/ /Users/my-user/git-repos/lnbits/lnbits/extensions/nostrrelay ``` diff --git a/config.json b/config.json index e3de9fa..afc7f67 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "name": "Nostr Relay", "short_description": "One click launch your own relay!", - "tile": "/nostrrelay/static/image/nostrrelay.png", + "tile": "/nostrrelay/static/image/nostrrelay.png", "contributors": ["arcbtc", "DCs"] } diff --git a/manifest.json b/manifest.json index 7a3cc6c..67ed091 100644 --- a/manifest.json +++ b/manifest.json @@ -1,9 +1,9 @@ { - "repos": [ - { - "id": "nostrrelay", - "organisation": "lnbits", - "repository": "nostr-relay-extension" - } - ] + "repos": [ + { + "id": "nostrrelay", + "organisation": "lnbits", + "repository": "nostr-relay-extension" + } + ] } diff --git a/tests/fixture/clients.json b/tests/fixture/clients.json index 865ec19..3ad9378 100644 --- a/tests/fixture/clients.json +++ b/tests/fixture/clients.json @@ -1,384 +1,365 @@ { - "alice": { - "meta": [ - "EVENT", - { - "id": "9d4883c31d6ae3d80fd8882a248cc193800a096d87bd55d5c1df8a237e78ca09", - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "created_at": 1675332095, - "kind": 0, - "tags": [], - "content": "{\"name\":\"Alice\"}", - "sig": "95c30b6bbc70f3777d2b2b47ae3961e196eae0df72f3ae301ff1009cdabf9c50bb0eb7825891c842fc6ca5cb268342cc486850a6127ab40df871bd3e1fd0b0d7" - } + "alice": { + "meta": [ + "EVENT", + { + "id": "9d4883c31d6ae3d80fd8882a248cc193800a096d87bd55d5c1df8a237e78ca09", + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "created_at": 1675332095, + "kind": 0, + "tags": [], + "content": "{\"name\":\"Alice\"}", + "sig": "95c30b6bbc70f3777d2b2b47ae3961e196eae0df72f3ae301ff1009cdabf9c50bb0eb7825891c842fc6ca5cb268342cc486850a6127ab40df871bd3e1fd0b0d7" + } + ], + "meta_response": [ + "OK", + "9d4883c31d6ae3d80fd8882a248cc193800a096d87bd55d5c1df8a237e78ca09", + true, + "" + ], + "meta_update": [ + "EVENT", + { + "id": "2928f73760ac3a60affdf51d04169680472a8594b4584f087f497dcf6a28d12a", + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "created_at": 1675673494, + "kind": 0, + "tags": [], + "content": "{\"name\":\"Alice\",\"about\":\"Uses Hamstr\"}", + "sig": "938313418d6d8b16b43213b3347c64925cbc1846e4447b4d878be9b865fe4b78f276ac399ea6b0aa81ed88fb18c992f2fae9e4f70c35c49202e576c54a0dc89c" + } + ], + "meta_update_response": [ + "OK", + "2928f73760ac3a60affdf51d04169680472a8594b4584f087f497dcf6a28d12a", + true, + "" + ], + "post01": [ + "EVENT", + { + "id": "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "created_at": 1675332224, + "kind": 1, + "tags": [], + "content": "Alice - post 01", + "sig": "8d27c9f818ff194b491de1dc7d52d2d26916d87189ed1330315c4ff5509a986c80f34c2202302f8fe246c0b3f4e2f79103c000cbd6ca65bbe3921e14f30cb35b" + } + ], + "post01_response_ok": [ + "OK", + "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", + true, + "" + ], + "post01_response_duplicate": [ + "OK", + "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", + true, + "error: failed to create event" + ], + "post02": [ + "EVENT", + { + "id": "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5", + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "created_at": 1675332284, + "kind": 1, + "tags": [], + "content": "Alice post 02", + "sig": "012fc88407b0cfb967e80d1117acf6cf03410f6810039543d2290eef64e246d82ad130d08814b2564cee68e77dd0e99ea539e7a9751ef2e0914e7d93f345094e" + } + ], + "post02_response_ok": [ + "OK", + "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5", + true, + "" + ], + "subscribe_reactions_to_me": [ + "REQ", + "notifications:0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345", + { + "kinds": [1, 7, 6, 4], + "#p": [ + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" ], - "meta_response": [ - "OK", - "9d4883c31d6ae3d80fd8882a248cc193800a096d87bd55d5c1df8a237e78ca09", - true, - "" + "limit": 400 + } + ], + "direct_message01": [ + "EVENT", + { + "id": "28c96b6e80681c18a690e0e0dc6ca4e72b9d291d1d2576bc8949a07bb4bee225", + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "created_at": 1675412967, + "kind": 4, + "tags": [ + [ + "p", + "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" + ] ], - "meta_update": [ - "EVENT", - { - "id": "2928f73760ac3a60affdf51d04169680472a8594b4584f087f497dcf6a28d12a", - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "created_at": 1675673494, - "kind": 0, - "tags": [], - "content": "{\"name\":\"Alice\",\"about\":\"Uses Hamstr\"}", - "sig": "938313418d6d8b16b43213b3347c64925cbc1846e4447b4d878be9b865fe4b78f276ac399ea6b0aa81ed88fb18c992f2fae9e4f70c35c49202e576c54a0dc89c" - } + "content": "BwstXDkQJAHnLOrWFzBRDHdMoF4hoXSCwgmR+K2uw237yss/i639rpR2iOIYJP4z?iv=5pTRQh6NBKfe1hyhwh2WEw==", + "sig": "5da31b8a51dcc9fc9665db6199084696b705fc415e1be684b82fe39f3cbd271c2d707fd5a532232205a016e99ed1ef12abdacb52d139d7f5746cb693de71e5aa" + } + ], + "direct_message01_response": [ + "OK", + "28c96b6e80681c18a690e0e0dc6ca4e72b9d291d1d2576bc8949a07bb4bee225", + true, + "" + ], + "delete_post01": [ + "EVENT", + { + "kind": 5, + "content": "deleted", + "tags": [ + [ + "e", + "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" + ], + ["e", "mock-id", ""], + [ + "e", + "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea" + ] ], - "meta_update_response": [ - "OK", - "2928f73760ac3a60affdf51d04169680472a8594b4584f087f497dcf6a28d12a", - true, - "" - ], - "post01": [ - "EVENT", - { - "id": "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "created_at": 1675332224, - "kind": 1, - "tags": [], - "content": "Alice - post 01", - "sig": "8d27c9f818ff194b491de1dc7d52d2d26916d87189ed1330315c4ff5509a986c80f34c2202302f8fe246c0b3f4e2f79103c000cbd6ca65bbe3921e14f30cb35b" - } - ], - "post01_response_ok": [ - "OK", - "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", - true, - "" - ], - "post01_response_duplicate": [ - "OK", - "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85", - true, - "error: failed to create event" - ], - "post02": [ - "EVENT", - { - "id": "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5", - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "created_at": 1675332284, - "kind": 1, - "tags": [], - "content": "Alice post 02", - "sig": "012fc88407b0cfb967e80d1117acf6cf03410f6810039543d2290eef64e246d82ad130d08814b2564cee68e77dd0e99ea539e7a9751ef2e0914e7d93f345094e" - } - ], - "post02_response_ok": [ - "OK", - "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5", - true, - "" - ], - "subscribe_reactions_to_me": [ - "REQ", - "notifications:0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345", - { - "kinds": [ - 1, - 7, - 6, - 4 - ], - "#p": [ - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ], - "limit": 400 - } - ], - "direct_message01": [ - "EVENT", - { - "id": "28c96b6e80681c18a690e0e0dc6ca4e72b9d291d1d2576bc8949a07bb4bee225", - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "created_at": 1675412967, - "kind": 4, - "tags": [ - [ - "p", - "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" - ] - ], - "content": "BwstXDkQJAHnLOrWFzBRDHdMoF4hoXSCwgmR+K2uw237yss/i639rpR2iOIYJP4z?iv=5pTRQh6NBKfe1hyhwh2WEw==", - "sig": "5da31b8a51dcc9fc9665db6199084696b705fc415e1be684b82fe39f3cbd271c2d707fd5a532232205a016e99ed1ef12abdacb52d139d7f5746cb693de71e5aa" - } - ], - "direct_message01_response": [ - "OK", - "28c96b6e80681c18a690e0e0dc6ca4e72b9d291d1d2576bc8949a07bb4bee225", - true, - "" - ], - "delete_post01": [ - "EVENT", - { - "kind": 5, - "content": "deleted", - "tags": [ - [ - "e", - "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" - ], - [ - "e", - "mock-id", - "" - ], - [ - "e", - "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea" - ] - ], - "created_at": 1675427798, - "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", - "id": "2751f2ee0f894268c61300c5b1a1a434f49a33a467a6f4516f10a82a1848f093", - "sig": "8e972ba7f1ce9d11ba5d49fdd48db4a92ea999790eb604e6a7f01868a26a70a8e96e1f9e104d8f77a5aa7f29e94119e33117b4cc8a5ff9e50ec8c23eeccd94e9" - } - ], - "delete_post01_response": [ - "OK", - "2751f2ee0f894268c61300c5b1a1a434f49a33a467a6f4516f10a82a1848f093", - true, - "" - ], - "subscribe_to_bob_contact_list": [ - "REQ", - "contact", - { - "kinds": [ - 3 - ], - "authors": [ - "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" - ] - } + "created_at": 1675427798, + "pubkey": "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816", + "id": "2751f2ee0f894268c61300c5b1a1a434f49a33a467a6f4516f10a82a1848f093", + "sig": "8e972ba7f1ce9d11ba5d49fdd48db4a92ea999790eb604e6a7f01868a26a70a8e96e1f9e104d8f77a5aa7f29e94119e33117b4cc8a5ff9e50ec8c23eeccd94e9" + } + ], + "delete_post01_response": [ + "OK", + "2751f2ee0f894268c61300c5b1a1a434f49a33a467a6f4516f10a82a1848f093", + true, + "" + ], + "subscribe_to_bob_contact_list": [ + "REQ", + "contact", + { + "kinds": [3], + "authors": [ + "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" ] - }, - "bob": { - "meta": [ - "EVENT", - { - "id": "a3591f44f9f12e8d745a79c19affc1f9ea267a716981116835ddb7b327096be5", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675332410, - "kind": 0, - "tags": [], - "content": "{\"name\":\"Bob\"}", - "sig": "52b142eb5bf95e46424d8f146a0efcfd1be35ec2ae446152ccc875bc82eee66bef6df1af9a4456ec8984540ac4e21905544b5291334e2b18a24e534b788b2d81" - } - ], - "meta_response": [ - "OK", - "a3591f44f9f12e8d745a79c19affc1f9ea267a716981116835ddb7b327096be5", - true, - "" - ], - "request_meta_alice": [ - "REQ", - "profile", - { - "kinds": [ - 0 - ], - "authors": [ - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - } - ], - "request_posts_alice": [ - "REQ", - "sub0", - { - "kinds": [ - 1 - ], - "authors": [ - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ], - "limit": 50 - } - ], - "like_post01": [ - "EVENT", - { - "id": "700da4df9029a049ddecd1c586b778f434afb55e56c3016d94334108e3829db7", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675350162, - "kind": 7, - "tags": [ - [ - "e", - "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" - ], - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - ], - "content": "\u2764\ufe0f", - "sig": "3522d670f2e28bd63d32184aa9617df360684e5bc4b7c791b53c5401437e1bf91d1d335f016076fdee9afa99046dc9cc06a39738b25ff9a1562ac7321e3dca2e" - } - ], - "like_post02": [ - "EVENT", - { - "id": "920ee4e856acb3310e64415183da0dd7e2e2b7e7c5a517553b9a75981fbafcc9", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675332450, - "kind": 7, - "tags": [ - [ - "e", - "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5" - ], - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - ], - "content": "\u2764\ufe0f", - "sig": "90fa8093088ed9280277f10a97c41d68d9f51d24254f7b27c28f5d84ac25426f1bfc217bca0c6712a9965164b07db219ee7e583b94c4d26f00aee87344c3f17a" - } - ], - "like_post02_response": [ - "OK", - "920ee4e856acb3310e64415183da0dd7e2e2b7e7c5a517553b9a75981fbafcc9", - true, - "" - ], - "comment_on_alice_post01": [ - "EVENT", - { - "id": "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675332468, - "kind": 1, - "tags": [ - [ - "e", - "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" - ], - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - ], - "content": "bob comment 01", - "sig": "f9bb53e2adc27f3a49ec42d681833742e28d734327107ebba3076be226340503048116947a75274e5262fa03aa0430da6fe697e46e19342639ef208e5690d8c5" - } - ], - "comment_on_alice_post01_response": [ - "OK", - "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea", - true, - "" - ], - "direct_message01": [ - "EVENT", - { - "id": "15f6e6bd6cb538167d4430ea6bd7c0cfb99b400ca3e8879a114e90f74b3f20b2", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675412687, - "kind": 4, - "tags": [ - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - ], - "content": "jjBSyp36t555ywERY2fI4A==?iv=+8bg2vsltrXewAywxw9m6w==", - "sig": "091f4e8e5c497099bfe6af58126e022bc8babe648b8157c39f51e5d3906bfddf01f2f6d1a3ed36f94fbf07b009008fd448fbb8ce35b60260517aa0124a6c5c39" - } - ], - "direct_message01_response": [ - "OK", - "15f6e6bd6cb538167d4430ea6bd7c0cfb99b400ca3e8879a114e90f74b3f20b2", - true, - "" - ], - "subscribe_to_direct_messages": [ - "REQ", - "notifications:d685447c43c7c18dbbea61923cf0b63e1ab46bed", - { - "kinds": [ - 4 - ], - "#p": [ - "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" - ], - "limit": 400 - } - ], - "subscribe_to_delete_from_alice": [ - "REQ", - "notifications:delete", - { - "kinds": [ - 5 - ], - "authors": [ - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ], - "limit": 400 - } - ], - "contact_list_create": [ - "EVENT", - { - "id": "141ddb3008ed1cc35fa09ff88d3b82da0351c6166c566e6220293136aa902a62", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675350109, - "kind": 3, - "tags": [ - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ] - ], - "content": "", - "sig": "740972ce0335fe6be7194c995e407e440b4194e49ee2775a19dc36eb5e9d8302ea8d0ab93cdc11eb345a9f8bae32c14bcbd4b7f3fe9b97d197b8426dba139847" - } - ], - "contact_list_create_response": [ - "OK", - "141ddb3008ed1cc35fa09ff88d3b82da0351c6166c566e6220293136aa902a62", - true, - "" - ], - "contact_list_update": [ - "EVENT", - { - "id": "1439f08983433295bc54d24b8c3cda2fa137d86636535a408d2d9a7bac5f0c40", - "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", - "created_at": 1675444161, - "kind": 3, - "tags": [ - [ - "p", - "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" - ], - [ - "p", - "8d21cd7c3f204cbb8aaf7708445b49e6cef7da23a550f9a27d21b1122c0cb4e9" - ] - ], - "content": "", - "sig": "648230464f6b79063da76c1c9d06cd290c65f95fca4bac2e055f84f003847a4b9a2e144b4d77ec9f2f5289d477353a21494548d1b1fbf8795602c8914a062d50" - } - ], - "contact_list_update_response": [ - "OK", - "1439f08983433295bc54d24b8c3cda2fa137d86636535a408d2d9a7bac5f0c40", - true, - "" + } + ] + }, + "bob": { + "meta": [ + "EVENT", + { + "id": "a3591f44f9f12e8d745a79c19affc1f9ea267a716981116835ddb7b327096be5", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675332410, + "kind": 0, + "tags": [], + "content": "{\"name\":\"Bob\"}", + "sig": "52b142eb5bf95e46424d8f146a0efcfd1be35ec2ae446152ccc875bc82eee66bef6df1af9a4456ec8984540ac4e21905544b5291334e2b18a24e534b788b2d81" + } + ], + "meta_response": [ + "OK", + "a3591f44f9f12e8d745a79c19affc1f9ea267a716981116835ddb7b327096be5", + true, + "" + ], + "request_meta_alice": [ + "REQ", + "profile", + { + "kinds": [0], + "authors": [ + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" ] - } -} \ No newline at end of file + } + ], + "request_posts_alice": [ + "REQ", + "sub0", + { + "kinds": [1], + "authors": [ + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ], + "limit": 50 + } + ], + "like_post01": [ + "EVENT", + { + "id": "700da4df9029a049ddecd1c586b778f434afb55e56c3016d94334108e3829db7", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675350162, + "kind": 7, + "tags": [ + [ + "e", + "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" + ], + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ] + ], + "content": "\u2764\ufe0f", + "sig": "3522d670f2e28bd63d32184aa9617df360684e5bc4b7c791b53c5401437e1bf91d1d335f016076fdee9afa99046dc9cc06a39738b25ff9a1562ac7321e3dca2e" + } + ], + "like_post02": [ + "EVENT", + { + "id": "920ee4e856acb3310e64415183da0dd7e2e2b7e7c5a517553b9a75981fbafcc9", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675332450, + "kind": 7, + "tags": [ + [ + "e", + "79d89e66626c4c54b007259cf068a7ba9416ffb6262cc01ba8e7cebf79b9c0d5" + ], + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ] + ], + "content": "\u2764\ufe0f", + "sig": "90fa8093088ed9280277f10a97c41d68d9f51d24254f7b27c28f5d84ac25426f1bfc217bca0c6712a9965164b07db219ee7e583b94c4d26f00aee87344c3f17a" + } + ], + "like_post02_response": [ + "OK", + "920ee4e856acb3310e64415183da0dd7e2e2b7e7c5a517553b9a75981fbafcc9", + true, + "" + ], + "comment_on_alice_post01": [ + "EVENT", + { + "id": "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675332468, + "kind": 1, + "tags": [ + [ + "e", + "05741bda9079cdf66f3be977a4d31287366470d1337b1aeb09506da4fbf7cd85" + ], + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ] + ], + "content": "bob comment 01", + "sig": "f9bb53e2adc27f3a49ec42d681833742e28d734327107ebba3076be226340503048116947a75274e5262fa03aa0430da6fe697e46e19342639ef208e5690d8c5" + } + ], + "comment_on_alice_post01_response": [ + "OK", + "bb34749ffd3eb0e393e54cc90b61a7dd5f34108d4931467861d20281c0b7daea", + true, + "" + ], + "direct_message01": [ + "EVENT", + { + "id": "15f6e6bd6cb538167d4430ea6bd7c0cfb99b400ca3e8879a114e90f74b3f20b2", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675412687, + "kind": 4, + "tags": [ + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ] + ], + "content": "jjBSyp36t555ywERY2fI4A==?iv=+8bg2vsltrXewAywxw9m6w==", + "sig": "091f4e8e5c497099bfe6af58126e022bc8babe648b8157c39f51e5d3906bfddf01f2f6d1a3ed36f94fbf07b009008fd448fbb8ce35b60260517aa0124a6c5c39" + } + ], + "direct_message01_response": [ + "OK", + "15f6e6bd6cb538167d4430ea6bd7c0cfb99b400ca3e8879a114e90f74b3f20b2", + true, + "" + ], + "subscribe_to_direct_messages": [ + "REQ", + "notifications:d685447c43c7c18dbbea61923cf0b63e1ab46bed", + { + "kinds": [4], + "#p": [ + "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a" + ], + "limit": 400 + } + ], + "subscribe_to_delete_from_alice": [ + "REQ", + "notifications:delete", + { + "kinds": [5], + "authors": [ + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ], + "limit": 400 + } + ], + "contact_list_create": [ + "EVENT", + { + "id": "141ddb3008ed1cc35fa09ff88d3b82da0351c6166c566e6220293136aa902a62", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675350109, + "kind": 3, + "tags": [ + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ] + ], + "content": "", + "sig": "740972ce0335fe6be7194c995e407e440b4194e49ee2775a19dc36eb5e9d8302ea8d0ab93cdc11eb345a9f8bae32c14bcbd4b7f3fe9b97d197b8426dba139847" + } + ], + "contact_list_create_response": [ + "OK", + "141ddb3008ed1cc35fa09ff88d3b82da0351c6166c566e6220293136aa902a62", + true, + "" + ], + "contact_list_update": [ + "EVENT", + { + "id": "1439f08983433295bc54d24b8c3cda2fa137d86636535a408d2d9a7bac5f0c40", + "pubkey": "d685447c43c7c18dbbea61923cf0b63e1ab46bed69b153a48279a95c40bd414a", + "created_at": 1675444161, + "kind": 3, + "tags": [ + [ + "p", + "0b29ecc73ba400e5b4bd1e4cb0d8f524e9958345749197ca21c8da38d0622816" + ], + [ + "p", + "8d21cd7c3f204cbb8aaf7708445b49e6cef7da23a550f9a27d21b1122c0cb4e9" + ] + ], + "content": "", + "sig": "648230464f6b79063da76c1c9d06cd290c65f95fca4bac2e055f84f003847a4b9a2e144b4d77ec9f2f5289d477353a21494548d1b1fbf8795602c8914a062d50" + } + ], + "contact_list_update_response": [ + "OK", + "1439f08983433295bc54d24b8c3cda2fa137d86636535a408d2d9a7bac5f0c40", + true, + "" + ] + } +} diff --git a/tests/fixture/events.json b/tests/fixture/events.json index 29720f1..a9a2903 100644 --- a/tests/fixture/events.json +++ b/tests/fixture/events.json @@ -1,220 +1,215 @@ { - "valid": [ - { - "name": "kind 0, metadata", - "data": { - "id": "380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acf3440269e3bd2486f6", - "pubkey": "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491", - "created_at": 1675242172, - "kind": 0, - "tags": [], - "content": "{\"name\":\"chrome-snort\",\"display_name\":\"the ugly\",\"about\":\"meeeee\",\"website\":\"lnbits.com\",\"lud16\":\"nostr@lnbits.com\"}", - "sig": "2e3da396e6eb32962b31d490cefe422c02c5fa8a48a60f3ece27e1dcea374978b4a78b110e78dcff3859a6036287aceba1801df8877fc15266996d41235b7c4f" - } - }, - { - "name": "kind 1, no tags", - "data": { - "kind": 1, - "content": "i126", - "tags": [], - "created_at": 1675239988, - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "id": "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", - "sig": "b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634db9830ba53ad8caeb1e2afc9b7d1" - } - }, - { - "name": "kind 1, reply, e & p tags", - "data": { - "kind": 1, - "content": "i126 reply", - "tags": [ - [ - "e", - "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", - "", - "root" - ], - [ - "p", - "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" - ] - ], - "created_at": 1675240147, - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "id": "6b2b6cb9c72caaf3dfbc5baa5e68d75ac62f38ec011b36cc83832218c36e4894", - "sig": "ee855296f691880bac51148996b4200c21da7c8a54c65ab29a83a30bbace3bb5de49f6bdbe8102473211078d006b63bcc67a6e905bf22b3f2195b9e2feaa0957" - } - }, - { - "name": "kind 3, contact list", - "data": { - "id": "d1e5db203ef5fb1699f106f132bae1a3b5c9c8acf4fbb6c4a50844a6827164f1", - "pubkey": "69795541a6635015b7e18b7f3f0f663fdec952bbd92642ee879610fae2e25718", - "created_at": 1675095502, - "kind": 3, - "tags": [ - [ - "p", - "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" - ] - ], - "content": "", - "sig": "591cf6fd40c6fa6ed0b4ef47e22e52577f786a87aafcd293582076cb3ff75a9598f973fe93de833bb5a793bb3c756a853eab884323257207b2df7d217fabf9e9" - } - }, - { - "name": "kind 3, relays", - "data": { - "id": "ee5fd14c3f8198bafbc70250c1c9d773069479ea456e8a11cfd889eb0eb63a9e", - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "created_at": 1675175242, - "kind": 3, - "tags": [ - [ - "p", - "4b1b856e263836ef4e2ffc439f49b5f0f7b7c4bfc6fba79019ea5f0f648c55d5" - ], - [ - "p", - "ba6dbec940142c806e5eebe02863968d2037ef50af33fd43b82309165eed1e2a" - ], - [ - "p", - "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491" - ], - [ - "p", - "69795541a6635015b7e18b7f3f0f663fdec952bbd92642ee879610fae2e25718" - ] - ], - "content": "{\"wss://lnbits.link/nostrrelay/client\":{\"read\":true,\"write\":true}}", - "sig": "279940c52322467abcfcc10a9123f6e25542a40bc7751fef4b4941de1d5382f2bee7e0fc48a744efc4c227609d619009a0ab4557b36b35ec6df8f71e2e384b3a" - } - }, - { - "name": "kind 4, direct message", - "data": { - "kind": 4, - "content": "gw8BFFM6anxgv77elHM5RQ==?iv=w1Qq4gPS3EZ4Csn1NfEgXg==", - "tags": [ - [ - "p", - "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" - ] - ], - "created_at": 1675240247, - "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", - "id": "e742abcd1befd0ef51fc047d5bcd3df360bf0d87f29702a333b06cb405ca40e5", - "sig": "eb7269eec350a3a1456261fe4e53a6a58b028497bdfc469c1579940ddcfe29688b420f33b7a9d69d41a9a689e00e661749cde5a44de16a341a8b2be3df6d770d" - } - }, - { - "name": "kind 5, delete message", - "data": { - "kind": 5, - "content": "deleted", - "tags": [ - [ - "e", - "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96" - ] - ], - "created_at": 1675241034, - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "id": "31e27bb0133d48b4e27cc23ca533f305fd613b1485d0fc27b3d65354ae7bd4d1", - "sig": "e6f48d78f516212f3272c73eb2a6229b7f4d8254f453d8fe3f225ecf5e1367ed6d15859c678c7d00dee0d6b545fb4967c383b559fe20e59891e229428ed2c312" - } - }, - { - "name": "kind 6, mention (?)", - "data": { - "kind": 6, - "tags": [ - [ - "e", - "201eaebc2a3176eefa488558749a7978b5189794550c58aff885c2d362917bda", - "", - "mention" - ], - [ - "p", - "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" - ] - ], - "content": "#[0]", - "created_at": 1675240471, - "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", - "id": "64e69392dc44972433f80bdb4889d3a5a53b6ba7a18a0f5b9518e0bebfeb202e", - "sig": "6ae812a285be3a0bee8c4ae894bc3a92bbc4a78e03c3b1265e9e4f67668fd2c4fe59af69ab2248e49739e733e270b258384abe45f3b7e2a2fba9caebf405f74e" - } - }, - { - "name": "kind 7, reaction", - "data": { - "kind": 7, - "content": "+", - "tags": [ - [ - "e", - "8dacb8a9326d1b8e055386ba7f1ddf9df1cc0dd90ffe3d15802955227c311c14" - ], - [ - "p", - "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" - ] - ], - "created_at": 1675240377, - "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", - "id": "9ad503684485edc2d2c52d024e00d920f50c29e07c7b0e39d221c96f9eecc6da", - "sig": "2619c94b8ae65ac153f287de810a5447bcdd9bf177b149cc1f428a7aa750a3751881bb0ef6359017ab70a45b5062d0be7205fa2c71b6c990e886486a17875947" - } - }, - { - "name": "kind 30,000, replaceable events, 'd' tag", - "data": { - "kind": 30000, - "tags": [ - [ - "d", - "chats/null/lastOpened" - ] - ], - "content": "1675242945", - "created_at": 1675242945, - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "id": "21248bddbab900b8c2f0713c925519f4f50d71eb081149f71221e69db3a5e2d1", - "sig": "f9be83b62cbbfd6070d434758d3fe7e709947abfff701b240fca5f20fc538f35018be97fd5b236c72f7021845f3a3c805ba878269b5ddf44fe03ec161f60e5d8" - } - } - ], - "invalid": [ - { - "name": "invalid event id", - "exception": "Invalid event id. Expected: '380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acf3440269e3bd2486f6' got '380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acaaaaaaaaaaaaaaaaaa'", - "data": { - "id": "380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acaaaaaaaaaaaaaaaaaa", - "pubkey": "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491", - "created_at": 1675242172, - "kind": 0, - "tags": [], - "content": "{\"name\":\"chrome-snort\",\"display_name\":\"the ugly\",\"about\":\"meeeee\",\"website\":\"lnbits.com\",\"lud16\":\"nostr@lnbits.com\"}", - "sig": "2e3da396e6eb32962b31d490cefe422c02c5fa8a48a60f3ece27e1dcea374978b4a78b110e78dcff3859a6036287aceba1801df8877fc15266996d41235b7c4f" - } - }, - { - "name": "invalid signature", - "exception": "Invalid signature: 'b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634dbaaaaaaaaaaaaaaaaaaaaaaaaaa' for event '3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96'", - "data": { - "kind": 1, - "content": "i126", - "tags": [], - "created_at": 1675239988, - "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", - "id": "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", - "sig": "b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634dbaaaaaaaaaaaaaaaaaaaaaaaaaa" - } - } - ] -} \ No newline at end of file + "valid": [ + { + "name": "kind 0, metadata", + "data": { + "id": "380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acf3440269e3bd2486f6", + "pubkey": "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491", + "created_at": 1675242172, + "kind": 0, + "tags": [], + "content": "{\"name\":\"chrome-snort\",\"display_name\":\"the ugly\",\"about\":\"meeeee\",\"website\":\"lnbits.com\",\"lud16\":\"nostr@lnbits.com\"}", + "sig": "2e3da396e6eb32962b31d490cefe422c02c5fa8a48a60f3ece27e1dcea374978b4a78b110e78dcff3859a6036287aceba1801df8877fc15266996d41235b7c4f" + } + }, + { + "name": "kind 1, no tags", + "data": { + "kind": 1, + "content": "i126", + "tags": [], + "created_at": 1675239988, + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "id": "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", + "sig": "b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634db9830ba53ad8caeb1e2afc9b7d1" + } + }, + { + "name": "kind 1, reply, e & p tags", + "data": { + "kind": 1, + "content": "i126 reply", + "tags": [ + [ + "e", + "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", + "", + "root" + ], + [ + "p", + "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" + ] + ], + "created_at": 1675240147, + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "id": "6b2b6cb9c72caaf3dfbc5baa5e68d75ac62f38ec011b36cc83832218c36e4894", + "sig": "ee855296f691880bac51148996b4200c21da7c8a54c65ab29a83a30bbace3bb5de49f6bdbe8102473211078d006b63bcc67a6e905bf22b3f2195b9e2feaa0957" + } + }, + { + "name": "kind 3, contact list", + "data": { + "id": "d1e5db203ef5fb1699f106f132bae1a3b5c9c8acf4fbb6c4a50844a6827164f1", + "pubkey": "69795541a6635015b7e18b7f3f0f663fdec952bbd92642ee879610fae2e25718", + "created_at": 1675095502, + "kind": 3, + "tags": [ + [ + "p", + "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" + ] + ], + "content": "", + "sig": "591cf6fd40c6fa6ed0b4ef47e22e52577f786a87aafcd293582076cb3ff75a9598f973fe93de833bb5a793bb3c756a853eab884323257207b2df7d217fabf9e9" + } + }, + { + "name": "kind 3, relays", + "data": { + "id": "ee5fd14c3f8198bafbc70250c1c9d773069479ea456e8a11cfd889eb0eb63a9e", + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "created_at": 1675175242, + "kind": 3, + "tags": [ + [ + "p", + "4b1b856e263836ef4e2ffc439f49b5f0f7b7c4bfc6fba79019ea5f0f648c55d5" + ], + [ + "p", + "ba6dbec940142c806e5eebe02863968d2037ef50af33fd43b82309165eed1e2a" + ], + [ + "p", + "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491" + ], + [ + "p", + "69795541a6635015b7e18b7f3f0f663fdec952bbd92642ee879610fae2e25718" + ] + ], + "content": "{\"wss://lnbits.link/nostrrelay/client\":{\"read\":true,\"write\":true}}", + "sig": "279940c52322467abcfcc10a9123f6e25542a40bc7751fef4b4941de1d5382f2bee7e0fc48a744efc4c227609d619009a0ab4557b36b35ec6df8f71e2e384b3a" + } + }, + { + "name": "kind 4, direct message", + "data": { + "kind": 4, + "content": "gw8BFFM6anxgv77elHM5RQ==?iv=w1Qq4gPS3EZ4Csn1NfEgXg==", + "tags": [ + [ + "p", + "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" + ] + ], + "created_at": 1675240247, + "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", + "id": "e742abcd1befd0ef51fc047d5bcd3df360bf0d87f29702a333b06cb405ca40e5", + "sig": "eb7269eec350a3a1456261fe4e53a6a58b028497bdfc469c1579940ddcfe29688b420f33b7a9d69d41a9a689e00e661749cde5a44de16a341a8b2be3df6d770d" + } + }, + { + "name": "kind 5, delete message", + "data": { + "kind": 5, + "content": "deleted", + "tags": [ + [ + "e", + "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96" + ] + ], + "created_at": 1675241034, + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "id": "31e27bb0133d48b4e27cc23ca533f305fd613b1485d0fc27b3d65354ae7bd4d1", + "sig": "e6f48d78f516212f3272c73eb2a6229b7f4d8254f453d8fe3f225ecf5e1367ed6d15859c678c7d00dee0d6b545fb4967c383b559fe20e59891e229428ed2c312" + } + }, + { + "name": "kind 6, mention (?)", + "data": { + "kind": 6, + "tags": [ + [ + "e", + "201eaebc2a3176eefa488558749a7978b5189794550c58aff885c2d362917bda", + "", + "mention" + ], + [ + "p", + "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" + ] + ], + "content": "#[0]", + "created_at": 1675240471, + "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", + "id": "64e69392dc44972433f80bdb4889d3a5a53b6ba7a18a0f5b9518e0bebfeb202e", + "sig": "6ae812a285be3a0bee8c4ae894bc3a92bbc4a78e03c3b1265e9e4f67668fd2c4fe59af69ab2248e49739e733e270b258384abe45f3b7e2a2fba9caebf405f74e" + } + }, + { + "name": "kind 7, reaction", + "data": { + "kind": 7, + "content": "+", + "tags": [ + [ + "e", + "8dacb8a9326d1b8e055386ba7f1ddf9df1cc0dd90ffe3d15802955227c311c14" + ], + [ + "p", + "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211" + ] + ], + "created_at": 1675240377, + "pubkey": "99a566c374211fd7f3db531f296b574a726329f509fbf3285cf3feac4e9b488e", + "id": "9ad503684485edc2d2c52d024e00d920f50c29e07c7b0e39d221c96f9eecc6da", + "sig": "2619c94b8ae65ac153f287de810a5447bcdd9bf177b149cc1f428a7aa750a3751881bb0ef6359017ab70a45b5062d0be7205fa2c71b6c990e886486a17875947" + } + }, + { + "name": "kind 30,000, replaceable events, 'd' tag", + "data": { + "kind": 30000, + "tags": [["d", "chats/null/lastOpened"]], + "content": "1675242945", + "created_at": 1675242945, + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "id": "21248bddbab900b8c2f0713c925519f4f50d71eb081149f71221e69db3a5e2d1", + "sig": "f9be83b62cbbfd6070d434758d3fe7e709947abfff701b240fca5f20fc538f35018be97fd5b236c72f7021845f3a3c805ba878269b5ddf44fe03ec161f60e5d8" + } + } + ], + "invalid": [ + { + "name": "invalid event id", + "exception": "Invalid event id. Expected: '380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acf3440269e3bd2486f6' got '380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acaaaaaaaaaaaaaaaaaa'", + "data": { + "id": "380299ac06ef1bff58e7e5a04a2c5efcd0e15b113e71acaaaaaaaaaaaaaaaaaa", + "pubkey": "ae9d97d1627f6d02376cd0ce0ceed716d573deca355649d8e03a9323aaaa2491", + "created_at": 1675242172, + "kind": 0, + "tags": [], + "content": "{\"name\":\"chrome-snort\",\"display_name\":\"the ugly\",\"about\":\"meeeee\",\"website\":\"lnbits.com\",\"lud16\":\"nostr@lnbits.com\"}", + "sig": "2e3da396e6eb32962b31d490cefe422c02c5fa8a48a60f3ece27e1dcea374978b4a78b110e78dcff3859a6036287aceba1801df8877fc15266996d41235b7c4f" + } + }, + { + "name": "invalid signature", + "exception": "Invalid signature: 'b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634dbaaaaaaaaaaaaaaaaaaaaaaaaaa' for event '3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96'", + "data": { + "kind": 1, + "content": "i126", + "tags": [], + "created_at": 1675239988, + "pubkey": "a24496bca5dd73300f4e5d5d346c73132b7354c597fcbb6509891747b4689211", + "id": "3219eec7427e365585d5adf26f5d2dd2709d3f0f2c0e1f79dc9021e951c67d96", + "sig": "b1791d17052cef2a65f487ecd976952a721680da9cda4e0f11f4ea04425b1e0a273b27233a4fc50b9d98ebdf1d0722e52634dbaaaaaaaaaaaaaaaaaaaaaaaaaa" + } + } + ] +} From abe8c65c4c3b6cf2051efa081c2877f4de061c43 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 15:48:02 +0200 Subject: [PATCH 05/54] refactor: rename fields --- __init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__init__.py b/__init__.py index 64d30c7..e3fa391 100644 --- a/__init__.py +++ b/__init__.py @@ -20,13 +20,13 @@ nostrrelay_static_files = [ } ] -redirect_paths = [ +nostrrelay_redirect_paths = [ { - "from_path": "/", + "from_path": "/nostr", "redirect_to_path": "/api/v1/relay-info", - "header_filters": [{ + "header_filters": { "accept": "application/nostr+json" - }] + } } ] From 8c860f851a5ae4d88ace5c425987c6243c2a0bcf Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 16:09:37 +0200 Subject: [PATCH 06/54] feat: update supported NIPs --- relay/relay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/relay.py b/relay/relay.py index 71f2f24..6109769 100644 --- a/relay/relay.py +++ b/relay/relay.py @@ -122,7 +122,7 @@ class NostrRelay(BaseModel): ) -> dict: return { "contact": "https://t.me/lnbits", - "supported_nips": [1, 9, 11, 15, 20, 22, 42], + "supported_nips": [1, 2, 4, 9, 11, 15, 16, 20, 22, 28, 42], "software": "LNbits", "version": "", } From f4d47062378e95c317ce3a3b46e33d4f4ea032f3 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 16:11:09 +0200 Subject: [PATCH 07/54] chore: remove test path --- __init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index e3fa391..97dc8bd 100644 --- a/__init__.py +++ b/__init__.py @@ -22,7 +22,7 @@ nostrrelay_static_files = [ nostrrelay_redirect_paths = [ { - "from_path": "/nostr", + "from_path": "/", "redirect_to_path": "/api/v1/relay-info", "header_filters": { "accept": "application/nostr+json" From dd9dbbe818570c1e5087463105e467d524f2ae19 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 21 Feb 2023 16:14:18 +0200 Subject: [PATCH 08/54] fix: return generic Relay Info --- views_api.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/views_api.py b/views_api.py index 4f9a3fa..1620a3d 100644 --- a/views_api.py +++ b/views_api.py @@ -126,16 +126,8 @@ async def api_get_relays( detail="Cannot fetch relays", ) @nostrrelay_ext.get("/api/v1/relay-info") -async def api_get_relay_info( request: Request, -) -> JSONResponse: - - if request.headers.get("accept") == "application/nostr+json": - return relay_info_response({}) - - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, - detail="Cannot fetch relays info", - ) +async def api_get_relay_info() -> JSONResponse: + return relay_info_response(NostrRelay.info()) From 8df0dc2f52c5e2a5c1bb1a531b0de045ecc15756 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 22 Feb 2023 11:38:33 +0200 Subject: [PATCH 09/54] chore: code clean-up --- static/components/relay-details/relay-details.js | 3 --- static/js/index.js | 5 ----- templates/nostrrelay/public.html | 2 -- 3 files changed, 10 deletions(-) diff --git a/static/components/relay-details/relay-details.js b/static/components/relay-details/relay-details.js index 3c8111f..0ab78b1 100644 --- a/static/components/relay-details/relay-details.js +++ b/static/components/relay-details/relay-details.js @@ -132,7 +132,6 @@ async function relayDetails(path) { ) this.relay = data - console.log('### this.relay', this.relay) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -168,8 +167,6 @@ async function relayDetails(path) { this.inkey ) this.accounts = data - - console.log('### this.accounts', this.accounts) } catch (error) { LNbits.utils.notifyApiError(error) } diff --git a/static/js/index.js b/static/js/index.js index 950edd1..0845fc1 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -100,9 +100,7 @@ const relays = async () => { this.relayLinks.find(old => old.id === c.id) ) ) - console.log('### relayLinks', this.relayLinks) } catch (error) { - console.log('### getRelays', error) LNbits.utils.notifyApiError(error) } }, @@ -123,7 +121,6 @@ const relays = async () => { } }, showToggleRelayDialog: function (relay) { - console.log('### showToggleRelayDialog', relay) if (relay.active) { this.toggleRelay(relay) return @@ -134,12 +131,10 @@ const relays = async () => { this.toggleRelay(relay) }) .onCancel(async () => { - console.log('#### onCancel') relay.active = !relay.active }) }, toggleRelay: async function (relay) { - console.log('### toggleRelay', relay) try { await LNbits.api.request( 'PUT', diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index 29207a5..7c19329 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -237,7 +237,6 @@ '', reqData ) - console.log('### data.invoice', data.invoice) this.invoice = data.invoice } catch (error) { LNbits.utils.notifyApiError(error) @@ -245,7 +244,6 @@ } }, created: function () { - console.log('### created', this.relay) } }) From 16b9d93dca399e062c582b0425784f09221c673a Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 22 Feb 2023 11:38:52 +0200 Subject: [PATCH 10/54] fix: use `Spec` for `PaymentSpec` --- relay/relay.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/relay/relay.py b/relay/relay.py index 6109769..82320f9 100644 --- a/relay/relay.py +++ b/relay/relay.py @@ -60,7 +60,7 @@ class StorageSpec(Spec): return value -class AuthSpec(BaseModel): +class AuthSpec(Spec): require_auth_events = Field(False, alias="requireAuthEvents") skiped_auth_events = Field([], alias="skipedAuthEvents") forced_auth_events = Field([], alias="forcedAuthEvents") @@ -72,7 +72,7 @@ class AuthSpec(BaseModel): return kind in self.forced_auth_events -class PaymentSpec(BaseModel): +class PaymentSpec(Spec): is_paid_relay = Field(False, alias="isPaidRelay") cost_to_join = Field(0, alias="costToJoin") From 5e313c02822aed35f74ff87e2249af39e00cbc46 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 15 Mar 2023 21:17:51 +0200 Subject: [PATCH 11/54] chore: code format --- static/components/relay-details/relay-details.js | 1 - templates/nostrrelay/public.html | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/static/components/relay-details/relay-details.js b/static/components/relay-details/relay-details.js index 0ab78b1..21a3775 100644 --- a/static/components/relay-details/relay-details.js +++ b/static/components/relay-details/relay-details.js @@ -131,7 +131,6 @@ async function relayDetails(path) { this.inkey ) this.relay = data - } catch (error) { LNbits.utils.notifyApiError(error) } diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index 7c19329..d300cb7 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -243,8 +243,7 @@ } } }, - created: function () { - } + created: function () {} }) {% endblock %} From 63be2b5b2df51bff3096bfab47083724770901ee Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 24 Feb 2023 15:10:58 +0200 Subject: [PATCH 12/54] feat: show `wss` URL --- .../relay-details/relay-details.html | 20 +++++++++++++++++++ .../components/relay-details/relay-details.js | 9 ++++++++- static/js/index.js | 6 +----- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/static/components/relay-details/relay-details.html b/static/components/relay-details/relay-details.html index 2deeeb5..8ea8394 100644 --- a/static/components/relay-details/relay-details.html +++ b/static/components/relay-details/relay-details.html @@ -68,6 +68,26 @@
+
+
Web Socket Link:
+
+ +
+
+ Copy +
+
diff --git a/static/components/relay-details/relay-details.js b/static/components/relay-details/relay-details.js index 21a3775..37616b9 100644 --- a/static/components/relay-details/relay-details.js +++ b/static/components/relay-details/relay-details.js @@ -92,6 +92,13 @@ async function relayDetails(path) { {value: 'block', label: 'Block New Events'}, {value: 'prune', label: 'Prune Old Events'} ] + }, + wssLink: function () { + this.relay.config.domain = + this.relay.config.domain || window.location.hostname + return ( + 'wss://' + this.relay.config.domain + '/nostrrelay/' + this.relay.id + ) } }, @@ -138,7 +145,7 @@ async function relayDetails(path) { updateRelay: async function () { try { const {data} = await LNbits.api.request( - 'PUT', + 'PATCH', '/nostrrelay/api/v1/relay/' + this.relayId, this.adminkey, this.relay diff --git a/static/js/index.js b/static/js/index.js index 0845fc1..1b6d317 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -140,11 +140,7 @@ const relays = async () => { 'PUT', '/nostrrelay/api/v1/relay/' + relay.id, this.g.user.wallets[0].adminkey, - { - active: relay.active, - id: relay.id, - name: relay.name - } + {} ) } catch (error) { LNbits.utils.notifyApiError(error) From 67dda89c81540eeaf2b8d43fd8b9ad928ac24820 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 24 Feb 2023 15:11:16 +0200 Subject: [PATCH 13/54] fix: separate relay update from activete/deactivate --- views_api.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/views_api.py b/views_api.py index 1620a3d..61f361f 100644 --- a/views_api.py +++ b/views_api.py @@ -76,7 +76,7 @@ async def api_create_relay( ) -@nostrrelay_ext.put("/api/v1/relay/{relay_id}") +@nostrrelay_ext.patch("/api/v1/relay/{relay_id}") async def api_update_relay( relay_id: str, data: NostrRelay, wallet: WalletTypeInfo = Depends(require_admin_key) ) -> NostrRelay: @@ -95,6 +95,8 @@ async def api_update_relay( ) updated_relay = NostrRelay.parse_obj({**dict(relay), **dict(data)}) updated_relay = await update_relay(wallet.wallet.user, updated_relay) + # activate & deactivate have their own endpoint + updated_relay.active = relay.active if updated_relay.active: await client_manager.enable_relay(relay_id, updated_relay.config) @@ -113,6 +115,38 @@ async def api_update_relay( ) +@nostrrelay_ext.put("/api/v1/relay/{relay_id}") +async def api_toggle_relay( + relay_id: str, wallet: WalletTypeInfo = Depends(require_admin_key) +) -> NostrRelay: + + try: + relay = await get_relay(wallet.wallet.user,relay_id) + if not relay: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, + detail="Relay not found", + ) + relay.active = not relay.active + updated_relay = await update_relay(wallet.wallet.user, relay) + + if relay.active: + await client_manager.enable_relay(relay_id, relay.config) + else: + await client_manager.disable_relay(relay_id) + + return updated_relay + + except HTTPException as ex: + raise ex + except Exception as ex: + logger.warning(ex) + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="Cannot update relay", + ) + + @nostrrelay_ext.get("/api/v1/relay") async def api_get_relays( wallet: WalletTypeInfo = Depends(require_invoice_key), From 6e1b5dd0bb8ade926db266208cbdbd56ec471164 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 24 Feb 2023 15:15:06 +0200 Subject: [PATCH 14/54] fix: copy button --- static/components/relay-details/relay-details.html | 2 +- static/components/relay-details/relay-details.js | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/static/components/relay-details/relay-details.html b/static/components/relay-details/relay-details.html index 8ea8394..a28c110 100644 --- a/static/components/relay-details/relay-details.html +++ b/static/components/relay-details/relay-details.html @@ -83,7 +83,7 @@ Copy diff --git a/static/components/relay-details/relay-details.js b/static/components/relay-details/relay-details.js index 37616b9..41d1a94 100644 --- a/static/components/relay-details/relay-details.js +++ b/static/components/relay-details/relay-details.js @@ -245,7 +245,17 @@ async function relayDetails(path) { value = +eventKind this.relay.config.forcedAuthEvents = this.relay.config.forcedAuthEvents.filter(e => e !== value) - } + }, + // todo: bad. base.js not present in custom components + copyText: function (text, message, position) { + var notify = this.$q.notify + Quasar.utils.copyToClipboard(text).then(function () { + notify({ + message: message || 'Copied to clipboard!', + position: position || 'bottom' + }) + }) + }, }, created: async function () { From 218b3243471b446c39f4786e19e61d16398699dd Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 24 Feb 2023 16:36:53 +0200 Subject: [PATCH 15/54] chore: code format --- static/components/relay-details/relay-details.html | 7 +------ static/components/relay-details/relay-details.js | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/static/components/relay-details/relay-details.html b/static/components/relay-details/relay-details.html index a28c110..a4e58cc 100644 --- a/static/components/relay-details/relay-details.html +++ b/static/components/relay-details/relay-details.html @@ -80,12 +80,7 @@ >
- Copy + Copy
diff --git a/static/components/relay-details/relay-details.js b/static/components/relay-details/relay-details.js index 41d1a94..ad14b3f 100644 --- a/static/components/relay-details/relay-details.js +++ b/static/components/relay-details/relay-details.js @@ -255,7 +255,7 @@ async function relayDetails(path) { position: position || 'bottom' }) }) - }, + } }, created: async function () { From 30ffcf7f554a2cf8eae7a36f5f569ec34bb49d1d Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 24 Feb 2023 16:37:21 +0200 Subject: [PATCH 16/54] fix: show `wss` & invoice generation --- templates/nostrrelay/public.html | 203 +++++++++++++++---------------- views_api.py | 15 ++- 2 files changed, 110 insertions(+), 108 deletions(-) diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index d300cb7..7334568 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -11,43 +11,90 @@

+
+ + +
- Public Key: - +
+
+ Relay Link: +
+
+ +
+
+ Copy +
+
-
+
+
+ Public Key: +
+
+ +
+
+
+ + +
Cost to join:
- - sats +
+ + sats +
- Pay to Join +
+ Pay to Join +
+
+ Free to join + +
- +
+
-
+
Storage cost:
-
+
sats per @@ -56,6 +103,7 @@
-
- - sats +
+
+ + sats +
- Buy storage space +
+ Buy storage space +
+
+ Free storage + +
- This is a free relay +
+ This is a free Nostr Relay +
@@ -118,77 +177,6 @@
-
- - - - - - - - - - GET - /lnurlp/api/v1/links -
Headers
- {"X-Api-Key": <invoice_key>}
-
- Body (application/json) -
-
- Returns 200 OK (application/json) -
- [<pay_link_object>, ...] -
Curl example
-
-
-
- - - - - - - - - - - - - - - -
-
-
-
@@ -211,11 +199,20 @@ storageCost: function () { if (!this.relay || !this.relay.config.storageCostValue) return 0 return this.unitsToBuy * this.relay.config.storageCostValue + }, + wssLink: function () { + this.relay.config.domain = + this.relay.config.domain || window.location.hostname + return ( + 'wss://' + this.relay.config.domain + '/nostrrelay/' + this.relay.id + ) } }, methods: { createInvoice: async function (action) { + console.log('### action', action) if (!action) return + this.invoice = '' if (!this.pubkey) { this.$q.notify({ timeout: 5000, diff --git a/views_api.py b/views_api.py index 61f361f..347b197 100644 --- a/views_api.py +++ b/views_api.py @@ -283,11 +283,13 @@ async def api_pay_to_join(data: BuyOrder): detail="Relay not found", ) - if data.action == "join" and relay.is_free_to_join: - raise ValueError("Relay is free to join") - + amount = 0 storage_to_buy = 0 - if data.action == "storage": + if data.action == "join": + if relay.is_free_to_join: + raise ValueError("Relay is free to join") + amount = int(relay.config.cost_to_join) + elif data.action == "storage": if relay.config.storage_cost_value == 0: raise ValueError("Relay storage cost is zero. Cannot buy!") if data.units_to_buy == 0: @@ -295,10 +297,13 @@ async def api_pay_to_join(data: BuyOrder): storage_to_buy = data.units_to_buy * relay.config.storage_cost_value * 1024 if relay.config.storage_cost_unit == "MB": storage_to_buy *= 1024 + amount = data.units_to_buy * relay.config.storage_cost_value + else: + raise ValueError(f"Unknown action: '{data.action}'") _, payment_request = await create_invoice( wallet_id=relay.config.wallet, - amount=int(relay.config.cost_to_join), + amount=amount, memo=f"Pubkey '{data.pubkey}' wants to join {relay.id}", extra={ "tag": "nostrrely", From 3aa4875558edb1987ea9f8c9c61f395575327a16 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 17 Mar 2023 15:06:09 +0200 Subject: [PATCH 17/54] chore: code format --- __init__.py | 11 +++++------ helpers.py | 2 +- views_api.py | 7 ++++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/__init__.py b/__init__.py index 97dc8bd..12154d0 100644 --- a/__init__.py +++ b/__init__.py @@ -21,17 +21,16 @@ nostrrelay_static_files = [ ] nostrrelay_redirect_paths = [ - { - "from_path": "/", - "redirect_to_path": "/api/v1/relay-info", - "header_filters": { - "accept": "application/nostr+json" + { + "from_path": "/", + "redirect_to_path": "/api/v1/relay-info", + "header_filters": {"accept": "application/nostr+json"}, } - } ] scheduled_tasks: List[asyncio.Task] = [] + def nostrrelay_renderer(): return template_renderer(["lnbits/extensions/nostrrelay/templates"]) diff --git a/helpers.py b/helpers.py index 169c65c..5466e70 100644 --- a/helpers.py +++ b/helpers.py @@ -34,4 +34,4 @@ def relay_info_response(relay_public_data: dict) -> JSONResponse: "Access-Control-Allow-Headers": "*", "Access-Control-Allow-Methods": "GET", }, - ) \ No newline at end of file + ) diff --git a/views_api.py b/views_api.py index 347b197..9c6557f 100644 --- a/views_api.py +++ b/views_api.py @@ -121,7 +121,7 @@ async def api_toggle_relay( ) -> NostrRelay: try: - relay = await get_relay(wallet.wallet.user,relay_id) + relay = await get_relay(wallet.wallet.user, relay_id) if not relay: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -159,12 +159,13 @@ async def api_get_relays( status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail="Cannot fetch relays", ) + + @nostrrelay_ext.get("/api/v1/relay-info") async def api_get_relay_info() -> JSONResponse: return relay_info_response(NostrRelay.info()) - @nostrrelay_ext.get("/api/v1/relay/{relay_id}") async def api_get_relay( relay_id: str, wallet: WalletTypeInfo = Depends(require_invoice_key) @@ -288,7 +289,7 @@ async def api_pay_to_join(data: BuyOrder): if data.action == "join": if relay.is_free_to_join: raise ValueError("Relay is free to join") - amount = int(relay.config.cost_to_join) + amount = int(relay.config.cost_to_join) elif data.action == "storage": if relay.config.storage_cost_value == 0: raise ValueError("Relay storage cost is zero. Cannot buy!") From 527afa0c8cfa73fea3c8d9073d83ba2a12b18b5f Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 17 Mar 2023 15:06:59 +0200 Subject: [PATCH 18/54] feat: wait for paid invoce --- tasks.py | 25 +++++++++++++----- templates/nostrrelay/public.html | 44 ++++++++++++++++++++++++++++++-- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/tasks.py b/tasks.py index 87b8eed..8b37e1f 100644 --- a/tasks.py +++ b/tasks.py @@ -1,8 +1,10 @@ import asyncio +import json from loguru import logger from lnbits.core.models import Payment +from lnbits.core.services import websocketUpdater from lnbits.helpers import get_current_extension_name from lnbits.tasks import register_invoice_listener @@ -25,27 +27,36 @@ async def on_invoice_paid(payment: Payment): relay_id = payment.extra.get("relay_id") pubkey = payment.extra.get("pubkey") + hash = payment.payment_hash if not relay_id or not pubkey: - logger.warning( - f"Invoice extra data missing for 'relay_id' and 'pubkey'. Payment hash: {payment.payment_hash}" - ) + message = f"Invoice extra data missing for 'relay_id' and 'pubkey'. Payment hash: {hash}" + logger.warning(message) + await websocketUpdater(hash, json.dumps({"success": False, "message": message})) return - if payment.extra.get("action") == "join": + action = payment.extra.get("action") + if action == "join": await invoice_paid_to_join(relay_id, pubkey, payment.amount) + await websocketUpdater(hash, json.dumps({"success": True})) return - if payment.extra.get("action") == "storage": + if action == "storage": storage_to_buy = payment.extra.get("storage_to_buy") if not storage_to_buy: - logger.warning( - f"Invoice extra data missing for 'storage_to_buy'. Payment hash: {payment.payment_hash}" + message = ( + f"Invoice extra data missing for 'storage_to_buy'. Payment hash: {hash}" ) + logger.warning(message) return await invoice_paid_for_storage(relay_id, pubkey, storage_to_buy, payment.amount) + await websocketUpdater(hash, json.dumps({"success": True})) return + await websocketUpdater( + hash, json.dumps({"success": False, "message": f"Bad action name: '{action}'"}) + ) + async def invoice_paid_to_join(relay_id: str, pubkey: str, amount: int): try: diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index 7334568..9d4a9a0 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -144,8 +144,9 @@ - +
+ +
+
+
+ + +
+
+
+
@@ -192,6 +207,7 @@ relay: JSON.parse('{{relay | tojson | safe}}'), pubkey: '', invoice: '', + invoiceResponse: null, unitsToBuy: 0 } }, @@ -210,7 +226,6 @@ }, methods: { createInvoice: async function (action) { - console.log('### action', action) if (!action) return this.invoice = '' if (!this.pubkey) { @@ -235,9 +250,34 @@ reqData ) this.invoice = data.invoice + const paymentHashTag = decode(data.invoice).data.tags.find( + t => t.description === 'payment_hash' + ) + if (paymentHashTag) { + await this.waitForPaidInvoice(paymentHashTag.value) + } } catch (error) { LNbits.utils.notifyApiError(error) } + }, + waitForPaidInvoice: function (paymentHash) { + try { + const scheme = location.protocol === 'http:' ? 'ws' : 'wss' + const wsUrl = `${scheme}://${document.domain}:${location.port}/api/v1/ws/${paymentHash}` + const wsConnection = new WebSocket(wsUrl) + wsConnection.onmessage = e => { + this.invoiceResponse = JSON.parse(e.data) + this.invoice = null + wsConnection.close() + } + } catch (error) { + this.$q.notify({ + timeout: 5000, + type: 'warning', + message: 'Failed to get invoice status', + caption: `${error}` + }) + } } }, created: function () {} From 28c0947afb78cc6a04a88588ff72a87806ef0b0d Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 17 Mar 2023 15:24:17 +0200 Subject: [PATCH 19/54] fix: invoice can have `undefined` tag --- templates/nostrrelay/public.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index 9d4a9a0..53eed80 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -251,7 +251,7 @@ ) this.invoice = data.invoice const paymentHashTag = decode(data.invoice).data.tags.find( - t => t.description === 'payment_hash' + t => t && t.description === 'payment_hash' ) if (paymentHashTag) { await this.waitForPaidInvoice(paymentHashTag.value) From f7fb926c5223b23d26efb4674dedddeee0fea71a Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 17 Mar 2023 17:24:33 +0200 Subject: [PATCH 20/54] fix: port value --- templates/nostrrelay/public.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/nostrrelay/public.html b/templates/nostrrelay/public.html index 53eed80..98487c5 100644 --- a/templates/nostrrelay/public.html +++ b/templates/nostrrelay/public.html @@ -263,7 +263,8 @@ waitForPaidInvoice: function (paymentHash) { try { const scheme = location.protocol === 'http:' ? 'ws' : 'wss' - const wsUrl = `${scheme}://${document.domain}:${location.port}/api/v1/ws/${paymentHash}` + const port = location.port ? `:${location.port}` : '' + const wsUrl = `${scheme}://${document.domain}${port}/api/v1/ws/${paymentHash}` const wsConnection = new WebSocket(wsUrl) wsConnection.onmessage = e => { this.invoiceResponse = JSON.parse(e.data) From f19fb4a18e42eed48bb7f1ff608fedb5a898ebf4 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Thu, 6 Apr 2023 16:59:15 +0300 Subject: [PATCH 21/54] fix: delete account --- crud.py | 10 ++++++ .../relay-details/relay-details.html | 18 +++++++--- .../components/relay-details/relay-details.js | 33 +++++++++++++++++++ views_api.py | 28 ++++++++++++++++ 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/crud.py b/crud.py index 1f965b1..926cedf 100644 --- a/crud.py +++ b/crud.py @@ -363,6 +363,16 @@ async def update_account(relay_id: str, a: NostrAccount) -> NostrAccount: return a +async def delete_account(relay_id: str, pubkey: str): + await db.execute( + """ + DELETE FROM nostrrelay.accounts + WHERE relay_id = ? AND pubkey = ? + """, + (relay_id, pubkey), + ) + + async def get_account( relay_id: str, pubkey: str, diff --git a/static/components/relay-details/relay-details.html b/static/components/relay-details/relay-details.html index a4e58cc..8896a0d 100644 --- a/static/components/relay-details/relay-details.html +++ b/static/components/relay-details/relay-details.html @@ -545,7 +545,7 @@ >
Public Key:
-
+
Allow
-
+
Block @@ -613,6 +613,16 @@ >