5

I recently got an BOLT11 invoice from a store. For example this one:

LNBC13934430N1PWJUJEZPP5K7FLC2M5CLHTWMTF3HZDN7VVRCA4RNFAFA89F2D6KGYWW4JCSDAQDZ62PSKJEPQW3HJQ4RGV5SYC6T8DP6XU6TWVUSYXMMWVEJHYETWVDJJQ2Z0WFJX2U3QF9ZR5GZ5F3PNZWFD25UY54Z39YXQZURCQP2RZJQG8ZM9WXGVHZPMUQEWY9J9KDQNRVLZHPCWM6S8CVLC2CKRDNELE42Z9U5VQQY3SQQYQQQQL8QQQQPJQQ9Q6KM84F7KTW6UV574UR2LFNKZLM7VNK8NJRZV20JD8SAW6FZ3TQGSZE6YUT0X2UXGDGYJZGTXEFSQSSEVTKFF97P3TER5K23ZPHDDXHQQ95UT4N

Luckily I my node was able to find a route to the destination but if it wouldn't? How could I find out the nodeid to open and fund a direct payment channel with the store? They did not say anything about their nodeid on their website.

1 Answer 1

4

Lightning invoices are signed by the node issuing the invoice in order to verify the signature we need to know the node id. Thus it is included in the invoice. Lightning nodes provide an API to decode invoices.

In c-lightning you can do (lnd below!)

lightning-cli decodepay LNBC13934430N1PWJUJEZPP5K7FLC2M5CLHTWMTF3HZDN7VVRCA4RNFAFA89F2D6KGYWW4JCSDAQDZ62PSKJEPQW3HJQ4RGV5SYC6T8DP6XU6TWVUSYXMMWVEJHYETWVDJJQ2Z0WFJX2U3QF9ZR5GZ5F3PNZWFD25UY54Z39YXQZURCQP2RZJQG8ZM9WXGVHZPMUQEWY9J9KDQNRVLZHPCWM6S8CVLC2CKRDNELE42Z9U5VQQY3SQQYQQQQL8QQQQPJQQ9Q6KM84F7KTW6UV574UR2LFNKZLM7VNK8NJRZV20JD8SAW6FZ3TQGSZE6YUT0X2UXGDGYJZGTXEFSQSSEVTKFF97P3TER5K23ZPHDDXHQQ95UT4N
{
  "currency": "bc", 
  "created_at": 1563314978, 
  "expiry": 899, 
  "payee": "024a8228d764091fce2ed67e1a7404f83e38ea3c7cb42030a2789e73cf3b341365", 
  "msatoshi": 1393443000, 
  "amount_msat": "1393443000msat", 
  "description": "Paid to The Lightning Conference (Order ID: TLC19-U8JTQ)", 
  "min_final_cltv_expiry": 10, 
  "routes": [
    [
      {
        "pubkey": "020e2d95c6432e20ef80cb885916cd04c6cf8ae1c3b7a81f0cfe158b0db3cff355", 
        "short_channel_id": "572579x582x1", 
        "fee_base_msat": 999, 
        "fee_proportional_millionths": 200, 
        "cltv_expiry_delta": 40
      }
    ]
  ], 
  "payment_hash": "b793fc2b74c7eeb76d698dc4d9f98c1e3b51cd3d4f4e54a9bab208e75658837a", 
  "signature": "3045022100d5b67aa7d65bb5c653d5e0d5f4cec2fefcc9d8f390c4c53e4d3c3aed245158110220016744e2de6570c86a09212166ca6008432c5d9292f8315e474b2a220ddad35c"
}

In particular we find the entry which reveals the node of the store:

 "payee": "024a8228d764091fce2ed67e1a7404f83e38ea3c7cb42030a2789e73cf3b341365"

We can query the gossip store for more information about the node with the following command:

lightning-cli listnodes | grep 024a8228d764091fce2ed67e1a7404f83e38ea3c7cb42030a2789e73cf3b341365 -B 1 -C 13
    {
      "nodeid": "024a8228d764091fce2ed67e1a7404f83e38ea3c7cb42030a2789e73cf3b341365", 
      "alias": "www.fulmo.org", 
      "color": "f2f3f4", 
      "last_timestamp": 1561973177, 
      "globalfeatures": "", 
      "global_features": "", 
      "addresses": [
        {
          "type": "ipv4", 
          "address": "95.211.207.81", 
          "port": 9735
        }
      ]
    }, 

This gives us all the information we need to peer with the shop and fund a channel. (In case the node was private we could use the routes hints from the decoded invoice to connect to a public exit node.)

lnd users

If you are using lnd you can use the command DecodePayReq and instead of invoking listnodes to get the information from the gossip store you can invoke GetNetworkInfo

2
  • 1
    Also note that the payee field in a BOLT 11 invoice is optional. If omitted, the signing node's public key can be recovered from the signature and the recovery id. I am not sure whether the implementations will automatically fill in the payee field in this case when using decodepay/DecodePayReq.
    – Mark H
    Commented Jul 18, 2019 at 16:46
  • I was not aware that pub keys can be computed from signatures in ecdsa. If others are surprised too look at crypto.stackexchange.com/questions/18105/… to see why / how this is possible. Commented Jul 19, 2019 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.