diff --git a/.github/workflows/core-build.yaml b/.github/workflows/core-build.yaml index ac0124d7..7d1e882e 100644 --- a/.github/workflows/core-build.yaml +++ b/.github/workflows/core-build.yaml @@ -9,6 +9,13 @@ on: branches: - 'main' - 'develop' + pull_request: + branches: + - 'develop' + paths: + - 'core/**' + - 'build.gradle.kts' + - '.github/workflows/core-build.yaml' jobs: build: @@ -25,5 +32,7 @@ jobs: uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 - name: Build and lint uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: core:assemble diff --git a/.github/workflows/core-publish.yaml b/.github/workflows/core-publish.yaml index 19b18ac3..7d7e8c4d 100644 --- a/.github/workflows/core-publish.yaml +++ b/.github/workflows/core-publish.yaml @@ -23,6 +23,7 @@ jobs: with: arguments: core:publish env: + CI: true ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY_IN_MEMORY }} diff --git a/.github/workflows/crypto-build.yaml b/.github/workflows/crypto-build.yaml index 750c7014..8ff79ce8 100644 --- a/.github/workflows/crypto-build.yaml +++ b/.github/workflows/crypto-build.yaml @@ -9,6 +9,13 @@ on: branches: - 'main' - 'develop' + pull_request: + branches: + - 'develop' + paths: + - 'crypto/**' + - 'build.gradle.kts' + - '.github/workflows/crypto-build.yaml' jobs: build: @@ -27,5 +34,7 @@ jobs: uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 - name: Build and lint uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: crypto:assemble diff --git a/.github/workflows/crypto-publish.yaml b/.github/workflows/crypto-publish.yaml index 3b161ee1..433d2d2c 100644 --- a/.github/workflows/crypto-publish.yaml +++ b/.github/workflows/crypto-publish.yaml @@ -23,6 +23,7 @@ jobs: with: arguments: crypto:publish env: + CI: true ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY_IN_MEMORY }} diff --git a/.github/workflows/docs-publish.yaml b/.github/workflows/docs-publish.yaml index 70ca22db..6769f4e3 100644 --- a/.github/workflows/docs-publish.yaml +++ b/.github/workflows/docs-publish.yaml @@ -36,6 +36,8 @@ jobs: uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 - name: Build dokka uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: dokkaHtmlMultiModule - name: "Upload to S3" diff --git a/.github/workflows/lightspark-sdk-build.yaml b/.github/workflows/lightspark-sdk-build.yaml index 029c4acf..aa551c03 100644 --- a/.github/workflows/lightspark-sdk-build.yaml +++ b/.github/workflows/lightspark-sdk-build.yaml @@ -10,6 +10,14 @@ on: branches: - 'main' - 'develop' + pull_request: + branches: + - 'develop' + paths: + - 'lightspark-sdk/**' + - 'core/**' + - 'build.gradle.kts' + - '.github/workflows/lightspark-sdk-build.yaml' jobs: build: @@ -28,5 +36,7 @@ jobs: uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 - name: Build and lint uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: lightspark-sdk:assemble diff --git a/.github/workflows/lightspark-sdk-publish.yaml b/.github/workflows/lightspark-sdk-publish.yaml index 31bbaaff..0aacb90e 100644 --- a/.github/workflows/lightspark-sdk-publish.yaml +++ b/.github/workflows/lightspark-sdk-publish.yaml @@ -23,6 +23,7 @@ jobs: with: arguments: lightspark-sdk:publish env: + CI: true ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY_IN_MEMORY }} diff --git a/.github/workflows/release-branch-cut.yaml b/.github/workflows/release-branch-cut.yaml index cab103fa..3f551959 100644 --- a/.github/workflows/release-branch-cut.yaml +++ b/.github/workflows/release-branch-cut.yaml @@ -36,10 +36,14 @@ jobs: fi - name: Bump Version uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: "${{ env.sdk_name }}:bumpVersion -PnewVersion=${{ env.rel_version }}" - name: Build uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: "${{ env.sdk_name }}:assemble" - name: Merge version updates diff --git a/.github/workflows/wallet-build.yaml b/.github/workflows/wallet-build.yaml index 56e1f2eb..55be03fa 100644 --- a/.github/workflows/wallet-build.yaml +++ b/.github/workflows/wallet-build.yaml @@ -10,6 +10,14 @@ on: branches: - 'main' - 'develop' + pull_request: + branches: + - 'develop' + paths: + - 'wallet-sdk/**' + - 'core/**' + - 'build.gradle.kts' + - '.github/workflows/wallet-build.yaml' jobs: build: @@ -28,5 +36,7 @@ jobs: uses: gradle/wrapper-validation-action@ccb4328a959376b642e027874838f60f8e596de3 - name: Build and lint uses: gradle/gradle-build-action@v2.4.2 + env: + CI: true with: arguments: wallet-sdk:assemble diff --git a/.github/workflows/wallet-publish.yaml b/.github/workflows/wallet-publish.yaml index 9630cad0..101b6106 100644 --- a/.github/workflows/wallet-publish.yaml +++ b/.github/workflows/wallet-publish.yaml @@ -23,6 +23,7 @@ jobs: with: arguments: wallet-sdk:publish env: + CI: true ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY_IN_MEMORY }} diff --git a/androidwalletdemo/README.md b/androidwalletdemo/README.md index 70fb1377..112b2480 100644 --- a/androidwalletdemo/README.md +++ b/androidwalletdemo/README.md @@ -9,4 +9,9 @@ various examples: - [Generating keys and initializing a wallet - WalletRepository::initializeWallet](./src/main/java/com/lightspark/androidwalletdemo/wallet/WalletRepository.kt) - [Unlocking a wallet to make payments - WalletRepository::attemptKeyStoreUnlock](./src/main/java/com/lightspark/androidwalletdemo/wallet/WalletRepository.kt) - [Creating, Decoding, and Paying Invoices - PaymentRepository.kt](./src/main/java/com/lightspark/androidwalletdemo/wallet/PaymentRepository.kt) - - [Scanning an invoice QR code - InvoiceQrScanner.kt](./src/main/java/com/lightspark/androidwalletdemo/sendpayment/InvoiceQrScanner.kt) \ No newline at end of file + - [Scanning an invoice QR code - InvoiceQrScanner.kt](./src/main/java/com/lightspark/androidwalletdemo/sendpayment/InvoiceQrScanner.kt) + +### How to run + +1. Set up the [demo JWT server](https://github.com/lightsparkdev/js-sdk/tree/main/apps/examples/jwt-server) +2. Edit `local.properties` generated by Android Studio and add the ngrok URL as `jwtServerUrl`. diff --git a/androidwalletdemo/build.gradle.kts b/androidwalletdemo/build.gradle.kts index f631a960..709e113f 100644 --- a/androidwalletdemo/build.gradle.kts +++ b/androidwalletdemo/build.gradle.kts @@ -1,3 +1,4 @@ +import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties import java.io.FileInputStream import java.util.* @@ -17,6 +18,11 @@ try { throw RuntimeException("Unable to load version.properties", e) } +val isCI: Boolean = System.getenv("CI") == "true" +val jwtServerUrl: String = if (isCI) "" else + gradleLocalProperties(rootDir).getProperty("jwtServerUrl") + ?: throw Error("You must set the jwtServerUrl property in a local.properties file") + android { namespace = "com.lightspark.androidwalletdemo" compileSdk = 34 @@ -33,6 +39,7 @@ android { useSupportLibrary = true } manifestPlaceholders["appAuthRedirectScheme"] = "com.lightspark.androidwalletdemo" + buildConfigField("String", "JWT_SERVER_URL", "\"${jwtServerUrl}\"") } buildTypes { diff --git a/androidwalletdemo/src/main/java/com/lightspark/androidwalletdemo/di/AuthModule.kt b/androidwalletdemo/src/main/java/com/lightspark/androidwalletdemo/di/AuthModule.kt index c64b8688..94452a8b 100644 --- a/androidwalletdemo/src/main/java/com/lightspark/androidwalletdemo/di/AuthModule.kt +++ b/androidwalletdemo/src/main/java/com/lightspark/androidwalletdemo/di/AuthModule.kt @@ -1,5 +1,6 @@ package com.lightspark.androidwalletdemo.di +import com.lightspark.androidwalletdemo.BuildConfig import com.lightspark.androidwalletdemo.auth.DemoAuthService import dagger.Module import dagger.Provides @@ -15,7 +16,7 @@ class AuthModule { @Provides @Singleton fun provideDemoAuthRetrofit(): Retrofit = Retrofit.Builder() - .baseUrl("https://us-central1-jwt-minter.cloudfunctions.net/") + .baseUrl(BuildConfig.JWT_SERVER_URL) .addConverterFactory(GsonConverterFactory.create()) .build() diff --git a/core/src/commonMain/kotlin/com/lightspark/sdk/core/auth/AuthConstants.kt b/core/src/commonMain/kotlin/com/lightspark/sdk/core/auth/AuthConstants.kt deleted file mode 100644 index 5bd67a04..00000000 --- a/core/src/commonMain/kotlin/com/lightspark/sdk/core/auth/AuthConstants.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.lightspark.sdk.core.auth - -const val BETA_HEADER_KEY = "X-Lightspark-Beta" -const val BETA_HEADER_VALUE = "z2h0BBYxTA83cjW7fi8QwWtBPCzkQKiemcuhKY08LOo" diff --git a/core/src/commonMain/kotlin/com/lightspark/sdk/core/requester/Requester.kt b/core/src/commonMain/kotlin/com/lightspark/sdk/core/requester/Requester.kt index 999202f8..cf9e0e0c 100644 --- a/core/src/commonMain/kotlin/com/lightspark/sdk/core/requester/Requester.kt +++ b/core/src/commonMain/kotlin/com/lightspark/sdk/core/requester/Requester.kt @@ -6,8 +6,6 @@ import com.lightspark.sdk.core.LightsparkCoreConfig import com.lightspark.sdk.core.LightsparkErrorCode import com.lightspark.sdk.core.LightsparkException import com.lightspark.sdk.core.auth.AuthProvider -import com.lightspark.sdk.core.auth.BETA_HEADER_KEY -import com.lightspark.sdk.core.auth.BETA_HEADER_VALUE import com.lightspark.sdk.core.crypto.MissingKeyException import com.lightspark.sdk.core.crypto.NodeKeyCache import com.lightspark.sdk.core.util.getPlatform @@ -53,7 +51,6 @@ class Requester constructor( "lightspark-kotlin-sdk/${LightsparkCoreConfig.VERSION} ${getPlatform().platformName}/${getPlatform().version}" private val defaultHeaders = mapOf( "Content-Type" to "application/json", - BETA_HEADER_KEY to BETA_HEADER_VALUE, "User-Agent" to userAgent, "X-Lightspark-SDK" to userAgent, ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index baae2dad..dcdab387 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ ktlint = "11.3.1" ktor = "2.2.3" lightsparkCore = "0.5.0" lightsparkCrypto = "0.5.0" -uma = "0.3.0" +uma = "0.6.0" mavenPublish = "0.25.2" mockitoCore = "5.5.0" taskTree = "2.1.1" diff --git a/lightspark-sdk/README.md b/lightspark-sdk/README.md index 4141e185..2f475910 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.11.0" + implementation "com.lightspark:lightspark-sdk:0.12.0" } ``` or with **build.gradle.kts:** ```kotlin dependencies { - implementation("com.lightspark:lightspark-sdk:0.11.0") + implementation("com.lightspark:lightspark-sdk:0.12.0") } ``` diff --git a/lightspark-sdk/gradle.properties b/lightspark-sdk/gradle.properties index 63e7272e..d30fb5d6 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.11.0 +VERSION_NAME=0.12.0 POM_DESCRIPTION=The Lightspark API SDK for Kotlin and Java. POM_INCEPTION_YEAR=2023 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 6dd31cfa..36828380 100644 --- a/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt +++ b/lightspark-sdk/src/commonJvmAndroidMain/kotlin/com/lightspark/sdk/LightsparkFuturesClient.kt @@ -156,6 +156,25 @@ class LightsparkFuturesClient(config: ClientConfig) { ): CompletableFuture = coroutineScope.future { coroutinesClient.createLnurlInvoice(nodeId, amountMsats, metadata, expirySecs) } + /** + * Creates a Lightning invoice for the given node. This should only be used for generating invoices for UMA, with + * [LightsparkCoroutinesClient.createInvoice] preferred in the general case. + * + * @param nodeId The ID of the node for which to create the invoice. + * @param amountMsats The amount of the invoice in milli-satoshis. + * @param metadata The LNURL metadata payload field from the initial payreq response. This will be hashed and + * present in the h-tag (SHA256 purpose of payment) of the resulting Bolt 11 invoice. + * @param expirySecs The number of seconds until the invoice expires. Defaults to 1 day. + */ + @JvmOverloads + fun createUmaInvoice( + nodeId: String, + amountMsats: Long, + metadata: String, + expirySecs: Int? = null, + ): CompletableFuture = + coroutineScope.future { coroutinesClient.createUmaInvoice(nodeId, amountMsats, metadata, expirySecs) } + /** * Cancels an existing unpaid invoice and returns that invoice. Cancelled invoices cannot be paid. * @@ -201,6 +220,38 @@ class LightsparkFuturesClient(config: ClientConfig) { ) } + /** + * [payUmaInvoice] sends an UMA payment to a node on the Lightning Network, based on the invoice (as defined by the + * BOLT11 specification) that you provide. This should only be used for paying UMA invoices, with [payInvoice] + * preferred in the general case. + * + * @param nodeId The ID of the node which will pay the invoice. + * @param encodedInvoice An encoded string representation of the invoice to pay. + * @param maxFeesMsats The maximum fees to pay in milli-satoshis. You must pass a value. + * As guidance, a maximum fee of 15 basis points should make almost all transactions succeed. For example, + * for a transaction between 10k sats and 100k sats, this would mean a fee limit of 15 to 150 sats. + * @param amountMsats The amount to pay in milli-satoshis. Defaults to the full amount of the invoice. + * @param timeoutSecs The number of seconds to wait for the payment to complete. Defaults to 60. + * @return The payment details. + */ + @JvmOverloads + fun payUmaInvoice( + nodeId: String, + encodedInvoice: String, + maxFeesMsats: Long, + amountMsats: Long? = null, + timeoutSecs: Int = 60, + ): CompletableFuture = + coroutineScope.future { + coroutinesClient.payUmaInvoice( + nodeId, + encodedInvoice, + maxFeesMsats, + amountMsats, + timeoutSecs, + ) + } + /** * Decode a lightning invoice to get its details included payment amount, destination, etc. * 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 cc17cffb..4ad3c430 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/LightsparkSyncClient.kt @@ -136,6 +136,24 @@ class LightsparkSyncClient constructor(config: ClientConfig) { expirySecs: Int? = null, ): Invoice = runBlocking { asyncClient.createLnurlInvoice(nodeId, amountMsats, metadata, expirySecs) } + /** + * Creates a Lightning invoice for the given node. This should only be used for generating invoices for UMA, with + * [LightsparkCoroutinesClient.createInvoice] preferred in the general case. + * + * @param nodeId The ID of the node for which to create the invoice. + * @param amountMsats The amount of the invoice in milli-satoshis. + * @param metadata The LNURL metadata payload field from the initial payreq response. This will be hashed and + * present in the h-tag (SHA256 purpose of payment) of the resulting Bolt 11 invoice. + * @param expirySecs The number of seconds until the invoice expires. Defaults to 1 day. + */ + @JvmOverloads + fun createUmaInvoice( + nodeId: String, + amountMsats: Long, + metadata: String, + expirySecs: Int? = null, + ): Invoice = runBlocking { asyncClient.createUmaInvoice(nodeId, amountMsats, metadata, expirySecs) } + /** * Cancels an existing unpaid invoice and returns that invoice. Cancelled invoices cannot be paid. * @@ -172,6 +190,30 @@ class LightsparkSyncClient constructor(config: ClientConfig) { ): OutgoingPayment = runBlocking { asyncClient.payInvoice(nodeId, encodedInvoice, maxFeesMsats, amountMsats, timeoutSecs) } + /** + * [payUmaInvoice] sends an UMA payment to a node on the Lightning Network, based on the invoice (as defined by the + * BOLT11 specification) that you provide. This should only be used for paying UMA invoices, with [payInvoice] + * preferred in the general case. + * + * @param nodeId The ID of the node which will pay the invoice. + * @param encodedInvoice An encoded string representation of the invoice to pay. + * @param maxFeesMsats The maximum fees to pay in milli-satoshis. You must pass a value. + * As guidance, a maximum fee of 15 basis points should make almost all transactions succeed. For example, + * for a transaction between 10k sats and 100k sats, this would mean a fee limit of 15 to 150 sats. + * @param amountMsats The amount to pay in milli-satoshis. Defaults to the full amount of the invoice. + * @param timeoutSecs The number of seconds to wait for the payment to complete. Defaults to 60. + * @return The payment details. + */ + @JvmOverloads + fun payUmaInvoice( + nodeId: String, + encodedInvoice: String, + maxFeesMsats: Long, + amountMsats: Long? = null, + timeoutSecs: Int = 60, + ): OutgoingPayment = + runBlocking { asyncClient.payUmaInvoice(nodeId, encodedInvoice, maxFeesMsats, amountMsats, timeoutSecs) } + /** * Decode a lightning invoice to get its details included payment amount, destination, etc. * diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Account.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Account.kt index 28efc604..5be57b7d 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Account.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Account.kt @@ -1673,6 +1673,99 @@ query FetchAccountToPaymentRequestsConnection(${'$'}first: Int, ${'$'}after: Str } } + @JvmOverloads + fun getWithdrawalRequestsQuery( + first: Int? = null, + after: String? = null, + bitcoinNetworks: List? = null, + statuses: List? = null, + nodeIds: List? = null, + afterDate: Instant? = null, + beforeDate: Instant? = null, + ): Query { + return Query( + queryPayload = """ +query FetchAccountToWithdrawalRequestsConnection(${'$'}first: Int, ${'$'}after: String, ${'$'}bitcoin_networks: [BitcoinNetwork!], ${'$'}statuses: [WithdrawalRequestStatus!], ${'$'}node_ids: [ID!], ${'$'}after_date: DateTime, ${'$'}before_date: DateTime) { + current_account { + ... on Account { + withdrawal_requests(, first: ${'$'}first, after: ${'$'}after, bitcoin_networks: ${'$'}bitcoin_networks, statuses: ${'$'}statuses, node_ids: ${'$'}node_ids, after_date: ${'$'}after_date, before_date: ${'$'}before_date) { + type: __typename + account_to_withdrawal_requests_connection_count: count + account_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + account_to_withdrawal_requests_connection_entities: entities { + type: __typename + withdrawal_request_id: id + withdrawal_request_created_at: created_at + withdrawal_request_updated_at: updated_at + withdrawal_request_requested_amount: requested_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount: amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_estimated_amount: estimated_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount_withdrawn: amount_withdrawn { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_bitcoin_address: bitcoin_address + withdrawal_request_withdrawal_mode: withdrawal_mode + withdrawal_request_status: status + withdrawal_request_completed_at: completed_at + withdrawal_request_withdrawal: withdrawal { + id + } + } + } + } + } +} +""", + variableBuilder = { + add("first", first) + add("after", after) + add("bitcoin_networks", bitcoinNetworks) + add("statuses", statuses) + add("node_ids", nodeIds) + add("after_date", afterDate) + add("before_date", beforeDate) + } + ) { + val connection = + requireNotNull( + it["current_account"]?.jsonObject?.get("withdrawal_requests") + ) { "withdrawal_requests not found" } + return@Query serializerFormat.decodeFromJsonElement(connection) + } + } + @JvmOverloads fun getWalletsQuery( first: Int? = null, diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/AccountToWithdrawalRequestsConnection.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/AccountToWithdrawalRequestsConnection.kt new file mode 100644 index 00000000..7cd34343 --- /dev/null +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/AccountToWithdrawalRequestsConnection.kt @@ -0,0 +1,42 @@ +// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved +@file:Suppress("ktlint:standard:max-line-length") + +package com.lightspark.sdk.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * A connection between an account and its past and present withdrawal requests. + * @param count The total count of objects in this connection, using the current filters. It is different from the number of objects returned in the current page (in the `entities` field). + * @param pageInfo An object that holds pagination information about the objects in this connection. + * @param entities The withdrawal requests for the current page of this connection. + */ +@Serializable +@SerialName("AccountToWithdrawalRequestsConnection") +data class AccountToWithdrawalRequestsConnection( + @SerialName("account_to_withdrawal_requests_connection_count") + override val count: Int, + @SerialName("account_to_withdrawal_requests_connection_page_info") + override val pageInfo: PageInfo, + @SerialName("account_to_withdrawal_requests_connection_entities") + val entities: List, +) : Connection { + companion object { + const val FRAGMENT = """ +fragment AccountToWithdrawalRequestsConnectionFragment on AccountToWithdrawalRequestsConnection { + type: __typename + account_to_withdrawal_requests_connection_count: count + account_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + account_to_withdrawal_requests_connection_entities: entities { + id + } +}""" + } +} diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Connection.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Connection.kt index b24af627..c8ba28be 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Connection.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Connection.kt @@ -115,6 +115,20 @@ fragment ConnectionFragment on Connection { id } } + ... on AccountToWithdrawalRequestsConnection { + type: __typename + account_to_withdrawal_requests_connection_count: count + account_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + account_to_withdrawal_requests_connection_entities: entities { + id + } + } ... on IncomingPaymentToAttemptsConnection { type: __typename incoming_payment_to_attempts_connection_count: count @@ -199,6 +213,20 @@ fragment ConnectionFragment on Connection { id } } + ... on WalletToWithdrawalRequestsConnection { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + id + } + } }""" } } diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Wallet.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Wallet.kt index d405324e..c8f41ac7 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Wallet.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/Wallet.kt @@ -1019,6 +1019,95 @@ query FetchWalletTotalAmountReceived(${'$'}created_after_date: DateTime, ${'$'}c } } + @JvmOverloads + fun getWithdrawalRequestsQuery( + first: Int? = null, + after: String? = null, + statuses: List? = null, + createdAfterDate: Instant? = null, + createdBeforeDate: Instant? = null, + ): Query { + return Query( + queryPayload = """ +query FetchWalletToWithdrawalRequestsConnection(${'$'}first: Int, ${'$'}after: ID, ${'$'}statuses: [WithdrawalRequestStatus!], ${'$'}created_after_date: DateTime, ${'$'}created_before_date: DateTime) { + current_wallet { + ... on Wallet { + withdrawal_requests(, first: ${'$'}first, after: ${'$'}after, statuses: ${'$'}statuses, created_after_date: ${'$'}created_after_date, created_before_date: ${'$'}created_before_date) { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + type: __typename + withdrawal_request_id: id + withdrawal_request_created_at: created_at + withdrawal_request_updated_at: updated_at + withdrawal_request_requested_amount: requested_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount: amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_estimated_amount: estimated_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount_withdrawn: amount_withdrawn { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_bitcoin_address: bitcoin_address + withdrawal_request_withdrawal_mode: withdrawal_mode + withdrawal_request_status: status + withdrawal_request_completed_at: completed_at + withdrawal_request_withdrawal: withdrawal { + id + } + } + } + } + } +} +""", + variableBuilder = { + add("first", first) + add("after", after) + add("statuses", statuses) + add("created_after_date", createdAfterDate) + add("created_before_date", createdBeforeDate) + } + ) { + val connection = + requireNotNull( + it["current_wallet"]?.jsonObject?.get("withdrawal_requests") + ) { "withdrawal_requests not found" } + return@Query serializerFormat.decodeFromJsonElement(connection) + } + } + @JvmOverloads fun getTotalAmountSentQuery( createdAfterDate: Instant? = null, diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WalletToWithdrawalRequestsConnection.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WalletToWithdrawalRequestsConnection.kt new file mode 100644 index 00000000..18db3199 --- /dev/null +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WalletToWithdrawalRequestsConnection.kt @@ -0,0 +1,42 @@ +// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved +@file:Suppress("ktlint:standard:max-line-length") + +package com.lightspark.sdk.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * + * @param count The total count of objects in this connection, using the current filters. It is different from the number of objects returned in the current page (in the `entities` field). + * @param pageInfo An object that holds pagination information about the objects in this connection. + * @param entities The withdrawal requests for the current page of this connection. + */ +@Serializable +@SerialName("WalletToWithdrawalRequestsConnection") +data class WalletToWithdrawalRequestsConnection( + @SerialName("wallet_to_withdrawal_requests_connection_count") + override val count: Int, + @SerialName("wallet_to_withdrawal_requests_connection_page_info") + override val pageInfo: PageInfo, + @SerialName("wallet_to_withdrawal_requests_connection_entities") + val entities: List, +) : Connection { + companion object { + const val FRAGMENT = """ +fragment WalletToWithdrawalRequestsConnectionFragment on WalletToWithdrawalRequestsConnection { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + id + } +}""" + } +} diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WithdrawalRequest.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WithdrawalRequest.kt index de9ebe9a..30c9ef64 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WithdrawalRequest.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/model/WithdrawalRequest.kt @@ -18,11 +18,13 @@ import kotlinx.serialization.json.jsonObject * @param id The unique identifier of this entity across all Lightspark systems. Should be treated as an opaque string. * @param createdAt The date and time when the entity was first created. * @param updatedAt The date and time when the entity was last updated. + * @param requestedAmount The requested amount of money to be withdrawn. If the requested amount is -1, it means to withdraw all. * @param amount The amount of money that should be withdrawn in this request. * @param bitcoinAddress The bitcoin address where the funds should be sent. * @param withdrawalMode The strategy that should be used to withdraw the funds from the account. * @param status The current status of this withdrawal request. * @param estimatedAmount If the requested amount is `-1` (i.e. everything), this field may contain an estimate of the amount for the withdrawal. + * @param amountWithdrawn The actual amount that is withdrawn. It will be set once the request is completed. * @param completedAt The time at which this request was completed. * @param withdrawalId The withdrawal transaction that has been generated by this request. */ @@ -35,6 +37,8 @@ data class WithdrawalRequest( override val createdAt: Instant, @SerialName("withdrawal_request_updated_at") override val updatedAt: Instant, + @SerialName("withdrawal_request_requested_amount") + val requestedAmount: CurrencyAmount, @SerialName("withdrawal_request_amount") val amount: CurrencyAmount, @SerialName("withdrawal_request_bitcoin_address") @@ -45,6 +49,8 @@ data class WithdrawalRequest( val status: WithdrawalRequestStatus, @SerialName("withdrawal_request_estimated_amount") val estimatedAmount: CurrencyAmount? = null, + @SerialName("withdrawal_request_amount_withdrawn") + val amountWithdrawn: CurrencyAmount? = null, @SerialName("withdrawal_request_completed_at") val completedAt: Instant? = null, @SerialName("withdrawal_request_withdrawal") @@ -220,6 +226,14 @@ fragment WithdrawalRequestFragment on WithdrawalRequest { withdrawal_request_id: id withdrawal_request_created_at: created_at withdrawal_request_updated_at: updated_at + withdrawal_request_requested_amount: requested_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } withdrawal_request_amount: amount { type: __typename currency_amount_original_value: original_value @@ -236,6 +250,14 @@ fragment WithdrawalRequestFragment on WithdrawalRequest { currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded currency_amount_preferred_currency_value_approx: preferred_currency_value_approx } + withdrawal_request_amount_withdrawn: amount_withdrawn { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } withdrawal_request_bitcoin_address: bitcoin_address withdrawal_request_withdrawal_mode: withdrawal_mode withdrawal_request_status: status diff --git a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/util/SerializerFormat.kt b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/util/SerializerFormat.kt index ea092033..97da15a0 100644 --- a/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/util/SerializerFormat.kt +++ b/lightspark-sdk/src/commonMain/kotlin/com/lightspark/sdk/util/SerializerFormat.kt @@ -6,6 +6,7 @@ import com.lightspark.sdk.model.AccountToNodesConnection import com.lightspark.sdk.model.AccountToPaymentRequestsConnection import com.lightspark.sdk.model.AccountToTransactionsConnection import com.lightspark.sdk.model.AccountToWalletsConnection +import com.lightspark.sdk.model.AccountToWithdrawalRequestsConnection import com.lightspark.sdk.model.ApiToken import com.lightspark.sdk.model.Channel import com.lightspark.sdk.model.ChannelClosingTransaction @@ -42,6 +43,7 @@ import com.lightspark.sdk.model.UmaInvitation import com.lightspark.sdk.model.Wallet import com.lightspark.sdk.model.WalletToPaymentRequestsConnection import com.lightspark.sdk.model.WalletToTransactionsConnection +import com.lightspark.sdk.model.WalletToWithdrawalRequestsConnection import com.lightspark.sdk.model.Withdrawal import com.lightspark.sdk.model.WithdrawalRequest import kotlinx.serialization.json.Json @@ -57,12 +59,14 @@ private val serializerModule = subclass(AccountToPaymentRequestsConnection::class) subclass(AccountToTransactionsConnection::class) subclass(AccountToWalletsConnection::class) + subclass(AccountToWithdrawalRequestsConnection::class) subclass(IncomingPaymentToAttemptsConnection::class) subclass(LightsparkNodeToChannelsConnection::class) subclass(OutgoingPaymentAttemptToHopsConnection::class) subclass(OutgoingPaymentToAttemptsConnection::class) subclass(WalletToPaymentRequestsConnection::class) subclass(WalletToTransactionsConnection::class) + subclass(WalletToWithdrawalRequestsConnection::class) } polymorphic(Entity::class) { subclass(Account::class) diff --git a/umaserverdemo/src/main/kotlin/com/lightspark/Vasp2.kt b/umaserverdemo/src/main/kotlin/com/lightspark/Vasp2.kt index 598adae3..ea114f95 100644 --- a/umaserverdemo/src/main/kotlin/com/lightspark/Vasp2.kt +++ b/umaserverdemo/src/main/kotlin/com/lightspark/Vasp2.kt @@ -25,6 +25,9 @@ import me.uma.protocol.PayerDataOptions import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +// In real life, this would come from some actual exchange rate API. +private const val MSATS_PER_USD_CENT = 22883.56 + class Vasp2( private val config: UmaConfig, private val uma: UmaProtocolHelper, @@ -93,10 +96,10 @@ class Vasp2( code = "USD", name = "US Dollar", symbol = "$", - millisatoshiPerUnit = 34_150, + millisatoshiPerUnit = MSATS_PER_USD_CENT, minSendable = 1, maxSendable = 10_000_000, - displayDecimals = 2, + decimals = 2, ), ), receiverKycStatus = KycStatus.VERIFIED, @@ -188,7 +191,6 @@ class Vasp2( return "Invalid payreq signature." } - val conversionRate = 34_150L // In real life, this would come from some actual exchange rate API. val client = LightsparkCoroutinesClient( ClientConfig( serverUrl = config.clientBaseURL ?: "api.lightspark.com", @@ -203,7 +205,8 @@ class Vasp2( invoiceCreator = LightsparkClientUmaInvoiceCreator(client, config.nodeID, expirySecs), metadata = getEncodedMetadata(), currencyCode = "USD", - conversionRate = conversionRate, + currencyDecimals = 2, + conversionRate = MSATS_PER_USD_CENT, receiverFeesMillisats = 0, // TODO(Jeremy): Actually get the UTXOs from the request. receiverChannelUtxos = emptyList(), @@ -241,7 +244,7 @@ class Vasp2( private fun getUtxoCallback(call: ApplicationCall, txId: String): String { val protocol = call.request.origin.scheme val host = call.request.host() - val path = "/api/uma/utxoCallback?txId=${config.userID}" + val path = "/api/uma/utxoCallback?txId=${txId}" return "$protocol://$host$path" } diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Connection.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Connection.kt index 8309297f..8b8d4ba6 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Connection.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Connection.kt @@ -49,6 +49,20 @@ fragment ConnectionFragment on Connection { id } } + ... on WalletToWithdrawalRequestsConnection { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + id + } + } }""" } } diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Wallet.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Wallet.kt index 597ea92c..2e839fbc 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Wallet.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/Wallet.kt @@ -370,6 +370,94 @@ query FetchWalletToPaymentRequestsConnection(${'$'}first: Int, ${'$'}after: ID, } } + @JvmOverloads + fun getWithdrawalRequestsQuery( + first: Int? = null, + after: String? = null, + statuses: List? = null, + createdAfterDate: Instant? = null, + createdBeforeDate: Instant? = null, + ): Query { + return Query( + queryPayload = """ +query FetchWalletToWithdrawalRequestsConnection(${'$'}first: Int, ${'$'}after: ID, ${'$'}statuses: [WithdrawalRequestStatus!], ${'$'}created_after_date: DateTime, ${'$'}created_before_date: DateTime) { + current_wallet { + ... on Wallet { + withdrawal_requests(, first: ${'$'}first, after: ${'$'}after, statuses: ${'$'}statuses, created_after_date: ${'$'}created_after_date, created_before_date: ${'$'}created_before_date) { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + type: __typename + withdrawal_request_id: id + withdrawal_request_created_at: created_at + withdrawal_request_updated_at: updated_at + withdrawal_request_requested_amount: requested_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount: amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_estimated_amount: estimated_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_amount_withdrawn: amount_withdrawn { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } + withdrawal_request_bitcoin_address: bitcoin_address + withdrawal_request_status: status + withdrawal_request_completed_at: completed_at + withdrawal_request_withdrawal: withdrawal { + id + } + } + } + } + } +} +""", + variableBuilder = { + add("first", first) + add("after", after) + add("statuses", statuses) + add("created_after_date", createdAfterDate) + add("created_before_date", createdBeforeDate) + } + ) { + val connection = + requireNotNull( + it["current_wallet"]?.jsonObject?.get("withdrawal_requests") + ) { "withdrawal_requests not found" } + return@Query serializerFormat.decodeFromJsonElement(connection) + } + } + companion object { @JvmStatic fun getWalletQuery(): Query { diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WalletToWithdrawalRequestsConnection.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WalletToWithdrawalRequestsConnection.kt new file mode 100644 index 00000000..384ef1a3 --- /dev/null +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WalletToWithdrawalRequestsConnection.kt @@ -0,0 +1,42 @@ +// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved +@file:Suppress("ktlint:standard:max-line-length") + +package com.lightspark.sdk.wallet.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * + * @param count The total count of objects in this connection, using the current filters. It is different from the number of objects returned in the current page (in the `entities` field). + * @param pageInfo An object that holds pagination information about the objects in this connection. + * @param entities The withdrawal requests for the current page of this connection. + */ +@Serializable +@SerialName("WalletToWithdrawalRequestsConnection") +data class WalletToWithdrawalRequestsConnection( + @SerialName("wallet_to_withdrawal_requests_connection_count") + override val count: Int, + @SerialName("wallet_to_withdrawal_requests_connection_page_info") + override val pageInfo: PageInfo, + @SerialName("wallet_to_withdrawal_requests_connection_entities") + val entities: List, +) : Connection { + companion object { + const val FRAGMENT = """ +fragment WalletToWithdrawalRequestsConnectionFragment on WalletToWithdrawalRequestsConnection { + type: __typename + wallet_to_withdrawal_requests_connection_count: count + wallet_to_withdrawal_requests_connection_page_info: page_info { + type: __typename + page_info_has_next_page: has_next_page + page_info_has_previous_page: has_previous_page + page_info_start_cursor: start_cursor + page_info_end_cursor: end_cursor + } + wallet_to_withdrawal_requests_connection_entities: entities { + id + } +}""" + } +} diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WithdrawalRequest.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WithdrawalRequest.kt index 51c71290..bb6863bd 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WithdrawalRequest.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/model/WithdrawalRequest.kt @@ -16,10 +16,12 @@ import kotlinx.serialization.json.decodeFromJsonElement * @param id The unique identifier of this entity across all Lightspark systems. Should be treated as an opaque string. * @param createdAt The date and time when the entity was first created. * @param updatedAt The date and time when the entity was last updated. + * @param requestedAmount The requested amount of money to be withdrawn. If the requested amount is -1, it means to withdraw all. * @param amount The amount of money that should be withdrawn in this request. * @param bitcoinAddress The bitcoin address where the funds should be sent. * @param status The current status of this withdrawal request. * @param estimatedAmount If the requested amount is `-1` (i.e. everything), this field may contain an estimate of the amount for the withdrawal. + * @param amountWithdrawn The actual amount that is withdrawn. It will be set once the request is completed. * @param completedAt The time at which this request was completed. * @param withdrawalId The withdrawal transaction that has been generated by this request. */ @@ -32,6 +34,8 @@ data class WithdrawalRequest( override val createdAt: Instant, @SerialName("withdrawal_request_updated_at") override val updatedAt: Instant, + @SerialName("withdrawal_request_requested_amount") + val requestedAmount: CurrencyAmount, @SerialName("withdrawal_request_amount") val amount: CurrencyAmount, @SerialName("withdrawal_request_bitcoin_address") @@ -40,6 +44,8 @@ data class WithdrawalRequest( val status: WithdrawalRequestStatus, @SerialName("withdrawal_request_estimated_amount") val estimatedAmount: CurrencyAmount? = null, + @SerialName("withdrawal_request_amount_withdrawn") + val amountWithdrawn: CurrencyAmount? = null, @SerialName("withdrawal_request_completed_at") val completedAt: Instant? = null, @SerialName("withdrawal_request_withdrawal") @@ -73,6 +79,14 @@ fragment WithdrawalRequestFragment on WithdrawalRequest { withdrawal_request_id: id withdrawal_request_created_at: created_at withdrawal_request_updated_at: updated_at + withdrawal_request_requested_amount: requested_amount { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } withdrawal_request_amount: amount { type: __typename currency_amount_original_value: original_value @@ -89,6 +103,14 @@ fragment WithdrawalRequestFragment on WithdrawalRequest { currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded currency_amount_preferred_currency_value_approx: preferred_currency_value_approx } + withdrawal_request_amount_withdrawn: amount_withdrawn { + type: __typename + currency_amount_original_value: original_value + currency_amount_original_unit: original_unit + currency_amount_preferred_currency_unit: preferred_currency_unit + currency_amount_preferred_currency_value_rounded: preferred_currency_value_rounded + currency_amount_preferred_currency_value_approx: preferred_currency_value_approx + } withdrawal_request_bitcoin_address: bitcoin_address withdrawal_request_status: status withdrawal_request_completed_at: completed_at diff --git a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/util/SerializerFormat.kt b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/util/SerializerFormat.kt index 1e6b11a8..52d65ed6 100644 --- a/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/util/SerializerFormat.kt +++ b/wallet-sdk/src/commonMain/kotlin/com/lightspark/sdk/wallet/util/SerializerFormat.kt @@ -21,6 +21,7 @@ import com.lightspark.sdk.wallet.model.Transaction import com.lightspark.sdk.wallet.model.Wallet import com.lightspark.sdk.wallet.model.WalletToPaymentRequestsConnection import com.lightspark.sdk.wallet.model.WalletToTransactionsConnection +import com.lightspark.sdk.wallet.model.WalletToWithdrawalRequestsConnection import com.lightspark.sdk.wallet.model.Withdrawal import com.lightspark.sdk.wallet.model.WithdrawalRequest import kotlinx.serialization.json.Json @@ -33,6 +34,7 @@ private val serializerModule = polymorphic(Connection::class) { subclass(WalletToPaymentRequestsConnection::class) subclass(WalletToTransactionsConnection::class) + subclass(WalletToWithdrawalRequestsConnection::class) } polymorphic(Entity::class) { subclass(ChannelClosingTransaction::class)