Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature]: Discover information about Quote / Taproot Asset Denominated Value as Payer of Invoice ASAP #1166

Closed
Nsandomeno opened this issue Oct 31, 2024 · 7 comments · Fixed by #1253
Labels
enhancement New feature or request
Milestone

Comments

@Nsandomeno
Copy link

Is your feature request related to a problem? Please describe.

General User Story
As a payer of a taproot asset invoice, I can glean the satoshi-denominated value by decoding the invoice however I'm not sure what the taproot asset-denominated value that I'm paying is.

Description
Neither node is using the taproot-assets.experimental.rfq.skipacceptquotepricecheck=true config line (although have tried with as well), but is still using the mock price oracle in the example outlined below:

An initial quote is returned by the payee at the time of creating the invoice, and returned with the cli output like this:

litd@dave:/$ litcliln addinvoice --asset_id=701ebb3d6859e34f7538ca43299f4080a87409db9a2584b7239bb25793cb494d --asset_amount=10 --rfq_peer_pubkey=03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798
{
    "accepted_buy_quote": {
        "peer": "03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798",
        "id": "8a2ac1df6181bb666f72ea14aed65058ef7437ba7bfb3395a5fba183f3d964c5",
        "scid": "11960330823516382405",
        "asset_amount": "10",
        "ask_price": "10000",
        "expiry": "1730409077"
    },
    "invoice_result": {
        "r_hash": "91c8a9b63ada4c87e11cb9378931385b8b8084886f137520592c451179fbb6b0",
        "payment_request": "lnbcrt1u1pnj8er9pp5j8y2nd36mfxg0cguhymcjvfctw9cppygdufh2gze93z3z70mk6cqdqqcqzzsxqzfvrzjqde8cgkpxl40lrcna7e6nvld2vnuzzzad6e9g4flm6mnjf4t50re3f0m5xpl8ktyc5qqqqlgqqqqqqgq2qsp53u95m4ssmcnyjfezzzenkl6vacd86u6rmr73vknza7mved4jlxgs9qxpqysgqd2453l9pqqdtqm0rkdyjapj5jqpkkra6zmr5c0espswd6769xfc3d2deczykfezl0xdwp53a33ky9j97k2f3ps2997st5qkpjwf3hyqq8z29ac",
        "add_index": "22",
        "payment_addr": "8f0b4dd610de2649272210b33b7f4cee1a7d7343d8fd165a62efb6ccb6b2f991"
    }
}

After the invoice is created (and prior to it being paid), despite referring properly to the peer ID, the quote is only findable from the RFQ service of the payee node:

Payee Node

litd@dave:/$ tapcli rfq acceptedquotes
{
    "buy_quotes":  [
        {
            "peer":  "03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798",
            "id":  "5b6402c9561e017c65debabb4081d21bf6a1f44e9c376414058a334d65f8453e",
            "scid":  "399187924491978046",
            "asset_amount":  "10",
            "ask_price":  "10000",
            "expiry":  "1730406898"
        },
        {
            "peer":  "03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798",
            "id":  "8a2ac1df6181bb666f72ea14aed65058ef7437ba7bfb3395a5fba183f3d964c5",
            "scid":  "11960330823516382405",
            "asset_amount":  "10",
            "ask_price":  "10000",
            "expiry":  "1730409077"
        }
    ],
    "sell_quotes":  []
}

We see that the payee retains quote info...

Payer Node
... However, the payer isn't able to learn anything about it yet.

Proof that identity pubkey is 03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798:

nicholassandomeno@Nicholass-MacBook-Pro lightning-terminal % lncli -n regtest --tlscertpath=~/.lnd/tls.cert --macaroonpath=~/
.lnd/data/chain/bitcoin/regtest/admin.macaroon getinfo
{
    "version": "0.18.0-beta commit=lightning-terminal-v0.13.993-experimental-15-g7fad4c603c49c56c12b2542bd2b3b4f583077f02-dirty",
    "commit_hash": "7fad4c603c49c56c12b2542bd2b3b4f583077f02",
    "identity_pubkey": "03727c22c137eaff8f13efb3a9b3ed5327c1085d6eb254553fdeb73926aba3c798",
    "alias": "03727c22c137eaff8f13",
    "color": "#3399ff",
    "num_pending_channels": 0,
    "num_active_channels": 1,
    
    ...

RFQ lookup:

nicholassandomeno@Nicholass-MacBook-Pro lightning-terminal % tapcli -n regtest --rpcserver=localhost:8443 --tlscertpath=~/.lit/tls.cert --macaroonpath=~/.tapd/admin.macaroon rfq acceptedquotes
{
    "buy_quotes": [],
    "sell_quotes": []
}

Assuming that only some form-factor of the payment_request is communicated between the payee and payer, I'm looking to learn more about the quote earlier on in the workflow with the ultimate goal of going from invoice to taproot asset denomination as the payer (taproot asset invoice --> decoded taproot asset invoice --> taproot-asset denominated value of invoice).

Describe the solution you'd like

  • Confirmation that the real workflow (using a real price oracle) is testable through a configured mock oracle

  • Information about the ideal way a payer learns of the final amount charged, denominated in the taproot asset

  • Information about the earliest time an accepted taproot asset-denominated quote for an invoice can be known be the payer of that invoice

  • Potentially (based on responses to questions above) encoding quote information in taproot asset invoices as a custom record

  • Potential RFQ service addition for retaining quotes (based on responses to questions above)

  • Potentially (based on responses to questions above) updates to tapchannelrpc.SendPayment to reject payment based on the final quote/value denominated in the taproot asset

Describe alternatives you've considered

  • Encoding quote information in taproot asset invoices

  • Additional updates in tapchannelrpc.SendPayment to be able to confirm acceptance of the taproot asset-denominated amount

Additional context

  • Using 2 LITD's of v0.13.993-experimental - one from source and one running out Docker via Polar.

  • The configurations of both node's specify the same fixed rate to use for the mock oracle:
    taproot-assets.experimental.rfq.mockoraclesatsperasset=10

  • When the payee generates the invoice, the payer node (whom the channel is open with), receives a warning log:

2024-10-31 16:36:35.954 [INF] RFQS: Would reject buy request: no suitable buy offer, but ignoring for now
@guggero
Copy link
Member

guggero commented Nov 1, 2024

Thanks for the report and the questions.
What you see in terms of invoices and visible quotes on the payee is correct. The amount of assets the payee wants to receive is converted into satoshi using the oracle and a quote.

But the invoice will only ever show the satoshi amount. The main reasons for that are:

  • It's an invoice that's 100% BOLTS standard compliant, so it can be paid by anyone on the Lightning Network
  • Because it is denominated in satoshi, it can also be paid with satoshis directly
  • Because it is denominated in satoshi, the payment can flow through the wider Lightning Network, which only knows satoshi
  • A payer could use a completely different asset (e.g. EUR stablecoin instead of an USD stablecoin), but both would convert to satoshi in the middle

With the above said, what you want to do on the payer side, is to ask the payer's edge node (which might be a completely different edge node than the payee's) for a quote in the payment asset over the given satoshi amount in the invoice.
You would do that programmatically using the rfqrpc.AddAssetSellOrder RPC, which would give you the number of assets.

And you are correct that tapchannelrpc.SendPayment does that under the hood automatically and you don't have a way to confirm that currently. So we definitely need a fix for that.
Because if you run rfqrpc.AddAssetSellOrder and then tapchannelrpc.SendPayment you would end up with two quotes, which is not ideal.

So perhaps what we want to add to tapchannelrpc.SendPayment is a parameter that allows you to specify using a quote that was already negotiated using the rfqrpc.AddAssetSellOrder.
I believe that would solve your request?

2024-10-31 16:36:35.954 [INF] RFQS: Would reject buy request: no suitable buy offer, but ignoring for now

You can ignore that warning, we should actually remove that.

@guggero guggero added this to the v0.5 milestone Nov 1, 2024
@Nsandomeno
Copy link
Author

@guggero Thanks very much for your response and yes, a quote parameter to tapchannelrpc.SendPayment would be ideal to solve for this.

I am also curious about your thought on using the invoice itself to pass data through custom records, perhaps something for quote_id and rfqrpc_uri. Do you have any quick thoughts on that?

@guggero
Copy link
Member

guggero commented Nov 1, 2024

I am also curious about your thought on using the invoice itself to pass data through custom records, perhaps something for quote_id and rfqrpc_uri. Do you have any quick thoughts on that?

The quote is something that's local to the two participants (the wallet end user and the edge node). It's basically a secret agreement on an exchange rate.
I don't see what benefit exposing that quote in the invoice would give other participants in the payment.
Or do you simply mean the information like "this invoice was created for X units of the asset ABC"?
If that is useful, then it could be encoded in the normal metadata fields of the invoice, on a voluntary basis.

But I don't think it should be a standard. Because perhaps the recipient doesn't want anyone to know, they're receiving an asset instead of satoshis? Or perhaps it's an asset that only the wallet end user and edge node even know, so the information would be useless for any outside participant.
But perhaps you can expand on the use case a bit more?

@Nsandomeno
Copy link
Author

@guggero At the highest level, the goal is to provide the payer with the best information possible about the quote associated with an invoice they are about to pay.

This applies to any case where the accounting is done in the taproot asset first, lending to user's familiarity with dealing in a stablecoin's currency units or validation on the quoted rate (or best estimate from the source) prior to paying the invoice.

@guggero
Copy link
Member

guggero commented Nov 1, 2024

about the quote associated with an invoice they are about to pay

But that's the thing: The quote associated with the invoice is only relevant to the recipient and its counter party (the edge node).
If the sender wants to also use a stable coin to pay for the invoice, they themselves need to ask for a quote from their counter party (the sender's edge node), using the rfqrpc.AddAssetSellOrder. And since you get a quote and exchange rate from that RPC, all that information can be shown to the sender user in the UI. But it's completely independent from the quote the recipient got.

@Nsandomeno
Copy link
Author

Understood, thank you very much!

@Roasbeef
Copy link
Member

This will be fixed by #1253.

@github-project-automation github-project-automation bot moved this from 🆕 New to ✅ Done in Taproot-Assets Project Board Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: ✅ Done
Development

Successfully merging a pull request may close this issue.

3 participants