From d19bd8bfc4337873a9ff1c1dae23b5af9d26d287 Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Mon, 27 Mar 2023 15:32:08 +0100 Subject: [PATCH 1/3] fix: url not displayed in light theme --- templates/nostrmarket/_api_docs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/nostrmarket/_api_docs.html b/templates/nostrmarket/_api_docs.html index 9a9a9d5..6bce480 100644 --- a/templates/nostrmarket/_api_docs.html +++ b/templates/nostrmarket/_api_docs.html @@ -36,7 +36,7 @@ > - Visit the market clientMarket client From d267583e42f20ada559a371b8b1db933d9cb0656 Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Mon, 27 Mar 2023 15:32:57 +0100 Subject: [PATCH 2/3] replace readme content with guide --- README.md | 335 ++++++++++++------------------------------------------ 1 file changed, 74 insertions(+), 261 deletions(-) diff --git a/README.md b/README.md index 1cd1e04..4a4ea8f 100644 --- a/README.md +++ b/README.md @@ -1,276 +1,89 @@ -## Nostr Diagon Alley protocol (for resilient marketplaces) +## Nostr Market -#### Original protocol https://github.com/lnbits/Diagon-Alley +**This extension follows [NIP-45](https://github.com/nostr-protocol/nips/blob/master/45.md)** + +**Original protocol for [Diagon Alley](https://github.com/lnbits/Diagon-Alley) (resilient marketplaces)** > The concepts around resilience in Diagon Alley helped influence the creation of the NOSTR protocol, now we get to build Diagon Alley on NOSTR! -In Diagon Alley, `merchant` and `customer` communicate via NOSTR relays, so loss of money, product information, and reputation become far less likely if attacked. - -A `merchant` and `customer` both have a NOSTR key-pair that are used to sign notes and subscribe to events. - #### For further information about NOSTR, see https://github.com/nostr-protocol/nostr -## Terms +## Create, or import, a merchant account -- `merchant` - seller of products with NOSTR key-pair -- `customer` - buyer of products with NOSTR key-pair -- `product` - item for sale by the `merchant` -- `stall` - list of products controlled by `merchant` (a `merchant` can have multiple stalls) -- `marketplace` - clientside software for searching `stalls` and purchasing `products` +As a merchant you need to provide a Nostr key pair, or the extension can generate one for you. +![create keys](https://i.imgur.com/KhQYKOe.png) + +Once you have a merchant "account", you can view the details on the merchant dropdown +![merchant dropdown](https://i.imgur.com/M5abrK9.png) + +## Create a Stall, or shop + +To create a stall, you first need to set a _Shipping zone_. Click on the _Zones_ button and fill in the fields: +![zone dialog](https://i.imgur.com/SMAviHm.png) + +- Give your shipping zone a name +- Select to which countries does this _Shipping zone_ applies to (you can set a "Free" zone for digital goods) +- Select the unit of account. If your will list products in EUR, the shipping zone must be in the same currency +- Select the cost to ship + +**Let's create the stall** +Click on _New Stall_ button and fill the necessary fields +![Create stall](https://i.imgur.com/gb9b4We.png) +![Stall dialog](https://i.imgur.com/lX3Cd9K.png) + +- Give your stall/shop a name +- An optional description (this can be used by client to search shops) +- Select which wallet to use for this shop +- Select the unit +- select a Shipping Zone (multiple zones can be selected) + +Click on the "Plus" button to open the stall details and click "New Product" to create a product +![create product](https://i.imgur.com/zNG8wZx.png) + +Fill the necessary fields on the dialog +![product dialog](https://i.imgur.com/lAmkuvy.png) + +- The product name +- Give it a description +- Add some categories (this can be used by clients to search for products) +- Supply an URL for your product image (you can upload an image but it's recommended that the images are hosted outside of LNbits) +- A price for the product, in the currency selected for the shop (this will be converted to sats when a customer buys) +- The quantity you have in stock, for the product. This will update when orders are made/paid + +On the _Stall_ section you can also see (update or delete) the stall details in _Stall Info_ tab +![stall details](https://i.imgur.com/97eJ7R0.png) + +Create, update or delete products in _Products_ tab +![products tab](https://i.imgur.com/ilbxeOG.png) + +And check your orders on the _Orders_ tab +![orders tab](https://i.imgur.com/RiqMKUM.png) + +When you get an order, you can see the details by clicking on the "Plus" sign for the order +![order details](https://i.imgur.com/PtYbaPm.png) + +- Ordered products +- The order ID +- Customer's shipping address +- Customer's public key +- Invoice ID + +If applicable, you can set as shipped when shipping is processed. + +You also have a _Chat Box_ to chat with customer +![chat box](https://i.imgur.com/fhPP9IB.png) ## Diagon Alley Clients -### Merchant admin +LNbits also provides a Nostr Market client app. You can visit the client from the merchant dashboard by clicking on the "Market client" link +![market client link](https://i.imgur.com/3tsots2.png) -Where the `merchant` creates, updates and deletes `stalls` and `products`, as well as where they manage sales, payments and communication with `customers`. +or by visiting `https:///nostrmarket/market` -The `merchant` admin software can be purely clientside, but for `convenience` and uptime, implementations will likely have a server listening for NOSTR events. +## Aditional info -### Marketplace +Stall and product are _Parameterized Replaceable Events_ according to [NIP-33](https://github.com/nostr-protocol/nips/blob/master/33.md) and use kind `30017` and `30018` respectivelly. See [NIP-45](https://github.com/nostr-protocol/nips/blob/master/45.md) for more details. -`Marketplace` software should be entirely clientside, either as a stand-alone app, or as a purely frontend webpage. A `customer` subscribes to different merchant NOSTR public keys, and those `merchants` `stalls` and `products` become listed and searchable. The marketplace client is like any other ecommerce site, with basket and checkout. `Marketplaces` may also wish to include a `customer` support area for direct message communication with `merchants`. +Order placing, invoicing, payment details and order statuses are handled over Nostr using [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md). -## `Merchant` publishing/updating products (event) - -NIP-01 https://github.com/nostr-protocol/nips/blob/master/01.md uses the basic NOSTR event type. - -The `merchant` event that publishes and updates product lists - -The below json goes in `content` of NIP-01. - -Data from newer events should replace data from older events. - -`action` types (used to indicate changes): - -- `update` element has changed -- `delete` element should be deleted -- `suspend` element is suspended -- `unsuspend` element is unsuspended - -``` -{ - "name": , - "description": , - "currency": , - "action": , - "shipping": [ - { - "id": , - "zones": , - "price": , - }, - { - "id": , - "zones": , - "price": , - }, - { - "id": , - "zones": , - "price": , - } - ], - "stalls": [ - { - "id": , - "name": , - "description": , - "categories": , - "shipping": , - "action": , - "products": [ - { - "id": , - "name": , - "description": , - "categories": , - "amount": , - "price": , - "images": [ - { - "id": , - "name": , - "link": - } - ], - "action": , - }, - { - "id": , - "name": , - "description": , - "categories": , - "amount": , - "price": , - "images": [ - { - "id": , - "name": , - "link": - }, - { - "id": , - "name": , - "link": - } - ], - "action": , - }, - ] - }, - { - "id": , - "name": , - "description": , - "categories": , - "shipping": , - "action": , - "products": [ - { - "id": , - "name": , - "categories": , - "amount": , - "price": , - "images": [ - { - "id": , - "name": , - "link": - } - ], - "action": , - } - ] - } - ] -} - -``` - -As all elements are optional, an `update` `action` to a `product` `image`, may look as simple as: - -``` -{ - "stalls": [ - { - "id": , - "products": [ - { - "id": , - "images": [ - { - "id": , - "name": , - "link": - } - ], - "action": , - }, - ] - } - ] -} - -``` - -## Checkout events - -NIP-04 https://github.com/nostr-protocol/nips/blob/master/04.md, all checkout events are encrypted - -The below json goes in `content` of NIP-04. - -### Step 1: `customer` order (event) - -``` -{ - "id": , - "name": , - "description": , - "address": , - "message": , - "contact": [ - "nostr": , - "phone": , - "email": - ], - "items": [ - { - "id": , - "quantity": , - "message": - }, - { - "id": , - "quantity": , - "message": - }, - { - "id": , - "quantity": , - "message": - } - -} - -``` - -Merchant should verify the sum of product ids + timestamp. - -### Step 2: `merchant` request payment (event) - -Sent back from the merchant for payment. Any payment option is valid that the merchant can check. - -The below json goes in `content` of NIP-04. - -`payment_options`/`type` include: - -- `url` URL to a payment page, stripe, paypal, btcpayserver, etc -- `btc` onchain bitcoin address -- `ln` bitcoin lightning invoice -- `lnurl` bitcoin lnurl-pay - -``` -{ - "id": , - "message": , - "payment_options": [ - { - "type": , - "link": - }, - { - "type": , - "link": - }, - { - "type": , - "link": - } -} - -``` - -### Step 3: `merchant` verify payment/shipped (event) - -Once payment has been received and processed. - -The below json goes in `content` of NIP-04. - -``` -{ - "id": , - "message": , - "paid": , - "shipped": , -} - -``` - -## Customer support events - -Customer support is handle over whatever communication method was specified. If communicationg via nostr, NIP-04 is used https://github.com/nostr-protocol/nips/blob/master/04.md. - -## Additional - -Standard data models can be found here here +Customer support is handled over whatever communication method was specified. If communicationg via nostr, [NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md) is used. From a88f0ee1d24ffccb9732210945efb89eb661aaf6 Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Mon, 27 Mar 2023 15:39:07 +0100 Subject: [PATCH 3/3] fix: motorina0's camel-case nitpick --- static/components/customer-stall/customer-stall.html | 2 +- static/components/customer-stall/customer-stall.js | 7 +++---- templates/nostrmarket/market.html | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/static/components/customer-stall/customer-stall.html b/static/components/customer-stall/customer-stall.html index 9d11834..f9651d8 100644 --- a/static/components/customer-stall/customer-stall.html +++ b/static/components/customer-stall/customer-stall.html @@ -23,7 +23,7 @@ o.type == 'ln' - ).link + let payment_request = json.payment_options.find(o => o.type == 'ln') + .link if (!payment_request) return this.loading = false this.qrCodeDialog.data.payment_request = payment_request diff --git a/templates/nostrmarket/market.html b/templates/nostrmarket/market.html index 82d874b..fc3c3d2 100644 --- a/templates/nostrmarket/market.html +++ b/templates/nostrmarket/market.html @@ -186,7 +186,7 @@ v-if="!isLoading && activeStall" :stall="stalls.find(stall => stall.id == activeStall)" :products="filterProducts" - :stallproducts="products.filter(p => p.stall_id == activeStall)" + :stall-products="products.filter(p => p.stall_id == activeStall)" :product-detail="activeProduct" :relays="relays" :account="account"