From d852e2cf0d924d77003b07544a840bc9c62dfde2 Mon Sep 17 00:00:00 2001 From: Brandon McAnsh Date: Mon, 5 Feb 2024 03:25:19 -0500 Subject: [PATCH] fix(airdrop): receiveFromPrimary after receiving first airdrop to allow gives after Signed-off-by: Brandon McAnsh --- .../network/client/Client_Transaction.kt | 4 +- .../repository/TransactionRepository.kt | 40 +++++++++++-------- .../view/main/getKin/GetKinSheetViewModel.kt | 26 ++++++------ 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/api/src/main/java/com/getcode/network/client/Client_Transaction.kt b/api/src/main/java/com/getcode/network/client/Client_Transaction.kt index a7db7cac9..cf2b48eb6 100644 --- a/api/src/main/java/com/getcode/network/client/Client_Transaction.kt +++ b/api/src/main/java/com/getcode/network/client/Client_Transaction.kt @@ -355,9 +355,9 @@ fun Client.sendRemotely( } -fun Client.requestFirstKinAirdrop( +suspend fun Client.requestFirstKinAirdrop( owner: KeyPair, -): Single { +): Result { return transactionRepository.requestFirstKinAirdrop(owner) } diff --git a/api/src/main/java/com/getcode/network/repository/TransactionRepository.kt b/api/src/main/java/com/getcode/network/repository/TransactionRepository.kt index c824fe350..ca8bf5fe4 100644 --- a/api/src/main/java/com/getcode/network/repository/TransactionRepository.kt +++ b/api/src/main/java/com/getcode/network/repository/TransactionRepository.kt @@ -45,6 +45,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.filterNot +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map @@ -343,7 +344,7 @@ class TransactionRepository @Inject constructor( // TODO: potentially make this more generic in the event we introduce more airdrop types // that can be requested for - fun requestFirstKinAirdrop(owner: Ed25519.KeyPair): Single { + suspend fun requestFirstKinAirdrop(owner: KeyPair): Result { val request = TransactionService.AirdropRequest.newBuilder() .setOwner(owner.publicKeyBytes.toSolanaAccount()) .setAirdropType(TransactionService.AirdropType.GET_FIRST_KIN) @@ -354,25 +355,30 @@ class TransactionRepository @Inject constructor( } .build() - return transactionApi.airdrop(request).flatMap { - when (it.result) { - TransactionService.AirdropResponse.Result.OK -> { - Single.just(KinAmount.fromProtoExchangeData(it.exchangeData)) - ?: Single.error(IllegalStateException()) - } + return runCatching { + transactionApi.airdrop(request) + .toFlowable() + .asFlow() + .flowOn(Dispatchers.IO) + .map { + when (it.result) { + TransactionService.AirdropResponse.Result.OK -> { + KinAmount.fromProtoExchangeData(it.exchangeData) + } - TransactionService.AirdropResponse.Result.ALREADY_CLAIMED -> { - Single.error(AirdropException.AlreadyClaimedException()) - } + TransactionService.AirdropResponse.Result.ALREADY_CLAIMED -> { + throw AirdropException.AlreadyClaimedException() + } - TransactionService.AirdropResponse.Result.UNAVAILABLE -> { - Single.error(AirdropException.UnavailableException()) - } + TransactionService.AirdropResponse.Result.UNAVAILABLE -> { + throw AirdropException.UnavailableException() + } - else -> { - Single.error(AirdropException.UnknownException()) - } - } + else -> { + throw AirdropException.UnknownException() + } + } + }.first() } } diff --git a/app/src/main/java/com/getcode/view/main/getKin/GetKinSheetViewModel.kt b/app/src/main/java/com/getcode/view/main/getKin/GetKinSheetViewModel.kt index b46e8be7e..f5786690d 100644 --- a/app/src/main/java/com/getcode/view/main/getKin/GetKinSheetViewModel.kt +++ b/app/src/main/java/com/getcode/view/main/getKin/GetKinSheetViewModel.kt @@ -9,6 +9,7 @@ import com.getcode.model.PrefsBool import com.getcode.network.BalanceController import com.getcode.network.client.Client import com.getcode.network.client.fetchPaymentHistoryDelta +import com.getcode.network.client.receiveFromPrimaryIfWithinLimits import com.getcode.network.client.requestFirstKinAirdrop import com.getcode.network.repository.PrefRepository import com.getcode.network.repository.TransactionRepository @@ -33,6 +34,7 @@ import kotlinx.coroutines.reactive.asFlow import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds @HiltViewModel class GetKinSheetViewModel @Inject constructor( @@ -96,17 +98,16 @@ class GetKinSheetViewModel @Inject constructor( SessionManager.getKeyPair() }.onEach { dispatchEvent(Event.OnLoadingChanged(true)) } - .flatMapLatest { owner -> - client.requestFirstKinAirdrop(owner) - .subscribeOn(Schedulers.computation()) - .delay(1, TimeUnit.SECONDS) - .toFlowable().asFlow() - } .catchSafely( - action = { amount -> + action = { owner -> + delay(1.seconds) + val amount = client.requestFirstKinAirdrop(owner).getOrThrow() + dispatchEvent(Event.OnGetEligibilityChanged(eligible = false, fromEvent = true)) dispatchEvent(Event.OnLoadingChanged(false)) dispatchEvent(Event.OnKinRequestSuccessful(amount)) + + balanceController.fetchBalanceSuspend() }, onFailure = { if (it is TransactionRepository.AirdropException.AlreadyClaimedException) { @@ -121,11 +122,12 @@ class GetKinSheetViewModel @Inject constructor( } ) .flatMapLatest { - Completable.concatArray( - balanceController.fetchBalance(), - client.fetchPaymentHistoryDelta(owner = SessionManager.getKeyPair()!!) - .ignoreElement() - ).toFlowable().asFlow() + val organizer = SessionManager.getOrganizer() + val receiveWithinLimits = organizer?.let { + client.receiveFromPrimaryIfWithinLimits(it) + } ?: Completable.complete() + + receiveWithinLimits.toFlowable().asFlow() } .launchIn(viewModelScope)