summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/withdraw
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-07-29 14:12:50 -0300
committerTorsten Grote <t@grobox.de>2020-07-29 16:17:46 -0300
commite19ba096d57353db6b1f141da4bf170ef2d2d534 (patch)
tree8ce7d138757a73f999f8e270e69cef44aa2f781b /wallet/src/main/java/net/taler/wallet/withdraw
parentbc35e8924e652c323001f62f6781657545fa378f (diff)
downloadtaler-android-e19ba096d57353db6b1f141da4bf170ef2d2d534.tar.gz
taler-android-e19ba096d57353db6b1f141da4bf170ef2d2d534.tar.bz2
taler-android-e19ba096d57353db6b1f141da4bf170ef2d2d534.zip
[wallet] update to new wallet-core with v8 exchange API
(except payments which are still buggy)
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/withdraw')
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/ExchangeFees.kt95
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt26
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt2
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/SelectExchangeFragment.kt142
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt227
6 files changed, 126 insertions, 368 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ExchangeFees.kt b/wallet/src/main/java/net/taler/wallet/withdraw/ExchangeFees.kt
deleted file mode 100644
index 9c815c9..0000000
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ExchangeFees.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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.withdraw
-
-import net.taler.common.Amount
-import net.taler.common.Timestamp
-import org.json.JSONObject
-
-data class CoinFee(
- val coin: Amount,
- val quantity: Int,
- val feeDeposit: Amount,
- val feeRefresh: Amount,
- val feeRefund: Amount,
- val feeWithdraw: Amount
-)
-
-data class WireFee(
- val start: Timestamp,
- val end: Timestamp,
- val wireFee: Amount,
- val closingFee: Amount
-)
-
-data class ExchangeFees(
- val withdrawFee: Amount,
- val overhead: Amount,
- val earliestDepositExpiration: Timestamp,
- val coinFees: List<CoinFee>,
- val wireFees: List<WireFee>
-) {
- companion object {
- fun fromExchangeWithdrawDetailsJson(json: JSONObject): ExchangeFees {
- val earliestDepositExpiration =
- json.getJSONObject("earliestDepositExpiration").getLong("t_ms")
- val selectedDenoms = json.getJSONObject("selectedDenoms")
- val denoms = selectedDenoms.getJSONArray("selectedDenoms")
- val coinFees = ArrayList<CoinFee>(denoms.length())
- for (i in 0 until denoms.length()) {
- val denom = denoms.getJSONObject(i)
- val d = denom.getJSONObject("denom")
- val coinFee = CoinFee(
- coin = Amount.fromJsonObject(d.getJSONObject("value")),
- quantity = denom.getInt("count"),
- feeDeposit = Amount.fromJsonObject(d.getJSONObject("feeDeposit")),
- feeRefresh = Amount.fromJsonObject(d.getJSONObject("feeRefresh")),
- feeRefund = Amount.fromJsonObject(d.getJSONObject("feeRefund")),
- feeWithdraw = Amount.fromJsonObject(d.getJSONObject("feeWithdraw"))
- )
- coinFees.add(coinFee)
- }
-
- val wireFeesJson = json.getJSONObject("wireFees")
- val feesForType = wireFeesJson.getJSONObject("feesForType")
- val bankFees = feesForType.getJSONArray("x-taler-bank")
- val wireFees = ArrayList<WireFee>(bankFees.length())
- for (i in 0 until bankFees.length()) {
- val fee = bankFees.getJSONObject(i)
- val startStamp =
- fee.getJSONObject("startStamp").getLong("t_ms")
- val endStamp =
- fee.getJSONObject("endStamp").getLong("t_ms")
- val wireFee = WireFee(
- start = Timestamp(startStamp),
- end = Timestamp(endStamp),
- wireFee = Amount.fromJsonObject(fee.getJSONObject("wireFee")),
- closingFee = Amount.fromJsonObject(fee.getJSONObject("closingFee"))
- )
- wireFees.add(wireFee)
- }
-
- return ExchangeFees(
- withdrawFee = Amount.fromJsonObject(json.getJSONObject("withdrawFee")),
- overhead = Amount.fromJsonObject(json.getJSONObject("overhead")),
- earliestDepositExpiration = Timestamp(earliestDepositExpiration),
- coinFees = coinFees,
- wireFees = wireFees
- )
- }
- }
-}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
index 55f931d..9788d1c 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/ManualWithdrawFragment.kt
@@ -60,7 +60,7 @@ class ManualWithdrawFragment : Fragment() {
val amount = Amount(exchangeItem.currency, value, 0)
amountView.hideKeyboard()
Toast.makeText(view.context, "Not implemented: $amount", LENGTH_SHORT).show()
- withdrawManager.getWithdrawalDetails(exchangeItem, amount)
+ withdrawManager.getWithdrawalDetails(exchangeItem.exchangeBaseUrl, amount)
}
}
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
index 331554b..5a98a89 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/PromptWithdrawFragment.kt
@@ -20,6 +20,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Toast
+import android.widget.Toast.LENGTH_SHORT
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
@@ -34,7 +36,7 @@ import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.cleanExchange
import net.taler.wallet.withdraw.WithdrawStatus.Loading
-import net.taler.wallet.withdraw.WithdrawStatus.TermsOfServiceReviewRequired
+import net.taler.wallet.withdraw.WithdrawStatus.TosReviewRequired
import net.taler.wallet.withdraw.WithdrawStatus.Withdrawing
class PromptWithdrawFragment : Fragment() {
@@ -59,17 +61,13 @@ class PromptWithdrawFragment : Fragment() {
private fun showWithdrawStatus(status: WithdrawStatus?): Any = when (status) {
is WithdrawStatus.ReceivedDetails -> {
- showContent(status.amount, status.fee, status.exchange)
+ showContent(status.amountRaw, status.amountEffective, status.exchangeBaseUrl)
confirmWithdrawButton.apply {
text = getString(R.string.withdraw_button_confirm)
setOnClickListener {
it.fadeOut()
confirmProgressBar.fadeIn()
- withdrawManager.acceptWithdrawal(
- status.talerWithdrawUri,
- status.exchange,
- status.amount.currency
- )
+ withdrawManager.acceptWithdrawal()
}
isEnabled = true
}
@@ -87,8 +85,8 @@ class PromptWithdrawFragment : Fragment() {
is Withdrawing -> {
model.showProgressBar.value = true
}
- is TermsOfServiceReviewRequired -> {
- showContent(status.amount, status.fee, status.exchange)
+ is TosReviewRequired -> {
+ showContent(status.amountRaw, status.amountEffective, status.exchangeBaseUrl)
confirmWithdrawButton.apply {
text = getString(R.string.withdraw_button_tos)
setOnClickListener {
@@ -104,20 +102,20 @@ class PromptWithdrawFragment : Fragment() {
null -> model.showProgressBar.value = false
}
- private fun showContent(amount: Amount, fee: Amount, exchange: String) {
+ private fun showContent(amountRaw: Amount, amountEffective: Amount, exchange: String) {
model.showProgressBar.value = false
progressBar.fadeOut()
introView.fadeIn()
- effectiveAmountView.text = (amount - fee).toString()
+ effectiveAmountView.text = amountEffective.toString()
effectiveAmountView.fadeIn()
chosenAmountLabel.fadeIn()
- chosenAmountView.text = amount.toString()
+ chosenAmountView.text = amountRaw.toString()
chosenAmountView.fadeIn()
feeLabel.fadeIn()
- feeView.text = getString(R.string.amount_negative, fee.toString())
+ feeView.text = getString(R.string.amount_negative, (amountRaw - amountEffective).toString())
feeView.fadeIn()
exchangeIntroView.fadeIn()
@@ -125,7 +123,7 @@ class PromptWithdrawFragment : Fragment() {
withdrawExchangeUrl.fadeIn()
selectExchangeButton.fadeIn()
selectExchangeButton.setOnClickListener {
- findNavController().navigate(R.id.action_promptWithdraw_to_selectExchangeFragment)
+ Toast.makeText(context, "Not yet implemented", LENGTH_SHORT).show()
}
withdrawCard.fadeIn()
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
index ffaef5a..db1f326 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/ReviewExchangeTosFragment.kt
@@ -55,7 +55,7 @@ class ReviewExchangeTosFragment : Fragment() {
}
withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer {
when (it) {
- is WithdrawStatus.TermsOfServiceReviewRequired -> {
+ is WithdrawStatus.TosReviewRequired -> {
val sections = try {
// TODO remove next line once exchange delivers proper markdown
val text = it.tosText.replace("****************", "================")
diff --git a/wallet/src/main/java/net/taler/wallet/withdraw/SelectExchangeFragment.kt b/wallet/src/main/java/net/taler/wallet/withdraw/SelectExchangeFragment.kt
deleted file mode 100644
index 2ade9f2..0000000
--- a/wallet/src/main/java/net/taler/wallet/withdraw/SelectExchangeFragment.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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.withdraw
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.View.GONE
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.core.content.ContextCompat.getColor
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.recyclerview.widget.RecyclerView.Adapter
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import kotlinx.android.synthetic.main.fragment_select_exchange.*
-import net.taler.common.Amount
-import net.taler.common.toRelativeTime
-import net.taler.common.toShortDate
-import net.taler.wallet.MainViewModel
-import net.taler.wallet.R
-import net.taler.wallet.withdraw.CoinFeeAdapter.CoinFeeViewHolder
-import net.taler.wallet.withdraw.WireFeeAdapter.WireFeeViewHolder
-
-class SelectExchangeFragment : Fragment() {
-
- private val model: MainViewModel by activityViewModels()
- private val withdrawManager by lazy { model.withdrawManager }
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- return inflater.inflate(R.layout.fragment_select_exchange, container, false)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val fees = withdrawManager.exchangeFees ?: throw IllegalStateException()
- if (fees.withdrawFee.isZero()) {
- withdrawFeeLabel.visibility = GONE
- withdrawFeeView.visibility = GONE
- } else withdrawFeeView.setAmount(fees.withdrawFee)
- if (fees.overhead.isZero()) {
- overheadLabel.visibility = GONE
- overheadView.visibility = GONE
- } else overheadView.setAmount(fees.overhead)
- expirationView.text = fees.earliestDepositExpiration.ms.toRelativeTime(requireContext())
- coinFeesList.adapter = CoinFeeAdapter(fees.coinFees)
- wireFeesList.adapter = WireFeeAdapter(fees.wireFees)
- }
-
- private fun TextView.setAmount(amount: Amount) {
- if (amount.isZero()) text = amount.toString()
- else {
- text = getString(R.string.amount_negative, amount)
- setTextColor(getColor(context, R.color.red))
- }
- }
-
-}
-
-private class CoinFeeAdapter(private val items: List<CoinFee>) : Adapter<CoinFeeViewHolder>() {
- override fun getItemCount() = items.size
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CoinFeeViewHolder {
- val v =
- LayoutInflater.from(parent.context).inflate(R.layout.list_item_coin_fee, parent, false)
- return CoinFeeViewHolder(v)
- }
-
- override fun onBindViewHolder(holder: CoinFeeViewHolder, position: Int) {
- holder.bind(items[position])
- }
-
- private class CoinFeeViewHolder(private val v: View) : ViewHolder(v) {
- private val res = v.context.resources
- private val coinView: TextView = v.findViewById(R.id.coinView)
- private val withdrawFeeView: TextView = v.findViewById(R.id.withdrawFeeView)
- private val depositFeeView: TextView = v.findViewById(R.id.depositFeeView)
- private val refreshFeeView: TextView = v.findViewById(R.id.refreshFeeView)
- private val refundFeeView: TextView = v.findViewById(R.id.refundFeeView)
- fun bind(item: CoinFee) {
- coinView.text = res.getQuantityString(
- R.plurals.exchange_fee_coin,
- item.quantity,
- item.coin,
- item.quantity
- )
- withdrawFeeView.text =
- v.context.getString(R.string.exchange_fee_withdraw_fee, item.feeWithdraw)
- depositFeeView.text =
- v.context.getString(R.string.exchange_fee_deposit_fee, item.feeDeposit)
- refreshFeeView.text =
- v.context.getString(R.string.exchange_fee_refresh_fee, item.feeRefresh)
- refundFeeView.text =
- v.context.getString(R.string.exchange_fee_refund_fee, item.feeRefresh)
- }
- }
-}
-
-private class WireFeeAdapter(private val items: List<WireFee>) : Adapter<WireFeeViewHolder>() {
- override fun getItemCount() = items.size
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WireFeeViewHolder {
- val v =
- LayoutInflater.from(parent.context).inflate(R.layout.list_item_wire_fee, parent, false)
- return WireFeeViewHolder(v)
- }
-
- override fun onBindViewHolder(holder: WireFeeViewHolder, position: Int) {
- holder.bind(items[position])
- }
-
- private class WireFeeViewHolder(private val v: View) : ViewHolder(v) {
- private val validityView: TextView = v.findViewById(R.id.validityView)
- private val wireFeeView: TextView = v.findViewById(R.id.wireFeeView)
- private val closingFeeView: TextView = v.findViewById(R.id.closingFeeView)
- fun bind(item: WireFee) {
- validityView.text = v.context.getString(
- R.string.exchange_fee_wire_fee_timespan,
- item.start.ms.toShortDate(v.context),
- item.end.ms.toShortDate(v.context)
- )
- wireFeeView.text =
- v.context.getString(R.string.exchange_fee_wire_fee_wire_fee, item.wireFee)
- closingFeeView.text =
- v.context.getString(R.string.exchange_fee_wire_fee_closing_fee, item.closingFee)
- }
- }
-}
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)
+ }
+
}