fix: improve nostrclient status detection and display
- Call nostrclient /relays API directly from frontend for accurate status - Show correct error messages from API response (body.detail) - Add orange warning state for no relays configured - Show relay count when connected (X of Y connected) - Simplify status logic: 200 = green, no relays = orange, error = red 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9911a03575
commit
d2755d7232
4 changed files with 118 additions and 60 deletions
|
|
@ -18,21 +18,18 @@ window.app = Vue.createApp({
|
|||
},
|
||||
wsConnection: null,
|
||||
nostrStatus: {
|
||||
nostrclient_available: false,
|
||||
nostrclient_relays: [],
|
||||
nostrclient_error: null,
|
||||
nostrmarket_running: false,
|
||||
websocket_connected: false
|
||||
connected: false,
|
||||
error: null,
|
||||
relays_connected: 0,
|
||||
relays_total: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nostrStatusColor: function () {
|
||||
if (!this.nostrStatus.nostrclient_available) {
|
||||
return 'red'
|
||||
} else if (this.nostrStatus.websocket_connected) {
|
||||
if (this.nostrStatus.connected) {
|
||||
return 'green'
|
||||
} else if (this.nostrStatus.nostrmarket_running) {
|
||||
} else if (this.nostrStatus.warning) {
|
||||
return 'orange'
|
||||
}
|
||||
return 'red'
|
||||
|
|
@ -218,31 +215,61 @@ window.app = Vue.createApp({
|
|||
})
|
||||
}
|
||||
},
|
||||
checkNostrStatus: async function () {
|
||||
checkNostrStatus: async function (showNotification = false) {
|
||||
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) {
|
||||
const response = await fetch('/nostrclient/api/v1/relays')
|
||||
const body = await response.json()
|
||||
console.log('Nostrclient /relays:', response.status, body)
|
||||
|
||||
if (response.status === 200) {
|
||||
const relaysConnected = body.filter(r => r.connected).length
|
||||
if (body.length === 0) {
|
||||
this.nostrStatus = {
|
||||
connected: false,
|
||||
error: 'No relays configured in Nostr Client',
|
||||
relays_connected: 0,
|
||||
relays_total: 0,
|
||||
warning: true
|
||||
}
|
||||
} else {
|
||||
this.nostrStatus = {
|
||||
connected: true,
|
||||
error: null,
|
||||
relays_connected: relaysConnected,
|
||||
relays_total: body.length
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.nostrStatus = {
|
||||
connected: false,
|
||||
error: body.detail,
|
||||
relays_connected: 0,
|
||||
relays_total: 0
|
||||
}
|
||||
}
|
||||
|
||||
if (showNotification) {
|
||||
this.$q.notify({
|
||||
timeout: 5000,
|
||||
type: 'warning',
|
||||
message: 'Nostrclient extension not available',
|
||||
caption:
|
||||
data.nostrclient_error ||
|
||||
'Please install and configure the nostrclient extension'
|
||||
timeout: 3000,
|
||||
type: this.nostrStatus.connected ? 'positive' : 'warning',
|
||||
message: this.nostrStatus.connected ? 'Connected' : 'Disconnected',
|
||||
caption: this.nostrStatus.error || undefined
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to check nostr status:', error)
|
||||
this.nostrStatus = {
|
||||
nostrclient_available: false,
|
||||
nostrclient_relays: [],
|
||||
nostrclient_error: 'Failed to check status',
|
||||
nostrmarket_running: false,
|
||||
websocket_connected: false
|
||||
connected: false,
|
||||
error: error.message,
|
||||
relays_connected: 0,
|
||||
relays_total: 0
|
||||
}
|
||||
if (showNotification) {
|
||||
this.$q.notify({
|
||||
timeout: 5000,
|
||||
type: 'negative',
|
||||
message: this.nostrStatus.error
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -253,13 +280,18 @@ window.app = Vue.createApp({
|
|||
)
|
||||
.onOk(async () => {
|
||||
try {
|
||||
this.$q.notify({
|
||||
timeout: 2000,
|
||||
type: 'info',
|
||||
message: 'Reconnecting...'
|
||||
})
|
||||
await LNbits.api.request(
|
||||
'PUT',
|
||||
'/nostrmarket/api/v1/restart',
|
||||
this.g.user.wallets[0].adminkey
|
||||
)
|
||||
// Check status after restart
|
||||
setTimeout(() => this.checkNostrStatus(), 2000)
|
||||
// Check status after restart (give time for websocket to reconnect)
|
||||
setTimeout(() => this.checkNostrStatus(true), 3000)
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<q-card>
|
||||
<q-card-section>
|
||||
<p class="text-body1">
|
||||
<p>
|
||||
Create, edit and publish products to your Nostr relays. Customers can
|
||||
browse your stalls and pay with Lightning.
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@
|
|||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item clickable v-close-popup @click="checkNostrStatus">
|
||||
<q-item clickable v-close-popup @click="checkNostrStatus(true)">
|
||||
<q-item-section avatar>
|
||||
<q-icon name="wifi_find" color="primary"></q-icon>
|
||||
</q-item-section>
|
||||
|
|
@ -185,27 +185,29 @@
|
|||
<q-item>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
<strong>Nostrclient:</strong>
|
||||
<strong>Status:</strong>
|
||||
<q-badge
|
||||
:color="nostrStatus.nostrclient_available ? 'green' : 'red'"
|
||||
:color="nostrStatus.connected ? 'green' : 'red'"
|
||||
class="q-ml-xs"
|
||||
v-text="nostrStatus.nostrclient_available ? 'Available' : 'Not Available'"
|
||||
></q-badge>
|
||||
<br />
|
||||
<strong>Relays:</strong>
|
||||
<span v-text="(nostrStatus.nostrclient_relays || []).length"></span> configured<br />
|
||||
<strong>WebSocket:</strong>
|
||||
<q-badge
|
||||
:color="nostrStatus.websocket_connected ? 'green' : 'orange'"
|
||||
class="q-ml-xs"
|
||||
v-text="nostrStatus.websocket_connected ? 'Connected' : 'Disconnected'"
|
||||
v-text="nostrStatus.connected ? 'Connected' : 'Disconnected'"
|
||||
></q-badge>
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
v-if="nostrStatus.nostrclient_error"
|
||||
v-if="nostrStatus.relays_total > 0"
|
||||
caption
|
||||
class="q-mt-xs"
|
||||
>
|
||||
<strong>Relays:</strong>
|
||||
<span v-text="nostrStatus.relays_connected"></span>
|
||||
of
|
||||
<span v-text="nostrStatus.relays_total"></span>
|
||||
connected
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
v-if="nostrStatus.error"
|
||||
caption
|
||||
class="text-negative q-mt-xs"
|
||||
v-text="nostrStatus.nostrclient_error"
|
||||
v-text="nostrStatus.error"
|
||||
></q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
|
|
|||
52
views_api.py
52
views_api.py
|
|
@ -1113,31 +1113,55 @@ async def api_get_nostr_status(
|
|||
) -> dict:
|
||||
"""Get the status of the nostrclient extension."""
|
||||
nostrclient_available = False
|
||||
nostrclient_relays = []
|
||||
nostrclient_error = None
|
||||
relays = []
|
||||
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,
|
||||
url = f"http://127.0.0.1:{settings.port}/nostrclient/api/v1/relays"
|
||||
logger.info(f"Calling nostrclient API: {url}")
|
||||
response = await client.get(url, timeout=5.0)
|
||||
logger.info(
|
||||
f"Nostrclient response: status={response.status_code}, "
|
||||
f"body={response.text[:500]}"
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
nostrclient_available = True
|
||||
nostrclient_relays = response.json()
|
||||
relays = response.json()
|
||||
else:
|
||||
# Any non-200 response means we can't verify nostrclient is working
|
||||
try:
|
||||
error = response.json().get("detail", f"HTTP {response.status_code}")
|
||||
except Exception:
|
||||
error = f"HTTP {response.status_code}"
|
||||
except httpx.ConnectError:
|
||||
nostrclient_error = "Cannot connect to nostrclient extension"
|
||||
error = "Cannot connect to nostrclient extension"
|
||||
except httpx.TimeoutException:
|
||||
nostrclient_error = "Timeout connecting to nostrclient"
|
||||
error = "Timeout connecting to nostrclient"
|
||||
except Exception as ex:
|
||||
nostrclient_error = str(ex)
|
||||
error = str(ex)
|
||||
|
||||
# Only show connected if no errors and websocket is connected
|
||||
connected = (
|
||||
nostrclient_available
|
||||
and nostr_client.is_websocket_connected
|
||||
and error is None
|
||||
)
|
||||
|
||||
# If nostrclient exists but websocket not connected, explain why
|
||||
if nostrclient_available and not nostr_client.is_websocket_connected and not error:
|
||||
error = "Websocket not connected"
|
||||
|
||||
# Count connected relays
|
||||
relays_connected = sum(1 for r in relays if r.get("connected", False))
|
||||
relays_total = len(relays)
|
||||
|
||||
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,
|
||||
"connected": connected,
|
||||
"error": error,
|
||||
"relays_connected": relays_connected,
|
||||
"relays_total": relays_total,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue