diff --git a/static/js/index.js b/static/js/index.js index 3d89779..21f67f6 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -16,7 +16,29 @@ window.app = Vue.createApp({ privateKey: null } }, - wsConnection: null + wsConnection: null, + nostrStatus: { + nostrclient_available: false, + nostrclient_relays: [], + nostrclient_error: null, + nostrmarket_running: false, + websocket_connected: false + } + } + }, + computed: { + nostrStatusColor: function () { + if (!this.nostrStatus.nostrclient_available) { + return 'red' + } else if (this.nostrStatus.websocket_connected) { + return 'green' + } else if (this.nostrStatus.nostrmarket_running) { + return 'orange' + } + return 'red' + }, + nostrStatusLabel: function () { + return 'Connect' } }, methods: { @@ -196,10 +218,38 @@ window.app = Vue.createApp({ }) } }, + checkNostrStatus: async function () { + try { + const {data} = await LNbits.api.request( + 'GET', + '/nostrmarket/api/v1/status', + this.g.user.wallets[0].inkey + ) + this.nostrStatus = data + if (!data.nostrclient_available) { + this.$q.notify({ + timeout: 5000, + type: 'warning', + message: 'Nostrclient extension not available', + caption: + data.nostrclient_error || + 'Please install and configure the nostrclient extension' + }) + } + } catch (error) { + this.nostrStatus = { + nostrclient_available: false, + nostrclient_relays: [], + nostrclient_error: 'Failed to check status', + nostrmarket_running: false, + websocket_connected: false + } + } + }, restartNostrConnection: async function () { LNbits.utils .confirmDialog( - 'Are you sure you want to reconnect to the nostrcient extension?' + 'Are you sure you want to reconnect to the nostrclient extension?' ) .onOk(async () => { try { @@ -208,6 +258,8 @@ window.app = Vue.createApp({ '/nostrmarket/api/v1/restart', this.g.user.wallets[0].adminkey ) + // Check status after restart + setTimeout(() => this.checkNostrStatus(), 2000) } catch (error) { LNbits.utils.notifyApiError(error) } @@ -216,6 +268,7 @@ window.app = Vue.createApp({ }, created: async function () { await this.getMerchant() + await this.checkNostrStatus() setInterval(async () => { if ( !this.wsConnection || diff --git a/templates/nostrmarket/_api_docs.html b/templates/nostrmarket/_api_docs.html index 6bce480..f4f7cab 100644 --- a/templates/nostrmarket/_api_docs.html +++ b/templates/nostrmarket/_api_docs.html @@ -1,44 +1,61 @@ -

- Nostr Market
+

+ Create, edit and publish products to your Nostr relays. Customers can + browse your stalls and pay with Lightning. +

+

- Created by, + Created by Tal Vasconcelos + >, Ben Arc + >, motorina0 + > +

- Swagger REST API Documentation
- - Visit the market clientMarket client + + + Market client + Visit the market client + +
+ + API Documentation + Swagger REST API Documentation + +
+ + + + Requires:  + nostrclient + extension to be installed and configured with relays. +
diff --git a/templates/nostrmarket/index.html b/templates/nostrmarket/index.html index d95d965..319fbdb 100644 --- a/templates/nostrmarket/index.html +++ b/templates/nostrmarket/index.html @@ -151,16 +151,66 @@
- - - Restart the connection to the nostrclient extension - - + + + + + + + Restart Connection + + Reconnect to the nostrclient extension + + + + + + + + + Check Status + + Check connection to nostrclient + + + + + + + + Nostrclient: + +
+ Relays: + configured
+ WebSocket: + +
+ +
+
+
+
@@ -168,7 +218,7 @@
- {{SITE_TITLE}} Nostr Market Extension + Nostr Market
diff --git a/views_api.py b/views_api.py index af675cd..ba10674 100644 --- a/views_api.py +++ b/views_api.py @@ -1,10 +1,12 @@ import json from http import HTTPStatus +import httpx from fastapi import Depends from fastapi.exceptions import HTTPException from lnbits.core.models import WalletTypeInfo from lnbits.core.services import websocket_updater +from lnbits.settings import settings from lnbits.decorators import ( require_admin_key, require_invoice_key, @@ -1105,6 +1107,40 @@ async def api_list_currencies_available(): return list(currencies.keys()) +@nostrmarket_ext.get("/api/v1/status") +async def api_get_nostr_status( + wallet: WalletTypeInfo = Depends(require_invoice_key), +) -> dict: + """Get the status of the nostrclient extension.""" + nostrclient_available = False + nostrclient_relays = [] + nostrclient_error = None + + try: + async with httpx.AsyncClient() as client: + response = await client.get( + f"http://localhost:{settings.port}/nostrclient/api/v1/relays", + timeout=5.0, + ) + if response.status_code == 200: + nostrclient_available = True + nostrclient_relays = response.json() + except httpx.ConnectError: + nostrclient_error = "Cannot connect to nostrclient extension" + except httpx.TimeoutException: + nostrclient_error = "Timeout connecting to nostrclient" + except Exception as ex: + nostrclient_error = str(ex) + + return { + "nostrclient_available": nostrclient_available, + "nostrclient_relays": nostrclient_relays, + "nostrclient_error": nostrclient_error, + "nostrmarket_running": nostr_client.running, + "websocket_connected": nostr_client.is_websocket_connected, + } + + @nostrmarket_ext.put("/api/v1/restart") async def restart_nostr_client(wallet: WalletTypeInfo = Depends(require_admin_key)): try: