Skip to content

Commit

Permalink
Merge branch 'main' into bump-py-3-10-requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
callebtc committed Nov 4, 2024
2 parents 9c9882e + 05547e3 commit f2370a9
Show file tree
Hide file tree
Showing 47 changed files with 1,267 additions and 1,082 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repos:
- id: mixed-line-ending
- id: check-case-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.1
rev: v0.7.1
hooks:
- id: ruff
args: [--fix]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ This command runs the mint on your local computer. Skip this step if you want to
## Docker

```
docker run -d -p 3338:3338 --name nutshell -e MINT_BACKEND_BOLT11_SAT=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.16.1 poetry run mint
docker run -d -p 3338:3338 --name nutshell -e MINT_BACKEND_BOLT11_SAT=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.16.2 poetry run mint
```

## From this repository
Expand Down
110 changes: 70 additions & 40 deletions cashu/core/base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import base64
import json
import math
import time
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from enum import Enum
Expand Down Expand Up @@ -134,12 +135,12 @@ class Proof(BaseModel):
time_created: Union[None, str] = ""
time_reserved: Union[None, str] = ""
derivation_path: Union[None, str] = "" # derivation path of the proof
mint_id: Union[
None, str
] = None # holds the id of the mint operation that created this proof
melt_id: Union[
None, str
] = None # holds the id of the melt operation that destroyed this proof
mint_id: Union[None, str] = (
None # holds the id of the mint operation that created this proof
)
melt_id: Union[None, str] = (
None # holds the id of the melt operation that destroyed this proof
)

def __init__(self, **data):
super().__init__(**data)
Expand Down Expand Up @@ -260,20 +261,7 @@ def from_row(cls, row: Row):
)


# ------- LIGHTNING INVOICE -------


class Invoice(BaseModel):
amount: int
bolt11: str
id: str
out: Union[None, bool] = None
payment_hash: Union[None, str] = None
preimage: Union[str, None] = None
issued: Union[None, bool] = False
paid: Union[None, bool] = False
time_created: Union[None, str, int, float] = ""
time_paid: Union[None, str, int, float] = ""
# ------- Quotes -------


class MeltQuoteState(Enum):
Expand All @@ -297,9 +285,10 @@ class MeltQuote(LedgerEvent):
created_time: Union[int, None] = None
paid_time: Union[int, None] = None
fee_paid: int = 0
payment_preimage: str = ""
payment_preimage: Optional[str] = None
expiry: Optional[int] = None
change: Optional[List[BlindedSignature]] = None
mint: Optional[str] = None

@classmethod
def from_row(cls, row: Row):
Expand All @@ -314,6 +303,8 @@ def from_row(cls, row: Row):
paid_time = int(row["paid_time"].timestamp()) if row["paid_time"] else None
expiry = int(row["expiry"].timestamp()) if row["expiry"] else None

payment_preimage = row.get("payment_preimage") or row.get("proof") # type: ignore

# parse change from row as json
change = None
if row["change"]:
Expand All @@ -327,13 +318,37 @@ def from_row(cls, row: Row):
unit=row["unit"],
amount=row["amount"],
fee_reserve=row["fee_reserve"],
state=MeltQuoteState[row["state"]],
state=MeltQuoteState(row["state"]),
created_time=created_time,
paid_time=paid_time,
fee_paid=row["fee_paid"],
change=change,
expiry=expiry,
payment_preimage=row["proof"],
payment_preimage=payment_preimage,
)

@classmethod
def from_resp_wallet(
cls, melt_quote_resp, mint: str, amount: int, unit: str, request: str
):
# BEGIN: BACKWARDS COMPATIBILITY < 0.16.0: "paid" field to "state"
if melt_quote_resp.state is None:
if melt_quote_resp.paid is True:
melt_quote_resp.state = MeltQuoteState.paid
elif melt_quote_resp.paid is False:
melt_quote_resp.state = MeltQuoteState.unpaid
# END: BACKWARDS COMPATIBILITY < 0.16.0
return cls(
quote=melt_quote_resp.quote,
method="bolt11",
request=request,
checking_id="",
unit=unit,
amount=amount,
fee_reserve=melt_quote_resp.fee_reserve,
state=MeltQuoteState(melt_quote_resp.state),
mint=mint,
change=melt_quote_resp.change,
)

@property
Expand Down Expand Up @@ -397,6 +412,7 @@ class MintQuote(LedgerEvent):
created_time: Union[int, None] = None
paid_time: Union[int, None] = None
expiry: Optional[int] = None
mint: Optional[str] = None

@classmethod
def from_row(cls, row: Row):
Expand All @@ -417,11 +433,33 @@ def from_row(cls, row: Row):
checking_id=row["checking_id"],
unit=row["unit"],
amount=row["amount"],
state=MintQuoteState[row["state"]],
state=MintQuoteState(row["state"]),
created_time=created_time,
paid_time=paid_time,
)

@classmethod
def from_resp_wallet(cls, mint_quote_resp, mint: str, amount: int, unit: str):
# BEGIN: BACKWARDS COMPATIBILITY < 0.16.0: "paid" field to "state"
if mint_quote_resp.state is None:
if mint_quote_resp.paid is True:
mint_quote_resp.state = MintQuoteState.paid
elif mint_quote_resp.paid is False:
mint_quote_resp.state = MintQuoteState.unpaid
# END: BACKWARDS COMPATIBILITY < 0.16.0
return cls(
quote=mint_quote_resp.quote,
method="bolt11",
request=mint_quote_resp.request,
checking_id="",
unit=unit,
amount=amount,
state=MintQuoteState(mint_quote_resp.state),
mint=mint,
expiry=mint_quote_resp.expiry,
created_time=int(time.time()),
)

@property
def identifier(self) -> str:
"""Implementation of the abstract method from LedgerEventManager"""
Expand Down Expand Up @@ -801,43 +839,35 @@ def generate_keys(self):
class Token(ABC):
@property
@abstractmethod
def proofs(self) -> List[Proof]:
...
def proofs(self) -> List[Proof]: ...

@property
@abstractmethod
def amount(self) -> int:
...
def amount(self) -> int: ...

@property
@abstractmethod
def mint(self) -> str:
...
def mint(self) -> str: ...

@property
@abstractmethod
def keysets(self) -> List[str]:
...
def keysets(self) -> List[str]: ...

@property
@abstractmethod
def memo(self) -> Optional[str]:
...
def memo(self) -> Optional[str]: ...

@memo.setter
@abstractmethod
def memo(self, memo: Optional[str]):
...
def memo(self, memo: Optional[str]): ...

@property
@abstractmethod
def unit(self) -> str:
...
def unit(self) -> str: ...

@unit.setter
@abstractmethod
def unit(self, unit: str):
...
def unit(self, unit: str): ...


class TokenV3Token(BaseModel):
Expand Down
13 changes: 8 additions & 5 deletions cashu/core/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def big_int(self) -> str:
def table_with_schema(self, table: str):
return f"{self.references_schema if self.schema else ''}{table}"


# https://docs.sqlalchemy.org/en/14/core/connections.html#sqlalchemy.engine.CursorResult
class Connection(Compat):
def __init__(self, conn: AsyncSession, txn, typ, name, schema):
Expand All @@ -82,7 +83,9 @@ def rewrite_query(self, query) -> TextClause:

async def fetchall(self, query: str, values: dict = {}):
result = await self.conn.execute(self.rewrite_query(query), values)
return [r._mapping for r in result.all()] # will return [] if result list is empty
return [
r._mapping for r in result.all()
] # will return [] if result list is empty

async def fetchone(self, query: str, values: dict = {}):
result = await self.conn.execute(self.rewrite_query(query), values)
Expand Down Expand Up @@ -134,13 +137,13 @@ def __init__(self, db_name: str, db_location: str):
if not settings.db_connection_pool:
kwargs["poolclass"] = NullPool
elif self.type == POSTGRES:
kwargs["poolclass"] = AsyncAdaptedQueuePool # type: ignore[assignment]
kwargs["pool_size"] = 50 # type: ignore[assignment]
kwargs["max_overflow"] = 100 # type: ignore[assignment]
kwargs["poolclass"] = AsyncAdaptedQueuePool # type: ignore[assignment]
kwargs["pool_size"] = 50 # type: ignore[assignment]
kwargs["max_overflow"] = 100 # type: ignore[assignment]

self.engine = create_async_engine(database_uri, **kwargs)
self.async_session = sessionmaker(
self.engine,
self.engine, # type: ignore
expire_on_commit=False,
class_=AsyncSession, # type: ignore
)
Expand Down
6 changes: 3 additions & 3 deletions cashu/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ class PostMeltQuoteResponse(BaseModel):
quote: str # quote id
amount: int # input amount
fee_reserve: int # input fee reserve
paid: Optional[
bool
] = None # whether the request has been paid # DEPRECATED as per NUT PR #136
paid: Optional[bool] = (
None # whether the request has been paid # DEPRECATED as per NUT PR #136
)
state: Optional[str] # state of the quote
expiry: Optional[int] # expiry of the quote
payment_preimage: Optional[str] = None # payment preimage
Expand Down
3 changes: 2 additions & 1 deletion cashu/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

env = Env()

VERSION = "0.16.1"
VERSION = "0.16.2"


def find_env_file():
Expand Down Expand Up @@ -62,6 +62,7 @@ class MintSettings(CashuSettings):
mint_max_secret_length: int = Field(default=512)

mint_input_fee_ppk: int = Field(default=0)
mint_disable_melt_on_error: bool = Field(default=False)


class MintDeprecationFlags(MintSettings):
Expand Down
2 changes: 1 addition & 1 deletion cashu/lightning/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@


class FakeWallet(LightningBackend):
unit: Unit
fake_btc_price = 1e8 / 1337
paid_invoices_queue: asyncio.Queue[Bolt11] = asyncio.Queue(0)
payment_secrets: Dict[str, str] = dict()
Expand All @@ -46,7 +47,6 @@ class FakeWallet(LightningBackend):
).hex()

supported_units = {Unit.sat, Unit.msat, Unit.usd, Unit.eur}
unit = Unit.sat

supports_incoming_payment_stream: bool = True
supports_description: bool = True
Expand Down
Loading

0 comments on commit f2370a9

Please sign in to comment.