diff --git a/__init__.py b/__init__.py index b4f7af0..4a2d0e7 100644 --- a/__init__.py +++ b/__init__.py @@ -42,9 +42,13 @@ from .views_api import * # noqa def nostrmarket_start(): async def _subscribe_to_nostr_client(): + # wait for 'nostrclient' extension to initialize + await asyncio.sleep(10) await subscribe_to_nostr_client(recieve_event_queue, send_req_queue) async def _wait_for_nostr_events(): + # wait for this extension to initialize + await asyncio.sleep(5) await wait_for_nostr_events(recieve_event_queue, send_req_queue) loop = asyncio.get_event_loop() diff --git a/crud.py b/crud.py index 5fbad90..5e56000 100644 --- a/crud.py +++ b/crud.py @@ -76,16 +76,16 @@ async def get_merchant_for_user(user_id: str) -> Optional[Merchant]: ######################################## ZONES ######################################## -async def create_zone(user_id: str, data: PartialZone) -> Zone: +async def create_zone(merchant_id: str, data: PartialZone) -> Zone: zone_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO nostrmarket.zones (id, user_id, name, currency, cost, regions) + INSERT INTO nostrmarket.zones (id, merchant_id, name, currency, cost, regions) VALUES (?, ?, ?, ?, ?, ?) """, ( zone_id, - user_id, + merchant_id, data.name, data.currency, data.cost, @@ -93,55 +93,67 @@ async def create_zone(user_id: str, data: PartialZone) -> Zone: ), ) - zone = await get_zone(user_id, zone_id) + zone = await get_zone(merchant_id, zone_id) assert zone, "Newly created zone couldn't be retrieved" return zone -async def update_zone(user_id: str, z: Zone) -> Optional[Zone]: +async def update_zone(merchant_id: str, z: Zone) -> Optional[Zone]: await db.execute( - f"UPDATE nostrmarket.zones SET name = ?, cost = ?, regions = ? WHERE id = ? AND user_id = ?", - (z.name, z.cost, json.dumps(z.countries), z.id, user_id), + f"UPDATE nostrmarket.zones SET name = ?, cost = ?, regions = ? WHERE id = ? AND merchant_id = ?", + (z.name, z.cost, json.dumps(z.countries), z.id, merchant_id), ) - return await get_zone(user_id, z.id) + return await get_zone(merchant_id, z.id) -async def get_zone(user_id: str, zone_id: str) -> Optional[Zone]: +async def get_zone(merchant_id: str, zone_id: str) -> Optional[Zone]: row = await db.fetchone( - "SELECT * FROM nostrmarket.zones WHERE user_id = ? AND id = ?", + "SELECT * FROM nostrmarket.zones WHERE merchant_id = ? AND id = ?", ( - user_id, + merchant_id, zone_id, ), ) return Zone.from_row(row) if row else None -async def get_zones(user_id: str) -> List[Zone]: +async def get_zones(merchant_id: str) -> List[Zone]: rows = await db.fetchall( - "SELECT * FROM nostrmarket.zones WHERE user_id = ?", (user_id,) + "SELECT * FROM nostrmarket.zones WHERE merchant_id = ?", (merchant_id,) ) return [Zone.from_row(row) for row in rows] -async def delete_zone(zone_id: str) -> None: - # todo: add user_id - await db.execute("DELETE FROM nostrmarket.zones WHERE id = ?", (zone_id,)) +async def delete_zone(merchant_id: str, zone_id: str) -> None: + + await db.execute( + "DELETE FROM nostrmarket.zones WHERE merchant_id = ? AND id = ?", + ( + merchant_id, + zone_id, + ), + ) + + +async def delete_merchant_zones(merchant_id: str) -> None: + await db.execute( + "DELETE FROM nostrmarket.zones WHERE merchant_id = ?", (merchant_id,) + ) ######################################## STALL ######################################## -async def create_stall(user_id: str, data: PartialStall) -> Stall: +async def create_stall(merchant_id: str, data: PartialStall) -> Stall: stall_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO nostrmarket.stalls (user_id, id, wallet, name, currency, zones, meta) + INSERT INTO nostrmarket.stalls (merchant_id, id, wallet, name, currency, zones, meta) VALUES (?, ?, ?, ?, ?, ?, ?) """, ( - user_id, + merchant_id, stall_id, data.wallet, data.name, @@ -153,35 +165,35 @@ async def create_stall(user_id: str, data: PartialStall) -> Stall: ), ) - stall = await get_stall(user_id, stall_id) + stall = await get_stall(merchant_id, stall_id) assert stall, "Newly created stall couldn't be retrieved" return stall -async def get_stall(user_id: str, stall_id: str) -> Optional[Stall]: +async def get_stall(merchant_id: str, stall_id: str) -> Optional[Stall]: row = await db.fetchone( - "SELECT * FROM nostrmarket.stalls WHERE user_id = ? AND id = ?", + "SELECT * FROM nostrmarket.stalls WHERE merchant_id = ? AND id = ?", ( - user_id, + merchant_id, stall_id, ), ) return Stall.from_row(row) if row else None -async def get_stalls(user_id: str) -> List[Stall]: +async def get_stalls(merchant_id: str) -> List[Stall]: rows = await db.fetchall( - "SELECT * FROM nostrmarket.stalls WHERE user_id = ?", - (user_id,), + "SELECT * FROM nostrmarket.stalls WHERE merchant_id = ?", + (merchant_id,), ) return [Stall.from_row(row) for row in rows] -async def update_stall(user_id: str, stall: Stall) -> Optional[Stall]: +async def update_stall(merchant_id: str, stall: Stall) -> Optional[Stall]: await db.execute( f""" UPDATE nostrmarket.stalls SET wallet = ?, name = ?, currency = ?, zones = ?, meta = ? - WHERE user_id = ? AND id = ? + WHERE merchant_id = ? AND id = ? """, ( stall.wallet, @@ -191,18 +203,18 @@ async def update_stall(user_id: str, stall: Stall) -> Optional[Stall]: [z.dict() for z in stall.shipping_zones] ), # todo: cost is float. should be int for sats json.dumps(stall.config.dict()), - user_id, + merchant_id, stall.id, ), ) - return await get_stall(user_id, stall.id) + return await get_stall(merchant_id, stall.id) -async def delete_stall(user_id: str, stall_id: str) -> None: +async def delete_stall(merchant_id: str, stall_id: str) -> None: await db.execute( - "DELETE FROM nostrmarket.stalls WHERE user_id =? AND id = ?", + "DELETE FROM nostrmarket.stalls WHERE merchant_id =? AND id = ?", ( - user_id, + merchant_id, stall_id, ), ) @@ -211,16 +223,16 @@ async def delete_stall(user_id: str, stall_id: str) -> None: ######################################## PRODUCTS ######################################## -async def create_product(user_id: str, data: PartialProduct) -> Product: +async def create_product(merchant_id: str, data: PartialProduct) -> Product: product_id = urlsafe_short_hash() await db.execute( f""" - INSERT INTO nostrmarket.products (user_id, id, stall_id, name, image, price, quantity, category_list, meta) + INSERT INTO nostrmarket.products (merchant_id, id, stall_id, name, image, price, quantity, category_list, meta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( - user_id, + merchant_id, product_id, data.stall_id, data.name, @@ -231,18 +243,18 @@ async def create_product(user_id: str, data: PartialProduct) -> Product: json.dumps(data.config.dict()), ), ) - product = await get_product(user_id, product_id) + product = await get_product(merchant_id, product_id) assert product, "Newly created product couldn't be retrieved" return product -async def update_product(user_id: str, product: Product) -> Product: +async def update_product(merchant_id: str, product: Product) -> Product: await db.execute( f""" UPDATE nostrmarket.products set name = ?, image = ?, price = ?, quantity = ?, category_list = ?, meta = ? - WHERE user_id = ? AND id = ? + WHERE merchant_id = ? AND id = ? """, ( product.name, @@ -251,40 +263,42 @@ async def update_product(user_id: str, product: Product) -> Product: product.quantity, json.dumps(product.categories), json.dumps(product.config.dict()), - user_id, + merchant_id, product.id, ), ) - updated_product = await get_product(user_id, product.id) + updated_product = await get_product(merchant_id, product.id) assert updated_product, "Updated product couldn't be retrieved" return updated_product -async def get_product(user_id: str, product_id: str) -> Optional[Product]: +async def get_product(merchant_id: str, product_id: str) -> Optional[Product]: row = await db.fetchone( - "SELECT * FROM nostrmarket.products WHERE user_id =? AND id = ?", + "SELECT * FROM nostrmarket.products WHERE merchant_id =? AND id = ?", ( - user_id, + merchant_id, product_id, ), ) return Product.from_row(row) if row else None -async def get_products(user_id: str, stall_id: str) -> List[Product]: +async def get_products(merchant_id: str, stall_id: str) -> List[Product]: rows = await db.fetchall( - "SELECT * FROM nostrmarket.products WHERE user_id = ? AND stall_id = ?", - (user_id, stall_id), + "SELECT * FROM nostrmarket.products WHERE merchant_id = ? AND stall_id = ?", + (merchant_id, stall_id), ) return [Product.from_row(row) for row in rows] -async def get_products_by_ids(user_id: str, product_ids: List[str]) -> List[Product]: +async def get_products_by_ids( + merchant_id: str, product_ids: List[str] +) -> List[Product]: q = ",".join(["?"] * len(product_ids)) rows = await db.fetchall( - f"SELECT id, stall_id, name, price, quantity, category_list, meta FROM nostrmarket.products WHERE user_id = ? AND id IN ({q})", - (user_id, *product_ids), + f"SELECT id, stall_id, name, price, quantity, category_list, meta FROM nostrmarket.products WHERE merchant_id = ? AND id IN ({q})", + (merchant_id, *product_ids), ) return [Product.from_row(row) for row in rows] @@ -302,11 +316,11 @@ async def get_wallet_for_product(product_id: str) -> Optional[str]: return row[0] if row else None -async def delete_product(user_id: str, product_id: str) -> None: +async def delete_product(merchant_id: str, product_id: str) -> None: await db.execute( - "DELETE FROM nostrmarket.products WHERE user_id =? AND id = ?", + "DELETE FROM nostrmarket.products WHERE merchant_id =? AND id = ?", ( - user_id, + merchant_id, product_id, ), ) @@ -315,11 +329,11 @@ async def delete_product(user_id: str, product_id: str) -> None: ######################################## ORDERS ######################################## -async def create_order(user_id: str, o: Order) -> Order: +async def create_order(merchant_id: str, o: Order) -> Order: await db.execute( f""" INSERT INTO nostrmarket.orders ( - user_id, + merchant_id, id, event_id, event_created_at, @@ -337,7 +351,7 @@ async def create_order(user_id: str, o: Order) -> Order: ON CONFLICT(event_id) DO NOTHING """, ( - user_id, + merchant_id, o.id, o.event_id, o.event_created_at, @@ -352,47 +366,47 @@ async def create_order(user_id: str, o: Order) -> Order: o.total, ), ) - order = await get_order(user_id, o.id) + order = await get_order(merchant_id, o.id) assert order, "Newly created order couldn't be retrieved" return order -async def get_order(user_id: str, order_id: str) -> Optional[Order]: +async def get_order(merchant_id: str, order_id: str) -> Optional[Order]: row = await db.fetchone( - "SELECT * FROM nostrmarket.orders WHERE user_id =? AND id = ?", + "SELECT * FROM nostrmarket.orders WHERE merchant_id =? AND id = ?", ( - user_id, + merchant_id, order_id, ), ) return Order.from_row(row) if row else None -async def get_order_by_event_id(user_id: str, event_id: str) -> Optional[Order]: +async def get_order_by_event_id(merchant_id: str, event_id: str) -> Optional[Order]: row = await db.fetchone( - "SELECT * FROM nostrmarket.orders WHERE user_id =? AND event_id =?", + "SELECT * FROM nostrmarket.orders WHERE merchant_id =? AND event_id =?", ( - user_id, + merchant_id, event_id, ), ) return Order.from_row(row) if row else None -async def get_orders(user_id: str) -> List[Order]: +async def get_orders(merchant_id: str) -> List[Order]: rows = await db.fetchall( - "SELECT * FROM nostrmarket.orders WHERE user_id = ? ORDER BY time DESC", - (user_id,), + "SELECT * FROM nostrmarket.orders WHERE merchant_id = ? ORDER BY time DESC", + (merchant_id,), ) return [Order.from_row(row) for row in rows] -async def get_orders_for_stall(user_id: str, stall_id: str) -> List[Order]: +async def get_orders_for_stall(merchant_id: str, stall_id: str) -> List[Order]: rows = await db.fetchall( - "SELECT * FROM nostrmarket.orders WHERE user_id = ? AND stall_id = ? ORDER BY time DESC", + "SELECT * FROM nostrmarket.orders WHERE merchant_id = ? AND stall_id = ? ORDER BY time DESC", ( - user_id, + merchant_id, stall_id, ), ) @@ -423,11 +437,11 @@ async def update_order_paid_status(order_id: str, paid: bool) -> Optional[Order] async def update_order_shipped_status( - user_id: str, order_id: str, shipped: bool + merchant_id: str, order_id: str, shipped: bool ) -> Optional[Order]: await db.execute( - f"UPDATE nostrmarket.orders SET shipped = ? WHERE user_id = ? AND id = ?", - (shipped, user_id, order_id), + f"UPDATE nostrmarket.orders SET shipped = ? WHERE merchant_id = ? AND id = ?", + (shipped, merchant_id, order_id), ) row = await db.fetchone( @@ -460,8 +474,10 @@ async def create_direct_message( dm.incoming, ), ) - - msg = await get_direct_message(merchant_id, dm_id) + if dm.event_id: + msg = await get_direct_message_by_event_id(merchant_id, dm.event_id) + else: + msg = await get_direct_message(merchant_id, dm_id) assert msg, "Newly created dm couldn't be retrieved" return msg @@ -476,6 +492,16 @@ async def get_direct_message(merchant_id: str, dm_id: str) -> Optional[DirectMes ) return DirectMessage.from_row(row) if row else None +async def get_direct_message_by_event_id(merchant_id: str, event_id: str) -> Optional[DirectMessage]: + row = await db.fetchone( + "SELECT * FROM nostrmarket.direct_messages WHERE merchant_id = ? AND event_id = ?", + ( + merchant_id, + event_id, + ), + ) + return DirectMessage.from_row(row) if row else None + async def get_direct_messages(merchant_id: str, public_key: str) -> List[DirectMessage]: rows = await db.fetchall( diff --git a/helpers.py b/helpers.py index ee73cd9..d06598d 100644 --- a/helpers.py +++ b/helpers.py @@ -16,6 +16,8 @@ def get_shared_secret(privkey: str, pubkey: str): def decrypt_message(encoded_message: str, encryption_key) -> str: encoded_data = encoded_message.split("?iv=") + if len(encoded_data) == 1: + return encoded_data[0] encoded_content, encoded_iv = encoded_data[0], encoded_data[1] iv = base64.b64decode(encoded_iv) diff --git a/migrations.py b/migrations.py index 522fa7b..530f12e 100644 --- a/migrations.py +++ b/migrations.py @@ -18,11 +18,11 @@ async def m001_initial(db): """ Initial stalls table. """ - # user_id, id, wallet, name, currency, zones, meta + await db.execute( """ CREATE TABLE nostrmarket.stalls ( - user_id TEXT NOT NULL, + merchant_id TEXT NOT NULL, id TEXT PRIMARY KEY, wallet TEXT NOT NULL, name TEXT NOT NULL, @@ -39,7 +39,7 @@ async def m001_initial(db): await db.execute( """ CREATE TABLE nostrmarket.products ( - user_id TEXT NOT NULL, + merchant_id TEXT NOT NULL, id TEXT PRIMARY KEY, stall_id TEXT NOT NULL, name TEXT NOT NULL, @@ -59,7 +59,7 @@ async def m001_initial(db): """ CREATE TABLE nostrmarket.zones ( id TEXT PRIMARY KEY, - user_id TEXT NOT NULL, + merchant_id TEXT NOT NULL, name TEXT NOT NULL, currency TEXT NOT NULL, cost REAL NOT NULL, @@ -75,7 +75,7 @@ async def m001_initial(db): await db.execute( f""" CREATE TABLE nostrmarket.orders ( - user_id TEXT NOT NULL, + merchant_id TEXT NOT NULL, id TEXT PRIMARY KEY, event_id TEXT, event_created_at INTEGER NOT NULL, @@ -120,8 +120,8 @@ async def m001_initial(db): Create indexes for message fetching """ await db.execute( - "CREATE INDEX idx_messages_timestamp ON nostrmarket.messages (timestamp DESC)" + "CREATE INDEX idx_messages_timestamp ON nostrmarket.direct_messages (time DESC)" ) await db.execute( - "CREATE INDEX idx_messages_conversations ON nostrmarket.messages (conversation_id)" + "CREATE INDEX idx_event_id ON nostrmarket.direct_messages (event_id)" ) diff --git a/nostr/nostr_client.py b/nostr/nostr_client.py index 3e8a47e..a05c4ea 100644 --- a/nostr/nostr_client.py +++ b/nostr/nostr_client.py @@ -33,7 +33,7 @@ async def connect_to_nostrclient_ws( logger.debug(f"Subscribing to websockets for nostrclient extension") ws = WebSocketApp( - f"ws://localhost:{settings.port}/nostrclient/api/v1/filters", + f"ws://localhost:{settings.port}/nostrclient/api/v1/relay", on_message=on_message, on_open=on_open, on_error=on_error, diff --git a/services.py b/services.py index 5f11739..18ff95e 100644 --- a/services.py +++ b/services.py @@ -33,17 +33,19 @@ from .nostr.nostr_client import publish_nostr_event async def create_new_order( - user_id: str, data: PartialOrder + merchant_public_key: str, data: PartialOrder ) -> Optional[PaymentRequest]: - if await get_order(user_id, data.id): - return None - if data.event_id and await get_order_by_event_id(user_id, data.event_id): - return None - - merchant = await get_merchant_for_user(user_id) + merchant = await get_merchant_by_pubkey(merchant_public_key) assert merchant, "Cannot find merchant!" - products = await get_products_by_ids(user_id, [p.product_id for p in data.items]) + if await get_order(merchant.id, data.id): + return None + if data.event_id and await get_order_by_event_id(merchant.id, data.event_id): + return None + + products = await get_products_by_ids( + merchant.id, [p.product_id for p in data.items] + ) data.validate_order_items(products) total_amount = await data.total_sats(products) @@ -69,7 +71,7 @@ async def create_new_order( total=total_amount, extra=await OrderExtra.from_products(products), ) - await create_order(user_id, order) + await create_order(merchant.id, order) return PaymentRequest( id=data.id, payment_options=[PaymentOption(type="ln", link=invoice)] @@ -77,11 +79,8 @@ async def create_new_order( async def sign_and_send_to_nostr( - user_id: str, n: Nostrable, delete=False + merchant: Merchant, n: Nostrable, delete=False ) -> NostrEvent: - merchant = await get_merchant_for_user(user_id) - assert merchant, "Cannot find merchant!" - event = ( n.to_nostr_delete_event(merchant.public_key) if delete @@ -115,24 +114,28 @@ async def handle_order_paid(order_id: str, merchant_pubkey: str): async def process_nostr_message(msg: str): try: - type, subscription_id, event = json.loads(msg) - subscription_name, public_key = subscription_id.split(":") + type, *rest= json.loads(msg) if type.upper() == "EVENT": + subscription_id, event = rest + subscription_name, merchant_public_key = subscription_id.split(":") event = NostrEvent(**event) if event.kind == 4: - await _handle_nip04_message(subscription_name, public_key, event) - + await _handle_nip04_message( + subscription_name, merchant_public_key, event + ) + return except Exception as ex: logger.warning(ex) async def _handle_nip04_message( - subscription_name: str, public_key: str, event: NostrEvent + subscription_name: str, merchant_public_key: str, event: NostrEvent ): - merchant = await get_merchant_by_pubkey(public_key) - assert merchant, f"Merchant not found for public key '{public_key}'" + merchant = await get_merchant_by_pubkey(merchant_public_key) + assert merchant, f"Merchant not found for public key '{merchant_public_key}'" clear_text_msg = merchant.decrypt_message(event.content, event.pubkey) + # print("### clear_text_msg", subscription_name, clear_text_msg) if subscription_name == "direct-messages-in": await _handle_incoming_dms(event, merchant, clear_text_msg) else: @@ -187,7 +190,7 @@ async def _handle_dirrect_message( order["event_created_at"] = event_created_at return await _handle_new_order(PartialOrder(**order)) else: - print("### text_msg", text_msg, event_created_at, event_id) + # print("### text_msg", text_msg, event_created_at, event_id) dm = PartialDirectMessage( event_id=event_id, event_created_at=event_created_at, diff --git a/static/components/stall-list/stall-list.html b/static/components/stall-list/stall-list.html index bc6236e..ea738bf 100644 --- a/static/components/stall-list/stall-list.html +++ b/static/components/stall-list/stall-list.html @@ -6,7 +6,7 @@ unelevated color="green" class="float-left" - >New StallNew Stall (Store)
- +
+ + +
+
+ +
+
+
+ +
+
+
+ + + +
+ + + + + +
+ Wellcome to Nostr Market!
In Nostr Market, merchant and customer communicate via NOSTR relays, so @@ -57,44 +95,6 @@
-
- - -
-
- -
-
-
- -
-
-
- - - -
- - - - - -
diff --git a/views_api.py b/views_api.py index 1f9aaee..4027434 100644 --- a/views_api.py +++ b/views_api.py @@ -13,6 +13,7 @@ from lnbits.decorators import ( require_admin_key, require_invoice_key, ) +from lnbits.extensions.nostrmarket.helpers import get_shared_secret from lnbits.utils.exchange_rates import currencies from . import nostrmarket_ext, scheduled_tasks @@ -22,6 +23,7 @@ from .crud import ( create_product, create_stall, create_zone, + delete_merchant_zones, delete_product, delete_stall, delete_zone, @@ -69,6 +71,7 @@ async def api_create_merchant( try: merchant = await create_merchant(wallet.wallet.user, data) + return merchant except Exception as ex: logger.warning(ex) @@ -94,13 +97,33 @@ async def api_get_merchant( ) +@nostrmarket_ext.delete("/api/v1/merchant") +async def api_delete_merchant( + wallet: WalletTypeInfo = Depends(require_admin_key), +): + + try: + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + await delete_merchant_zones(wallet.wallet.user) + except Exception as ex: + logger.warning(ex) + raise HTTPException( + status_code=HTTPStatus.INTERNAL_SERVER_ERROR, + detail="Cannot get merchant", + ) + + ######################################## ZONES ######################################## @nostrmarket_ext.get("/api/v1/zone") async def api_get_zones(wallet: WalletTypeInfo = Depends(get_key_type)) -> List[Zone]: try: - return await get_zones(wallet.wallet.user) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + return await get_zones(merchant.id) except Exception as ex: logger.warning(ex) raise HTTPException( @@ -114,7 +137,9 @@ async def api_create_zone( data: PartialZone, wallet: WalletTypeInfo = Depends(require_admin_key) ): try: - zone = await create_zone(wallet.wallet.user, data) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + zone = await create_zone(merchant.id, data) return zone except Exception as ex: logger.warning(ex) @@ -131,7 +156,9 @@ async def api_update_zone( wallet: WalletTypeInfo = Depends(require_admin_key), ) -> Zone: try: - zone = await get_zone(wallet.wallet.user, zone_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + zone = await get_zone(merchant.id, zone_id) if not zone: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -153,7 +180,9 @@ async def api_update_zone( @nostrmarket_ext.delete("/api/v1/zone/{zone_id}") async def api_delete_zone(zone_id, wallet: WalletTypeInfo = Depends(require_admin_key)): try: - zone = await get_zone(wallet.wallet.user, zone_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + zone = await get_zone(merchant.id, zone_id) if not zone: raise HTTPException( @@ -161,7 +190,7 @@ async def api_delete_zone(zone_id, wallet: WalletTypeInfo = Depends(require_admi detail="Zone does not exist.", ) - await delete_zone(zone_id) + await delete_zone(wallet.wallet.user, zone_id) except Exception as ex: logger.warning(ex) @@ -182,12 +211,14 @@ async def api_create_stall( try: data.validate_stall() - stall = await create_stall(wallet.wallet.user, data=data) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + stall = await create_stall(merchant.id, data=data) - event = await sign_and_send_to_nostr(wallet.wallet.user, stall) + event = await sign_and_send_to_nostr(merchant, stall) stall.config.event_id = event.id - await update_stall(wallet.wallet.user, stall) + await update_stall(merchant.id, stall) return stall except ValueError as ex: @@ -211,13 +242,16 @@ async def api_update_stall( try: data.validate_stall() - stall = await update_stall(wallet.wallet.user, data) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + stall = await update_stall(merchant.id, data) assert stall, "Cannot update stall" - event = await sign_and_send_to_nostr(wallet.wallet.user, stall) + event = await sign_and_send_to_nostr(merchant, stall) stall.config.event_id = event.id - await update_stall(wallet.wallet.user, stall) + await update_stall(merchant.id, stall) return stall except HTTPException as ex: @@ -238,7 +272,9 @@ async def api_update_stall( @nostrmarket_ext.get("/api/v1/stall/{stall_id}") async def api_get_stall(stall_id: str, wallet: WalletTypeInfo = Depends(get_key_type)): try: - stall = await get_stall(wallet.wallet.user, stall_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + stall = await get_stall(merchant.id, stall_id) if not stall: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -258,7 +294,9 @@ async def api_get_stall(stall_id: str, wallet: WalletTypeInfo = Depends(get_key_ @nostrmarket_ext.get("/api/v1/stall") async def api_get_stalls(wallet: WalletTypeInfo = Depends(get_key_type)): try: - stalls = await get_stalls(wallet.wallet.user) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + stalls = await get_stalls(merchant.id) return stalls except Exception as ex: logger.warning(ex) @@ -274,7 +312,9 @@ async def api_get_stall_products( wallet: WalletTypeInfo = Depends(require_invoice_key), ): try: - products = await get_products(wallet.wallet.user, stall_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + products = await get_products(merchant.id, stall_id) return products except Exception as ex: logger.warning(ex) @@ -290,7 +330,9 @@ async def api_get_stall_orders( wallet: WalletTypeInfo = Depends(require_invoice_key), ): try: - orders = await get_orders_for_stall(wallet.wallet.user, stall_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + orders = await get_orders_for_stall(merchant.id, stall_id) return orders except Exception as ex: logger.warning(ex) @@ -305,19 +347,21 @@ async def api_delete_stall( stall_id: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): try: - stall = await get_stall(wallet.wallet.user, stall_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + stall = await get_stall(merchant.id, stall_id) if not stall: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Stall does not exist.", ) - await delete_stall(wallet.wallet.user, stall_id) + await delete_stall(merchant.id, stall_id) - event = await sign_and_send_to_nostr(wallet.wallet.user, stall, True) + event = await sign_and_send_to_nostr(merchant, stall, True) stall.config.event_id = event.id - await update_stall(wallet.wallet.user, stall) + await update_stall(merchant.id, stall) except HTTPException as ex: raise ex @@ -339,17 +383,19 @@ async def api_create_product( ) -> Product: try: data.validate_product() + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" - stall = await get_stall(wallet.wallet.user, data.stall_id) + stall = await get_stall(merchant.id, data.stall_id) assert stall, "Stall missing for product" data.config.currency = stall.currency - product = await create_product(wallet.wallet.user, data=data) + product = await create_product(merchant.id, data=data) - event = await sign_and_send_to_nostr(wallet.wallet.user, product) + event = await sign_and_send_to_nostr(merchant, product) product.config.event_id = event.id - await update_product(wallet.wallet.user, product) + await update_product(merchant.id, product) return product except ValueError as ex: @@ -376,17 +422,19 @@ async def api_update_product( raise ValueError("Bad product ID") product.validate_product() + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" - stall = await get_stall(wallet.wallet.user, product.stall_id) + stall = await get_stall(merchant.id, product.stall_id) assert stall, "Stall missing for product" product.config.currency = stall.currency - product = await update_product(wallet.wallet.user, product) + product = await update_product(merchant.id, product) - event = await sign_and_send_to_nostr(wallet.wallet.user, product) + event = await sign_and_send_to_nostr(merchant, product) product.config.event_id = event.id - await update_product(wallet.wallet.user, product) + await update_product(merchant.id, product) return product except ValueError as ex: @@ -408,7 +456,10 @@ async def api_get_product( wallet: WalletTypeInfo = Depends(require_invoice_key), ) -> Optional[Product]: try: - products = await get_product(wallet.wallet.user, product_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + products = await get_product(merchant.id, product_id) return products except Exception as ex: logger.warning(ex) @@ -424,15 +475,18 @@ async def api_delete_product( wallet: WalletTypeInfo = Depends(require_admin_key), ): try: - product = await get_product(wallet.wallet.user, product_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + product = await get_product(merchant.id, product_id) if not product: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Product does not exist.", ) - await delete_product(wallet.wallet.user, product_id) - await sign_and_send_to_nostr(wallet.wallet.user, product, True) + await delete_product(merchant.id, product_id) + await sign_and_send_to_nostr(merchant, product, True) except HTTPException as ex: raise ex @@ -452,7 +506,10 @@ nostrmarket_ext.get("/api/v1/order/{order_id}") async def api_get_order(order_id: str, wallet: WalletTypeInfo = Depends(get_key_type)): try: - order = await get_order(wallet.wallet.user, order_id) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + order = await get_order(merchant.id, order_id) if not order: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -472,7 +529,10 @@ async def api_get_order(order_id: str, wallet: WalletTypeInfo = Depends(get_key_ @nostrmarket_ext.get("/api/v1/order") async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)): try: - orders = await get_orders(wallet.wallet.user) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + orders = await get_orders(merchant.id) return orders except Exception as ex: logger.warning(ex) @@ -489,12 +549,13 @@ async def api_update_order_status( ) -> Order: try: assert data.shipped != None, "Shipped value is required for order" - order = await update_order_shipped_status( - wallet.wallet.user, data.id, data.shipped - ) + merchant = await get_merchant_for_user(wallet.wallet.user) + assert merchant, "Merchant cannot be found" + + order = await update_order_shipped_status(merchant.id, data.id, data.shipped) assert order, "Cannot find updated order" - merchant = await get_merchant_for_user(wallet.wallet.user) + merchant = await get_merchant_for_user(merchant.id) assert merchant, f"Merchant cannot be found for order {data.id}" data.paid = order.paid @@ -530,7 +591,7 @@ async def api_get_messages( logger.warning(ex) raise HTTPException( status_code=HTTPStatus.INTERNAL_SERVER_ERROR, - detail="Cannot get zone", + detail="Cannot get direct message", )