Fixed destination amount push payments

Is it possible for a person A to send money to a person B with a fixed destination amount in B’s currency with Interledger? I mean B does not want even a tiny bit more or a tiny bit less. However, the sender A is ready to pay any fees necessary. (This is probably the case for most payments.)

I found this in ILPv4’s RFC:

Now, instead of fixed destination amount delivery being built into the core protocol, senders may use higher-level protocols to indicate the minimum amount the receiver should accept for a given packet and receivers can reject packets with less than that.

I understand that ILPv4 does not work with fixed destination amounts but do higher-level layers (SPSP) enable this?

I don’t quite understand why there should be both a sendMax and receiveMin in a high-level layer. Shouldn’t the end receiver just always stop the connection at the fixed destination amount (receiveMin) by default? The receiver is not concerned with the fee slippage. It’s the sender who pays whatever fee is needed.

I consider the fee to be the difference between the exchange rate of all the connectors on the path to the receiver and the one the client can get from somewhere like CoinMarketCap’s API.

Shouldn’t the higher-level layer just tell the sender: “this the total amount (amount + fee) you should pay in your currency for you to send X amount of currency Y to person B”. It’s actually “amount + feeMax”. In my opinion, feeMax that defaults to a certain value is a concept that’s much easier to understand for a developer trying to build on top of Interledger, especially if he/she is familiar with cryptocurrencies like Ethereum for example.

eth_sendTransaction:
{
“from”: “0xb60e8dd61c5d32be8058bb8eb970870f07233155”,
“to”: “0xd46e8dd67c5d32be8058bb8eb970870f07244567”,
“gas”: 30400,
“gasPrice”: 10000000000000,
“value”: 2441406250,
“data”: “0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675”
}

Telling someone: “how much are you willing to pay?”, is not as straight forward as telling him “oh btw, the fee will be less than a penny”.

I’m new to Interledger. I would love it if someone can help me out with these questions.

Found that this has been discussed before for the rust implementation #256.

In these ramblings, I assume that the sender knows what currencies the receiver accepts somehow and the client knows how to get an exchange rate from somewhere. I will maybe post a similar post about exchange logic.

1 Like

Hey @bariabbassi!

Fixed destination amount payments are handled at the transport layer, using STREAM, and currently setup using SPSP (but @adrianhopebailie and others are working on improving this with Open Payments).

How this could work (AFAIK, only the Java implementation and the Open Payments demos support this, but hopefully it’ll be expanded upon soon):

  1. Recipient/merchant provides the user with an invoice for the destination amount and asset they want to receive (ideally, this would be automatically populated into the user’s wallet).
  2. The sender’s wallet pulls from an exchange rate API (like CoinMarketCap) to determine the rate between their source asset and the destination asset. It subtracts some slippage/fees from this to determine the maximum amount it’s willing to send in its source asset. It may also send probing packets to the recipient to get a better idea of what the actual exchange rate is before presenting it to the user.
  3. Wallet prompts the user to authorize the payment, likely displaying the maximum source amount, invoice amount in the destination asset, and expected fees. User approves or denies.
  4. The wallet begins sending the payment with STREAM. Using the exchange rate calculated previously, in every STREAM packet the sender effectively says “only fulfill this if you receive more than x amount” (in the destination asset). That way, the sender can enforce that money only gets their if it meets a particular minimum exchange rate, and it knows if the recipient fulfills the packet, they got at least that much money. When they fulfill the packet, the recipient also tells the sender how much they got (*although they could lie about this). The sender uses this to determine how much more money it needs to send. Note that if all the packets received by the recipient don’t meet the minimum exchange rate, they’ll reject them, and the payment will eventually fail. Partial completion is a possibility if the exchange rate fluctuated a lot in the meantime, but this is unlikely.
  5. It’s possible the sender might overpay the recipient slightly, since you can’t precisely account for the exchange rate/fees between source and destination, so if the recipient only wants to receive the exact amount in the invoice, it’s their job to enforce this. Their STREAM receiver should reject packets that would result in the sender overpaying the invoice. The sender would reduce their packet amount, and slowly get closer and closer to completing the payment, kinda like a binary search.

The interesting thing about a lot of this (by contrast to e.g. a blockchain like Ethereum) is it’s mostly implementation-related concerns, rather than protocol concerns. That’s really powerful, since it’s much easier to just update/improve one participant’s software rather than requiring every participant to agree to a new protocol!

1 Like

Thanks for the quick reply @kincaid !! I couldn’t have asked for a clearer explanation. This was exactly what I was looking for.

The only remark I have is that I think that a fixed destination amount payment is not necessarily a pull payment (a receiver/merchant sends an invoice). It could be a sender who just wants to send a fixed amount tip, donation … in a foreign currency. What I mean by push is basically the international transfer that you have on a banking app.

The 2 are basically the same thing it’s just that for a push the flow of the logic doesn’t start with the recipient sending an invoice. It starts with the sender asking for an invoice. “Invoice” is not the right word but you get the point. So, basically 1 step extra before starting the 5 steps you wrote. I’m probably nitpicking here but I just wanted to give some feedback.

And yes you’re right. An interoperability layer is nothing like a blockchain. The protocol should be loose and flexible enough to make interoperability between all ledgers possible. I think that ILPv4 and STREAM do a perfect job at that but I think that the documentation for SPSP could be better. It should explain to the reader all the different types of payments possible with the right naming standards ISO20022. To avoid confusion about exchange rates, send money, send money in a different currency, request money, give permission to a subscription service … I’m interested in working on this for Open Payments that’s the reason why I accually asked the questions.

1 Like