From 758f935f76f88136ac8db16eb1e2b6cc193ff323 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Thu, 21 Dec 2023 14:49:14 -0800 Subject: [PATCH 1/2] Add the decimals field to payreq paymentinfo for convenience --- .../test/java/me/uma/javatest/UmaTest.java | 2 ++ .../kotlin/me/uma/UmaProtocolHelper.kt | 27 ++++++++++++++----- .../kotlin/me/uma/protocol/PayReqResponse.kt | 6 +++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/javatest/src/test/java/me/uma/javatest/UmaTest.java b/javatest/src/test/java/me/uma/javatest/UmaTest.java index d57c941..f7526e0 100644 --- a/javatest/src/test/java/me/uma/javatest/UmaTest.java +++ b/javatest/src/test/java/me/uma/javatest/UmaTest.java @@ -111,6 +111,7 @@ public void testGetPayReqResponseSync() throws Exception { new TestUmaInvoiceCreator(), "metadata", "USD", + 2, 12345L, 0L, List.of(), @@ -134,6 +135,7 @@ public void testGetPayReqResponseFuture() throws Exception { new TestUmaInvoiceCreator(), "metadata", "USD", + 2, 12345L, 0L, List.of(), diff --git a/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt b/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt index b1521f4..20d02c1 100644 --- a/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt +++ b/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt @@ -2,12 +2,6 @@ package me.uma -import java.security.MessageDigest -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future -import kotlin.math.roundToLong -import kotlin.random.Random -import kotlin.random.nextULong import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -20,6 +14,12 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import me.uma.crypto.Secp256k1 import me.uma.protocol.* +import java.security.MessageDigest +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Future +import kotlin.math.roundToLong +import kotlin.random.Random +import kotlin.random.nextULong /** * A helper class for interacting with the UMA protocol. It provides methods for creating and verifying UMA requests @@ -359,6 +359,9 @@ class UmaProtocolHelper @JvmOverloads constructor( * @param invoiceCreator The [UmaInvoiceCreator] that will be used to create the invoice. * @param metadata The metadata that will be added to the invoice's metadata hash field. * @param currencyCode The code of the currency that the receiver will receive for this payment. + * @param currencyDecimals The number of digits after the decimal point for the receiving currency. For example, + * USD has 2 decimal places. This should align with the `decimals` field returned for the chosen currency in the + * LNURLP response. * @param conversionRate The conversion rate. It is the numer of milli-satoshis per the smallest unit of the * specified currency (for example: cents in USD). This rate is committed to by the receiving VASP until the * invoice expires. @@ -377,6 +380,7 @@ class UmaProtocolHelper @JvmOverloads constructor( invoiceCreator: UmaInvoiceCreator, metadata: String, currencyCode: String, + currencyDecimals: Int, conversionRate: Double, receiverFeesMillisats: Long, receiverChannelUtxos: List, @@ -388,6 +392,7 @@ class UmaProtocolHelper @JvmOverloads constructor( invoiceCreator, metadata, currencyCode, + currencyDecimals, conversionRate, receiverFeesMillisats, receiverChannelUtxos, @@ -406,6 +411,9 @@ class UmaProtocolHelper @JvmOverloads constructor( * @param invoiceCreator The [UmaInvoiceCreator] that will be used to create the invoice. * @param metadata The metadata that will be added to the invoice's metadata hash field. * @param currencyCode The code of the currency that the receiver will receive for this payment. + * @param currencyDecimals The number of digits after the decimal point for the receiving currency. For example, + * USD has 2 decimal places. This should align with the `decimals` field returned for the chosen currency in the + * LNURLP response. * @param conversionRate The conversion rate. It is the number of milli-satoshis per the smallest unit of the * specified currency (for example: cents in USD). This rate is committed to by the receiving VASP until the * invoice expires. @@ -424,6 +432,7 @@ class UmaProtocolHelper @JvmOverloads constructor( invoiceCreator: UmaInvoiceCreator, metadata: String, currencyCode: String, + currencyDecimals: Int, conversionRate: Double, receiverFeesMillisats: Long, receiverChannelUtxos: List, @@ -435,6 +444,7 @@ class UmaProtocolHelper @JvmOverloads constructor( invoiceCreator, metadata, currencyCode, + currencyDecimals, conversionRate, receiverFeesMillisats, receiverChannelUtxos, @@ -450,6 +460,9 @@ class UmaProtocolHelper @JvmOverloads constructor( * @param invoiceCreator The [UmaInvoiceCreator] that will be used to create the invoice. * @param metadata The metadata that will be added to the invoice's metadata hash field. * @param currencyCode The code of the currency that the receiver will receive for this payment. + * @param currencyDecimals The number of digits after the decimal point for the receiving currency. For example, + * USD has 2 decimal places. This should align with the `decimals` field returned for the chosen currency in the + * LNURLP response. * @param conversionRate The conversion rate. It is the numer of milli-satoshis per the smallest unit of the * specified currency (for example: cents in USD). This rate is committed to by the receiving VASP until the * invoice expires. @@ -468,6 +481,7 @@ class UmaProtocolHelper @JvmOverloads constructor( invoiceCreator: UmaInvoiceCreator, metadata: String, currencyCode: String, + currencyDecimals: Int, conversionRate: Double, receiverFeesMillisats: Long, receiverChannelUtxos: List, @@ -489,6 +503,7 @@ class UmaProtocolHelper @JvmOverloads constructor( ), paymentInfo = PayReqResponsePaymentInfo( currencyCode = currencyCode, + decimals = currencyDecimals, multiplier = conversionRate, exchangeFeesMillisatoshi = receiverFeesMillisats, ), diff --git a/uma-sdk/src/commonMain/kotlin/me/uma/protocol/PayReqResponse.kt b/uma-sdk/src/commonMain/kotlin/me/uma/protocol/PayReqResponse.kt index 0fcdd7e..407e684 100644 --- a/uma-sdk/src/commonMain/kotlin/me/uma/protocol/PayReqResponse.kt +++ b/uma-sdk/src/commonMain/kotlin/me/uma/protocol/PayReqResponse.kt @@ -59,6 +59,11 @@ data class PayReqResponseCompliance( * The payment info from the receiver. * * @property currencyCode The currency code that the receiver will receive for this payment. + * @property decimals Number of digits after the decimal point for the receiving currency. For example, in USD, by + * convention, there are 2 digits for cents - $5.95. In this case, `decimals` would be 2. This should align with + * the currency's `decimals` field in the LNURLP response. It is included here for convenience. See + * [UMAD-04](https://github.com/uma-universal-money-address/protocol/blob/main/umad-04-lnurlp-response.md) for + * details, edge cases, and examples. * @property multiplier The conversion rate. It is the number of millisatoshis that the receiver will receive for 1 * unit of the specified currency (eg: cents in USD). In this context, this is just for convenience. The conversion * rate is also baked into the invoice amount itself. Specifically: @@ -69,6 +74,7 @@ data class PayReqResponseCompliance( @Serializable data class PayReqResponsePaymentInfo( val currencyCode: String, + val decimals: Int, val multiplier: Double, val exchangeFeesMillisatoshi: Long, ) From 6a893ab614344e20e967e26816e51cc1abd0a85b Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Thu, 21 Dec 2023 14:51:10 -0800 Subject: [PATCH 2/2] Bump protocol version to 0.3 since this is breaking --- .../commonMain/kotlin/me/uma/UmaProtocolHelper.kt | 12 ++++++------ uma-sdk/src/commonMain/kotlin/me/uma/Version.kt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt b/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt index 20d02c1..f778f7f 100644 --- a/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt +++ b/uma-sdk/src/commonMain/kotlin/me/uma/UmaProtocolHelper.kt @@ -2,6 +2,12 @@ package me.uma +import java.security.MessageDigest +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Future +import kotlin.math.roundToLong +import kotlin.random.Random +import kotlin.random.nextULong import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -14,12 +20,6 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import me.uma.crypto.Secp256k1 import me.uma.protocol.* -import java.security.MessageDigest -import java.util.concurrent.CompletableFuture -import java.util.concurrent.Future -import kotlin.math.roundToLong -import kotlin.random.Random -import kotlin.random.nextULong /** * A helper class for interacting with the UMA protocol. It provides methods for creating and verifying UMA requests diff --git a/uma-sdk/src/commonMain/kotlin/me/uma/Version.kt b/uma-sdk/src/commonMain/kotlin/me/uma/Version.kt index de2048a..1d608af 100644 --- a/uma-sdk/src/commonMain/kotlin/me/uma/Version.kt +++ b/uma-sdk/src/commonMain/kotlin/me/uma/Version.kt @@ -6,7 +6,7 @@ import kotlinx.serialization.json.encodeToJsonElement import kotlinx.serialization.json.put const val MAJOR_VERSION = 0 -const val MINOR_VERSION = 2 +const val MINOR_VERSION = 3 const val UMA_VERSION_STRING = "$MAJOR_VERSION.$MINOR_VERSION" /**