From 7e1d3d1f237513862e3d0ab480fc0f56c7353cd4 Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Sat, 27 Sep 2025 11:42:02 +0200 Subject: [PATCH 1/3] nip-AD --- AD.md | 585 ++++++++++++++++++++++++++++++ README.md | 3 + nostr-content-taxonomy.csv | 721 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1309 insertions(+) create mode 100644 AD.md create mode 100644 nostr-content-taxonomy.csv diff --git a/AD.md b/AD.md new file mode 100644 index 0000000000..a21c4a902d --- /dev/null +++ b/AD.md @@ -0,0 +1,585 @@ +# NIP-AD: Decentralized Advertising Protocol + + + +`draft` `optional` `author:riccardobl` + + +--- + +## High-level Overview + +This NIP defines a standard protocol for coordinating interactions in a decentralized advertising ecosystem built on Nostr. + +The ecosystem involves four main roles: + +* **Application**: A passive entity that serves as the ad placement target. It does not participate in negotiations directly but represents the environment (website, app, or codebase) where ads are shown. Applications also act as the recipient of payouts for completed ad actions. +* **Advertiser**: The entity that wants to promote a product, service, or brand. Advertisers create bids and fund ad placements. +* **Delegate**: A service that manages negotiations and executes payments on behalf of the advertiser. Delegates handle the interaction with offerers and enforce the campaign’s rules. +* **Offerer**: A user of an application who is presented with ads as part of their interaction with the app. Offerers engage in negotiations with the delegate and carry out the display of ads. + +All communication flows between the **Offerer** and the **Delegate**, but always in relation to a bid originally created by an **Advertiser**. The advertiser entrusts the **Delegate** with managing the ad campaign, while the **Application** provides the context and the payout address. + + +### Advertiser’s workflow + +Advertisers are entities (individuals, companies, or organizations) that want to promote a product, service, or brand. + +They interact with two main components: + +* A **Client**, which facilitates ads creation and submission of bids. +* A **Delegate Service**, which negotiates deals and manages payments for ad placements on behalf of the advertiser. + +The workflow looks like this: + +1. The **Advertiser** publishes a [Bidding Event](#bidding-event), tagging it with the public key of the chosen **Delegate Service**. +2. The **Delegate Service** picks up the event and decides whether to handle it or ignore it. +3. For each bid it manages, the **Delegate Service** processes incoming [Offers](#making-an-offer), handles the [Negotiation](#negotiation-events), and pays the **Applications** once the ad action is successfully completed. + +*Advertisers can rely on third-party delegate services, or they may choose to run their own for maximum control and decentralization.* + +*The delegate might take a small fee from the advertiser for its services, but the fee structure and terms are outside the scope of this NIP and specific to the delegate’s implementation.* + +### Application + +An **Application** is any digital environment where ads can be shown. + +It is represented by a unique Nostr public key and can be: + +* A website +* A mobile app +* A game +* The user itself + +etc... + +**Delegates** pay **Applications** for bids that are successfully fulfilled by **Offerers**. + +To accept payments, each application must have a published NIP-01 metadata event containing a `lud16` or `lud06` field with its payment address. + + + + +### Offerer’s workflow + + + +An **Offerer** is a user of an application that can display ads in exchanges of payments made to the application `lud16` or `lud06` address. + +When users interact with the application, they automatically trigger its **discovery logic**, which searches for relevant bids. The specifics of this filtering are implementation-dependent, but common strategies include: + +* Subscribing to relays with filters that match the application’s current context (e.g., page content, session type). +* Taking into account user preferences, such as interests or blocked advertisers. +* Applying additional application-specific rules. + +Once a suitable **Bid** is identified, the **Offerer** initiates a negotiation with the bid’s **Delegate** using [Negotiation Events](#negotiation-events). To preserve privacy, these events are signed with *ephemeral, anonymous private keys* generated by the application itself. These keys are short-lived (e.g., refreshed at each app launch or per session), ensuring that individual offers cannot be trivially linked back to the user. + + + +The **Offerer’s workflow** is: + +1. When a relevant bid is found, a random private key is generated. This key will be used to sign every event sent by the **Offerer**. +2. An [Offer Event](#making-an-offer), tagged with the application’s pubkey, is sent to the **Delegate** specified in the bid. +3. The **Delegate** reviews the offer and either: + + - Accepts it with an [Accept Offer Event](#accepting-an-offer). + - Rejects it with a [Bailing Event](#bailing-or-cancelling-an-offer). + +4. If accepted, the **Offerer** must display the ad and, once the required action is completed (or assumed to be completed), send a [Payment Request Event](#requesting-a-payment) to the **Delegate**. +5. The **Delegate** may verify the action (e.g., by tracking if the link was followed) and pay the application’s designated payment `lud16`/`lud06` address. +6. The **Delegate** then publishes a [Payout Event](#payout-event) and the negotiation is considered complete. + +At any time, either party can [Bail](#bailing-or-cancelling-an-offer) out of the negotiation with a reason. +To reduce fraud or abuse, participants may impose a [Proof-of-Work penalty](#punishments-and-due-diligence) if the other party is suspected of cheating or misbehaving. + + + +## Bidding Event + +A replaceable event (`kind:30100`) where an advertiser bids for ad placement. + +```json +{ + "kind": 30100, + "content": json({ + "description": "", + "context": "", + "payload": "", + "link": "", + "call_to_action": "", + "bid": , + "hold_time":