lndk-org / lndk

MIT License
83 stars 21 forks source link

Cli: add pay offer command #91

Closed orbitalturtle closed 5 months ago

orbitalturtle commented 8 months ago

This PR adds CLI command lndk-cli pay-offer, and adds some documentation for doing so. Depends on #90

Probably the main change I need to make is to move the reply path code to #87, it makes more sense there!

carlaKC commented 8 months ago

How did you test this flow end to end? I tried creating an offer with CLN (recent commit 3f4306eea) using the setup described here, but it doesn't include a blinded path (which makes LNDK panic because we expect one).

Offer decode:

lno1qgsqvgnwgcg35z6ee2h3yczraddm72xrfua9uve2rlrm9deu7xyfzrcgqgp7szsyw3jhxaqkyypj0n9ujt8z4409axqxnm6n5f36gh7hr7lyy0ex4emjw7jsdtvc56c
{
   "type": "bolt12 offer",
   "offer_id": "de1c13682f3dc7fef5324f63598fe661f7cb00fe46d615a81f222dd3f0dc58d0",
   "offer_chains": [
      "06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"
   ],
   "offer_amount_msat": 1000,
   "offer_description": "test",
   "offer_node_id": "0327ccbc92ce2ad5e5e98069ef53a263a45fd71fbe423f26ae77277a506ad98a6b",
   "valid": true
}

Fetch and decode invoice:

lni1qqg9xqmwud74wxrsqsy4gz33syy35q3qqc3xu3s3rg94nj40zfsy866mhu5vxne6tcej5878k2mneuvgjy8ssqsraq9qgar9wd6pvggrylxteykw9t27t6vqd8h48gnr530aw8a7ggljdtnhyaa9q6ke3f44qgqxyfhyvyg6pdvu4tcjvpp7kkal9rp57wj7xv4pl3ajku70rzy3pavzzqhv2pm896u8m6mtrsg2zqjlthpqwzmqewrnnff0uyn692sfnayq5wswgqnj408dg9k2ja6r3q6qtlxhh9w6zspkkaa77g602w3h37m3kandnqpy509xyqcfg78va352ud0y629k2janqvw2jwdrkpymthsywr68q8szqvy2fnc25rvnspmd9uejy66hl2sdh0jk36hnm5x6plr0ef395hs0zqpfaj3qdzgns6kz958kjpwhju9qzmu86ugnfhdk2pjhdsv30q7dqm986uwqae66dw5w9qp845xhhe2rnrfksczvn0ra2am4g79kw2u7csllqsxkhf5eupcyuyqqxtnwh67wjmkdq7vg8gjhh4qjpvae08g6t7sdmd6fntfkg8y0rr6s6sddd2a2l74ynz8mklju8pdf623qsj3pcqqqqqqsqqqqpgqqvqqqqqqqqqqqqqqqqqqq8tyqqqqqqzjqgew983n2sgpyhh5msnj0edmzklvh48ell96rddnezwc7aw0aut2ma74x86nuwk4qyqlgkqssxf7vhjfvu2k4uh5cq6002w3x8fzl6u0mus3ly6h8wfm62p4dnznt7pqvl8vhjy5cc5t0sn5rvegylphvy0pm6ewr4ru3msk7xurh5prrvu49vdh7wdqtyxj8dq2n0m2982d7zyhr6kwvp85kw5qq2wl5jq6afy
{
   "type": "bolt12 invoice",
   "offer_id": "de1c13682f3dc7fef5324f63598fe661f7cb00fe46d615a81f222dd3f0dc58d0",
   "offer_chains": [
      "06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f"
   ],
   "offer_amount_msat": 1000,
   "offer_description": "test",
   "offer_node_id": "0327ccbc92ce2ad5e5e98069ef53a263a45fd71fbe423f26ae77277a506ad98a6b",
   "invreq_metadata": "53036ee37d5718700409540a3181091a",
   "invreq_payer_id": "02ec507672eb87deb6b1c10a1025f5dc2070b60cb8739a52fe127a2aa099f480a3",
   "invreq_chain": "06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f",
   "invoice_paths": [
      {
         "first_node_id": "0272abced416ca97743883405fcd7b95da14036b77bef234f53a378fb71b766d98",
         "blinding": "024a3ca620309478ecec68ae35e4d28b654bb3031ca939a3b049b5de0470f4701e",
         "payinfo": {
            "fee_base_msat": 1,
            "fee_proportional_millionths": 10,
            "cltv_expiry_delta": 6,
            "features": ""
         },
         "path": [
            {
               "blinded_node_id": "0308a4cf0aa0d938076d2f33226b57faa0dbbe568eaf3dd0da0fc6fca625a5e0f1",
               "encrypted_recipient_data": "eca206891386ac22d0f6905d7970a016f87d71134ddb6506576c191783cd06ca7d71c0ee75a6ba8e28"
            },
            {
               "blinded_node_id": "027ad0d7be54398d368604c9bc7d57775478b672b9ec43ff040d6ba699e0704e10",
               "encrypted_recipient_data": "e6ebebce96ecd079883a257bd4120b3b979d1a5fa0ddb7499ad3641c8f18f50d41ad6abaaffaa4988fbb7e5c385a9d2a2084"
            }
         ]
      }
   ],
   "invoice_created_at": 1707424870,
   "invoice_relative_expiry": 7200,
   "invoice_payment_hash": "24bde9b84e4fcb762b7d97a9f3ff97436b67913b1eeb9fde2d5befaa63ea7c75",
   "invoice_amount_msat": 1000,
   "invoice_node_id": "0327ccbc92ce2ad5e5e98069ef53a263a45fd71fbe423f26ae77277a506ad98a6b",
   "signature": "cf9d9791298c516f84e8366504f86ec23c3bd65c3a8f91dc2de37077a0463672a5636fe7340b21a47681537ed453a9be112e3d59cc09e967500053bf49035d49",
   "valid": true
}
orbitalturtle commented 8 months ago

@carlaKC Ah to be honest, so far I've only tested against ldk-sample. I'll give CLN a try and see what I can come up with. We might also encounter this problem, though, when trying to send a payment: https://github.com/ElementsProject/lightning/issues/6588

If that is still an issue, what do you think of testing it against a live LDK-based node that distributes offers (I just mean, something a little more realistic than our ldk-sample branch. I'd have to check with the LDK team if there are any such nodes yet) or against Eclair as an alternative?

carlaKC commented 7 months ago

Tested this against LDK sample with direct connection and ran into:

2024-03-08 22:33:15.288 TRACE [lightning::onion_message::messenger:906] Received an onion message with path_id None and a reply_path: Offers((PayerTlvStreamRef { metadata: Some([18, 182, 212, 92, 152, 22, 243, 72, 33, 234, 188, 189, 104, 218, 159, 211, 170, 221, 233, 244, 219, 188, 65, 65, 199, 50, 205, 0, 208, 89, 135, 68, 182, 55, 194, 48, 213, 158, 20, 121, 94, 50, 197, 229, 45, 26, 23, 7, 71, 100, 9, 192, 92, 89, 189, 11, 145, 106, 87, 66, 54, 189, 87, 25, 8, 171, 224, 193, 47, 208, 63, 13, 239, 148, 112, 60, 93, 90, 153, 228]) }, OfferTlvStreamRef { chains: Some([06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f]), metadata: Some([1, 145, 223, 201, 38, 58, 18, 176, 189, 171, 103, 22, 111, 75, 218, 160]), currency: None, amount: Some(1000), description: Some(""), features: None, absolute_expiry: None, paths: Some([BlindedPath { introduction_node_id: PublicKey(cba71001ad2f52fa04a821d7103ecb696ef3a0bd68579e1b8eb105f003828aab97f472a1103b17002eecf599dfe88f2677d1dd7b482bc14a7434a17d9173cb00), blinding_point: PublicKey(6229aa020820ad5661457ec5aac0d12f3e1d51de1bd31fff47675f257ab93cde53aab93778aa2ad1dde98f86b048227ec20dcd291ad1f58e84675ba611a65a20), blinded_hops: [BlindedHop { blinded_node_id: PublicKey(0743f24b571b9a2e298d3f7223f9399bffb69e85c7163e291ea916b5ce1821cfa5b5415dfc04ae50819748376d9a6f1d12c2a16a2ce9a6afff9be75c24ff79a6), encrypted_payload: [49, 10, 72, 201, 27, 115, 168, 144, 88, 113, 240, 108, 164, 73, 51, 187] }] }]), issuer: None, quantity_max: None, node_id: Some(PublicKey(c5ff4ab127e7af9e34727770113fe7a66498fd0173ebde43b3c5f5d970422d7028923d494704f9a82605a771b6b16dd2b676861d6054f3b657d6a3186b54d9ae)) }, InvoiceRequestTlvStreamRef { chain: Some(06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f), amount: Some(1000), features: None, quantity: None, payer_id: Some(PublicKey(1c6c8d2a0cc71ab5b52aec2b54f9cc46a2e989b33b095e5bfac047969936d43a2969346f2eab15d559bee79feefdad060c2374e1c120949d2f884607594afa5d)), payer_note: None }, SignatureTlvStreamRef { signature: Some(Signature(246fc2b0fea2d93c918aaad5cdd7b826af8101bde6442b11a2e6c5e4b5173788b8a78a841e6ab2f6660d679072eae1a9d76b55f702ab98d2a7e31440d8e37836)) }))
2024-03-08 22:33:15.297 TRACE [lightning::onion_message::messenger:740] Failed to find path when responding to Offers onion message with path_id None

I think that this may be an issue with the LDK node's networking, but we should probably be setting PathID in the meantime? I also think that we should add a really basic timeout, because right now we just hang waiting to hear back:

2024-03-08T17:33:15.171145-05:00 INFO lndk - Starting lndk for node: 03416c56f2d0733aefa530d9e49857484eaec628b4bc769a6c5b7d3a406769d952.
2024-03-08T17:33:15.174018-05:00 INFO lndk::onion_messenger - Consume messenger events received: messenger event: 035c0b392725bb7298d56bf1bcb23634fc509d86a39a8141d435f9d4d6cd4b12eb connected, onion message support: true.
2024-03-08T17:33:15.174270-05:00 INFO lndk::onion_messenger - Consume messenger events received: messenger event: 03ab8a8203f005b18e1b9e5768bda0f36e69cb3e10d721a804fa522fad0110a7cb connected, onion message support: true.
2024-03-08T17:33:15.276883-05:00 INFO lndk::onion_messenger - Sending outgoing onion message to 03ab8a8203f005b18e1b9e5768bda0f36e69cb3e10d721a804fa522fad0110a7cb.
carlaKC commented 7 months ago

Just posting things as I go on this PR, even if they're something that we should have in followups. Don't want to merge the command itself until we've tested it with various impls.

orbitalturtle commented 6 months ago

I also think that we should add a really basic timeout, because right now we just hang waiting to hear back:

Good idea, I'll add something along those lines.

Re: the "failed to find path" error. Is this the upstream ldk-sample or our fork of it? Are ldk and lnd connected directly in your setup?

I'll take a look, though even if that's fixed, the upstream ldk-sample won't work right now because of another bug I just reported to the LDK team. So in short we can't pay offers created by ldk-sample or CLN due to bugs on their end. Eclair is the only one that works right now. But hopefully some fixes go in pretty soon - I'll try to keep this up to date https://github.com/lndk-org/lndk/issues/93

orbitalturtle commented 6 months ago

Added that timeout :)