Auto-provision merchant from account keypair on first access
The LNbits user account IS the merchant identity. GET /api/v1/merchant now auto-creates the merchant record using the account's existing Nostr keypair if one doesn't exist yet, so the extension is immediately usable without any setup screen. - Extract _auto_create_merchant() helper used by both GET and POST - Remove welcome/key-generation screen (replaced with loading spinner) - Remove dead frontend code (generateKeys, importKeys dialogs) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
725944ae9c
commit
5c38947fc6
3 changed files with 62 additions and 136 deletions
107
views_api.py
107
views_api.py
|
|
@ -93,6 +93,56 @@ from .services import (
|
|||
######################################## MERCHANT ######################################
|
||||
|
||||
|
||||
async def _auto_create_merchant(
|
||||
wallet: WalletTypeInfo,
|
||||
config: MerchantConfig | None = None,
|
||||
) -> Merchant:
|
||||
"""
|
||||
Provision a merchant record from the user's account keypair.
|
||||
Called automatically on first GET or explicitly via POST.
|
||||
"""
|
||||
account = await get_account(wallet.wallet.user)
|
||||
assert account, "User account not found"
|
||||
|
||||
# In our fork, accounts always have keypairs.
|
||||
# Generate as fallback only if somehow missing.
|
||||
if not account.pubkey or not account.prvkey:
|
||||
private_key, public_key = generate_keypair()
|
||||
account.pubkey = public_key
|
||||
account.prvkey = private_key
|
||||
await update_account(account)
|
||||
else:
|
||||
public_key = account.pubkey
|
||||
private_key = account.prvkey
|
||||
|
||||
existing_merchant = await get_merchant_by_pubkey(public_key)
|
||||
assert existing_merchant is None, "A merchant already uses this public key"
|
||||
|
||||
partial_merchant = PartialMerchant(
|
||||
private_key=private_key,
|
||||
public_key=public_key,
|
||||
config=config or MerchantConfig(),
|
||||
)
|
||||
|
||||
merchant = await create_merchant(wallet.wallet.user, partial_merchant)
|
||||
|
||||
await create_zone(
|
||||
merchant.id,
|
||||
Zone(
|
||||
id=f"online-{merchant.public_key}",
|
||||
name="Online",
|
||||
currency="sat",
|
||||
cost=0,
|
||||
countries=["Free (digital)"],
|
||||
),
|
||||
)
|
||||
|
||||
await resubscribe_to_all_merchants()
|
||||
await nostr_client.merchant_temp_subscription(public_key)
|
||||
|
||||
return merchant
|
||||
|
||||
|
||||
@nostrmarket_ext.post("/api/v1/merchant")
|
||||
async def api_create_merchant(
|
||||
data: CreateMerchantRequest,
|
||||
|
|
@ -100,60 +150,10 @@ async def api_create_merchant(
|
|||
) -> Merchant:
|
||||
|
||||
try:
|
||||
# Check if merchant already exists for this user
|
||||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
assert merchant is None, "A merchant already exists for this user"
|
||||
|
||||
# Get user's account to access their Nostr keypairs
|
||||
account = await get_account(wallet.wallet.user)
|
||||
if not account:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="User account not found",
|
||||
)
|
||||
|
||||
# Check if user has Nostr keypairs, generate them if not
|
||||
if not account.pubkey or not account.prvkey:
|
||||
# Generate new keypair for user
|
||||
private_key, public_key = generate_keypair()
|
||||
|
||||
# Update user account with new keypairs
|
||||
account.pubkey = public_key
|
||||
account.prvkey = private_key
|
||||
await update_account(account)
|
||||
else:
|
||||
public_key = account.pubkey
|
||||
private_key = account.prvkey
|
||||
|
||||
# Check if another merchant is already using this public key
|
||||
existing_merchant = await get_merchant_by_pubkey(public_key)
|
||||
assert existing_merchant is None, "A merchant already uses this public key"
|
||||
|
||||
# Create PartialMerchant with user's keypairs
|
||||
partial_merchant = PartialMerchant(
|
||||
private_key=private_key,
|
||||
public_key=public_key,
|
||||
config=data.config
|
||||
)
|
||||
|
||||
merchant = await create_merchant(wallet.wallet.user, partial_merchant)
|
||||
|
||||
await create_zone(
|
||||
merchant.id,
|
||||
Zone(
|
||||
id=f"online-{merchant.public_key}",
|
||||
name="Online",
|
||||
currency="sat",
|
||||
cost=0,
|
||||
countries=["Free (digital)"],
|
||||
),
|
||||
)
|
||||
|
||||
await resubscribe_to_all_merchants()
|
||||
|
||||
await nostr_client.merchant_temp_subscription(public_key)
|
||||
|
||||
return merchant
|
||||
return await _auto_create_merchant(wallet, data.config)
|
||||
except AssertionError as ex:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
|
|
@ -170,12 +170,13 @@ async def api_create_merchant(
|
|||
@nostrmarket_ext.get("/api/v1/merchant")
|
||||
async def api_get_merchant(
|
||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||
) -> Optional[Merchant]:
|
||||
) -> Merchant:
|
||||
|
||||
try:
|
||||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
if not merchant:
|
||||
return None
|
||||
# Auto-provision merchant from the user's account keypair
|
||||
merchant = await _auto_create_merchant(wallet)
|
||||
|
||||
merchant = await touch_merchant(wallet.wallet.user, merchant.id)
|
||||
assert merchant
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue