Mega-merge 2: Invoice/refactor description hash (WIP) (#814)

* description hashing in backend
This commit is contained in:
calle 2022-08-01 16:20:25 +02:00 committed by GitHub
parent c88e6b0e62
commit f1ec7e33f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 40 additions and 41 deletions

View File

@ -184,11 +184,13 @@ async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
lnurl_response: Union[None, bool, str] = None lnurl_response: Union[None, bool, str] = None
if data.lnurl_callback: if data.lnurl_callback:
if "lnurl_balance_check" in data: if data.lnurl_balance_check is not None:
assert (
data.lnurl_balance_check is not None
), "lnurl_balance_check is required"
await save_balance_check(wallet.id, data.lnurl_balance_check) await save_balance_check(wallet.id, data.lnurl_balance_check)
else:
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail="lnurl_balance_check not set.",
)
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
try: try:

View File

@ -73,11 +73,9 @@ async def lnurl_callback(
wallet_id=cp.wallet, wallet_id=cp.wallet,
amount=int(amount_received / 1000), amount=int(amount_received / 1000),
memo=cp.lnurl_title, memo=cp.lnurl_title,
description_hash=hashlib.sha256( description_hash=(
(
LnurlPayMetadata(json.dumps([["text/plain", str(cp.lnurl_title)]])) LnurlPayMetadata(json.dumps([["text/plain", str(cp.lnurl_title)]]))
).encode("utf-8") ).encode("utf-8"),
).digest(),
extra={"tag": "copilot", "copilotid": cp.id, "comment": comment}, extra={"tag": "copilot", "copilotid": cp.id, "comment": comment},
) )
payResponse = {"pr": payment_request, "routes": []} payResponse = {"pr": payment_request, "routes": []}

View File

@ -90,9 +90,7 @@ async def lnurl_callback(
wallet_id=ls.wallet, wallet_id=ls.wallet,
amount=int(amount_received / 1000), amount=int(amount_received / 1000),
memo=await track.fullname(), memo=await track.fullname(),
description_hash=hashlib.sha256( description_hash=(await track.lnurlpay_metadata()).encode("utf-8"),
(await track.lnurlpay_metadata()).encode("utf-8")
).digest(),
extra={"tag": "livestream", "track": track.id, "comment": comment}, extra={"tag": "livestream", "track": track.id, "comment": comment},
) )

View File

@ -70,11 +70,9 @@ async def lnurl_callback(address_id, amount: int = Query(...)):
json={ json={
"out": False, "out": False,
"amount": int(amount_received / 1000), "amount": int(amount_received / 1000),
"description_hash": hashlib.sha256( "description_hash": (
(await address.lnurlpay_metadata(domain=domain.domain)).encode( await address.lnurlpay_metadata(domain=domain.domain)
"utf-8" ).encode("utf-8"),
)
).hexdigest(),
"extra": {"tag": f"Payment to {address.username}@{domain.domain}"}, "extra": {"tag": f"Payment to {address.username}@{domain.domain}"},
}, },
timeout=40, timeout=40,

View File

@ -205,9 +205,7 @@ async def lnurl_callback(
wallet_id=device.wallet, wallet_id=device.wallet,
amount=lnurldevicepayment.sats / 1000, amount=lnurldevicepayment.sats / 1000,
memo=device.title, memo=device.title,
description_hash=hashlib.sha256( description_hash=(await device.lnurlpay_metadata()).encode("utf-8"),
(await device.lnurlpay_metadata()).encode("utf-8")
).digest(),
extra={"tag": "PoS"}, extra={"tag": "PoS"},
) )
lnurldevicepayment = await update_lnurldevicepayment( lnurldevicepayment = await update_lnurldevicepayment(

View File

@ -87,9 +87,7 @@ async def api_lnurl_callback(request: Request, link_id):
wallet_id=link.wallet, wallet_id=link.wallet,
amount=int(amount_received / 1000), amount=int(amount_received / 1000),
memo=link.description, memo=link.description,
description_hash=hashlib.sha256( description_hash=link.lnurlpay_metadata.encode("utf-8"),
link.lnurlpay_metadata.encode("utf-8")
).digest(),
extra={ extra={
"tag": "lnurlp", "tag": "lnurlp",
"link": link.id, "link": link.id,

View File

@ -73,9 +73,7 @@ async def lnurl_callback(request: Request, item_id: int):
wallet_id=shop.wallet, wallet_id=shop.wallet,
amount=int(amount_received / 1000), amount=int(amount_received / 1000),
memo=item.name, memo=item.name,
description_hash=hashlib.sha256( description_hash=(await item.lnurlpay_metadata()).encode("utf-8"),
(await item.lnurlpay_metadata()).encode("utf-8")
).digest(),
extra={"tag": "offlineshop", "item": item.id}, extra={"tag": "offlineshop", "item": item.id},
) )
except Exception as exc: except Exception as exc:

View File

@ -77,9 +77,7 @@ async def api_lnurlp_callback(
wallet_id=link.wallet, wallet_id=link.wallet,
amount=int(amount_received / 1000), amount=int(amount_received / 1000),
memo="Satsdice bet", memo="Satsdice bet",
description_hash=hashlib.sha256( description_hash=link.lnurlpay_metadata.encode("utf-8"),
link.lnurlpay_metadata.encode("utf-8")
).digest(),
extra={"tag": "satsdice", "link": link.id, "comment": "comment"}, extra={"tag": "satsdice", "link": link.id, "comment": "comment"},
) )

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import hashlib
import json import json
from os import getenv from os import getenv
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
@ -47,9 +48,10 @@ class ClicheWallet(Wallet):
description_hash: Optional[bytes] = None, description_hash: Optional[bytes] = None,
) -> InvoiceResponse: ) -> InvoiceResponse:
if description_hash: if description_hash:
description_hash_hashed = hashlib.sha256(description_hash).hexdigest()
ws = create_connection(self.endpoint) ws = create_connection(self.endpoint)
ws.send( ws.send(
f"create-invoice --msatoshi {amount*1000} --description_hash {description_hash.hex()}" f"create-invoice --msatoshi {amount*1000} --description_hash {description_hash_hashed}"
) )
r = ws.recv() r = ws.recv()
else: else:

View File

@ -4,6 +4,7 @@ except ImportError: # pragma: nocover
LightningRpc = None LightningRpc = None
import asyncio import asyncio
import hashlib
import random import random
import time import time
from functools import partial, wraps from functools import partial, wraps
@ -94,7 +95,7 @@ class CLightningWallet(Wallet):
if not self.supports_description_hash: if not self.supports_description_hash:
raise Unsupported("description_hash") raise Unsupported("description_hash")
params = [msat, label, description_hash.hex()] params = [msat, label, hashlib.sha256(description_hash).hexdigest()]
r = self.ln.call("invoicewithdescriptionhash", params) r = self.ln.call("invoicewithdescriptionhash", params)
return InvoiceResponse(True, label, r["bolt11"], "") return InvoiceResponse(True, label, r["bolt11"], "")
else: else:

View File

@ -1,5 +1,6 @@
import asyncio import asyncio
import base64 import base64
import hashlib
import json import json
import urllib.parse import urllib.parse
from os import getenv from os import getenv
@ -72,7 +73,7 @@ class EclairWallet(Wallet):
data: Dict = {"amountMsat": amount * 1000} data: Dict = {"amountMsat": amount * 1000}
if description_hash: if description_hash:
data["description_hash"] = description_hash.hex() data["description_hash"] = hashlib.sha256(description_hash).hexdigest()
else: else:
data["description"] = memo or "" data["description"] = memo or ""

View File

@ -61,7 +61,7 @@ class FakeWallet(Wallet):
data["timestamp"] = datetime.now().timestamp() data["timestamp"] = datetime.now().timestamp()
if description_hash: if description_hash:
data["tags_set"] = ["h"] data["tags_set"] = ["h"]
data["description_hash"] = description_hash.hex() data["description_hash"] = description_hash.decode("utf-8")
else: else:
data["tags_set"] = ["d"] data["tags_set"] = ["d"]
data["memo"] = memo data["memo"] = memo

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import hashlib
import json import json
from os import getenv from os import getenv
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
@ -59,7 +60,7 @@ class LNbitsWallet(Wallet):
) -> InvoiceResponse: ) -> InvoiceResponse:
data: Dict = {"out": False, "amount": amount} data: Dict = {"out": False, "amount": amount}
if description_hash: if description_hash:
data["description_hash"] = description_hash.hex() data["description_hash"] = hashlib.sha256(description_hash).hexdigest()
else: else:
data["memo"] = memo or "" data["memo"] = memo or ""

View File

@ -132,7 +132,9 @@ class LndWallet(Wallet):
params: Dict = {"value": amount, "expiry": 600, "private": True} params: Dict = {"value": amount, "expiry": 600, "private": True}
if description_hash: if description_hash:
params["description_hash"] = description_hash # as bytes directly params["description_hash"] = base64.b64encode(
hashlib.sha256(description_hash).digest()
) # as bytes directly
else: else:
params["memo"] = memo or "" params["memo"] = memo or ""

View File

@ -1,5 +1,6 @@
import asyncio import asyncio
import base64 import base64
import hashlib
import json import json
from os import getenv from os import getenv
from pydoc import describe from pydoc import describe
@ -75,9 +76,9 @@ class LndRestWallet(Wallet):
) -> InvoiceResponse: ) -> InvoiceResponse:
data: Dict = {"value": amount, "private": True} data: Dict = {"value": amount, "private": True}
if description_hash: if description_hash:
data["description_hash"] = base64.b64encode(description_hash).decode( data["description_hash"] = base64.b64encode(
"ascii" hashlib.sha256(description_hash).digest()
) ).decode("ascii")
else: else:
data["memo"] = memo or "" data["memo"] = memo or ""

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import hashlib
import json import json
from http import HTTPStatus from http import HTTPStatus
from os import getenv from os import getenv
@ -54,7 +55,7 @@ class LNPayWallet(Wallet):
) -> InvoiceResponse: ) -> InvoiceResponse:
data: Dict = {"num_satoshis": f"{amount}"} data: Dict = {"num_satoshis": f"{amount}"}
if description_hash: if description_hash:
data["description_hash"] = description_hash.hex() data["description_hash"] = hashlib.sha256(description_hash).hexdigest()
else: else:
data["memo"] = memo or "" data["memo"] = memo or ""

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import hashlib
import json import json
from os import getenv from os import getenv
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
@ -54,7 +55,7 @@ class LntxbotWallet(Wallet):
) -> InvoiceResponse: ) -> InvoiceResponse:
data: Dict = {"amt": str(amount)} data: Dict = {"amt": str(amount)}
if description_hash: if description_hash:
data["description_hash"] = description_hash.hex() data["description_hash"] = hashlib.sha256(description_hash).hexdigest()
else: else:
data["memo"] = memo or "" data["memo"] = memo or ""

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import hashlib
import json import json
import random import random
from os import getenv from os import getenv
@ -101,7 +102,7 @@ class SparkWallet(Wallet):
r = await self.invoicewithdescriptionhash( r = await self.invoicewithdescriptionhash(
msatoshi=amount * 1000, msatoshi=amount * 1000,
label=label, label=label,
description_hash=description_hash.hex(), description_hash=hashlib.sha256(description_hash).hexdigest(),
) )
else: else:
r = await self.invoice( r = await self.invoice(