Skip to content

Latest commit

 

History

History
283 lines (242 loc) · 10 KB

XX.md

File metadata and controls

283 lines (242 loc) · 10 KB

NIP-XX

Accommodation

draft optional author:PatrickGeyer

The purpose of this NIP is to allow nostr users to discover accommodation availability similarly to AirBnB, booking.com or longer-term accommodation finding services.

Terms

  • guest - NOSTR user that is searching for accommodation
  • host - NOSTR user that is providing accommodation
  • listing - item of accommodation

Nostr Marketplace Clients

Hoster admin

Where the host creates, updates and deletes listings, as well as where they manage bookings, payments and communication with guests.

The host admin software can be purely clientside, but for convenience and uptime, implementations will likely have a server client listening for NOSTR events.

Guest browsing

Listing browsing software should be entirely clientside, either as a stand-alone app, or as a purely frontend webpage. A guest subscribes to listing events tagged with specific area and availability date range. These become listed and searchable. The browsing client is like any other booking site, with date selector, pricing and eventual payment.

Hoster publishing/updating listings (event)

A hoster can publish these events:

Kind Description NIP
0 set_meta The merchant description (similar with any nostr public key). NIP01
30021 set_listing Create or update a listing. NIP33 (Parameterized Replaceable Event)
30022 set_booking Create or update a booking. NIP33 (Parameterized Replaceable Event)
4 direct_message Communicate with the customer. The messages can be plain-text or JSON. NIP09
5 delete Delete a product or a stall. NIP05

Event 30021: Create or update a listing.

Event Content:

{
    "id": <String, UUID generated by the merchant. Sequential IDs (`0`, `1`, `2`...) are discouraged>,
    "name": <String, stall name>,
    "description": <String (optional), stall description>,
    "amountPerDay": float,
    "minStay": "P(n)Y(n)M(n)DT(n)H(n)M(n)S", <String, ISO 8601 duration format>
    "checkIn": "T12:00", <String, ISO 8601 time format>
    "checkOut": "T12:00", <String, ISO 8601 time format>
    "currency": "USD", <String, currency used>,
    "location": <String, geohash of 8 digits (accuracy should be 19 meters)>
    "discounts": [
        {
            "P(n)Y(n)M(n)DT(n)H(n)M(n)S": "0.5",
        }
    ],
    "quantity": 1, <Integer>
    "type": "room" | "studio" | "flat" | "house",
    "images": <[String], array of image/video URLs, optional>,
    "amenities": <{[String]: any}[], array of standardized amenities this listing offers>,
    "private": <String, encrypted JSON encoded properties that should only be shared after a booking request>: {

        "address": <String, provide exact address>
    }
}

List of amenities: All default to zero or false if not specified

{
    "airconditioning": boolean,
    "allows_pets": boolean,
    "bathtub": integer,
    "beds: integer,
    "tv": integer,
    "crib": boolean,
    "tumble_dryer": boolean,
    "washer": boolean,
    "elevator": boolean,
    "free_parking": boolean,
    "gym": boolean,
    "hair_dryer": boolean,
    "heating": boolean,
    "high_chair": boolean,
    "wireless_internet": boolean,
    "iron": boolean,
    "jacuzzi": boolean,
    "kitchen": boolean,
    "outlet_covers": boolean,
    "pool": boolean,
    "private_entrance": boolean,
    "smoking_allowed": boolean,
    "breakfast": boolean,
    "fireplace": boolean,
    "smoke_detector": boolean,
    "essentials": boolean,
    "shampoo": boolean,
    "infants_allowed": boolean,
    "children_allowed": boolean,
    "hangers": boolean,
    "flat_smooth_pathway_to_front_door": boolean,
    "grab_rails_in_shower_and_toilet": boolean,
    "oven": boolean,
    "bbq": boolean,
    "balcony": boolean,
    "patio": boolean,
    "dishwasher": boolean,
    "refrigerator": boolean,
    "garden_or_backyard": boolean,
    "microwave": boolean,
    "coffee_maker": boolean,
    "dishes_and_silverware": boolean,
    "stove": boolean,
    "fire_extinguisher": boolean,
    "carbon_monoxide_detector": boolean,
    "luggage_dropoff_allowed": boolean,
    "beach_essentials": boolean,
    "beachfront": boolean,
    "baby_monitor": boolean,
    "babysitter_recommendations": boolean,
    "childrens_books_and_toys": boolean,
    "game_console": boolean,
    "street_parking": boolean,
    "paid_parking": boolean,
    "hot_water": boolean,
    "lake_access": boolean,
    "single_level_home": boolean,
    "waterfront": boolean,
    "first_aid_kit": boolean,
    "handheld_shower_head": boolean,
    "home_step_free_access": boolean,
    "lock_on_bedroom_door": boolean,
    "mobile_hoist": boolean,
    "path_to_entrance_lit_at_night": boolean,
    "pool_hoist": boolean,
    "ev_charger": boolean,
    "rollin_shower",
    shower_chair,
    tub_with_shower_bench
    wide_clearance_to_bed
    wide_clearance_to_shower_and_toilet
    wide_hallway_clearance
    baby_bath
    changing_table
    room_darkening_shades
    stair_gates
    table_corner_guards
    extra_pillows_and_blankets
    ski_in_ski_out
    window_guards
    disabled_parking_spot
    grab_rails_in_toilet
    events_allowed
    common_spaces_shared
    bathroom_shared
    security_cameras
}

Event Tags:

  "tags": [["d", <String, id of first issued event of this listing>]]
  • the d tag is required by NIP33. Its value MUST be the same as the previous listing nostr event id.

Booking enquiry messages

All checkout/booking enquiry events are sent as JSON strings using (NIP04).

The host and the guest can exchange JSON messages that represent different actions. Each JSON message MUST have a type field indicating the what the JSON represents. Possible types:

Message Type Sent By Description
0 Guest New Booking
1 Hoster Payment Request
2 Hoster Order Status Update

Step 1: Booking order (event)

The below json goes in content of NIP04.

"tags": [["escrow": ""]<Optional>, ["e", "" <String, event id of listing publication>], ["type", "booking-enquiry"]], //NIP-XX: Escrow service, type tag required to quickly pull in booking related messages to clients
"kind": 4,
"content": 
{
    "type": 0,
    "contact": {
        "phone": <String (optional), if the customer wants to be contacted by phone>,
        "email": <String (optional), if the customer wants to be contacted by email>,
    },
    "start": <Date>,
    "stay": <Duration>
}

Step 2: host accept booking (event)

The below json goes in content of NIP04.

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
{
    "tags": [["e", <String, event id of >]]
"content": {
    "type": 1,
    "payment_options": [
        {
            "type": <String, option type>,
            "link": <String, url, btc address, ln invoice, etc>
        },
        {
            "type": <String, option type>,
            "link": <String, url, btc address, ln invoice, etc>
        },
                {
            "type": <String, option type>,
            "link": <String, url, btc address, ln invoice, etc>
        }
    ]
}
}

Step 3: host verify payment/booked (event)

Once payment has been received and processed, the host will publish a booking event, it will enclude a NIP-04 encrypted pubkey of the guest, so that the guest can be sure the booking is allocated to them.

{
    "tags": [["e", <String, event id of NIP04 booking enquiry>, 
    ["listing_id", <String, event id of listing>], ["encrypted_guest_pubkey", <String, encrypted pubkey received as part of booking enquiry>]],
    "kind": 4,
"content": 
{
    "type": 2,
    "status": ACCEPTED/REJECTED 
}
}

Event 30022: Create or update a booking

Event Content:

{
    "tags": [["e", <String, event id of NIP04 booking enquiry>, 
    ["listing_id", <String, event id of listing>], ["encrypted_guest_pubkey", <String, encrypted pubkey received as part of booking enquiry>]],
    "kind": 4,
"content": 
{
    "start": <Date (optional), product description>,
    "stay": <String, ISO 8601 duration format>,
}
}

Event Tags:

  "tags": [
       ["d", <String, id of booking],
       ["e", <String, id of listing>]
       ...
    ]
  • the d tag is required by NIP33. Its value MUST be the same as the booking id.

Support events

Messaging the host or guest is handled over whatever communication method was specified. If communicating via nostr, NIP-04 is used https://github.com/nostr-protocol/nips/blob/master/04.md.

Additional