v1.9.0-beta01 changes

This commit includes HUSH specific changes starting at v.1.9.0-beta01 release here: https://github.com/zcash/zcash-android-wallet-sdk/releases/tag/v1.9.0-beta01
This commit is contained in:
fekt
2022-11-29 20:19:12 -05:00
parent 1b4660b53b
commit 2225f65ee7
115 changed files with 2335 additions and 1766 deletions

View File

@@ -20,7 +20,9 @@ import androidx.viewbinding.ViewBinding
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
import cash.z.ecc.android.sdk.internal.service.LightWalletService
import cash.z.ecc.android.sdk.type.ZcashNetwork
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.model.defaultForNetwork
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.navigation.NavigationView
@@ -108,7 +110,11 @@ class MainActivity :
if (lightwalletService != null) {
lightwalletService?.shutdown()
}
lightwalletService = LightWalletGrpcService(applicationContext, ZcashNetwork.fromResources(applicationContext))
val network = ZcashNetwork.fromResources(applicationContext)
lightwalletService = LightWalletGrpcService.new(
applicationContext,
LightWalletEndpoint.defaultForNetwork(network)
)
}
private fun onFabClicked(view: View) {

View File

@@ -9,9 +9,9 @@ import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentGetAddressBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

View File

@@ -14,9 +14,11 @@ import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.ext.collectWith
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.model.defaultForNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.runBlocking
@@ -50,8 +52,12 @@ class GetBalanceFragment : BaseDemoFragment<FragmentGetBalanceBinding>() {
// using the ViewingKey to initialize
runBlocking {
Initializer.new(requireApplicationContext(), null) {
it.setNetwork(ZcashNetwork.fromResources(requireApplicationContext()))
it.importWallet(viewingKey, network = ZcashNetwork.fromResources(requireApplicationContext()))
val network = ZcashNetwork.fromResources(requireApplicationContext())
it.newWallet(
viewingKey,
network = network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
)
}
}.let { initializer ->
synchronizer = Synchronizer.newBlocking(initializer)
@@ -81,7 +87,7 @@ class GetBalanceFragment : BaseDemoFragment<FragmentGetBalanceBinding>() {
private fun onStatus(status: Synchronizer.Status) {
binding.textStatus.text = "Status: $status"
val balance = synchronizer.saplingBalances.value
val balance: WalletBalance? = synchronizer.saplingBalances.value
if (null == balance) {
binding.textBalance.text = "Calculating balance..."
} else {

View File

@@ -7,11 +7,15 @@ import android.view.View
import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentGetBlockBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.demoapp.util.mainActivity
import cash.z.ecc.android.sdk.demoapp.util.toHtml
import cash.z.ecc.android.sdk.demoapp.util.toRelativeTime
import cash.z.ecc.android.sdk.demoapp.util.withCommas
import cash.z.ecc.android.sdk.ext.toHex
import cash.z.ecc.android.sdk.model.BlockHeight
import cash.z.ecc.android.sdk.model.ZcashNetwork
import kotlin.math.min
/**
* Retrieves a compact block from the lightwalletd service and displays basic information about it.
@@ -20,7 +24,7 @@ import cash.z.ecc.android.sdk.ext.toHex
*/
class GetBlockFragment : BaseDemoFragment<FragmentGetBlockBinding>() {
private fun setBlockHeight(blockHeight: Int) {
private fun setBlockHeight(blockHeight: BlockHeight) {
val blocks =
lightwalletService?.getBlockRange(blockHeight..blockHeight)
val block = blocks?.firstOrNull()
@@ -38,8 +42,11 @@ class GetBlockFragment : BaseDemoFragment<FragmentGetBlockBinding>() {
}
private fun onApply(_unused: View? = null) {
val network = ZcashNetwork.fromResources(requireApplicationContext())
val newHeight = min(binding.textBlockHeight.text.toString().toLongOrNull() ?: network.saplingActivationHeight.value, network.saplingActivationHeight.value)
try {
setBlockHeight(binding.textBlockHeight.text.toString().toInt())
setBlockHeight(BlockHeight.new(network, newHeight))
} catch (t: Throwable) {
toast("Error: $t")
}

View File

@@ -8,9 +8,13 @@ import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.R
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentGetBlockRangeBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.demoapp.util.mainActivity
import cash.z.ecc.android.sdk.demoapp.util.toRelativeTime
import cash.z.ecc.android.sdk.demoapp.util.withCommas
import cash.z.ecc.android.sdk.model.BlockHeight
import cash.z.ecc.android.sdk.model.ZcashNetwork
import kotlin.math.max
/**
* Retrieves a range of compact block from the lightwalletd service and displays basic information
@@ -20,16 +24,17 @@ import cash.z.ecc.android.sdk.demoapp.util.withCommas
*/
class GetBlockRangeFragment : BaseDemoFragment<FragmentGetBlockRangeBinding>() {
private fun setBlockRange(blockRange: IntRange) {
private fun setBlockRange(blockRange: ClosedRange<BlockHeight>) {
val start = System.currentTimeMillis()
val blocks =
lightwalletService?.getBlockRange(blockRange)
val fetchDelta = System.currentTimeMillis() - start
// Note: This is a demo so we won't worry about iterating efficiently over these blocks
// Note: Converting the blocks sequence to a list can consume a lot of memory and may
// cause OOM.
binding.textInfo.text = Html.fromHtml(
blocks?.run {
blocks?.toList()?.run {
val count = size
val emptyCount = count { it.vtxCount == 0 }
val maxTxs = maxByOrNull { it.vtxCount }
@@ -41,9 +46,9 @@ class GetBlockRangeFragment : BaseDemoFragment<FragmentGetBlockRangeBinding>() {
block.vtxList.maxOfOrNull { it.outputsCount } ?: -1
}
val maxOutTx = maxOuts?.vtxList?.maxByOrNull { it.outputsCount }
val txCount = sumBy { it.vtxCount }
val outCount = sumBy { block -> block.vtxList.sumBy { it.outputsCount } }
val inCount = sumBy { block -> block.vtxList.sumBy { it.spendsCount } }
val txCount = sumOf { it.vtxCount }
val outCount = sumOf { block -> block.vtxList.sumOf { it.outputsCount } }
val inCount = sumOf { block -> block.vtxList.sumOf { it.spendsCount } }
val processTime = System.currentTimeMillis() - start - fetchDelta
@Suppress("MaxLineLength")
@@ -69,8 +74,9 @@ class GetBlockRangeFragment : BaseDemoFragment<FragmentGetBlockRangeBinding>() {
}
private fun onApply(_unused: View) {
val start = binding.textStartHeight.text.toString().toInt()
val end = binding.textEndHeight.text.toString().toInt()
val network = ZcashNetwork.fromResources(requireApplicationContext())
val start = max(binding.textStartHeight.text.toString().toLongOrNull() ?: network.saplingActivationHeight.value, network.saplingActivationHeight.value)
val end = max(binding.textEndHeight.text.toString().toLongOrNull() ?: network.saplingActivationHeight.value, network.saplingActivationHeight.value)
if (start <= end) {
try {
with(binding.buttonApply) {
@@ -78,7 +84,7 @@ class GetBlockRangeFragment : BaseDemoFragment<FragmentGetBlockRangeBinding>() {
setText(R.string.loading)
binding.textInfo.setText(R.string.loading)
post {
setBlockRange(start..end)
setBlockRange(BlockHeight.new(network, start)..BlockHeight.new(network, end))
isEnabled = true
setText(R.string.apply)
}

View File

@@ -9,8 +9,8 @@ import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentGetPrivateKeyBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.launch
/**

View File

@@ -17,8 +17,10 @@ import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.ext.collectWith
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.model.defaultForNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.runBlocking
/**
@@ -48,12 +50,20 @@ class ListTransactionsFragment : BaseDemoFragment<FragmentListTransactionsBindin
// have the seed stored
val seed = Mnemonics.MnemonicCode(seedPhrase).toSeed()
initializer = runBlocking {
Initializer.new(requireApplicationContext()) {
runBlocking { it.importWallet(seed, network = ZcashNetwork.fromResources(requireApplicationContext())) }
it.setNetwork(ZcashNetwork.fromResources(requireApplicationContext()))
initializer = Initializer.newBlocking(
requireApplicationContext(),
Initializer.Config {
val network = ZcashNetwork.fromResources(requireApplicationContext())
runBlocking {
it.importWallet(
seed,
birthday = null,
network = network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
)
}
}
}
)
address = runBlocking {
DerivationTool.deriveShieldedAddress(
seed,

View File

@@ -1,5 +1,6 @@
package cash.z.ecc.android.sdk.demoapp.demos.listutxos
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -13,20 +14,23 @@ import cash.z.ecc.android.sdk.Synchronizer
import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.ecc.android.sdk.demoapp.BaseDemoFragment
import cash.z.ecc.android.sdk.demoapp.DemoConstants
import cash.z.ecc.android.sdk.demoapp.databinding.FragmentListUtxosBinding
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
import cash.z.ecc.android.sdk.demoapp.util.fromResources
import cash.z.ecc.android.sdk.demoapp.util.mainActivity
import cash.z.ecc.android.sdk.ext.collectWith
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.BlockHeight
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.model.defaultForNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import kotlin.math.max
/**
* ===============================================================================================
@@ -62,8 +66,15 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
// have the seed stored
seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
initializer = runBlocking {
val network = ZcashNetwork.fromResources(requireApplicationContext())
Initializer.new(requireApplicationContext()) {
runBlocking { it.importWallet(seed, network = ZcashNetwork.fromResources(requireApplicationContext())) }
runBlocking {
it.newWallet(
seed,
network = network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
)
}
it.alias = "Demo_Utxos"
}
}
@@ -78,38 +89,48 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
fun initUi() {
binding.inputAddress.setText(address)
binding.inputRangeStart.setText(ZcashNetwork.fromResources(requireApplicationContext()).saplingActivationHeight.toString())
binding.inputRangeEnd.setText(DemoConstants.utxoEndHeight.toString())
binding.inputRangeEnd.setText(getUxtoEndHeight(requireApplicationContext()).value.toString())
binding.buttonLoad.setOnClickListener {
mainActivity()?.hideKeyboard()
//downloadTransactions()
downloadTransactions()
}
initTransactionUi()
}
/* THIS IS NOT SUPPORTED IN HUSH LIGHTWALLETD
fun downloadTransactions() {
binding.textStatus.text = "loading..."
binding.textStatus.post {
val network = ZcashNetwork.fromResources(requireApplicationContext())
binding.textStatus.requestFocus()
val addressToUse = binding.inputAddress.text.toString()
val startToUse = binding.inputRangeStart.text.toString().toIntOrNull() ?: ZcashNetwork.fromResources(requireApplicationContext()).saplingActivationHeight
val endToUse = binding.inputRangeEnd.text.toString().toIntOrNull() ?: DemoConstants.utxoEndHeight
val startToUse = max(
binding.inputRangeStart.text.toString().toLongOrNull()
?: network.saplingActivationHeight.value,
network.saplingActivationHeight.value
)
val endToUse = binding.inputRangeEnd.text.toString().toLongOrNull()
?: getUxtoEndHeight(requireApplicationContext()).value
var allStart = now
twig("loading transactions in range $startToUse..$endToUse")
val txids = lightwalletService?.getTAddressTransactions(addressToUse, startToUse..endToUse)
val txids = lightwalletService?.getTAddressTransactions(
addressToUse,
BlockHeight.new(network, startToUse)..BlockHeight.new(network, endToUse)
)
var delta = now - allStart
updateStatus("found ${txids?.size} transactions in ${delta}ms.", false)
txids?.map {
it.data.apply {
try {
runBlocking { initializer.rustBackend.decryptAndStoreTransaction(toByteArray()) }
} catch (t: Throwable) {
twig("failed to decrypt and store transaction due to: $t")
}
}
// Disabled during migration to newer SDK version; this appears to have been
// leveraging non-public APIs in the SDK so perhaps should be removed
// it.data.apply {
// try {
// runBlocking { initializer.rustBackend.decryptAndStoreTransaction(toByteArray()) }
// } catch (t: Throwable) {
// twig("failed to decrypt and store transaction due to: $t")
// }
// }
}?.let { txData ->
// Disabled during migration to newer SDK version; this appears to have been
// leveraging non-public APIs in the SDK so perhaps should be removed
@@ -136,7 +157,6 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
}
}
}
*/
private val now get() = System.currentTimeMillis()
@@ -159,7 +179,12 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
resetInBackground()
val seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
binding.inputAddress.setText(DerivationTool.deriveTransparentAddress(seed, ZcashNetwork.fromResources(requireApplicationContext())))
binding.inputAddress.setText(
DerivationTool.deriveTransparentAddress(
seed,
ZcashNetwork.fromResources(requireApplicationContext())
)
)
}
}
@@ -248,4 +273,9 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
}
}
}
@Suppress("MagicNumber")
private fun getUxtoEndHeight(context: Context): BlockHeight {
return BlockHeight.new(ZcashNetwork.fromResources(context), 968085L)
}
}

View File

@@ -29,9 +29,11 @@ import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.ecc.android.sdk.ext.toZecString
import cash.z.ecc.android.sdk.internal.Twig
import cash.z.ecc.android.sdk.internal.twig
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
import cash.z.ecc.android.sdk.model.WalletBalance
import cash.z.ecc.android.sdk.model.ZcashNetwork
import cash.z.ecc.android.sdk.model.defaultForNetwork
import cash.z.ecc.android.sdk.tool.DerivationTool
import cash.z.ecc.android.sdk.type.WalletBalance
import cash.z.ecc.android.sdk.type.ZcashNetwork
import kotlinx.coroutines.runBlocking
/**
@@ -66,8 +68,14 @@ class SendFragment : BaseDemoFragment<FragmentSendBinding>() {
runBlocking {
Initializer.new(requireApplicationContext()) {
runBlocking { it.importWallet(seed, network = ZcashNetwork.fromResources(requireApplicationContext())) }
it.setNetwork(ZcashNetwork.fromResources(requireApplicationContext()))
val network = ZcashNetwork.fromResources(requireApplicationContext())
runBlocking {
it.newWallet(
seed,
network = network,
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
)
}
}
}.let { initializer ->
synchronizer = Synchronizer.newBlocking(initializer)

View File

@@ -4,10 +4,16 @@ package cash.z.ecc.android.sdk.demoapp.util
import android.content.Context
import cash.z.ecc.android.sdk.demoapp.R
import cash.z.ecc.android.sdk.type.ZcashNetwork
import cash.z.ecc.android.sdk.model.ZcashNetwork
import java.util.*
fun ZcashNetwork.Companion.fromResources(context: Context) = ZcashNetwork.valueOf(
context.getString(
R.string.network_name
)
)
fun ZcashNetwork.Companion.fromResources(context: Context): ZcashNetwork {
val networkNameFromResources = context.getString(R.string.network_name).lowercase(Locale.ROOT)
return if (networkNameFromResources == Testnet.networkName) {
ZcashNetwork.Testnet
} else if (networkNameFromResources.lowercase(Locale.ROOT) == Mainnet.networkName) {
ZcashNetwork.Mainnet
} else {
throw IllegalArgumentException("Unknown network name: $networkNameFromResources")
}
}