{"type":"rich","version":"1.0","title":"Rusty Russell [ARCHIVE] wrote","author_name":"Rusty Russell [ARCHIVE] (npub1zw…hkhpx)","author_url":"https://yabu.me/npub1zw7cc8z78v6s3grujfvcv3ckpvg6kr0w7nz9yzvwyglyg0qu5sjsqhkhpx","provider_name":"njump","provider_url":"https://yabu.me","html":"📅 Original date posted:2019-11-08\n📝 Original message:\nYaacov Akiba Slama \u003cya at slamail.org\u003e writes:\n\u003e Hi Rusty,\n\u003e\n\u003e It seems that there are two kind of TLV fields in your proposition:\n\u003e 1) LN specific fields like `num_paths` and `payment_preimage`.\n\u003e 2) \"Business\" fields like `address1` and `currency`.\n\u003e I understand the need to define and include the first category, but I \n\u003e don't think that we need or can define the second category. These fields \n\u003e already exists in software like crm, erp, etc.. and are well defined by \n\u003e standard body.\n\u003e My suggestion is to have a generic field containing well defined \n\u003e structured and standardized data. See for instance \n\u003e https://en.wikipedia.org/wiki/EDIFACT and/or \n\u003e https://en.wikipedia.org/wiki/Universal_Business_Language.\n\nHi Yaacov,\n\n        I've been pondering this since reading your comment on the PR!\n\n        As a fan of standards, I am attracted to UBL (I've chaired an\nOASIS TC in the past and have great respect for them); as a fan of\nsimplicity I am not.  Forcing UBL implementation on wallet providers is\nsimply not going to happen, whatever I were to propose.\n\n\tWe also don't want duplication; what if the \"UBL field\" were to\nsay I were selling you a bridge for $1 and the description and amount\nfields actually said I was selling you a coffee for $3?\n\n\tHowever, since invoices/offers and UBL are both structures, we\nshould have an explicit mapping between the two.  What fields should\nhave their own existence in the invoice/offer and what should be in a\ngeneral UBL field is a question we have to think on further.\n\n        Anyway, you'll have to bear with me as I read this 172 page\nstandard...\n\nCheers,\nRusty.\n\n\u003e What do you think?\n\u003e PS: Sorry for crossposting here and in \n\u003e https://github.com/lightningnetwork/lightning-rfc/pull/694\n\u003e --yas\n\u003e\n\u003e On 05/11/2019 06:23, Rusty Russell wrote:\n\u003e\u003e Hi all,\n\u003e\u003e\n\u003e\u003e          This took longer than I'd indicated; for that I'm sorry.\n\u003e\u003e However, this should give us all something to chew on.  I've started\n\u003e\u003e with a draft \"BOLT 12\" (it might be BOLT 13 by the time it's finalized\n\u003e\u003e though!).\n\u003e\u003e\n\u003e\u003e I've also appended indications where we touch other BOLTs:\n\u003e\u003e 1. BOLT 7 gains a message/reply system, encoded like htlc onions and\n\u003e\u003e     failure messages.\n\u003e\u003e 2. BOLT 11 gains a `q` field for quantity; this avoids changing the\n\u003e\u003e     description when the user requests an invoice for more than one of something\n\u003e\u003e     (since changing the description between offer and invoice requires user\n\u003e\u003e     interaction: it's the *invoice* which you are committing to).\n\u003e\u003e\n\u003e\u003e There's definite handwaving in here; let's see if you can find it!\n\u003e\u003e\n\u003e\u003e Cheers,\n\u003e\u003e Rusty.\n\u003e\u003e\n\u003e\u003e # BOLT #12: Offer Protocols for Lightning Payments\n\u003e\u003e\n\u003e\u003e An higher-level, QR-code-ready protocol for dealing with invoices over\n\u003e\u003e Lightning.  There are two simple flows supported: in one, a user gets\n\u003e\u003e an offer (`lno...`) and requests an invoice over the lightning\n\u003e\u003e network, obtaining one (or an error) in reply.  In the other, a user\n\u003e\u003e gets an invoice request (`lni...`), and sends the invoice over the\n\u003e\u003e lightning network, retreiving an empty reply.\n\u003e\u003e\n\u003e\u003e # Table of Contents\n\u003e\u003e\n\u003e\u003e    * [Offers](#offers)\n\u003e\u003e      * [Encoding](#encoding)\n\u003e\u003e      * [TLV Fields](#tlv-fields)\n\u003e\u003e    * [Invrequests](#invrequests)\n\u003e\u003e      * [Encoding](#encoding)\n\u003e\u003e      * [TLV Fields](#tlv-fields)\n\u003e\u003e\n\u003e\u003e # Offers\n\u003e\u003e\n\u003e\u003e Offers supply a reader with enough information to request one or more\n\u003e\u003e invoices via the lightning network itself.\n\u003e\u003e\n\u003e\u003e ## Encoding\n\u003e\u003e\n\u003e\u003e The human-readable part of a Lightning offer is `lno`.  The data part\n\u003e\u003e consists of three parts:\n\u003e\u003e\n\u003e\u003e 1. 0 or more [TLV](01-messaging.md#type-length-value-format) encoded fields.\n\u003e\u003e 2. A 32-byte nodeid[1]\n\u003e\u003e 3. 64-byte signature of SHA256(hrp-as-utf8 | tlv | nodeid).\n\u003e\u003e\n\u003e\u003e ## TLV Fields\n\u003e\u003e\n\u003e\u003e The TLV fields define how to get the invoice, and what it's for.\n\u003e\u003e Each offer has a unique `offer_idenfitier` so the offering node can\n\u003e\u003e distinguish different invoice requests.\n\u003e\u003e\n\u003e\u003e Offers can request recurring payments of various kinds, and specify\n\u003e\u003e what base currency they are calculated in (the actual amount will be\n\u003e\u003e in the invoice).\n\u003e\u003e\n\u003e\u003e `additional_data` is a bitfield which indicates what information the\n\u003e\u003e invoice requester should (odd) or must (even) supply:\n\u003e\u003e 1. Bits `0/1`: include `delivery_address`\n\u003e\u003e 2. Bits `2/3`: include `delivery_telephone_number`\n\u003e\u003e 3. Bits `4/5`: include `voucher_code`\n\u003e\u003e 4. Bits `6/7`: include `refund_proof`\n\u003e\u003e\n\u003e\u003e `refund_for` indicates an offer for a (whole or part) refund for a\n\u003e\u003e previous invoice, as indicated by the `payment_hash`.\n\u003e\u003e\n\u003e\u003e 1. tlvs: `offer`\n\u003e\u003e 2. types:\n\u003e\u003e      1. type: 1 (`paths`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`u16`:`num_paths`]\n\u003e\u003e          * [`num_paths*path`:`path`]\n\u003e\u003e      1. type: 2 (`description`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`...*byte`:`description`]\n\u003e\u003e      1. type: 3 (`expiry`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`tu64`:`seconds_from_epoch`]\n\u003e\u003e      1. type: 4 (`offer_identifier`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`...*byte`:`id`]\n\u003e\u003e      1. type: 5 (`amount`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`4*byte`:`currency`]\n\u003e\u003e          * [`tu64`:`amount`]\n\u003e\u003e      1. type: 6 (`additional_data`)\n\u003e\u003e      2. data:\n\u003e\u003e \t    * [`...*byte`:`rbits`]\n\u003e\u003e      1. type: 7 (`recurrance`)\n\u003e\u003e      2. data:\n\u003e\u003e \t    * [`byte`:`time_unit`]\n\u003e\u003e \t\t* [`u32`:`period`]\n\u003e\u003e \t\t* [`tu32`:`number`]\n\u003e\u003e      1. type: 8 (`recurrance_base`)\n\u003e\u003e      2. data:\n\u003e\u003e \t\t* [`u32`:`basetime`]\n\u003e\u003e \t\t* [`tu32`:`paywindow`]\n\u003e\u003e      1. type: 9 (`quantity`)\n\u003e\u003e      2. data:\n\u003e\u003e \t\t* [`tu64`:`max`]\n\u003e\u003e      1. type: 10 (`refund_for`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`32*byte`:`payment_hash`]\n\u003e\u003e\n\u003e\u003e 1. subtype: `path`\n\u003e\u003e 2. data:\n\u003e\u003e     * [`u16`:`num_hops`]\n\u003e\u003e     * [`num_hops*hop`:`hops`]\n\u003e\u003e\n\u003e\u003e 1. subtype: `hop`\n\u003e\u003e 2. data:\n\u003e\u003e     * [`pubkey`:`nodeid`]\n\u003e\u003e     * [`short_channel_id`:`short_channel_id`]\n\u003e\u003e     * [`u16`:`flen`]\n\u003e\u003e     * [`flen*byte`:`features`]\n\u003e\u003e\n\u003e\u003e ## Requirements For Offers And Invrequests\n\u003e\u003e\n\u003e\u003e A writer of an offer or an invrequest:\n\u003e\u003e    - if it is connected only by private channels:\n\u003e\u003e      - MUST include `paths` containing a path to the node.\n\u003e\u003e    - otherwise:\n\u003e\u003e      - MAY include `paths` containing a path to the node.\n\u003e\u003e    - MUST describe the item(s) being offered or purpose of invoice in `description`.\n\u003e\u003e    - MUST include `expiry` if the offer/invrequest will not be valid after some time.\n\u003e\u003e    - if it includes `expiry`:\n\u003e\u003e      - MUST set `seconds_from_epoch` to the expiry time in seconds since 1970 UTC.\n\u003e\u003e\n\u003e\u003e ## Requirements For Offers\n\u003e\u003e\n\u003e\u003e A writer of an offer:\n\u003e\u003e    - MUST use a unique `offer_idenfitier` for each offer.\n\u003e\u003e    - MAY include `recurrence` to indicate offer should trigger time-spaced\n\u003e\u003e      invoices.\n\u003e\u003e    - MUST include `amount` if it includes `recurrence`.\n\u003e\u003e    - if it includes `amount`:\n\u003e\u003e      - MUST specify `currency` as the ISO 4712 or BIP-0173, padded with zero bytes if required\n\u003e\u003e \t- MUST specify `amount` to the amount expected for the invoice, as the ISO 4712 currency unit multiplied by exponent, OR the BIP-0173 minimum unit (eg. `satoshis`).\n\u003e\u003e    - if it requires specific fields in the invoice:\n\u003e\u003e      - MUST set the corresponding even bits in the `additional_data` field\n\u003e\u003e\n\u003e\u003e A reader of an offer:\n\u003e\u003e    - SHOULD gain user consent for recurring payments.\n\u003e\u003e    - SHOULD allow user to view and cancel recurring payments.\n\u003e\u003e    - SHOULD gain user consent to send `delivery_` fields.\n\u003e\u003e    - if it uses `amount` to provide the user with a cost estimate:\n\u003e\u003e \t- MUST warn user if amount of actual invoice differs significantly\n\u003e\u003e \t\tfrom that expectation.\n\u003e\u003e    - FIXME: more!\n\u003e\u003e\n\u003e\u003e ## Recurrance\n\u003e\u003e\n\u003e\u003e Some offers are *periodic*, such as a subscription service or monthly\n\u003e\u003e dues, in that payment is expected to be repeated.  There are many\n\u003e\u003e different flavors of repetition, consider:\n\u003e\u003e\n\u003e\u003e * Payments due on the first of every month, for 6 months.\n\u003e\u003e * Payments due on every Monday, 1pm Pacific Standard Time.\n\u003e\u003e * Payments due once a year:\n\u003e\u003e     * which must be made on January 1st, or\n\u003e\u003e     * which are only valid if started January 1st 2020, or\n\u003e\u003e     * which if paid after January 1st you (over) pay the full rate first year, or\n\u003e\u003e     * which if paid after January 1st are paid pro-rata for the first year, or\n\u003e\u003e     * which repeat from whenever you made the first payment\n\u003e\u003e\n\u003e\u003e Thus, each payment has:\n\u003e\u003e 1. A `time_unit` defining 0 (seconds), 1 (days), 2 (months), 3 (years).\n\u003e\u003e 2. A `period`, defining how often (in `time_unit`) it has to be paid.\n\u003e\u003e 3. An optional `number` of total payments to be paid.\n\u003e\u003e 4. An optional `basetime`, defining when the first payment applies\n\u003e\u003e     in seconds since 1970-01-01 UTC.\n\u003e\u003e 5. An optional `paywindow`, defining how many seconds into the period\n\u003e\u003e     a payment will be accepted: 0xFFFFFFFF being a special value meaning\n\u003e\u003e     \"any time during the period, but you will have to pay proportionally\n\u003e\u003e     to the remaining time in the period\".\n\u003e\u003e\n\u003e\u003e Note that the `expiry` field covers the case where an offer is no longer\n\u003e\u003e valid after January 1st 2020.\n\u003e\u003e\n\u003e\u003e ## Default Offer\n\u003e\u003e\n\u003e\u003e The \"default offer\" of a node is a nominal offer used to send\n\u003e\u003e unsolicited payments.  It is generally not actually sent, but can be\n\u003e\u003e used by any other node as if it has been.  It has the following\n\u003e\u003e fields:\n\u003e\u003e\n\u003e\u003e * `offer_idenfitier`: zero-length\n\u003e\u003e * `d`: any\n\u003e\u003e * `n`: the node id of the recipient.\n\u003e\u003e\n\u003e\u003e ## Invoice Request Encoding\n\u003e\u003e\n\u003e\u003e Once it has an offer, the node can request an actual invoice using the\n\u003e\u003e `invoice_req` message inside `directed`'s `onion_routing_packet`.  It\n\u003e\u003e would expect an `invoice_or_error_tlv` inside the `directed_reply`\n\u003e\u003e message.\n\u003e\u003e\n\u003e\u003e This includes a `tag` it can use to identify replies, the\n\u003e\u003e `offer_idenfitier` from the offer, a `key` it can use to prove it was\n\u003e\u003e the requester of this invoice, a `recurrence` number if this\n\u003e\u003e is a payment in a recurring series, and other codes as required.\n\u003e\u003e\n\u003e\u003e The `refund_proof` refers to a previous invoice paid by the sender for\n\u003e\u003e the specific case of a `refund_for` offer.  It provides proof of\n\u003e\u003e payment (the `payment_preimage` and also a signature of the\n\u003e\u003e `payment_hash` from the `key` which requested the being-refunded\n\u003e\u003e invoice (which does *not* have to be the same as this `key`!).\n\u003e\u003e\n\u003e\u003e 1. tlvs: `invoice_request_tlv`\n\u003e\u003e 2. types:\n\u003e\u003e     1. type: 1 (`tag`)\n\u003e\u003e     2. data:\n\u003e\u003e        * [`...*byte`:`tag`]\n\u003e\u003e     1. type: 2 (`offer_identifier`)\n\u003e\u003e     2. data:\n\u003e\u003e        * [`...*byte`:`id`]\n\u003e\u003e     1. type: 3 (`key`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`32`:`key`]\n\u003e\u003e     1. type: 4 (`recurrence`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`tu64`:`number`]\n\u003e\u003e     1. type: 5 (`quantity`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`tu64`:`n`]\n\u003e\u003e     1. type: 6 (`delivery_address_name`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`name`]\n\u003e\u003e     1. type: 7 (`delivery_address1`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`address1`]\n\u003e\u003e     1. type: 8 (`delivery_address2`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`address2`]\n\u003e\u003e     1. type: 9 (`delivery_city`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`city`]\n\u003e\u003e     1. type: 10 (`delivery_state_province_or_region`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`state_province_or_region`]\n\u003e\u003e     1. type: 11 (`delivery_zip_or_postal_code`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`zip_or_postal_code`]\n\u003e\u003e     1. type: 12 (`delivery_country`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`2*byte`:`country_code`]\n\u003e\u003e     1. type: 13 (`delivery_telephone_number`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`tel`]\n\u003e\u003e     1. type: 14 (`voucher_code`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*byte`:`code`]\n\u003e\u003e     1. type: 15 (`refund_proof`)\n\u003e\u003e     2. data:\n\u003e\u003e        * [`32*byte`:`payment_preimage`]\n\u003e\u003e        * [`signature`:`signature`]\n\u003e\u003e\n\u003e\u003e ## Requirements\n\u003e\u003e\n\u003e\u003e FIXME: many more\n\u003e\u003e Sender MUST use ISO 3166 alpha-2 code for `delivery_country`.\n\u003e\u003e Sender MUST set offer_identifier to match offer.\n\u003e\u003e Sender MUST include `key`\n\u003e\u003e     - SHOULD use a transient unpredictable key\n\u003e\u003e     - MUST reuse key for successive recurring invoices.\n\u003e\u003e Sender MUST set `recurrence` for recurring invoices.\n\u003e\u003e\n\u003e\u003e Receiver MUST check `offer_identifier`\n\u003e\u003e Receiver MUST check `delivery_` fields.\n\u003e\u003e Receiver MUST check `recurrence`.\n\u003e\u003e Receiver MUST check `amount`.\n\u003e\u003e\n\u003e\u003e 1. tlvs: `invoice_or_error_tlv`\n\u003e\u003e 2. types:\n\u003e\u003e     1. type: 1 (`tag`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`...*byte`:`tag`]\n\u003e\u003e     1. type: 3 (`omitted`)\n\u003e\u003e     2. data:\n\u003e\u003e \t * [`...*u64`:`omitted_fields`]\n\u003e\u003e     1. type: 4 (`invoice`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`...*byte`:`invoice`]\n\u003e\u003e     1. type: 5 (`message`)\n\u003e\u003e       * [`...*byte`:`message`]\n\u003e\u003e     1. type: 6 (`replacement`)\n\u003e\u003e     2. data:\n\u003e\u003e       * [`signature`:`signature`]\n\u003e\u003e       * [`...*byte`:`offer`]\n\u003e\u003e\n\u003e\u003e Sender:\n\u003e\u003e - MUST copy `tag` from sender.\n\u003e\u003e - MUST omit fields it does not use, and place number in order in `omitted_fields`.\n\u003e\u003e - if it includes `invoice`:\n\u003e\u003e    - MUST not include `message`\n\u003e\u003e    - MUST not include `replacement`\n\u003e\u003e    - MUST [merkle fields it used](#merkle-calculation) and place that in invoice `s` field.\n\u003e\u003e - otherwise, if it includes `replacement`:\n\u003e\u003e    - MAY include `message`\n\u003e\u003e - otherwise:\n\u003e\u003e    - MUST include `message` describing the error.\n\u003e\u003e\n\u003e\u003e Receiver:\n\u003e\u003e - MUST check that `tag` matches req.\n\u003e\u003e - if `replacement`:\n\u003e\u003e    - MUST fail if `signature` does not sign `offer` with same key as original.\n\u003e\u003e    - MUST only fetch once (no double-redirects!)\n\u003e\u003e - if description or amount significantly changes, must re-ask user.\n\u003e\u003e    - SHOULD note if description simply has something appended (eg \"+ postage\").\n\u003e\u003e - within invoice:\n\u003e\u003e      - MUST check that `s` matches merkle of fields, minus `omitted`.\n\u003e\u003e \t- MUST check that no vital fields are in `omitted`.\n\u003e\u003e \t- MUST check that `d` matches `description`\n\u003e\u003e      - MUST check that `q` DNE if `quantity` DNE, otherwise is equal.\n\u003e\u003e      - Must check valid signature, etc.\n\u003e\u003e\n\u003e\u003e ## Merkle Calculation\n\u003e\u003e\n\u003e\u003e 1. For each `invoice_req_tlv` field in ascending `tlv` type order:\n\u003e\u003e     1. If the field was omitted, it is added to `omitted_fields`.\n\u003e\u003e     2. Otherwise, the immediate parent merkle is:\n\u003e\u003e     \n\u003e\u003e        SHA256(SHA256(`tag` | `be64-n`) | SHA256(`tlv-value`))\n\u003e\u003e\n\u003e\u003e        Where `be64-n` is a 64-bit big-endian counter starting at 0 and\n\u003e\u003e        incrementing for each leaf.\n\u003e\u003e\n\u003e\u003e     3. Order these nodes in increasing SHA256(`tag` | `be64-n`) order.\n\u003e\u003e\n\u003e\u003e 2. Create additional leaves until `be64-n` is the next power of 2:\n\u003e\u003e\n\u003e\u003e        SHA256(`tag` | `be64-n`)\n\u003e\u003e\n\u003e\u003e 3. Combine adjacent leaves using SHA256(leaf1 | leaf2) until none remain.\n\u003e\u003e\n\u003e\u003e By creating adjacent leaves using the `tag` field and a counter, and\n\u003e\u003e sorting the leaves, the only significant information revealed by a\n\u003e\u003e merkle proof on a node is the depth of tree (which implies the total\n\u003e\u003e number of TLV fields).\n\u003e\u003e\n\u003e\u003e # InvRequests\n\u003e\u003e\n\u003e\u003e There are times when it makes sense to request an invoice over another\n\u003e\u003e medium, such as HTTP or a QR code.\n\u003e\u003e\n\u003e\u003e ## Encoding\n\u003e\u003e\n\u003e\u003e The human-readable part of a Lightning invrequest is `lni`.  The data part\n\u003e\u003e consists of three parts:\n\u003e\u003e\n\u003e\u003e 1. 0 or more [TLV](01-messaging.md#type-length-value-format) encoded fields.\n\u003e\u003e 2. A 32-byte nodeid[1]\n\u003e\u003e 3. 64-byte signature of SHA256(hrp-as-utf8 | tlv | nodeid).\n\u003e\u003e\n\u003e\u003e ## TLV Fields\n\u003e\u003e\n\u003e\u003e 1. tlvs: `invreq`\n\u003e\u003e 2. types:\n\u003e\u003e      1. type: 1 (`paths`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`u16`:`num_paths`]\n\u003e\u003e          * [`num_paths*path`:`path`]\n\u003e\u003e      1. type: 2 (`description`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`...*byte`:`description`]\n\u003e\u003e      1. type: 3 (`expiry`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`tu64`:`seconds_from_epoch`]\n\u003e\u003e      1. type: 4 (`amount`)\n\u003e\u003e      2. data:\n\u003e\u003e          * [`tu64`:`millisatoshis`]\n\u003e\u003e\n\u003e\u003e The fields `paths`, `description`, and `expiry` fields are the\n\u003e\u003e same as those for offers; the optional `amount` field describes the\n\u003e\u003e amount an invoice will be accepted for.\n\u003e\u003e\n\u003e\u003e Upon parsing and accepting an `invreq`, the node sends an\n\u003e\u003e `invoice_or_error_tlv` within an onion.  The reply is empty.\n\u003e\u003e\n\u003e\u003e ## Requirements\n\u003e\u003e\n\u003e\u003e The requirements for `paths`, `description` and `expiry` are\n\u003e\u003e [described above](#requirements-for-offers-and-invrequests).\n\u003e\u003e\n\u003e\u003e FIXME: More.\n\u003e\u003e\n\u003e\u003e [1] Assuming we go for Schnorr sigs and 32-byte pubkeys.\n\u003e\u003e ----\n\u003e\u003e Addendum: BOLT #7: P2P Node and Channel Discovery and Directed Messages\n\u003e\u003e ...\n\u003e\u003e # Directed Messages\n\u003e\u003e\n\u003e\u003e Directed messages allow peers to use existing connections to query for\n\u003e\u003e invoices (see [BOLT 12](12-offer-encoding.md)).  Like gossip messages,\n\u003e\u003e they are not associated with a particular local channel.\n\u003e\u003e\n\u003e\u003e The `id` is a unique, transient identifier between the peers, used to\n\u003e\u003e identify match messages and replies.\n\u003e\u003e\n\u003e\u003e ## The `directed` and `directed_reply` Messages\n\u003e\u003e\n\u003e\u003e 1. type: 384 (`directed`) (`option_directed_messages`)\n\u003e\u003e 2. data:\n\u003e\u003e      * [`chain_hash`:`chain_hash`]\n\u003e\u003e      * [`u64`:`id`]\n\u003e\u003e      * [`1366*byte`:`onion_routing_packet`]\n\u003e\u003e\n\u003e\u003e 1. type: 384 (`directed_reply`) (`option_directed_messages`)\n\u003e\u003e 2. data:\n\u003e\u003e      * [`chain_hash`:`chain_hash`]\n\u003e\u003e      * [`u64`:`id`]\n\u003e\u003e      * [`u16`:`len`]\n\u003e\u003e      * [`len*byte`:`reply`]\n\u003e\u003e\n\u003e\u003e ## Requirements\n\u003e\u003e\n\u003e\u003e FIXME: similar to update_add_htlc and update_fail_htlc.\n\u003e\u003e FIXME: define reasonable timeout after which you can forget if not replied?\n\u003e\u003e _______________________________________________\n\u003e\u003e Lightning-dev mailing list\n\u003e\u003e Lightning-dev at lists.linuxfoundation.org\n\u003e\u003e https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev"}
