[#303] Zcash SDK 1.4.0-beta01

This commit is contained in:
Carter Jernigan 2022-05-20 12:02:00 -04:00 committed by Carter Jernigan
parent cb7c2d3e74
commit d749aa0879
11 changed files with 62 additions and 38 deletions

View File

@ -11,5 +11,5 @@ class InitializerModule {
@Provides @Provides
@Reusable @Reusable
fun provideInitializer(appContext: Context, config: Initializer.Config) = Initializer(appContext, config) fun provideInitializer(appContext: Context, config: Initializer.Config) = Initializer.newBlocking(appContext, config)
} }

View File

@ -18,6 +18,6 @@ class SynchronizerModule {
@Provides @Provides
@SynchronizerScope @SynchronizerScope
fun provideSynchronizer(initializer: Initializer): Synchronizer { fun provideSynchronizer(initializer: Initializer): Synchronizer {
return synchronizer ?: Synchronizer(initializer).also { synchronizer = it } return synchronizer ?: Synchronizer.newBlocking(initializer).also { synchronizer = it }
} }
} }

View File

@ -1,7 +1,8 @@
package cash.z.ecc.android.feedback package cash.z.ecc.android.feedback
import cash.z.ecc.android.ZcashWalletApp import cash.z.ecc.android.ZcashWalletApp
import okio.Okio import okio.appendingSink
import okio.buffer
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -30,7 +31,7 @@ class FeedbackFile(fileName: String = "user_log.txt") :
} }
private fun appendToFile(message: String) { private fun appendToFile(message: String) {
Okio.buffer(Okio.appendingSink(file)).use { file.appendingSink().buffer().use {
it.writeUtf8("${format.format(System.currentTimeMillis())}|\t$message\n") it.writeUtf8("${format.format(System.currentTimeMillis())}|\t$message\n")
} }
} }

View File

@ -9,9 +9,9 @@ import cash.z.ecc.android.sdk.Initializer
import cash.z.ecc.android.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.db.entity.PendingTransaction import cash.z.ecc.android.sdk.db.entity.PendingTransaction
import cash.z.ecc.android.sdk.ext.ZcashSdk 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.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.util.twig
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -59,9 +59,9 @@ class ProfileViewModel @Inject constructor() : ViewModel() {
fun shieldFunds(): Flow<PendingTransaction> { fun shieldFunds(): Flow<PendingTransaction> {
return lockBox.getBytes(Const.Backup.SEED)?.let { return lockBox.getBytes(Const.Backup.SEED)?.let {
val sk = DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] val sk = runBlocking { DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] }
val tsk = DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) val tsk = runBlocking { DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) }
val addr = DerivationTool.deriveTransparentAddressFromPrivateKey(tsk, 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 { synchronizer.shieldFunds(sk, tsk, "${ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX}\nAll UTXOs from $addr").onEach {
twig("Received shielding txUpdate: ${it?.toString()}") twig("Received shielding txUpdate: ${it?.toString()}")
// updateMetrics(it) // updateMetrics(it)
@ -85,7 +85,12 @@ class ProfileViewModel @Inject constructor() : ViewModel() {
fun wipe() { fun wipe() {
synchronizer.stop() synchronizer.stop()
Toast.makeText(ZcashWalletApp.instance, "SUCCESS! Wallet data cleared. Please relaunch to rescan!", Toast.LENGTH_LONG).show() 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() { suspend fun fullRescan() {

View File

@ -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.db.entity.isSubmitSuccess
import cash.z.ecc.android.sdk.ext.ZcashSdk import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString 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.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.util.twig
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combineTransform import kotlinx.coroutines.flow.combineTransform
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import javax.inject.Inject import javax.inject.Inject
class AutoShieldViewModel @Inject constructor() : ViewModel() { class AutoShieldViewModel @Inject constructor() : ViewModel() {
@ -73,9 +74,19 @@ class AutoShieldViewModel @Inject constructor() : ViewModel() {
fun shieldFunds(): Flow<PendingTransaction> { fun shieldFunds(): Flow<PendingTransaction> {
return lockBox.getBytes(Const.Backup.SEED)?.let { return lockBox.getBytes(Const.Backup.SEED)?.let {
val sk = DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] val sk = runBlocking { DerivationTool.deriveSpendingKeys(it, synchronizer.network)[0] }
val tsk = DerivationTool.deriveTransparentSecretKey(it, synchronizer.network) val tsk = runBlocking {
val addr = DerivationTool.deriveTransparentAddressFromPrivateKey(tsk, synchronizer.network) 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 -> synchronizer.shieldFunds(sk, tsk, "${ZcashSdk.DEFAULT_SHIELD_FUNDS_MEMO_PREFIX}\nAll UTXOs from $addr").onEach { tx ->
twig("Received shielding txUpdate: ${tx?.toString()}") twig("Received shielding txUpdate: ${tx?.toString()}")
// updateMetrics(it) // updateMetrics(it)

View File

@ -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.isMined
import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess import cash.z.ecc.android.sdk.db.entity.isSubmitSuccess
import cash.z.ecc.android.sdk.ext.ZcashSdk 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.tool.DerivationTool
import cash.z.ecc.android.sdk.type.AddressType import cash.z.ecc.android.sdk.type.AddressType
import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX_STANDARD 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.Dispatchers.IO
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.lang.IllegalArgumentException import java.lang.IllegalArgumentException
import javax.inject.Inject import javax.inject.Inject
@ -75,10 +76,12 @@ class SendViewModel @Inject constructor() : ViewModel() {
fun send(): Flow<PendingTransaction> { fun send(): Flow<PendingTransaction> {
funnel(SendSelected) funnel(SendSelected)
val memoToSend = createMemoToSend() val memoToSend = createMemoToSend()
val keys = DerivationTool.deriveSpendingKeys( val keys = runBlocking {
lockBox.getBytes(Const.Backup.SEED)!!, DerivationTool.deriveSpendingKeys(
synchronizer.network lockBox.getBytes(Const.Backup.SEED)!!,
) synchronizer.network
)
}
funnel(SpendingKeyFound) funnel(SpendingKeyFound)
reportUserInputIssues(memoToSend) reportUserInputIssues(memoToSend)
return synchronizer.sendToAddress( return synchronizer.sendToAddress(

View File

@ -10,7 +10,6 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.lockbox.LockBox
import cash.z.ecc.android.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.ecc.android.sdk.exception.InitializerException 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.DerivationTool
import cash.z.ecc.android.sdk.tool.WalletBirthdayTool import cash.z.ecc.android.sdk.tool.WalletBirthdayTool
import cash.z.ecc.android.sdk.type.UnifiedViewingKey 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.NO_SEED
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITHOUT_BACKUP 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.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP
import cash.z.ecc.android.util.twig
import cash.z.ecc.kotlin.mnemonic.Mnemonics import cash.z.ecc.kotlin.mnemonic.Mnemonics
import com.bugsnag.android.Bugsnag import com.bugsnag.android.Bugsnag
import kotlinx.coroutines.Dispatchers.IO 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") twig("Recover Birthday: falling back to sapling birthday")
loadNearestBirthday(network, network.saplingActivationHeight).height loadNearestBirthday(network, network.saplingActivationHeight).height
} }
private fun loadNearestBirthday(network: ZcashNetwork, birthdayHeight: Int? = null) = private suspend fun loadNearestBirthday(network: ZcashNetwork, birthdayHeight: Int? = null) =
WalletBirthdayTool.loadNearest(ZcashWalletApp.instance, network, birthdayHeight) WalletBirthdayTool.loadNearest(
ZcashWalletApp.instance,
network,
birthdayHeight
)
// //
// Storage Helpers // Storage Helpers

View File

@ -2,7 +2,8 @@ package cash.z.ecc.android.ui.util
import cash.z.ecc.android.ZcashWalletApp import cash.z.ecc.android.ZcashWalletApp
import cash.z.ecc.android.util.TroubleshootingTwig import cash.z.ecc.android.util.TroubleshootingTwig
import okio.Okio import okio.appendingSink
import okio.buffer
import java.io.File import java.io.File
class DebugFileTwig(fileName: String = "developer_log.txt") : TroubleshootingTwig(formatter = spiffy(6)) { 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) { private fun appendToFile(message: String) {
Okio.buffer(Okio.appendingSink(file)).use { file.appendingSink().buffer().use {
it.writeUtf8("$message\n") it.writeUtf8("$message\n")
} }
} }

View File

@ -83,7 +83,7 @@ object Deps {
object Zcash { object Zcash {
const val ANDROID_WALLET_PLUGINS = "cash.z.ecc.android:zcash-android-wallet-plugins:1.0.0" 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 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 { object Misc {
const val LOTTIE = "com.airbnb.android:lottie:3.7.0" const val LOTTIE = "com.airbnb.android:lottie:3.7.0"

View File

@ -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 # org.gradle.parallel=true
#Wed Jan 29 09:45:08 EST 2020
kotlin.code.style=official kotlin.code.style=official
android.enableJetifier=true android.enableJetifier=true
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m
android.useAndroidX=true android.useAndroidX=true
dagger.fastInit=enabled dagger.fastInit=enabled
android.builder.sdkDownload=true android.builder.sdkDownload=true

View File

@ -9,11 +9,22 @@ pluginManagement {
} }
dependencyResolutionManagement { dependencyResolutionManagement {
@Suppress("UnstableApiUsage")
repositories { repositories {
val isRepoRestrictionEnabled = true
google() google()
mavenCentral() mavenCentral()
maven("https://jitpack.io") maven("https://jitpack.io")
jcenter() 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")
// }
// }
//}
} }
} }