summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt')
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt227
1 files changed, 112 insertions, 115 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
index ea65e7c..e14a747 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
@@ -17,38 +17,57 @@
package net.taler.wallet.withdraw
import android.util.Log
+import androidx.annotation.UiThread
import androidx.lifecycle.MutableLiveData
+import com.fasterxml.jackson.databind.ObjectMapper
+import com.fasterxml.jackson.module.kotlin.readValue
import net.taler.common.Amount
import net.taler.wallet.TAG
import net.taler.wallet.backend.WalletBackendApi
+import net.taler.wallet.exchanges.ExchangeFees
import net.taler.wallet.exchanges.ExchangeItem
import net.taler.wallet.withdraw.WithdrawStatus.ReceivedDetails
import org.json.JSONObject
sealed class WithdrawStatus {
- data class Loading(val talerWithdrawUri: String) : WithdrawStatus()
- data class TermsOfServiceReviewRequired(
- val talerWithdrawUri: String,
- val exchange: String,
+ data class Loading(val talerWithdrawUri: String? = null) : WithdrawStatus()
+ data class TosReviewRequired(
+ val talerWithdrawUri: String? = null,
+ val exchangeBaseUrl: String,
+ val amountRaw: Amount,
+ val amountEffective: Amount,
val tosText: String,
- val tosEtag: String,
- val amount: Amount,
- val fee: Amount
+ val tosEtag: String
) : WithdrawStatus()
data class ReceivedDetails(
- val talerWithdrawUri: String,
- val exchange: String,
- val amount: Amount,
- val fee: Amount
+ val talerWithdrawUri: String? = null,
+ val exchangeBaseUrl: String,
+ val amountRaw: Amount,
+ val amountEffective: Amount
) : WithdrawStatus()
- data class Withdrawing(val talerWithdrawUri: String) : WithdrawStatus()
+ object Withdrawing : WithdrawStatus()
data class Success(val currency: String) : WithdrawStatus()
data class Error(val message: String?) : WithdrawStatus()
}
-class WithdrawManager(private val walletBackendApi: WalletBackendApi) {
+data class WithdrawalDetailsForUri(
+ val amount: Amount,
+ val defaultExchangeBaseUrl: String?,
+ val possibleExchanges: List<ExchangeItem>
+)
+
+data class WithdrawalDetails(
+ val tosAccepted: Boolean,
+ val amountRaw: Amount,
+ val amountEffective: Amount
+)
+
+class WithdrawManager(
+ private val walletBackendApi: WalletBackendApi,
+ private val mapper: ObjectMapper
+) {
val withdrawStatus = MutableLiveData<WithdrawStatus>()
val testWithdrawalInProgress = MutableLiveData(false)
@@ -58,149 +77,127 @@ class WithdrawManager(private val walletBackendApi: WalletBackendApi) {
fun withdrawTestkudos() {
testWithdrawalInProgress.value = true
-
- walletBackendApi.sendRequest("withdrawTestkudos", null) { _, _ ->
+ walletBackendApi.sendRequest("withdrawTestkudos") { _, _ ->
testWithdrawalInProgress.postValue(false)
}
}
- fun getWithdrawalDetails(exchangeItem: ExchangeItem, amount: Amount) {
+ fun getWithdrawalDetails(uri: String) {
+ withdrawStatus.value = WithdrawStatus.Loading(uri)
val args = JSONObject().apply {
- put("exchangeBaseUrl", exchangeItem.exchangeBaseUrl)
- put("amount", amount.toJSONString())
+ put("talerWithdrawUri", uri)
}
- walletBackendApi.sendRequest("getWithdrawalDetailsForAmount", args) { isError, result ->
- // {"rawAmount":"TESTKUDOS:5","effectiveAmount":"TESTKUDOS:4.8","paytoUris":["payto:\/\/x-taler-bank\/bank.test.taler.net\/Exchange"],"tosAccepted":false}
+ walletBackendApi.sendRequest("getWithdrawalDetailsForUri", args) { isError, result ->
if (isError) {
- Log.e(TAG, "$result")
+ handleError("getWithdrawalDetailsForUri", result)
+ return@sendRequest
+ }
+ val details: WithdrawalDetailsForUri = mapper.readValue(result.toString())
+ if (details.defaultExchangeBaseUrl == null) {
+ // TODO go to exchange selection screen instead
+ val chosenExchange = details.possibleExchanges[0].exchangeBaseUrl
+ getWithdrawalDetails(chosenExchange, details.amount, uri)
} else {
- Log.e(TAG, "$result")
+ getWithdrawalDetails(details.defaultExchangeBaseUrl, details.amount, uri)
}
}
}
- fun getWithdrawalInfo(talerWithdrawUri: String) {
+ fun getWithdrawalDetails(exchangeBaseUrl: String, amount: Amount, uri: String? = null) {
+ withdrawStatus.value = WithdrawStatus.Loading(uri)
val args = JSONObject().apply {
- put("talerWithdrawUri", talerWithdrawUri)
+ put("exchangeBaseUrl", exchangeBaseUrl)
+ put("amount", amount.toJSONString())
}
- withdrawStatus.value = WithdrawStatus.Loading(talerWithdrawUri)
-
- walletBackendApi.sendRequest("getWithdrawDetailsForUri", args) { isError, result ->
+ walletBackendApi.sendRequest("getWithdrawalDetailsForAmount", args) { isError, result ->
if (isError) {
- Log.e(TAG, "Error getWithdrawDetailsForUri ${result.toString(4)}")
- val message = if (result.has("message")) result.getString("message") else null
- withdrawStatus.postValue(WithdrawStatus.Error(message))
+ handleError("getWithdrawalDetailsForAmount", result)
return@sendRequest
}
- Log.v(TAG, "got getWithdrawDetailsForUri result")
- val status = withdrawStatus.value
- if (status !is WithdrawStatus.Loading) {
- Log.v(TAG, "ignoring withdrawal info result, not loading.")
- return@sendRequest
- }
- val wi = result.getJSONObject("bankWithdrawDetails")
- val suggestedExchange = wi.getString("suggestedExchange")
- // We just use the suggested exchange, in the future there will be
- // a selection dialog.
- getWithdrawalInfoWithExchange(talerWithdrawUri, suggestedExchange)
+ val details: WithdrawalDetails = mapper.readValue(result.toString())
+ if (details.tosAccepted)
+ withdrawStatus.value = ReceivedDetails(
+ talerWithdrawUri = uri,
+ exchangeBaseUrl = exchangeBaseUrl,
+ amountRaw = details.amountRaw,
+ amountEffective = details.amountEffective
+ )
+ else getExchangeTos(exchangeBaseUrl, details, uri)
}
}
- private fun getWithdrawalInfoWithExchange(talerWithdrawUri: String, selectedExchange: String) {
+ private fun getExchangeTos(exchangeBaseUrl: String, details: WithdrawalDetails, uri: String?) {
val args = JSONObject().apply {
- put("talerWithdrawUri", talerWithdrawUri)
- put("selectedExchange", selectedExchange)
+ put("exchangeBaseUrl", exchangeBaseUrl)
}
-
- walletBackendApi.sendRequest("getWithdrawDetailsForUri", args) { isError, result ->
+ walletBackendApi.sendRequest("getExchangeTos", args) { isError, result ->
if (isError) {
- Log.e(TAG, "Error getWithdrawDetailsForUri ${result.toString(4)}")
- val message = if (result.has("message")) result.getString("message") else null
- withdrawStatus.postValue(WithdrawStatus.Error(message))
- return@sendRequest
- }
- Log.v(TAG, "got getWithdrawDetailsForUri result (with exchange details)")
- val status = withdrawStatus.value
- if (status !is WithdrawStatus.Loading) {
- Log.w(TAG, "ignoring withdrawal info result, not loading.")
+ handleError("getExchangeTos", result)
return@sendRequest
}
- val wi = result.getJSONObject("bankWithdrawDetails")
- val amount = Amount.fromJsonObject(wi.getJSONObject("amount"))
-
- val ei = result.getJSONObject("exchangeWithdrawDetails")
- val termsOfServiceAccepted = ei.getBoolean("termsOfServiceAccepted")
-
- exchangeFees = ExchangeFees.fromExchangeWithdrawDetailsJson(ei)
-
- val withdrawFee = Amount.fromJsonObject(ei.getJSONObject("withdrawFee"))
- val overhead = Amount.fromJsonObject(ei.getJSONObject("overhead"))
- val fee = withdrawFee + overhead
-
- if (!termsOfServiceAccepted) {
- val exchange = ei.getJSONObject("exchangeInfo")
- val tosText = exchange.getString("termsOfServiceText")
- val tosEtag = exchange.optString("termsOfServiceLastEtag", "undefined")
- withdrawStatus.postValue(
- WithdrawStatus.TermsOfServiceReviewRequired(
- status.talerWithdrawUri,
- selectedExchange, tosText, tosEtag,
- amount, fee
- )
- )
- } else {
- withdrawStatus.postValue(
- ReceivedDetails(
- status.talerWithdrawUri,
- selectedExchange, amount,
- fee
- )
- )
- }
+ withdrawStatus.value = WithdrawStatus.TosReviewRequired(
+ talerWithdrawUri = uri,
+ exchangeBaseUrl = exchangeBaseUrl,
+ amountRaw = details.amountRaw,
+ amountEffective = details.amountEffective,
+ tosText = result.getString("tos"),
+ tosEtag = result.getString("currentEtag")
+ )
}
}
- fun acceptWithdrawal(talerWithdrawUri: String, selectedExchange: String, currency: String) {
- val args = JSONObject()
- args.put("talerWithdrawUri", talerWithdrawUri)
- args.put("selectedExchange", selectedExchange)
-
- withdrawStatus.value = WithdrawStatus.Withdrawing(talerWithdrawUri)
-
- walletBackendApi.sendRequest("acceptWithdrawal", args) { isError, result ->
+ /**
+ * Accept the currently displayed terms of service.
+ */
+ fun acceptCurrentTermsOfService() {
+ val s = withdrawStatus.value as WithdrawStatus.TosReviewRequired
+ val args = JSONObject().apply {
+ put("exchangeBaseUrl", s.exchangeBaseUrl)
+ put("etag", s.tosEtag)
+ }
+ walletBackendApi.sendRequest("setExchangeTosAccepted", args) { isError, result ->
if (isError) {
- Log.v(TAG, "got acceptWithdrawal error result: ${result.toString(2)}")
- return@sendRequest
- }
- Log.v(TAG, "got acceptWithdrawal result")
- val status = withdrawStatus.value
- if (status !is WithdrawStatus.Withdrawing) {
- Log.w(TAG, "ignoring acceptWithdrawal result, invalid state: $status")
+ handleError("setExchangeTosAccepted", result)
return@sendRequest
}
- withdrawStatus.postValue(WithdrawStatus.Success(currency))
+ withdrawStatus.value = ReceivedDetails(
+ talerWithdrawUri = s.talerWithdrawUri,
+ exchangeBaseUrl = s.exchangeBaseUrl,
+ amountRaw = s.amountRaw,
+ amountEffective = s.amountEffective
+ )
}
}
- /**
- * Accept the currently displayed terms of service.
- */
- fun acceptCurrentTermsOfService() {
- val s = withdrawStatus.value
- check(s is WithdrawStatus.TermsOfServiceReviewRequired)
+ @UiThread
+ fun acceptWithdrawal() {
+ val status = withdrawStatus.value as ReceivedDetails
+ val operation = if (status.talerWithdrawUri == null)
+ "acceptManualWithdrawal" else "acceptBankIntegratedWithdrawal"
val args = JSONObject().apply {
- put("exchangeBaseUrl", s.exchange)
- put("etag", s.tosEtag)
+ put("exchangeBaseUrl", status.exchangeBaseUrl)
+ if (status.talerWithdrawUri == null) {
+ put("amount", status.amountRaw)
+ } else {
+ put("talerWithdrawUri", status.talerWithdrawUri)
+ }
}
- walletBackendApi.sendRequest("acceptExchangeTermsOfService", args) { isError, result ->
+ withdrawStatus.value = WithdrawStatus.Withdrawing
+ walletBackendApi.sendRequest(operation, args) { isError, result ->
if (isError) {
- Log.e(TAG, "Error acceptExchangeTermsOfService ${result.toString(4)}")
+ handleError(operation, result)
return@sendRequest
}
- val status = ReceivedDetails(s.talerWithdrawUri, s.exchange, s.amount, s.fee)
- withdrawStatus.postValue(status)
+ withdrawStatus.value = WithdrawStatus.Success(status.amountRaw.currency)
}
}
+ @UiThread
+ private fun handleError(operation: String, result: JSONObject) {
+ Log.e(TAG, "Error $operation ${result.toString(2)}")
+ val message = if (result.has("message")) result.getString("message") else null
+ withdrawStatus.value = WithdrawStatus.Error(message)
+ }
+
}