feat: add basic NIP20 response

This commit is contained in:
Vlad Stan 2023-01-31 12:36:59 +02:00
parent 30150c4561
commit fbae6d6c88
2 changed files with 28 additions and 15 deletions

View file

@ -1,5 +1,5 @@
import json import json
from typing import Callable, List from typing import Any, Callable, List, Union
from fastapi import WebSocket from fastapi import WebSocket
from loguru import logger from loguru import logger
@ -49,28 +49,37 @@ class NostrClientConnection:
async def notify_event(self, event: NostrEvent): async def notify_event(self, event: NostrEvent):
for filter in self.filters: for filter in self.filters:
if filter.matches(event): if filter.matches(event):
r = [NostrEventType.EVENT, filter.subscription_id, dict(event)] resp = event.serialize_response(filter.subscription_id)
await self.websocket.send_text(json.dumps(r)) await self.websocket.send_text(json.dumps(resp))
async def __handle_message(self, data: List): async def __handle_message(self, data: List) -> Union[None, List]:
if len(data) < 2: if len(data) < 2:
return return None
message_type = data[0] message_type = data[0]
if message_type == NostrEventType.EVENT: if message_type == NostrEventType.EVENT:
return await self.__handle_event(NostrEvent.parse_obj(data[1])) await self.__handle_event(NostrEvent.parse_obj(data[1]))
return None
if message_type == NostrEventType.REQ: if message_type == NostrEventType.REQ:
if len(data) != 3: if len(data) != 3:
return return None
return await self.__handle_request(data[1], NostrFilter.parse_obj(data[2])) return await self.__handle_request(data[1], NostrFilter.parse_obj(data[2]))
if message_type == NostrEventType.CLOSE: if message_type == NostrEventType.CLOSE:
return self.__handle_close(data[1]) self.__handle_close(data[1])
async def __handle_event(self, e: "NostrEvent") -> None: return None
# print('### __handle_event', e)
e.check_signature() async def __handle_event(self, e: "NostrEvent"):
await create_event("111", e) resp_nip20: List[Any] = ["ok", e.id]
await self.broadcast_event(self, e) try:
e.check_signature()
await create_event("111", e)
await self.broadcast_event(self, e)
resp_nip20 += [True, ""]
except Exception as ex:
resp_nip20 += [False, f"error: {ex}"]
await self.websocket.send_text(json.dumps(resp_nip20))
async def __handle_request(self, subscription_id: str, filter: NostrFilter) -> List: async def __handle_request(self, subscription_id: str, filter: NostrFilter) -> List:
filter.subscription_id = subscription_id filter.subscription_id = subscription_id
@ -78,10 +87,10 @@ class NostrClientConnection:
self.filters.append(filter) self.filters.append(filter)
events = await get_events("111", filter) events = await get_events("111", filter)
return [ return [
[NostrEventType.EVENT, subscription_id, dict(event)] for event in events event.serialize_response(subscription_id) for event in events
] ]
def __handle_close(self, subscription_id: str) -> None: def __handle_close(self, subscription_id: str):
self.remove_filter(subscription_id) self.remove_filter(subscription_id)
def remove_filter(self, subscription_id: str): def remove_filter(self, subscription_id: str):

View file

@ -62,6 +62,10 @@ class NostrEvent(BaseModel):
if not valid_signature: if not valid_signature:
raise ValueError(f"Invalid signature: '{self.sig}' for event '{self.id}'") raise ValueError(f"Invalid signature: '{self.sig}' for event '{self.id}'")
def serialize_response(self, subscription_id):
return [NostrEventType.EVENT, subscription_id, dict(self)]
@classmethod @classmethod
def from_row(cls, row: Row) -> "NostrEvent": def from_row(cls, row: Row) -> "NostrEvent":
return cls(**dict(row)) return cls(**dict(row))