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

211 lines
7.7 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
2020-12-13 06:08:42 -08:00
import androidx.lifecycle.lifecycleScope
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.util.SyncBlockchainBenchmarkTrace
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.ext.BenchmarkingExt
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.collectWith
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.fixture.BlockRangeFixture
import cash.z.ecc.android.sdk.internal.twig
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.model.Account
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
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
import cash.z.ecc.android.sdk.model.defaultForNetwork
2022-11-16 04:38:45 -08:00
import cash.z.ecc.android.sdk.tool.DerivationTool
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>() {
2020-12-14 08:10:50 -08:00
private lateinit var synchronizer: Synchronizer
2020-12-13 06:08:42 -08:00
2020-12-11 13:20:56 -08:00
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
setup()
}
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)
}
2020-12-13 06:08:42 -08:00
private fun setup() {
2020-12-13 06:14:05 -08:00
// defaults to the value of `DemoConfig.seedWords` but can also be set by the user
val seedPhrase = sharedViewModel.seedPhrase.value
2020-12-13 06:08:42 -08:00
2020-12-13 06:14:05 -08:00
// Use a BIP-39 library to convert a seed phrase into a byte array. Most wallets already
// have the seed stored
2020-12-13 06:08:42 -08:00
val seed = Mnemonics.MnemonicCode(seedPhrase).toSeed()
val network = ZcashNetwork.fromResources(requireApplicationContext())
synchronizer = Synchronizer.newBlocking(
requireApplicationContext(),
network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network),
seed = seed,
birthday = if (BenchmarkingExt.isBenchmarking()) {
BlockRangeFixture.new().start
} else {
sharedViewModel.birthdayHeight.value
}
)
2020-12-13 06:08:42 -08:00
}
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 {
synchronizer.shieldFunds(DerivationTool.deriveUnifiedSpendingKey(seed, network, Account.DEFAULT))
}
}
}
}
2020-12-13 06:08:42 -08:00
override fun onResume() {
super.onResume()
2020-12-13 06:14:05 -08:00
// the lifecycleScope is used to dispose of the synchronize when the fragment dies
2020-12-14 08:10:50 -08:00
synchronizer.start(lifecycleScope)
2020-12-13 06:08:42 -08:00
monitorChanges()
}
private fun monitorChanges() {
2020-12-14 08:10:50 -08:00
synchronizer.status.collectWith(lifecycleScope, ::onStatus)
2020-12-19 12:38:25 -08:00
synchronizer.progress.collectWith(lifecycleScope, ::onProgress)
synchronizer.processorInfo.collectWith(lifecycleScope, ::onProcessorInfoUpdated)
2022-11-02 09:39:48 -07:00
synchronizer.orchardBalances.collectWith(lifecycleScope, ::onOrchardBalance)
synchronizer.saplingBalances.collectWith(lifecycleScope, ::onSaplingBalance)
synchronizer.transparentBalances.collectWith(lifecycleScope, ::onTransparentBalance)
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"
2022-11-02 09:39:48 -07:00
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()
}