Skip to content

Commit

Permalink
Stabilize (#24)
Browse files Browse the repository at this point in the history
* refactor: clean-up

* refactor: extra logs plus try-catch

* refactor: do not use bare `except`

* refactor: clean-up redundant fields

* chore: pass code checks

* chore: code format

* refactor: code clean-up

* fix: refactoring stuff

* refactor: remove un-used file

* chore: code clean-up

* chore: code clean-up

* chore: code-format fix

* refactor: remove nostr.client wrapper

* refactor: code clean-up

* chore: code format

* refactor: remove `RelayList` class

* refactor: extract smaller methods with try-catch

* fix: better exception handling

* fix: remove redundant filters

* fix: simplify event

* chore: code format

* fix: code check

* fix: code check

* fix: simplify `REQ`

* fix: more clean-ups

* refactor: use simpler method

* refactor: re-order and rename

* fix: stop logic

* fix: subscription close before disconnect

* chore: play commit
  • Loading branch information
motorina0 authored Nov 1, 2023
1 parent ab185bd commit 16ae9d1
Show file tree
Hide file tree
Showing 20 changed files with 525 additions and 720 deletions.
11 changes: 3 additions & 8 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart

from .nostr.client.client import NostrClient as NostrClientLib
from .nostr.client.client import NostrClient

db = Database("ext_nostrclient")

Expand All @@ -22,19 +22,14 @@

scheduled_tasks: List[asyncio.Task] = []

class NostrClient:
def __init__(self):
self.client: NostrClientLib = NostrClientLib(connect=False)


nostr = NostrClient()
nostr_client = NostrClient()


def nostr_renderer():
return template_renderer(["nostrclient/templates"])


from .tasks import check_relays, init_relays, subscribe_events
from .tasks import check_relays, init_relays, subscribe_events # noqa
from .views import * # noqa
from .views_api import * # noqa

Expand Down
26 changes: 0 additions & 26 deletions cbc.py

This file was deleted.

16 changes: 6 additions & 10 deletions crud.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
from typing import List, Optional, Union

import shortuuid

from lnbits.helpers import urlsafe_short_hash
from typing import List

from . import db
from .models import Relay, RelayList
from .models import Relay


async def get_relays() -> RelayList:
row = await db.fetchall("SELECT * FROM nostrclient.relays")
return RelayList(__root__=row)
async def get_relays() -> List[Relay]:
rows = await db.fetchall("SELECT * FROM nostrclient.relays")
return [Relay.from_row(r) for r in rows]


async def add_relay(relay: Relay) -> None:
await db.execute(
f"""
"""
INSERT INTO nostrclient.relays (
id,
url,
Expand Down
2 changes: 1 addition & 1 deletion migrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ async def m001_initial(db):
Initial nostrclient table.
"""
await db.execute(
f"""
"""
CREATE TABLE nostrclient.relays (
id TEXT NOT NULL PRIMARY KEY,
url TEXT NOT NULL,
Expand Down
42 changes: 9 additions & 33 deletions models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from dataclasses import dataclass
from typing import Dict, List, Optional
from sqlite3 import Row
from typing import List, Optional

from fastapi import Request
from fastapi.param_functions import Query
from pydantic import BaseModel, Field
from pydantic import BaseModel

from lnbits.helpers import urlsafe_short_hash

Expand All @@ -14,7 +12,8 @@ class RelayStatus(BaseModel):
error_counter: Optional[int] = 0
error_list: Optional[List] = []
notice_list: Optional[List] = []



class Relay(BaseModel):
id: Optional[str] = None
url: Optional[str] = None
Expand All @@ -28,40 +27,17 @@ def _init__(self):
if not self.id:
self.id = urlsafe_short_hash()


class RelayList(BaseModel):
__root__: List[Relay]


class Event(BaseModel):
content: str
pubkey: str
created_at: Optional[int]
kind: int
tags: Optional[List[List[str]]]
sig: str


class Filter(BaseModel):
ids: Optional[List[str]]
kinds: Optional[List[int]]
authors: Optional[List[str]]
since: Optional[int]
until: Optional[int]
e: Optional[List[str]] = Field(alias="#e")
p: Optional[List[str]] = Field(alias="#p")
limit: Optional[int]


class Filters(BaseModel):
__root__: List[Filter]
@classmethod
def from_row(cls, row: Row) -> "Relay":
return cls(**dict(row))


class TestMessage(BaseModel):
sender_private_key: Optional[str]
reciever_public_key: str
message: str


class TestMessageResponse(BaseModel):
private_key: str
public_key: str
Expand Down
Empty file removed nostr/__init__.py
Empty file.
32 changes: 22 additions & 10 deletions nostr/bech32.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,22 @@

class Encoding(Enum):
"""Enumeration type to list the various supported encodings."""

BECH32 = 1
BECH32M = 2


CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
BECH32M_CONST = 0x2bc830a3
BECH32M_CONST = 0x2BC830A3


def bech32_polymod(values):
"""Internal function that computes the Bech32 checksum."""
generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3]
generator = [0x3B6A57B2, 0x26508E6D, 0x1EA119FA, 0x3D4233DD, 0x2A1462B3]
chk = 1
for value in values:
top = chk >> 25
chk = (chk & 0x1ffffff) << 5 ^ value
chk = (chk & 0x1FFFFFF) << 5 ^ value
for i in range(5):
chk ^= generator[i] if ((top >> i) & 1) else 0
return chk
Expand All @@ -58,6 +61,7 @@ def bech32_verify_checksum(hrp, data):
return Encoding.BECH32M
return None


def bech32_create_checksum(hrp, data, spec):
"""Compute the checksum values given HRP and data."""
values = bech32_hrp_expand(hrp) + data
Expand All @@ -69,26 +73,29 @@ def bech32_create_checksum(hrp, data, spec):
def bech32_encode(hrp, data, spec):
"""Compute a Bech32 string given HRP and data values."""
combined = data + bech32_create_checksum(hrp, data, spec)
return hrp + '1' + ''.join([CHARSET[d] for d in combined])
return hrp + "1" + "".join([CHARSET[d] for d in combined])


def bech32_decode(bech):
"""Validate a Bech32/Bech32m string, and determine HRP and data."""
if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or
(bech.lower() != bech and bech.upper() != bech)):
if (any(ord(x) < 33 or ord(x) > 126 for x in bech)) or (
bech.lower() != bech and bech.upper() != bech
):
return (None, None, None)
bech = bech.lower()
pos = bech.rfind('1')
pos = bech.rfind("1")
if pos < 1 or pos + 7 > len(bech) or len(bech) > 90:
return (None, None, None)
if not all(x in CHARSET for x in bech[pos+1:]):
if not all(x in CHARSET for x in bech[pos + 1 :]):
return (None, None, None)
hrp = bech[:pos]
data = [CHARSET.find(x) for x in bech[pos+1:]]
data = [CHARSET.find(x) for x in bech[pos + 1 :]]
spec = bech32_verify_checksum(hrp, data)
if spec is None:
return (None, None, None)
return (hrp, data[:-6], spec)


def convertbits(data, frombits, tobits, pad=True):
"""General power-of-2 base conversion."""
acc = 0
Expand Down Expand Up @@ -124,7 +131,12 @@ def decode(hrp, addr):
return (None, None)
if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32:
return (None, None)
if data[0] == 0 and spec != Encoding.BECH32 or data[0] != 0 and spec != Encoding.BECH32M:
if (
data[0] == 0
and spec != Encoding.BECH32
or data[0] != 0
and spec != Encoding.BECH32M
):
return (None, None)
return (data[0], decoded)

Expand Down
57 changes: 43 additions & 14 deletions nostr/client/client.py
Original file line number Diff line number Diff line change
@@ -1,44 +1,73 @@
import asyncio
from typing import List

from loguru import logger

from ..relay_manager import RelayManager


class NostrClient:
relays = [ ]
relay_manager = RelayManager()

def __init__(self, relays: List[str] = [], connect=True):
if len(relays):
self.relays = relays
if connect:
self.connect()
def __init__(self):
self.running = True

def connect(self, relays):
for relay in relays:
try:
self.relay_manager.add_relay(relay)
except Exception as e:
logger.debug(e)
self.running = True

async def connect(self):
for relay in self.relays:
self.relay_manager.add_relay(relay)
def reconnect(self, relays):
self.relay_manager.remove_relays()
self.connect(relays)

def close(self):
self.relay_manager.close_connections()
try:
self.relay_manager.close_all_subscriptions()
self.relay_manager.close_connections()

self.running = False
except Exception as e:
logger.error(e)

async def subscribe(
self,
callback_events_func=None,
callback_notices_func=None,
callback_eosenotices_func=None,
):
while True:
while self.running:
self._check_events(callback_events_func)
self._check_notices(callback_notices_func)
self._check_eos_notices(callback_eosenotices_func)

await asyncio.sleep(0.2)

def _check_events(self, callback_events_func=None):
try:
while self.relay_manager.message_pool.has_events():
event_msg = self.relay_manager.message_pool.get_event()
if callback_events_func:
callback_events_func(event_msg)
except Exception as e:
logger.debug(e)

def _check_notices(self, callback_notices_func=None):
try:
while self.relay_manager.message_pool.has_notices():
event_msg = self.relay_manager.message_pool.get_notice()
if callback_notices_func:
callback_notices_func(event_msg)
except Exception as e:
logger.debug(e)

def _check_eos_notices(self, callback_eosenotices_func=None):
try:
while self.relay_manager.message_pool.has_eose_notices():
event_msg = self.relay_manager.message_pool.get_eose_notice()
if callback_eosenotices_func:
callback_eosenotices_func(event_msg)

await asyncio.sleep(0.5)
except Exception as e:
logger.debug(e)
32 changes: 0 additions & 32 deletions nostr/delegation.py

This file was deleted.

3 changes: 2 additions & 1 deletion nostr/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def __post_init__(self):
def id(self) -> str:
if self.content is None:
raise Exception(
"EncryptedDirectMessage `id` is undefined until its message is encrypted and stored in the `content` field"
"EncryptedDirectMessage `id` is undefined until its"
+ " message is encrypted and stored in the `content` field"
)
return super().id
Loading

0 comments on commit 16ae9d1

Please sign in to comment.