diff options
author | Torsten Grote <t@grobox.de> | 2020-08-03 15:04:18 -0300 |
---|---|---|
committer | Torsten Grote <t@grobox.de> | 2020-08-03 15:04:18 -0300 |
commit | e3fb6f93d05b8d8148cc3958b59bc16741fc32f9 (patch) | |
tree | 563171f01b4c87b82d8b8c10c14320ac875f008b | |
parent | 33ab2485b984787a2eb774e407b413b9d7c62116 (diff) | |
download | wallet-kotlin-e3fb6f93d05b8d8148cc3958b59bc16741fc32f9.tar.gz wallet-kotlin-e3fb6f93d05b8d8148cc3958b59bc16741fc32f9.tar.bz2 wallet-kotlin-e3fb6f93d05b8d8148cc3958b59bc16741fc32f9.zip |
Implement beginning of public API for iOS test
5 files changed, 172 insertions, 9 deletions
diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/Version.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/Version.kt index 457fb07..45e7840 100644 --- a/src/commonMain/kotlin/net/taler/wallet/kotlin/Version.kt +++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/Version.kt @@ -69,3 +69,10 @@ fun parseVersion(v: String): Version? { if (current == null || revision == null || age == null) return null return Version(current, revision, age) } + +class SupportedVersions( + val walletVersion: Version, + val exchangeVersion: Version, + val bankVersion: Version, + val merchantVersion: Version +) diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/WalletApi.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/WalletApi.kt new file mode 100644 index 0000000..61a3a1a --- /dev/null +++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/WalletApi.kt @@ -0,0 +1,54 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.wallet.kotlin + +import net.taler.wallet.kotlin.operations.Withdraw +import net.taler.wallet.kotlin.operations.WithdrawalDetails +import net.taler.wallet.kotlin.operations.WithdrawalDetailsForUri + +public class WalletApi { + + private val withdrawManager = Withdraw() + + public fun getVersions(): SupportedVersions { + return SupportedVersions( + walletVersion = Version(8, 0, 0), + exchangeVersion = Version(8, 0, 0), + bankVersion = Version(0, 0, 0), + merchantVersion = Version(1, 0, 0) + ) + } + + public suspend fun getWithdrawalDetailsForUri(talerWithdrawUri: String): WithdrawalDetailsForUri { + val bankInfo = withdrawManager.getBankInfo(talerWithdrawUri) + return WithdrawalDetailsForUri( + amount = bankInfo.amount, + defaultExchangeBaseUrl = bankInfo.suggestedExchange, + possibleExchanges = emptyList() + ) + } + + public suspend fun getWithdrawalDetailsForAmount(exchangeBaseUrl: String, amount: Amount): WithdrawalDetails { + val details = withdrawManager.getWithdrawalDetails(exchangeBaseUrl, amount) + return WithdrawalDetails( + tosAccepted = details.exchange.termsOfServiceAccepted, + amountRaw = amount, + amountEffective = amount - details.overhead - details.withdrawFee + ) + } + +} diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/exchange/Exchange.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/exchange/Exchange.kt index e4a99b7..3af430f 100644 --- a/src/commonMain/kotlin/net/taler/wallet/kotlin/exchange/Exchange.kt +++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/exchange/Exchange.kt @@ -53,7 +53,7 @@ internal class Exchange( ) { companion object { - private const val PROTOCOL_VERSION = "7:0:0" + private const val PROTOCOL_VERSION = "8:0:0" fun getVersionMatch(version: String) = compareVersions(PROTOCOL_VERSION, version) fun normalizeUrl(exchangeBaseUrl: String): String { var url = exchangeBaseUrl diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt index 1173140..3981012 100644 --- a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt +++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt @@ -88,8 +88,10 @@ internal class Withdraw( } suspend fun getBankInfo(talerWithdrawUri: String): BankDetails { - val uriResult = parseWithdrawUri(talerWithdrawUri) ?: throw Error("Can't parse URI $talerWithdrawUri") - val url = "${uriResult.bankIntegrationApiBaseUrl}api/withdraw-operation/${uriResult.withdrawalOperationId}" + val uriResult = + parseWithdrawUri(talerWithdrawUri) ?: throw Error("Can't parse URI $talerWithdrawUri") + val url = + "${uriResult.bankIntegrationApiBaseUrl}api/withdraw-operation/${uriResult.withdrawalOperationId}" val response: Response = httpClient.get(url) return response.toBankDetails(url) } @@ -161,12 +163,16 @@ internal class Withdraw( } - internal suspend fun getWithdrawalDetails(exchangeBaseUrl: String, amount: Amount): WithdrawalDetails { + internal suspend fun getWithdrawalDetails( + exchangeBaseUrl: String, + amount: Amount + ): WithdrawalDetails { val exchange = exchange.updateFromUrl(exchangeBaseUrl) check(exchange.details != null) check(exchange.wireInfo != null) val selectedDenominations = selectDenominations(exchange, amount) - val possibleDenominations = db.getDenominationsByBaseUrl(exchangeBaseUrl).filter { it.isOffered } + val possibleDenominations = + db.getDenominationsByBaseUrl(exchangeBaseUrl).filter { it.isOffered } // TODO determine trust and audit status return WithdrawalDetails( exchange = exchange, @@ -182,8 +188,12 @@ internal class Withdraw( * Get a list of denominations to withdraw from the given exchange for the given amount, * making sure that all denominations' signatures are verified. */ - internal suspend fun selectDenominations(exchange: ExchangeRecord, amount: Amount): DenominationSelectionInfo { - val exchangeDetails = exchange.details ?: throw Error("Exchange $exchange details not available.") + internal suspend fun selectDenominations( + exchange: ExchangeRecord, + amount: Amount + ): DenominationSelectionInfo { + val exchangeDetails = + exchange.details ?: throw Error("Exchange $exchange details not available.") val possibleDenominations = getPossibleDenominations(exchange.baseUrl) val selectedDenominations = getDenominationSelection(amount, possibleDenominations) @@ -191,7 +201,10 @@ internal class Withdraw( for (selectedDenomination in selectedDenominations.selectedDenominations) { var denomination = selectedDenomination.denominationRecord if (denomination.status == Unverified) { - val valid = signature.verifyDenominationRecord(denomination, exchangeDetails.masterPublicKey) + val valid = signature.verifyDenominationRecord( + denomination, + exchangeDetails.masterPublicKey + ) denomination = if (!valid) { denomination.copy(status = VerifiedBad) } else { @@ -217,7 +230,10 @@ internal class Withdraw( * * Note that this algorithm does not try to optimize withdrawal fees. */ - fun getDenominationSelection(amount: Amount, denoms: List<DenominationRecord>): DenominationSelectionInfo { + fun getDenominationSelection( + amount: Amount, + denoms: List<DenominationRecord> + ): DenominationSelectionInfo { val selectedDenominations = ArrayList<SelectedDenomination>() var totalCoinValue = Amount.zero(amount.currency) var totalWithdrawCost = Amount.zero(amount.currency) @@ -252,3 +268,43 @@ internal class Withdraw( } } + +data class WithdrawalDetailsForUri( + /** + * The amount that the user wants to withdraw + */ + val amount: Amount, + + /** + * Exchange suggested by the wallet + */ + val defaultExchangeBaseUrl: String?, + + /** + * A list of exchanges that can be used for this withdrawal + */ + val possibleExchanges: List<ExchangeListItem> +) + +data class ExchangeListItem( + val exchangeBaseUrl: String, + val currency: String, + val paytoUris: List<String> +) + +data class WithdrawalDetails( + /** + * Did the user accept the current version of the exchange's terms of service? + */ + val tosAccepted: Boolean, + + /** + * Amount that will be transferred to the exchange. + */ + val amountRaw: Amount, + + /** + * Amount that will be added to the user's wallet balance. + */ + val amountEffective: Amount +) diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/WalletApiTest.kt b/src/commonTest/kotlin/net/taler/wallet/kotlin/WalletApiTest.kt new file mode 100644 index 0000000..9498792 --- /dev/null +++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/WalletApiTest.kt @@ -0,0 +1,46 @@ +/* + * This file is part of GNU Taler + * (C) 2020 Taler Systems S.A. + * + * GNU Taler is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 3, or (at your option) any later version. + * + * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +package net.taler.wallet.kotlin + +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertEquals + +@Ignore // Live-Test +class WalletApiTest { + + private val api = WalletApi() + + @Test + fun testGetVersions() { + api.getVersions() + } + + @Test + fun testGetWithdrawalDetails() = runCoroutine { + val detailsForUri = + api.getWithdrawalDetailsForUri("taler://withdraw/bank.test.taler.net/8adabbf8-fe61-4d31-a2d1-89350b5be8fa") + assertEquals(Amount("TESTKUDOS", 5, 0), detailsForUri.amount) + assertEquals("https://exchange.test.taler.net/", detailsForUri.defaultExchangeBaseUrl) + + val detailsForAmount = + api.getWithdrawalDetailsForAmount(detailsForUri.defaultExchangeBaseUrl!!, detailsForUri.amount) + assertEquals(Amount("TESTKUDOS", 5, 0), detailsForAmount.amountRaw) + assertEquals(Amount("TESTKUDOS", 4, 80000000), detailsForAmount.amountEffective) + } + +} |