feat: user merchant_id instead of user_id
This commit is contained in:
parent
152fe5baab
commit
3e0b480f0a
10 changed files with 286 additions and 187 deletions
|
|
@ -42,9 +42,13 @@ from .views_api import * # noqa
|
||||||
|
|
||||||
def nostrmarket_start():
|
def nostrmarket_start():
|
||||||
async def _subscribe_to_nostr_client():
|
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)
|
await subscribe_to_nostr_client(recieve_event_queue, send_req_queue)
|
||||||
|
|
||||||
async def _wait_for_nostr_events():
|
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)
|
await wait_for_nostr_events(recieve_event_queue, send_req_queue)
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
|
||||||
174
crud.py
174
crud.py
|
|
@ -76,16 +76,16 @@ async def get_merchant_for_user(user_id: str) -> Optional[Merchant]:
|
||||||
######################################## ZONES ########################################
|
######################################## 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()
|
zone_id = urlsafe_short_hash()
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
INSERT INTO nostrmarket.zones (id, user_id, name, currency, cost, regions)
|
INSERT INTO nostrmarket.zones (id, merchant_id, name, currency, cost, regions)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
zone_id,
|
zone_id,
|
||||||
user_id,
|
merchant_id,
|
||||||
data.name,
|
data.name,
|
||||||
data.currency,
|
data.currency,
|
||||||
data.cost,
|
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"
|
assert zone, "Newly created zone couldn't be retrieved"
|
||||||
return zone
|
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(
|
await db.execute(
|
||||||
f"UPDATE nostrmarket.zones SET name = ?, cost = ?, regions = ? WHERE id = ? AND 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, user_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(
|
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,
|
zone_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return Zone.from_row(row) if row else None
|
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(
|
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]
|
return [Zone.from_row(row) for row in rows]
|
||||||
|
|
||||||
|
|
||||||
async def delete_zone(zone_id: str) -> None:
|
async def delete_zone(merchant_id: str, zone_id: str) -> None:
|
||||||
# todo: add user_id
|
|
||||||
await db.execute("DELETE FROM nostrmarket.zones WHERE id = ?", (zone_id,))
|
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 ########################################
|
######################################## 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()
|
stall_id = urlsafe_short_hash()
|
||||||
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
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 (?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
user_id,
|
merchant_id,
|
||||||
stall_id,
|
stall_id,
|
||||||
data.wallet,
|
data.wallet,
|
||||||
data.name,
|
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"
|
assert stall, "Newly created stall couldn't be retrieved"
|
||||||
return stall
|
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(
|
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,
|
stall_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return Stall.from_row(row) if row else None
|
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(
|
rows = await db.fetchall(
|
||||||
"SELECT * FROM nostrmarket.stalls WHERE user_id = ?",
|
"SELECT * FROM nostrmarket.stalls WHERE merchant_id = ?",
|
||||||
(user_id,),
|
(merchant_id,),
|
||||||
)
|
)
|
||||||
return [Stall.from_row(row) for row in rows]
|
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(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
UPDATE nostrmarket.stalls SET wallet = ?, name = ?, currency = ?, zones = ?, meta = ?
|
UPDATE nostrmarket.stalls SET wallet = ?, name = ?, currency = ?, zones = ?, meta = ?
|
||||||
WHERE user_id = ? AND id = ?
|
WHERE merchant_id = ? AND id = ?
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
stall.wallet,
|
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]
|
[z.dict() for z in stall.shipping_zones]
|
||||||
), # todo: cost is float. should be int for sats
|
), # todo: cost is float. should be int for sats
|
||||||
json.dumps(stall.config.dict()),
|
json.dumps(stall.config.dict()),
|
||||||
user_id,
|
merchant_id,
|
||||||
stall.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(
|
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,
|
stall_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -211,16 +223,16 @@ async def delete_stall(user_id: str, stall_id: str) -> None:
|
||||||
######################################## PRODUCTS ########################################
|
######################################## 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()
|
product_id = urlsafe_short_hash()
|
||||||
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
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 (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
user_id,
|
merchant_id,
|
||||||
product_id,
|
product_id,
|
||||||
data.stall_id,
|
data.stall_id,
|
||||||
data.name,
|
data.name,
|
||||||
|
|
@ -231,18 +243,18 @@ async def create_product(user_id: str, data: PartialProduct) -> Product:
|
||||||
json.dumps(data.config.dict()),
|
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"
|
assert product, "Newly created product couldn't be retrieved"
|
||||||
|
|
||||||
return product
|
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(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
UPDATE nostrmarket.products set name = ?, image = ?, price = ?, quantity = ?, category_list = ?, meta = ?
|
UPDATE nostrmarket.products set name = ?, image = ?, price = ?, quantity = ?, category_list = ?, meta = ?
|
||||||
WHERE user_id = ? AND id = ?
|
WHERE merchant_id = ? AND id = ?
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
product.name,
|
product.name,
|
||||||
|
|
@ -251,40 +263,42 @@ async def update_product(user_id: str, product: Product) -> Product:
|
||||||
product.quantity,
|
product.quantity,
|
||||||
json.dumps(product.categories),
|
json.dumps(product.categories),
|
||||||
json.dumps(product.config.dict()),
|
json.dumps(product.config.dict()),
|
||||||
user_id,
|
merchant_id,
|
||||||
product.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"
|
assert updated_product, "Updated product couldn't be retrieved"
|
||||||
|
|
||||||
return updated_product
|
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(
|
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,
|
product_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return Product.from_row(row) if row else None
|
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(
|
rows = await db.fetchall(
|
||||||
"SELECT * FROM nostrmarket.products WHERE user_id = ? AND stall_id = ?",
|
"SELECT * FROM nostrmarket.products WHERE merchant_id = ? AND stall_id = ?",
|
||||||
(user_id, stall_id),
|
(merchant_id, stall_id),
|
||||||
)
|
)
|
||||||
return [Product.from_row(row) for row in rows]
|
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))
|
q = ",".join(["?"] * len(product_ids))
|
||||||
rows = await db.fetchall(
|
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})",
|
f"SELECT id, stall_id, name, price, quantity, category_list, meta FROM nostrmarket.products WHERE merchant_id = ? AND id IN ({q})",
|
||||||
(user_id, *product_ids),
|
(merchant_id, *product_ids),
|
||||||
)
|
)
|
||||||
return [Product.from_row(row) for row in rows]
|
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
|
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(
|
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,
|
product_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
@ -315,11 +329,11 @@ async def delete_product(user_id: str, product_id: str) -> None:
|
||||||
######################################## ORDERS ########################################
|
######################################## ORDERS ########################################
|
||||||
|
|
||||||
|
|
||||||
async def create_order(user_id: str, o: Order) -> Order:
|
async def create_order(merchant_id: str, o: Order) -> Order:
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
INSERT INTO nostrmarket.orders (
|
INSERT INTO nostrmarket.orders (
|
||||||
user_id,
|
merchant_id,
|
||||||
id,
|
id,
|
||||||
event_id,
|
event_id,
|
||||||
event_created_at,
|
event_created_at,
|
||||||
|
|
@ -337,7 +351,7 @@ async def create_order(user_id: str, o: Order) -> Order:
|
||||||
ON CONFLICT(event_id) DO NOTHING
|
ON CONFLICT(event_id) DO NOTHING
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
user_id,
|
merchant_id,
|
||||||
o.id,
|
o.id,
|
||||||
o.event_id,
|
o.event_id,
|
||||||
o.event_created_at,
|
o.event_created_at,
|
||||||
|
|
@ -352,47 +366,47 @@ async def create_order(user_id: str, o: Order) -> Order:
|
||||||
o.total,
|
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"
|
assert order, "Newly created order couldn't be retrieved"
|
||||||
|
|
||||||
return order
|
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(
|
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,
|
order_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return Order.from_row(row) if row else None
|
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(
|
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,
|
event_id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return Order.from_row(row) if row else None
|
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(
|
rows = await db.fetchall(
|
||||||
"SELECT * FROM nostrmarket.orders WHERE user_id = ? ORDER BY time DESC",
|
"SELECT * FROM nostrmarket.orders WHERE merchant_id = ? ORDER BY time DESC",
|
||||||
(user_id,),
|
(merchant_id,),
|
||||||
)
|
)
|
||||||
return [Order.from_row(row) for row in rows]
|
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(
|
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,
|
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(
|
async def update_order_shipped_status(
|
||||||
user_id: str, order_id: str, shipped: bool
|
merchant_id: str, order_id: str, shipped: bool
|
||||||
) -> Optional[Order]:
|
) -> Optional[Order]:
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"UPDATE nostrmarket.orders SET shipped = ? WHERE user_id = ? AND id = ?",
|
f"UPDATE nostrmarket.orders SET shipped = ? WHERE merchant_id = ? AND id = ?",
|
||||||
(shipped, user_id, order_id),
|
(shipped, merchant_id, order_id),
|
||||||
)
|
)
|
||||||
|
|
||||||
row = await db.fetchone(
|
row = await db.fetchone(
|
||||||
|
|
@ -460,8 +474,10 @@ async def create_direct_message(
|
||||||
dm.incoming,
|
dm.incoming,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
if dm.event_id:
|
||||||
msg = await get_direct_message(merchant_id, dm_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"
|
assert msg, "Newly created dm couldn't be retrieved"
|
||||||
return msg
|
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
|
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]:
|
async def get_direct_messages(merchant_id: str, public_key: str) -> List[DirectMessage]:
|
||||||
rows = await db.fetchall(
|
rows = await db.fetchall(
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ def get_shared_secret(privkey: str, pubkey: str):
|
||||||
|
|
||||||
def decrypt_message(encoded_message: str, encryption_key) -> str:
|
def decrypt_message(encoded_message: str, encryption_key) -> str:
|
||||||
encoded_data = encoded_message.split("?iv=")
|
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]
|
encoded_content, encoded_iv = encoded_data[0], encoded_data[1]
|
||||||
|
|
||||||
iv = base64.b64decode(encoded_iv)
|
iv = base64.b64decode(encoded_iv)
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ async def m001_initial(db):
|
||||||
"""
|
"""
|
||||||
Initial stalls table.
|
Initial stalls table.
|
||||||
"""
|
"""
|
||||||
# user_id, id, wallet, name, currency, zones, meta
|
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
CREATE TABLE nostrmarket.stalls (
|
CREATE TABLE nostrmarket.stalls (
|
||||||
user_id TEXT NOT NULL,
|
merchant_id TEXT NOT NULL,
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
wallet TEXT NOT NULL,
|
wallet TEXT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
|
@ -39,7 +39,7 @@ async def m001_initial(db):
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
CREATE TABLE nostrmarket.products (
|
CREATE TABLE nostrmarket.products (
|
||||||
user_id TEXT NOT NULL,
|
merchant_id TEXT NOT NULL,
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
stall_id TEXT NOT NULL,
|
stall_id TEXT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
|
|
@ -59,7 +59,7 @@ async def m001_initial(db):
|
||||||
"""
|
"""
|
||||||
CREATE TABLE nostrmarket.zones (
|
CREATE TABLE nostrmarket.zones (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
user_id TEXT NOT NULL,
|
merchant_id TEXT NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
currency TEXT NOT NULL,
|
currency TEXT NOT NULL,
|
||||||
cost REAL NOT NULL,
|
cost REAL NOT NULL,
|
||||||
|
|
@ -75,7 +75,7 @@ async def m001_initial(db):
|
||||||
await db.execute(
|
await db.execute(
|
||||||
f"""
|
f"""
|
||||||
CREATE TABLE nostrmarket.orders (
|
CREATE TABLE nostrmarket.orders (
|
||||||
user_id TEXT NOT NULL,
|
merchant_id TEXT NOT NULL,
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
event_id TEXT,
|
event_id TEXT,
|
||||||
event_created_at INTEGER NOT NULL,
|
event_created_at INTEGER NOT NULL,
|
||||||
|
|
@ -120,8 +120,8 @@ async def m001_initial(db):
|
||||||
Create indexes for message fetching
|
Create indexes for message fetching
|
||||||
"""
|
"""
|
||||||
await db.execute(
|
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(
|
await db.execute(
|
||||||
"CREATE INDEX idx_messages_conversations ON nostrmarket.messages (conversation_id)"
|
"CREATE INDEX idx_event_id ON nostrmarket.direct_messages (event_id)"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ async def connect_to_nostrclient_ws(
|
||||||
|
|
||||||
logger.debug(f"Subscribing to websockets for nostrclient extension")
|
logger.debug(f"Subscribing to websockets for nostrclient extension")
|
||||||
ws = WebSocketApp(
|
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_message=on_message,
|
||||||
on_open=on_open,
|
on_open=on_open,
|
||||||
on_error=on_error,
|
on_error=on_error,
|
||||||
|
|
|
||||||
45
services.py
45
services.py
|
|
@ -33,17 +33,19 @@ from .nostr.nostr_client import publish_nostr_event
|
||||||
|
|
||||||
|
|
||||||
async def create_new_order(
|
async def create_new_order(
|
||||||
user_id: str, data: PartialOrder
|
merchant_public_key: str, data: PartialOrder
|
||||||
) -> Optional[PaymentRequest]:
|
) -> Optional[PaymentRequest]:
|
||||||
if await get_order(user_id, data.id):
|
merchant = await get_merchant_by_pubkey(merchant_public_key)
|
||||||
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)
|
|
||||||
assert merchant, "Cannot find merchant!"
|
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)
|
data.validate_order_items(products)
|
||||||
|
|
||||||
total_amount = await data.total_sats(products)
|
total_amount = await data.total_sats(products)
|
||||||
|
|
@ -69,7 +71,7 @@ async def create_new_order(
|
||||||
total=total_amount,
|
total=total_amount,
|
||||||
extra=await OrderExtra.from_products(products),
|
extra=await OrderExtra.from_products(products),
|
||||||
)
|
)
|
||||||
await create_order(user_id, order)
|
await create_order(merchant.id, order)
|
||||||
|
|
||||||
return PaymentRequest(
|
return PaymentRequest(
|
||||||
id=data.id, payment_options=[PaymentOption(type="ln", link=invoice)]
|
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(
|
async def sign_and_send_to_nostr(
|
||||||
user_id: str, n: Nostrable, delete=False
|
merchant: Merchant, n: Nostrable, delete=False
|
||||||
) -> NostrEvent:
|
) -> NostrEvent:
|
||||||
merchant = await get_merchant_for_user(user_id)
|
|
||||||
assert merchant, "Cannot find merchant!"
|
|
||||||
|
|
||||||
event = (
|
event = (
|
||||||
n.to_nostr_delete_event(merchant.public_key)
|
n.to_nostr_delete_event(merchant.public_key)
|
||||||
if delete
|
if delete
|
||||||
|
|
@ -115,24 +114,28 @@ async def handle_order_paid(order_id: str, merchant_pubkey: str):
|
||||||
|
|
||||||
async def process_nostr_message(msg: str):
|
async def process_nostr_message(msg: str):
|
||||||
try:
|
try:
|
||||||
type, subscription_id, event = json.loads(msg)
|
type, *rest= json.loads(msg)
|
||||||
subscription_name, public_key = subscription_id.split(":")
|
|
||||||
if type.upper() == "EVENT":
|
if type.upper() == "EVENT":
|
||||||
|
subscription_id, event = rest
|
||||||
|
subscription_name, merchant_public_key = subscription_id.split(":")
|
||||||
event = NostrEvent(**event)
|
event = NostrEvent(**event)
|
||||||
if event.kind == 4:
|
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:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
||||||
|
|
||||||
async def _handle_nip04_message(
|
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)
|
merchant = await get_merchant_by_pubkey(merchant_public_key)
|
||||||
assert merchant, f"Merchant not found for public key '{public_key}'"
|
assert merchant, f"Merchant not found for public key '{merchant_public_key}'"
|
||||||
|
|
||||||
clear_text_msg = merchant.decrypt_message(event.content, event.pubkey)
|
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":
|
if subscription_name == "direct-messages-in":
|
||||||
await _handle_incoming_dms(event, merchant, clear_text_msg)
|
await _handle_incoming_dms(event, merchant, clear_text_msg)
|
||||||
else:
|
else:
|
||||||
|
|
@ -187,7 +190,7 @@ async def _handle_dirrect_message(
|
||||||
order["event_created_at"] = event_created_at
|
order["event_created_at"] = event_created_at
|
||||||
return await _handle_new_order(PartialOrder(**order))
|
return await _handle_new_order(PartialOrder(**order))
|
||||||
else:
|
else:
|
||||||
print("### text_msg", text_msg, event_created_at, event_id)
|
# print("### text_msg", text_msg, event_created_at, event_id)
|
||||||
dm = PartialDirectMessage(
|
dm = PartialDirectMessage(
|
||||||
event_id=event_id,
|
event_id=event_id,
|
||||||
event_created_at=event_created_at,
|
event_created_at=event_created_at,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
unelevated
|
unelevated
|
||||||
color="green"
|
color="green"
|
||||||
class="float-left"
|
class="float-left"
|
||||||
>New Stall</q-btn
|
>New Stall (Store)</q-btn
|
||||||
>
|
>
|
||||||
<q-input
|
<q-input
|
||||||
borderless
|
borderless
|
||||||
|
|
|
||||||
15
tasks.py
15
tasks.py
|
|
@ -46,11 +46,9 @@ async def subscribe_to_nostr_client(recieve_event_queue: Queue, send_req_queue:
|
||||||
logger.info("Connected to 'nostrclient' websocket")
|
logger.info("Connected to 'nostrclient' websocket")
|
||||||
|
|
||||||
def on_message(_, message):
|
def on_message(_, message):
|
||||||
print("### on_message", message)
|
# print("### on_message", message)
|
||||||
recieve_event_queue.put_nowait(message)
|
recieve_event_queue.put_nowait(message)
|
||||||
|
|
||||||
# wait for 'nostrclient' extension to initialize
|
|
||||||
await asyncio.sleep(5)
|
|
||||||
ws: WebSocketApp = None
|
ws: WebSocketApp = None
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
|
@ -70,6 +68,7 @@ async def subscribe_to_nostr_client(recieve_event_queue: Queue, send_req_queue:
|
||||||
|
|
||||||
|
|
||||||
async def wait_for_nostr_events(recieve_event_queue: Queue, send_req_queue: Queue):
|
async def wait_for_nostr_events(recieve_event_queue: Queue, send_req_queue: Queue):
|
||||||
|
print("### wait_for_nostr_events")
|
||||||
public_keys = await get_public_keys_for_merchants()
|
public_keys = await get_public_keys_for_merchants()
|
||||||
for p in public_keys:
|
for p in public_keys:
|
||||||
last_order_time = await get_last_order_time(p)
|
last_order_time = await get_last_order_time(p)
|
||||||
|
|
@ -77,13 +76,17 @@ async def wait_for_nostr_events(recieve_event_queue: Queue, send_req_queue: Queu
|
||||||
since = max(last_order_time, last_dm_time)
|
since = max(last_order_time, last_dm_time)
|
||||||
|
|
||||||
in_messages_filter = {"kind": 4, "#p": [p]}
|
in_messages_filter = {"kind": 4, "#p": [p]}
|
||||||
|
out_messages_filter = {"kind": 4, "authors": [p]}
|
||||||
if since != 0:
|
if since != 0:
|
||||||
in_messages_filter["since"] = since
|
in_messages_filter["since"] = since
|
||||||
|
# out_messages_filter["since"] = since
|
||||||
print("### in_messages_filter", in_messages_filter)
|
print("### in_messages_filter", in_messages_filter)
|
||||||
|
print("### out_messages_filter", out_messages_filter)
|
||||||
|
|
||||||
await send_req_queue.put(["REQ", f"direct-messages-in:{p}", in_messages_filter])
|
await send_req_queue.put(["REQ", f"direct-messages-in:{p}", in_messages_filter])
|
||||||
# await send_req_queue.put(
|
await send_req_queue.put(
|
||||||
# ["REQ", f"direct-messages-out:{p}", {"kind": 4, "authors": [p]}]
|
["REQ", f"direct-messages-out:{p}", out_messages_filter]
|
||||||
# )
|
)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
message = await recieve_event_queue.get()
|
message = await recieve_event_queue.get()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,45 @@
|
||||||
%} {% block page %}
|
%} {% block page %}
|
||||||
<div class="row q-col-gutter-md">
|
<div class="row q-col-gutter-md">
|
||||||
<div class="col-12 col-md-7 q-gutter-y-md">
|
<div class="col-12 col-md-7 q-gutter-y-md">
|
||||||
<q-card v-if="!merchant">
|
<div v-if="merchant && merchant.id">
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-2">
|
||||||
|
<merchant-details
|
||||||
|
:inkey="g.user.wallets[0].inkey"
|
||||||
|
:adminkey="g.user.wallets[0].adminkey"
|
||||||
|
@show-keys="toggleMerchantKeys"
|
||||||
|
></merchant-details>
|
||||||
|
</div>
|
||||||
|
<div class="col-8"></div>
|
||||||
|
<div class="col-2">
|
||||||
|
<shipping-zones
|
||||||
|
:inkey="g.user.wallets[0].inkey"
|
||||||
|
:adminkey="g.user.wallets[0].adminkey"
|
||||||
|
class="float-right"
|
||||||
|
></shipping-zones>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section v-if="showKeys">
|
||||||
|
<key-pair
|
||||||
|
:public-key="merchant.public_key"
|
||||||
|
:private-key="merchant.private_key"
|
||||||
|
></key-pair>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
<q-card class="q-mt-lg">
|
||||||
|
<q-card-section>
|
||||||
|
<stall-list
|
||||||
|
:adminkey="g.user.wallets[0].adminkey"
|
||||||
|
:inkey="g.user.wallets[0].inkey"
|
||||||
|
:wallet-options="g.user.walletOptions"
|
||||||
|
></stall-list>
|
||||||
|
</q-card-section>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
<q-card v-else>
|
||||||
<q-card-section>
|
<q-card-section>
|
||||||
<span class="text-h4">Wellcome to Nostr Market!</span><br />
|
<span class="text-h4">Wellcome to Nostr Market!</span><br />
|
||||||
In Nostr Market, merchant and customer communicate via NOSTR relays, so
|
In Nostr Market, merchant and customer communicate via NOSTR relays, so
|
||||||
|
|
@ -57,44 +95,6 @@
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
<div v-else>
|
|
||||||
<q-card>
|
|
||||||
<q-card-section>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-2">
|
|
||||||
<merchant-details
|
|
||||||
:inkey="g.user.wallets[0].inkey"
|
|
||||||
:adminkey="g.user.wallets[0].adminkey"
|
|
||||||
@show-keys="toggleMerchantKeys"
|
|
||||||
></merchant-details>
|
|
||||||
</div>
|
|
||||||
<div class="col-8"></div>
|
|
||||||
<div class="col-2">
|
|
||||||
<shipping-zones
|
|
||||||
:inkey="g.user.wallets[0].inkey"
|
|
||||||
:adminkey="g.user.wallets[0].adminkey"
|
|
||||||
class="float-right"
|
|
||||||
></shipping-zones>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</q-card-section>
|
|
||||||
<q-card-section v-if="showKeys">
|
|
||||||
<key-pair
|
|
||||||
:public-key="merchant.public_key"
|
|
||||||
:private-key="merchant.private_key"
|
|
||||||
></key-pair>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
<q-card class="q-mt-lg">
|
|
||||||
<q-card-section>
|
|
||||||
<stall-list
|
|
||||||
:adminkey="g.user.wallets[0].adminkey"
|
|
||||||
:inkey="g.user.wallets[0].inkey"
|
|
||||||
:wallet-options="g.user.walletOptions"
|
|
||||||
></stall-list>
|
|
||||||
</q-card-section>
|
|
||||||
</q-card>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 col-md-5 q-gutter-y-md">
|
<div class="col-12 col-md-5 q-gutter-y-md">
|
||||||
|
|
|
||||||
137
views_api.py
137
views_api.py
|
|
@ -13,6 +13,7 @@ from lnbits.decorators import (
|
||||||
require_admin_key,
|
require_admin_key,
|
||||||
require_invoice_key,
|
require_invoice_key,
|
||||||
)
|
)
|
||||||
|
from lnbits.extensions.nostrmarket.helpers import get_shared_secret
|
||||||
from lnbits.utils.exchange_rates import currencies
|
from lnbits.utils.exchange_rates import currencies
|
||||||
|
|
||||||
from . import nostrmarket_ext, scheduled_tasks
|
from . import nostrmarket_ext, scheduled_tasks
|
||||||
|
|
@ -22,6 +23,7 @@ from .crud import (
|
||||||
create_product,
|
create_product,
|
||||||
create_stall,
|
create_stall,
|
||||||
create_zone,
|
create_zone,
|
||||||
|
delete_merchant_zones,
|
||||||
delete_product,
|
delete_product,
|
||||||
delete_stall,
|
delete_stall,
|
||||||
delete_zone,
|
delete_zone,
|
||||||
|
|
@ -69,6 +71,7 @@ async def api_create_merchant(
|
||||||
|
|
||||||
try:
|
try:
|
||||||
merchant = await create_merchant(wallet.wallet.user, data)
|
merchant = await create_merchant(wallet.wallet.user, data)
|
||||||
|
|
||||||
return merchant
|
return merchant
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(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 ########################################
|
######################################## ZONES ########################################
|
||||||
|
|
||||||
|
|
||||||
@nostrmarket_ext.get("/api/v1/zone")
|
@nostrmarket_ext.get("/api/v1/zone")
|
||||||
async def api_get_zones(wallet: WalletTypeInfo = Depends(get_key_type)) -> List[Zone]:
|
async def api_get_zones(wallet: WalletTypeInfo = Depends(get_key_type)) -> List[Zone]:
|
||||||
try:
|
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:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -114,7 +137,9 @@ async def api_create_zone(
|
||||||
data: PartialZone, wallet: WalletTypeInfo = Depends(require_admin_key)
|
data: PartialZone, wallet: WalletTypeInfo = Depends(require_admin_key)
|
||||||
):
|
):
|
||||||
try:
|
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
|
return zone
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -131,7 +156,9 @@ async def api_update_zone(
|
||||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||||
) -> Zone:
|
) -> Zone:
|
||||||
try:
|
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:
|
if not zone:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
|
|
@ -153,7 +180,9 @@ async def api_update_zone(
|
||||||
@nostrmarket_ext.delete("/api/v1/zone/{zone_id}")
|
@nostrmarket_ext.delete("/api/v1/zone/{zone_id}")
|
||||||
async def api_delete_zone(zone_id, wallet: WalletTypeInfo = Depends(require_admin_key)):
|
async def api_delete_zone(zone_id, wallet: WalletTypeInfo = Depends(require_admin_key)):
|
||||||
try:
|
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:
|
if not zone:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
@ -161,7 +190,7 @@ async def api_delete_zone(zone_id, wallet: WalletTypeInfo = Depends(require_admi
|
||||||
detail="Zone does not exist.",
|
detail="Zone does not exist.",
|
||||||
)
|
)
|
||||||
|
|
||||||
await delete_zone(zone_id)
|
await delete_zone(wallet.wallet.user, zone_id)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -182,12 +211,14 @@ async def api_create_stall(
|
||||||
try:
|
try:
|
||||||
data.validate_stall()
|
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
|
stall.config.event_id = event.id
|
||||||
await update_stall(wallet.wallet.user, stall)
|
await update_stall(merchant.id, stall)
|
||||||
|
|
||||||
return stall
|
return stall
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
|
|
@ -211,13 +242,16 @@ async def api_update_stall(
|
||||||
try:
|
try:
|
||||||
data.validate_stall()
|
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"
|
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
|
stall.config.event_id = event.id
|
||||||
await update_stall(wallet.wallet.user, stall)
|
await update_stall(merchant.id, stall)
|
||||||
|
|
||||||
return stall
|
return stall
|
||||||
except HTTPException as ex:
|
except HTTPException as ex:
|
||||||
|
|
@ -238,7 +272,9 @@ async def api_update_stall(
|
||||||
@nostrmarket_ext.get("/api/v1/stall/{stall_id}")
|
@nostrmarket_ext.get("/api/v1/stall/{stall_id}")
|
||||||
async def api_get_stall(stall_id: str, wallet: WalletTypeInfo = Depends(get_key_type)):
|
async def api_get_stall(stall_id: str, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
try:
|
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:
|
if not stall:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
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")
|
@nostrmarket_ext.get("/api/v1/stall")
|
||||||
async def api_get_stalls(wallet: WalletTypeInfo = Depends(get_key_type)):
|
async def api_get_stalls(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
try:
|
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
|
return stalls
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -274,7 +312,9 @@ async def api_get_stall_products(
|
||||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||||
):
|
):
|
||||||
try:
|
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
|
return products
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -290,7 +330,9 @@ async def api_get_stall_orders(
|
||||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||||
):
|
):
|
||||||
try:
|
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
|
return orders
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -305,19 +347,21 @@ async def api_delete_stall(
|
||||||
stall_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
|
stall_id: str, wallet: WalletTypeInfo = Depends(require_admin_key)
|
||||||
):
|
):
|
||||||
try:
|
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:
|
if not stall:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
detail="Stall does not exist.",
|
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
|
stall.config.event_id = event.id
|
||||||
await update_stall(wallet.wallet.user, stall)
|
await update_stall(merchant.id, stall)
|
||||||
|
|
||||||
except HTTPException as ex:
|
except HTTPException as ex:
|
||||||
raise ex
|
raise ex
|
||||||
|
|
@ -339,17 +383,19 @@ async def api_create_product(
|
||||||
) -> Product:
|
) -> Product:
|
||||||
try:
|
try:
|
||||||
data.validate_product()
|
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"
|
assert stall, "Stall missing for product"
|
||||||
data.config.currency = stall.currency
|
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
|
product.config.event_id = event.id
|
||||||
await update_product(wallet.wallet.user, product)
|
await update_product(merchant.id, product)
|
||||||
|
|
||||||
return product
|
return product
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
|
|
@ -376,17 +422,19 @@ async def api_update_product(
|
||||||
raise ValueError("Bad product ID")
|
raise ValueError("Bad product ID")
|
||||||
|
|
||||||
product.validate_product()
|
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"
|
assert stall, "Stall missing for product"
|
||||||
product.config.currency = stall.currency
|
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
|
product.config.event_id = event.id
|
||||||
await update_product(wallet.wallet.user, product)
|
await update_product(merchant.id, product)
|
||||||
|
|
||||||
return product
|
return product
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
|
|
@ -408,7 +456,10 @@ async def api_get_product(
|
||||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||||
) -> Optional[Product]:
|
) -> Optional[Product]:
|
||||||
try:
|
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
|
return products
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -424,15 +475,18 @@ async def api_delete_product(
|
||||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||||
):
|
):
|
||||||
try:
|
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:
|
if not product:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
detail="Product does not exist.",
|
detail="Product does not exist.",
|
||||||
)
|
)
|
||||||
|
|
||||||
await delete_product(wallet.wallet.user, product_id)
|
await delete_product(merchant.id, product_id)
|
||||||
await sign_and_send_to_nostr(wallet.wallet.user, product, True)
|
await sign_and_send_to_nostr(merchant, product, True)
|
||||||
|
|
||||||
except HTTPException as ex:
|
except HTTPException as ex:
|
||||||
raise 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)):
|
async def api_get_order(order_id: str, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
try:
|
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:
|
if not order:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
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")
|
@nostrmarket_ext.get("/api/v1/order")
|
||||||
async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)):
|
async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
try:
|
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
|
return orders
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
|
|
@ -489,12 +549,13 @@ async def api_update_order_status(
|
||||||
) -> Order:
|
) -> Order:
|
||||||
try:
|
try:
|
||||||
assert data.shipped != None, "Shipped value is required for order"
|
assert data.shipped != None, "Shipped value is required for order"
|
||||||
order = await update_order_shipped_status(
|
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||||
wallet.wallet.user, data.id, data.shipped
|
assert merchant, "Merchant cannot be found"
|
||||||
)
|
|
||||||
|
order = await update_order_shipped_status(merchant.id, data.id, data.shipped)
|
||||||
assert order, "Cannot find updated order"
|
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}"
|
assert merchant, f"Merchant cannot be found for order {data.id}"
|
||||||
|
|
||||||
data.paid = order.paid
|
data.paid = order.paid
|
||||||
|
|
@ -530,7 +591,7 @@ async def api_get_messages(
|
||||||
logger.warning(ex)
|
logger.warning(ex)
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||||
detail="Cannot get zone",
|
detail="Cannot get direct message",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue