From 523bc9a8f50899e00b3ad9cbb32c59ae382f81fb Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Tue, 6 Aug 2024 10:39:58 -0700 Subject: [PATCH 01/11] Fix copy-pasta in an operation name. --- .../lightspark/sdk/graphql/IncomingPaymentsForPaymentHash.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForPaymentHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForPaymentHash.kt index 94863d84..ee8c0f21 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForPaymentHash.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForPaymentHash.kt @@ -3,7 +3,7 @@ package com.lightspark.sdk.graphql import com.lightspark.sdk.model.IncomingPayment const val IncomingPaymentsForPaymentHashQuery = """ -query OutgoingPaymentsForInvoice( +query IncomingPaymentsForPaymentHash( ${'$'}paymentHash: Hash32!, ${'$'}transactionStatuses: [TransactionStatus!] = null ) { From 63cdb5b9d9f3bd34a9ba55206470c096393cb3f9 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 8 Aug 2024 10:53:28 -0700 Subject: [PATCH 02/11] add incoming / outgoing payment hash commands --- .../kotlin/com/lightspark/sdk/ClientIntegrationTests.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt index 4e7fe551..96e6d8f5 100644 --- a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt +++ b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt @@ -309,6 +309,8 @@ class ClientIntegrationTests { payments[0].id.shouldBe(payment?.id) } + // todo add payment has tests + @Test fun `test uma identifier hashing`() = runTest { val privKeyBytes = "xyz".toByteArray() From b7a42f0ab19158a142bd90464e61ed0447edd7ba Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 6 Aug 2024 11:22:27 -0700 Subject: [PATCH 03/11] first attempt at adding graphql queries --- .../sdk/graphql/InvoiceForPaymentsHash.kt | 19 +++++++++++++++++++ .../graphql/OutgoingPaymentsForPaymentHash.kt | 0 2 files changed, 19 insertions(+) create mode 100644 lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt create mode 100644 lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt new file mode 100644 index 00000000..0512e160 --- /dev/null +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt @@ -0,0 +1,19 @@ +package com.lightspark.sdk.graphql + +import com.lightspark.sdk.model.IncomingPayment + +const val InvoiceForPaymentsHashQuery = """ +query InvoiceForPaymentHash( + ${'$'}paymentHash: Hash32!, +) { + invoice_for_payment_hash(input: { + payment_hash: ${'$'}paymentHash, + }) { + invoice { + ...InvoiceFragment + } + } +} + + ${IncomingPayment.FRAGMENT} +""" \ No newline at end of file diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt new file mode 100644 index 00000000..e69de29b From 3a258d79fe02af7a27128412f6a104fa90bb57eb Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 6 Aug 2024 12:15:52 -0700 Subject: [PATCH 04/11] saved this time --- .../graphql/OutgoingPaymentsForPaymentHash.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt index e69de29b..37beead1 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/OutgoingPaymentsForPaymentHash.kt @@ -0,0 +1,21 @@ +package com.lightspark.sdk.graphql + +import com.lightspark.sdk.model.OutgoingPayment + +const val OutgoingPaymentsForPaymentHashQuery = """ +query OutgoingPaymentsForPaymentHash( + ${'$'}paymentHash: Hash32!, + ${'$'}transactionStatuses: [TransactionStatus!] = null +) { + outgoing_payments_for_payment_hash(input: { + payment_hash: ${'$'}paymentHash, + statuses: ${'$'}transactionStatuses + }) { + payments { + ...OutgoingPaymentFragment + } + } +} + + ${OutgoingPayment.FRAGMENT} +""" \ No newline at end of file From 97520640fe8d168665a98a27033049c1c49b37a4 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Tue, 6 Aug 2024 16:02:53 -0700 Subject: [PATCH 05/11] empty file --- .../com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt new file mode 100644 index 00000000..542084f3 --- /dev/null +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt @@ -0,0 +1,4 @@ +package com.lightspark.sdk.graphql + +const val IncomingPaymentsForInvoiceQuery = """ +""" \ No newline at end of file From 114cfb7c1adbef2129caa2b7f6d2bf69d20a33ab Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 8 Aug 2024 10:15:42 -0700 Subject: [PATCH 06/11] adding unit tests and invoice for payments hash --- .../lightspark/sdk/LightsparkFuturesClient.kt | 35 ++++++++ .../sdk/LightsparkCoroutinesClient.kt | 84 +++++++++++++++++++ .../lightspark/sdk/LightsparkSyncClient.kt | 24 +++++- .../sdk/graphql/IncomingPaymentsForInvoice.kt | 19 ++++- .../sdk/graphql/InvoiceForPaymentsHash.kt | 6 +- .../lightspark/sdk/ClientIntegrationTests.kt | 38 +++++++++ 6 files changed, 201 insertions(+), 5 deletions(-) diff --git a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt index 944a9c8e..0dacb9c7 100644 --- a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt +++ b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt @@ -576,6 +576,33 @@ class LightsparkFuturesClient(config: ClientConfig) { coroutinesClient.getOutgoingPaymentsForInvoice(encodedInvoice, transactionStatuses) } + /** + * fetch outgoing payments for a given payment hash + * + * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments + * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. + */ + @Throws(LightsparkException::class, LightsparkAuthenticationException::class) + fun getOutgoingPaymentsForPaymentsHash( + paymentHash: String, + transactionStatuses: List? = null + ): CompletableFuture> = coroutineScope.future { + coroutinesClient.getOutgoingPaymentsForPaymentsHash(paymentHash, transactionStatuses) + } + + /** + * fetch invoice for a given payments hash + * + * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments + * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. + */ + @Throws(LightsparkException::class, LightsparkAuthenticationException::class) + fun getInvoiceForPaymentHash( + paymentHash: String + ): CompletableFuture = coroutineScope.future { + coroutinesClient.getInvoiceForPaymentHash(paymentHash) + } + /** * Fetch incoming payments for a given payment hash. * @@ -592,6 +619,14 @@ class LightsparkFuturesClient(config: ClientConfig) { coroutinesClient.getIncomingPaymentsForPaymentHash(paymentHash, transactionStatuses) } + @Throws(LightsparkException::class, LightsparkAuthenticationException::class) + fun getIncomingPaymentsForInvoice( + invoiceId: String, + transactionStatuses: List? = null + ): CompletableFuture> = coroutineScope.future { + coroutinesClient.getIncomingPaymentsForInvoice(invoiceId, transactionStatuses) + } + /** * Creates an UMA invitation. If you are part of the incentive program you should use * [createUmaInvitationWithIncentives]. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt index 0d6fb427..e9f6a0fc 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt @@ -1036,6 +1036,90 @@ class LightsparkCoroutinesClient private constructor( ) } + /** + * fetch outgoing payments for a given payment hash + * + * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments + * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. + */ + suspend fun getOutgoingPaymentsForPaymentsHash( + paymentHash: String, + transactionStatuses: List? = null, + ): List { + requireValidAuth() + return executeQuery( + Query( + OutgoingPaymentsForPaymentHashQuery, + { + add("paymentHash", paymentHash) + transactionStatuses?.let { + add("transactionStatuses", serializerFormat.encodeToJsonElement(it)) + } + }, + ) { + val outputJson = + requireNotNull(it["outgoing_payments_for_payment_hash"]) { "No payment output found in response" } + val paymentsJson = + requireNotNull(outputJson.jsonObject["payments"]) { "No payments found in response" } + serializerFormat.decodeFromJsonElement(paymentsJson) + }, + ) + } + + /** + * fetch invoice for a given payments hash + * + * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments + */ + suspend fun getInvoiceForPaymentHash( + paymentHash: String + ): Invoice { + requireValidAuth() + return executeQuery( + Query( + InvoiceForPaymentsHashQuery, + { + add("paymentHash", paymentHash) + }, + ) { + val outputJson = + requireNotNull(it["invoice_for_payment_hash"]) { "No invoice found in response" } + val invoiceJson = + requireNotNull(outputJson.jsonObject["invoice"]) { "No invoice found in response" } + serializerFormat.decodeFromJsonElement(invoiceJson) + }, + ) + } + + /** + * fetch invoice for a given invoice id + * + * @param invoiceId the id of the invoice for which to fetch the outgoing payments + * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. + */ + suspend fun getIncomingPaymentsForInvoice( + invoiceId: String, + transactionStatuses: List? = null, + ): List { + return executeQuery( + Query( + IncomingPaymentsForInvoiceQuery, + { + add("invoiceId", invoiceId) + transactionStatuses?.let { + add("transactionStatuses", serializerFormat.encodeToJsonElement(it)) + } + }, + ) { + val outputJson = + requireNotNull(it["incoming_payments_for_invoice"]) { "No payment output found in response" } + val paymentsJson = + requireNotNull(outputJson.jsonObject["payments"]) { "No payments found in response" } + serializerFormat.decodeFromJsonElement(paymentsJson) + } + ) + } + /** * Creates an UMA invitation. If you are part of the incentive program you should use * [createUmaInvitationWithIncentives]. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt index 2303447a..7fd95f4d 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt @@ -563,7 +563,7 @@ class LightsparkSyncClient constructor(config: ClientConfig) { /** * Fetch incoming payments for a given payment hash. * - * @param paymentHash The payment hash of the invoice for which to fetch the incoming payments. + * @param paymentHash The payment hash of the invoice for which to fetch the incoming payments. * @param transactionStatuses The transaction statuses to filter the payments by. If null, all payments will be * returned. * @return The list of incoming payments for the payment hash. @@ -576,6 +576,28 @@ class LightsparkSyncClient constructor(config: ClientConfig) { asyncClient.getIncomingPaymentsForPaymentHash(paymentHash, transactionStatuses) } + /** + * fetch outgoing payments for a given payment hash + * + * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments + * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. + */ + @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) + fun getOutgoingPaymentsForPaymentsHash( + paymentHash: String, + transactionStatuses: List? = null + ): List = runBlocking { + asyncClient.getOutgoingPaymentsForPaymentsHash(paymentHash, transactionStatuses) + } + + @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) + fun getIncomingPaymentsForInvoice( + invoiceId: String, + transactionStatuses: List? = null + ): List = runBlocking { + asyncClient.getIncomingPaymentsForInvoice(invoiceId, transactionStatuses) + } + /** * Creates an UMA invitation. If you are part of the incentive program you should use * [createUmaInvitationWithIncentives]. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt index 542084f3..e9596df0 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt @@ -1,4 +1,21 @@ package com.lightspark.sdk.graphql +import com.lightspark.sdk.model.IncomingPayment + const val IncomingPaymentsForInvoiceQuery = """ -""" \ No newline at end of file +query IncomingPaymentsForInvoice( + ${'$'}invoiceId: Hash32!, + ${'$'}transactionStatuses: [TransactionStatus!] = null +) { + incoming_payments_for_invoice_query(input: { + invoice_id: ${'$'}invoiceId, + statuses: ${'$'}transactionStatuses + }) { + payments { + ...IncomingPaymentFragment + } + } +} + +${IncomingPayment.FRAGMENT} +""" diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt index 0512e160..2cb1b052 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt @@ -1,6 +1,6 @@ package com.lightspark.sdk.graphql -import com.lightspark.sdk.model.IncomingPayment +import com.lightspark.sdk.model.Invoice const val InvoiceForPaymentsHashQuery = """ query InvoiceForPaymentHash( @@ -15,5 +15,5 @@ query InvoiceForPaymentHash( } } - ${IncomingPayment.FRAGMENT} -""" \ No newline at end of file + ${Invoice.FRAGMENT} +""" diff --git a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt index 96e6d8f5..be0dee6c 100644 --- a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt +++ b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt @@ -311,6 +311,44 @@ class ClientIntegrationTests { // todo add payment has tests + @Test + fun `test getOutgoingPaymentsForPaymentsHash`() = runTest { + val node = getFirstOskNode() + client.loadNodeSigningKey(node.id, PasswordRecoverySigningKeyLoader(node.id, NODE_PASSWORD)) + val invoice = client.createTestModeInvoice(node.id, 100_000, "test invoice") + var outgoingPayment: OutgoingPayment? = client.payInvoice(node.id, invoice, maxFeesMsats = 100_000) + outgoingPayment.shouldNotBeNull() + while (outgoingPayment?.status == TransactionStatus.PENDING) { + delay(500) + outgoingPayment = OutgoingPayment.getOutgoingPaymentQuery(outgoingPayment.id).execute(client) + println("Payment status: ${outgoingPayment?.status}") + } + outgoingPayment?.status.shouldBe(TransactionStatus.SUCCESS) + + val payments = client.getOutgoingPaymentsForPaymentsHash(outgoingPayment?.transactionHash!!) + payments.shouldNotBeNull() + payments.shouldHaveSize(1) + payments[0].id.shouldBe(outgoingPayment.id) + } + + @Test + fun `test getInvoiceForPaymentsHash`() = runTest { + val node = getFirstOskNode() + client.loadNodeSigningKey(node.id, PasswordRecoverySigningKeyLoader(node.id, NODE_PASSWORD)) + val testInvoice = client.createInvoice(node.id, 100_000, "test invoice") + var payment: IncomingPayment? = client.createTestModePayment(node.id, testInvoice.data.encodedPaymentRequest) + payment.shouldNotBeNull() + while (payment?.status == TransactionStatus.PENDING) { + delay(500) + payment = IncomingPayment.getIncomingPaymentQuery(payment.id).execute(client) + println("Payment status: ${payment?.status}") + } + + val invoice = client.getInvoiceForPaymentHash(payment?.transactionHash!!) + invoice.shouldNotBeNull() + invoice.id.shouldBe(testInvoice.id) + } + @Test fun `test uma identifier hashing`() = runTest { val privKeyBytes = "xyz".toByteArray() From acbf9a5d092a0dd5b3650053793090ac79190251 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 8 Aug 2024 13:02:08 -0700 Subject: [PATCH 07/11] addressing feedback --- .../com/lightspark/sdk/LightsparkFuturesClient.kt | 4 ++-- .../lightspark/sdk/LightsparkCoroutinesClient.kt | 6 +++--- .../com/lightspark/sdk/LightsparkSyncClient.kt | 13 ++++++++++--- .../sdk/graphql/IncomingPaymentsForInvoice.kt | 2 +- ...eForPaymentsHash.kt => InvoiceForPaymentHash.kt} | 2 +- .../com/lightspark/sdk/ClientIntegrationTests.kt | 10 ++++------ 6 files changed, 21 insertions(+), 16 deletions(-) rename lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/{InvoiceForPaymentsHash.kt => InvoiceForPaymentHash.kt} (86%) diff --git a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt index 0dacb9c7..28fb9b85 100644 --- a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt +++ b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt @@ -583,11 +583,11 @@ class LightsparkFuturesClient(config: ClientConfig) { * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. */ @Throws(LightsparkException::class, LightsparkAuthenticationException::class) - fun getOutgoingPaymentsForPaymentsHash( + fun getOutgoingPaymentsForPaymentHash( paymentHash: String, transactionStatuses: List? = null ): CompletableFuture> = coroutineScope.future { - coroutinesClient.getOutgoingPaymentsForPaymentsHash(paymentHash, transactionStatuses) + coroutinesClient.getOutgoingPaymentForPaymentHash(paymentHash, transactionStatuses) } /** diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt index e9f6a0fc..5b1573ef 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt @@ -1042,7 +1042,7 @@ class LightsparkCoroutinesClient private constructor( * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. */ - suspend fun getOutgoingPaymentsForPaymentsHash( + suspend fun getOutgoingPaymentForPaymentHash( paymentHash: String, transactionStatuses: List? = null, ): List { @@ -1067,7 +1067,7 @@ class LightsparkCoroutinesClient private constructor( } /** - * fetch invoice for a given payments hash + * fetch invoice for a given payment hash * * @param paymentHash the payment hash of the invoice for which to fetch the outgoing payments */ @@ -1077,7 +1077,7 @@ class LightsparkCoroutinesClient private constructor( requireValidAuth() return executeQuery( Query( - InvoiceForPaymentsHashQuery, + InvoiceForPaymentHashQuery, { add("paymentHash", paymentHash) }, diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt index 7fd95f4d..40902cb9 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt @@ -563,7 +563,7 @@ class LightsparkSyncClient constructor(config: ClientConfig) { /** * Fetch incoming payments for a given payment hash. * - * @param paymentHash The payment hash of the invoice for which to fetch the incoming payments. + * @param paymentHash The payment hash of the invoice for which to fetch the incoming payments. * @param transactionStatuses The transaction statuses to filter the payments by. If null, all payments will be * returned. * @return The list of incoming payments for the payment hash. @@ -583,11 +583,11 @@ class LightsparkSyncClient constructor(config: ClientConfig) { * @param transactionStatuses the transaction statuses to filter the payments by. If null, all payments will be returned. */ @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) - fun getOutgoingPaymentsForPaymentsHash( + fun getOutgoingPaymentsForPaymentHash( paymentHash: String, transactionStatuses: List? = null ): List = runBlocking { - asyncClient.getOutgoingPaymentsForPaymentsHash(paymentHash, transactionStatuses) + asyncClient.getOutgoingPaymentForPaymentHash(paymentHash, transactionStatuses) } @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) @@ -598,6 +598,13 @@ class LightsparkSyncClient constructor(config: ClientConfig) { asyncClient.getIncomingPaymentsForInvoice(invoiceId, transactionStatuses) } + @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) + fun getInvoiceForPaymentHash( + paymentHash: String + ): Invoice = runBlocking { + asyncClient.getInvoiceForPaymentHash(paymentHash) + } + /** * Creates an UMA invitation. If you are part of the incentive program you should use * [createUmaInvitationWithIncentives]. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt index e9596df0..a66b00d5 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/IncomingPaymentsForInvoice.kt @@ -9,7 +9,7 @@ query IncomingPaymentsForInvoice( ) { incoming_payments_for_invoice_query(input: { invoice_id: ${'$'}invoiceId, - statuses: ${'$'}transactionStatuses + statuses: ${'$'}transactionStatuses }) { payments { ...IncomingPaymentFragment diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentHash.kt similarity index 86% rename from lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt rename to lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentHash.kt index 2cb1b052..056edebb 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentsHash.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/InvoiceForPaymentHash.kt @@ -2,7 +2,7 @@ package com.lightspark.sdk.graphql import com.lightspark.sdk.model.Invoice -const val InvoiceForPaymentsHashQuery = """ +const val InvoiceForPaymentHashQuery = """ query InvoiceForPaymentHash( ${'$'}paymentHash: Hash32!, ) { diff --git a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt index be0dee6c..ef3de767 100644 --- a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt +++ b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt @@ -309,10 +309,8 @@ class ClientIntegrationTests { payments[0].id.shouldBe(payment?.id) } - // todo add payment has tests - @Test - fun `test getOutgoingPaymentsForPaymentsHash`() = runTest { + fun `test getOutgoingPaymentsForPaymentHash`() = runTest { val node = getFirstOskNode() client.loadNodeSigningKey(node.id, PasswordRecoverySigningKeyLoader(node.id, NODE_PASSWORD)) val invoice = client.createTestModeInvoice(node.id, 100_000, "test invoice") @@ -325,14 +323,14 @@ class ClientIntegrationTests { } outgoingPayment?.status.shouldBe(TransactionStatus.SUCCESS) - val payments = client.getOutgoingPaymentsForPaymentsHash(outgoingPayment?.transactionHash!!) + val payments = client.getOutgoingPaymentForPaymentHash(outgoingPayment?.transactionHash!!) payments.shouldNotBeNull() payments.shouldHaveSize(1) payments[0].id.shouldBe(outgoingPayment.id) } @Test - fun `test getInvoiceForPaymentsHash`() = runTest { + fun `test getInvoiceForPaymentHash`() = runTest { val node = getFirstOskNode() client.loadNodeSigningKey(node.id, PasswordRecoverySigningKeyLoader(node.id, NODE_PASSWORD)) val testInvoice = client.createInvoice(node.id, 100_000, "test invoice") @@ -344,7 +342,7 @@ class ClientIntegrationTests { println("Payment status: ${payment?.status}") } - val invoice = client.getInvoiceForPaymentHash(payment?.transactionHash!!) + val invoice = client.getInvoiceForPaymentHash(testInvoice.data.paymentHash) invoice.shouldNotBeNull() invoice.id.shouldBe(testInvoice.id) } From 9008c1d2ed943a39d0c105158a82d605457623b6 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Fri, 9 Aug 2024 16:21:36 -0700 Subject: [PATCH 08/11] using payment hash from decoded invoice --- .../kotlin/com/lightspark/sdk/ClientIntegrationTests.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt index ef3de767..ffbd1604 100644 --- a/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt +++ b/lightspark-sdk/src/commonTest/kotlin/com/lightspark/sdk/ClientIntegrationTests.kt @@ -322,11 +322,12 @@ class ClientIntegrationTests { println("Payment status: ${outgoingPayment?.status}") } outgoingPayment?.status.shouldBe(TransactionStatus.SUCCESS) - - val payments = client.getOutgoingPaymentForPaymentHash(outgoingPayment?.transactionHash!!) + val payments = client.getOutgoingPaymentForPaymentHash( + client.decodeInvoice(invoice).paymentHash + ) payments.shouldNotBeNull() payments.shouldHaveSize(1) - payments[0].id.shouldBe(outgoingPayment.id) + payments[0].id.shouldBe(outgoingPayment?.id!!) } @Test From 55a3612bc85437d5adcd75d9e3c7cfe3e58aa1e2 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 15 Aug 2024 10:44:32 -0700 Subject: [PATCH 09/11] add funding address param to FundNode query --- .../kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt | 5 +++-- .../com/lightspark/sdk/LightsparkCoroutinesClient.kt | 8 +++++++- .../kotlin/com/lightspark/sdk/LightsparkSyncClient.kt | 5 +++-- .../kotlin/com/lightspark/sdk/graphql/FundNode.kt | 7 ++++++- .../kotlin/com/lightspark/sdk/model/FundNodeInput.kt | 1 + .../com/lightspark/sdk/wallet/model/FundWalletInput.kt | 1 + 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt index 28fb9b85..a1c5b939 100644 --- a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt +++ b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt @@ -414,10 +414,11 @@ class LightsparkFuturesClient(config: ClientConfig) { * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. + * @param fundingAddress: L1 address owned by funded node * @return The amount of funds added to the node. */ - fun fundNode(nodeId: String, amountSats: Long?): CompletableFuture = - coroutineScope.future { coroutinesClient.fundNode(nodeId, amountSats) } + fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String?): CompletableFuture = + coroutineScope.future { coroutinesClient.fundNode(nodeId, amountSats, fundingAddress) } /** * Withdraws funds from the account and sends it to the requested bitcoin address. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt index 5b1573ef..f527801c 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt @@ -729,9 +729,14 @@ class LightsparkCoroutinesClient private constructor( * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. + * @param fundingAddress: L1 address owned by funded node * @return The amount of funds added to the node. */ - suspend fun fundNode(nodeId: String, amountSats: Long?): CurrencyAmount { + suspend fun fundNode( + nodeId: String, + amountSats: Long?, + fundingAddress: String? + ): CurrencyAmount { requireValidAuth() return executeQuery( Query( @@ -739,6 +744,7 @@ class LightsparkCoroutinesClient private constructor( { add("node_id", nodeId) amountSats?.let { add("amount_sats", it) } + fundingAddress?.let { add("funding_address", it)} }, signingNodeId = nodeId, ) { diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt index 40902cb9..d3e56557 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt @@ -397,11 +397,12 @@ class LightsparkSyncClient constructor(config: ClientConfig) { * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. + * @param fundingAddress: L1 address owned by funded node * @return The amount of funds added to the node. */ @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) - fun fundNode(nodeId: String, amountSats: Long?): CurrencyAmount = - runBlocking { asyncClient.fundNode(nodeId, amountSats) } + fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String?): CurrencyAmount = + runBlocking { asyncClient.fundNode(nodeId, amountSats, fundingAddress) } /** * Withdraws funds from the account and sends it to the requested bitcoin address. diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/FundNode.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/FundNode.kt index b80d257e..4e30a832 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/FundNode.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/graphql/FundNode.kt @@ -6,8 +6,13 @@ const val FundNodeMutation = """ mutation FundNode( ${'$'}node_id: ID!, ${'$'}amount_sats: Long + ${'$'}funding_address: String ) { - fund_node(input: { node_id: ${'$'}node_id, amount_sats: ${'$'}amount_sats }) { + fund_node(input: { + node_id: ${'$'}node_id, + amount_sats: ${'$'}amount_sats, + funding_address: ${'$'}funding_address + }) { amount { ...CurrencyAmountFragment } diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/FundNodeInput.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/FundNodeInput.kt index 1747bb60..e7e08c2e 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/FundNodeInput.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/FundNodeInput.kt @@ -14,6 +14,7 @@ import kotlinx.serialization.Serializable data class FundNodeInput( val nodeId: String, val amountSats: Long? = null, + val fundingAddress: String? = null, ) { companion object { } diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/FundWalletInput.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/FundWalletInput.kt index 113f28a8..60a5b671 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/FundWalletInput.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/FundWalletInput.kt @@ -13,6 +13,7 @@ import kotlinx.serialization.Serializable @SerialName("FundWalletInput") data class FundWalletInput( val amountSats: Long? = null, + val fundingAddress: String? = null, ) { companion object { } From 2e6bace17a48167b72821ac7a68ca40d493a0e9c Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Thu, 15 Aug 2024 15:03:02 -0700 Subject: [PATCH 10/11] default parameters and updated javadoc --- .../kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt | 4 ++-- .../kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt | 4 ++-- .../kotlin/com/lightspark/sdk/LightsparkSyncClient.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt index a1c5b939..9d76ef88 100644 --- a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt +++ b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt @@ -414,10 +414,10 @@ class LightsparkFuturesClient(config: ClientConfig) { * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. - * @param fundingAddress: L1 address owned by funded node + * @param fundingAddress: L1 address owned by funded node. If null, automatically create new funding address * @return The amount of funds added to the node. */ - fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String?): CompletableFuture = + fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String? = null): CompletableFuture = coroutineScope.future { coroutinesClient.fundNode(nodeId, amountSats, fundingAddress) } /** diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt index f527801c..6eaf367c 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkCoroutinesClient.kt @@ -729,13 +729,13 @@ class LightsparkCoroutinesClient private constructor( * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. - * @param fundingAddress: L1 address owned by funded node + * @param fundingAddress: L1 address owned by funded node. If null, automatically create new funding address * @return The amount of funds added to the node. */ suspend fun fundNode( nodeId: String, amountSats: Long?, - fundingAddress: String? + fundingAddress: String? = null ): CurrencyAmount { requireValidAuth() return executeQuery( diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt index d3e56557..bc80e00e 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt @@ -397,11 +397,11 @@ class LightsparkSyncClient constructor(config: ClientConfig) { * * @param nodeId The ID of the node to fund. Must be a REGTEST node. * @param amountSats The amount of funds to add to the node. Defaults to 10,000,000 SATOSHI. - * @param fundingAddress: L1 address owned by funded node + * @param fundingAddress: L1 address owned by funded node. If null, automatically create new funding address * @return The amount of funds added to the node. */ @Throws(LightsparkException::class, LightsparkAuthenticationException::class, CancellationException::class) - fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String?): CurrencyAmount = + fun fundNode(nodeId: String, amountSats: Long?, fundingAddress: String? = null): CurrencyAmount = runBlocking { asyncClient.fundNode(nodeId, amountSats, fundingAddress) } /** From a66f7a2f88412169834d141409c258b5132331d0 Mon Sep 17 00:00:00 2001 From: runner Date: Thu, 15 Aug 2024 23:49:15 +0000 Subject: [PATCH 11/11] Bump lightspark-sdk to version 0.17.0 --- lightspark-sdk/README.md | 4 ++-- lightspark-sdk/gradle.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lightspark-sdk/README.md b/lightspark-sdk/README.md index cead931e..62e21216 100644 --- a/lightspark-sdk/README.md +++ b/lightspark-sdk/README.md @@ -17,14 +17,14 @@ Start by installing the SDK from maven: **build.gradle:** ```groovy dependencies { - implementation "com.lightspark:lightspark-sdk:0.16.0" + implementation "com.lightspark:lightspark-sdk:0.17.0" } ``` or with **build.gradle.kts:** ```kotlin dependencies { - implementation("com.lightspark:lightspark-sdk:0.16.0") + implementation("com.lightspark:lightspark-sdk:0.17.0") } ``` diff --git a/lightspark-sdk/gradle.properties b/lightspark-sdk/gradle.properties index ee694ffb..89fcdee7 100644 --- a/lightspark-sdk/gradle.properties +++ b/lightspark-sdk/gradle.properties @@ -1,7 +1,7 @@ GROUP=com.lightspark POM_ARTIFACT_ID=lightspark-sdk # Don't bump this manually. Run `scripts/versions.main.kt ` to bump the version instead. -VERSION_NAME=0.16.0 +VERSION_NAME=0.17.0 POM_DESCRIPTION=The Lightspark API SDK for Kotlin and Java. POM_INCEPTION_YEAR=2023