Skip to content

Commit

Permalink
wip, lots of things broken but invoice callback works
Browse files Browse the repository at this point in the history
  • Loading branch information
callebtc committed Apr 4, 2024
1 parent 7f05035 commit 8d714b2
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 89 deletions.
2 changes: 1 addition & 1 deletion cashu/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from loguru import logger
from pydantic import BaseModel, Field, root_validator

from ..mint.events.base import LedgerEvent
from ..mint.events.events import LedgerEvent
from .crypto.aes import AESCipher
from .crypto.b_dhke import hash_to_curve
from .crypto.keys import (
Expand Down
8 changes: 4 additions & 4 deletions cashu/lightning/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from abc import ABC, abstractmethod
from typing import Coroutine, Optional, Union
from typing import AsyncGenerator, Coroutine, Optional, Union

from pydantic import BaseModel

Expand Down Expand Up @@ -118,9 +118,9 @@ async def get_payment_quote(
# ) -> InvoiceQuoteResponse:
# pass

# @abstractmethod
# def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
# pass
@abstractmethod
def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
pass


class Unsupported(Exception):
Expand Down
62 changes: 47 additions & 15 deletions cashu/lightning/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import random
from datetime import datetime
from os import urandom
from typing import AsyncGenerator, Dict, Optional, Set
from typing import AsyncGenerator, Dict, List, Optional

from bolt11 import (
Bolt11,
Expand All @@ -30,9 +30,11 @@

class FakeWallet(LightningBackend):
fake_btc_price = 1e8 / 1337
queue: asyncio.Queue[Bolt11] = asyncio.Queue(0)
paid_invoices_queue: asyncio.Queue[Bolt11] = asyncio.Queue(0)
payment_secrets: Dict[str, str] = dict()
paid_invoices: Set[str] = set()
created_invoices: List[Bolt11] = []
paid_invoices_outgoing: List[Bolt11] = []
paid_invoices_incoming: List[Bolt11] = []
secret: str = "FAKEWALLET SECRET"
privkey: str = hashlib.pbkdf2_hmac(
"sha256",
Expand All @@ -52,6 +54,11 @@ def __init__(self, unit: Unit = Unit.sat, **kwargs):
async def status(self) -> StatusResponse:
return StatusResponse(error_message=None, balance=1337)

async def mark_invoice_paid(self, invoice: Bolt11) -> None:
await asyncio.sleep(1)
self.paid_invoices_incoming.append(invoice)
await self.paid_invoices_queue.put(invoice)

async def create_invoice(
self,
amount: Amount,
Expand Down Expand Up @@ -105,8 +112,15 @@ async def create_invoice(
tags=tags,
)

if bolt11 not in self.created_invoices:
self.created_invoices.append(bolt11)
else:
raise ValueError("Invoice already created")

payment_request = encode(bolt11, self.privkey)

asyncio.create_task(self.mark_invoice_paid(bolt11))

return InvoiceResponse(
ok=True, checking_id=payment_hash, payment_request=payment_request
)
Expand All @@ -118,8 +132,11 @@ async def pay_invoice(self, quote: MeltQuote, fee_limit: int) -> PaymentResponse
await asyncio.sleep(5)

if invoice.payment_hash in self.payment_secrets or settings.fakewallet_brr:
await self.queue.put(invoice)
self.paid_invoices.add(invoice.payment_hash)
if invoice not in self.paid_invoices_outgoing:
self.paid_invoices_outgoing.append(invoice)
else:
raise ValueError("Invoice already paid")

return PaymentResponse(
ok=True,
checking_id=invoice.payment_hash,
Expand All @@ -132,20 +149,30 @@ async def pay_invoice(self, quote: MeltQuote, fee_limit: int) -> PaymentResponse
)

async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
if settings.fakewallet_stochastic_invoice:
paid = random.random() > 0.7
return PaymentStatus(paid=paid)
paid = checking_id in self.paid_invoices or settings.fakewallet_brr
return PaymentStatus(paid=paid or None)
is_created_invoice = any(
[checking_id == i.payment_hash for i in self.created_invoices]
)
if not is_created_invoice:
return PaymentStatus(paid=None)
invoice = next(
i for i in self.created_invoices if i.payment_hash == checking_id
)
paid = False
if is_created_invoice or (
settings.fakewallet_brr
or (settings.fakewallet_stochastic_invoice and random.random() > 0.7)
):
paid = True

# invoice is paid but not in paid_invoices_incoming yet
# so we add it to the paid_invoices_queue
if paid and invoice not in self.paid_invoices_incoming:
await self.paid_invoices_queue.put(invoice)
return PaymentStatus(paid=paid)

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

async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True:
value: Bolt11 = await self.queue.get()
yield value.payment_hash

# async def get_invoice_quote(self, bolt11: str) -> InvoiceQuoteResponse:
# invoice_obj = decode(bolt11)
# assert invoice_obj.amount_msat, "invoice has no amount."
Expand Down Expand Up @@ -173,3 +200,8 @@ async def get_payment_quote(self, bolt11: str) -> PaymentQuoteResponse:
fee=fees.to(self.unit, round="up"),
amount=amount.to(self.unit, round="up"),
)

async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True:
value: Bolt11 = await self.paid_invoices_queue.get()
yield value.payment_hash
Loading

0 comments on commit 8d714b2

Please sign in to comment.