lightning: add fakewallet (#134)

* lightning: add fakewallet

* make format

* fix mypy

* make backend configurable

* weird mypy
This commit is contained in:
calle
2023-03-07 17:49:27 +01:00
committed by GitHub
parent 3828da294b
commit 3333102327
7 changed files with 127 additions and 8 deletions

View File

@@ -21,6 +21,9 @@ TOR=TRUE
MINT_PRIVATE_KEY=supersecretprivatekey
# Supported: LNbitsWallet, FakeWallet
MINT_LIGHTNING_BACKEND=LNbitsWallet
MINT_SERVER_HOST=127.0.0.1
MINT_SERVER_PORT=3338

View File

@@ -44,6 +44,7 @@ MINT_URL = env.str("MINT_URL", default=None)
MINT_HOST = env.str("MINT_HOST", default="8333.space")
MINT_PORT = env.int("MINT_PORT", default=3338)
MINT_LIGHTNING_BACKEND = env.str("MINT_LIGHTNING_BACKEND", default="FakeWallet")
MINT_DATABASE = env.str("MINT_DATABASE", default="data/mint")
if not MINT_URL:

View File

@@ -1,3 +1,3 @@
# from cashu.lightning.lnbits import LNbitsWallet
# WALLET = LNbitsWallet()
# type: ignore
from .fake import FakeWallet
from .lnbits import LNbitsWallet

100
cashu/lightning/fake.py Normal file
View File

@@ -0,0 +1,100 @@
import asyncio
import hashlib
import random
from datetime import datetime
from typing import AsyncGenerator, Dict, Optional, Set
from cashu.core.bolt11 import Invoice, decode, encode
from .base import (
InvoiceResponse,
PaymentResponse,
PaymentStatus,
StatusResponse,
Wallet,
)
class FakeWallet(Wallet):
"""https://github.com/lnbits/lnbits"""
queue: asyncio.Queue = asyncio.Queue(0)
paid_invoices: Set[str] = set()
secret: str = "FAKEWALLET SECRET"
privkey: str = hashlib.pbkdf2_hmac(
"sha256",
secret.encode(),
("FakeWallet").encode(),
2048,
32,
).hex()
async def status(self) -> StatusResponse:
return StatusResponse(None, 1337)
async def create_invoice(
self,
amount: int,
memo: Optional[str] = None,
description_hash: Optional[bytes] = None,
unhashed_description: Optional[bytes] = None,
**kwargs,
) -> InvoiceResponse:
data: Dict = {
"out": False,
"amount": amount * 1000,
"currency": "bc",
"privkey": self.privkey,
"memo": memo,
"description_hash": b"",
"description": "",
"fallback": None,
"expires": kwargs.get("expiry"),
"timestamp": datetime.now().timestamp(),
"route": None,
"tags_set": [],
}
if description_hash:
data["tags_set"] = ["h"]
data["description_hash"] = description_hash
elif unhashed_description:
data["tags_set"] = ["d"]
data["description_hash"] = hashlib.sha256(unhashed_description).digest()
else:
data["tags_set"] = ["d"]
data["memo"] = memo
data["description"] = memo
randomHash = (
self.privkey[:6]
+ hashlib.sha256(str(random.getrandbits(256)).encode()).hexdigest()[6:]
)
data["paymenthash"] = randomHash
payment_request = encode(data)
checking_id = randomHash
return InvoiceResponse(True, checking_id, payment_request)
async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse:
invoice = decode(bolt11)
if invoice.payment_hash[:6] == self.privkey[:6]:
await self.queue.put(invoice)
self.paid_invoices.add(invoice.payment_hash)
return PaymentResponse(True, invoice.payment_hash, 0)
else:
return PaymentResponse(
ok=False, error_message="Only internal invoices can be used!"
)
async def get_invoice_status(self, checking_id: str) -> PaymentStatus:
paid = checking_id in self.paid_invoices
return PaymentStatus(paid or None)
async def get_payment_status(self, _: str) -> PaymentStatus:
return PaymentStatus(None)
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
while True:
value: Invoice = await self.queue.get()
yield value.payment_hash

View File

@@ -1,5 +1,4 @@
# type: ignore
from os import getenv
from typing import Dict, Optional
import requests

View File

@@ -1,22 +1,32 @@
# startup routine of the standalone app. These are the steps that need
# to be taken by external apps importing the cashu mint.
import asyncio
import importlib
from loguru import logger
from cashu.core.db import Database
from cashu.core.migrations import migrate_databases
from cashu.core.settings import CASHU_DIR, LIGHTNING, MINT_DATABASE, MINT_PRIVATE_KEY
from cashu.core.settings import (
CASHU_DIR,
LIGHTNING,
MINT_DATABASE,
MINT_LIGHTNING_BACKEND,
MINT_PRIVATE_KEY,
)
from cashu.lightning.fake import FakeWallet # type: ignore
from cashu.lightning.lnbits import LNbitsWallet # type: ignore
from cashu.mint import migrations
from cashu.mint.ledger import Ledger
wallets_module = importlib.import_module("cashu.lightning")
LIGHTNING_BACKEND = getattr(wallets_module, MINT_LIGHTNING_BACKEND)()
ledger = Ledger(
db=Database("mint", MINT_DATABASE),
seed=MINT_PRIVATE_KEY,
derivation_path="0/0/0/0",
lightning=LNbitsWallet(),
lightning=LIGHTNING_BACKEND,
)
@@ -27,6 +37,7 @@ async def start_mint_init():
await ledger.init_keysets()
if LIGHTNING:
logger.info(f"Using backend: {MINT_LIGHTNING_BACKEND}")
error_message, balance = await ledger.lightning.status()
if error_message:
logger.warning(

View File

@@ -1,2 +1,7 @@
[mypy]
exclude = /cashu/nostr/
python_version = 3.9
# disallow_untyped_defs = True
ignore_missing_imports = True
[mypy-cashu.nostr.*]
ignore_errors = True