diff --git a/lnbits/extensions/satsdice/README.md b/lnbits/extensions/satsdice/README.md deleted file mode 100644 index c24199300..000000000 --- a/lnbits/extensions/satsdice/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# satsdice - -## Create staic LNURL powered satsdices - -Gambling is dangerous, flip responsibly diff --git a/lnbits/extensions/satsdice/__init__.py b/lnbits/extensions/satsdice/__init__.py deleted file mode 100644 index a13653bf3..000000000 --- a/lnbits/extensions/satsdice/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -from fastapi import APIRouter -from starlette.staticfiles import StaticFiles - -from lnbits.db import Database -from lnbits.helpers import template_renderer - -db = Database("ext_satsdice") - -satsdice_ext: APIRouter = APIRouter(prefix="/satsdice", tags=["satsdice"]) - -satsdice_static_files = [ - { - "path": "/satsdice/static", - "app": StaticFiles(directory="lnbits/extensions/satsdice/static"), - "name": "satsdice_static", - } -] - - -def satsdice_renderer(): - return template_renderer(["lnbits/extensions/satsdice/templates"]) - - -from .lnurl import * # noqa: F401,F403 -from .views import * # noqa: F401,F403 -from .views_api import * # noqa: F401,F403 diff --git a/lnbits/extensions/satsdice/config.json b/lnbits/extensions/satsdice/config.json deleted file mode 100644 index 3f4355fea..000000000 --- a/lnbits/extensions/satsdice/config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Sats Dice", - "short_description": "LNURL Satoshi dice", - "tile": "/satsdice/static/image/satsdice.png", - "contributors": ["arcbtc"] -} diff --git a/lnbits/extensions/satsdice/crud.py b/lnbits/extensions/satsdice/crud.py deleted file mode 100644 index 6aeaf31ff..000000000 --- a/lnbits/extensions/satsdice/crud.py +++ /dev/null @@ -1,279 +0,0 @@ -from datetime import datetime -from typing import List, Optional, Union - -from lnbits.helpers import urlsafe_short_hash - -from . import db -from .models import ( - CreateSatsDiceLink, - CreateSatsDicePayment, - CreateSatsDiceWithdraw, - satsdiceLink, - satsdicePayment, - satsdiceWithdraw, -) - - -async def create_satsdice_pay(wallet_id: str, data: CreateSatsDiceLink) -> satsdiceLink: - satsdice_id = urlsafe_short_hash() - await db.execute( - """ - INSERT INTO satsdice.satsdice_pay ( - id, - wallet, - title, - base_url, - min_bet, - max_bet, - amount, - served_meta, - served_pr, - multiplier, - chance, - haircut, - open_time - ) - VALUES (?, ?, ?, ?, ?, ?, 0, 0, 0, ?, ?, ?, ?) - """, - ( - satsdice_id, - wallet_id, - data.title, - data.base_url, - data.min_bet, - data.max_bet, - data.multiplier, - data.chance, - data.haircut, - int(datetime.now().timestamp()), - ), - ) - link = await get_satsdice_pay(satsdice_id) - assert link, "Newly created link couldn't be retrieved" - return link - - -async def get_satsdice_pay(link_id: str) -> Optional[satsdiceLink]: - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_pay WHERE id = ?", (link_id,) - ) - return satsdiceLink(**row) if row else None - - -async def get_satsdice_pays(wallet_ids: Union[str, List[str]]) -> List[satsdiceLink]: - if isinstance(wallet_ids, str): - wallet_ids = [wallet_ids] - - q = ",".join(["?"] * len(wallet_ids)) - rows = await db.fetchall( - f""" - SELECT * FROM satsdice.satsdice_pay WHERE wallet IN ({q}) - ORDER BY id - """, - (*wallet_ids,), - ) - return [satsdiceLink(**row) for row in rows] - - -async def update_satsdice_pay(link_id: str, **kwargs) -> satsdiceLink: - q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) - await db.execute( - f"UPDATE satsdice.satsdice_pay SET {q} WHERE id = ?", - (*kwargs.values(), link_id), - ) - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_pay WHERE id = ?", (link_id,) - ) - return satsdiceLink(**row) - - -async def increment_satsdice_pay(link_id: str, **kwargs) -> Optional[satsdiceLink]: - q = ", ".join([f"{field[0]} = {field[0]} + ?" for field in kwargs.items()]) - await db.execute( - f"UPDATE satsdice.satsdice_pay SET {q} WHERE id = ?", - (*kwargs.values(), link_id), - ) - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_pay WHERE id = ?", (link_id,) - ) - return satsdiceLink(**row) if row else None - - -async def delete_satsdice_pay(link_id: str) -> None: - await db.execute("DELETE FROM satsdice.satsdice_pay WHERE id = ?", (link_id,)) - - -##################SATSDICE PAYMENT LINKS - - -async def create_satsdice_payment(data: CreateSatsDicePayment) -> satsdicePayment: - await db.execute( - """ - INSERT INTO satsdice.satsdice_payment ( - payment_hash, - satsdice_pay, - value, - paid, - lost - ) - VALUES (?, ?, ?, ?, ?) - """, - ( - data.payment_hash, - data.satsdice_pay, - data.value, - False, - False, - ), - ) - payment = await get_satsdice_payment(data.payment_hash) - assert payment, "Newly created withdraw couldn't be retrieved" - return payment - - -async def get_satsdice_payment(payment_hash: str) -> Optional[satsdicePayment]: - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_payment WHERE payment_hash = ?", - (payment_hash,), - ) - return satsdicePayment(**row) if row else None - - -async def update_satsdice_payment(payment_hash: str, **kwargs) -> satsdicePayment: - q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) - - await db.execute( - f"UPDATE satsdice.satsdice_payment SET {q} WHERE payment_hash = ?", - (bool(*kwargs.values()), payment_hash), - ) - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_payment WHERE payment_hash = ?", - (payment_hash,), - ) - return satsdicePayment(**row) - - -##################SATSDICE WITHDRAW LINKS - - -async def create_satsdice_withdraw(data: CreateSatsDiceWithdraw) -> satsdiceWithdraw: - await db.execute( - """ - INSERT INTO satsdice.satsdice_withdraw ( - id, - satsdice_pay, - value, - unique_hash, - k1, - open_time, - used - ) - VALUES (?, ?, ?, ?, ?, ?, ?) - """, - ( - data.payment_hash, - data.satsdice_pay, - data.value, - urlsafe_short_hash(), - urlsafe_short_hash(), - int(datetime.now().timestamp()), - data.used, - ), - ) - withdraw = await get_satsdice_withdraw(data.payment_hash, 0) - assert withdraw, "Newly created withdraw couldn't be retrieved" - return withdraw - - -async def get_satsdice_withdraw(withdraw_id: str, num=0) -> Optional[satsdiceWithdraw]: - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_withdraw WHERE id = ?", (withdraw_id,) - ) - if not row: - return None - - withdraw = [] - for item in row: - withdraw.append(item) - withdraw.append(num) - return satsdiceWithdraw(**row) - - -async def get_satsdice_withdraw_by_hash( - unique_hash: str, num=0 -) -> Optional[satsdiceWithdraw]: - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_withdraw WHERE unique_hash = ?", (unique_hash,) - ) - if not row: - return None - - withdraw = [] - for item in row: - withdraw.append(item) - withdraw.append(num) - return satsdiceWithdraw(**row) - - -async def get_satsdice_withdraws( - wallet_ids: Union[str, List[str]] -) -> List[satsdiceWithdraw]: - if isinstance(wallet_ids, str): - wallet_ids = [wallet_ids] - - q = ",".join(["?"] * len(wallet_ids)) - rows = await db.fetchall( - f"SELECT * FROM satsdice.satsdice_withdraw WHERE wallet IN ({q})", - (*wallet_ids,), - ) - - return [satsdiceWithdraw(**row) for row in rows] - - -async def update_satsdice_withdraw( - withdraw_id: str, **kwargs -) -> Optional[satsdiceWithdraw]: - q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) - await db.execute( - f"UPDATE satsdice.satsdice_withdraw SET {q} WHERE id = ?", - (*kwargs.values(), withdraw_id), - ) - row = await db.fetchone( - "SELECT * FROM satsdice.satsdice_withdraw WHERE id = ?", (withdraw_id,) - ) - return satsdiceWithdraw(**row) if row else None - - -async def delete_satsdice_withdraw(withdraw_id: str) -> None: - await db.execute( - "DELETE FROM satsdice.satsdice_withdraw WHERE id = ?", (withdraw_id,) - ) - - -async def create_withdraw_hash_check(the_hash: str, lnurl_id: str): - await db.execute( - """ - INSERT INTO satsdice.hash_checkw ( - id, - lnurl_id - ) - VALUES (?, ?) - """, - (the_hash, lnurl_id), - ) - hashCheck = await get_withdraw_hash_checkw(the_hash, lnurl_id) - return hashCheck - - -async def get_withdraw_hash_checkw(the_hash: str, lnurl_id: str): - rowid = await db.fetchone( - "SELECT * FROM satsdice.hash_checkw WHERE id = ?", (the_hash,) - ) - rowlnurl = await db.fetchone( - "SELECT * FROM satsdice.hash_checkw WHERE lnurl_id = ?", (lnurl_id,) - ) - if not rowlnurl or not rowid: - await create_withdraw_hash_check(the_hash, lnurl_id) - return {"lnurl": True, "hash": False} - else: - return {"lnurl": True, "hash": True} diff --git a/lnbits/extensions/satsdice/lnurl.py b/lnbits/extensions/satsdice/lnurl.py deleted file mode 100644 index 2bb590162..000000000 --- a/lnbits/extensions/satsdice/lnurl.py +++ /dev/null @@ -1,156 +0,0 @@ -import json -import math -from http import HTTPStatus - -from fastapi import Request -from fastapi.param_functions import Query -from starlette.exceptions import HTTPException -from starlette.responses import HTMLResponse - -from lnbits.core.services import create_invoice, pay_invoice - -from . import satsdice_ext -from .crud import ( - create_satsdice_payment, - get_satsdice_pay, - get_satsdice_withdraw_by_hash, - update_satsdice_withdraw, -) -from .models import CreateSatsDicePayment - - -@satsdice_ext.get( - "/api/v1/lnurlp/{link_id}", - response_class=HTMLResponse, - name="satsdice.lnurlp_response", -) -async def api_lnurlp_response(req: Request, link_id: str = Query(None)): - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found." - ) - payResponse = { - "tag": "payRequest", - "callback": req.url_for("satsdice.api_lnurlp_callback", link_id=link.id), - "metadata": link.lnurlpay_metadata, - "minSendable": math.ceil(link.min_bet * 1) * 1000, - "maxSendable": round(link.max_bet * 1) * 1000, - } - return json.dumps(payResponse) - - -@satsdice_ext.get( - "/api/v1/lnurlp/cb/{link_id}", - response_class=HTMLResponse, - name="satsdice.api_lnurlp_callback", -) -async def api_lnurlp_callback( - req: Request, link_id: str = Query(None), amount: str = Query(None) -): - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found." - ) - - min, max = link.min_bet, link.max_bet - min = link.min_bet * 1000 - max = link.max_bet * 1000 - - amount_received = int(amount or 0) - if amount_received < min: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, - detail=f"Amount {amount_received} is smaller than minimum {min}.", - ) - elif amount_received > max: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, - detail=f"Amount {amount_received} is greater than maximum {max}.", - ) - - payment_hash, payment_request = await create_invoice( - wallet_id=link.wallet, - amount=int(amount_received / 1000), - memo="Satsdice bet", - unhashed_description=link.lnurlpay_metadata.encode(), - extra={"tag": "satsdice", "link": link.id, "comment": "comment"}, - ) - - success_action = link.success_action(payment_hash=payment_hash, req=req) - - data = CreateSatsDicePayment( - satsdice_pay=link.id, - value=int(amount_received / 1000), - payment_hash=payment_hash, - ) - - await create_satsdice_payment(data) - payResponse: dict = { - "pr": payment_request, - "successAction": success_action, - "routes": [], - } - return json.dumps(payResponse) - - -##############LNURLW STUFF - - -@satsdice_ext.get( - "/api/v1/lnurlw/{unique_hash}", - response_class=HTMLResponse, - name="satsdice.lnurlw_response", -) -async def api_lnurlw_response(req: Request, unique_hash: str = Query(None)): - link = await get_satsdice_withdraw_by_hash(unique_hash) - - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="LNURL-satsdice not found." - ) - if link.used: - raise HTTPException(status_code=HTTPStatus.OK, detail="satsdice is spent.") - url = req.url_for("satsdice.api_lnurlw_callback", unique_hash=link.unique_hash) - withdrawResponse = { - "tag": "withdrawRequest", - "callback": url, - "k1": link.k1, - "minWithdrawable": link.value * 1000, - "maxWithdrawable": link.value * 1000, - "defaultDescription": "Satsdice winnings!", - } - return json.dumps(withdrawResponse) - - -# CALLBACK - - -@satsdice_ext.get( - "/api/v1/lnurlw/cb/{unique_hash}", - status_code=HTTPStatus.OK, - name="satsdice.api_lnurlw_callback", -) -async def api_lnurlw_callback( - unique_hash: str = Query(None), - pr: str = Query(None), -): - - link = await get_satsdice_withdraw_by_hash(unique_hash) - if not link: - return {"status": "ERROR", "reason": "no withdraw"} - if link.used: - return {"status": "ERROR", "reason": "spent"} - paylink = await get_satsdice_pay(link.satsdice_pay) - - if paylink: - await update_satsdice_withdraw(link.id, used=1) - await pay_invoice( - wallet_id=paylink.wallet, - payment_request=pr, - max_sat=link.value, - extra={"tag": "withdraw"}, - ) - - return {"status": "OK"} diff --git a/lnbits/extensions/satsdice/migrations.py b/lnbits/extensions/satsdice/migrations.py deleted file mode 100644 index 82ab35ba7..000000000 --- a/lnbits/extensions/satsdice/migrations.py +++ /dev/null @@ -1,73 +0,0 @@ -async def m001_initial(db): - """ - Creates an improved satsdice table and migrates the existing data. - """ - await db.execute( - f""" - CREATE TABLE satsdice.satsdice_pay ( - id TEXT PRIMARY KEY, - wallet TEXT, - title TEXT, - min_bet INTEGER, - max_bet INTEGER, - amount {db.big_int} DEFAULT 0, - served_meta INTEGER NOT NULL, - served_pr INTEGER NOT NULL, - multiplier FLOAT, - haircut FLOAT, - chance FLOAT, - base_url TEXT, - open_time INTEGER - ); - """ - ) - - -async def m002_initial(db): - """ - Creates an improved satsdice table and migrates the existing data. - """ - await db.execute( - f""" - CREATE TABLE satsdice.satsdice_withdraw ( - id TEXT PRIMARY KEY, - satsdice_pay TEXT, - value {db.big_int} DEFAULT 1, - unique_hash TEXT UNIQUE, - k1 TEXT, - open_time INTEGER, - used INTEGER DEFAULT 0 - ); - """ - ) - - -async def m003_initial(db): - """ - Creates an improved satsdice table and migrates the existing data. - """ - await db.execute( - f""" - CREATE TABLE satsdice.satsdice_payment ( - payment_hash TEXT PRIMARY KEY, - satsdice_pay TEXT, - value {db.big_int}, - paid BOOL DEFAULT FALSE, - lost BOOL DEFAULT FALSE - ); - """ - ) - - -async def m004_make_hash_check(db): - """ - Creates a hash check table. - """ - await db.execute( - """ - CREATE TABLE satsdice.hash_checkw ( - id TEXT PRIMARY KEY, - lnurl_id TEXT - ); - """ - ) diff --git a/lnbits/extensions/satsdice/models.py b/lnbits/extensions/satsdice/models.py deleted file mode 100644 index 510b7bde0..000000000 --- a/lnbits/extensions/satsdice/models.py +++ /dev/null @@ -1,134 +0,0 @@ -import json -from sqlite3 import Row -from typing import Dict, Optional - -from fastapi import Request -from fastapi.param_functions import Query -from lnurl import Lnurl -from lnurl import encode as lnurl_encode -from lnurl.types import LnurlPayMetadata -from pydantic import BaseModel - - -class satsdiceLink(BaseModel): - id: str - wallet: str - title: str - min_bet: int - max_bet: int - amount: int - served_meta: int - served_pr: int - multiplier: float - haircut: float - chance: float - base_url: str - open_time: int - - def lnurl(self, req: Request) -> str: - return lnurl_encode(req.url_for("satsdice.lnurlp_response", link_id=self.id)) - - @classmethod - def from_row(cls, row: Row) -> "satsdiceLink": - data = dict(row) - return cls(**data) - - @property - def lnurlpay_metadata(self) -> LnurlPayMetadata: - return LnurlPayMetadata( - json.dumps( - [ - [ - "text/plain", - f"{self.title} (Chance: {self.chance}%, Multiplier: {self.multiplier})", - ] - ] - ) - ) - - def success_action(self, payment_hash: str, req: Request) -> Optional[Dict]: - url = req.url_for( - "satsdice.displaywin", link_id=self.id, payment_hash=payment_hash - ) - return {"tag": "url", "description": "Check the attached link", "url": url} - - -class satsdicePayment(BaseModel): - payment_hash: str - satsdice_pay: str - value: int - paid: bool - lost: bool - - -class satsdiceWithdraw(BaseModel): - id: str - satsdice_pay: str - value: int - unique_hash: str - k1: str - open_time: int - used: int - - def lnurl(self, req: Request) -> Lnurl: - return lnurl_encode( - req.url_for("satsdice.lnurlw_response", unique_hash=self.unique_hash) - ) - - @property - def is_spent(self) -> bool: - return self.used >= 1 - - def lnurl_response(self, req: Request): - url = req.url_for("satsdice.api_lnurlw_callback", unique_hash=self.unique_hash) - withdrawResponse = { - "tag": "withdrawRequest", - "callback": url, - "k1": self.k1, - "minWithdrawable": self.value * 1000, - "maxWithdrawable": self.value * 1000, - "defaultDescription": "Satsdice winnings!", - } - return withdrawResponse - - -class HashCheck(BaseModel): - id: str - lnurl_id: str - - @classmethod - def from_row(cls, row: Row): - return cls(**dict(row)) - - -class CreateSatsDiceLink(BaseModel): - wallet: str = Query(None) - title: str = Query(None) - base_url: str = Query(None) - min_bet: str = Query(None) - max_bet: str = Query(None) - multiplier: float = Query(0) - chance: float = Query(0) - haircut: int = Query(0) - - -class CreateSatsDicePayment(BaseModel): - satsdice_pay: str = Query(None) - value: int = Query(0) - payment_hash: str = Query(None) - - -class CreateSatsDiceWithdraw(BaseModel): - payment_hash: str = Query(None) - satsdice_pay: str = Query(None) - value: int = Query(0) - used: int = Query(0) - - -class CreateSatsDiceWithdraws(BaseModel): - title: str = Query(None) - min_satsdiceable: int = Query(0) - max_satsdiceable: int = Query(0) - uses: int = Query(0) - wait_time: str = Query(None) - is_unique: bool = Query(False) diff --git a/lnbits/extensions/satsdice/static/image/satsdice.png b/lnbits/extensions/satsdice/static/image/satsdice.png deleted file mode 100644 index 8c7ccaf96..000000000 Binary files a/lnbits/extensions/satsdice/static/image/satsdice.png and /dev/null differ diff --git a/lnbits/extensions/satsdice/templates/satsdice/_api_docs.html b/lnbits/extensions/satsdice/templates/satsdice/_api_docs.html deleted file mode 100644 index e85e9586c..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/_api_docs.html +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - GET /satsdice/api/v1/links -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 200 OK (application/json) -
- [<satsdice_link_object>, ...] -
Curl example
- curl -X GET {{ request.base_url }}satsdice/api/v1/links -H - "X-Api-Key: {{ user.wallets[0].inkey }}" - -
-
-
- - - - GET - /satsdice/api/v1/links/<satsdice_id> -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 201 CREATED (application/json) -
- {"lnurl": <string>} -
Curl example
- curl -X GET {{ request.base_url - }}satsdice/api/v1/links/<satsdice_id> -H "X-Api-Key: {{ - user.wallets[0].inkey }}" - -
-
-
- - - - POST /satsdice/api/v1/links -
Headers
- {"X-Api-Key": <admin_key>}
-
Body (application/json)
- {"title": <string>, "min_satsdiceable": <integer>, - "max_satsdiceable": <integer>, "uses": <integer>, - "wait_time": <integer>, "is_unique": <boolean>} -
- Returns 201 CREATED (application/json) -
- {"lnurl": <string>} -
Curl example
- curl -X POST {{ request.base_url }}satsdice/api/v1/links -d - '{"title": <string>, "min_satsdiceable": <integer>, - "max_satsdiceable": <integer>, "uses": <integer>, - "wait_time": <integer>, "is_unique": <boolean>}' -H - "Content-type: application/json" -H "X-Api-Key: {{ - user.wallets[0].adminkey }}" - -
-
-
- - - - PUT - /satsdice/api/v1/links/<satsdice_id> -
Headers
- {"X-Api-Key": <admin_key>}
-
Body (application/json)
- {"title": <string>, "min_satsdiceable": <integer>, - "max_satsdiceable": <integer>, "uses": <integer>, - "wait_time": <integer>, "is_unique": <boolean>} -
- Returns 200 OK (application/json) -
- {"lnurl": <string>} -
Curl example
- curl -X PUT {{ request.base_url - }}satsdice/api/v1/links/<satsdice_id> -d '{"title": - <string>, "min_satsdiceable": <integer>, - "max_satsdiceable": <integer>, "uses": <integer>, - "wait_time": <integer>, "is_unique": <boolean>}' -H - "Content-type: application/json" -H "X-Api-Key: {{ - user.wallets[0].adminkey }}" - -
-
-
- - - - DELETE - /satsdice/api/v1/links/<satsdice_id> -
Headers
- {"X-Api-Key": <admin_key>}
-
Returns 204 NO CONTENT
- -
Curl example
- curl -X DELETE {{ request.base_url - }}satsdice/api/v1/links/<satsdice_id> -H "X-Api-Key: {{ - user.wallets[0].adminkey }}" - -
-
-
- - - - GET - /satsdice/api/v1/links/<the_hash>/<lnurl_id> -
Headers
- {"X-Api-Key": <invoice_key>}
-
Body (application/json)
-
- Returns 201 CREATED (application/json) -
- {"status": <bool>} -
Curl example
- curl -X GET {{ request.base_url - }}satsdice/api/v1/links/<the_hash>/<lnurl_id> -H - "X-Api-Key: {{ user.wallets[0].inkey }}" - -
-
-
- - - - GET - /satsdice/img/<lnurl_id> -
Curl example
- curl -X GET {{ request.base_url }}satsdice/img/<lnurl_id>" - -
-
-
-
diff --git a/lnbits/extensions/satsdice/templates/satsdice/_lnurl.html b/lnbits/extensions/satsdice/templates/satsdice/_lnurl.html deleted file mode 100644 index 750fb5869..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/_lnurl.html +++ /dev/null @@ -1,32 +0,0 @@ - - - -

- WARNING: LNURL must be used over https or TOR
- LNURL is a range of lightning-network standards that allow us to use - lightning-network differently. An LNURL satsdice is the permission for - someone to pull a certain amount of funds from a lightning wallet. In - this extension time is also added - an amount can be satsdice over a - period of time. A typical use case for an LNURL satsdice is a faucet, - although it is a very powerful technology, with much further reaching - implications. For example, an LNURL satsdice could be minted to pay for - a subscription service. -

-

- Exploring LNURL and finding use cases, is really helping inform - lightning protocol development, rather than the protocol dictating how - lightning-network should be engaged with. -

- Check - Awesome LNURL - for further information. -
-
-
diff --git a/lnbits/extensions/satsdice/templates/satsdice/display.html b/lnbits/extensions/satsdice/templates/satsdice/display.html deleted file mode 100644 index 56e7ebe6e..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/display.html +++ /dev/null @@ -1,63 +0,0 @@ -{% extends "public.html" %} {% block page %} -
-
- - - -
- Copy Satsdice LNURL -
-
-
-
-
- - -
- Chance of winning: {% raw %}{{ chance }}{% endraw %}, Amount - multiplier: {{ multiplier }} -
-

- Use a LNURL compatible bitcoin wallet to play the satsdice. -

-
- - - {% include "satsdice/_lnurl.html" %} - -
-
-
-{% endblock %} {% block scripts %} - -{% endblock %} diff --git a/lnbits/extensions/satsdice/templates/satsdice/displaywin.html b/lnbits/extensions/satsdice/templates/satsdice/displaywin.html deleted file mode 100644 index f3ce36d56..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/displaywin.html +++ /dev/null @@ -1,56 +0,0 @@ -{% extends "public.html" %} {% block page %} -
-
- - - -
- Copy winnings LNURL -
-
-
-
-
- - -
- Congrats! You have won {{ value }}sats (you must claim the sats now) -
-

- Use a LNURL compatible bitcoin wallet to play the satsdice. -

-
- - - {% include "satsdice/_lnurl.html" %} - -
-
-
-{% endblock %} {% block scripts %} - -{% endblock %} diff --git a/lnbits/extensions/satsdice/templates/satsdice/error.html b/lnbits/extensions/satsdice/templates/satsdice/error.html deleted file mode 100644 index 63f726d56..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/error.html +++ /dev/null @@ -1,54 +0,0 @@ -{% extends "public.html" %} {% from "macros.jinja" import window_vars with -context %}{% block page %} -
-
- - -
- {% if lost %} -
- You lost. - Play again? -
- {% endif %} {% if paid %} -
- Winnings spent. - Play again? -
- {% endif %} -
- -
-
-
-
-
-
-{% endblock %} {% block scripts %}{{ window_vars(user) }} - -{% endblock %} diff --git a/lnbits/extensions/satsdice/templates/satsdice/index.html b/lnbits/extensions/satsdice/templates/satsdice/index.html deleted file mode 100644 index 277442734..000000000 --- a/lnbits/extensions/satsdice/templates/satsdice/index.html +++ /dev/null @@ -1,534 +0,0 @@ -{% extends "base.html" %} {% from "macros.jinja" import window_vars with context -%} {% block page %} -
-
- - - New satsdice - - - - - -
-
-
satsdices
-
-
- - {% raw %} - - - {% endraw %} - -
-
-
- -
- - -
- {{SITE_TITLE}} Sats Dice extension -
-
- - - - {% include "satsdice/_api_docs.html" %} - - {% include "satsdice/_lnurl.html" %} - - -
-
- - - - - - - {% raw %} - - -
-
- -
-
- -
-
- - -
- - Multipler: x{{ multiValue }}, Chance of winning: {{ chanceValueCalc - | percent }} - - - -
- -
- Update flip link - Create satsdice - Cancel -
-
-
-
- - - - - - -

- ID: {{ qrCodeDialog.data.id }}
- Amount: {{ qrCodeDialog.data.amount }}
- {{ qrCodeDialog.data.currency }} price: {{ - fiatRates[qrCodeDialog.data.currency] ? - fiatRates[qrCodeDialog.data.currency] + ' sat' : 'Loading...' }}
- Accepts comments: {{ qrCodeDialog.data.comments }}
- Dispatches webhook to: {{ qrCodeDialog.data.webhook - }}
- On success: {{ qrCodeDialog.data.success }}
-

- {% endraw %} -
- Copy Satsdice LNURL - Copy shareable link - - Launch shareable link - Print Satsdice - Close -
-
-
-
- -{% endblock %} {% block scripts %} {{ window_vars(user) }} - - -{% endblock %} diff --git a/lnbits/extensions/satsdice/views.py b/lnbits/extensions/satsdice/views.py deleted file mode 100644 index e51c1e103..000000000 --- a/lnbits/extensions/satsdice/views.py +++ /dev/null @@ -1,147 +0,0 @@ -import random -from http import HTTPStatus -from io import BytesIO - -import pyqrcode -from fastapi import Depends, Query, Request -from fastapi.templating import Jinja2Templates -from starlette.exceptions import HTTPException -from starlette.responses import HTMLResponse - -from lnbits.core.models import User -from lnbits.core.views.api import api_payment -from lnbits.decorators import check_user_exists - -from . import satsdice_ext, satsdice_renderer -from .crud import ( - create_satsdice_withdraw, - get_satsdice_pay, - get_satsdice_payment, - get_satsdice_withdraw, - update_satsdice_payment, -) -from .models import CreateSatsDiceWithdraw - -templates = Jinja2Templates(directory="templates") - - -@satsdice_ext.get("/", response_class=HTMLResponse) -async def index(request: Request, user: User = Depends(check_user_exists)): - return satsdice_renderer().TemplateResponse( - "satsdice/index.html", {"request": request, "user": user.dict()} - ) - - -@satsdice_ext.get("/{link_id}", response_class=HTMLResponse) -async def display(request: Request, link_id: str = Query(None)): - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="satsdice link does not exist." - ) - - return satsdice_renderer().TemplateResponse( - "satsdice/display.html", - { - "request": request, - "chance": link.chance, - "multiplier": link.multiplier, - "lnurl": link.lnurl(request), - "unique": True, - }, - ) - - -@satsdice_ext.get( - "/win/{link_id}/{payment_hash}", - name="satsdice.displaywin", - response_class=HTMLResponse, -) -async def displaywin( - request: Request, link_id: str = Query(None), payment_hash: str = Query(None) -): - satsdicelink = await get_satsdice_pay(link_id) - if not satsdicelink: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="satsdice link does not exist." - ) - withdrawLink = await get_satsdice_withdraw(payment_hash) - payment = await get_satsdice_payment(payment_hash) - if not payment or payment.lost: - return satsdice_renderer().TemplateResponse( - "satsdice/error.html", - {"request": request, "link": satsdicelink.id, "paid": False, "lost": True}, - ) - if withdrawLink: - return satsdice_renderer().TemplateResponse( - "satsdice/displaywin.html", - { - "request": request, - "value": withdrawLink.value, - "chance": satsdicelink.chance, - "multiplier": satsdicelink.multiplier, - "lnurl": withdrawLink.lnurl(request), - "paid": False, - "lost": False, - }, - ) - rand = random.randint(0, 100) - chance = satsdicelink.chance - status = await api_payment(payment_hash) - if not rand < chance or not status["paid"]: - await update_satsdice_payment(payment_hash, lost=1) - return satsdice_renderer().TemplateResponse( - "satsdice/error.html", - {"request": request, "link": satsdicelink.id, "paid": False, "lost": True}, - ) - await update_satsdice_payment(payment_hash, paid=1) - paylink = await get_satsdice_payment(payment_hash) - if not paylink: - return satsdice_renderer().TemplateResponse( - "satsdice/error.html", - {"request": request, "link": satsdicelink.id, "paid": False, "lost": True}, - ) - - data = CreateSatsDiceWithdraw( - satsdice_pay=satsdicelink.id, - value=int(paylink.value * satsdicelink.multiplier), - payment_hash=payment_hash, - used=0, - ) - - withdrawLink = await create_satsdice_withdraw(data) - return satsdice_renderer().TemplateResponse( - "satsdice/displaywin.html", - { - "request": request, - "value": withdrawLink.value, - "chance": satsdicelink.chance, - "multiplier": satsdicelink.multiplier, - "lnurl": withdrawLink.lnurl(request), - "paid": False, - "lost": False, - }, - ) - - -@satsdice_ext.get("/img/{link_id}", response_class=HTMLResponse) -async def img(link_id): - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="satsdice link does not exist." - ) - - qr = pyqrcode.create(link.lnurl) - stream = BytesIO() - qr.svg(stream, scale=3) - return ( - stream.getvalue(), - 200, - { - "Content-Type": "image/svg+xml", - "Cache-Control": "no-cache, no-store, must-revalidate", - "Pragma": "no-cache", - "Expires": "0", - }, - ) diff --git a/lnbits/extensions/satsdice/views_api.py b/lnbits/extensions/satsdice/views_api.py deleted file mode 100644 index 57ab26b84..000000000 --- a/lnbits/extensions/satsdice/views_api.py +++ /dev/null @@ -1,129 +0,0 @@ -from http import HTTPStatus - -from fastapi import Depends, Query, Request -from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl -from starlette.exceptions import HTTPException - -from lnbits.core.crud import get_user -from lnbits.decorators import WalletTypeInfo, get_key_type - -from . import satsdice_ext -from .crud import ( - create_satsdice_pay, - delete_satsdice_pay, - get_satsdice_pay, - get_satsdice_pays, - get_withdraw_hash_checkw, - update_satsdice_pay, -) -from .models import CreateSatsDiceLink - -################LNURL pay - - -@satsdice_ext.get("/api/v1/links") -async def api_links( - request: Request, - wallet: WalletTypeInfo = Depends(get_key_type), - all_wallets: bool = Query(False), -): - wallet_ids = [wallet.wallet.id] - - if all_wallets: - user = await get_user(wallet.wallet.user) - if user: - wallet_ids = user.wallet_ids - - try: - links = await get_satsdice_pays(wallet_ids) - - return [{**link.dict(), **{"lnurl": link.lnurl(request)}} for link in links] - except LnurlInvalidUrl: - raise HTTPException( - status_code=HTTPStatus.UPGRADE_REQUIRED, - detail="LNURLs need to be delivered over a publically accessible `https` domain or Tor.", - ) - - -@satsdice_ext.get("/api/v1/links/{link_id}") -async def api_link_retrieve( - link_id: str = Query(None), wallet: WalletTypeInfo = Depends(get_key_type) -): - link = await get_satsdice_pay(link_id) - - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist." - ) - - if link.wallet != wallet.wallet.id: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="Not your pay link." - ) - - return {**link.dict(), **{"lnurl": link.lnurl}} - - -@satsdice_ext.post("/api/v1/links", status_code=HTTPStatus.CREATED) -@satsdice_ext.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) -async def api_link_create_or_update( - data: CreateSatsDiceLink, - wallet: WalletTypeInfo = Depends(get_key_type), - link_id: str = Query(None), -): - if data.min_bet > data.max_bet: - raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="Bad request") - if link_id: - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Satsdice does not exist" - ) - - if link.wallet != wallet.wallet.id: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, - detail="Come on, seriously, this isn't your satsdice!", - ) - - data.wallet = wallet.wallet.id - link = await update_satsdice_pay(link_id, **data.dict()) - else: - link = await create_satsdice_pay(wallet_id=wallet.wallet.id, data=data) - - return {**link.dict(), **{"lnurl": link.lnurl}} - - -@satsdice_ext.delete("/api/v1/links/{link_id}") -async def api_link_delete( - wallet: WalletTypeInfo = Depends(get_key_type), - link_id: str = Query(None), -): - link = await get_satsdice_pay(link_id) - if not link: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="Pay link does not exist." - ) - - if link.wallet != wallet.wallet.id: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="Not your pay link." - ) - - await delete_satsdice_pay(link_id) - - return "", HTTPStatus.NO_CONTENT - - -##########LNURL withdraw - - -@satsdice_ext.get( - "/api/v1/withdraws/{the_hash}/{lnurl_id}", dependencies=[Depends(get_key_type)] -) -async def api_withdraw_hash_retrieve( - lnurl_id: str = Query(None), - the_hash: str = Query(None), -): - hashCheck = await get_withdraw_hash_checkw(the_hash, lnurl_id) - return hashCheck