[#853] Adopt latest SDK changes
Co-authored-by: Honza <rychnovsky.honza@gmail.com>
This commit is contained in:
parent
e20221f117
commit
b6226c55eb
|
@ -153,7 +153,7 @@ ZCASH_ANDROID_WALLET_PLUGINS_VERSION=1.0.0
|
|||
ZCASH_BIP39_VERSION=1.0.4
|
||||
# TODO [#279]: Revert to stable SDK before app release
|
||||
# TODO [#279]: https://github.com/zcash/secant-android-wallet/issues/279
|
||||
ZCASH_SDK_VERSION=1.14.0-beta01-SNAPSHOT
|
||||
ZCASH_SDK_VERSION=1.17.0-beta01-SNAPSHOT
|
||||
ZXING_VERSION=3.5.1
|
||||
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
package cash.z.ecc.sdk.model
|
||||
|
||||
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
|
||||
fun CompactBlockProcessor.ProcessorInfo.downloadProgress(): PercentDecimal {
|
||||
val lastDownloadRangeSnapshot = lastDownloadRange
|
||||
val lastDownloadedHeightSnapshot = lastDownloadedHeight
|
||||
|
||||
return if (lastDownloadRangeSnapshot?.isEmpty() != false || lastDownloadedHeightSnapshot == null) {
|
||||
PercentDecimal.ONE_HUNDRED_PERCENT
|
||||
} else {
|
||||
val numerator = (lastDownloadedHeightSnapshot.value - lastDownloadRangeSnapshot.start.value + 1)
|
||||
.toFloat()
|
||||
.coerceAtLeast(PercentDecimal.MIN)
|
||||
val denominator = (lastDownloadRangeSnapshot.endInclusive.value - lastDownloadRangeSnapshot.start.value + 1)
|
||||
.toFloat()
|
||||
|
||||
val progress = (numerator / denominator).coerceAtMost(PercentDecimal.MAX)
|
||||
|
||||
PercentDecimal(progress)
|
||||
}
|
||||
}
|
||||
|
||||
fun CompactBlockProcessor.ProcessorInfo.scanProgress(): PercentDecimal {
|
||||
val lastScanRangeSnapshot = lastScanRange
|
||||
val lastScannedHeightSnapshot = lastScannedHeight
|
||||
|
||||
return if (lastScanRangeSnapshot?.isEmpty() != false || lastScannedHeightSnapshot == null) {
|
||||
PercentDecimal.ONE_HUNDRED_PERCENT
|
||||
} else {
|
||||
val numerator = (lastScannedHeightSnapshot.value - lastScanRangeSnapshot.start.value + 1)
|
||||
.toFloat()
|
||||
.coerceAtLeast(PercentDecimal.MIN)
|
||||
val demonimator = (lastScanRangeSnapshot.endInclusive.value - lastScanRangeSnapshot.start.value + 1)
|
||||
.toFloat()
|
||||
|
||||
val progress = (numerator / demonimator).coerceAtMost(PercentDecimal.MAX)
|
||||
|
||||
PercentDecimal(progress)
|
||||
}
|
||||
}
|
||||
|
||||
// These are estimates
|
||||
@Suppress("MagicNumber")
|
||||
private val DOWNLOAD_WEIGHT = PercentDecimal(0.4f)
|
||||
private val SCAN_WEIGHT = PercentDecimal(PercentDecimal.MAX - DOWNLOAD_WEIGHT.decimal)
|
||||
|
||||
fun CompactBlockProcessor.ProcessorInfo.totalProgress(): PercentDecimal {
|
||||
val downloadWeighted = DOWNLOAD_WEIGHT.decimal * (downloadProgress().decimal).coerceAtMost(PercentDecimal.MAX)
|
||||
val scanWeighted = SCAN_WEIGHT.decimal * (scanProgress().decimal).coerceAtMost(PercentDecimal.MAX)
|
||||
|
||||
return PercentDecimal(
|
||||
downloadWeighted.coerceAtLeast(PercentDecimal.MIN) +
|
||||
scanWeighted.coerceAtLeast(PercentDecimal.MIN)
|
||||
)
|
||||
}
|
|
@ -332,6 +332,7 @@ if (zcashSdkIncludedBuildPath.isNotEmpty()) {
|
|||
includeBuild(zcashSdkIncludedBuildPath) {
|
||||
dependencySubstitution {
|
||||
substitute(module("cash.z.ecc.android:zcash-android-sdk")).using(project(":sdk-lib"))
|
||||
substitute(module("cash.z.ecc.android:zcash-android-sdk-incubator")).using(project(":sdk-incubator-lib"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,7 @@ import cash.z.ecc.android.sdk.Synchronizer
|
|||
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
||||
import cash.z.ecc.android.sdk.model.Account
|
||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||
import cash.z.ecc.android.sdk.model.PendingTransaction
|
||||
import cash.z.ecc.android.sdk.model.Transaction
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.TransactionRecipient
|
||||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||
|
@ -17,7 +16,6 @@ import cash.z.ecc.android.sdk.type.AddressType
|
|||
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
|
||||
/**
|
||||
* Mocked Synchronizer that can be used instead of the production SdkSynchronizer e.g. for tests.
|
||||
|
@ -25,9 +23,6 @@ import kotlinx.coroutines.flow.emptyFlow
|
|||
@Suppress("TooManyFunctions", "UNUSED_PARAMETER")
|
||||
internal class MockSynchronizer : CloseableSynchronizer {
|
||||
|
||||
override val clearedTransactions: Flow<List<TransactionOverview>>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val latestBirthdayHeight: BlockHeight
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
|
@ -63,26 +58,18 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
override val orchardBalances: StateFlow<WalletBalance?>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val pendingTransactions: Flow<List<PendingTransaction>>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val processorInfo: Flow<CompactBlockProcessor.ProcessorInfo>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val progress: Flow<Int>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val receivedTransactions: Flow<List<Transaction.Received>>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
override val progress: Flow<PercentDecimal>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val saplingBalances: StateFlow<WalletBalance?>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val sentTransactions: Flow<List<Transaction.Sent>>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
||||
override val status: Flow<Synchronizer.Status>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
override val transactions: Flow<List<TransactionOverview>>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val transparentBalances: StateFlow<WalletBalance?>
|
||||
get() = error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
|
@ -143,14 +130,11 @@ internal class MockSynchronizer : CloseableSynchronizer {
|
|||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
||||
/**
|
||||
* This method intentionally returns empty flow, as the PendingTransaction is only an SDK internal class.
|
||||
*/
|
||||
override fun sendToAddress(usk: UnifiedSpendingKey, amount: Zatoshi, toAddress: String, memo: String): Flow<PendingTransaction> {
|
||||
return emptyFlow()
|
||||
override suspend fun sendToAddress(usk: UnifiedSpendingKey, amount: Zatoshi, toAddress: String, memo: String): Long {
|
||||
return 1
|
||||
}
|
||||
|
||||
override fun shieldFunds(usk: UnifiedSpendingKey, memo: String): Flow<PendingTransaction> {
|
||||
override suspend fun shieldFunds(usk: UnifiedSpendingKey, memo: String): Long {
|
||||
error("Intentionally not implemented in ${MockSynchronizer::class.simpleName} implementation.")
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class HomeActivityTest : UiTestPrerequisites() {
|
|||
@MediumTest
|
||||
fun open_close_drawer_menu_test() {
|
||||
val walletSnapshot = WalletSnapshotFixture.new(
|
||||
status = Synchronizer.Status.DOWNLOADING,
|
||||
status = Synchronizer.Status.SYNCING,
|
||||
progress = PercentDecimal(0.5f)
|
||||
)
|
||||
val testSetup = newTestSetup(walletSnapshot)
|
||||
|
|
|
@ -37,7 +37,7 @@ class HomeViewIntegrationTest : UiTestPrerequisites() {
|
|||
fun wallet_snapshot_restoration() {
|
||||
val restorationTester = StateRestorationTester(composeTestRule)
|
||||
val walletSnapshot = WalletSnapshotFixture.new(
|
||||
status = Synchronizer.Status.DOWNLOADING,
|
||||
status = Synchronizer.Status.SYNCING,
|
||||
progress = PercentDecimal(0.5f)
|
||||
)
|
||||
val testSetup = newTestSetup(walletSnapshot)
|
||||
|
@ -47,7 +47,7 @@ class HomeViewIntegrationTest : UiTestPrerequisites() {
|
|||
}
|
||||
|
||||
assertNotEquals(WalletSnapshotFixture.STATUS, testSetup.getWalletSnapshot().status)
|
||||
assertEquals(Synchronizer.Status.DOWNLOADING, testSetup.getWalletSnapshot().status)
|
||||
assertEquals(Synchronizer.Status.SYNCING, testSetup.getWalletSnapshot().status)
|
||||
|
||||
assertNotEquals(WalletSnapshotFixture.PROGRESS, testSetup.getWalletSnapshot().progress)
|
||||
assertEquals(0.5f, testSetup.getWalletSnapshot().progress.decimal)
|
||||
|
@ -55,7 +55,7 @@ class HomeViewIntegrationTest : UiTestPrerequisites() {
|
|||
restorationTester.emulateSavedInstanceStateRestore()
|
||||
|
||||
assertNotEquals(WalletSnapshotFixture.STATUS, testSetup.getWalletSnapshot().status)
|
||||
assertEquals(Synchronizer.Status.DOWNLOADING, testSetup.getWalletSnapshot().status)
|
||||
assertEquals(Synchronizer.Status.SYNCING, testSetup.getWalletSnapshot().status)
|
||||
|
||||
assertNotEquals(WalletSnapshotFixture.PROGRESS, testSetup.getWalletSnapshot().progress)
|
||||
assertEquals(0.5f, testSetup.getWalletSnapshot().progress.decimal)
|
||||
|
|
|
@ -12,6 +12,7 @@ import co.electriccoin.zcash.ui.test.getStringResource
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class WalletDisplayValuesTest {
|
||||
|
||||
|
@ -20,7 +21,7 @@ class WalletDisplayValuesTest {
|
|||
fun download_running_test() {
|
||||
val walletSnapshot = WalletSnapshotFixture.new(
|
||||
progress = PercentDecimal.ONE_HUNDRED_PERCENT,
|
||||
status = Synchronizer.Status.SCANNING,
|
||||
status = Synchronizer.Status.SYNCING,
|
||||
orchardBalance = WalletSnapshotFixture.ORCHARD_BALANCE,
|
||||
saplingBalance = WalletSnapshotFixture.SAPLING_BALANCE,
|
||||
transparentBalance = WalletSnapshotFixture.TRANSPARENT_BALANCE
|
||||
|
@ -34,7 +35,7 @@ class WalletDisplayValuesTest {
|
|||
assertNotNull(values)
|
||||
assertEquals(1f, values.progress.decimal)
|
||||
assertEquals(walletSnapshot.totalBalance().toZecString(), values.zecAmountText)
|
||||
assertEquals(getStringResource(R.string.home_status_syncing_catchup), values.statusText)
|
||||
assertTrue(values.statusText.startsWith(getStringResource(R.string.home_status_syncing_catchup)))
|
||||
// TODO [#578] https://github.com/zcash/zcash-android-wallet-sdk/issues/578
|
||||
assertEquals(FiatCurrencyConversionRateState.Unavailable, values.fiatCurrencyAmountState)
|
||||
assertEquals(getStringResource(R.string.fiat_currency_conversion_rate_unavailable), values.fiatCurrencyAmountText)
|
||||
|
|
|
@ -70,7 +70,7 @@ class HomeViewTest : UiTestPrerequisites() {
|
|||
newTestSetup(
|
||||
isCircularProgressBar = true,
|
||||
walletSnapshot = WalletSnapshotFixture.new(
|
||||
status = Synchronizer.Status.SCANNING,
|
||||
status = Synchronizer.Status.SYNCING,
|
||||
progress = PercentDecimal.ONE_HUNDRED_PERCENT
|
||||
)
|
||||
)
|
||||
|
@ -87,7 +87,7 @@ class HomeViewTest : UiTestPrerequisites() {
|
|||
newTestSetup(
|
||||
isCircularProgressBar = false,
|
||||
walletSnapshot = WalletSnapshotFixture.new(
|
||||
status = Synchronizer.Status.SCANNING,
|
||||
status = Synchronizer.Status.SYNCING,
|
||||
progress = PercentDecimal.ONE_HUNDRED_PERCENT
|
||||
)
|
||||
)
|
||||
|
|
|
@ -25,13 +25,10 @@ object WalletSnapshotFixture {
|
|||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
),
|
||||
orchardBalance: WalletBalance = ORCHARD_BALANCE,
|
||||
saplingBalance: WalletBalance = SAPLING_BALANCE,
|
||||
transparentBalance: WalletBalance = TRANSPARENT_BALANCE,
|
||||
pendingCount: Int = 0,
|
||||
progress: PercentDecimal = PROGRESS,
|
||||
synchronizerError: SynchronizerError? = null
|
||||
) = WalletSnapshot(
|
||||
|
@ -40,7 +37,6 @@ object WalletSnapshotFixture {
|
|||
orchardBalance,
|
||||
saplingBalance,
|
||||
transparentBalance,
|
||||
pendingCount,
|
||||
progress,
|
||||
synchronizerError
|
||||
)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package co.electriccoin.zcash.ui.screen.home.model
|
||||
|
||||
import cash.z.ecc.android.sdk.model.PendingTransaction
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
|
||||
/**
|
||||
* A common transactions wrapper class to provide unified way to work with a transactions classes from our SDK.
|
||||
*/
|
||||
sealed class CommonTransaction {
|
||||
data class Pending(val data: PendingTransaction) : CommonTransaction()
|
||||
data class Overview(val data: TransactionOverview) : CommonTransaction()
|
||||
}
|
|
@ -39,9 +39,7 @@ data class WalletDisplayValues(
|
|||
var fiatCurrencyAmountText = getFiatCurrencyRateValue(context, fiatCurrencyAmountState)
|
||||
|
||||
when (walletSnapshot.status) {
|
||||
Synchronizer.Status.PREPARING,
|
||||
Synchronizer.Status.DOWNLOADING,
|
||||
Synchronizer.Status.VALIDATING -> {
|
||||
Synchronizer.Status.SYNCING -> {
|
||||
progress = walletSnapshot.progress
|
||||
val progressPercent = (walletSnapshot.progress.decimal * 100).roundToInt()
|
||||
// we add "so far" to the amount
|
||||
|
@ -53,11 +51,6 @@ data class WalletDisplayValues(
|
|||
}
|
||||
statusText = context.getString(R.string.home_status_syncing_format, progressPercent)
|
||||
}
|
||||
Synchronizer.Status.SCANNING -> {
|
||||
// SDK provides us only one progress, which keeps on 100 in the scanning state
|
||||
progress = PercentDecimal.ONE_HUNDRED_PERCENT
|
||||
statusText = context.getString(R.string.home_status_syncing_catchup)
|
||||
}
|
||||
Synchronizer.Status.SYNCED,
|
||||
Synchronizer.Status.ENHANCING -> {
|
||||
statusText = if (updateAvailable) {
|
||||
|
|
|
@ -15,7 +15,6 @@ data class WalletSnapshot(
|
|||
val orchardBalance: WalletBalance,
|
||||
val saplingBalance: WalletBalance,
|
||||
val transparentBalance: WalletBalance,
|
||||
val pendingCount: Int,
|
||||
val progress: PercentDecimal,
|
||||
val synchronizerError: SynchronizerError?
|
||||
) {
|
||||
|
|
|
@ -58,6 +58,7 @@ import androidx.compose.ui.unit.dp
|
|||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.model.FiatCurrencyConversionRateState
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import co.electriccoin.zcash.crash.android.GlobalCrashReporter
|
||||
import co.electriccoin.zcash.ui.R
|
||||
import co.electriccoin.zcash.ui.common.DisableScreenTimeout
|
||||
|
@ -71,7 +72,6 @@ import co.electriccoin.zcash.ui.design.component.PrimaryButton
|
|||
import co.electriccoin.zcash.ui.design.theme.ZcashTheme
|
||||
import co.electriccoin.zcash.ui.fixture.WalletSnapshotFixture
|
||||
import co.electriccoin.zcash.ui.screen.home.HomeTag
|
||||
import co.electriccoin.zcash.ui.screen.home.model.CommonTransaction
|
||||
import co.electriccoin.zcash.ui.screen.home.model.WalletDisplayValues
|
||||
import co.electriccoin.zcash.ui.screen.home.model.WalletSnapshot
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
@ -110,7 +110,7 @@ fun ComposablePreview() {
|
|||
@Composable
|
||||
fun Home(
|
||||
walletSnapshot: WalletSnapshot,
|
||||
transactionHistory: ImmutableList<CommonTransaction>,
|
||||
transactionHistory: ImmutableList<TransactionOverview>,
|
||||
isUpdateAvailable: Boolean,
|
||||
isKeepScreenOnDuringSync: Boolean?,
|
||||
isFiatConversionEnabled: Boolean,
|
||||
|
@ -295,7 +295,7 @@ private fun HomeDrawer(
|
|||
@Composable
|
||||
private fun HomeMainContent(
|
||||
walletSnapshot: WalletSnapshot,
|
||||
transactionHistory: ImmutableList<CommonTransaction>,
|
||||
transactionHistory: ImmutableList<TransactionOverview>,
|
||||
isUpdateAvailable: Boolean,
|
||||
isKeepScreenOnDuringSync: Boolean?,
|
||||
isFiatConversionEnabled: Boolean,
|
||||
|
@ -347,9 +347,7 @@ private fun HomeMainContent(
|
|||
}
|
||||
|
||||
private fun isSyncing(status: Synchronizer.Status): Boolean {
|
||||
return status == Synchronizer.Status.DOWNLOADING ||
|
||||
status == Synchronizer.Status.VALIDATING ||
|
||||
status == Synchronizer.Status.SCANNING ||
|
||||
return status == Synchronizer.Status.SYNCING ||
|
||||
status == Synchronizer.Status.ENHANCING
|
||||
}
|
||||
|
||||
|
@ -458,7 +456,7 @@ private fun Status(
|
|||
|
||||
@Composable
|
||||
@Suppress("MagicNumber")
|
||||
private fun History(transactionHistory: ImmutableList<CommonTransaction>) {
|
||||
private fun History(transactionHistory: ImmutableList<TransactionOverview>) {
|
||||
if (transactionHistory.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -11,15 +11,13 @@ import cash.z.ecc.android.sdk.block.CompactBlockProcessor
|
|||
import cash.z.ecc.android.sdk.model.Account
|
||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||
import cash.z.ecc.android.sdk.model.FiatCurrency
|
||||
import cash.z.ecc.android.sdk.model.PendingTransaction
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import cash.z.ecc.android.sdk.model.PersistableWallet
|
||||
import cash.z.ecc.android.sdk.model.TransactionOverview
|
||||
import cash.z.ecc.android.sdk.model.WalletAddresses
|
||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||
import cash.z.ecc.android.sdk.model.isMined
|
||||
import cash.z.ecc.android.sdk.model.isSubmitSuccess
|
||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||
import cash.z.ecc.sdk.type.fromResources
|
||||
import co.electriccoin.zcash.global.getInstance
|
||||
|
@ -30,7 +28,6 @@ import co.electriccoin.zcash.ui.preference.EncryptedPreferenceKeys
|
|||
import co.electriccoin.zcash.ui.preference.EncryptedPreferenceSingleton
|
||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceKeys
|
||||
import co.electriccoin.zcash.ui.preference.StandardPreferenceSingleton
|
||||
import co.electriccoin.zcash.ui.screen.home.model.CommonTransaction
|
||||
import co.electriccoin.zcash.ui.screen.home.model.WalletSnapshot
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
@ -44,7 +41,6 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.flow.WhileSubscribed
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
|
@ -154,12 +150,12 @@ class WalletViewModel(application: Application) : AndroidViewModel(application)
|
|||
|
||||
// This is not the right API, because the transaction list could be very long and might need UI filtering
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
val transactionSnapshot: StateFlow<ImmutableList<CommonTransaction>> = synchronizer
|
||||
val transactionSnapshot: StateFlow<ImmutableList<TransactionOverview>> = synchronizer
|
||||
.flatMapLatest {
|
||||
if (null == it) {
|
||||
flowOf(persistentListOf())
|
||||
} else {
|
||||
it.toTransactions()
|
||||
it.transactions.map { list -> list.toPersistentList() }
|
||||
}
|
||||
}
|
||||
.stateIn(
|
||||
|
@ -331,25 +327,14 @@ private fun Synchronizer.toWalletSnapshot() =
|
|||
orchardBalances, // 2
|
||||
saplingBalances, // 3
|
||||
transparentBalances, // 4
|
||||
pendingTransactions.distinctUntilChanged(), // 5
|
||||
progress, // 6
|
||||
toCommonError() // 7
|
||||
progress, // 5
|
||||
toCommonError() // 6
|
||||
) { flows ->
|
||||
val pendingCount = (flows[5] as List<*>)
|
||||
.filterIsInstance(PendingTransaction::class.java)
|
||||
.count {
|
||||
it.isSubmitSuccess() && !it.isMined()
|
||||
}
|
||||
val orchardBalance = flows[2] as WalletBalance?
|
||||
val saplingBalance = flows[3] as WalletBalance?
|
||||
val transparentBalance = flows[4] as WalletBalance?
|
||||
|
||||
val progressPercentDecimal = (flows[6] as Int).let { value ->
|
||||
if (value > PercentDecimal.MAX || value < PercentDecimal.MIN) {
|
||||
PercentDecimal.ZERO_PERCENT
|
||||
}
|
||||
PercentDecimal((flows[6] as Int) / 100f)
|
||||
}
|
||||
val progressPercentDecimal = flows[5] as PercentDecimal
|
||||
|
||||
WalletSnapshot(
|
||||
flows[0] as Synchronizer.Status,
|
||||
|
@ -357,23 +342,7 @@ private fun Synchronizer.toWalletSnapshot() =
|
|||
orchardBalance ?: WalletBalance(Zatoshi(0), Zatoshi(0)),
|
||||
saplingBalance ?: WalletBalance(Zatoshi(0), Zatoshi(0)),
|
||||
transparentBalance ?: WalletBalance(Zatoshi(0), Zatoshi(0)),
|
||||
pendingCount,
|
||||
progressPercentDecimal,
|
||||
flows[7] as SynchronizerError?
|
||||
flows[6] as SynchronizerError?
|
||||
)
|
||||
}
|
||||
|
||||
private fun Synchronizer.toTransactions(): Flow<ImmutableList<CommonTransaction>> =
|
||||
combine(
|
||||
clearedTransactions.distinctUntilChanged(),
|
||||
pendingTransactions.distinctUntilChanged()
|
||||
) { cleared, pending ->
|
||||
// TODO [#157]: Sort the transactions to show the most recent
|
||||
// TODO [#157]: https://github.com/zcash/secant-android-wallet/issues/157
|
||||
|
||||
// Note that the list of transactions will not be sorted.
|
||||
buildList {
|
||||
addAll(cleared.map { CommonTransaction.Overview(it) })
|
||||
addAll(pending.map { CommonTransaction.Pending(it) })
|
||||
}.toPersistentList()
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ import cash.z.ecc.android.sdk.Synchronizer
|
|||
import cash.z.ecc.android.sdk.model.UnifiedSpendingKey
|
||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||
import cash.z.ecc.android.sdk.model.ZecSend
|
||||
import cash.z.ecc.android.sdk.model.isFailedSubmit
|
||||
import cash.z.ecc.android.sdk.model.isSubmitSuccess
|
||||
import cash.z.ecc.sdk.send
|
||||
import co.electriccoin.zcash.spackle.Twig
|
||||
import co.electriccoin.zcash.ui.MainActivity
|
||||
|
@ -85,7 +83,9 @@ internal fun WrapSend(
|
|||
when (sendStage) {
|
||||
SendStage.Form -> goBack()
|
||||
SendStage.Confirmation -> setSendStage(SendStage.Form)
|
||||
SendStage.Sending -> { /* no action - wait until done */ }
|
||||
SendStage.Sending -> { // no action - wait until done
|
||||
}
|
||||
|
||||
SendStage.SendFailure -> setSendStage(SendStage.Form)
|
||||
SendStage.SendSuccessful -> goBack()
|
||||
}
|
||||
|
@ -108,21 +108,16 @@ internal fun WrapSend(
|
|||
onBack = onBackAction,
|
||||
onCreateAndSend = {
|
||||
scope.launch {
|
||||
synchronizer.send(spendingKey, it).collect {
|
||||
Twig.debug { "Sending transaction id: ${it.id}" }
|
||||
|
||||
if (it.isSubmitSuccess()) {
|
||||
Twig.debug { "Sending transaction" }
|
||||
runCatching { synchronizer.send(spendingKey, it) }
|
||||
.onSuccess {
|
||||
setSendStage(SendStage.SendSuccessful)
|
||||
Twig.debug {
|
||||
"Transaction id:${it.id} submitted successfully at ${it.createTime} with " +
|
||||
"${it.submitAttempts} attempts."
|
||||
}
|
||||
} else if (it.isFailedSubmit()) {
|
||||
Twig.debug { "Transaction id:${it.id} submission failed with: ${it.errorMessage}." }
|
||||
Twig.debug { "Transaction id:$it submitted successfully" }
|
||||
}
|
||||
.onFailure {
|
||||
Twig.debug { "Transaction submission failed with: $it." }
|
||||
setSendStage(SendStage.SendFailure)
|
||||
}
|
||||
// All other states of Pending transaction mean waiting for one of the states above
|
||||
}
|
||||
}
|
||||
},
|
||||
onQrScannerOpen = goToQrScanner,
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.work.PeriodicWorkRequestBuilder
|
|||
import androidx.work.WorkerParameters
|
||||
import cash.z.ecc.android.sdk.Synchronizer
|
||||
import cash.z.ecc.android.sdk.WalletCoordinator
|
||||
import cash.z.ecc.android.sdk.model.PercentDecimal
|
||||
import co.electriccoin.zcash.global.getInstance
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.collect
|
||||
|
@ -35,7 +36,7 @@ class SyncWorker(context: Context, workerParameters: WorkerParameters) : Corouti
|
|||
} ?: emptyFlow()
|
||||
}
|
||||
.takeWhile {
|
||||
it.status != Synchronizer.Status.DISCONNECTED && it.progress < ONE_HUNDRED_PERCENT
|
||||
it.status != Synchronizer.Status.DISCONNECTED && it.progress.isLessThanHundredPercent()
|
||||
}
|
||||
.collect()
|
||||
|
||||
|
@ -43,7 +44,6 @@ class SyncWorker(context: Context, workerParameters: WorkerParameters) : Corouti
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val ONE_HUNDRED_PERCENT = 100
|
||||
|
||||
/*
|
||||
* There may be better periods; we have not optimized for this yet.
|
||||
|
@ -63,4 +63,4 @@ class SyncWorker(context: Context, workerParameters: WorkerParameters) : Corouti
|
|||
}
|
||||
}
|
||||
|
||||
private data class StatusAndProgress(val status: Synchronizer.Status, val progress: Int)
|
||||
private data class StatusAndProgress(val status: Synchronizer.Status, val progress: PercentDecimal)
|
||||
|
|
Loading…
Reference in New Issue