From d749aa08798834d7f8b9da1628adbffbe1b26022 Mon Sep 17 00:00:00 2001 From: Carter Jernigan Date: Fri, 20 May 2022 12:02:00 -0400 Subject: [PATCH] [#303] Zcash SDK 1.4.0-beta01 --- .../android/di/module/InitializerModule.kt | 2 +- .../android/di/module/SynchronizerModule.kt | 2 +- .../z/ecc/android/feedback/FeedbackFile.kt | 5 +++-- .../android/ui/profile/ProfileViewModel.kt | 15 ++++++++++----- .../android/ui/send/AutoShieldViewModel.kt | 19 +++++++++++++++---- .../z/ecc/android/ui/send/SendViewModel.kt | 13 ++++++++----- .../android/ui/setup/WalletSetupViewModel.kt | 12 ++++++++---- .../z/ecc/android/ui/util/DebugFileTwig.kt | 5 +++-- .../java/cash/z/ecc/android/Dependencies.kt | 2 +- gradle.properties | 14 +------------- settings.gradle.kts | 11 +++++++++++ 11 files changed, 62 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt index 9b9b318..121942e 100644 --- a/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/InitializerModule.kt @@ -11,5 +11,5 @@ class InitializerModule { @Provides @Reusable - fun provideInitializer(appContext: Context, config: Initializer.Config) = Initializer(appContext, config) + fun provideInitializer(appContext: Context, config: Initializer.Config) = Initializer.newBlocking(appContext, config) } diff --git a/app/src/main/java/cash/z/ecc/android/di/module/SynchronizerModule.kt b/app/src/main/java/cash/z/ecc/android/di/module/SynchronizerModule.kt index a4f497d..ec659ea 100644 --- a/app/src/main/java/cash/z/ecc/android/di/module/SynchronizerModule.kt +++ b/app/src/main/java/cash/z/ecc/android/di/module/SynchronizerModule.kt @@ -18,6 +18,6 @@ class SynchronizerModule { @Provides @SynchronizerScope fun provideSynchronizer(initializer: Initializer): Synchronizer { - return synchronizer ?: Synchronizer(initializer).also { synchronizer = it } + return synchronizer ?: Synchronizer.newBlocking(initializer).also { synchronizer = it } } } diff --git a/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt b/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt index 4ff58d4..19becda 100644 --- a/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt +++ b/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt @@ -1,7 +1,8 @@ package cash.z.ecc.android.feedback import cash.z.ecc.android.ZcashWalletApp -import okio.Okio +import okio.appendingSink +import okio.buffer import java.io.File import java.text.SimpleDateFormat @@ -30,7 +31,7 @@ class FeedbackFile(fileName: String = "user_log.txt") : } private fun appendToFile(message: String) { - Okio.buffer(Okio.appendingSink(file)).use { + file.appendingSink().buffer().use { it.writeUtf8("${format.format(System.currentTimeMillis())}|\t$message\n") } } diff --git a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileViewModel.kt index 6cf90d9..df1bbba 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileViewModel.kt @@ -9,9 +9,9 @@ import cash.z.ecc.android.sdk.Initializer import cash.z.ecc.android.sdk.Synchronizer import cash.z.ecc.android.sdk.db.entity.PendingTransaction import cash.z.ecc.android.sdk.ext.ZcashSdk -import cash.z.ecc.android.util.twig import cash.z.ecc.android.sdk.tool.DerivationTool import cash.z.ecc.android.sdk.type.WalletBalance +import cash.z.ecc.android.util.twig import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.runBlocking @@ -59,9 +59,9 @@ class ProfileViewModel @Inject constructor() : ViewModel() { fun shieldFunds(): Flow { return lockBox.getBytes(Const.Backup.SEED)?.let { - val sk = DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] - val tsk = DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) - val addr = DerivationTool.deriveTransparentAddressFromPrivateKey(tsk, synchronizer.network) + val sk = runBlocking { DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] } + val tsk = runBlocking { DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) } + val addr = runBlocking { DerivationTool.deriveTransparentAddressFromPrivateKey(tsk, synchronizer.network) } synchronizer.shieldFunds(sk, tsk, "${ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX}\nAll UTXOs from $addr").onEach { twig("Received shielding txUpdate: ${it?.toString()}") // updateMetrics(it) @@ -85,7 +85,12 @@ class ProfileViewModel @Inject constructor() : ViewModel() { fun wipe() { synchronizer.stop() Toast.makeText(ZcashWalletApp.instance, "SUCCESS! Wallet data cleared. Please relaunch to rescan!", Toast.LENGTH_LONG).show() - Initializer.erase(ZcashWalletApp.instance, ZcashWalletApp.instance.defaultNetwork) + runBlocking { + Initializer.erase( + ZcashWalletApp.instance, + ZcashWalletApp.instance.defaultNetwork + ) + } } suspend fun fullRescan() { diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/AutoShieldViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/send/AutoShieldViewModel.kt index 6690f7d..1ba5da3 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/AutoShieldViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/AutoShieldViewModel.kt @@ -11,13 +11,14 @@ import cash.z.ecc.android.sdk.db.entity.isMined import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess import cash.z.ecc.android.sdk.ext.ZcashSdk import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString -import cash.z.ecc.android.util.twig import cash.z.ecc.android.sdk.tool.DerivationTool import cash.z.ecc.android.sdk.type.WalletBalance +import cash.z.ecc.android.util.twig import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combineTransform import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import javax.inject.Inject class AutoShieldViewModel @Inject constructor() : ViewModel() { @@ -73,9 +74,19 @@ class AutoShieldViewModel @Inject constructor() : ViewModel() { fun shieldFunds(): Flow { return lockBox.getBytes(Const.Backup.SEED)?.let { - val sk = DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] - val tsk = DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) - val addr = DerivationTool.deriveTransparentAddressFromPrivateKey(tsk, synchronizer.network) + val sk = runBlocking { DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] } + val tsk = runBlocking { + DerivationTool.deriveTransparentSecretKey( + it, + synchronizer.network + ) + } + val addr = runBlocking { + DerivationTool.deriveTransparentAddressFromPrivateKey( + tsk, + synchronizer.network + ) + } synchronizer.shieldFunds(sk, tsk, "${ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX}\nAll UTXOs from $addr").onEach { tx -> twig("Received shielding txUpdate: ${tx?.toString()}") // updateMetrics(it) diff --git a/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt index 57596e4..a772242 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/send/SendViewModel.kt @@ -31,15 +31,16 @@ import cash.z.ecc.android.sdk.db.entity.isFailedSubmit import cash.z.ecc.android.sdk.db.entity.isMined import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess import cash.z.ecc.android.sdk.ext.ZcashSdk -import cash.z.ecc.android.util.twig import cash.z.ecc.android.sdk.tool.DerivationTool import cash.z.ecc.android.sdk.type.AddressType import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX_STANDARD +import cash.z.ecc.android.util.twig import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import java.lang.IllegalArgumentException import javax.inject.Inject @@ -75,10 +76,12 @@ class SendViewModel @Inject constructor() : ViewModel() { fun send(): Flow { funnel(SendSelected) val memoToSend = createMemoToSend() - val keys = DerivationTool.deriveSpendingKeys( - lockBox.getBytes(Const.Backup.SEED)!!, - synchronizer.network - ) + val keys = runBlocking { + DerivationTool.deriveSpendingKeys( + lockBox.getBytes(Const.Backup.SEED)!!, + synchronizer.network + ) + } funnel(SpendingKeyFound) reportUserInputIssues(memoToSend) return synchronizer.sendToAddress( diff --git a/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt b/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt index 410ec32..875212f 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/setup/WalletSetupViewModel.kt @@ -10,7 +10,6 @@ import cash.z.ecc.android.feedback.Report import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.sdk.Initializer import cash.z.ecc.android.sdk.exception.InitializerException -import cash.z.ecc.android.util.twig import cash.z.ecc.android.sdk.tool.DerivationTool import cash.z.ecc.android.sdk.tool.WalletBirthdayTool import cash.z.ecc.android.sdk.type.UnifiedViewingKey @@ -19,6 +18,7 @@ import cash.z.ecc.android.sdk.type.ZcashNetwork import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.NO_SEED import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITHOUT_BACKUP import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP +import cash.z.ecc.android.util.twig import cash.z.ecc.kotlin.mnemonic.Mnemonics import com.bugsnag.android.Bugsnag import kotlinx.coroutines.Dispatchers.IO @@ -167,13 +167,17 @@ class WalletSetupViewModel @Inject constructor() : ViewModel() { } } - private fun onMissingBirthday(network: ZcashNetwork): Int = failWith(InitializerException.MissingBirthdayException) { + private suspend fun onMissingBirthday(network: ZcashNetwork): Int = failWith(InitializerException.MissingBirthdayException) { twig("Recover Birthday: falling back to sapling birthday") loadNearestBirthday(network, network.saplingActivationHeight).height } - private fun loadNearestBirthday(network: ZcashNetwork, birthdayHeight: Int? = null) = - WalletBirthdayTool.loadNearest(ZcashWalletApp.instance, network, birthdayHeight) + private suspend fun loadNearestBirthday(network: ZcashNetwork, birthdayHeight: Int? = null) = + WalletBirthdayTool.loadNearest( + ZcashWalletApp.instance, + network, + birthdayHeight + ) // // Storage Helpers diff --git a/app/src/main/java/cash/z/ecc/android/ui/util/DebugFileTwig.kt b/app/src/main/java/cash/z/ecc/android/ui/util/DebugFileTwig.kt index cef4986..f4a1fd2 100644 --- a/app/src/main/java/cash/z/ecc/android/ui/util/DebugFileTwig.kt +++ b/app/src/main/java/cash/z/ecc/android/ui/util/DebugFileTwig.kt @@ -2,7 +2,8 @@ package cash.z.ecc.android.ui.util import cash.z.ecc.android.ZcashWalletApp import cash.z.ecc.android.util.TroubleshootingTwig -import okio.Okio +import okio.appendingSink +import okio.buffer import java.io.File class DebugFileTwig(fileName: String = "developer_log.txt") : TroubleshootingTwig(formatter = spiffy(6)) { @@ -14,7 +15,7 @@ class DebugFileTwig(fileName: String = "developer_log.txt") : TroubleshootingTwi } private fun appendToFile(message: String) { - Okio.buffer(Okio.appendingSink(file)).use { + file.appendingSink().buffer().use { it.writeUtf8("$message\n") } } diff --git a/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt b/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt index 7c08ab1..05f31e3 100644 --- a/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt +++ b/buildSrc/src/main/java/cash/z/ecc/android/Dependencies.kt @@ -83,7 +83,7 @@ object Deps { object Zcash { const val ANDROID_WALLET_PLUGINS = "cash.z.ecc.android:zcash-android-wallet-plugins:1.0.0" const val KOTLIN_BIP39 = "cash.z.ecc.android:kotlin-bip39:1.0.1" - const val SDK = "cash.z.ecc.android:zcash-android-sdk:1.3.0-beta19" + const val SDK = "cash.z.ecc.android:zcash-android-sdk:1.4.0-beta01" } object Misc { const val LOTTIE = "com.airbnb.android:lottie:3.7.0" diff --git a/gradle.properties b/gradle.properties index fe0ffe1..f5e6189 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,19 +1,7 @@ -## For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx1024m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -# -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -#Wed Jan 29 09:45:08 EST 2020 kotlin.code.style=official android.enableJetifier=true -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" +org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m android.useAndroidX=true dagger.fastInit=enabled android.builder.sdkDownload=true diff --git a/settings.gradle.kts b/settings.gradle.kts index fe2a6e6..3ca9873 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,11 +9,22 @@ pluginManagement { } dependencyResolutionManagement { + @Suppress("UnstableApiUsage") repositories { + val isRepoRestrictionEnabled = true + google() mavenCentral() maven("https://jitpack.io") jcenter() + // Uncomment to use a snapshot version of the SDK, e.g. when the SDK version ends in -SNAPSHOT + // maven("https://oss.sonatype.org/content/repositories/snapshots") { + // if (isRepoRestrictionEnabled) { + // content { + // includeGroup("cash.z.ecc.android") + // } + // } + //} } }