From e58a6923fcdfc3fe06ee21a23b98ecae80e3a69e Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Mon, 25 Oct 2021 18:25:57 +0100 Subject: [PATCH] proposal to allow decimal valued items in fiat --- lnbits/extensions/offlineshop/lnurl.py | 24 +++++++++---------- lnbits/extensions/offlineshop/migrations.py | 3 +++ .../extensions/offlineshop/static/js/index.js | 5 +++- lnbits/extensions/offlineshop/views.py | 10 ++++---- lnbits/extensions/offlineshop/views_api.py | 13 ++++++---- 5 files changed, 33 insertions(+), 22 deletions(-) diff --git a/lnbits/extensions/offlineshop/lnurl.py b/lnbits/extensions/offlineshop/lnurl.py index ea576f1da..22e470da3 100644 --- a/lnbits/extensions/offlineshop/lnurl.py +++ b/lnbits/extensions/offlineshop/lnurl.py @@ -1,20 +1,19 @@ import hashlib -from lnbits.extensions.offlineshop.models import Item -from fastapi.params import Query -from starlette.requests import Request -from lnbits.helpers import url_for -from lnurl import ( - LnurlPayResponse, - LnurlPayActionResponse, +from fastapi.params import Query +from lnurl import ( # type: ignore LnurlErrorResponse, -) # type: ignore + LnurlPayActionResponse, + LnurlPayResponse, +) +from starlette.requests import Request from lnbits.core.services import create_invoice +from lnbits.extensions.offlineshop.models import Item from lnbits.utils.exchange_rates import fiat_amount_as_satoshis from . import offlineshop_ext -from .crud import get_shop, get_item +from .crud import get_item, get_shop @offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response") @@ -27,7 +26,7 @@ async def lnurl_response(req: Request, item_id: int = Query(...)): return {"status": "ERROR", "reason": "Item disabled."} price_msat = ( - await fiat_amount_as_satoshis(item.price, item.unit) + await fiat_amount_as_satoshis(item.price / 1000, item.unit) if item.unit != "sat" else item.price ) * 1000 @@ -47,12 +46,12 @@ async def lnurl_callback(request: Request, item_id: int): item = await get_item(item_id) # type: Item if not item: return {"status": "ERROR", "reason": "Couldn't find item."} - + if item.unit == "sat": min = item.price * 1000 max = item.price * 1000 else: - price = await fiat_amount_as_satoshis(item.price, item.unit) + price = await fiat_amount_as_satoshis(item.price / 1000, item.unit) # allow some fluctuation (the fiat price may have changed between the calls) min = price * 995 max = price * 1010 @@ -68,7 +67,6 @@ async def lnurl_callback(request: Request, item_id: int): ).dict() shop = await get_shop(item.shop) - try: payment_hash, payment_request = await create_invoice( wallet_id=shop.wallet, diff --git a/lnbits/extensions/offlineshop/migrations.py b/lnbits/extensions/offlineshop/migrations.py index f7c2dfec8..2d86a644a 100644 --- a/lnbits/extensions/offlineshop/migrations.py +++ b/lnbits/extensions/offlineshop/migrations.py @@ -27,3 +27,6 @@ async def m001_initial(db): ); """ ) + +async def m002_store_fiat_in_cents(db): + await db.execute("UPDATE offlineshop.items SET price = (price * 1000) WHERE unit NOT LIKE 'sat'") diff --git a/lnbits/extensions/offlineshop/static/js/index.js b/lnbits/extensions/offlineshop/static/js/index.js index 00e932416..7be1b26ff 100644 --- a/lnbits/extensions/offlineshop/static/js/index.js +++ b/lnbits/extensions/offlineshop/static/js/index.js @@ -31,7 +31,7 @@ new Vue({ computed: { printItems() { return this.offlineshop.items.filter(({enabled}) => enabled) - } + }, }, methods: { openNewDialog() { @@ -119,6 +119,9 @@ new Vue({ }, async sendItem() { let {id, name, image, description, price, unit} = this.itemDialog.data + //convert fiat price to milli (int) + price = unit == 'sat' ? price : price * 1000 + const data = { name, description, diff --git a/lnbits/extensions/offlineshop/views.py b/lnbits/extensions/offlineshop/views.py index 748d20240..fb7711667 100644 --- a/lnbits/extensions/offlineshop/views.py +++ b/lnbits/extensions/offlineshop/views.py @@ -3,17 +3,17 @@ from datetime import datetime from http import HTTPStatus from typing import List +from fastapi import HTTPException, Request from fastapi.params import Depends, Query from starlette.responses import HTMLResponse -from lnbits.decorators import check_user_exists -from lnbits.core.models import Payment, User from lnbits.core.crud import get_standalone_payment +from lnbits.core.models import Payment, User +from lnbits.decorators import check_user_exists from . import offlineshop_ext, offlineshop_renderer -from .models import Item from .crud import get_item, get_shop -from fastapi import Request, HTTPException +from .models import Item @offlineshop_ext.get("/", response_class=HTMLResponse) @@ -29,6 +29,8 @@ async def print_qr_codes(request: Request, items: List[int] = None): for item_id in request.query_params.get("items").split(","): item = await get_item(item_id) # type: Item if item: + if item.unit != 'sat': + item.price = (item.price / 1000) items.append( { "lnurl": item.lnurl(request), diff --git a/lnbits/extensions/offlineshop/views_api.py b/lnbits/extensions/offlineshop/views_api.py index 906526517..afb7d7ee3 100644 --- a/lnbits/extensions/offlineshop/views_api.py +++ b/lnbits/extensions/offlineshop/views_api.py @@ -27,7 +27,7 @@ from .models import ShopCounter @offlineshop_ext.get("/api/v1/currencies") async def api_list_currencies_available(): - return json.dumps(list(currencies.keys())) + return list(currencies.keys()) @offlineshop_ext.get("/api/v1/offlineshop") @@ -37,7 +37,12 @@ async def api_shop_from_wallet( ): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) items = await get_items(shop.id) - + + #revert millicents to unit + for item in items: + if item.unit != 'sat': + item.price = item.price / 1000 + try: return { **shop.dict(), @@ -60,11 +65,11 @@ class CreateItemsData(BaseModel): @offlineshop_ext.post("/api/v1/offlineshop/items") @offlineshop_ext.put("/api/v1/offlineshop/items/{item_id}") -# @api_check_wallet_key("invoice") async def api_add_or_update_item( data: CreateItemsData, item_id=None, wallet: WalletTypeInfo = Depends(get_key_type) ): - shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + if item_id == None: await add_item( shop.id, data.name, data.description, data.image, data.price, data.unit