From 0da40bd5b715ecff3d2a570d301192d1a4e24be5 Mon Sep 17 00:00:00 2001 From: Arc Date: Tue, 19 Nov 2024 12:27:56 +0000 Subject: [PATCH 1/5] initial --- crud.py | 81 ++++++++++++++----------------------------------------- models.py | 10 ++++++- 2 files changed, 29 insertions(+), 62 deletions(-) diff --git a/crud.py b/crud.py index 806cbf2..0ae3cfe 100644 --- a/crud.py +++ b/crud.py @@ -4,72 +4,31 @@ from typing import List, Optional from lnbits.db import Database from .execution_queue import enqueue -from .models import NWCBudget, NWCKey, NWCNewBudget +from .models import NWCBudget, NWCKey, CreateNWCKey db = Database("ext_nwcprovider") - -async def create_nwc( - pubkey: str, - wallet_id: str, - description: str, - expires_at: int, - permissions: List[str], - budgets: Optional[List[NWCNewBudget]] = None, -) -> NWCKey: - # Check if the key already exists - if await get_nwc(pubkey, None, True): - raise Exception("Public key already used") - # If not, create it - now = int(time.time()) - await db.execute( - """ - INSERT INTO nwcprovider.keys ( - pubkey, - wallet, - description, - permissions, - created_at, - expires_at, - last_used - ) - VALUES (?, ?, ?, ?, ?, ?, ?) - """, - ( - pubkey, - wallet_id, - description, - " ".join(permissions), - now, - int(expires_at) if expires_at else 0, - now, - ), +async def create_nwc(data: CreateNWCKey) -> NWCKey: + nwckey_entry = NWCKey( + pubkey=data.pubkey, + wallet=data.wallet_id, + description=data.description, + expires_at=int(data.expires_at) if data.expires_at else 0, + permissions=" ".join(data.permissions), + created_at=int(time.time()), + last_used=int(time.time()), ) - # Add budgets - if budgets: - for budget in budgets: - await db.execute( - """ - INSERT INTO nwcprovider.budgets ( - pubkey, - budget_msats, - refresh_window, - created_at - ) - VALUES (?, ?, ?, ?) - """, - (pubkey, budget.budget_msats, budget.refresh_window, budget.created_at), + await db.insert("nwcprovider.keys", nwckey_entry) + if data.budgets: + for budget in data.budgets: + budget_entry = NWCKey( + pubkey=data.pubkey, + budget_msats=budget.budget_msats, + refresh_window=budget.refresh_window, + created_at=budget.created_at ) - # Return the created key - return NWCKey( - pubkey=pubkey, - wallet=wallet_id, - description=description, - expires_at=expires_at, - permissions=" ".join(permissions), - created_at=now, - last_used=now, - ) + await db.insert("nwcprovider.budgets", budget_entry) + return NWCKey(**data.dict()) async def delete_nwc(pubkey: str, wallet_id: str): diff --git a/models.py b/models.py index 83f0b2a..dae61af 100644 --- a/models.py +++ b/models.py @@ -2,7 +2,7 @@ import time from sqlite3 import Row -from typing import Any, Dict, List +from typing import Any, Dict, List, Optional from pydantic import BaseModel @@ -79,3 +79,11 @@ class NWCRegistrationRequest(BaseModel): class NWCGetResponse(BaseModel): data: NWCKey budgets: List[NWCBudget] + +class CreateNWCKey(BaseModel): + pubkey: str + wallet_id: str + description: str + expires_at: int + permissions: List[str] + budgets: Optional[List[NWCNewBudget]] = None \ No newline at end of file From 9503a909ebbd6a66eba32630dbf3cb9757f42e66 Mon Sep 17 00:00:00 2001 From: Arc Date: Tue, 19 Nov 2024 13:18:17 +0000 Subject: [PATCH 2/5] fixup crud and models --- crud.py | 116 ++++++++++++++++++++++++++++-------------------------- models.py | 21 ++++++++++ 2 files changed, 81 insertions(+), 56 deletions(-) diff --git a/crud.py b/crud.py index 0ae3cfe..d66d50e 100644 --- a/crud.py +++ b/crud.py @@ -4,7 +4,16 @@ from typing import List, Optional from lnbits.db import Database from .execution_queue import enqueue -from .models import NWCBudget, NWCKey, CreateNWCKey +from .models import ( + NWCBudget, + NWCKey, + CreateNWCKey, + GetNWCKey, + GetWalletNWCKey, + GetBudgetsNWC, + TrackedSpendNWC, + DeleteNWC +) db = Database("ext_nwcprovider") @@ -30,46 +39,35 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey: await db.insert("nwcprovider.budgets", budget_entry) return NWCKey(**data.dict()) - -async def delete_nwc(pubkey: str, wallet_id: str): - nwc = await get_nwc(pubkey, wallet_id) - if not nwc: - raise Exception("Public key does not exist") +async def delete_nwc(data:DeleteNWC) -> None: await db.execute( - """ - DELETE FROM nwcprovider.keys WHERE pubkey = ? AND wallet = ? - """, - (pubkey, wallet_id), + "DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet", {"pubkey": data.pubkey, "wallet": data.wallet_id} ) - -async def get_wallet_nwcs( - wallet_id: str, include_expired: Optional[bool] = False -) -> List[NWCKey]: - rows = await db.fetchall( +async def get_wallet_nwcs(data: GetWalletNWCKey) -> List[NWCKey]: + return await db.fetchall( """ - SELECT * FROM nwcprovider.keys - WHERE wallet = ? AND (expires_at = 0 OR expires_at > ?) - """, - (wallet_id, int(time.time()) if not include_expired else -1), + SELECT * FROM nwcprovider.keys + WHERE wallet = :wallet AND (expires_at = 0 OR expires_at > :expires) + """, + {"wallet": data.wallet_id, "expires": int(time.time()) if not data.include_expired else -1}, + model=NWCKey, ) - return [NWCKey(**row) for row in rows] - async def get_nwc( - pubkey: str, - wallet_id: Optional[str] = None, - include_expired: Optional[bool] = False, - refresh_last_used: Optional[bool] = False, + data: GetNWCKey ) -> Optional[NWCKey]: # expires_at = 0 means it never expires - if wallet_id: + if data.wallet_id: row = await db.fetchone( """ - SELECT * FROM nwcprovider.keys - WHERE pubkey = ? AND wallet = ? AND (expires_at = 0 OR expires_at > ?) + SELECT * FROM nwcprovider.keys + WHERE pubkey = :pubkey AND wallet = :wallet + AND (expires_at = 0 OR expires_at > :expires) """, - (pubkey, wallet_id, int(time.time()) if not include_expired else -1), + {"pubkey": data.pubkey, "wallet": data.wallet_id, + "expires": int(time.time()) if not data.include_expired else -1}, + NWCKey, ) else: row = await db.fetchone( @@ -77,44 +75,52 @@ async def get_nwc( SELECT * FROM nwcprovider.keys WHERE pubkey = ? AND (expires_at = 0 OR expires_at > ?) """, - (pubkey, int(time.time()) if not include_expired else -1), + (data.pubkey, int(time.time()) if not data.include_expired else -1), + ) + row = await db.fetchone( + """ + SELECT * FROM nwcprovider.keys + WHERE pubkey = :pubkey AND (expires_at = 0 OR expires_at > :expires) + """, + {"pubkey": data.pubkey, "expires": int(time.time()) if not data.include_expired else -1}, + NWCKey, ) if not row: return None - if refresh_last_used: + if data.refresh_last_used: await db.execute( """ - UPDATE nwcprovider.keys SET last_used = ? WHERE pubkey = ? + UPDATE nwcprovider.keys SET last_used = :last_used WHERE pubkey = :pubkey """, - (int(time.time()), pubkey), + {"last_used":int(time.time()), "pubkey":data.pubkey}, ) return NWCKey(**row) -async def get_budgets_nwc(pubkey, calculate_spent=False): +async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: rows = await db.fetchall( - "SELECT * FROM nwcprovider.budgets WHERE pubkey = ?", (pubkey) + "SELECT * FROM nwcprovider.budgets WHERE pubkey = :pubkey", {"pubkey":data.pubkey} ) budgets = [NWCBudget(**row) for row in rows] - if calculate_spent: + if data.calculate_spent: for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() tot_spent_in_range_msats = await db.fetchone( """ SELECT SUM(amount_msats) FROM nwcprovider.spent - WHERE pubkey = ? AND created_at >= ? AND created_at < ? + WHERE pubkey = :pubkey AND created_at >= :last_cycle AND created_at < next_cycle """, - (pubkey, last_cycle, next_cycle), + {"pubkey":data.pubkey, "last_cycle":last_cycle, "next_cycle":next_cycle}, ) tot_spent_in_range_msats = tot_spent_in_range_msats[0] or 0 budget.used_budget_msats = tot_spent_in_range_msats return budgets -async def tracked_spend_nwc(pubkey: str, amount_msats: int, action): +async def tracked_spend_nwc(data:TrackedSpendNWC, action): async def r(): created_at = int(time.time()) - budgets = await get_budgets_nwc(pubkey) + budgets = await get_budgets_nwc(data.pubkey) in_budget = True for budget in budgets: last_cycle, next_cycle = budget.get_timestamp_range() @@ -123,14 +129,14 @@ async def tracked_spend_nwc(pubkey: str, amount_msats: int, action): await db.fetchone( """ SELECT SUM(amount_msats) FROM nwcprovider.spent - WHERE pubkey = ? AND created_at >= ? AND created_at < ? + WHERE pubkey = :pubkey AND created_at >= :last_cycle AND created_at < :next_cycle """, - (pubkey, last_cycle, next_cycle), + {"pubkey":data.pubkey, "last_cycle":last_cycle, "next_cycle":next_cycle}, ) )[0] or 0 ) - if tot_spent_in_range_msats + amount_msats > budget.budget_msats: + if tot_spent_in_range_msats + data.amount_msats > budget.budget_msats: in_budget = False break if not in_budget: @@ -139,9 +145,9 @@ async def tracked_spend_nwc(pubkey: str, amount_msats: int, action): await db.execute( """ INSERT INTO nwcprovider.spent (pubkey, amount_msats, created_at) - VALUES (?, ?, ?) + VALUES (:pubkey, :amount_msats, :created_at) """, - (pubkey, amount_msats, created_at), + {"pubkey":data.pubkey, "amount_msats":data.amount_msats, "created_at":created_at}, ) return True, out @@ -149,29 +155,27 @@ async def tracked_spend_nwc(pubkey: str, amount_msats: int, action): async def get_config_nwc(key: str): - row = await db.fetchone("SELECT * FROM nwcprovider.config WHERE key = ?", (key,)) + row = await db.fetchone("SELECT * FROM nwcprovider.config WHERE key = :key", {"key":key}) if not row: return None return row["value"] - -async def get_all_config_nwc(): - rows = await db.fetchall("SELECT * FROM nwcprovider.config") - return {row["key"]: row["value"] for row in rows} - - async def set_config_nwc(key: str, value: str): await db.execute( """ DELETE FROM nwcprovider.config - WHERE key = ? + WHERE key = :key """, - (key,), + {"key":key}, ) await db.execute( """ INSERT INTO nwcprovider.config (key, value) - VALUES (?, ?) + VALUES (:key, :value) """, - (key, value), + {"key":key, "value":value}, ) + +async def get_all_config_nwc(): + rows = await db.fetchall("SELECT * FROM nwcprovider.config") + return {row["key"]: row["value"] for row in rows} \ No newline at end of file diff --git a/models.py b/models.py index dae61af..b99a52f 100644 --- a/models.py +++ b/models.py @@ -26,6 +26,27 @@ class NWCKey(BaseModel): def from_row(cls, row: Dict[str, Any]) -> "NWCKey": return cls(**row) +class GetNWCKey(BaseModel): + pubkey: str + wallet_id: Optional[str] = None + include_expired: Optional[bool] = False + refresh_last_used: Optional[bool] = False + +class GetWalletNWCKey(BaseModel): + wallet_id: Optional[str] = None + include_expired: Optional[bool] = False + +class GetBudgetsNWC(BaseModel): + pubkey: str + calculate_spent: Optional[bool] = False + +class TrackedSpendNWC(BaseModel): + pubkey: str + amount_msats: int + +class DeleteNWC(BaseModel): + pubkey: str + wallet_id: str class NWCBudget(BaseModel): id: int From 72651991390c12c0a9275d3ebfc89dac9dd99ae2 Mon Sep 17 00:00:00 2001 From: Arc Date: Tue, 19 Nov 2024 13:47:45 +0000 Subject: [PATCH 3/5] views and tasks --- config.json | 2 +- crud.py | 4 +-- models.py | 18 +++++++++++--- tasks.py | 70 ++++++++++++++++++++++++++-------------------------- views_api.py | 67 +++++++++++++++++++++++++++---------------------- 5 files changed, 90 insertions(+), 71 deletions(-) diff --git a/config.json b/config.json index 66d391d..b68048a 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,7 @@ "name": "NWC Service Provider", "short_description": "A NWC service provider for LNbits", "tile": "/nwcprovider/static/image/nwcprovider.png", - "min_lnbits_version": "0.12.5", + "min_lnbits_version": "1.0.0", "contributors": [ { "name": "Riccardo Balbo", diff --git a/crud.py b/crud.py index d66d50e..c68aa0b 100644 --- a/crud.py +++ b/crud.py @@ -9,7 +9,7 @@ from .models import ( NWCKey, CreateNWCKey, GetNWCKey, - GetWalletNWCKey, + GetWalletNWC, GetBudgetsNWC, TrackedSpendNWC, DeleteNWC @@ -44,7 +44,7 @@ async def delete_nwc(data:DeleteNWC) -> None: "DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet", {"pubkey": data.pubkey, "wallet": data.wallet_id} ) -async def get_wallet_nwcs(data: GetWalletNWCKey) -> List[NWCKey]: +async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: return await db.fetchall( """ SELECT * FROM nwcprovider.keys diff --git a/models.py b/models.py index b99a52f..0460427 100644 --- a/models.py +++ b/models.py @@ -5,7 +5,7 @@ from sqlite3 import Row from typing import Any, Dict, List, Optional from pydantic import BaseModel - +from .nwcp import NWCServiceProvider class NWCKey(BaseModel): pubkey: str @@ -32,7 +32,11 @@ class GetNWCKey(BaseModel): include_expired: Optional[bool] = False refresh_last_used: Optional[bool] = False -class GetWalletNWCKey(BaseModel): +class GetNWCs(BaseModel): + include_expired: bool = False + calculate_spent_budget: bool = False + +class GetWalletNWC(BaseModel): wallet_id: Optional[str] = None include_expired: Optional[bool] = False @@ -46,7 +50,12 @@ class TrackedSpendNWC(BaseModel): class DeleteNWC(BaseModel): pubkey: str - wallet_id: str + wallet_id: Optional[str] = None + +class OnInvoicePaid(BaseModel): + sp: NWCServiceProvider + pubkey: str + payload: Dict class NWCBudget(BaseModel): id: int @@ -96,6 +105,9 @@ class NWCRegistrationRequest(BaseModel): expires_at: int budgets: List[NWCNewBudget] +class RegisterNWC(BaseModel): + pubkey: str + registration_data: NWCRegistrationRequest class NWCGetResponse(BaseModel): data: NWCKey diff --git a/tasks.py b/tasks.py index 356bb43..1f03e5f 100644 --- a/tasks.py +++ b/tasks.py @@ -19,12 +19,12 @@ from loguru import logger from .crud import get_config_nwc, get_nwc, tracked_spend_nwc from .execution_queue import execution_queue -from .models import NWCKey +from .models import NWCKey, OnInvoicePaid from .nwcp import NWCServiceProvider from .permission import nwc_permissions -async def _check(nwc: Optional[NWCKey], method: str, payload: Dict) -> Optional[Dict]: +async def _check(nwc: Optional[NWCKey], method: str) -> Optional[Dict]: # check if not nwc: return { @@ -106,15 +106,15 @@ async def _process_invoice( async def _on_pay_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict -) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "pay_invoice", payload) + data:OnInvoicePaid + ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "pay_invoice", data.payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = payload.get("params", {}) + params = data.payload.get("params", {}) invoice = params.get("invoice", None) # Ensures invoice is provided if not invoice: @@ -122,7 +122,7 @@ async def _on_pay_invoice( invoice_data = bolt11_decode(invoice) amount_msats = int(invoice_data.amount_msat or 0) res = await _process_invoice( - nwc.wallet, pubkey, invoice, amount_msats, invoice_data.description + nwc.wallet, data.pubkey, invoice, amount_msats, invoice_data.description ) error = res.get("error") if error: @@ -136,15 +136,15 @@ async def _on_pay_invoice( async def _on_multi_pay_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "multi_pay_invoice", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "multi_pay_invoice", data.payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = payload.get("params", {}) + params = data.payload.get("params", {}) invoices = params.get("invoices", []) results: List[Tuple[Optional[Dict], Optional[Dict], List]] = [] @@ -182,15 +182,15 @@ async def _on_multi_pay_invoice( async def _on_make_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "make_invoice", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "make_invoice", data.payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = payload.get("params", {}) + params = data.payload.get("params", {}) amount_msats = params.get("amount", None) # Ensures amount is provided if not amount_msats: @@ -234,15 +234,15 @@ async def _on_make_invoice( async def _on_lookup_invoice( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "lookup_invoice", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "lookup_invoice", data.payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - params = payload.get("params", {}) + params = data.payload.get("params", {}) payment_hash = params.get("payment_hash", None) invoice = params.get("invoice", None) # Ensure payment_hash or invoice are provided @@ -281,20 +281,20 @@ async def _on_lookup_invoice( async def _on_list_transactions( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "list_transactions", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "list_transactions", data.payload) if error: return [(None, error, [])] if not nwc: raise Exception("Pubkey has no associated wallet") - tfrom = payload.get("from", 0) - tto = payload.get("to", int(time.time())) - limit = payload.get("limit", 10) - offset = payload.get("offset", 0) - unpaid = payload.get("unpaid", False) - tx_type = payload.get("type", None) + tfrom = data.payload.get("from", 0) + tto = data.payload.get("to", int(time.time())) + limit = data.payload.get("limit", 10) + offset = data.payload.get("offset", 0) + unpaid = data.payload.get("unpaid", False) + tx_type = data.payload.get("type", None) values = [] filters: Filters = Filters() filters.where(["time <= ?"]) @@ -337,10 +337,10 @@ async def _on_list_transactions( async def _on_get_balance( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "get_balance", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "get_balance", data.payload) if error: return [(None, error, [])] if not nwc: @@ -355,10 +355,10 @@ async def _on_get_balance( async def _on_get_info( - sp: NWCServiceProvider, pubkey: str, payload: Dict + data:OnInvoicePaid ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: - nwc = await get_nwc(pubkey, None, False, True) - error = await _check(nwc, "get_info", payload) + nwc = await get_nwc(data.pubkey, None, False, True) + error = await _check(nwc, "get_info", data.payload) if error: return [(None, error, [])] if not nwc: diff --git a/views_api.py b/views_api.py index 3db81a6..a961460 100644 --- a/views_api.py +++ b/views_api.py @@ -17,7 +17,15 @@ from .crud import ( get_wallet_nwcs, set_config_nwc, ) -from .models import NWCGetResponse, NWCRegistrationRequest +from .models import ( + NWCGetResponse, + RegisterNWC, + GetWalletNWC, + GetBudgetsNWC, + GetNWCKey, + GetNWCs, + DeleteNWC +) from .permission import nwc_permissions nwcprovider_api_router = APIRouter() @@ -26,7 +34,6 @@ nwcprovider_api_router = APIRouter() # Get supported permissions @nwcprovider_api_router.get("/api/v1/permissions", status_code=HTTPStatus.OK) async def api_get_permissions( - req: Request, wallet: WalletTypeInfo = Depends(require_admin_key), ) -> Dict: return nwc_permissions @@ -37,17 +44,23 @@ async def api_get_permissions( "/api/v1/nwc", status_code=HTTPStatus.OK, response_model=List[NWCGetResponse] ) async def api_get_nwcs( - req: Request, - include_expired: bool = False, - calculate_spent_budget: bool = False, + data: GetNWCs, wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id - nwcs = await get_wallet_nwcs(wallet_id, include_expired) + wallet_nwcs = GetWalletNWC( + wallet_id=wallet_id, + include_expired=data.include_expired + ) + nwcs = await get_wallet_nwcs(wallet_nwcs) out = [] for nwc in nwcs: - budgets = await get_budgets_nwc(nwc.pubkey, calculate_spent_budget) + budgets_nwc = GetBudgetsNWC( + pubkey=nwc.pubkey, + calculate_spent=data.calculate_spent_budget + ) + budgets = await get_budgets_nwc(budgets_nwc) res = NWCGetResponse(data=nwc, budgets=budgets) out.append(res) return out @@ -58,16 +71,14 @@ async def api_get_nwcs( "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse ) async def api_get_nwc( - req: Request, - pubkey: str, - include_expired: Optional[bool] = False, - wallet: WalletTypeInfo = Depends(require_admin_key), -) -> NWCGetResponse: + data:GetNWCKey, + wallet: WalletTypeInfo = Depends(require_admin_key) + ) -> NWCGetResponse: wallet_id = wallet.wallet.id - nwc = await get_nwc(pubkey, wallet_id, include_expired) + nwc = await get_nwc(data.pubkey, wallet_id, data.include_expired) if not nwc: raise Exception("Pubkey has no associated wallet") - res = NWCGetResponse(data=nwc, budgets=await get_budgets_nwc(pubkey)) + res = NWCGetResponse(data=nwc, budgets=await get_budgets_nwc(data.pubkey)) return res @@ -115,21 +126,19 @@ async def api_get_pairing_url(req: Request, secret: str) -> str: response_model=NWCGetResponse, ) async def api_register_nwc( - req: Request, - pubkey: str, - registration_data: NWCRegistrationRequest, # Use the Pydantic model here + data:RegisterNWC, # Use the Pydantic model here wallet: WalletTypeInfo = Depends(require_admin_key), ): wallet_id = wallet.wallet.id nwc = await create_nwc( - pubkey, + data.pubkey, wallet_id, - registration_data.description, - registration_data.expires_at, - registration_data.permissions, - registration_data.budgets, + data.registration_data.description, + data.registration_data.expires_at, + data.registration_data.permissions, + data.registration_data.budgets, ) - budgets = await get_budgets_nwc(pubkey) + budgets = await get_budgets_nwc(data.pubkey) res = NWCGetResponse(data=nwc, budgets=budgets) return res @@ -137,20 +146,18 @@ async def api_register_nwc( # Delete a nwc key @nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK) async def api_delete_nwc( - req: Request, pubkey: str, wallet: WalletTypeInfo = Depends(require_admin_key) + data:DeleteNWC, wallet: WalletTypeInfo = Depends(require_admin_key) ): wallet_id = wallet.wallet.id - await delete_nwc(pubkey, wallet_id) - return JSONResponse(content={"message": f"NWC key {pubkey} deleted successfully."}) + await delete_nwc(data.pubkey, wallet_id) + return JSONResponse(content={"message": f"NWC key {data.pubkey} deleted successfully."}) # Get config @nwcprovider_api_router.get( "/api/v1/config", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] ) -async def api_get_all_config_nwc( - req: Request, -): +async def api_get_all_config_nwc(): config = await get_all_config_nwc() return config @@ -161,7 +168,7 @@ async def api_get_all_config_nwc( status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)], ) -async def api_get_config_nwc(req: Request, key: str): +async def api_get_config_nwc(key: str): config = await get_config_nwc(key) out = {} out[key] = config From b28c1db6b54a99308fea938499ccdd67667df7fe Mon Sep 17 00:00:00 2001 From: Arc Date: Tue, 19 Nov 2024 14:07:04 +0000 Subject: [PATCH 4/5] Added description for extension preview --- __init__.py | 13 ++++++++----- config.json | 18 ++++++++++++++++++ description.md | 3 +++ toc.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 description.md create mode 100644 toc.md diff --git a/__init__.py b/__init__.py index f0adf33..e7b2717 100644 --- a/__init__.py +++ b/__init__.py @@ -4,14 +4,11 @@ from fastapi import APIRouter from loguru import logger from lnbits.tasks import create_permanent_unique_task - from .crud import db from .tasks import handle_execution_queue, handle_nwc from .views import nwcprovider_router from .views_api import nwcprovider_api_router -scheduled_tasks: list[asyncio.Task] = [] - nwcprovider_ext: APIRouter = APIRouter( prefix="/nwcprovider", tags=["NWC Service Provider"] ) @@ -25,6 +22,7 @@ nwcprovider_static_files = [ } ] +scheduled_tasks: list[asyncio.Task] = [] def nwcprovider_stop(): for task in scheduled_tasks: @@ -42,5 +40,10 @@ def nwcprovider_start(): ) scheduled_tasks.append(task) - -__all__ = ["db"] +__all__ = [ + "db", + "nwcprovider_ext", + "nwcprovider_static_files", + "nwcprovider_start", + "nwcprovider_stop", +] diff --git a/config.json b/config.json index b68048a..92b27df 100644 --- a/config.json +++ b/config.json @@ -7,8 +7,26 @@ { "name": "Riccardo Balbo", "uri": "https://github.com/riccardobl", + "role": "Lead Dev" + }, + { + "name": "Ben Arc", + "uri": "https://github.com/arcbtc", "role": "Dev" } ], + "images": [ + { + "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/1.png" + }, + { + "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/2.png" + }, + { + "uri": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/static/image/3.png" + } + ], + "description_md": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/description.md", + "terms_and_conditions_md": "https://raw.githubusercontent.com/riccardobl/nwcprovider/main/toc.md", "license": "MIT" } diff --git a/description.md b/description.md new file mode 100644 index 0000000..e76978b --- /dev/null +++ b/description.md @@ -0,0 +1,3 @@ +NWC Service Provider Extension for https://github.com/lnbits/lnbits + +Easily connect your LNbits wallets via https://nwc.dev/ \ No newline at end of file diff --git a/toc.md b/toc.md new file mode 100644 index 0000000..baa0342 --- /dev/null +++ b/toc.md @@ -0,0 +1,29 @@ +# Terms and Conditions for LNbits Extension + +## 1. Acceptance of Terms + +By installing and using the LNbits extension ("Extension"), you agree to be bound by these terms and conditions ("Terms"). If you do not agree to these Terms, do not use the Extension. + +## 2. License + +The Extension is free and open-source software, released under [specify the FOSS license here, e.g., GPL-3.0, MIT, etc.]. You are permitted to use, copy, modify, and distribute the Extension under the terms of that license. + +## 3. No Warranty + +The Extension is provided "as is" and with all faults, and the developer expressly disclaims all warranties of any kind, whether express, implied, statutory, or otherwise, including but not limited to warranties of merchantability, fitness for a particular purpose, non-infringement, and any warranties arising out of course of dealing or usage of trade. No advice or information, whether oral or written, obtained from the developer or elsewhere will create any warranty not expressly stated in this Terms. + +## 4. Limitation of Liability + +In no event will the developer be liable to you or any third party for any direct, indirect, incidental, special, consequential, or punitive damages, including lost profit, lost revenue, loss of data, or other damages arising out of or in connection with your use of the Extension, even if the developer has been advised of the possibility of such damages. The foregoing limitation of liability shall apply to the fullest extent permitted by law in the applicable jurisdiction. + +## 5. Modification of Terms + +The developer reserves the right to modify these Terms at any time. You are advised to review these Terms periodically for any changes. Changes to these Terms are effective when they are posted on the appropriate location within or associated with the Extension. + +## 6. General Provisions + +If any provision of these Terms is held to be invalid or unenforceable, that provision will be enforced to the maximum extent permissible, and the other provisions of these Terms will remain in full force and effect. These Terms constitute the entire agreement between you and the developer regarding the use of the Extension. + +## 7. Contact Information + +If you have any questions about these Terms, please contact the developer at [developer's contact information]. From 3149be8046780ffb029cdffcefd99834f4480ff2 Mon Sep 17 00:00:00 2001 From: Arc Date: Tue, 19 Nov 2024 22:02:36 +0000 Subject: [PATCH 5/5] fixed js --- templates/nwcprovider/admin.html | 4 ++-- templates/nwcprovider/index.html | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/nwcprovider/admin.html b/templates/nwcprovider/admin.html index dbd87ba..3a64166 100644 --- a/templates/nwcprovider/admin.html +++ b/templates/nwcprovider/admin.html @@ -38,8 +38,8 @@ {% endblock %} {% block scripts %} {{ window_vars(user) }}