diff --git a/static/js/index.js b/static/js/index.js index b10220c..e180d85 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -13,19 +13,6 @@ window.app = Vue.createApp({ orderPubkey: null, showKeys: false, stallCount: 0, - importKeyDialog: { - show: false, - data: { - privateKey: null - } - }, - generateKeyDialog: { - show: false, - privateKey: null, - nsec: null, - npub: null, - showNsec: false - }, wsConnection: null, nostrStatus: { connected: false, @@ -49,23 +36,6 @@ window.app = Vue.createApp({ } }, methods: { - generateKeys: async function () { - // No longer need to generate keys here - the backend will use user's existing keypairs - await this.createMerchant() - }, - importKeys: async function () { - this.importKeyDialog.show = false - // Import keys functionality removed since we use user's native keypairs - // Show a message that this is no longer needed - this.$q.notify({ - type: 'info', - message: 'Merchants now use your account Nostr keys automatically. Key import is no longer needed.', - timeout: 3000 - }) - }, - showImportKeysDialog: async function () { - this.importKeyDialog.show = true - }, toggleShowKeys: function () { this.showKeys = !this.showKeys }, @@ -379,7 +349,11 @@ window.app = Vue.createApp({ } }, created: async function () { - await this.getMerchant() + const merchant = await this.getMerchant() + if (!merchant) { + // Auto-create merchant using the account's existing Nostr keypair + await this.createMerchant() + } await this.checkNostrStatus() setInterval(async () => { if ( diff --git a/templates/nostrmarket/index.html b/templates/nostrmarket/index.html index 949f8fe..2b6ea41 100644 --- a/templates/nostrmarket/index.html +++ b/templates/nostrmarket/index.html @@ -124,58 +124,9 @@ - - Welcome to Nostr Market!
- In Nostr Market, merchant and customer communicate via NOSTR relays, so - loss of money, product information, and reputation become far less - likely if attacked. -
- - Terms
- -
- -
-
- - Use an existing private key (hex or npub) - - - A new key pair will be generated for you - -
-
+ + +
Setting up Nostr Market...
diff --git a/views_api.py b/views_api.py index f974345..53cf9a6 100644 --- a/views_api.py +++ b/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