@@ -48,7 +46,6 @@
diff --git a/views_api.py b/views_api.py
index ad26520..7d44efb 100644
--- a/views_api.py
+++ b/views_api.py
@@ -22,9 +22,8 @@ from pydantic import BaseModel
from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user
-from lnbits.core.crud.users import get_account
-from lnbits.core.crud.wallets import get_wallet
from lnbits.core.models import Account, WalletTypeInfo
+from lnbits.core.signers import NostrSigner, resolve_for_wallet
from lnbits.decorators import (
check_admin,
check_user_exists,
@@ -108,53 +107,47 @@ restaurant_api_router = APIRouter()
# --------------------------------------------------------------------- #
-async def _resolve_signing_keypair(
+async def _resolve_signer(
restaurant: Restaurant,
-) -> Optional[tuple[str, str]]:
+) -> Optional[NostrSigner]:
"""
- Resolve the (pubkey, prvkey) pair for signing Nostr events on behalf
- of a restaurant.
+ Resolve a `NostrSigner` for signing events on behalf of a restaurant.
Order of precedence:
- 1. restaurant.nostr_pubkey is set → use a per-restaurant key.
- (Storage of the corresponding prvkey is intentionally out of
- scope here; for now this branch is a no-op until we ship a
- secret-management approach. Returns None.)
- 2. Otherwise → fall back to the LNbits Account keypair of the
- wallet owner.
+ 1. restaurant.nostr_pubkey is set → per-restaurant identity.
+ (A per-restaurant signer/vault is out of scope here; until
+ that lands this branch is a no-op. Returns None.)
+ 2. Otherwise → fall back to the wallet owner's signer via
+ `resolve_for_wallet` (wallet → account → signer with a
+ can_sign-check; soft-fails to None on missing wallet, missing
+ account, unclassified row, or ClientSideOnlySigner accounts
+ where the server has no signing authority).
"""
if restaurant.nostr_pubkey:
- # TODO: per-restaurant secret key vault.
+ # TODO: per-restaurant signer / secret vault.
return None
- wallet_obj = await get_wallet(restaurant.wallet)
- if not wallet_obj:
- return None
- account = await get_account(wallet_obj.user)
- if not account or not account.pubkey or not account.prvkey:
- return None
- return account.pubkey, account.prvkey
+ return await resolve_for_wallet(restaurant.wallet)
async def _publish_restaurant(restaurant: Restaurant) -> None:
settings = await get_settings()
if not settings.nostr_publish_enabled:
return
- keypair = await _resolve_signing_keypair(restaurant)
- if not keypair:
+ signer = await _resolve_signer(restaurant)
+ if signer is None:
return
- pubkey, prvkey = keypair
from . import nostr_client
- event = build_restaurant_metadata_event(restaurant, pubkey)
- published = await publish_event(nostr_client, event, prvkey)
+ event = build_restaurant_metadata_event(restaurant, signer.pubkey)
+ published = await publish_event(nostr_client, event, signer)
if published:
restaurant.nostr_event_id = published.id
restaurant.nostr_event_created_at = published.created_at
if not restaurant.nostr_pubkey:
# Echo back the resolved pubkey so the row carries it for
# discovery (e.g. webapp follows this pubkey).
- restaurant.nostr_pubkey = pubkey
+ restaurant.nostr_pubkey = signer.pubkey
await update_restaurant(restaurant)
@@ -188,18 +181,17 @@ async def _publish_menu_item(item: MenuItem) -> None:
restaurant = await get_restaurant(item.restaurant_id)
if not restaurant:
return
- keypair = await _resolve_signing_keypair(restaurant)
- if not keypair:
+ signer = await _resolve_signer(restaurant)
+ if signer is None:
return
- pubkey, prvkey = keypair
from . import nostr_client
ancestors = await _ancestor_names_for_node(item.node_id)
event = build_menu_item_event(
- item, restaurant, pubkey, ancestor_names=ancestors
+ item, restaurant, signer.pubkey, ancestor_names=ancestors
)
- published = await publish_event(nostr_client, event, prvkey)
+ published = await publish_event(nostr_client, event, signer)
if published:
item.nostr_event_id = published.id
item.nostr_event_created_at = published.created_at
@@ -213,15 +205,14 @@ async def _publish_menu_item_delete(item: MenuItem) -> None:
restaurant = await get_restaurant(item.restaurant_id)
if not restaurant:
return
- keypair = await _resolve_signing_keypair(restaurant)
- if not keypair:
+ signer = await _resolve_signer(restaurant)
+ if signer is None:
return
- pubkey, prvkey = keypair
from . import nostr_client
- event = build_delete_event(30402, item.id, pubkey, "Menu item removed")
- await publish_event(nostr_client, event, prvkey)
+ event = build_delete_event(30402, item.id, signer.pubkey, "Menu item removed")
+ await publish_event(nostr_client, event, signer)
def _require_owner(restaurant: Restaurant, wallet: WalletTypeInfo) -> None: