feat: Add phoenixd mnemonic display (#3931)
Co-authored-by: alan <alan@lnbits.com>
This commit is contained in:
co-authored by
alan
parent
7a2ddd9826
commit
07b1521dad
+4
-1
@@ -324,7 +324,8 @@ class AssetSettings(LNbitsSettings):
|
||||
"heif",
|
||||
"heics",
|
||||
"text/plain",
|
||||
"text/json" "text/xml",
|
||||
"text/json",
|
||||
"text/xml",
|
||||
"application/json",
|
||||
"application/pdf",
|
||||
]
|
||||
@@ -588,6 +589,8 @@ class ZBDFundingSource(LNbitsSettings):
|
||||
class PhoenixdFundingSource(LNbitsSettings):
|
||||
phoenixd_api_endpoint: str | None = Field(default="http://localhost:9740/")
|
||||
phoenixd_api_password: str | None = Field(default=None)
|
||||
phoenixd_data_dir: str | None = Field(default=None)
|
||||
phoenixd_mnemonic: str | None = Field(default=None)
|
||||
|
||||
|
||||
class AlbyFundingSource(LNbitsSettings):
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -275,6 +275,8 @@ window.localisation.en = {
|
||||
requires_server_restart:
|
||||
'Changing these settings requires a server restart to take effect.',
|
||||
funding_source_info: 'Select the active funding wallet',
|
||||
phoenixd_warning:
|
||||
"Phoenixd mnemonic is only available if phoenixd data-dir is specified and is readable by LNbits. It's not indicative of phoenixd not running. It just means LNbits cannot access the mnemonic to display it here.",
|
||||
latest_update: 'You are on the latest version {version}.',
|
||||
notifications: 'Notifications',
|
||||
notifications_configure: 'Configure Notifications',
|
||||
|
||||
@@ -202,7 +202,18 @@ window.app.component('lnbits-admin-funding-sources', {
|
||||
'Phoenixd',
|
||||
{
|
||||
phoenixd_api_endpoint: 'Endpoint',
|
||||
phoenixd_api_password: 'Key'
|
||||
phoenixd_api_password: 'Key',
|
||||
phoenixd_data_dir: {
|
||||
label: 'Data Directory',
|
||||
hint: 'Directory where phoenixd stores its data, including the seed phrase.'
|
||||
},
|
||||
phoenixd_mnemonic: {
|
||||
label: 'Phoenixd Seed Phrase',
|
||||
hint: 'Only available if phoenixd data-dir is specified',
|
||||
readonly: true,
|
||||
copy: true,
|
||||
qrcode: true
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
:label="prop.label"
|
||||
:hint="prop.hint"
|
||||
:value="prop.value"
|
||||
:readonly="prop.readonly || false"
|
||||
>
|
||||
<q-btn
|
||||
v-if="prop.copy"
|
||||
@@ -73,6 +74,15 @@
|
||||
></q-btn>
|
||||
</q-input>
|
||||
</div>
|
||||
<p
|
||||
v-if="fund === 'PhoenixdWallet' && key === 'phoenixd_mnemonic'"
|
||||
class="col-12 q-my-md"
|
||||
>
|
||||
<span>
|
||||
<q-icon name="warning" color="orange" size="xs"></q-icon>
|
||||
<span v-text="$t('phoenixd_warning')"></span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<q-expansion-item
|
||||
v-if="
|
||||
|
||||
@@ -4,9 +4,11 @@ import hashlib
|
||||
import json
|
||||
import urllib.parse
|
||||
from collections.abc import AsyncGenerator
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
from embit.bip39 import mnemonic_is_valid
|
||||
from httpx import RequestError, TimeoutException
|
||||
from loguru import logger
|
||||
from websockets import connect
|
||||
@@ -61,6 +63,8 @@ class PhoenixdWallet(Wallet):
|
||||
}
|
||||
|
||||
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.headers)
|
||||
self._seed_mnemonic_to_persist: str | None = None
|
||||
self._load_mnemonic_from_seed_file()
|
||||
|
||||
async def cleanup(self):
|
||||
try:
|
||||
@@ -69,6 +73,7 @@ class PhoenixdWallet(Wallet):
|
||||
logger.warning(f"Error closing wallet connection: {e}")
|
||||
|
||||
async def status(self) -> StatusResponse:
|
||||
await self._persist_loaded_mnemonic()
|
||||
try:
|
||||
r = await self.client.get("/getinfo", timeout=10)
|
||||
r.raise_for_status()
|
||||
@@ -101,7 +106,6 @@ class PhoenixdWallet(Wallet):
|
||||
unhashed_description: bytes | None = None,
|
||||
**kwargs,
|
||||
) -> InvoiceResponse:
|
||||
|
||||
try:
|
||||
msats_amount = amount
|
||||
data: dict[str, Any] = {
|
||||
@@ -309,7 +313,7 @@ class PhoenixdWallet(Wallet):
|
||||
and message_json.get("type") == "payment_received"
|
||||
):
|
||||
logger.info(
|
||||
f'payment-received: {message_json["paymentHash"]}'
|
||||
f"payment-received: {message_json['paymentHash']}"
|
||||
)
|
||||
yield message_json["paymentHash"]
|
||||
|
||||
@@ -319,3 +323,49 @@ class PhoenixdWallet(Wallet):
|
||||
"retrying in 5 seconds"
|
||||
)
|
||||
await asyncio.sleep(5)
|
||||
|
||||
def _load_mnemonic_from_seed_file(self):
|
||||
data_dir = settings.phoenixd_data_dir
|
||||
if not data_dir:
|
||||
return
|
||||
|
||||
seed_path = Path(data_dir).expanduser() / "seed.dat"
|
||||
if not seed_path.is_file():
|
||||
return
|
||||
|
||||
try:
|
||||
mnemonic = seed_path.read_text(encoding="utf-8").strip()
|
||||
if mnemonic == settings.phoenixd_mnemonic:
|
||||
return
|
||||
except OSError as exc:
|
||||
logger.warning(f"Failed to read Phoenixd seed file '{seed_path}': {exc}")
|
||||
return
|
||||
|
||||
if not mnemonic:
|
||||
logger.warning(f"Phoenixd seed file '{seed_path}' is empty.")
|
||||
return
|
||||
|
||||
if not mnemonic_is_valid(mnemonic):
|
||||
logger.warning(
|
||||
f"Phoenixd seed file '{seed_path}' does not contain a valid "
|
||||
"BIP39 mnemonic."
|
||||
)
|
||||
return
|
||||
|
||||
settings.phoenixd_mnemonic = mnemonic
|
||||
self._seed_mnemonic_to_persist = mnemonic
|
||||
|
||||
async def _persist_loaded_mnemonic(self):
|
||||
if not self._seed_mnemonic_to_persist:
|
||||
return
|
||||
|
||||
logger.info("Updating 'PHOENIXD_MNEMONIC' mnemonic settings.")
|
||||
try:
|
||||
from lnbits.core.crud.settings import set_settings_field
|
||||
|
||||
await set_settings_field(
|
||||
"phoenixd_mnemonic", self._seed_mnemonic_to_persist
|
||||
)
|
||||
self._seed_mnemonic_to_persist = None
|
||||
except Exception as exc:
|
||||
logger.warning(f"Failed to persist Phoenixd mnemonic: {exc}")
|
||||
|
||||
Reference in New Issue
Block a user