summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt')
-rw-r--r--wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt128
1 files changed, 121 insertions, 7 deletions
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 8205eb7..fa357b5 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeManager.kt
@@ -17,24 +17,34 @@
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
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.serialization.Serializable
import net.taler.common.Event
import net.taler.common.toEvent
import net.taler.wallet.TAG
+import net.taler.wallet.backend.TalerErrorInfo
import net.taler.wallet.backend.WalletBackendApi
@Serializable
data class ExchangeListResponse(
- val exchanges: List<ExchangeItem>
+ val exchanges: List<ExchangeItem>,
+)
+
+@Serializable
+data class ExchangeDetailedResponse(
+ val exchange: ExchangeItem,
)
class ExchangeManager(
private val api: WalletBackendApi,
- private val scope: CoroutineScope
+ private val scope: CoroutineScope,
) {
private val mProgress = MutableLiveData<Boolean>()
@@ -43,8 +53,17 @@ class ExchangeManager(
private val mExchanges = MutableLiveData<List<ExchangeItem>>()
val exchanges: LiveData<List<ExchangeItem>> get() = list()
- private val mAddError = MutableLiveData<Event<Boolean>>()
- val addError: LiveData<Event<Boolean>> = mAddError
+ private val mAddError = MutableLiveData<Event<TalerErrorInfo>>()
+ val addError: LiveData<Event<TalerErrorInfo>> = mAddError
+
+ private val mListError = MutableLiveData<Event<TalerErrorInfo>>()
+ val listError: LiveData<Event<TalerErrorInfo>> = mListError
+
+ private val mDeleteError = MutableLiveData<Event<TalerErrorInfo>>()
+ val deleteError: LiveData<Event<TalerErrorInfo>> = mDeleteError
+
+ private val mReloadError = MutableLiveData<Event<TalerErrorInfo>>()
+ val reloadError: LiveData<Event<TalerErrorInfo>> = mReloadError
var withdrawalExchange: ExchangeItem? = null
@@ -53,7 +72,8 @@ class ExchangeManager(
scope.launch {
val response = api.request("listExchanges", ExchangeListResponse.serializer())
response.onError {
- throw AssertionError("Wallet core failed to return exchanges!")
+ mProgress.value = false
+ mListError.value = it.toEvent()
}.onSuccess {
Log.d(TAG, "Exchange list: ${it.exchanges}")
mProgress.value = false
@@ -68,9 +88,9 @@ class ExchangeManager(
api.request<Unit>("addExchange") {
put("exchangeBaseUrl", exchangeUrl)
}.onError {
- mProgress.value = false
Log.e(TAG, "Error adding exchange: $it")
- mAddError.value = true.toEvent()
+ mProgress.value = false
+ mAddError.value = it.toEvent()
}.onSuccess {
mProgress.value = false
Log.d(TAG, "Exchange $exchangeUrl added")
@@ -78,4 +98,98 @@ class ExchangeManager(
}
}
+ fun reload(exchangeUrl: String, force: Boolean = true) = scope.launch {
+ mProgress.value = true
+ api.request<Unit>("updateExchangeEntry") {
+ put("exchangeBaseUrl", exchangeUrl)
+ put("force", force)
+ }.onError {
+ Log.e(TAG, "Error reloading exchange: $it")
+ mProgress.value = false
+ mReloadError.value = it.toEvent()
+ }.onSuccess {
+ mProgress.value = false
+ Log.d(TAG, "Exchange $exchangeUrl reloaded")
+ list()
+ }
+ }
+
+ fun delete(exchangeUrl: String, purge: Boolean = false) = scope.launch {
+ mProgress.value = true
+ api.request<Unit>("deleteExchange") {
+ put("exchangeBaseUrl", exchangeUrl)
+ put("purge", purge)
+ }.onError {
+ Log.e(TAG, "Error deleting exchange: $it")
+ mProgress.value = false
+ mDeleteError.value = it.toEvent()
+ }.onSuccess {
+ mProgress.value = false
+ Log.d(TAG, "Exchange $exchangeUrl deleted")
+ list()
+ }
+ }
+
+ fun findExchangeForCurrency(currency: String): Flow<ExchangeItem?> = flow {
+ emit(findExchange(currency))
+ }
+
+ @WorkerThread
+ suspend fun findExchange(currency: String): ExchangeItem? {
+ var exchange: ExchangeItem? = null
+ api.request(
+ operation = "listExchanges",
+ serializer = ExchangeListResponse.serializer()
+ ).onSuccess { exchangeListResponse ->
+ // just pick the first for now
+ exchange = exchangeListResponse.exchanges.find { it.currency == currency }
+ }
+ return exchange
+ }
+
+ @WorkerThread
+ suspend fun findExchangeByUrl(exchangeUrl: String): ExchangeItem? {
+ var exchange: ExchangeItem? = null
+ api.request("getExchangeDetailedInfo", ExchangeDetailedResponse.serializer()) {
+ put("exchangeBaseUrl", exchangeUrl)
+ }.onError {
+ Log.e(TAG, "Error getExchangeDetailedInfo: $it")
+ }.onSuccess {
+ exchange = it.exchange
+ }
+ return exchange
+ }
+
+ fun addDevExchanges() {
+ scope.launch {
+ listOf(
+ "https://exchange.demo.taler.net/",
+ "https://exchange.test.taler.net/",
+ "https://exchange.head.taler.net/",
+ "https://exchange.taler.ar/",
+ "https://exchange.taler.fdold.eu/",
+ "https://exchange.taler.grothoff.org/",
+ ).forEach { exchangeUrl ->
+ add(exchangeUrl)
+ delay(100)
+ }
+ exchanges.value?.let { exs ->
+ exs.find {
+ it.exchangeBaseUrl.startsWith("https://exchange.taler.fdold.eu")
+ }?.let { fDoldExchange ->
+ api.request<Unit>("addGlobalCurrencyExchange") {
+ put("currency", fDoldExchange.currency)
+ put("exchangeBaseUrl", fDoldExchange.exchangeBaseUrl)
+ put("exchangeMasterPub",
+ "7ER30ZWJEXAG026H5KG9M19NGTFC2DKKFPV79GVXA6DK5DCNSWXG")
+ }.onError {
+ Log.e(TAG, "Error addGlobalCurrencyExchange: $it")
+ }.onSuccess {
+ Log.i(TAG, "fdold is global now!")
+ }
+ }
+ }
+ }
+ }
+
}