Merge branch 'v1_update'

This commit is contained in:
Arc 2024-11-19 22:31:49 +00:00
commit ef53a01bb7
12 changed files with 1185 additions and 1028 deletions

View file

@ -33,7 +33,7 @@ checkeditorconfig:
test: test:
PYTHONUNBUFFERED=1 \ PYTHONUNBUFFERED=1 \
DEBUG=true \ DEBUG=true \
poetry run pytest tests/unit/*.py -s poetry run pytest
install-pre-commit-hook: install-pre-commit-hook:
@echo "Installing pre-commit hook to git" @echo "Installing pre-commit hook to git"
@echo "Uninstall the hook with poetry run pre-commit uninstall" @echo "Uninstall the hook with poetry run pre-commit uninstall"
@ -44,4 +44,4 @@ pre-commit:
checkbundle: checkbundle:
@echo "skipping checkbundle" @echo "skipping checkbundle"

View file

@ -1,9 +1,9 @@
import asyncio import asyncio
from fastapi import APIRouter from fastapi import APIRouter
from lnbits.tasks import create_permanent_unique_task
from loguru import logger from loguru import logger
from lnbits.tasks import create_permanent_unique_task
from .crud import db from .crud import db
from .tasks import handle_execution_queue, handle_nwc from .tasks import handle_execution_queue, handle_nwc
from .views import nwcprovider_router from .views import nwcprovider_router
@ -24,6 +24,7 @@ nwcprovider_static_files = [
scheduled_tasks: list[asyncio.Task] = [] scheduled_tasks: list[asyncio.Task] = []
def nwcprovider_stop(): def nwcprovider_stop():
for task in scheduled_tasks: for task in scheduled_tasks:
try: try:
@ -40,6 +41,7 @@ def nwcprovider_start():
) )
scheduled_tasks.append(task) scheduled_tasks.append(task)
__all__ = [ __all__ = [
"db", "db",
"nwcprovider_ext", "nwcprovider_ext",

102
crud.py
View file

@ -5,18 +5,19 @@ from lnbits.db import Database
from .execution_queue import enqueue from .execution_queue import enqueue
from .models import ( from .models import (
NWCBudget, CreateNWCKey,
NWCKey, DeleteNWC,
CreateNWCKey, GetBudgetsNWC,
GetNWCKey, GetNWCKey,
GetWalletNWC, GetWalletNWC,
GetBudgetsNWC, NWCBudget,
NWCKey,
TrackedSpendNWC, TrackedSpendNWC,
DeleteNWC
) )
db = Database("ext_nwcprovider") db = Database("ext_nwcprovider")
async def create_nwc(data: CreateNWCKey) -> NWCKey: async def create_nwc(data: CreateNWCKey) -> NWCKey:
nwckey_entry = NWCKey( nwckey_entry = NWCKey(
pubkey=data.pubkey, pubkey=data.pubkey,
@ -34,39 +35,47 @@ async def create_nwc(data: CreateNWCKey) -> NWCKey:
pubkey=data.pubkey, pubkey=data.pubkey,
budget_msats=budget.budget_msats, budget_msats=budget.budget_msats,
refresh_window=budget.refresh_window, refresh_window=budget.refresh_window,
created_at=budget.created_at created_at=budget.created_at,
) )
await db.insert("nwcprovider.budgets", budget_entry) await db.insert("nwcprovider.budgets", budget_entry)
return NWCKey(**data.dict()) return NWCKey(**data.dict())
async def delete_nwc(data:DeleteNWC) -> None:
async def delete_nwc(data: DeleteNWC) -> None:
await db.execute( await db.execute(
"DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet", {"pubkey": data.pubkey, "wallet": data.wallet_id} "DELETE FROM nwcprovider.keys WHERE pubkey = :pubkey AND wallet = :wallet",
{"pubkey": data.pubkey, "wallet": data.wallet_id},
) )
async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]: async def get_wallet_nwcs(data: GetWalletNWC) -> List[NWCKey]:
return await db.fetchall( return await db.fetchall(
""" """
SELECT * FROM nwcprovider.keys SELECT * FROM nwcprovider.keys
WHERE wallet = :wallet AND (expires_at = 0 OR expires_at > :expires) 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}, {
"wallet": data.wallet_id,
"expires": int(time.time()) if not data.include_expired else -1,
},
model=NWCKey, model=NWCKey,
) )
async def get_nwc(
data: GetNWCKey async def get_nwc(data: GetNWCKey) -> Optional[NWCKey]:
) -> Optional[NWCKey]:
# expires_at = 0 means it never expires # expires_at = 0 means it never expires
if data.wallet_id: if data.wallet_id:
row = await db.fetchone( row = await db.fetchone(
""" """
SELECT * FROM nwcprovider.keys SELECT * FROM nwcprovider.keys
WHERE pubkey = :pubkey AND wallet = :wallet WHERE pubkey = :pubkey AND wallet = :wallet
AND (expires_at = 0 OR expires_at > :expires) AND (expires_at = 0 OR expires_at > :expires)
""", """,
{"pubkey": data.pubkey, "wallet": data.wallet_id, {
"expires": int(time.time()) if not data.include_expired else -1}, "pubkey": data.pubkey,
"wallet": data.wallet_id,
"expires": int(time.time()) if not data.include_expired else -1,
},
NWCKey, NWCKey,
) )
else: else:
@ -79,10 +88,13 @@ async def get_nwc(
) )
row = await db.fetchone( row = await db.fetchone(
""" """
SELECT * FROM nwcprovider.keys SELECT * FROM nwcprovider.keys
WHERE pubkey = :pubkey AND (expires_at = 0 OR expires_at > :expires) 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}, {
"pubkey": data.pubkey,
"expires": int(time.time()) if not data.include_expired else -1,
},
NWCKey, NWCKey,
) )
if not row: if not row:
@ -90,16 +102,18 @@ async def get_nwc(
if data.refresh_last_used: if data.refresh_last_used:
await db.execute( await db.execute(
""" """
UPDATE nwcprovider.keys SET last_used = :last_used WHERE pubkey = :pubkey UPDATE nwcprovider.keys SET last_used =
:last_used WHERE pubkey = :pubkey
""", """,
{"last_used":int(time.time()), "pubkey":data.pubkey}, {"last_used": int(time.time()), "pubkey": data.pubkey},
) )
return NWCKey(**row) return NWCKey(**row)
async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]: async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]:
rows = await db.fetchall( rows = await db.fetchall(
"SELECT * FROM nwcprovider.budgets WHERE pubkey = :pubkey", {"pubkey":data.pubkey} "SELECT * FROM nwcprovider.budgets WHERE pubkey = :pubkey",
{"pubkey": data.pubkey},
) )
budgets = [NWCBudget(**row) for row in rows] budgets = [NWCBudget(**row) for row in rows]
if data.calculate_spent: if data.calculate_spent:
@ -108,16 +122,21 @@ async def get_budgets_nwc(data: GetBudgetsNWC) -> Optional[NWCBudget]:
tot_spent_in_range_msats = await db.fetchone( tot_spent_in_range_msats = await db.fetchone(
""" """
SELECT SUM(amount_msats) FROM nwcprovider.spent SELECT SUM(amount_msats) FROM nwcprovider.spent
WHERE pubkey = :pubkey AND created_at >= :last_cycle AND created_at < next_cycle WHERE pubkey = :pubkey AND created_at >=
:last_cycle AND created_at < next_cycle
""", """,
{"pubkey":data.pubkey, "last_cycle":last_cycle, "next_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 tot_spent_in_range_msats = tot_spent_in_range_msats[0] or 0
budget.used_budget_msats = tot_spent_in_range_msats budget.used_budget_msats = tot_spent_in_range_msats
return budgets return budgets
async def tracked_spend_nwc(data:TrackedSpendNWC, action): async def tracked_spend_nwc(data: TrackedSpendNWC, action):
async def r(): async def r():
created_at = int(time.time()) created_at = int(time.time())
budgets = await get_budgets_nwc(data.pubkey) budgets = await get_budgets_nwc(data.pubkey)
@ -129,9 +148,14 @@ async def tracked_spend_nwc(data:TrackedSpendNWC, action):
await db.fetchone( await db.fetchone(
""" """
SELECT SUM(amount_msats) FROM nwcprovider.spent SELECT SUM(amount_msats) FROM nwcprovider.spent
WHERE pubkey = :pubkey AND created_at >= :last_cycle AND created_at < :next_cycle WHERE pubkey = :pubkey AND created_at >=
:last_cycle AND created_at < :next_cycle
""", """,
{"pubkey":data.pubkey, "last_cycle":last_cycle, "next_cycle":next_cycle}, {
"pubkey": data.pubkey,
"last_cycle": last_cycle,
"next_cycle": next_cycle,
},
) )
)[0] )[0]
or 0 or 0
@ -147,7 +171,11 @@ async def tracked_spend_nwc(data:TrackedSpendNWC, action):
INSERT INTO nwcprovider.spent (pubkey, amount_msats, created_at) INSERT INTO nwcprovider.spent (pubkey, amount_msats, created_at)
VALUES (:pubkey, :amount_msats, :created_at) VALUES (:pubkey, :amount_msats, :created_at)
""", """,
{"pubkey":data.pubkey, "amount_msats":data.amount_msats, "created_at":created_at}, {
"pubkey": data.pubkey,
"amount_msats": data.amount_msats,
"created_at": created_at,
},
) )
return True, out return True, out
@ -155,27 +183,31 @@ async def tracked_spend_nwc(data:TrackedSpendNWC, action):
async def get_config_nwc(key: str): async def get_config_nwc(key: str):
row = await db.fetchone("SELECT * FROM nwcprovider.config WHERE key = :key", {"key":key}) row = await db.fetchone(
"SELECT * FROM nwcprovider.config WHERE key = :key", {"key": key}
)
if not row: if not row:
return None return None
return row["value"] return row["value"]
async def set_config_nwc(key: str, value: str): async def set_config_nwc(key: str, value: str):
await db.execute( await db.execute(
""" """
DELETE FROM nwcprovider.config DELETE FROM nwcprovider.config
WHERE key = :key WHERE key = :key
""", """,
{"key":key}, {"key": key},
) )
await db.execute( await db.execute(
""" """
INSERT INTO nwcprovider.config (key, value) INSERT INTO nwcprovider.config (key, value)
VALUES (:key, :value) VALUES (:key, :value)
""", """,
{"key":key, "value":value}, {"key": key, "value": value},
) )
async def get_all_config_nwc(): async def get_all_config_nwc():
rows = await db.fetchall("SELECT * FROM nwcprovider.config") rows = await db.fetchall("SELECT * FROM nwcprovider.config")
return {row["key"]: row["value"] for row in rows} return {row["key"]: row["value"] for row in rows}

View file

@ -1,3 +1,3 @@
NWC Service Provider Extension for https://github.com/lnbits/lnbits NWC Service Provider Extension for https://github.com/lnbits/lnbits
Easily connect your LNbits wallets via https://nwc.dev/ Easily connect your LNbits wallets via https://nwc.dev/

View file

@ -5,8 +5,10 @@ from sqlite3 import Row
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from pydantic import BaseModel from pydantic import BaseModel
from .nwcp import NWCServiceProvider from .nwcp import NWCServiceProvider
class NWCKey(BaseModel): class NWCKey(BaseModel):
pubkey: str pubkey: str
wallet: str wallet: str
@ -26,37 +28,45 @@ class NWCKey(BaseModel):
def from_row(cls, row: Dict[str, Any]) -> "NWCKey": def from_row(cls, row: Dict[str, Any]) -> "NWCKey":
return cls(**row) return cls(**row)
class GetNWCKey(BaseModel): class GetNWCKey(BaseModel):
pubkey: str pubkey: str
wallet_id: Optional[str] = None wallet_id: Optional[str] = None
include_expired: Optional[bool] = False include_expired: Optional[bool] = False
refresh_last_used: Optional[bool] = False refresh_last_used: Optional[bool] = False
class GetNWCs(BaseModel): class GetNWCs(BaseModel):
include_expired: bool = False include_expired: bool = False
calculate_spent_budget: bool = False calculate_spent_budget: bool = False
class GetWalletNWC(BaseModel): class GetWalletNWC(BaseModel):
wallet_id: Optional[str] = None wallet_id: Optional[str] = None
include_expired: Optional[bool] = False include_expired: Optional[bool] = False
class GetBudgetsNWC(BaseModel): class GetBudgetsNWC(BaseModel):
pubkey: str pubkey: str
calculate_spent: Optional[bool] = False calculate_spent: Optional[bool] = False
class TrackedSpendNWC(BaseModel): class TrackedSpendNWC(BaseModel):
pubkey: str pubkey: str
amount_msats: int amount_msats: int
class DeleteNWC(BaseModel): class DeleteNWC(BaseModel):
pubkey: str pubkey: str
wallet_id: Optional[str] = None wallet_id: Optional[str] = None
class OnInvoicePaid(BaseModel): class OnInvoicePaid(BaseModel):
sp: NWCServiceProvider sp: NWCServiceProvider
pubkey: str pubkey: str
payload: Dict payload: Dict
class NWCBudget(BaseModel): class NWCBudget(BaseModel):
id: int id: int
pubkey: str pubkey: str
@ -105,18 +115,21 @@ class NWCRegistrationRequest(BaseModel):
expires_at: int expires_at: int
budgets: List[NWCNewBudget] budgets: List[NWCNewBudget]
class RegisterNWC(BaseModel): class RegisterNWC(BaseModel):
pubkey: str pubkey: str
registration_data: NWCRegistrationRequest registration_data: NWCRegistrationRequest
class NWCGetResponse(BaseModel): class NWCGetResponse(BaseModel):
data: NWCKey data: NWCKey
budgets: List[NWCBudget] budgets: List[NWCBudget]
class CreateNWCKey(BaseModel): class CreateNWCKey(BaseModel):
pubkey: str pubkey: str
wallet_id: str wallet_id: str
description: str description: str
expires_at: int expires_at: int
permissions: List[str] permissions: List[str]
budgets: Optional[List[NWCNewBudget]] = None budgets: Optional[List[NWCNewBudget]] = None

View file

@ -76,7 +76,7 @@ class NWCServiceProvider:
self.request_listeners: Dict[ self.request_listeners: Dict[
str, str,
Callable[ Callable[
["NWCServiceProvider", str, Dict], [NWCServiceProvider, str, Dict],
Awaitable[List[Tuple[Optional[Dict], Optional[Dict], List]]], Awaitable[List[Tuple[Optional[Dict], Optional[Dict], List]]],
], ],
] = {} ] = {}

2003
poetry.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,8 +6,8 @@ authors = ["Riccardo Balbo <oc@rblb.it>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10 | ^3.9" python = "^3.10 | ^3.9"
lnbits = "*" lnbits = {version = "*", allow-prereleases = true}
psycopg2-binary = "^2.9.9" mypy = "^1.13.0"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
black = "^24.3.0" black = "^24.3.0"
@ -16,27 +16,19 @@ pytest = "^7.3.2"
mypy = "^1.5.1" mypy = "^1.5.1"
pre-commit = "^3.2.2" pre-commit = "^3.2.2"
ruff = "^0.3.2" ruff = "^0.3.2"
types-cffi = "^1.16.0.20240331" pytest-md = "^0.2.0"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.mypy] [tool.mypy]
exclude = "(tests/*)"
[[tool.mypy.overrides]] [[tool.mypy.overrides]]
module = [ module = [
"lnbits.*", "lnbits.*",
"lnurl.*",
"loguru.*", "loguru.*",
"fastapi.*", "fastapi.*",
"pydantic.*", "pydantic.*",
"pyqrcode.*",
"shortuuid.*",
"httpx.*",
"websocket.*",
"secp256k1.*",
] ]
ignore_missing_imports = "True" ignore_missing_imports = "True"
@ -52,9 +44,7 @@ line-length = 88
[tool.ruff] [tool.ruff]
# Same as Black. + 10% rule of black # Same as Black. + 10% rule of black
line-length = 88 line-length = 88
# exclude = [
# "nostr",
# ]
[tool.ruff.lint] [tool.ruff.lint]
# Enable: # Enable:
@ -69,7 +59,8 @@ line-length = 88
# RUF - ruff # RUF - ruff
# B - bugbear # B - bugbear
select = ["F", "E", "W", "I", "A", "C", "N", "UP", "RUF", "B"] select = ["F", "E", "W", "I", "A", "C", "N", "UP", "RUF", "B"]
ignore = ["C901"] # UP007: pyupgrade: use X | Y instead of Optional. (python3.10)
ignore = ["UP007"]
# Allow autofix for all enabled rules (when `--fix`) is provided. # Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"] fixable = ["ALL"]
@ -86,7 +77,7 @@ classmethod-decorators = [
# Ignore unused imports in __init__.py files. # Ignore unused imports in __init__.py files.
# [tool.ruff.lint.extend-per-file-ignores] # [tool.ruff.lint.extend-per-file-ignores]
# "__init__.py" = ["F401", "F403"] # "views_api.py" = ["F401"]
# [tool.ruff.lint.mccabe] # [tool.ruff.lint.mccabe]
# max-complexity = 10 # max-complexity = 10

View file

@ -106,8 +106,8 @@ async def _process_invoice(
async def _on_pay_invoice( async def _on_pay_invoice(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "pay_invoice", data.payload) error = await _check(nwc, "pay_invoice", data.payload)
if error: if error:
@ -136,7 +136,7 @@ async def _on_pay_invoice(
async def _on_multi_pay_invoice( async def _on_multi_pay_invoice(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "multi_pay_invoice", data.payload) error = await _check(nwc, "multi_pay_invoice", data.payload)
@ -161,7 +161,7 @@ async def _on_multi_pay_invoice(
invoice_data = bolt11_decode(invoice) invoice_data = bolt11_decode(invoice)
amount_msats = int(invoice_data.amount_msat or 0) amount_msats = int(invoice_data.amount_msat or 0)
res = await _process_invoice( 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") error = res.get("error")
if error: if error:
@ -182,7 +182,7 @@ async def _on_multi_pay_invoice(
async def _on_make_invoice( async def _on_make_invoice(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "make_invoice", data.payload) error = await _check(nwc, "make_invoice", data.payload)
@ -234,7 +234,7 @@ async def _on_make_invoice(
async def _on_lookup_invoice( async def _on_lookup_invoice(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "lookup_invoice", data.payload) error = await _check(nwc, "lookup_invoice", data.payload)
@ -281,7 +281,7 @@ async def _on_lookup_invoice(
async def _on_list_transactions( async def _on_list_transactions(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "list_transactions", data.payload) error = await _check(nwc, "list_transactions", data.payload)
@ -337,7 +337,7 @@ async def _on_list_transactions(
async def _on_get_balance( async def _on_get_balance(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "get_balance", data.payload) error = await _check(nwc, "get_balance", data.payload)
@ -355,7 +355,7 @@ async def _on_get_balance(
async def _on_get_info( async def _on_get_info(
data:OnInvoicePaid data: OnInvoicePaid,
) -> List[Tuple[Optional[Dict], Optional[Dict], List]]: ) -> List[Tuple[Optional[Dict], Optional[Dict], List]]:
nwc = await get_nwc(data.pubkey, None, False, True) nwc = await get_nwc(data.pubkey, None, False, True)
error = await _check(nwc, "get_info", data.payload) error = await _check(nwc, "get_info", data.payload)
@ -363,7 +363,7 @@ async def _on_get_info(
return [(None, error, [])] return [(None, error, [])]
if not nwc: if not nwc:
raise Exception("Pubkey has no associated wallet") raise Exception("Pubkey has no associated wallet")
sp_methods = sp.get_supported_methods() sp_methods = data.sp.get_supported_methods()
permissions = nwc.get_permissions() permissions = nwc.get_permissions()
# Filter only methods supported by the extension and allowed by the permissions # Filter only methods supported by the extension and allowed by the permissions
account_methods = [] account_methods = []

View file

@ -38,8 +38,8 @@
</div> </div>
{% endblock %} {% block scripts %} {{ window_vars(user) }} {% endblock %} {% block scripts %} {{ window_vars(user) }}
<script> <script>
window.app = Vue.createApp({ window.app = Vue.createApp({
el: '#vue', el: "#vue",
mixins: [windowMixin], mixins: [windowMixin],
delimiters: ["${", "}"], delimiters: ["${", "}"],
data: function () { data: function () {

View file

@ -99,7 +99,8 @@
<q-card-section> <q-card-section>
<h6 class="text-subtitle1 q-my-none">NWC Service provider</h6> <h6 class="text-subtitle1 q-my-none">NWC Service provider</h6>
<p> <p>
Nostr Wallet Connect (NWC) is an open protocol to connect lightning wallets to apps Nostr Wallet Connect (NWC) is an open protocol to connect lightning
wallets to apps
</p> </p>
</q-card-section> </q-card-section>
<q-card-section class="q-pa-none"> <q-card-section class="q-pa-none">
@ -407,8 +408,8 @@
window.NobleSecp256k1 = NobleSecp256k1; window.NobleSecp256k1 = NobleSecp256k1;
</script> </script>
<script> <script>
window.app = Vue.createApp({ window.app = Vue.createApp({
el: '#vue', el: "#vue",
mixins: [windowMixin], mixins: [windowMixin],
delimiters: ["${", "}"], delimiters: ["${", "}"],
data: function () { data: function () {

View file

@ -18,13 +18,13 @@ from .crud import (
set_config_nwc, set_config_nwc,
) )
from .models import ( from .models import (
NWCGetResponse, DeleteNWC,
RegisterNWC,
GetWalletNWC,
GetBudgetsNWC, GetBudgetsNWC,
GetNWCKey, GetNWCKey,
GetNWCs, GetNWCs,
DeleteNWC GetWalletNWC,
NWCGetResponse,
RegisterNWC,
) )
from .permission import nwc_permissions from .permission import nwc_permissions
@ -50,16 +50,14 @@ async def api_get_nwcs(
wallet_id = wallet.wallet.id wallet_id = wallet.wallet.id
wallet_nwcs = GetWalletNWC( wallet_nwcs = GetWalletNWC(
wallet_id=wallet_id, wallet_id=wallet_id, include_expired=data.include_expired
include_expired=data.include_expired )
)
nwcs = await get_wallet_nwcs(wallet_nwcs) nwcs = await get_wallet_nwcs(wallet_nwcs)
out = [] out = []
for nwc in nwcs: for nwc in nwcs:
budgets_nwc = GetBudgetsNWC( budgets_nwc = GetBudgetsNWC(
pubkey=nwc.pubkey, pubkey=nwc.pubkey, calculate_spent=data.calculate_spent_budget
calculate_spent=data.calculate_spent_budget )
)
budgets = await get_budgets_nwc(budgets_nwc) budgets = await get_budgets_nwc(budgets_nwc)
res = NWCGetResponse(data=nwc, budgets=budgets) res = NWCGetResponse(data=nwc, budgets=budgets)
out.append(res) out.append(res)
@ -71,9 +69,8 @@ async def api_get_nwcs(
"/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse "/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK, response_model=NWCGetResponse
) )
async def api_get_nwc( async def api_get_nwc(
data:GetNWCKey, data: GetNWCKey, wallet: WalletTypeInfo = Depends(require_admin_key)
wallet: WalletTypeInfo = Depends(require_admin_key) ) -> NWCGetResponse:
) -> NWCGetResponse:
wallet_id = wallet.wallet.id wallet_id = wallet.wallet.id
nwc = await get_nwc(data.pubkey, wallet_id, data.include_expired) nwc = await get_nwc(data.pubkey, wallet_id, data.include_expired)
if not nwc: if not nwc:
@ -126,7 +123,7 @@ async def api_get_pairing_url(req: Request, secret: str) -> str:
response_model=NWCGetResponse, response_model=NWCGetResponse,
) )
async def api_register_nwc( async def api_register_nwc(
data:RegisterNWC, # Use the Pydantic model here data: RegisterNWC, # Use the Pydantic model here
wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),
): ):
wallet_id = wallet.wallet.id wallet_id = wallet.wallet.id
@ -146,11 +143,13 @@ async def api_register_nwc(
# Delete a nwc key # Delete a nwc key
@nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK) @nwcprovider_api_router.delete("/api/v1/nwc/{pubkey}", status_code=HTTPStatus.OK)
async def api_delete_nwc( async def api_delete_nwc(
data:DeleteNWC, wallet: WalletTypeInfo = Depends(require_admin_key) data: DeleteNWC, wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
wallet_id = wallet.wallet.id wallet_id = wallet.wallet.id
await delete_nwc(data.pubkey, wallet_id) await delete_nwc(data.pubkey, wallet_id)
return JSONResponse(content={"message": f"NWC key {data.pubkey} deleted successfully."}) return JSONResponse(
content={"message": f"NWC key {data.pubkey} deleted successfully."}
)
# Get config # Get config