Skip to content

Commit

Permalink
Revert "Merge branch 'main' into multinut"
Browse files Browse the repository at this point in the history
This reverts commit 5049f62, reversing
changes made to c5832ef.
  • Loading branch information
callebtc committed May 22, 2024
1 parent 5049f62 commit 4134e6b
Show file tree
Hide file tree
Showing 44 changed files with 598 additions and 1,596 deletions.
3 changes: 1 addition & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ LIGHTNING_FEE_PERCENT=1.0
LIGHTNING_RESERVE_FEE_MIN=2000

# Limits
# Max mint balance in satoshis
# MINT_MAX_BALANCE=1000000

# Max peg-in amount in satoshis
# MINT_MAX_PEG_IN=100000
# Max peg-out amount in satoshis
Expand Down
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
custom: https://docs.cashu.space/contribute
custom: https://legend.lnbits.com/tipjar/794
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ jobs:
poetry-version: ["1.7.1"]
backend-wallet-class:
["LndRestWallet", "CoreLightningRestWallet", "LNbitsWallet"]
# mint-database: ["./test_data/test_mint", "postgres://cashu:cashu@localhost:5432/cashu"]
mint-database: ["./test_data/test_mint"]
with:
python-version: ${{ matrix.python-version }}
backend-wallet-class: ${{ matrix.backend-wallet-class }}
mint-database: ${{ matrix.mint-database }}
mint-database: "./test_data/test_mint"
4 changes: 2 additions & 2 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Docker Build

on:
release:
types: [released]
types: [published]

jobs:
build-and-push:
Expand Down Expand Up @@ -42,7 +42,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name == 'release' && github.event.action == 'released' }}
push: ${{ github.event_name == 'release' }}
tags: ${{ secrets.DOCKER_USERNAME }}/${{ github.event.repository.name }}:${{ steps.get_tag.outputs.tag }}
platforms: linux/amd64,linux/arm64
cache-from: type=local,src=/tmp/.buildx-cache
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pypi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Pip package
on:
push:
release:
types: [released]
types: [published]

jobs:
build-and-push:
Expand All @@ -30,6 +30,6 @@ jobs:
pip install --upgrade dist/*.whl
- name: Upload to PyPI on release
if: github.event_name == 'release' && github.event.action == 'released'
if: github.event_name == 'release'
run: |
poetry publish -u __token__ -p ${{ secrets.PYPI_API_TOKEN }}
4 changes: 4 additions & 0 deletions .github/workflows/regtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ jobs:
chmod -R 777 .
bash ./start.sh
- name: Create fake admin
if: ${{ inputs.backend-wallet-class == 'LNbitsWallet' }}
run: docker exec cashu-lnbits-1 poetry run python tools/create_fake_admin.py

- name: Run Tests
env:
WALLET_NAME: test_wallet
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ vim .env
To use the wallet with the [public test mint](#test-instance), you need to change the appropriate entries in the `.env` file.

#### Test instance
*Warning: this instance is just for demonstration purposes and development only. The satoshis are not real.*
*Warning: this instance is just for demonstration only. The server could vanish at any moment so consider any Satoshis you deposit a donation.*

Change the appropriate `.env` file settings to
```bash
MINT_URL=https://testnut.cashu.space
MINT_URL=https://8333.space:3338
```

# Using Cashu
Expand Down Expand Up @@ -172,7 +172,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.15.3 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.15.2 poetry run mint
```

## From this repository
Expand Down
81 changes: 37 additions & 44 deletions cashu/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,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 @@ -161,13 +161,20 @@ def htlcpreimage(self) -> Union[str, None]:
return HTLCWitness.from_witness(self.witness).preimage


class Proofs(BaseModel):
# NOTE: not used in Pydantic validation
__root__: List[Proof]


class BlindedMessage(BaseModel):
"""
Blinded message or blinded secret or "output" which is to be signed by the mint
"""

amount: int
id: str
id: Optional[
str
] # DEPRECATION: Only Optional for backwards compatibility with old clients < 0.15 for deprecated API route.
B_: str # Hex-encoded blinded message
witness: Union[str, None] = None # witnesses (used for P2PK with SIG_ALL)

Expand All @@ -187,14 +194,10 @@ class BlindedSignature(BaseModel):
C_: str # Hex-encoded signature
dleq: Optional[DLEQ] = None # DLEQ proof

@classmethod
def from_row(cls, row: Row):
return cls(
id=row["id"],
amount=row["amount"],
C_=row["c_"],
dleq=DLEQ(e=row["dleq_e"], s=row["dleq_s"]),
)

class BlindedMessages(BaseModel):
# NOTE: not used in Pydantic validation
__root__: List[BlindedMessage] = []


# ------- LIGHTNING INVOICE -------
Expand Down Expand Up @@ -330,19 +333,6 @@ class GetInfoResponse_deprecated(BaseModel):
parameter: Optional[dict] = None


class BlindedMessage_Deprecated(BaseModel):
# Same as BlindedMessage, but without the id field
amount: int
B_: str # Hex-encoded blinded message
id: Optional[str] = None
witness: Union[str, None] = None # witnesses (used for P2PK with SIG_ALL)

@property
def p2pksigs(self) -> List[str]:
assert self.witness, "Witness missing in output"
return P2PKWitness.from_witness(self.witness).signatures


# ------- API: KEYS -------


Expand Down Expand Up @@ -409,7 +399,7 @@ class GetMintResponse_deprecated(BaseModel):


class PostMintRequest_deprecated(BaseModel):
outputs: List[BlindedMessage_Deprecated] = Field(
outputs: List[BlindedMessage] = Field(
..., max_items=settings.mint_max_request_length
)

Expand Down Expand Up @@ -457,7 +447,7 @@ class PostMeltResponse(BaseModel):
class PostMeltRequest_deprecated(BaseModel):
proofs: List[Proof] = Field(..., max_items=settings.mint_max_request_length)
pr: str = Field(..., max_length=settings.mint_max_request_length)
outputs: Union[List[BlindedMessage_Deprecated], None] = Field(
outputs: Union[List[BlindedMessage], None] = Field(
None, max_items=settings.mint_max_request_length
)

Expand Down Expand Up @@ -486,7 +476,7 @@ class PostSplitResponse(BaseModel):
class PostSplitRequest_Deprecated(BaseModel):
proofs: List[Proof] = Field(..., max_items=settings.mint_max_request_length)
amount: Optional[int] = None
outputs: List[BlindedMessage_Deprecated] = Field(
outputs: List[BlindedMessage] = Field(
..., max_items=settings.mint_max_request_length
)

Expand Down Expand Up @@ -658,6 +648,7 @@ def __init__(
valid_to=None,
first_seen=None,
active=True,
use_deprecated_id=False, # BACKWARDS COMPATIBILITY < 0.15.0
):
self.valid_from = valid_from
self.valid_to = valid_to
Expand All @@ -672,10 +663,19 @@ def __init__(
else:
self.id = id

# BEGIN BACKWARDS COMPATIBILITY < 0.15.0
if use_deprecated_id:
logger.warning(
"Using deprecated keyset id derivation for backwards compatibility <"
" 0.15.0"
)
self.id = derive_keyset_id_deprecated(self.public_keys)
# END BACKWARDS COMPATIBILITY < 0.15.0

self.unit = Unit[unit]

logger.trace(f"Derived keyset id {self.id} from public keys.")
if id and id != self.id:
if id and id != self.id and use_deprecated_id:
logger.warning(
f"WARNING: Keyset id {self.id} does not match the given id {id}."
" Overwriting."
Expand Down Expand Up @@ -730,6 +730,8 @@ class MintKeyset:
first_seen: Optional[str] = None
version: Optional[str] = None

duplicate_keyset_id: Optional[str] = None # BACKWARDS COMPATIBILITY < 0.15.0

def __init__(
self,
*,
Expand Down Expand Up @@ -810,12 +812,6 @@ def generate_keys(self):
assert self.seed, "seed not set"
assert self.derivation_path, "derivation path not set"

# we compute the keyset id from the public keys only if it is not
# loaded from the database. This is to allow for backwards compatibility
# with old keysets with new id's and vice versa. This code can be removed
# if there are only new keysets in the mint (> 0.15.0)
id_in_db = self.id

if self.version_tuple < (0, 12):
# WARNING: Broken key derivation for backwards compatibility with < 0.12
self.private_keys = derive_keys_backwards_compatible_insecure_pre_0_12(
Expand All @@ -826,22 +822,19 @@ def generate_keys(self):
f"WARNING: Using weak key derivation for keyset {self.id} (backwards"
" compatibility < 0.12)"
)
# load from db or derive
self.id = id_in_db or derive_keyset_id_deprecated(self.public_keys) # type: ignore
self.id = derive_keyset_id_deprecated(self.public_keys) # type: ignore
elif self.version_tuple < (0, 15):
self.private_keys = derive_keys_sha256(self.seed, self.derivation_path)
logger.trace(
f"WARNING: Using non-bip32 derivation for keyset {self.id} (backwards"
" compatibility < 0.15)"
)
self.public_keys = derive_pubkeys(self.private_keys) # type: ignore
# load from db or derive
self.id = id_in_db or derive_keyset_id_deprecated(self.public_keys) # type: ignore
self.id = derive_keyset_id_deprecated(self.public_keys) # type: ignore
else:
self.private_keys = derive_keys(self.seed, self.derivation_path)
self.public_keys = derive_pubkeys(self.private_keys) # type: ignore
# load from db or derive
self.id = id_in_db or derive_keyset_id(self.public_keys) # type: ignore
self.id = derive_keyset_id(self.public_keys) # type: ignore


# ------- TOKEN -------
Expand Down
4 changes: 1 addition & 3 deletions cashu/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ class KeysetNotFoundError(KeysetError):
detail = "keyset not found"
code = 12001

def __init__(self, keyset_id: Optional[str] = None):
if keyset_id:
self.detail = f"{self.detail}: {keyset_id}"
def __init__(self):
super().__init__(self.detail, code=self.code)


Expand Down
12 changes: 10 additions & 2 deletions cashu/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

env = Env()

VERSION = "0.15.3"
VERSION = "0.15.1"


def find_env_file():
Expand Down Expand Up @@ -58,6 +58,14 @@ class MintSettings(CashuSettings):

mint_database: str = Field(default="data/mint")
mint_test_database: str = Field(default="test_data/test_mint")
mint_duplicate_keysets: bool = Field(
default=True,
title="Duplicate keysets",
description=(
"Whether to duplicate keysets for backwards compatibility before v1 API"
" (Nutshell 0.15.0)."
),
)


class MintBackends(MintSettings):
Expand Down Expand Up @@ -117,7 +125,6 @@ class FakeWalletSettings(MintSettings):
fakewallet_brr: bool = Field(default=True)
fakewallet_delay_payment: bool = Field(default=False)
fakewallet_stochastic_invoice: bool = Field(default=False)
fakewallet_payment_state: Optional[bool] = Field(default=None)
mint_cache_secrets: bool = Field(default=True)


Expand All @@ -126,6 +133,7 @@ class MintInformation(CashuSettings):
mint_info_description: str = Field(default=None)
mint_info_description_long: str = Field(default=None)
mint_info_contact: List[List[str]] = Field(default=[["", ""]])
mint_info_nuts: List[str] = Field(default=["NUT-07", "NUT-08", "NUT-09"])
mint_info_motd: str = Field(default=None)


Expand Down
14 changes: 5 additions & 9 deletions cashu/lightning/corelightningrest.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,21 +247,17 @@ async def get_payment_status(self, checking_id: str) -> PaymentStatus:
r.raise_for_status()
data = r.json()

if not data.get("pays"):
# payment not found
logger.error(f"payment not found: {data.get('pays')}")
raise Exception("payment not found")

if r.is_error or "error" in data:
message = data.get("error") or data
raise Exception(f"error in corelightning-rest response: {message}")
if r.is_error or "error" in data or not data.get("pays"):
raise Exception("error in corelightning-rest response")

pay = data["pays"][0]

fee_msat, preimage = None, None
if self.statuses[pay["status"]]:
# cut off "msat" and convert to int
fee_msat = -int(pay["amount_sent_msat"]) - int(pay["amount_msat"])
fee_msat = -int(pay["amount_sent_msat"][:-4]) - int(
pay["amount_msat"][:-4]
)
preimage = pay["preimage"]

return PaymentStatus(
Expand Down
2 changes: 1 addition & 1 deletion cashu/lightning/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
return PaymentStatus(paid=paid or None)

async def get_payment_status(self, _: str) -> PaymentStatus:
return PaymentStatus(paid=settings.fakewallet_payment_state)
return PaymentStatus(paid=None)

async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True:
Expand Down
12 changes: 1 addition & 11 deletions cashu/lightning/lnbits.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,8 @@ async def get_payment_status(self, checking_id: str) -> PaymentStatus:
if "paid" not in data and "details" not in data:
return PaymentStatus(paid=None)

paid_value = None
if data["paid"]:
paid_value = True
elif not data["paid"] and data["details"]["pending"]:
paid_value = None
elif not data["paid"] and not data["details"]["pending"]:
paid_value = False
else:
raise ValueError(f"unexpected value for paid: {data['paid']}")

return PaymentStatus(
paid=paid_value,
paid=data["paid"],
fee=Amount(unit=Unit.msat, amount=abs(data["details"]["fee"])),
preimage=data["preimage"],
)
Expand Down
Loading

0 comments on commit 4134e6b

Please sign in to comment.