code cleanup

This commit is contained in:
Riccardo Balbo 2024-07-24 14:18:57 +00:00
commit 17f4bb7218
10 changed files with 35 additions and 73 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "NWC Service Provider", "name": "NWC Service Provider",
"short_description": "A NWC service provider for lnbits", "short_description": "A NWC service provider for LNbits",
"tile": "/nwcprovider/static/image/nwcprovider.png", "tile": "/nwcprovider/static/image/nwcprovider.png",
"min_lnbits_version": "0.12.5", "min_lnbits_version": "0.12.5",
"contributors": [ "contributors": [

37
crud.py
View file

@ -12,10 +12,11 @@ async def create_nwc(
expires_at: int , expires_at: int ,
permissions:List[str] , permissions:List[str] ,
budgets: Optional[List[NWCNewBudget]] = None budgets: Optional[List[NWCNewBudget]] = None
): ) -> NWCKey:
# Check if the key already exists # Check if the key already exists
if await get_nwc(pubkey, None, True): if await get_nwc(pubkey, None, True):
raise Exception("Public key already used") raise Exception("Public key already used")
# If not, create it
now=int(time.time()) now=int(time.time())
await db.execute( await db.execute(
""" """
@ -24,7 +25,7 @@ async def create_nwc(
""", """,
(pubkey, wallet_id, description, " ".join(permissions), now,int(expires_at) if expires_at else 0, now) (pubkey, wallet_id, description, " ".join(permissions), now,int(expires_at) if expires_at else 0, now)
) )
# Add budgets
if budgets: if budgets:
for budget in budgets: for budget in budgets:
await db.execute( await db.execute(
@ -34,6 +35,7 @@ async def create_nwc(
""", """,
(pubkey, budget.budget_msats, budget.refresh_window, budget.created_at) (pubkey, budget.budget_msats, budget.refresh_window, budget.created_at)
) )
# Return the created key
return NWCKey( return NWCKey(
pubkey=pubkey, pubkey=pubkey,
wallet=wallet_id, wallet=wallet_id,
@ -44,6 +46,7 @@ async def create_nwc(
last_used=now last_used=now
) )
async def delete_nwc( async def delete_nwc(
pubkey: str, pubkey: str,
wallet_id:str wallet_id:str
@ -69,6 +72,7 @@ async def get_wallet_nwcs(
) )
return [NWCKey(**row) for row in rows] return [NWCKey(**row) for row in rows]
async def get_nwc( async def get_nwc(
pubkey: str, pubkey: str,
wallet_id: Optional[str] = None, wallet_id: Optional[str] = None,
@ -95,6 +99,7 @@ async def get_nwc(
) )
return NWCKey(**row) return NWCKey(**row)
async def get_budgets_nwc(pubkey, calculate_spent=False): async def get_budgets_nwc(pubkey, calculate_spent=False):
rows = await db.fetchall( rows = await db.fetchall(
"SELECT * FROM nwcprovider.budgets WHERE pubkey = ?", (pubkey) "SELECT * FROM nwcprovider.budgets WHERE pubkey = ?", (pubkey)
@ -114,19 +119,19 @@ async def get_budgets_nwc(pubkey, calculate_spent=False):
return budgets return budgets
async def log_nwc( # async def log_nwc(
pubkey: str, # pubkey: str,
payload:Optional[Any] = None # payload:Optional[Any] = None
): # ):
if not payload: payload="" # if not payload: payload=""
payload = json.dumps(payload) # payload = json.dumps(payload)
await db.execute( # await db.execute(
""" # """
INSERT INTO nwcprovider.logs (pubkey, payload, created_at) # INSERT INTO nwcprovider.logs (pubkey, payload, created_at)
VALUES (?, ?, ?) # VALUES (?, ?, ?)
""", # """,
(pubkey, payload, int(time.time())) # (pubkey, payload, int(time.time()))
) # )
async def tracked_spend_nwc( async def tracked_spend_nwc(
@ -145,7 +150,7 @@ async def tracked_spend_nwc(
SELECT SUM(amount_msats) FROM nwcprovider.spent WHERE pubkey = ? AND created_at >= ? AND created_at < ? SELECT SUM(amount_msats) FROM nwcprovider.spent WHERE pubkey = ? AND created_at >= ? AND created_at < ?
""", """,
(pubkey, last_cycle, next_cycle) (pubkey, last_cycle, next_cycle)
)[0] or 0 # Ensure we get an int, default to 0 if None )[0] or 0
if tot_spent_in_range_msats + amount_msats > budget.budget_msats: if tot_spent_in_range_msats + amount_msats > budget.budget_msats:
in_budget = False in_budget = False
break break

View file

@ -1,10 +0,0 @@
NWCService can be used as a template for building new extensions, it includes a bunch of functions that can be edited/deleted as you need them.
This is a longform description that will be used in the advanced description when users click on the "more" button on the extension cards.
Adding some bullets is nice covering:
* Functionality
* Use cases
...and some other text about just how great this etension is.

View file

@ -22,11 +22,9 @@ class NWCKey(BaseModel):
try: try:
return cls.permissions.split(" ") return cls.permissions.split(" ")
except: except:
# TODO: log error
return [] return []
@classmethod @classmethod
def from_row(cls, row: Dict[str, Any]) -> "NWCKey": def from_row(cls, row: Dict[str, Any]) -> "NWCKey":
return cls(**row) return cls(**row)
@ -51,7 +49,6 @@ class NWCBudget(BaseModel):
next_cycle = last_cycle + cls.refresh_window next_cycle = last_cycle + cls.refresh_window
return last_cycle, next_cycle return last_cycle, next_cycle
@classmethod @classmethod
def from_row(cls, row: Row) -> "NWCBudget": def from_row(cls, row: Row) -> "NWCBudget":
return cls(**dict(row)) return cls(**dict(row))
@ -68,12 +65,12 @@ class NWCLog(BaseModel):
return cls(**dict(row)) return cls(**dict(row))
class NWCNewBudget(BaseModel): class NWCNewBudget(BaseModel):
budget_msats: int budget_msats: int
refresh_window: int refresh_window: int
created_at: int created_at: int
class NWCRegistrationRequest(BaseModel): class NWCRegistrationRequest(BaseModel):
permissions: List[str] permissions: List[str]
description: str description: str

View file

@ -6,7 +6,8 @@ from lnbits.core.models import Payment
from lnbits.core.services import create_invoice, pay_invoice, check_transaction_status, PaymentError from lnbits.core.services import create_invoice, pay_invoice, check_transaction_status, PaymentError
from bolt11 import decode as bolt11_decode from bolt11 import decode as bolt11_decode
from lnbits.core.crud import get_wallet_payment, get_payments, get_wallet from lnbits.core.crud import get_wallet_payment, get_payments, get_wallet
from .crud import get_nwc, tracked_spend_nwc, log_nwc, get_config_nwc from .crud import get_nwc, tracked_spend_nwc, get_config_nwc
#from .crud import log_nwc
from . import execution_queue from . import execution_queue
from .NWCServiceProvider import NWCServiceProvider from .NWCServiceProvider import NWCServiceProvider
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
@ -113,7 +114,7 @@ async def _on_pay_invoice(sp: NWCServiceProvider, pubkey: str, payload: Dict) ->
out = { out = {
"preimage": preimage, "preimage": preimage,
} }
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [(out,None, [])] return [(out,None, [])]
@ -125,7 +126,7 @@ async def _on_multi_pay_invoice(sp: NWCServiceProvider, pubkey: str, payload: Di
params = payload.get("params", {}) params = payload.get("params", {})
invoices = params.get("invoices", []) invoices = params.get("invoices", [])
results = [] results = []
# Ensures all invoices are provided # Ensures all invoices are provided
for i in invoices: for i in invoices:
invoice = i.get("invoice",None) invoice = i.get("invoice",None)
@ -157,7 +158,7 @@ async def _on_multi_pay_invoice(sp: NWCServiceProvider, pubkey: str, payload: Di
"code": "INTERNAL", "code": "INTERNAL",
"message": str(e) "message": str(e)
})) }))
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return results return results
@ -198,7 +199,7 @@ async def _on_make_invoice(sp: NWCServiceProvider, pubkey: str, payload: Dict) -
} }
if expiry: if expiry:
res["expires_at"] = int(time.time()) + int(expiry) res["expires_at"] = int(time.time()) + int(expiry)
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [(res, None, [])] return [(res, None, [])]
@ -238,7 +239,7 @@ async def _on_lookup_invoice(sp: NWCServiceProvider, pubkey: str, payload: Dict)
} }
if invoice_data.description_hash: if invoice_data.description_hash:
res["description_hash"] = invoice_data.description_hash res["description_hash"] = invoice_data.description_hash
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [(res, None, [])] return [(res, None, [])]
@ -288,7 +289,7 @@ async def _on_list_transactions(sp: NWCServiceProvider, pubkey: str, payload: Di
"settled_at": p.time if is_settled else None, "settled_at": p.time if is_settled else None,
"metadata": {} "metadata": {}
}) })
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [({ return [({
"transactions": transactions "transactions": transactions
}, None, [])] }, None, [])]
@ -304,7 +305,7 @@ async def _on_get_balance(sp: NWCServiceProvider, pubkey: str, payload: Dict) ->
if not wallet: if not wallet:
raise Exception("Wallet not found") raise Exception("Wallet not found")
balance = wallet.balance_msat balance = wallet.balance_msat
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [({ return [({
"balance": balance "balance": balance
}, None, [])] }, None, [])]
@ -317,6 +318,7 @@ async def _on_get_info(sp: NWCServiceProvider, pubkey: str, payload: Dict) -> Li
return [(None, error, [])] return [(None, error, [])]
sp_methods = sp.getSupportedMethods() sp_methods = sp.getSupportedMethods()
permissions = nwc.getPermissions() permissions = nwc.getPermissions()
# Filter only methods supported by the extension and allowed by the permissions
account_methods = [] account_methods = []
for spm in sp_methods: for spm in sp_methods:
for p in permissions: for p in permissions:
@ -324,7 +326,7 @@ async def _on_get_info(sp: NWCServiceProvider, pubkey: str, payload: Dict) -> Li
if spm in allowed_methods: if spm in allowed_methods:
account_methods.append(spm) account_methods.append(spm)
break break
await log_nwc(pubkey, payload) #await log_nwc(pubkey, payload)
return [({ return [({
"alias": settings.lnbits_site_title, "alias": settings.lnbits_site_title,
"color": "", "color": "",
@ -336,7 +338,6 @@ async def _on_get_info(sp: NWCServiceProvider, pubkey: str, payload: Dict) -> Li
async def handle_nwc(): async def handle_nwc():
priv_key = await get_config_nwc("provider_key") priv_key = await get_config_nwc("provider_key")
relay = await get_config_nwc("relay") relay = await get_config_nwc("relay")

22
toc.md
View file

@ -1,22 +0,0 @@
# 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].

View file

@ -1,13 +1,8 @@
from http import HTTPStatus
from fastapi import Depends, Request from fastapi import Depends, Request
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from lnbits.core.models import User from lnbits.core.models import User
from lnbits.decorators import check_user_exists from lnbits.decorators import check_user_exists
from lnbits.settings import settings
from lnbits.decorators import check_admin from lnbits.decorators import check_admin
from . import nwcprovider_ext,nwcprovider_renderer from . import nwcprovider_ext,nwcprovider_renderer

View file

@ -1,16 +1,12 @@
from http import HTTPStatus from http import HTTPStatus
import json import json
from typing import List, Optional, Dict from typing import List, Optional, Dict
from .models import NWCKey, NWCBudget,NWCRegistrationRequest , NWCNewBudget,NWCGetResponse from .models import NWCRegistrationRequest, NWCGetResponse
from fastapi import Depends, Request from fastapi import Depends, Request
from loguru import logger
from lnbits.decorators import ( from lnbits.decorators import (
WalletTypeInfo, WalletTypeInfo,
get_key_type,
require_admin_key require_admin_key
) )
from pydantic import BaseModel,Field
from fastapi import HTTPException
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from . import nwcprovider_ext from . import nwcprovider_ext