[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.
- [taler-taler-android] branch master updated (f5213b2 -> 77cd01b),
gnunet <=