{"id":13666709,"url":"https://github.com/lnbits/market","last_synced_at":"2025-04-26T12:31:31.376Z","repository":{"id":73758120,"uuid":"600046490","full_name":"lnbits/market","owner":"lnbits","description":"market extension, inspired by nostrmarket","archived":true,"fork":false,"pushed_at":"2024-05-14T08:15:40.000Z","size":133,"stargazers_count":4,"open_issues_count":8,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-11T01:35:16.379Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lnbits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-10T13:15:26.000Z","updated_at":"2024-07-09T10:08:18.000Z","dependencies_parsed_at":"2024-01-14T16:12:29.747Z","dependency_job_id":"b600406c-070d-41dd-a79f-c6613c6e5c0f","html_url":"https://github.com/lnbits/market","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnbits%2Fmarket","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnbits%2Fmarket/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnbits%2Fmarket/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lnbits%2Fmarket/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lnbits","download_url":"https://codeload.github.com/lnbits/market/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250986464,"owners_count":21518520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T06:01:23.973Z","updated_at":"2025-04-26T12:31:31.059Z","avatar_url":"https://github.com/lnbits.png","language":"HTML","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"\n\n### WE ADVISE USING \u003ca href=\"https://github.com/lnbits/nostrmarket#nostr-market-nip-15---lnbits-extension\"\u003eNOSTR MARKET\u003c/a\u003e, BUT HAVE LEFT THIS EXTENSION HERE IN CASE ANYONE WANTS TO CONTRIBUTE.\n\n\u003e This was originally built to be a nostr market as well, although now that turned into \u003ca href=\"https://github.com/lnbits/nostrmarket\"\u003ethis extension\u003c/a\u003e. The below has been kept for historcial context, but is irrelvant for this extension.\n\n## Nostr Diagon Alley protocol (for resilient marketplaces)\n\n`authur: Ben Arc`\n\n#### Original protocol https://github.com/lnbits/Diagon-Alley\n\n\u003e The concepts around resilience in Diagon Alley helped influence the creation of the NOSTR protocol, now we get to build Diagon Alley on NOSTR!\n\nIn Diagon Alley, `merchant` and `customer` communicate via NOSTR relays, so loss of money, product information, and reputation become far less likely if attacked.\n\nA `merchant` and `customer` both have a NOSTR key-pair that are used to sign notes and subscribe to events. \n\n#### For further information about NOSTR, see https://github.com/nostr-protocol/nostr\n\n\n## Terms\n\n* `merchant` - seller of products with NOSTR key-pair\n* `customer` - buyer of products with NOSTR key-pair\n* `product` - item for sale by the `merchant`\n* `stall` - list of products controlled by `merchant` (a `merchant` can have multiple stalls)\n* `marketplace` - clientside software for searching `stalls` and purchasing `products`\n\n## Diagon Alley Clients\n\n### Merchant admin\n\nWhere the `merchant` creates, updates and deletes `stalls` and `products`, as well as where they manage sales, payments and communication with `customers`. \n\nThe `merchant` admin software can be purely clientside, but for `convenience` and uptime, implementations will likely have a server listening for NOSTR events.\n\n### Marketplace\n\n`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`.\n\n## `Merchant` publishing/updating products (event)\n\nNIP-01 https://github.com/nostr-protocol/nips/blob/master/01.md uses the basic NOSTR event type.\n\nThe `merchant` event that publishes and updates product lists\n\nThe below json goes in `content` of NIP-01.\n\nData from newer events should replace data from older events.  \n\n`action` types (used to indicate changes):\n* `update` element has changed\n* `delete` element should be deleted\n* `suspend` element is suspended\n* `unsuspend` element is unsuspended\n\n\n```\n{\n    \"name\": \u003cString, name of merchant\u003e,\n    \"description\": \u003cString, description of merchant\u003e,\n    \"currency\": \u003cStr, currency used\u003e,\n    \"action\": \u003cString, optional action\u003e,\n    \"shipping\": [\n        {\n            \"id\": \u003cString, UUID derived from stall ID\u003e,\n            \"zones\": \u003cString, CSV of countries/zones\u003e,\n            \"price\": \u003cint, cost\u003e,\n        },\n        {\n            \"id\": \u003cString, UUID derived from stall ID\u003e,\n            \"zones\": \u003cString, CSV of countries/zones\u003e,\n            \"price\": \u003cint, cost\u003e,\n        },\n        {\n            \"id\": \u003cString, UUID derived from stall ID\u003e,\n            \"zones\": \u003cString, CSV of countries/zones\u003e,\n            \"price\": \u003cint, cost\u003e,\n        }\n    ],\n    \"stalls\": [\n        {\n            \"id\": \u003cUUID derived from merchant public-key\u003e,\n            \"name\": \u003cString, stall name\u003e,\n            \"description\": \u003cString, stall description\u003e,\n            \"categories\": \u003cString, CSV of voluntary categories\u003e,\n            \"shipping\": \u003cString, CSV of shipping ids\u003e,\n            \"action\": \u003cString, optional action\u003e,\n            \"products\": [\n                {\n                    \"id\": \u003cString, UUID derived from stall ID\u003e,\n                    \"name\": \u003cString, name of product\u003e,\n                    \"description\": \u003cString, product description\u003e,\n                    \"categories\": \u003cString, CSV of voluntary categories\u003e,\n                    \"amount\": \u003cInt, number of units\u003e,\n                    \"price\": \u003cInt, cost per unit\u003e,\n                    \"images\": [\n                        {\n                            \"id\": \u003cString, UUID derived from product ID\u003e,\n                            \"name\": \u003cString, image name\u003e,\n                            \"link\": \u003cString, URL or BASE64\u003e\n                        }\n                    ],\n                    \"action\": \u003cString, optional action\u003e,\n                },\n                {\n                    \"id\": \u003cString, UUID derived from stall ID\u003e,\n                    \"name\": \u003cString, name of product\u003e,\n                    \"description\": \u003cString, product description\u003e,\n                    \"categories\": \u003cString, CSV of voluntary categories\u003e,\n                    \"amount\": \u003cInt, number of units\u003e,\n                    \"price\": \u003cInt, cost per unit\u003e,\n                    \"images\": [\n                        {\n                            \"id\": \u003cString, UUID derived from product ID\u003e,\n                            \"name\": \u003cString, image name\u003e,\n                            \"link\": \u003cString, URL or BASE64\u003e\n                        },\n                        {\n                            \"id\": \u003cString, UUID derived from product ID\u003e,\n                            \"name\": \u003cString, image name\u003e,\n                            \"link\": \u003cString, URL or BASE64\u003e\n                        }\n                    ],\n                    \"action\": \u003cString, optional action\u003e,\n                },\n            ]\n        },\n        {\n            \"id\": \u003cUUID derived from merchant public_key\u003e,\n            \"name\": \u003cString, stall name\u003e,\n            \"description\": \u003cString, stall description\u003e,\n            \"categories\": \u003cString, CSV of voluntary categories\u003e,\n            \"shipping\": \u003cString, CSV of shipping ids\u003e,\n            \"action\": \u003cString, optional action\u003e,\n            \"products\": [\n                {\n                    \"id\": \u003cString, UUID derived from stall ID\u003e,\n                    \"name\": \u003cString, name of product\u003e,\n                    \"categories\": \u003cString, CSV of voluntary categories\u003e,\n                    \"amount\": \u003cInt, number of units\u003e,\n                    \"price\": \u003cInt, cost per unit\u003e,\n                    \"images\": [\n                        {\n                            \"id\": \u003cString, UUID derived from product ID\u003e,\n                            \"name\": \u003cString, image name\u003e,\n                            \"link\": \u003cString, URL or BASE64\u003e\n                        }\n                    ],\n                    \"action\": \u003cString, optional action\u003e,\n                }\n            ]\n        }\n    ]\n}\n\n```\n\nAs all elements are optional, an `update` `action` to a `product` `image`, may look as simple as:\n\n```\n{\n    \"stalls\": [\n        {\n            \"id\": \u003cUUID derived from merchant public-key\u003e,\n            \"products\": [\n                {\n                    \"id\": \u003cString, UUID derived from stall ID\u003e,\n                    \"images\": [\n                        {\n                            \"id\": \u003cString, UUID derived from product ID\u003e,\n                            \"name\": \u003cString, image name\u003e,\n                            \"link\": \u003cString, URL or BASE64\u003e\n                        }\n                    ],\n                    \"action\": \u003cString, optional action\u003e,\n                },\n            ]\n        }\n    ]\n}\n\n```\n\n\n## Checkout events\n\nNIP-04 https://github.com/nostr-protocol/nips/blob/master/04.md, all checkout events are encrypted\n\nThe below json goes in `content` of NIP-04.\n\n### Step 1: `customer` order (event)\n\n\n```\n{\n    \"id\": \u003cString, UUID derived from sum of product ids + timestamp\u003e,\n    \"name\": \u003cString, name of customer\u003e,\n    \"description\": \u003cString, description of customer\u003e,\n    \"address\": \u003cString, postal address\u003e,\n    \"message\": \u003cString, special request\u003e,\n    \"contact\": [\n        \"nostr\": \u003cString, NOSTR public key\u003e,\n        \"phone\": \u003cString, phone number\u003e,\n        \"email\": \u003cString, email address\u003e\n    ],\n    \"items\": [\n        {\n            \"id\": \u003cString, product ID\u003e,\n            \"quantity\": \u003cString, stall name\u003e,\n            \"message\": \u003cString, special request\u003e\n        },\n        {\n            \"id\": \u003cString, product ID\u003e,\n            \"quantity\": \u003cString, stall name\u003e,\n            \"message\": \u003cString, special request\u003e\n        },\n        {\n            \"id\": \u003cString, product ID\u003e,\n            \"quantity\": \u003cString, stall name\u003e,\n            \"message\": \u003cString, special request\u003e\n        }\n    \n}\n\n```\n\nMerchant should verify the sum of product ids + timestamp.\n\n### Step 2: `merchant` request payment (event)\n\nSent back from the merchant for payment. Any payment option is valid that the merchant can check.\n\nThe below json goes in `content` of NIP-04.\n\n`payment_options`/`type` include:\n* `url` URL to a payment page, stripe, paypal, btcpayserver, etc\n* `btc` onchain bitcoin address\n* `ln` bitcoin lightning invoice\n* `lnurl` bitcoin lnurl-pay  \n\n```\n{\n    \"id\": \u003cString, UUID derived from sum of product ids + timestamp\u003e,\n    \"message\": \u003cString, message to customer\u003e,\n    \"payment_options\": [\n        {\n            \"type\": \u003cString, option type\u003e,\n            \"link\": \u003cString, url, btc address, ln invoice, etc\u003e\n        },\n        {\n            \"type\": \u003cString, option type\u003e,\n            \"link\": \u003cString, url, btc address, ln invoice, etc\u003e\n        },\n                {\n            \"type\": \u003cString, option type\u003e,\n            \"link\": \u003cString, url, btc address, ln invoice, etc\u003e\n        }\n}\n\n```\n\n### Step 3: `merchant` verify payment/shipped (event)\n\nOnce payment has been received and processed.\n\nThe below json goes in `content` of NIP-04.\n\n```\n{\n    \"id\": \u003cString, UUID derived from sum of product ids + timestamp\u003e,\n    \"message\": \u003cString, message to customer\u003e,\n    \"paid\": \u003cBool, true/false has received payment\u003e,\n    \"shipped\": \u003cBool, true/false has been shipped\u003e,\n}\n\n```\n\n## Customer support events\n\nCustomer 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.\n\n## Additional\n\nStandard data models can be found here \u003ca href=\"models.json\"\u003ehere\u003c/a\u003e\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flnbits%2Fmarket","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flnbits%2Fmarket","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flnbits%2Fmarket/lists"}