gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-android] branch master updated (f5213b2 -> 77cd01b)


From: gnunet
Subject: [taler-taler-android] branch master updated (f5213b2 -> 77cd01b)
Date: Wed, 22 Feb 2023 18:32:49 +0100

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a change to branch master
in repository taler-android.

    from f5213b2  Give gradle more memory, because CI saw OOM errors
     new 0bcaad2  [wallet] Fix action bar title for sending peer payments
     new 6e99207  [wallet] show fees for peer push debit
     new 77cd01b  [wallet] show fees for peer pull credit

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../main/java/net/taler/wallet/MainViewModel.kt    |  2 +-
 .../java/net/taler/wallet/ReceiveFundsFragment.kt  |  2 +
 .../java/net/taler/wallet/SendFundsFragment.kt     | 10 +--
 .../net/taler/wallet/exchanges/ExchangeManager.kt  | 14 +++-
 .../net/taler/wallet/peer/OutgoingPullFragment.kt  | 27 ++++----
 .../wallet/peer/OutgoingPullIntroComposable.kt     | 79 +++++++++++++---------
 .../wallet/peer/OutgoingPullResultComposable.kt    |  4 +-
 .../net/taler/wallet/peer/OutgoingPushFragment.kt  | 21 +++---
 .../wallet/peer/OutgoingPushIntroComposable.kt     | 51 ++++++++------
 .../wallet/peer/OutgoingPushResultComposable.kt    |  4 +-
 .../java/net/taler/wallet/peer/OutgoingState.kt    | 21 ++++++
 .../main/java/net/taler/wallet/peer/PeerManager.kt | 48 +++++++++++++
 12 files changed, 196 insertions(+), 87 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt 
b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index 255c28b..ed12533 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -99,7 +99,7 @@ class MainViewModel(val app: Application) : 
AndroidViewModel(app) {
     val transactionManager: TransactionManager = TransactionManager(api, 
viewModelScope)
     val refundManager = RefundManager(api, viewModelScope)
     val exchangeManager: ExchangeManager = ExchangeManager(api, viewModelScope)
-    val peerManager: PeerManager = PeerManager(api, viewModelScope)
+    val peerManager: PeerManager = PeerManager(api, exchangeManager, 
viewModelScope)
     val settingsManager: SettingsManager = 
SettingsManager(app.applicationContext, viewModelScope)
     val accountManager: AccountManager = AccountManager(api, viewModelScope)
     val depositManager: DepositManager = DepositManager(api, viewModelScope)
diff --git a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt 
b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
index 4fbb09b..0e362ac 100644
--- a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
@@ -62,6 +62,7 @@ import net.taler.wallet.exchanges.ExchangeItem
 class ReceiveFundsFragment : Fragment() {
     private val model: MainViewModel by activityViewModels()
     private val exchangeManager get() = model.exchangeManager
+    private val peerManager get() = model.peerManager
 
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?,
@@ -107,6 +108,7 @@ class ReceiveFundsFragment : Fragment() {
 
     private fun onPeerPull(amount: Amount) {
         val bundle = bundleOf("amount" to amount.toJSONString())
+        peerManager.checkPeerPullCredit(amount)
         
findNavController().navigate(R.id.action_receiveFunds_to_nav_peer_pull, bundle)
     }
 }
diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt 
b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
index 7ae7773..c2680d5 100644
--- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
@@ -82,18 +82,14 @@ class SendFundsFragment : Fragment() {
         activity?.setTitle(R.string.transactions_send_funds)
     }
 
-    override fun onDestroy() {
-        super.onDestroy()
-        if (!requireActivity().isChangingConfigurations) 
peerManager.resetPushPayment()
-    }
-
-    fun onDeposit(amount: Amount) {
+    private fun onDeposit(amount: Amount) {
         val bundle = bundleOf("amount" to amount.toJSONString())
         findNavController().navigate(R.id.action_sendFunds_to_nav_deposit, 
bundle)
     }
 
-    fun onPeerPush(amount: Amount) {
+    private fun onPeerPush(amount: Amount) {
         val bundle = bundleOf("amount" to amount.toJSONString())
+        peerManager.checkPeerPushDebit(amount)
         findNavController().navigate(R.id.action_sendFunds_to_nav_peer_push, 
bundle)
     }
 }
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt 
b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
index 5a4c6c2..4a57068 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
@@ -17,6 +17,7 @@
 package net.taler.wallet.exchanges
 
 import android.util.Log
+import androidx.annotation.WorkerThread
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import kotlinx.coroutines.CoroutineScope
@@ -81,13 +82,20 @@ class ExchangeManager(
     }
 
     fun findExchangeForCurrency(currency: String): Flow<ExchangeItem?> = flow {
-        val response = api.request("listExchanges", 
ExchangeListResponse.serializer())
+        emit(findExchange(currency))
+    }
+
+    @WorkerThread
+    suspend fun findExchange(currency: String): ExchangeItem? {
         var exchange: ExchangeItem? = null
-        response.onSuccess { exchangeListResponse ->
+        api.request(
+            operation = "listExchanges",
+            serializer = ExchangeListResponse.serializer()
+        ).onSuccess { exchangeListResponse ->
             // just pick the first for now
             exchange = exchangeListResponse.exchanges.find { it.currency == 
currency }
         }
-        emit(exchange)
+        return exchange
     }
 
 }
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
index 9f579e2..cccae0f 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullFragment.kt
@@ -44,22 +44,21 @@ class OutgoingPullFragment : Fragment() {
         val amount = arguments?.getString("amount")?.let {
             Amount.fromJSONString(it)
         } ?: error("no amount passed")
-        val exchangeFlow = 
exchangeManager.findExchangeForCurrency(amount.currency)
         return ComposeView(requireContext()).apply {
             setContent {
                 TalerSurface {
-                    val state = 
peerManager.pullState.collectAsStateLifecycleAware()
-                    if (state.value is OutgoingIntro) {
-                        val exchangeState =
-                            exchangeFlow.collectAsStateLifecycleAware(initial 
= null)
-                        OutgoingPullIntroComposable(
-                            amount = amount,
-                            exchangeState = exchangeState,
-                            onCreateInvoice = 
this@OutgoingPullFragment::onCreateInvoice,
-                        )
-                    } else {
-                        OutgoingPullResultComposable(state.value) {
-                            findNavController().popBackStack()
+                    when (val state = 
peerManager.pullState.collectAsStateLifecycleAware().value) {
+                        is OutgoingIntro, OutgoingChecking, is OutgoingChecked 
-> {
+                            OutgoingPullIntroComposable(
+                                amount = amount,
+                                state = state,
+                                onCreateInvoice = 
this@OutgoingPullFragment::onCreateInvoice,
+                            )
+                        }
+                        OutgoingCreating, is OutgoingResponse, is 
OutgoingError -> {
+                            OutgoingPullResultComposable(state) {
+                                findNavController().popBackStack()
+                            }
                         }
                     }
                 }
@@ -69,7 +68,7 @@ class OutgoingPullFragment : Fragment() {
 
     override fun onStart() {
         super.onStart()
-        activity?.setTitle(R.string.receive_peer_title)
+        activity?.setTitle(R.string.send_peer_title)
     }
 
     override fun onDestroy() {
diff --git 
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
index 6d74ba6..a7cd2a8 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullIntroComposable.kt
@@ -16,21 +16,19 @@
 
 package net.taler.wallet.peer
 
-import android.annotation.SuppressLint
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
 import androidx.compose.foundation.verticalScroll
-import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Button
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.OutlinedTextField
 import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.State
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -41,34 +39,36 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.colorResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
 import net.taler.common.Amount
 import net.taler.wallet.R
 import net.taler.wallet.cleanExchange
 import net.taler.wallet.exchanges.ExchangeItem
+import net.taler.wallet.transactions.AmountType
+import net.taler.wallet.transactions.TransactionAmountComposable
+import net.taler.wallet.transactions.TransactionInfoComposable
+import kotlin.random.Random
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun OutgoingPullIntroComposable(
     amount: Amount,
-    exchangeState: State<ExchangeItem?>,
+    state: OutgoingState,
     onCreateInvoice: (amount: Amount, subject: String, exchange: ExchangeItem) 
-> Unit,
 ) {
     val scrollState = rememberScrollState()
     Column(
         modifier = Modifier
             .fillMaxWidth()
+            .padding(16.dp)
             .verticalScroll(scrollState),
         horizontalAlignment = CenterHorizontally,
     ) {
         var subject by rememberSaveable { mutableStateOf("") }
         val focusRequester = remember { FocusRequester() }
-        val exchangeItem = exchangeState.value
         OutlinedTextField(
             modifier = Modifier
                 .fillMaxWidth()
@@ -101,30 +101,33 @@ fun OutgoingPullIntroComposable(
             text = stringResource(R.string.char_count, subject.length, 
MAX_LENGTH_SUBJECT),
             textAlign = TextAlign.End,
         )
-        Text(
-            modifier = Modifier.padding(horizontal = 16.dp),
-            text = stringResource(id = R.string.amount_chosen),
+        TransactionAmountComposable(
+            label = stringResource(id = R.string.amount_chosen),
+            amount = amount,
+            amountType = AmountType.Positive,
         )
-        Text(
-            modifier = Modifier.padding(16.dp),
-            fontSize = 24.sp,
-            color = colorResource(R.color.green),
-            text = amount.toString(),
-        )
-        Text(
-            modifier = Modifier.padding(horizontal = 16.dp),
-            text = stringResource(R.string.withdraw_exchange),
-        )
-        Text(
-            modifier = Modifier.padding(16.dp),
-            fontSize = 24.sp,
-            text = if (exchangeItem == null) "" else 
cleanExchange(exchangeItem.exchangeBaseUrl),
+        if (state is OutgoingChecked) {
+            val fee = state.amountRaw - state.amountEffective
+            if (!fee.isZero()) TransactionAmountComposable(
+                label = stringResource(id = R.string.withdraw_fees),
+                amount = fee,
+                amountType = AmountType.Negative,
+            )
+        }
+        val exchangeItem = (state as? OutgoingChecked)?.exchangeItem
+        TransactionInfoComposable(
+            label = stringResource(id = R.string.withdraw_exchange),
+            info = if (exchangeItem == null) "" else 
cleanExchange(exchangeItem.exchangeBaseUrl),
         )
         Button(
             modifier = Modifier.padding(16.dp),
-            enabled = subject.isNotBlank() && exchangeItem != null,
+            enabled = subject.isNotBlank() && state is OutgoingChecked,
             onClick = {
-                onCreateInvoice(amount, subject, exchangeItem ?: 
error("clickable without exchange"))
+                onCreateInvoice(
+                    amount,
+                    subject,
+                    exchangeItem ?: error("clickable without exchange")
+                )
             },
         ) {
             Text(text = stringResource(R.string.receive_peer_create_button))
@@ -134,11 +137,25 @@ fun OutgoingPullIntroComposable(
 
 @Preview
 @Composable
-fun PreviewReceiveFundsIntro() {
+fun PreviewReceiveFundsCheckingIntro() {
+    Surface {
+        OutgoingPullIntroComposable(
+            Amount.fromDouble("TESTKUDOS", 42.23),
+            if (Random.nextBoolean()) OutgoingIntro else OutgoingChecking,
+        ) { _, _, _ -> }
+    }
+}
+
+@Preview
+@Composable
+fun PreviewReceiveFundsCheckedIntro() {
     Surface {
-        @SuppressLint("UnrememberedMutableState")
-        val exchangeFlow =
-            mutableStateOf(ExchangeItem("https://example.org";, "TESTKUDOS", 
emptyList()))
-        OutgoingPullIntroComposable(Amount.fromDouble("TESTKUDOS", 42.23), 
exchangeFlow) { _, _, _ -> }
+        val amountRaw = Amount.fromDouble("TESTKUDOS", 42.42)
+        val amountEffective = Amount.fromDouble("TESTKUDOS", 42.23)
+        val exchangeItem = ExchangeItem("https://example.org";, "TESTKUDOS", 
emptyList())
+        OutgoingPullIntroComposable(
+            Amount.fromDouble("TESTKUDOS", 42.23),
+            OutgoingChecked(amountRaw, amountEffective, exchangeItem)
+        ) { _, _, _ -> }
     }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
index e6d9ec9..de62cda 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPullResultComposable.kt
@@ -58,7 +58,9 @@ fun OutgoingPullResultComposable(state: OutgoingState, 
onClose: () -> Unit) {
             text = stringResource(id = 
R.string.receive_peer_invoice_instruction),
         )
         when (state) {
-            OutgoingIntro -> error("Result composable with PullPaymentIntro")
+            OutgoingIntro, OutgoingChecking, is OutgoingChecked -> {
+                error("Result composable with ${state::class.simpleName}")
+            }
             is OutgoingCreating -> PeerPullCreatingComposable()
             is OutgoingResponse -> PeerPullResponseComposable(state)
             is OutgoingError -> PeerPullErrorComposable(state)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
index b7a510c..a844b85 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushFragment.kt
@@ -45,15 +45,18 @@ class OutgoingPushFragment : Fragment() {
         return ComposeView(requireContext()).apply {
             setContent {
                 TalerSurface {
-                    val state = 
peerManager.pushState.collectAsStateLifecycleAware()
-                    if (state.value is OutgoingIntro) {
-                        OutgoingPushIntroComposable(
-                            amount = amount,
-                            onSend = this@OutgoingPushFragment::onSend,
-                        )
-                    } else {
-                        OutgoingPushResultComposable(state.value) {
-                            findNavController().popBackStack()
+                    when (val state = 
peerManager.pushState.collectAsStateLifecycleAware().value) {
+                        is OutgoingIntro, OutgoingChecking, is OutgoingChecked 
-> {
+                            OutgoingPushIntroComposable(
+                                state = state,
+                                amount = amount,
+                                onSend = this@OutgoingPushFragment::onSend,
+                            )
+                        }
+                        OutgoingCreating, is OutgoingResponse, is 
OutgoingError -> {
+                            OutgoingPushResultComposable(state) {
+                                findNavController().popBackStack()
+                            }
                         }
                     }
                 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
index 7fd7c8b..33e8390 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushIntroComposable.kt
@@ -16,8 +16,8 @@
 
 package net.taler.wallet.peer
 
+import androidx.compose.foundation.layout.Arrangement.spacedBy
 import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.rememberScrollState
@@ -33,7 +33,6 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Alignment.Companion.CenterHorizontally
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -43,10 +42,12 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import net.taler.common.Amount
 import net.taler.wallet.R
+import kotlin.random.Random
 
 @OptIn(ExperimentalMaterial3Api::class)
 @Composable
 fun OutgoingPushIntroComposable(
+    state: OutgoingState,
     amount: Amount,
     onSend: (amount: Amount, summary: String) -> Unit,
 ) {
@@ -54,27 +55,28 @@ fun OutgoingPushIntroComposable(
     Column(
         modifier = Modifier
             .fillMaxWidth()
+            .padding(16.dp)
             .verticalScroll(scrollState),
         horizontalAlignment = CenterHorizontally,
+        verticalArrangement = spacedBy(16.dp),
     ) {
-        Row(
-            verticalAlignment = Alignment.CenterVertically,
-            modifier = Modifier
-                .padding(16.dp),
-        ) {
+        Text(
+            text = amount.toString(),
+            softWrap = false,
+            style = MaterialTheme.typography.titleLarge,
+        )
+        if (state is OutgoingChecked) {
+            val fee = state.amountEffective - state.amountRaw
             Text(
-                modifier = Modifier,
-                text = amount.toString(),
+                text = stringResource(id = R.string.payment_fee, fee),
                 softWrap = false,
-                style = MaterialTheme.typography.titleLarge,
+                color = MaterialTheme.colorScheme.error,
             )
         }
 
         var subject by rememberSaveable { mutableStateOf("") }
         OutlinedTextField(
-            modifier = Modifier
-                .fillMaxWidth()
-                .padding(horizontal = 16.dp),
+            modifier = Modifier.fillMaxWidth(),
             singleLine = true,
             value = subject,
             onValueChange = { input ->
@@ -93,19 +95,16 @@ fun OutgoingPushIntroComposable(
         )
         Text(
             modifier = Modifier
-                .fillMaxWidth()
-                .padding(top = 5.dp, end = 16.dp),
+                .fillMaxWidth(),
             color = if (subject.isBlank()) MaterialTheme.colorScheme.error 
else Color.Unspecified,
             text = stringResource(R.string.char_count, subject.length, 
MAX_LENGTH_SUBJECT),
             textAlign = TextAlign.End,
         )
         Text(
-            modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 
16.dp),
             text = stringResource(R.string.send_peer_warning),
         )
         Button(
-            modifier = Modifier.padding(16.dp),
-            enabled = subject.isNotBlank(),
+            enabled = state is OutgoingChecked && subject.isNotBlank(),
             onClick = {
                 onSend(amount, subject)
             },
@@ -117,8 +116,20 @@ fun OutgoingPushIntroComposable(
 
 @Preview
 @Composable
-fun PeerPushIntroComposablePreview() {
+fun PeerPushIntroComposableCheckingPreview() {
+    Surface {
+        val state = if (Random.nextBoolean()) OutgoingIntro else 
OutgoingChecking
+        OutgoingPushIntroComposable(state, Amount.fromDouble("TESTKUDOS", 
42.23)) { _, _ -> }
+    }
+}
+
+@Preview
+@Composable
+fun PeerPushIntroComposableCheckedPreview() {
     Surface {
-        OutgoingPushIntroComposable(Amount.fromDouble("TESTKUDOS", 42.23)) { 
_, _ -> }
+        val amountEffective = Amount.fromDouble("TESTKUDOS", 42.42)
+        val amountRaw = Amount.fromDouble("TESTKUDOS", 42.23)
+        val state = OutgoingChecked(amountRaw, amountEffective)
+        OutgoingPushIntroComposable(state, amountEffective) { _, _ -> }
     }
 }
diff --git 
a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
index 0fb3f2c..0a4ee70 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingPushResultComposable.kt
@@ -58,7 +58,9 @@ fun OutgoingPushResultComposable(state: OutgoingState, 
onClose: () -> Unit) {
             text = stringResource(id = R.string.send_peer_payment_instruction),
         )
         when (state) {
-            OutgoingIntro -> error("Result composable with PullPaymentIntro")
+            OutgoingIntro, OutgoingChecking, is OutgoingChecked -> {
+                error("Result composable with ${state::class.simpleName}")
+            }
             is OutgoingCreating -> PeerPushCreatingComposable()
             is OutgoingResponse -> PeerPushResponseComposable(state)
             is OutgoingError -> PeerPushErrorComposable(state)
diff --git a/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt 
b/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
index e40ddb8..5673417 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/OutgoingState.kt
@@ -18,10 +18,18 @@ package net.taler.wallet.peer
 
 import android.graphics.Bitmap
 import kotlinx.serialization.Serializable
+import net.taler.common.Amount
 import net.taler.wallet.backend.TalerErrorInfo
+import net.taler.wallet.exchanges.ExchangeItem
 
 sealed class OutgoingState
 object OutgoingIntro : OutgoingState()
+object OutgoingChecking : OutgoingState()
+data class OutgoingChecked(
+    val amountRaw: Amount,
+    val amountEffective: Amount,
+    val exchangeItem: ExchangeItem? = null,
+) : OutgoingState()
 object OutgoingCreating : OutgoingState()
 data class OutgoingResponse(
     val talerUri: String,
@@ -32,6 +40,13 @@ data class OutgoingError(
     val info: TalerErrorInfo,
 ) : OutgoingState()
 
+@Serializable
+data class CheckPeerPullCreditResponse(
+    val exchangeBaseUrl: String,
+    val amountRaw: Amount,
+    val amountEffective: Amount,
+)
+
 @Serializable
 data class InitiatePeerPullPaymentResponse(
     /**
@@ -40,6 +55,12 @@ data class InitiatePeerPullPaymentResponse(
     val talerUri: String,
 )
 
+@Serializable
+data class CheckPeerPushDebitResponse(
+    val amountRaw: Amount,
+    val amountEffective: Amount,
+)
+
 @Serializable
 data class InitiatePeerPullCreditResponse(
     val exchangeBaseUrl: String,
diff --git a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt 
b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
index 5b38e2f..f031d44 100644
--- a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt
@@ -28,8 +28,11 @@ import net.taler.common.Amount
 import net.taler.common.QrCodeManager
 import net.taler.common.Timestamp
 import net.taler.wallet.TAG
+import net.taler.wallet.backend.TalerErrorCode.UNKNOWN
+import net.taler.wallet.backend.TalerErrorInfo
 import net.taler.wallet.backend.WalletBackendApi
 import net.taler.wallet.exchanges.ExchangeItem
+import net.taler.wallet.exchanges.ExchangeManager
 import org.json.JSONObject
 import java.util.concurrent.TimeUnit.DAYS
 
@@ -37,6 +40,7 @@ const val MAX_LENGTH_SUBJECT = 100
 
 class PeerManager(
     private val api: WalletBackendApi,
+    private val exchangeManager: ExchangeManager,
     private val scope: CoroutineScope,
 ) {
 
@@ -52,6 +56,32 @@ class PeerManager(
     private val _incomingPushState = 
MutableStateFlow<IncomingState>(IncomingChecking)
     val incomingPushState: StateFlow<IncomingState> = _incomingPushState
 
+    fun checkPeerPullCredit(amount: Amount) {
+        _outgoingPullState.value = OutgoingChecking
+        scope.launch(Dispatchers.IO) {
+            val exchangeItem = exchangeManager.findExchange(amount.currency)
+            if (exchangeItem == null) {
+                _outgoingPullState.value = OutgoingError(
+                    TalerErrorInfo(UNKNOWN, "No exchange found for 
${amount.currency}")
+                )
+                return@launch
+            }
+            api.request("checkPeerPullCredit", 
CheckPeerPullCreditResponse.serializer()) {
+                put("exchangeBaseUrl", exchangeItem.exchangeBaseUrl)
+                put("amount", amount.toJSONString())
+            }.onSuccess {
+                _outgoingPullState.value = OutgoingChecked(
+                    amountRaw = it.amountRaw,
+                    amountEffective = it.amountEffective,
+                    exchangeItem = exchangeItem,
+                )
+            }.onError { error ->
+                Log.e(TAG, "got checkPeerPullCredit error result $error")
+                _outgoingPullState.value = OutgoingError(error)
+            }
+        }
+    }
+
     fun initiatePeerPullCredit(amount: Amount, summary: String, exchange: 
ExchangeItem) {
         _outgoingPullState.value = OutgoingCreating
         scope.launch(Dispatchers.IO) {
@@ -77,6 +107,24 @@ class PeerManager(
         _outgoingPullState.value = OutgoingIntro
     }
 
+    fun checkPeerPushDebit(amount: Amount) {
+        _outgoingPushState.value = OutgoingChecking
+        scope.launch(Dispatchers.IO) {
+            api.request("checkPeerPushDebit", 
CheckPeerPushDebitResponse.serializer()) {
+                put("amount", amount.toJSONString())
+            }.onSuccess { response ->
+                _outgoingPushState.value = OutgoingChecked(
+                    amountRaw = response.amountRaw,
+                    amountEffective = response.amountEffective,
+                    // FIXME add exchangeItem once available in API
+                )
+            }.onError { error ->
+                Log.e(TAG, "got checkPeerPushDebit error result $error")
+                _outgoingPushState.value = OutgoingError(error)
+            }
+        }
+    }
+
     fun initiatePeerPushDebit(amount: Amount, summary: String) {
         _outgoingPushState.value = OutgoingCreating
         scope.launch(Dispatchers.IO) {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]