diff options
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt')
-rw-r--r-- | wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt | 119 |
1 files changed, 89 insertions, 30 deletions
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 1e53e7c..5bd2b0b 100644 --- a/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt +++ b/wallet/src/main/java/net/taler/wallet/peer/PeerManager.kt @@ -22,15 +22,25 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json 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.HOURS + +const val MAX_LENGTH_SUBJECT = 100 +val DEFAULT_EXPIRY = ExpirationOption.DAYS_1 class PeerManager( private val api: WalletBackendApi, + private val exchangeManager: ExchangeManager, private val scope: CoroutineScope, ) { @@ -46,20 +56,47 @@ class PeerManager( private val _incomingPushState = MutableStateFlow<IncomingState>(IncomingChecking) val incomingPushState: StateFlow<IncomingState> = _incomingPushState - fun initiatePullPayment(amount: Amount, summary: String, exchange: ExchangeItem) { + 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, expirationHours: Long, exchange: ExchangeItem) { _outgoingPullState.value = OutgoingCreating scope.launch(Dispatchers.IO) { - api.request("initiatePeerPullPayment", InitiatePeerPullPaymentResponse.serializer()) { + val expiry = Timestamp.fromMillis(System.currentTimeMillis() + HOURS.toMillis(expirationHours)) + api.request("initiatePeerPullCredit", InitiatePeerPullPaymentResponse.serializer()) { put("exchangeBaseUrl", exchange.exchangeBaseUrl) - put("amount", amount.toJSONString()) put("partialContractTerms", JSONObject().apply { + put("amount", amount.toJSONString()) put("summary", summary) + put("purse_expiration", JSONObject(Json.encodeToString(expiry))) }) }.onSuccess { - val qrCode = QrCodeManager.makeQrCode(it.talerUri) - _outgoingPullState.value = OutgoingResponse(it.talerUri, qrCode) + _outgoingPullState.value = OutgoingResponse(it.transactionId) }.onError { error -> - Log.e(TAG, "got initiatePeerPullPayment error result $error") + Log.e(TAG, "got initiatePeerPullCredit error result $error") _outgoingPullState.value = OutgoingError(error) } } @@ -69,19 +106,39 @@ class PeerManager( _outgoingPullState.value = OutgoingIntro } - fun initiatePeerPushPayment(amount: Amount, summary: String) { + 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, expirationHours: Long) { _outgoingPushState.value = OutgoingCreating scope.launch(Dispatchers.IO) { - api.request("initiatePeerPushPayment", InitiatePeerPushPaymentResponse.serializer()) { + val expiry = Timestamp.fromMillis(System.currentTimeMillis() + HOURS.toMillis(expirationHours)) + api.request("initiatePeerPushDebit", InitiatePeerPushDebitResponse.serializer()) { put("amount", amount.toJSONString()) put("partialContractTerms", JSONObject().apply { + put("amount", amount.toJSONString()) put("summary", summary) + put("purse_expiration", JSONObject(Json.encodeToString(expiry))) }) }.onSuccess { response -> - val qrCode = QrCodeManager.makeQrCode(response.talerUri) - _outgoingPushState.value = OutgoingResponse(response.talerUri, qrCode) + _outgoingPushState.value = OutgoingResponse(response.transactionId) }.onError { error -> - Log.e(TAG, "got initiatePeerPushPayment error result $error") + Log.e(TAG, "got initiatePeerPushDebit error result $error") _outgoingPushState.value = OutgoingError(error) } } @@ -91,65 +148,67 @@ class PeerManager( _outgoingPushState.value = OutgoingIntro } - fun checkPeerPullPayment(talerUri: String) { + fun preparePeerPullDebit(talerUri: String) { _incomingPullState.value = IncomingChecking scope.launch(Dispatchers.IO) { - api.request("checkPeerPullPayment", CheckPeerPullPaymentResponse.serializer()) { + api.request("preparePeerPullDebit", PreparePeerPullDebitResponse.serializer()) { put("talerUri", talerUri) }.onSuccess { response -> _incomingPullState.value = IncomingTerms( - amount = response.amount, + amountRaw = response.amountRaw, + amountEffective = response.amountEffective, contractTerms = response.contractTerms, - id = response.peerPullPaymentIncomingId, + id = response.transactionId, ) }.onError { error -> - Log.e(TAG, "got checkPeerPushPayment error result $error") + Log.e(TAG, "got preparePeerPullDebit error result $error") _incomingPullState.value = IncomingError(error) } } } - fun acceptPeerPullPayment(terms: IncomingTerms) { + fun confirmPeerPullDebit(terms: IncomingTerms) { _incomingPullState.value = IncomingAccepting(terms) scope.launch(Dispatchers.IO) { - api.request<Unit>("acceptPeerPullPayment") { - put("peerPullPaymentIncomingId", terms.id) + api.request<Unit>("confirmPeerPullDebit") { + put("transactionId", terms.id) }.onSuccess { _incomingPullState.value = IncomingAccepted }.onError { error -> - Log.e(TAG, "got checkPeerPushPayment error result $error") + Log.e(TAG, "got confirmPeerPullDebit error result $error") _incomingPullState.value = IncomingError(error) } } } - fun checkPeerPushPayment(talerUri: String) { + fun preparePeerPushCredit(talerUri: String) { _incomingPushState.value = IncomingChecking scope.launch(Dispatchers.IO) { - api.request("checkPeerPushPayment", CheckPeerPushPaymentResponse.serializer()) { + api.request("preparePeerPushCredit", PreparePeerPushCreditResponse.serializer()) { put("talerUri", talerUri) }.onSuccess { response -> _incomingPushState.value = IncomingTerms( - amount = response.amount, + amountRaw = response.amountRaw, + amountEffective = response.amountEffective, contractTerms = response.contractTerms, - id = response.peerPushPaymentIncomingId, + id = response.transactionId, ) }.onError { error -> - Log.e(TAG, "got checkPeerPushPayment error result $error") + Log.e(TAG, "got preparePeerPushCredit error result $error") _incomingPushState.value = IncomingError(error) } } } - fun acceptPeerPushPayment(terms: IncomingTerms) { + fun confirmPeerPushCredit(terms: IncomingTerms) { _incomingPushState.value = IncomingAccepting(terms) scope.launch(Dispatchers.IO) { - api.request<Unit>("acceptPeerPushPayment") { - put("peerPushPaymentIncomingId", terms.id) + api.request<Unit>("confirmPeerPushCredit") { + put("transactionId", terms.id) }.onSuccess { _incomingPushState.value = IncomingAccepted }.onError { error -> - Log.e(TAG, "got checkPeerPushPayment error result $error") + Log.e(TAG, "got confirmPeerPushCredit error result $error") _incomingPushState.value = IncomingError(error) } } |