Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize #24

Merged
merged 30 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9ea01b7
refactor: clean-up
motorina0 Oct 26, 2023
b15be7e
refactor: extra logs plus try-catch
motorina0 Oct 26, 2023
de744f3
refactor: do not use bare `except`
motorina0 Oct 26, 2023
9ef62e1
refactor: clean-up redundant fields
motorina0 Oct 26, 2023
91fac03
chore: pass code checks
motorina0 Oct 26, 2023
636d4aa
chore: code format
motorina0 Oct 26, 2023
8c7c9a6
refactor: code clean-up
motorina0 Oct 26, 2023
55a71c4
fix: refactoring stuff
motorina0 Oct 26, 2023
1d6f0b9
refactor: remove un-used file
motorina0 Oct 26, 2023
ce265f8
chore: code clean-up
motorina0 Oct 26, 2023
e776ec9
chore: code clean-up
motorina0 Oct 26, 2023
1c4dd61
chore: code-format fix
motorina0 Oct 26, 2023
0f6659a
refactor: remove nostr.client wrapper
motorina0 Oct 26, 2023
c02317c
refactor: code clean-up
motorina0 Oct 26, 2023
a7f3448
chore: code format
motorina0 Oct 26, 2023
879e244
refactor: remove `RelayList` class
motorina0 Oct 27, 2023
23b1ef6
refactor: extract smaller methods with try-catch
motorina0 Oct 27, 2023
311c170
fix: better exception handling
motorina0 Oct 31, 2023
672990a
fix: remove redundant filters
motorina0 Oct 31, 2023
0b8e73b
fix: simplify event
motorina0 Oct 31, 2023
f14ca6e
chore: code format
motorina0 Oct 31, 2023
95b5845
fix: code check
motorina0 Oct 31, 2023
0d948ea
fix: code check
motorina0 Oct 31, 2023
e3d2843
fix: simplify `REQ`
motorina0 Oct 31, 2023
44fbb35
fix: more clean-ups
motorina0 Oct 31, 2023
e6b6ed9
refactor: use simpler method
motorina0 Oct 31, 2023
3bc10a7
refactor: re-order and rename
motorina0 Oct 31, 2023
fb1df37
fix: stop logic
motorina0 Oct 31, 2023
09d42f1
fix: subscription close before disconnect
motorina0 Oct 31, 2023
73e520f
chore: play commit
motorina0 Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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