summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt')
-rw-r--r--wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt155
1 files changed, 98 insertions, 57 deletions
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 90b8570..4661946 100644
--- a/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/withdraw/WithdrawManager.kt
@@ -33,10 +33,12 @@ import net.taler.wallet.backend.TalerErrorInfo
import net.taler.wallet.backend.WalletBackendApi
import net.taler.wallet.exchanges.ExchangeFees
import net.taler.wallet.exchanges.ExchangeItem
+import net.taler.wallet.transactions.WithdrawalExchangeAccountDetails
import net.taler.wallet.withdraw.WithdrawStatus.ReceivedDetails
sealed class WithdrawStatus {
data class Loading(val talerWithdrawUri: String? = null) : WithdrawStatus()
+
data class NeedsExchange(val exchangeSelection: Event<ExchangeSelection>) : WithdrawStatus()
data class TosReviewRequired(
@@ -44,6 +46,8 @@ sealed class WithdrawStatus {
val exchangeBaseUrl: String,
val amountRaw: Amount,
val amountEffective: Amount,
+ val numCoins: Int,
+ val withdrawalAccountList: List<WithdrawalExchangeAccountDetails>,
val ageRestrictionOptions: List<Int>? = null,
val tosText: String,
val tosEtag: String,
@@ -55,36 +59,50 @@ sealed class WithdrawStatus {
val exchangeBaseUrl: String,
val amountRaw: Amount,
val amountEffective: Amount,
+ val numCoins: Int,
+ val withdrawalAccountList: List<WithdrawalExchangeAccountDetails>,
val ageRestrictionOptions: List<Int>? = null,
) : WithdrawStatus()
- object Withdrawing : WithdrawStatus()
+ data object Withdrawing : WithdrawStatus()
+
data class Success(val currency: String, val transactionId: String) : WithdrawStatus()
- sealed class ManualTransferRequired : WithdrawStatus() {
- abstract val uri: Uri
- abstract val transactionId: String?
- }
- data class ManualTransferRequiredIBAN(
+ class ManualTransferRequired(
+ val transactionId: String?,
+ val transactionAmountRaw: Amount,
+ val transactionAmountEffective: Amount,
val exchangeBaseUrl: String,
- override val uri: Uri,
+ val withdrawalTransfers: List<TransferData>,
+ ) : WithdrawStatus()
+
+ data class Error(val message: String?) : WithdrawStatus()
+}
+
+sealed class TransferData {
+ abstract val subject: String
+ abstract val amountRaw: Amount
+ abstract val amountEffective: Amount
+ abstract val withdrawalAccount: WithdrawalExchangeAccountDetails
+
+ val currency get() = withdrawalAccount.transferAmount?.currency
+
+ data class IBAN(
+ override val subject: String,
+ override val amountRaw: Amount,
+ override val amountEffective: Amount,
+ override val withdrawalAccount: WithdrawalExchangeAccountDetails,
val iban: String,
- val subject: String,
- val amountRaw: Amount,
- override val transactionId: String?,
- ) : ManualTransferRequired()
+ ): TransferData()
- data class ManualTransferRequiredBitcoin(
- val exchangeBaseUrl: String,
- override val uri: Uri,
+ data class Bitcoin(
+ override val subject: String,
+ override val amountRaw: Amount,
+ override val amountEffective: Amount,
+ override val withdrawalAccount: WithdrawalExchangeAccountDetails,
val account: String,
- val segwitAddrs: List<String>,
- val subject: String,
- val amountRaw: Amount,
- override val transactionId: String?,
- ) : ManualTransferRequired()
-
- data class Error(val message: String?) : WithdrawStatus()
+ val segwitAddresses: List<String>,
+ ): TransferData()
}
sealed class WithdrawTestStatus {
@@ -101,10 +119,12 @@ data class WithdrawalDetailsForUri(
)
@Serializable
-data class WithdrawalDetails(
+data class ManualWithdrawalDetails(
val tosAccepted: Boolean,
val amountRaw: Amount,
val amountEffective: Amount,
+ val numCoins: Int,
+ val withdrawalAccountList: List<WithdrawalExchangeAccountDetails>,
val ageRestrictionOptions: List<Int>? = null,
)
@@ -115,7 +135,9 @@ data class AcceptWithdrawalResponse(
@Serializable
data class AcceptManualWithdrawalResponse(
- val exchangePaytoUris: List<String>,
+ val reservePub: String,
+ val withdrawalAccountsList: List<WithdrawalExchangeAccountDetails>,
+ val transactionId: String,
)
data class ExchangeSelection(
@@ -176,7 +198,7 @@ class WithdrawManager(
uri: String? = null,
) = scope.launch {
withdrawStatus.value = WithdrawStatus.Loading(uri)
- api.request("getWithdrawalDetailsForAmount", WithdrawalDetails.serializer()) {
+ api.request("getWithdrawalDetailsForAmount", ManualWithdrawalDetails.serializer()) {
put("exchangeBaseUrl", exchangeBaseUrl)
put("amount", amount.toJSONString())
}.onError { error ->
@@ -188,6 +210,8 @@ class WithdrawManager(
exchangeBaseUrl = exchangeBaseUrl,
amountRaw = details.amountRaw,
amountEffective = details.amountEffective,
+ numCoins = details.numCoins,
+ withdrawalAccountList = details.withdrawalAccountList,
ageRestrictionOptions = details.ageRestrictionOptions,
)
} else getExchangeTos(exchangeBaseUrl, details, showTosImmediately, uri)
@@ -196,7 +220,7 @@ class WithdrawManager(
private fun getExchangeTos(
exchangeBaseUrl: String,
- details: WithdrawalDetails,
+ details: ManualWithdrawalDetails,
showImmediately: Boolean,
uri: String?,
) = scope.launch {
@@ -210,6 +234,8 @@ class WithdrawManager(
exchangeBaseUrl = exchangeBaseUrl,
amountRaw = details.amountRaw,
amountEffective = details.amountEffective,
+ numCoins = details.numCoins,
+ withdrawalAccountList = details.withdrawalAccountList,
ageRestrictionOptions = details.ageRestrictionOptions,
tosText = it.content,
tosEtag = it.currentEtag,
@@ -234,6 +260,8 @@ class WithdrawManager(
exchangeBaseUrl = s.exchangeBaseUrl,
amountRaw = s.amountRaw,
amountEffective = s.amountEffective,
+ numCoins = s.numCoins,
+ withdrawalAccountList = s.withdrawalAccountList,
ageRestrictionOptions = s.ageRestrictionOptions,
)
}
@@ -275,10 +303,8 @@ class WithdrawManager(
handleError("acceptManualWithdrawal", it)
}.onSuccess { response ->
withdrawStatus.value = createManualTransferRequired(
- amount = status.amountRaw,
- exchangeBaseUrl = status.exchangeBaseUrl,
- // TODO what if there's more than one or no URI?
- uriStr = response.exchangePaytoUris[0],
+ status = status,
+ response = response,
)
}
}
@@ -301,33 +327,48 @@ class WithdrawManager(
}
fun createManualTransferRequired(
- amount: Amount,
+ transactionId: String,
exchangeBaseUrl: String,
- uriStr: String,
- transactionId: String? = null,
-): WithdrawStatus.ManualTransferRequired {
- val uri = Uri.parse(uriStr.replace("receiver-name=", "receiver_name="))
- if ("bitcoin".equals(uri.authority, true)) {
- val msg = uri.getQueryParameter("message").orEmpty()
- val reg = "\\b([A-Z0-9]{52})\\b".toRegex().find(msg)
- val reserve = reg?.value ?: uri.getQueryParameter("subject")!!
- val segwitAddrs = Bech32.generateFakeSegwitAddress(reserve, uri.pathSegments.first())
- return WithdrawStatus.ManualTransferRequiredBitcoin(
- exchangeBaseUrl = exchangeBaseUrl,
- uri = uri,
- account = uri.lastPathSegment!!,
- segwitAddrs = segwitAddrs,
- subject = reserve,
- amountRaw = amount,
- transactionId = transactionId,
+ amountRaw: Amount,
+ amountEffective: Amount,
+ withdrawalAccountList: List<WithdrawalExchangeAccountDetails>,
+) = WithdrawStatus.ManualTransferRequired(
+ transactionId = transactionId,
+ transactionAmountRaw = amountRaw,
+ transactionAmountEffective = amountEffective,
+ exchangeBaseUrl = exchangeBaseUrl,
+ withdrawalTransfers = withdrawalAccountList.map {
+ val uri = Uri.parse(it.paytoUri.replace("receiver-name=", "receiver_name="))
+ if ("bitcoin".equals(uri.authority, true)) {
+ val msg = uri.getQueryParameter("message").orEmpty()
+ val reg = "\\b([A-Z0-9]{52})\\b".toRegex().find(msg)
+ val reserve = reg?.value ?: uri.getQueryParameter("subject")!!
+ val segwitAddresses = Bech32.generateFakeSegwitAddress(reserve, uri.pathSegments.first())
+ TransferData.Bitcoin(
+ account = uri.lastPathSegment!!,
+ segwitAddresses = segwitAddresses,
+ subject = reserve,
+ amountRaw = amountRaw,
+ amountEffective = amountEffective,
+ withdrawalAccount = it.copy(paytoUri = uri.toString())
+ )
+ } else TransferData.IBAN(
+ iban = uri.lastPathSegment!!,
+ subject = uri.getQueryParameter("message") ?: "Error: No message in URI",
+ amountRaw = amountRaw,
+ amountEffective = amountEffective,
+ withdrawalAccount = it.copy(paytoUri = uri.toString())
)
- }
- return WithdrawStatus.ManualTransferRequiredIBAN(
- exchangeBaseUrl = exchangeBaseUrl,
- uri = uri,
- iban = uri.lastPathSegment!!,
- subject = uri.getQueryParameter("message") ?: "Error: No message in URI",
- amountRaw = amount,
- transactionId = transactionId,
- )
-}
+ },
+)
+
+fun createManualTransferRequired(
+ status: ReceivedDetails,
+ response: AcceptManualWithdrawalResponse,
+): WithdrawStatus.ManualTransferRequired = createManualTransferRequired(
+ transactionId = response.transactionId,
+ exchangeBaseUrl = status.exchangeBaseUrl,
+ amountRaw = status.amountRaw,
+ amountEffective = status.amountEffective,
+ withdrawalAccountList = response.withdrawalAccountsList,
+) \ No newline at end of file