zcash-android-wallet-sdk/demo-app/src/main/java/cash/z/ecc/android/sdk/demoapp/demos/getbalance/GetBalanceFragment.kt

224 lines
8.0 KiB
Kotlin
Raw Normal View History

2020-12-11 13:20:56 -08:00
package cash.z.ecc.android.sdk.demoapp.demos.getbalance
2020-12-13 06:08:42 -08:00
import android.os.Bundle
2020-12-11 13:20:56 -08:00
import android.view.LayoutInflater
import android.view.Menu
2022-11-16 04:38:45 -08:00
import android.view.View
import androidx.lifecycle.Lifecycle
2020-12-13 06:08:42 -08:00
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
2020-12-13 06:08:42 -08:00
import cash.z.ecc.android.bip39.Mnemonics
import cash.z.ecc.android.bip39.toSeed
import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
2020-12-11 13:20:56 -08:00
import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.R
2020-12-11 13:20:56 -08:00
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentGetBalanceBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.type.fromResources
import cash.z.ecc.android.sdk.demoapp.util.SyncBlockchainBenchmarkTrace
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.ext.ZcashSdk
2020-12-13 06:08:42 -08:00
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.internal.twig
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.model.Account
2022-07-07 05:52:07 -07:00
import cash.z.ecc.android.sdk.model.WalletBalance
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.model.Zatoshi
import cash.z.ecc.android.sdk.model.ZcashNetwork
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.tool.DerivationTool
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
2022-11-16 04:38:45 -08:00
import kotlinx.coroutines.launch
2020-12-11 13:20:56 -08:00
2020-12-14 08:10:50 -08:00
/**
* Displays the available balance && total balance associated with the seed defined by the default config.
* comments.
*/
2022-11-02 09:39:48 -07:00
@Suppress("TooManyFunctions")
2020-12-11 13:20:56 -08:00
class GetBalanceFragment : BaseDemoFragment<FragmentGetBalanceBinding>() {
override fun inflateBinding(layoutInflater: LayoutInflater): FragmentGetBalanceBinding =
FragmentGetBalanceBinding.inflate(layoutInflater)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
reportTraceEvent(SyncBlockchainBenchmarkTrace.Event.BALANCE_SCREEN_START)
setHasOptionsMenu(true)
2020-12-13 06:08:42 -08:00
}
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
// We rather hide options menu actions while actively using the Synchronizer
menu.setGroupVisible(R.id.main_menu_group, false)
}
override fun onDestroy() {
super.onDestroy()
reportTraceEvent(SyncBlockchainBenchmarkTrace.Event.BALANCE_SCREEN_END)
}
2022-11-16 04:38:45 -08:00
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val seedPhrase = sharedViewModel.seedPhrase.value
val seed = Mnemonics.MnemonicCode(seedPhrase).toSeed()
val network = ZcashNetwork.fromResources(requireApplicationContext())
binding.shield.apply {
setOnClickListener {
lifecycleScope.launch {
sharedViewModel.synchronizerFlow.value?.shieldFunds(
DerivationTool.deriveUnifiedSpendingKey(
seed,
network,
Account.DEFAULT
)
)
2022-11-16 04:38:45 -08:00
}
}
}
2020-12-13 06:08:42 -08:00
monitorChanges()
}
@OptIn(ExperimentalCoroutinesApi::class)
2020-12-13 06:08:42 -08:00
private fun monitorChanges() {
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.status }
.collect { onStatus(it) }
}
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.progress }
.collect { onProgress(it) }
}
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.processorInfo }
.collect { onProcessorInfoUpdated(it) }
}
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.saplingBalances }
.collect { onSaplingBalance(it) }
}
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.orchardBalances }
.collect { onOrchardBalance(it) }
}
launch {
sharedViewModel.synchronizerFlow
.filterNotNull()
.flatMapLatest { it.transparentBalances }
.collect { onTransparentBalance(it) }
}
}
}
2020-12-13 06:08:42 -08:00
}
2022-11-02 09:39:48 -07:00
private fun onOrchardBalance(
orchardBalance: WalletBalance?
) {
binding.orchardBalance.apply {
text = orchardBalance.humanString()
}
}
private fun onSaplingBalance(
saplingBalance: WalletBalance?
) {
binding.saplingBalance.apply {
text = saplingBalance.humanString()
}
}
private fun onTransparentBalance(
transparentBalance: WalletBalance?
) {
binding.transparentBalance.apply {
text = transparentBalance.humanString()
}
2022-11-16 04:38:45 -08:00
binding.shield.apply {
// TODO [#776]: Support variable fees
// TODO [#776]: https://github.com/zcash/zcash-android-wallet-sdk/issues/776
2022-11-16 04:38:45 -08:00
visibility = if ((transparentBalance?.available ?: Zatoshi(0)) > ZcashSdk.MINERS_FEE) {
View.VISIBLE
} else {
View.GONE
}
}
2020-12-13 06:08:42 -08:00
}
private fun onStatus(status: Synchronizer.Status) {
twig("Synchronizer status: $status")
// report benchmark event
val traceEvents = when (status) {
Synchronizer.Status.DOWNLOADING -> {
listOf(
SyncBlockchainBenchmarkTrace.Event.BLOCKCHAIN_SYNC_START,
SyncBlockchainBenchmarkTrace.Event.DOWNLOAD_START
)
}
Synchronizer.Status.VALIDATING -> {
listOf(
SyncBlockchainBenchmarkTrace.Event.DOWNLOAD_END,
SyncBlockchainBenchmarkTrace.Event.VALIDATION_START
)
}
Synchronizer.Status.SCANNING -> {
listOf(
SyncBlockchainBenchmarkTrace.Event.VALIDATION_END,
SyncBlockchainBenchmarkTrace.Event.SCAN_START
)
}
Synchronizer.Status.SYNCED -> {
listOf(
SyncBlockchainBenchmarkTrace.Event.SCAN_END,
SyncBlockchainBenchmarkTrace.Event.BLOCKCHAIN_SYNC_END
)
}
else -> null
}
traceEvents?.forEach { reportTraceEvent(it) }
2020-12-19 12:38:25 -08:00
binding.textStatus.text = "Status: $status"
sharedViewModel.synchronizerFlow.value?.let { synchronizer ->
onOrchardBalance(synchronizer.orchardBalances.value)
onSaplingBalance(synchronizer.saplingBalances.value)
onTransparentBalance(synchronizer.transparentBalances.value)
}
2020-12-13 06:08:42 -08:00
}
2020-12-14 08:10:50 -08:00
[#366] Fix Detekt warnings * Disable baseline file. Too many functions. * CurrencyFormatter.kt suppress too many functions * PersistentTransactionManager.kt suppress too many functions * OutboundTransactionManager suppress too many functions * Suppress long parameter list * Too many functions * Add log to avoid empty block warning * Fix several magic number warnings * Solve max line length warnings * Solve max line length warnings * Suppress too long method warnings * Suppress too complex method warnings * Suppress large class warning * Fixed empty catch block * Changed directory path to the file * Fix too generic and swallowed exception * Fix print stack trace warning * Suppressed single top level file name declaration * Change parameters name * Suppress Spread operator warning * Remove unused private code * Add Locale to suppress default locale used warning * Solve several forbidden TODOs warnings * Fixed another max line length warning * Simplify return statement * Suppress class to object change * Make DemoConstants variables const * Use error() instead of throwing an IllegalStateException * Solve too complex condition * Suppress intentionally generic and swallowed exception * Suppress TooGenericExceptionCaught * Solve or suppress several TooGenericExceptionCaught * Fix swallowed exception * Suppress warning TooGenericExceptionCaught of PersistentTransactionManager * Suppress warning TooGenericExceptionCaught of WalletTransactionEncoder * Suppress TooGenericExceptionCaught of SdkSynchronizer * Suppress TooGenericExceptionCaught in SaplingParamTool * Suppress TooGenericExceptionCaught in CompactBlockDownloader * Suppress TooGenericExceptionCaught in CheckpointTool * Fix TooGenericExceptionCaught in WalletService * Suppress TooGenericExceptionCaught in DerivedDataDb * Suppress TooGenericExceptionCaught in CompactBlockProcessor * Apply ktlint format after all the previous changes * Remove detekt baseline file * Set Android studio right margin * Address comments from review * Suppress failing tests on CI
2022-08-23 06:49:00 -07:00
@Suppress("MagicNumber")
2020-12-19 12:38:25 -08:00
private fun onProgress(i: Int) {
if (i < 100) {
binding.textStatus.text = "Downloading blocks...$i%"
}
}
private fun onProcessorInfoUpdated(info: CompactBlockProcessor.ProcessorInfo) {
if (info.isScanning) binding.textStatus.text = "Scanning blocks...${info.scanProgress}%"
}
2020-12-11 13:20:56 -08:00
}
2022-11-02 09:39:48 -07:00
@Suppress("MagicNumber")
private fun WalletBalance?.humanString() = if (null == this) {
"Calculating balance"
} else {
"""
2022-11-16 04:38:45 -08:00
Pending balance: ${pending.convertZatoshiToZecString(12)}
2022-11-02 09:39:48 -07:00
Available balance: ${available.convertZatoshiToZecString(12)}
Total balance: ${total.convertZatoshiToZecString(12)}
""".trimIndent()
}