Files
nutshell/cashu/mint/events/events.py
callebtc 6b38ef6c29 NUT-04 and NUT-05: Add state field to quotes (#560)
* wip adding states, tests failing

* add state field to quotes

* responses from quotes

* store correct state

* cleaner test

* fix swap check

* oops
2024-06-26 03:06:01 +02:00

62 lines
2.2 KiB
Python

import asyncio
from fastapi import WebSocket
from loguru import logger
from ...core.base import MeltQuote, MintQuote, ProofState
from ...core.db import Database
from ...core.models import PostMeltQuoteResponse, PostMintQuoteResponse
from ..crud import LedgerCrud
from .client import LedgerEventClientManager
from .event_model import LedgerEvent
class LedgerEventManager:
"""LedgerEventManager is a subscription service from the mint
for client websockets that subscribe to event updates.
Yields:
_type_: Union[MintQuote, MeltQuote]
"""
clients: list[LedgerEventClientManager] = []
MAX_CLIENTS = 1000
def add_client(
self, websocket: WebSocket, db: Database, crud: LedgerCrud
) -> LedgerEventClientManager:
client = LedgerEventClientManager(websocket, db, crud)
if len(self.clients) >= self.MAX_CLIENTS:
raise Exception("too many clients")
self.clients.append(client)
logger.debug(f"Added websocket subscription client {client}")
return client
def remove_client(self, client: LedgerEventClientManager) -> None:
self.clients.remove(client)
def serialize_event(self, event: LedgerEvent) -> dict:
if isinstance(event, MintQuote):
return_dict = PostMintQuoteResponse.from_mint_quote(event).dict()
elif isinstance(event, MeltQuote):
return_dict = PostMeltQuoteResponse.from_melt_quote(event).dict()
elif isinstance(event, ProofState):
return_dict = event.dict(exclude_unset=True, exclude_none=True)
return return_dict
async def submit(self, event: LedgerEvent) -> None:
if not isinstance(event, LedgerEvent):
raise ValueError(f"Unsupported event object type {type(event)}")
# check if any clients are subscribed to this event
for client in self.clients:
kind_sub = client.subscriptions.get(event.kind, {})
for sub in kind_sub.get(event.identifier, []):
logger.trace(
f"Submitting event to sub {sub}: {self.serialize_event(event)}"
)
asyncio.create_task(
client._send_obj(self.serialize_event(event), subId=sub)
)