[#593] Refactor ZcashNetwork
Splits the ZcashNetwork and Lightwalletd server information, making it easier to configure different servers
This commit is contained in:
parent
2362c60dd6
commit
e01a906407
|
@ -1,6 +1,10 @@
|
||||||
Change Log
|
Change Log
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
Upcoming
|
||||||
|
------------------------------------
|
||||||
|
- Split `ZcashNetwork` into `ZcashNetwork` and `LightWalletEndpoint` to decouple network and server configuration
|
||||||
|
|
||||||
Version 1.8.0-beta01
|
Version 1.8.0-beta01
|
||||||
------------------------------------
|
------------------------------------
|
||||||
- Added `BlockHeight` typesafe object to represent block heights
|
- Added `BlockHeight` typesafe object to represent block heights
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
Troubleshooting Migrations
|
Troubleshooting Migrations
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
Upcoming
|
||||||
|
--------------------------------------
|
||||||
|
`ZcashNetwork` is no longer an enum. The prior enum values are now declared as object properties `ZcashNetwork.Mainnet` and `ZcashNetwork.Testnet`. For the most part, this change should have minimal impact. ZcashNetwork was also moved from the package `cash.z.ecc.android.sdk.type` to `cash.z.ecc.android.sdk.model`, which will require a change to your import statements. The server fields have been removed from `ZcashNetwork`, allowing server and network configuration to be done independently.
|
||||||
|
|
||||||
|
`LightWalletEndpoint` is a new object to represent server information. Default values can be obtained from `LightWalletEndpoint.defaultForNetwork(ZcashNetwork)`
|
||||||
|
|
||||||
|
`Synchronizer` no longer allows changing the endpoint after construction. Instead, construct a new `Synchronizer` with the desired endpoint.
|
||||||
|
|
||||||
Migration to Version 1.8 from 1.7
|
Migration to Version 1.8 from 1.7
|
||||||
|
--------------------------------------
|
||||||
Various APIs used `Int` to represent network block heights. Those APIs now use a typesafe `BlockHeight` type. BlockHeight is constructed with a factory method `BlockHeight.new(ZcashNetwork, Long)` which uses the network to validate the height is above the network's sapling activation height.
|
Various APIs used `Int` to represent network block heights. Those APIs now use a typesafe `BlockHeight` type. BlockHeight is constructed with a factory method `BlockHeight.new(ZcashNetwork, Long)` which uses the network to validate the height is above the network's sapling activation height.
|
||||||
|
|
||||||
`WalletBirthday` has been renamed to `Checkpoint` and removed from the public API. Where clients previously passed in a `WalletBirthday` object, now a `BlockHeight` can be passed in instead.
|
`WalletBirthday` has been renamed to `Checkpoint` and removed from the public API. Where clients previously passed in a `WalletBirthday` object, now a `BlockHeight` can be passed in instead.
|
||||||
|
|
|
@ -5,7 +5,7 @@ import cash.z.ecc.android.sdk.darkside.test.DarksideTestCoordinator
|
||||||
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
|
@ -4,7 +4,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import cash.z.ecc.android.sdk.darkside.test.DarksideTestCoordinator
|
import cash.z.ecc.android.sdk.darkside.test.DarksideTestCoordinator
|
||||||
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
@ -5,7 +5,7 @@ import cash.z.ecc.android.sdk.darkside.test.DarksideTestCoordinator
|
||||||
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
import cash.z.ecc.android.sdk.darkside.test.ScopedTest
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package cash.z.ecc.android.sdk.darkside.test
|
package cash.z.ecc.android.sdk.darkside.test
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import cash.z.ecc.android.sdk.R
|
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.Darkside
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.wallet.sdk.rpc.Darkside
|
import cash.z.wallet.sdk.rpc.Darkside
|
||||||
import cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL
|
import cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL
|
||||||
import cash.z.wallet.sdk.rpc.DarksideStreamerGrpc
|
import cash.z.wallet.sdk.rpc.DarksideStreamerGrpc
|
||||||
|
@ -23,17 +24,11 @@ class DarksideApi(
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
appContext: Context,
|
appContext: Context,
|
||||||
host: String,
|
lightWalletEndpoint: LightWalletEndpoint
|
||||||
port: Int = ZcashNetwork.Mainnet.defaultPort,
|
|
||||||
usePlainText: Boolean = appContext.resources.getBoolean(
|
|
||||||
R.bool.lightwalletd_allow_very_insecure_connections
|
|
||||||
)
|
|
||||||
) : this(
|
) : this(
|
||||||
LightWalletGrpcService.createDefaultChannel(
|
LightWalletGrpcService.createDefaultChannel(
|
||||||
appContext,
|
appContext,
|
||||||
host,
|
lightWalletEndpoint
|
||||||
port,
|
|
||||||
usePlainText
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ import cash.z.ecc.android.sdk.SdkSynchronizer
|
||||||
import cash.z.ecc.android.sdk.Synchronizer
|
import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.Darkside
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import io.grpc.StatusRuntimeException
|
import io.grpc.StatusRuntimeException
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
@ -23,10 +25,9 @@ class DarksideTestCoordinator(val wallet: TestWallet) {
|
||||||
alias: String = "DarksideTestCoordinator",
|
alias: String = "DarksideTestCoordinator",
|
||||||
seedPhrase: String = DEFAULT_SEED_PHRASE,
|
seedPhrase: String = DEFAULT_SEED_PHRASE,
|
||||||
startHeight: BlockHeight = DEFAULT_START_HEIGHT,
|
startHeight: BlockHeight = DEFAULT_START_HEIGHT,
|
||||||
host: String = COMPUTER_LOCALHOST,
|
|
||||||
network: ZcashNetwork = ZcashNetwork.Mainnet,
|
network: ZcashNetwork = ZcashNetwork.Mainnet,
|
||||||
port: Int = network.defaultPort
|
endpoint: LightWalletEndpoint = LightWalletEndpoint.Darkside
|
||||||
) : this(TestWallet(seedPhrase, alias, network, host, startHeight = startHeight, port = port))
|
) : this(TestWallet(seedPhrase, alias, network, endpoint, startHeight = startHeight))
|
||||||
|
|
||||||
private val targetHeight = BlockHeight.new(wallet.network, 663250)
|
private val targetHeight = BlockHeight.new(wallet.network, 663250)
|
||||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||||
|
|
|
@ -11,10 +11,12 @@ import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.Darkside
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -36,9 +38,8 @@ class TestWallet(
|
||||||
val seedPhrase: String,
|
val seedPhrase: String,
|
||||||
val alias: String = "TestWallet",
|
val alias: String = "TestWallet",
|
||||||
val network: ZcashNetwork = ZcashNetwork.Testnet,
|
val network: ZcashNetwork = ZcashNetwork.Testnet,
|
||||||
val host: String = network.defaultHost,
|
val endpoint: LightWalletEndpoint = LightWalletEndpoint.Darkside,
|
||||||
startHeight: BlockHeight? = null,
|
startHeight: BlockHeight? = null
|
||||||
val port: Int = network.defaultPort
|
|
||||||
) {
|
) {
|
||||||
constructor(
|
constructor(
|
||||||
backup: Backups,
|
backup: Backups,
|
||||||
|
@ -66,7 +67,7 @@ class TestWallet(
|
||||||
runBlocking { DerivationTool.deriveTransparentSecretKey(seed, network = network) }
|
runBlocking { DerivationTool.deriveTransparentSecretKey(seed, network = network) }
|
||||||
val initializer = runBlocking {
|
val initializer = runBlocking {
|
||||||
Initializer.new(context) { config ->
|
Initializer.new(context) { config ->
|
||||||
runBlocking { config.importWallet(seed, startHeight, network, host, alias = alias) }
|
runBlocking { config.importWallet(seed, startHeight, network, endpoint, alias = alias) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val synchronizer: SdkSynchronizer = runBlocking { Synchronizer.new(initializer) } as SdkSynchronizer
|
val synchronizer: SdkSynchronizer = runBlocking { Synchronizer.new(initializer) } as SdkSynchronizer
|
||||||
|
@ -79,7 +80,6 @@ class TestWallet(
|
||||||
runBlocking { DerivationTool.deriveTransparentAddress(seed, network = network) }
|
runBlocking { DerivationTool.deriveTransparentAddress(seed, network = network) }
|
||||||
val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
||||||
val networkName get() = synchronizer.network.networkName
|
val networkName get() = synchronizer.network.networkName
|
||||||
val connectionInfo get() = service.connectionInfo.toString()
|
|
||||||
|
|
||||||
suspend fun transparentBalance(): WalletBalance {
|
suspend fun transparentBalance(): WalletBalance {
|
||||||
synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
||||||
|
@ -166,11 +166,46 @@ class TestWallet(
|
||||||
|
|
||||||
enum class Backups(val seedPhrase: String, val testnetBirthday: BlockHeight, val mainnetBirthday: BlockHeight) {
|
enum class Backups(val seedPhrase: String, val testnetBirthday: BlockHeight, val mainnetBirthday: BlockHeight) {
|
||||||
// TODO: get the proper birthday values for these wallets
|
// TODO: get the proper birthday values for these wallets
|
||||||
DEFAULT("column rhythm acoustic gym cost fit keen maze fence seed mail medal shrimp tell relief clip cannon foster soldier shallow refuse lunar parrot banana", BlockHeight.new(ZcashNetwork.Testnet, 1_355_928), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
DEFAULT(
|
||||||
SAMPLE_WALLET("input frown warm senior anxiety abuse yard prefer churn reject people glimpse govern glory crumble swallow verb laptop switch trophy inform friend permit purpose", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
"column rhythm acoustic gym cost fit keen maze fence seed mail medal shrimp tell relief clip cannon foster soldier shallow refuse lunar parrot banana",
|
||||||
DEV_WALLET("still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread", BlockHeight.new(ZcashNetwork.Testnet, 1_000_000), BlockHeight.new(ZcashNetwork.Mainnet, 991645)),
|
BlockHeight.new(
|
||||||
ALICE("quantum whisper lion route fury lunar pelican image job client hundred sauce chimney barely life cliff spirit admit weekend message recipe trumpet impact kitten", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
ZcashNetwork.Testnet,
|
||||||
BOB("canvas wine sugar acquire garment spy tongue odor hole cage year habit bullet make label human unit option top calm neutral try vocal arena", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
1_355_928
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
SAMPLE_WALLET(
|
||||||
|
"input frown warm senior anxiety abuse yard prefer churn reject people glimpse govern glory crumble swallow verb laptop switch trophy inform friend permit purpose",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
DEV_WALLET(
|
||||||
|
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_000_000
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 991645)
|
||||||
|
),
|
||||||
|
ALICE(
|
||||||
|
"quantum whisper lion route fury lunar pelican image job client hundred sauce chimney barely life cliff spirit admit weekend message recipe trumpet impact kitten",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
BOB(
|
||||||
|
"canvas wine sugar acquire garment spy tongue odor hole cage year habit bullet make label human unit option top calm neutral try vocal arena",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,10 @@ import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.Mainnet
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
|
@ -87,15 +89,18 @@ class SampleCodeTest {
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// Query latest block height
|
// Query latest block height
|
||||||
@Test fun getLatestBlockHeightTest() {
|
@Test fun getLatestBlockHeightTest() {
|
||||||
val lightwalletService = LightWalletGrpcService(context, lightwalletdHost)
|
val lightwalletService = LightWalletGrpcService.new(context, lightwalletdHost)
|
||||||
log("Latest Block: ${lightwalletService.getLatestBlockHeight()}")
|
log("Latest Block: ${lightwalletService.getLatestBlockHeight()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
// Download compact block range
|
// Download compact block range
|
||||||
@Test fun getBlockRange() {
|
@Test fun getBlockRange() {
|
||||||
val blockRange = BlockHeight.new(ZcashNetwork.Mainnet, 500_000)..BlockHeight.new(ZcashNetwork.Mainnet, 500_009)
|
val blockRange = BlockHeight.new(ZcashNetwork.Mainnet, 500_000)..BlockHeight.new(
|
||||||
val lightwalletService = LightWalletGrpcService(context, lightwalletdHost)
|
ZcashNetwork.Mainnet,
|
||||||
|
500_009
|
||||||
|
)
|
||||||
|
val lightwalletService = LightWalletGrpcService.new(context, lightwalletdHost)
|
||||||
val blocks = lightwalletService.getBlockRange(blockRange)
|
val blocks = lightwalletService.getBlockRange(blockRange)
|
||||||
assertEquals(blockRange.endInclusive.value - blockRange.start.value, blocks.count())
|
assertEquals(blockRange.endInclusive.value - blockRange.start.value, blocks.count())
|
||||||
|
|
||||||
|
@ -151,7 +156,7 @@ class SampleCodeTest {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val seed = "Insert seed for testing".toByteArray()
|
private val seed = "Insert seed for testing".toByteArray()
|
||||||
private val lightwalletdHost: String = ZcashNetwork.Mainnet.defaultHost
|
private val lightwalletdHost = LightWalletEndpoint.Mainnet
|
||||||
|
|
||||||
private val context = InstrumentationRegistry.getInstrumentation().targetContext
|
private val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
private val synchronizer: Synchronizer = run {
|
private val synchronizer: Synchronizer = run {
|
||||||
|
|
|
@ -20,7 +20,9 @@ import androidx.viewbinding.ViewBinding
|
||||||
import cash.z.ecc.android.sdk.demoapp.util.fromResources
|
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.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletService
|
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.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
|
|
||||||
|
@ -108,7 +110,11 @@ class MainActivity :
|
||||||
if (lightwalletService != null) {
|
if (lightwalletService != null) {
|
||||||
lightwalletService?.shutdown()
|
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) {
|
private fun onFabClicked(view: View) {
|
||||||
|
|
|
@ -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.databinding.FragmentGetAddressBinding
|
||||||
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
|
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.fromResources
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
|
|
@ -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.demoapp.util.fromResources
|
||||||
import cash.z.ecc.android.sdk.ext.collectWith
|
import cash.z.ecc.android.sdk.ext.collectWith
|
||||||
import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
|
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.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.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
|
@ -50,8 +52,12 @@ class GetBalanceFragment : BaseDemoFragment<FragmentGetBalanceBinding>() {
|
||||||
// using the ViewingKey to initialize
|
// using the ViewingKey to initialize
|
||||||
runBlocking {
|
runBlocking {
|
||||||
Initializer.new(requireApplicationContext(), null) {
|
Initializer.new(requireApplicationContext(), null) {
|
||||||
it.setNetwork(ZcashNetwork.fromResources(requireApplicationContext()))
|
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
it.newWallet(viewingKey, network = ZcashNetwork.fromResources(requireApplicationContext()))
|
it.newWallet(
|
||||||
|
viewingKey,
|
||||||
|
network = network,
|
||||||
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.let { initializer ->
|
}.let { initializer ->
|
||||||
synchronizer = Synchronizer.newBlocking(initializer)
|
synchronizer = Synchronizer.newBlocking(initializer)
|
||||||
|
|
|
@ -14,7 +14,7 @@ import cash.z.ecc.android.sdk.demoapp.util.toRelativeTime
|
||||||
import cash.z.ecc.android.sdk.demoapp.util.withCommas
|
import cash.z.ecc.android.sdk.demoapp.util.withCommas
|
||||||
import cash.z.ecc.android.sdk.ext.toHex
|
import cash.z.ecc.android.sdk.ext.toHex
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@ 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.toRelativeTime
|
||||||
import cash.z.ecc.android.sdk.demoapp.util.withCommas
|
import cash.z.ecc.android.sdk.demoapp.util.withCommas
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.databinding.FragmentGetPrivateKeyBinding
|
||||||
import cash.z.ecc.android.sdk.demoapp.ext.requireApplicationContext
|
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.fromResources
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.demoapp.util.fromResources
|
||||||
import cash.z.ecc.android.sdk.ext.collectWith
|
import cash.z.ecc.android.sdk.ext.collectWith
|
||||||
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.ZcashNetwork
|
||||||
|
import cash.z.ecc.android.sdk.model.defaultForNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,11 +53,13 @@ class ListTransactionsFragment : BaseDemoFragment<FragmentListTransactionsBindin
|
||||||
initializer = Initializer.newBlocking(
|
initializer = Initializer.newBlocking(
|
||||||
requireApplicationContext(),
|
requireApplicationContext(),
|
||||||
Initializer.Config {
|
Initializer.Config {
|
||||||
|
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
runBlocking {
|
runBlocking {
|
||||||
it.importWallet(
|
it.importWallet(
|
||||||
seed,
|
seed,
|
||||||
birthday = null,
|
birthday = null,
|
||||||
network = ZcashNetwork.fromResources(requireApplicationContext())
|
network = network,
|
||||||
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,10 @@ import cash.z.ecc.android.sdk.demoapp.util.mainActivity
|
||||||
import cash.z.ecc.android.sdk.ext.collectWith
|
import cash.z.ecc.android.sdk.ext.collectWith
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
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.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
@ -64,8 +66,15 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
|
||||||
// have the seed stored
|
// have the seed stored
|
||||||
seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
|
seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
|
||||||
initializer = runBlocking {
|
initializer = runBlocking {
|
||||||
|
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
Initializer.new(requireApplicationContext()) {
|
Initializer.new(requireApplicationContext()) {
|
||||||
runBlocking { it.newWallet(seed, network = ZcashNetwork.fromResources(requireApplicationContext())) }
|
runBlocking {
|
||||||
|
it.newWallet(
|
||||||
|
seed,
|
||||||
|
network = network,
|
||||||
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
|
||||||
|
)
|
||||||
|
}
|
||||||
it.alias = "Demo_Utxos"
|
it.alias = "Demo_Utxos"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,12 +105,19 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
|
||||||
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
binding.textStatus.requestFocus()
|
binding.textStatus.requestFocus()
|
||||||
val addressToUse = binding.inputAddress.text.toString()
|
val addressToUse = binding.inputAddress.text.toString()
|
||||||
val startToUse = max(binding.inputRangeStart.text.toString().toLongOrNull() ?: network.saplingActivationHeight.value, network.saplingActivationHeight.value)
|
val startToUse = max(
|
||||||
|
binding.inputRangeStart.text.toString().toLongOrNull()
|
||||||
|
?: network.saplingActivationHeight.value,
|
||||||
|
network.saplingActivationHeight.value
|
||||||
|
)
|
||||||
val endToUse = binding.inputRangeEnd.text.toString().toLongOrNull()
|
val endToUse = binding.inputRangeEnd.text.toString().toLongOrNull()
|
||||||
?: getUxtoEndHeight(requireApplicationContext()).value
|
?: getUxtoEndHeight(requireApplicationContext()).value
|
||||||
var allStart = now
|
var allStart = now
|
||||||
twig("loading transactions in range $startToUse..$endToUse")
|
twig("loading transactions in range $startToUse..$endToUse")
|
||||||
val txids = lightwalletService?.getTAddressTransactions(addressToUse, BlockHeight.new(network, startToUse)..BlockHeight.new(network, endToUse))
|
val txids = lightwalletService?.getTAddressTransactions(
|
||||||
|
addressToUse,
|
||||||
|
BlockHeight.new(network, startToUse)..BlockHeight.new(network, endToUse)
|
||||||
|
)
|
||||||
var delta = now - allStart
|
var delta = now - allStart
|
||||||
updateStatus("found ${txids?.size} transactions in ${delta}ms.", false)
|
updateStatus("found ${txids?.size} transactions in ${delta}ms.", false)
|
||||||
|
|
||||||
|
@ -163,7 +179,12 @@ class ListUtxosFragment : BaseDemoFragment<FragmentListUtxosBinding>() {
|
||||||
resetInBackground()
|
resetInBackground()
|
||||||
val seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
|
val seed = Mnemonics.MnemonicCode(sharedViewModel.seedPhrase.value).toSeed()
|
||||||
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
|
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
|
||||||
binding.inputAddress.setText(DerivationTool.deriveTransparentAddress(seed, ZcashNetwork.fromResources(requireApplicationContext())))
|
binding.inputAddress.setText(
|
||||||
|
DerivationTool.deriveTransparentAddress(
|
||||||
|
seed,
|
||||||
|
ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.ext.toZecString
|
||||||
import cash.z.ecc.android.sdk.internal.Twig
|
import cash.z.ecc.android.sdk.internal.Twig
|
||||||
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.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.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,8 +68,14 @@ class SendFragment : BaseDemoFragment<FragmentSendBinding>() {
|
||||||
|
|
||||||
runBlocking {
|
runBlocking {
|
||||||
Initializer.new(requireApplicationContext()) {
|
Initializer.new(requireApplicationContext()) {
|
||||||
runBlocking { it.newWallet(seed, network = ZcashNetwork.fromResources(requireApplicationContext())) }
|
val network = ZcashNetwork.fromResources(requireApplicationContext())
|
||||||
it.setNetwork(ZcashNetwork.fromResources(requireApplicationContext()))
|
runBlocking {
|
||||||
|
it.newWallet(
|
||||||
|
seed,
|
||||||
|
network = network,
|
||||||
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.let { initializer ->
|
}.let { initializer ->
|
||||||
synchronizer = Synchronizer.newBlocking(initializer)
|
synchronizer = Synchronizer.newBlocking(initializer)
|
||||||
|
|
|
@ -4,10 +4,16 @@ package cash.z.ecc.android.sdk.demoapp.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import cash.z.ecc.android.sdk.demoapp.R
|
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(
|
fun ZcashNetwork.Companion.fromResources(context: Context): ZcashNetwork {
|
||||||
context.getString(
|
val networkNameFromResources = context.getString(R.string.network_name).lowercase(Locale.ROOT)
|
||||||
R.string.network_name
|
return if (networkNameFromResources == Testnet.networkName) {
|
||||||
)
|
ZcashNetwork.Testnet
|
||||||
)
|
} else if (networkNameFromResources.lowercase(Locale.ROOT) == Mainnet.networkName) {
|
||||||
|
ZcashNetwork.Mainnet
|
||||||
|
} else {
|
||||||
|
throw IllegalArgumentException("Unknown network name: $networkNameFromResources")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ package cash.z.ecc.android.sdk
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
|
@ -77,6 +77,7 @@ class AssetTest {
|
||||||
val expectedNetworkName = when (network) {
|
val expectedNetworkName = when (network) {
|
||||||
ZcashNetwork.Mainnet -> "main"
|
ZcashNetwork.Mainnet -> "main"
|
||||||
ZcashNetwork.Testnet -> "test"
|
ZcashNetwork.Testnet -> "test"
|
||||||
|
else -> IllegalArgumentException("Unsupported network $network")
|
||||||
}
|
}
|
||||||
assertEquals("File: ${it.filename}", expectedNetworkName, jsonObject.getString("network"))
|
assertEquals("File: ${it.filename}", expectedNetworkName, jsonObject.getString("network"))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package cash.z.ecc.android.sdk.ext
|
package cash.z.ecc.android.sdk.ext
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.Initializer
|
import cash.z.ecc.android.sdk.Initializer
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.util.SimpleMnemonics
|
import cash.z.ecc.android.sdk.util.SimpleMnemonics
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
|
|
@ -4,11 +4,10 @@ import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||||
import cash.z.ecc.android.sdk.ext.BlockExplorer
|
import cash.z.ecc.android.sdk.ext.BlockExplorer
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.util.TestWallet
|
import cash.z.ecc.android.sdk.util.TestWallet
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Assert.assertFalse
|
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
@ -31,13 +30,6 @@ class SanityTest(
|
||||||
val networkName = wallet.networkName
|
val networkName = wallet.networkName
|
||||||
val name = "$networkName wallet"
|
val name = "$networkName wallet"
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testNotPlaintext() {
|
|
||||||
val message =
|
|
||||||
"is using plaintext. This will cause problems for the test. Ensure that the `lightwalletd_allow_very_insecure_connections` resource value is false"
|
|
||||||
assertFalse("$name $message", wallet.service.connectionInfo.usePlaintext)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFilePaths() {
|
fun testFilePaths() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
@ -80,24 +72,14 @@ class SanityTest(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testServerConnection() {
|
|
||||||
assertEquals(
|
|
||||||
"$name has an invalid server connection",
|
|
||||||
"$networkName.lightwalletd.com:9067?usePlaintext=false",
|
|
||||||
wallet.connectionInfo
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testLatestHeight() = runBlocking {
|
fun testLatestHeight() = runBlocking {
|
||||||
if (wallet.networkName == "mainnet") {
|
if (wallet.networkName == "mainnet") {
|
||||||
val expectedHeight = BlockExplorer.fetchLatestHeight()
|
val expectedHeight = BlockExplorer.fetchLatestHeight()
|
||||||
// fetch height directly because the synchronizer hasn't started, yet
|
// fetch height directly because the synchronizer hasn't started, yet
|
||||||
val downloaderHeight = wallet.service.getLatestBlockHeight()
|
val downloaderHeight = wallet.service.getLatestBlockHeight()
|
||||||
val info = wallet.connectionInfo
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"$info\n ${wallet.networkName} Lightwalletd is too far behind. Downloader height $downloaderHeight is more than 10 blocks behind block explorer height $expectedHeight",
|
"${wallet.endpoint} ${wallet.networkName} Lightwalletd is too far behind. Downloader height $downloaderHeight is more than 10 blocks behind block explorer height $expectedHeight",
|
||||||
expectedHeight - 10 < downloaderHeight.value
|
expectedHeight - 10 < downloaderHeight.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import androidx.test.filters.LargeTest
|
||||||
import androidx.test.filters.MediumTest
|
import androidx.test.filters.MediumTest
|
||||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
|
||||||
import cash.z.ecc.android.sdk.util.TestWallet
|
import cash.z.ecc.android.sdk.util.TestWallet
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
@ -19,16 +18,6 @@ import org.junit.Test
|
||||||
@MediumTest
|
@MediumTest
|
||||||
class SmokeTest {
|
class SmokeTest {
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testNotPlaintext() {
|
|
||||||
val service =
|
|
||||||
wallet.synchronizer.processor.downloader.lightWalletService as LightWalletGrpcService
|
|
||||||
Assert.assertFalse(
|
|
||||||
"Wallet is using plaintext. This will cause problems for the test. Ensure that the `lightwalletd_allow_very_insecure_connections` resource value is false",
|
|
||||||
service.connectionInfo.usePlaintext
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testFilePaths() {
|
fun testFilePaths() {
|
||||||
Assert.assertEquals("Invalid DataDB file", "/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_testnet_Data.db", wallet.initializer.rustBackend.pathDataDb)
|
Assert.assertEquals("Invalid DataDB file", "/data/user/0/cash.z.ecc.android.sdk.test/databases/TestWallet_testnet_Data.db", wallet.initializer.rustBackend.pathDataDb)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cash.z.wallet.sdk.integration
|
package cash.z.ecc.android.sdk.integration
|
||||||
|
|
||||||
import androidx.test.filters.LargeTest
|
import androidx.test.filters.LargeTest
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
@ -13,11 +13,12 @@ import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.test.ScopedTest
|
import cash.z.ecc.android.sdk.test.ScopedTest
|
||||||
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.filterNotNull
|
import kotlinx.coroutines.flow.filterNotNull
|
||||||
|
@ -39,9 +40,9 @@ class TestnetIntegrationTest : ScopedTest() {
|
||||||
@Test
|
@Test
|
||||||
@Ignore("This test is broken")
|
@Ignore("This test is broken")
|
||||||
fun testLatestBlockTest() {
|
fun testLatestBlockTest() {
|
||||||
val service = LightWalletGrpcService(
|
val service = LightWalletGrpcService.new(
|
||||||
context,
|
context,
|
||||||
host
|
lightWalletEndpoint
|
||||||
)
|
)
|
||||||
val height = service.getLatestBlockHeight()
|
val height = service.getLatestBlockHeight()
|
||||||
assertTrue(height > saplingActivation)
|
assertTrue(height > saplingActivation)
|
||||||
|
@ -118,7 +119,7 @@ class TestnetIntegrationTest : ScopedTest() {
|
||||||
companion object {
|
companion object {
|
||||||
init { Twig.plant(TroubleshootingTwig()) }
|
init { Twig.plant(TroubleshootingTwig()) }
|
||||||
|
|
||||||
const val host = "lightwalletd.testnet.z.cash"
|
val lightWalletEndpoint = LightWalletEndpoint("lightwalletd.testnet.z.cash", 9087, true)
|
||||||
private const val birthdayHeight = 963150L
|
private const val birthdayHeight = 963150L
|
||||||
private const val targetHeight = 663250
|
private const val targetHeight = 663250
|
||||||
private const val seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
private const val seedPhrase = "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
|
||||||
|
@ -129,8 +130,8 @@ class TestnetIntegrationTest : ScopedTest() {
|
||||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||||
private val initializer = runBlocking {
|
private val initializer = runBlocking {
|
||||||
Initializer.new(context) { config ->
|
Initializer.new(context) { config ->
|
||||||
config.setNetwork(ZcashNetwork.Testnet, host)
|
config.setNetwork(ZcashNetwork.Testnet, lightWalletEndpoint)
|
||||||
runBlocking { config.importWallet(seed, BlockHeight.new(ZcashNetwork.Testnet, birthdayHeight), ZcashNetwork.Testnet) }
|
runBlocking { config.importWallet(seed, BlockHeight.new(ZcashNetwork.Testnet, birthdayHeight), ZcashNetwork.Testnet, lightWalletEndpoint) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private lateinit var synchronizer: Synchronizer
|
private lateinit var synchronizer: Synchronizer
|
||||||
|
|
|
@ -12,8 +12,11 @@ import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.Mainnet
|
||||||
|
import cash.z.ecc.android.sdk.model.Testnet
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.test.ScopedTest
|
import cash.z.ecc.android.sdk.test.ScopedTest
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -35,13 +38,15 @@ import org.mockito.Spy
|
||||||
class ChangeServiceTest : ScopedTest() {
|
class ChangeServiceTest : ScopedTest() {
|
||||||
|
|
||||||
val network = ZcashNetwork.Mainnet
|
val network = ZcashNetwork.Mainnet
|
||||||
|
val lightWalletEndpoint = LightWalletEndpoint.Mainnet
|
||||||
|
private val eccEndpoint = LightWalletEndpoint("lightwalletd.electriccoin.co", 9087, true)
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var mockBlockStore: CompactBlockStore
|
lateinit var mockBlockStore: CompactBlockStore
|
||||||
var mockCloseable: AutoCloseable? = null
|
var mockCloseable: AutoCloseable? = null
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
val service = LightWalletGrpcService(context, network)
|
val service = LightWalletGrpcService.new(context, lightWalletEndpoint)
|
||||||
|
|
||||||
lateinit var downloader: CompactBlockDownloader
|
lateinit var downloader: CompactBlockDownloader
|
||||||
lateinit var otherService: LightWalletService
|
lateinit var otherService: LightWalletService
|
||||||
|
@ -50,7 +55,7 @@ class ChangeServiceTest : ScopedTest() {
|
||||||
fun setup() {
|
fun setup() {
|
||||||
initMocks()
|
initMocks()
|
||||||
downloader = CompactBlockDownloader(service, mockBlockStore)
|
downloader = CompactBlockDownloader(service, mockBlockStore)
|
||||||
otherService = LightWalletGrpcService(context, "lightwalletd.electriccoin.co")
|
otherService = LightWalletGrpcService.new(context, eccEndpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -106,7 +111,7 @@ class ChangeServiceTest : ScopedTest() {
|
||||||
@Test
|
@Test
|
||||||
fun testSwitchToInvalidServer() = runBlocking {
|
fun testSwitchToInvalidServer() = runBlocking {
|
||||||
var caughtException: Throwable? = null
|
var caughtException: Throwable? = null
|
||||||
downloader.changeService(LightWalletGrpcService(context, "invalid.lightwalletd")) {
|
downloader.changeService(LightWalletGrpcService.new(context, LightWalletEndpoint("invalid.lightwalletd", 9087, true))) {
|
||||||
caughtException = it
|
caughtException = it
|
||||||
}
|
}
|
||||||
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
||||||
|
@ -119,7 +124,7 @@ class ChangeServiceTest : ScopedTest() {
|
||||||
@Test
|
@Test
|
||||||
fun testSwitchToTestnetFails() = runBlocking {
|
fun testSwitchToTestnetFails() = runBlocking {
|
||||||
var caughtException: Throwable? = null
|
var caughtException: Throwable? = null
|
||||||
downloader.changeService(LightWalletGrpcService(context, ZcashNetwork.Testnet)) {
|
downloader.changeService(LightWalletGrpcService.new(context, LightWalletEndpoint.Testnet)) {
|
||||||
caughtException = it
|
caughtException = it
|
||||||
}
|
}
|
||||||
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
assertNotNull("Using an invalid host should generate an exception.", caughtException)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package cash.z.ecc.android.sdk.jni
|
||||||
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
@ -7,8 +7,8 @@ import cash.z.ecc.android.sdk.annotation.MaintainedTest
|
||||||
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
import cash.z.ecc.android.sdk.annotation.TestPurpose
|
||||||
import cash.z.ecc.android.sdk.internal.TroubleshootingTwig
|
import cash.z.ecc.android.sdk.internal.TroubleshootingTwig
|
||||||
import cash.z.ecc.android.sdk.internal.Twig
|
import cash.z.ecc.android.sdk.internal.Twig
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.BeforeClass
|
import org.junit.BeforeClass
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cash.z.ecc.android.sdk.sample
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.internal.Twig
|
import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.util.TestWallet
|
import cash.z.ecc.android.sdk.util.TestWallet
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
|
|
@ -5,8 +5,7 @@ import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork.Testnet
|
|
||||||
import cash.z.ecc.android.sdk.util.TestWallet
|
import cash.z.ecc.android.sdk.util.TestWallet
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
@ -90,7 +89,7 @@ class TransparentRestoreSample {
|
||||||
val wallet0 = TestWallet(
|
val wallet0 = TestWallet(
|
||||||
TestWallet.Backups.SAMPLE_WALLET.seedPhrase,
|
TestWallet.Backups.SAMPLE_WALLET.seedPhrase,
|
||||||
"tmpabc",
|
"tmpabc",
|
||||||
Testnet,
|
ZcashNetwork.Testnet,
|
||||||
startHeight = BlockHeight.new(
|
startHeight = BlockHeight.new(
|
||||||
ZcashNetwork.Testnet,
|
ZcashNetwork.Testnet,
|
||||||
1330190
|
1330190
|
||||||
|
@ -117,7 +116,15 @@ class TransparentRestoreSample {
|
||||||
*/
|
*/
|
||||||
// @Test
|
// @Test
|
||||||
fun hasFunds() = runBlocking<Unit> {
|
fun hasFunds() = runBlocking<Unit> {
|
||||||
val walletSandbox = TestWallet(TestWallet.Backups.SAMPLE_WALLET.seedPhrase, "WalletC", Testnet, startHeight = BlockHeight.new(ZcashNetwork.Testnet, 1330190))
|
val walletSandbox = TestWallet(
|
||||||
|
TestWallet.Backups.SAMPLE_WALLET.seedPhrase,
|
||||||
|
"WalletC",
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
startHeight = BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1330190
|
||||||
|
)
|
||||||
|
)
|
||||||
// val job = walletA.walletScope.launch {
|
// val job = walletA.walletScope.launch {
|
||||||
// twig("Syncing WalletA")
|
// twig("Syncing WalletA")
|
||||||
// walletA.sync()
|
// walletA.sync()
|
||||||
|
|
|
@ -4,8 +4,8 @@ import android.content.Context
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.CheckpointTool.IS_FALLBACK_ON_FAILURE
|
import cash.z.ecc.android.sdk.tool.CheckpointTool.IS_FALLBACK_ON_FAILURE
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package cash.z.ecc.android.sdk.util
|
package cash.z.ecc.android.sdk.util
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
|
@ -9,8 +9,10 @@ import cash.z.ecc.android.sdk.internal.ext.deleteSuspend
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
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.CheckpointTool
|
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
|
@ -82,8 +84,8 @@ class BalancePrinterUtil {
|
||||||
}.collect { seed ->
|
}.collect { seed ->
|
||||||
// TODO: clear the dataDb but leave the cacheDb
|
// TODO: clear the dataDb but leave the cacheDb
|
||||||
val initializer = Initializer.new(context) { config ->
|
val initializer = Initializer.new(context) { config ->
|
||||||
runBlocking { config.importWallet(seed, birthdayHeight, network) }
|
val endpoint = LightWalletEndpoint.defaultForNetwork(network)
|
||||||
config.setNetwork(network)
|
runBlocking { config.importWallet(seed, birthdayHeight, network, endpoint) }
|
||||||
config.alias = alias
|
config.alias = alias
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -7,7 +7,7 @@ import cash.z.ecc.android.sdk.Synchronizer
|
||||||
import cash.z.ecc.android.sdk.internal.TroubleshootingTwig
|
import cash.z.ecc.android.sdk.internal.TroubleshootingTwig
|
||||||
import cash.z.ecc.android.sdk.internal.Twig
|
import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
|
@ -11,10 +11,12 @@ import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.Testnet
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
@ -36,9 +38,8 @@ class TestWallet(
|
||||||
val seedPhrase: String,
|
val seedPhrase: String,
|
||||||
val alias: String = "TestWallet",
|
val alias: String = "TestWallet",
|
||||||
val network: ZcashNetwork = ZcashNetwork.Testnet,
|
val network: ZcashNetwork = ZcashNetwork.Testnet,
|
||||||
val host: String = network.defaultHost,
|
val endpoint: LightWalletEndpoint = LightWalletEndpoint.Testnet,
|
||||||
startHeight: BlockHeight? = null,
|
startHeight: BlockHeight? = null
|
||||||
val port: Int = network.defaultPort
|
|
||||||
) {
|
) {
|
||||||
constructor(
|
constructor(
|
||||||
backup: Backups,
|
backup: Backups,
|
||||||
|
@ -66,7 +67,7 @@ class TestWallet(
|
||||||
runBlocking { DerivationTool.deriveTransparentSecretKey(seed, network = network) }
|
runBlocking { DerivationTool.deriveTransparentSecretKey(seed, network = network) }
|
||||||
val initializer = runBlocking {
|
val initializer = runBlocking {
|
||||||
Initializer.new(context) { config ->
|
Initializer.new(context) { config ->
|
||||||
runBlocking { config.importWallet(seed, startHeight, network, host, alias = alias) }
|
runBlocking { config.importWallet(seed, startHeight, network, endpoint, alias = alias) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val synchronizer: SdkSynchronizer = Synchronizer.newBlocking(initializer) as SdkSynchronizer
|
val synchronizer: SdkSynchronizer = Synchronizer.newBlocking(initializer) as SdkSynchronizer
|
||||||
|
@ -79,7 +80,6 @@ class TestWallet(
|
||||||
runBlocking { DerivationTool.deriveTransparentAddress(seed, network = network) }
|
runBlocking { DerivationTool.deriveTransparentAddress(seed, network = network) }
|
||||||
val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
val birthdayHeight get() = synchronizer.latestBirthdayHeight
|
||||||
val networkName get() = synchronizer.network.networkName
|
val networkName get() = synchronizer.network.networkName
|
||||||
val connectionInfo get() = service.connectionInfo.toString()
|
|
||||||
|
|
||||||
suspend fun transparentBalance(): WalletBalance {
|
suspend fun transparentBalance(): WalletBalance {
|
||||||
synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
synchronizer.refreshUtxos(transparentAddress, synchronizer.latestBirthdayHeight)
|
||||||
|
@ -166,11 +166,46 @@ class TestWallet(
|
||||||
|
|
||||||
enum class Backups(val seedPhrase: String, val testnetBirthday: BlockHeight, val mainnetBirthday: BlockHeight) {
|
enum class Backups(val seedPhrase: String, val testnetBirthday: BlockHeight, val mainnetBirthday: BlockHeight) {
|
||||||
// TODO: get the proper birthday values for these wallets
|
// TODO: get the proper birthday values for these wallets
|
||||||
DEFAULT("column rhythm acoustic gym cost fit keen maze fence seed mail medal shrimp tell relief clip cannon foster soldier shallow refuse lunar parrot banana", BlockHeight.new(ZcashNetwork.Testnet, 1_355_928), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
DEFAULT(
|
||||||
SAMPLE_WALLET("input frown warm senior anxiety abuse yard prefer churn reject people glimpse govern glory crumble swallow verb laptop switch trophy inform friend permit purpose", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
"column rhythm acoustic gym cost fit keen maze fence seed mail medal shrimp tell relief clip cannon foster soldier shallow refuse lunar parrot banana",
|
||||||
DEV_WALLET("still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread", BlockHeight.new(ZcashNetwork.Testnet, 1_000_000), BlockHeight.new(ZcashNetwork.Mainnet, 991645)),
|
BlockHeight.new(
|
||||||
ALICE("quantum whisper lion route fury lunar pelican image job client hundred sauce chimney barely life cliff spirit admit weekend message recipe trumpet impact kitten", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
ZcashNetwork.Testnet,
|
||||||
BOB("canvas wine sugar acquire garment spy tongue odor hole cage year habit bullet make label human unit option top calm neutral try vocal arena", BlockHeight.new(ZcashNetwork.Testnet, 1_330_190), BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)),
|
1_355_928
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
SAMPLE_WALLET(
|
||||||
|
"input frown warm senior anxiety abuse yard prefer churn reject people glimpse govern glory crumble swallow verb laptop switch trophy inform friend permit purpose",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
DEV_WALLET(
|
||||||
|
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_000_000
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 991645)
|
||||||
|
),
|
||||||
|
ALICE(
|
||||||
|
"quantum whisper lion route fury lunar pelican image job client hundred sauce chimney barely life cliff spirit admit weekend message recipe trumpet impact kitten",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
|
BOB(
|
||||||
|
"canvas wine sugar acquire garment spy tongue odor hole cage year habit bullet make label human unit option top calm neutral try vocal arena",
|
||||||
|
BlockHeight.new(
|
||||||
|
ZcashNetwork.Testnet,
|
||||||
|
1_330_190
|
||||||
|
),
|
||||||
|
BlockHeight.new(ZcashNetwork.Mainnet, 1_000_000)
|
||||||
|
),
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ import cash.z.ecc.android.sdk.internal.Twig
|
||||||
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
import cash.z.ecc.android.sdk.internal.service.LightWalletGrpcService
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
|
import cash.z.ecc.android.sdk.model.Mainnet
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
@ -14,7 +16,7 @@ class TransactionCounterUtil {
|
||||||
|
|
||||||
private val network = ZcashNetwork.Mainnet
|
private val network = ZcashNetwork.Mainnet
|
||||||
private val context = InstrumentationRegistry.getInstrumentation().context
|
private val context = InstrumentationRegistry.getInstrumentation().context
|
||||||
private val service = LightWalletGrpcService(context, network)
|
private val service = LightWalletGrpcService.new(context, LightWalletEndpoint.Mainnet)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Twig.plant(TroubleshootingTwig())
|
Twig.plant(TroubleshootingTwig())
|
||||||
|
|
|
@ -8,7 +8,7 @@ import cash.z.ecc.android.sdk.internal.KEY_VERSION
|
||||||
import cash.z.ecc.android.sdk.internal.VERSION_1
|
import cash.z.ecc.android.sdk.internal.VERSION_1
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
object CheckpointFixture {
|
object CheckpointFixture {
|
||||||
|
|
|
@ -10,10 +10,11 @@ import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackend
|
import cash.z.ecc.android.sdk.jni.RustBackend
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
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.tool.CheckpointTool
|
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -21,13 +22,13 @@ import java.io.File
|
||||||
/**
|
/**
|
||||||
* Simplified Initializer focused on starting from a ViewingKey.
|
* Simplified Initializer focused on starting from a ViewingKey.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("LongParameterList")
|
||||||
class Initializer private constructor(
|
class Initializer private constructor(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
internal val rustBackend: RustBackend,
|
internal val rustBackend: RustBackend,
|
||||||
val network: ZcashNetwork,
|
val network: ZcashNetwork,
|
||||||
val alias: String,
|
val alias: String,
|
||||||
val host: String,
|
val lightWalletEndpoint: LightWalletEndpoint,
|
||||||
val port: Int,
|
|
||||||
val viewingKeys: List<UnifiedViewingKey>,
|
val viewingKeys: List<UnifiedViewingKey>,
|
||||||
val overwriteVks: Boolean,
|
val overwriteVks: Boolean,
|
||||||
internal val checkpoint: Checkpoint
|
internal val checkpoint: Checkpoint
|
||||||
|
@ -45,10 +46,7 @@ class Initializer private constructor(
|
||||||
lateinit var network: ZcashNetwork
|
lateinit var network: ZcashNetwork
|
||||||
private set
|
private set
|
||||||
|
|
||||||
lateinit var host: String
|
lateinit var lightWalletEndpoint: LightWalletEndpoint
|
||||||
private set
|
|
||||||
|
|
||||||
var port: Int = ZcashNetwork.Mainnet.defaultPort
|
|
||||||
private set
|
private set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,12 +158,10 @@ class Initializer private constructor(
|
||||||
*/
|
*/
|
||||||
fun setNetwork(
|
fun setNetwork(
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
host: String = network.defaultHost,
|
lightWalletEndpoint: LightWalletEndpoint
|
||||||
port: Int = network.defaultPort
|
|
||||||
): Config = apply {
|
): Config = apply {
|
||||||
this.network = network
|
this.network = network
|
||||||
this.host = host
|
this.lightWalletEndpoint = lightWalletEndpoint
|
||||||
this.port = port
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,16 +171,14 @@ class Initializer private constructor(
|
||||||
seed: ByteArray,
|
seed: ByteArray,
|
||||||
birthday: BlockHeight?,
|
birthday: BlockHeight?,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
host: String = network.defaultHost,
|
lightWalletEndpoint: LightWalletEndpoint,
|
||||||
port: Int = network.defaultPort,
|
|
||||||
alias: String = ZcashSdk.DEFAULT_ALIAS
|
alias: String = ZcashSdk.DEFAULT_ALIAS
|
||||||
): Config =
|
): Config =
|
||||||
importWallet(
|
importWallet(
|
||||||
DerivationTool.deriveUnifiedViewingKeys(seed, network = network)[0],
|
DerivationTool.deriveUnifiedViewingKeys(seed, network = network)[0],
|
||||||
birthday,
|
birthday,
|
||||||
network,
|
network,
|
||||||
host,
|
lightWalletEndpoint,
|
||||||
port,
|
|
||||||
alias
|
alias
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -195,12 +189,11 @@ class Initializer private constructor(
|
||||||
viewingKey: UnifiedViewingKey,
|
viewingKey: UnifiedViewingKey,
|
||||||
birthday: BlockHeight?,
|
birthday: BlockHeight?,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
host: String = network.defaultHost,
|
lightWalletEndpoint: LightWalletEndpoint,
|
||||||
port: Int = network.defaultPort,
|
|
||||||
alias: String = ZcashSdk.DEFAULT_ALIAS
|
alias: String = ZcashSdk.DEFAULT_ALIAS
|
||||||
): Config = apply {
|
): Config = apply {
|
||||||
setViewingKeys(viewingKey)
|
setViewingKeys(viewingKey)
|
||||||
setNetwork(network, host, port)
|
setNetwork(network, lightWalletEndpoint)
|
||||||
importedWalletBirthday(birthday)
|
importedWalletBirthday(birthday)
|
||||||
this.alias = alias
|
this.alias = alias
|
||||||
}
|
}
|
||||||
|
@ -211,14 +204,12 @@ class Initializer private constructor(
|
||||||
suspend fun newWallet(
|
suspend fun newWallet(
|
||||||
seed: ByteArray,
|
seed: ByteArray,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
host: String = network.defaultHost,
|
lightWalletEndpoint: LightWalletEndpoint,
|
||||||
port: Int = network.defaultPort,
|
|
||||||
alias: String = ZcashSdk.DEFAULT_ALIAS
|
alias: String = ZcashSdk.DEFAULT_ALIAS
|
||||||
): Config = newWallet(
|
): Config = newWallet(
|
||||||
DerivationTool.deriveUnifiedViewingKeys(seed, network)[0],
|
DerivationTool.deriveUnifiedViewingKeys(seed, network)[0],
|
||||||
network,
|
network,
|
||||||
host,
|
lightWalletEndpoint,
|
||||||
port,
|
|
||||||
alias
|
alias
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -228,12 +219,11 @@ class Initializer private constructor(
|
||||||
fun newWallet(
|
fun newWallet(
|
||||||
viewingKey: UnifiedViewingKey,
|
viewingKey: UnifiedViewingKey,
|
||||||
network: ZcashNetwork,
|
network: ZcashNetwork,
|
||||||
host: String = network.defaultHost,
|
lightWalletEndpoint: LightWalletEndpoint,
|
||||||
port: Int = network.defaultPort,
|
|
||||||
alias: String = ZcashSdk.DEFAULT_ALIAS
|
alias: String = ZcashSdk.DEFAULT_ALIAS
|
||||||
): Config = apply {
|
): Config = apply {
|
||||||
setViewingKeys(viewingKey)
|
setViewingKeys(viewingKey)
|
||||||
setNetwork(network, host, port)
|
setNetwork(network, lightWalletEndpoint)
|
||||||
newWalletBirthday()
|
newWalletBirthday()
|
||||||
this.alias = alias
|
this.alias = alias
|
||||||
}
|
}
|
||||||
|
@ -352,8 +342,7 @@ class Initializer private constructor(
|
||||||
rustBackend,
|
rustBackend,
|
||||||
config.network,
|
config.network,
|
||||||
config.alias,
|
config.alias,
|
||||||
config.host,
|
config.lightWalletEndpoint,
|
||||||
config.port,
|
|
||||||
config.viewingKeys,
|
config.viewingKeys,
|
||||||
config.overwriteVks,
|
config.overwriteVks,
|
||||||
loadedCheckpoint
|
loadedCheckpoint
|
||||||
|
|
|
@ -50,12 +50,12 @@ import cash.z.ecc.android.sdk.internal.twigTask
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
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.sdk.type.AddressType.Shielded
|
import cash.z.ecc.android.sdk.type.AddressType.Shielded
|
||||||
import cash.z.ecc.android.sdk.type.AddressType.Transparent
|
import cash.z.ecc.android.sdk.type.AddressType.Transparent
|
||||||
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import cash.z.wallet.sdk.rpc.Service
|
import cash.z.wallet.sdk.rpc.Service
|
||||||
import io.grpc.ManagedChannel
|
import io.grpc.ManagedChannel
|
||||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||||
|
@ -308,20 +308,6 @@ class SdkSynchronizer internal constructor(
|
||||||
*/
|
*/
|
||||||
override suspend fun getServerInfo(): Service.LightdInfo = processor.downloader.getServerInfo()
|
override suspend fun getServerInfo(): Service.LightdInfo = processor.downloader.getServerInfo()
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the server that is being used to download compact blocks. This will throw an
|
|
||||||
* exception if it detects that the server change is invalid e.g. switching to testnet from
|
|
||||||
* mainnet.
|
|
||||||
*/
|
|
||||||
override suspend fun changeServer(host: String, port: Int, errorHandler: (Throwable) -> Unit) {
|
|
||||||
val info =
|
|
||||||
(processor.downloader.lightWalletService as LightWalletGrpcService).connectionInfo
|
|
||||||
processor.downloader.changeService(
|
|
||||||
LightWalletGrpcService(info.appContext, host, port),
|
|
||||||
errorHandler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getNearestRewindHeight(height: BlockHeight): BlockHeight =
|
override suspend fun getNearestRewindHeight(height: BlockHeight): BlockHeight =
|
||||||
processor.getNearestRewindHeight(height)
|
processor.getNearestRewindHeight(height)
|
||||||
|
|
||||||
|
@ -800,7 +786,7 @@ object DefaultSynchronizerFactory {
|
||||||
CompactBlockDbStore.new(initializer.context, initializer.network, initializer.rustBackend.pathCacheDb)
|
CompactBlockDbStore.new(initializer.context, initializer.network, initializer.rustBackend.pathCacheDb)
|
||||||
|
|
||||||
fun defaultService(initializer: Initializer): LightWalletService =
|
fun defaultService(initializer: Initializer): LightWalletService =
|
||||||
LightWalletGrpcService(initializer.context, initializer.host, initializer.port)
|
LightWalletGrpcService.new(initializer.context, initializer.lightWalletEndpoint)
|
||||||
|
|
||||||
fun defaultEncoder(
|
fun defaultEncoder(
|
||||||
initializer: Initializer,
|
initializer: Initializer,
|
||||||
|
|
|
@ -7,9 +7,9 @@ import cash.z.ecc.android.sdk.ext.ZcashSdk
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.type.AddressType
|
import cash.z.ecc.android.sdk.type.AddressType
|
||||||
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
import cash.z.ecc.android.sdk.type.ConsensusMatchType
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import cash.z.wallet.sdk.rpc.Service
|
import cash.z.wallet.sdk.rpc.Service
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
@ -284,18 +284,6 @@ interface Synchronizer {
|
||||||
*/
|
*/
|
||||||
suspend fun getServerInfo(): Service.LightdInfo
|
suspend fun getServerInfo(): Service.LightdInfo
|
||||||
|
|
||||||
/**
|
|
||||||
* Gracefully change the server that the Synchronizer is currently using. In some cases, this
|
|
||||||
* will require waiting until current network activity is complete. Ideally, this would protect
|
|
||||||
* against accidentally switching between testnet and mainnet, by comparing the service info of
|
|
||||||
* the existing server with that of the new one.
|
|
||||||
*/
|
|
||||||
suspend fun changeServer(
|
|
||||||
host: String,
|
|
||||||
port: Int = network.defaultPort,
|
|
||||||
errorHandler: (Throwable) -> Unit = { throw it }
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download all UTXOs for the given address and store any new ones in the database.
|
* Download all UTXOs for the given address and store any new ones in the database.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cash.z.ecc.android.sdk.exception
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.wallet.sdk.rpc.Service
|
import cash.z.wallet.sdk.rpc.Service
|
||||||
import io.grpc.Status
|
import io.grpc.Status
|
||||||
import io.grpc.Status.Code.UNAVAILABLE
|
import io.grpc.Status.Code.UNAVAILABLE
|
||||||
|
|
|
@ -2,7 +2,7 @@ package cash.z.ecc.android.sdk.internal
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
// Version is not returned from the server, so version 1 is implied. A version is declared here
|
// Version is not returned from the server, so version 1 is implied. A version is declared here
|
||||||
|
|
|
@ -8,7 +8,7 @@ import cash.z.ecc.android.sdk.internal.SdkDispatchers
|
||||||
import cash.z.ecc.android.sdk.internal.SdkExecutors
|
import cash.z.ecc.android.sdk.internal.SdkExecutors
|
||||||
import cash.z.ecc.android.sdk.internal.db.CompactBlockDb
|
import cash.z.ecc.android.sdk.internal.db.CompactBlockDb
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.wallet.sdk.rpc.CompactFormats
|
import cash.z.wallet.sdk.rpc.CompactFormats
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package cash.z.ecc.android.sdk.internal.service
|
package cash.z.ecc.android.sdk.internal.service
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import cash.z.ecc.android.sdk.R
|
|
||||||
import cash.z.ecc.android.sdk.annotation.OpenForTesting
|
import cash.z.ecc.android.sdk.annotation.OpenForTesting
|
||||||
import cash.z.ecc.android.sdk.exception.LightWalletException
|
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.LightWalletEndpoint
|
||||||
import cash.z.wallet.sdk.rpc.CompactFormats
|
import cash.z.wallet.sdk.rpc.CompactFormats
|
||||||
import cash.z.wallet.sdk.rpc.CompactTxStreamerGrpc
|
import cash.z.wallet.sdk.rpc.CompactTxStreamerGrpc
|
||||||
import cash.z.wallet.sdk.rpc.Service
|
import cash.z.wallet.sdk.rpc.Service
|
||||||
|
@ -31,39 +29,14 @@ import kotlin.time.Duration.Companion.seconds
|
||||||
*/
|
*/
|
||||||
@OpenForTesting
|
@OpenForTesting
|
||||||
class LightWalletGrpcService private constructor(
|
class LightWalletGrpcService private constructor(
|
||||||
|
context: Context,
|
||||||
|
private val lightWalletEndpoint: LightWalletEndpoint,
|
||||||
var channel: ManagedChannel,
|
var channel: ManagedChannel,
|
||||||
private val singleRequestTimeout: Duration = 10.seconds,
|
private val singleRequestTimeout: Duration = 10.seconds,
|
||||||
private val streamingRequestTimeout: Duration = 90.seconds
|
private val streamingRequestTimeout: Duration = 90.seconds
|
||||||
) : LightWalletService {
|
) : LightWalletService {
|
||||||
|
|
||||||
lateinit var connectionInfo: ConnectionInfo
|
private val applicationContext = context.applicationContext
|
||||||
|
|
||||||
constructor(
|
|
||||||
appContext: Context,
|
|
||||||
network: ZcashNetwork,
|
|
||||||
usePlaintext: Boolean =
|
|
||||||
appContext.resources.getBoolean(R.bool.lightwalletd_allow_very_insecure_connections)
|
|
||||||
) : this(appContext, network.defaultHost, network.defaultPort, usePlaintext)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an instance that corresponds to the given host and port.
|
|
||||||
*
|
|
||||||
* @param appContext the application context used to check whether TLS is required by this build
|
|
||||||
* flavor.
|
|
||||||
* @param host the host of the server to use.
|
|
||||||
* @param port the port of the server to use.
|
|
||||||
* @param usePlaintext whether to use TLS or plaintext for requests. Plaintext is dangerous so
|
|
||||||
* it requires jumping through a few more hoops.
|
|
||||||
*/
|
|
||||||
constructor(
|
|
||||||
appContext: Context,
|
|
||||||
host: String,
|
|
||||||
port: Int = ZcashNetwork.Mainnet.defaultPort,
|
|
||||||
usePlaintext: Boolean =
|
|
||||||
appContext.resources.getBoolean(R.bool.lightwalletd_allow_very_insecure_connections)
|
|
||||||
) : this(createDefaultChannel(appContext, host, port, usePlaintext)) {
|
|
||||||
connectionInfo = ConnectionInfo(appContext.applicationContext, host, port, usePlaintext)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LightWalletService implementation */
|
/* LightWalletService implementation */
|
||||||
|
|
||||||
|
@ -141,22 +114,14 @@ class LightWalletGrpcService private constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reconnect() {
|
override fun reconnect() {
|
||||||
twig(
|
twig("closing existing channel and then reconnecting")
|
||||||
"closing existing channel and then reconnecting to ${connectionInfo.host}:" +
|
|
||||||
"${connectionInfo.port}?usePlaintext=${connectionInfo.usePlaintext}"
|
|
||||||
)
|
|
||||||
channel.shutdown()
|
channel.shutdown()
|
||||||
channel = createDefaultChannel(
|
channel = createDefaultChannel(applicationContext, lightWalletEndpoint)
|
||||||
connectionInfo.appContext,
|
|
||||||
connectionInfo.host,
|
|
||||||
connectionInfo.port,
|
|
||||||
connectionInfo.usePlaintext
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test code
|
// test code
|
||||||
var stateCount = 0
|
internal var stateCount = 0
|
||||||
var state: ConnectivityState? = null
|
internal var state: ConnectivityState? = null
|
||||||
private fun requireChannel(): ManagedChannel {
|
private fun requireChannel(): ManagedChannel {
|
||||||
state = channel.getState(false).let { new ->
|
state = channel.getState(false).let { new ->
|
||||||
if (state == new) stateCount++ else stateCount = 0
|
if (state == new) stateCount++ else stateCount = 0
|
||||||
|
@ -172,37 +137,13 @@ class LightWalletGrpcService private constructor(
|
||||||
return channel
|
return channel
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Utilities
|
|
||||||
//
|
|
||||||
|
|
||||||
private fun Channel.createStub(timeoutSec: Duration = 60.seconds) = CompactTxStreamerGrpc
|
|
||||||
.newBlockingStub(this)
|
|
||||||
.withDeadlineAfter(timeoutSec.inWholeSeconds, TimeUnit.SECONDS)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function effectively parses streaming responses. Each call to next(), on the iterators
|
|
||||||
* returned from grpc, triggers a network call.
|
|
||||||
*/
|
|
||||||
private fun <T> Iterator<T>.toList(): List<T> =
|
|
||||||
mutableListOf<T>().apply {
|
|
||||||
while (hasNext()) {
|
|
||||||
this@apply += next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class ConnectionInfo(
|
|
||||||
val appContext: Context,
|
|
||||||
val host: String,
|
|
||||||
val port: Int,
|
|
||||||
val usePlaintext: Boolean
|
|
||||||
) {
|
|
||||||
override fun toString(): String {
|
|
||||||
return "$host:$port?usePlaintext=$usePlaintext"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
fun new(context: Context, lightWalletEndpoint: LightWalletEndpoint): LightWalletGrpcService {
|
||||||
|
val channel = createDefaultChannel(context, lightWalletEndpoint)
|
||||||
|
|
||||||
|
return LightWalletGrpcService(context, lightWalletEndpoint, channel)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience function for creating the default channel to be used for all connections. It
|
* Convenience function for creating the default channel to be used for all connections. It
|
||||||
* is important that this channel can handle transitioning from WiFi to Cellular connections
|
* is important that this channel can handle transitioning from WiFi to Cellular connections
|
||||||
|
@ -210,24 +151,23 @@ class LightWalletGrpcService private constructor(
|
||||||
*/
|
*/
|
||||||
fun createDefaultChannel(
|
fun createDefaultChannel(
|
||||||
appContext: Context,
|
appContext: Context,
|
||||||
host: String,
|
lightWalletEndpoint: LightWalletEndpoint
|
||||||
port: Int,
|
|
||||||
usePlaintext: Boolean
|
|
||||||
): ManagedChannel {
|
): ManagedChannel {
|
||||||
twig("Creating channel that will connect to $host:$port?usePlaintext=$usePlaintext")
|
twig(
|
||||||
|
"Creating channel that will connect to " +
|
||||||
|
"${lightWalletEndpoint.host}:${lightWalletEndpoint.port}" +
|
||||||
|
"/?usePlaintext=${!lightWalletEndpoint.isSecure}"
|
||||||
|
)
|
||||||
return AndroidChannelBuilder
|
return AndroidChannelBuilder
|
||||||
.forAddress(host, port)
|
.forAddress(lightWalletEndpoint.host, lightWalletEndpoint.port)
|
||||||
.context(appContext)
|
.context(appContext)
|
||||||
.enableFullStreamDecompression()
|
.enableFullStreamDecompression()
|
||||||
.apply {
|
.apply {
|
||||||
if (usePlaintext) {
|
if (lightWalletEndpoint.isSecure) {
|
||||||
if (!appContext.resources.getBoolean(
|
|
||||||
R.bool.lightwalletd_allow_very_insecure_connections
|
|
||||||
)
|
|
||||||
) throw LightWalletException.InsecureConnection
|
|
||||||
usePlaintext()
|
|
||||||
} else {
|
|
||||||
useTransportSecurity()
|
useTransportSecurity()
|
||||||
|
} else {
|
||||||
|
twig("WARNING: Using insecure channel")
|
||||||
|
usePlaintext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
|
@ -235,6 +175,10 @@ class LightWalletGrpcService private constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Channel.createStub(timeoutSec: Duration = 60.seconds) = CompactTxStreamerGrpc
|
||||||
|
.newBlockingStub(this)
|
||||||
|
.withDeadlineAfter(timeoutSec.inWholeSeconds, TimeUnit.SECONDS)
|
||||||
|
|
||||||
private fun BlockHeight.toBlockHeight(): Service.BlockID =
|
private fun BlockHeight.toBlockHeight(): Service.BlockID =
|
||||||
Service.BlockID.newBuilder().setHeight(value).build()
|
Service.BlockID.newBuilder().setHeight(value).build()
|
||||||
|
|
||||||
|
@ -243,3 +187,14 @@ private fun ClosedRange<BlockHeight>.toBlockRange(): Service.BlockRange =
|
||||||
.setStart(start.toBlockHeight())
|
.setStart(start.toBlockHeight())
|
||||||
.setEnd(endInclusive.toBlockHeight())
|
.setEnd(endInclusive.toBlockHeight())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function effectively parses streaming responses. Each call to next(), on the iterators
|
||||||
|
* returned from grpc, triggers a network call.
|
||||||
|
*/
|
||||||
|
private fun <T> Iterator<T>.toList(): List<T> =
|
||||||
|
mutableListOf<T>().apply {
|
||||||
|
while (hasNext()) {
|
||||||
|
this@apply += next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@ import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackend
|
import cash.z.ecc.android.sdk.jni.RustBackend
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.flow.emitAll
|
import kotlinx.coroutines.flow.emitAll
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
|
@ -9,9 +9,9 @@ import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.tool.DerivationTool
|
import cash.z.ecc.android.sdk.tool.DerivationTool
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.model.WalletBalance
|
import cash.z.ecc.android.sdk.model.WalletBalance
|
||||||
import cash.z.ecc.android.sdk.model.Zatoshi
|
import cash.z.ecc.android.sdk.model.Zatoshi
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contract defining the exposed capabilities of the Rust backend.
|
* Contract defining the exposed capabilities of the Rust backend.
|
||||||
|
|
|
@ -2,7 +2,6 @@ package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
import cash.z.ecc.android.sdk.tool.CheckpointTool
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a block height, which is a UInt32. SDK clients use this class to represent the "birthday" of a wallet.
|
* Represents a block height, which is a UInt32. SDK clients use this class to represent the "birthday" of a wallet.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
data class LightWalletEndpoint(val host: String, val port: Int, val isSecure: Boolean) {
|
||||||
|
companion object
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
@file:Suppress("ktlint:filename")
|
||||||
|
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a set of extension functions currently, because we expect them to change in the future.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fun LightWalletEndpoint.Companion.defaultForNetwork(zcashNetwork: ZcashNetwork): LightWalletEndpoint {
|
||||||
|
return when (zcashNetwork.id) {
|
||||||
|
ZcashNetwork.Mainnet.id -> LightWalletEndpoint.Mainnet
|
||||||
|
ZcashNetwork.Testnet.id -> LightWalletEndpoint.Testnet
|
||||||
|
else -> error("Unknown network id: ${zcashNetwork.id}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a special localhost value on the Android emulator, which allows it to contact
|
||||||
|
* the localhost of the computer running the emulator.
|
||||||
|
*/
|
||||||
|
private const val COMPUTER_LOCALHOST = "10.0.2.2"
|
||||||
|
|
||||||
|
private const val DEFAULT_PORT = 9067
|
||||||
|
|
||||||
|
val LightWalletEndpoint.Companion.Mainnet
|
||||||
|
get() = LightWalletEndpoint(
|
||||||
|
"mainnet.lightwalletd.com",
|
||||||
|
DEFAULT_PORT,
|
||||||
|
isSecure = true
|
||||||
|
)
|
||||||
|
|
||||||
|
val LightWalletEndpoint.Companion.Testnet
|
||||||
|
get() = LightWalletEndpoint(
|
||||||
|
"testnet.lightwalletd.com",
|
||||||
|
DEFAULT_PORT,
|
||||||
|
isSecure = true
|
||||||
|
)
|
||||||
|
|
||||||
|
val LightWalletEndpoint.Companion.Darkside
|
||||||
|
get() = LightWalletEndpoint(
|
||||||
|
COMPUTER_LOCALHOST,
|
||||||
|
DEFAULT_PORT,
|
||||||
|
isSecure = false
|
||||||
|
)
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Zcash network. Should be one of [ZcashNetwork.Testnet] or [ZcashNetwork.Mainnet].
|
||||||
|
*
|
||||||
|
* The constructor for the network is public to allow for certain test cases to use a custom "darkside" network.
|
||||||
|
*/
|
||||||
|
data class ZcashNetwork(
|
||||||
|
val id: Int,
|
||||||
|
val networkName: String,
|
||||||
|
val saplingActivationHeight: BlockHeight,
|
||||||
|
val orchardActivationHeight: BlockHeight
|
||||||
|
) {
|
||||||
|
|
||||||
|
@Suppress("MagicNumber")
|
||||||
|
companion object {
|
||||||
|
const val ID_TESTNET = 0
|
||||||
|
const val ID_MAINNET = 1
|
||||||
|
|
||||||
|
// You may notice there are extra checkpoints bundled in the SDK that match the
|
||||||
|
// sapling/orchard activation heights.
|
||||||
|
|
||||||
|
val Testnet = ZcashNetwork(
|
||||||
|
ID_TESTNET,
|
||||||
|
"testnet",
|
||||||
|
saplingActivationHeight = BlockHeight(280_000),
|
||||||
|
orchardActivationHeight = BlockHeight(1_842_420)
|
||||||
|
)
|
||||||
|
|
||||||
|
val Mainnet = ZcashNetwork(
|
||||||
|
ID_MAINNET,
|
||||||
|
"mainnet",
|
||||||
|
saplingActivationHeight = BlockHeight(419_200),
|
||||||
|
orchardActivationHeight = BlockHeight(1_687_104)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun from(id: Int) = when (id) {
|
||||||
|
0 -> Testnet
|
||||||
|
1 -> Mainnet
|
||||||
|
else -> throw IllegalArgumentException("Unknown network id: $id")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import cash.z.ecc.android.sdk.internal.from
|
||||||
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
import cash.z.ecc.android.sdk.internal.model.Checkpoint
|
||||||
import cash.z.ecc.android.sdk.internal.twig
|
import cash.z.ecc.android.sdk.internal.twig
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
|
|
@ -2,8 +2,8 @@ package cash.z.ecc.android.sdk.tool
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackend
|
import cash.z.ecc.android.sdk.jni.RustBackend
|
||||||
import cash.z.ecc.android.sdk.jni.RustBackendWelding
|
import cash.z.ecc.android.sdk.jni.RustBackendWelding
|
||||||
|
import cash.z.ecc.android.sdk.model.ZcashNetwork
|
||||||
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
import cash.z.ecc.android.sdk.type.UnifiedViewingKey
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
|
|
||||||
class DerivationTool {
|
class DerivationTool {
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package cash.z.ecc.android.sdk.type
|
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.model.BlockHeight
|
|
||||||
|
|
||||||
enum class ZcashNetwork(
|
|
||||||
val id: Int,
|
|
||||||
val networkName: String,
|
|
||||||
val saplingActivationHeight: BlockHeight,
|
|
||||||
val defaultHost: String,
|
|
||||||
val defaultPort: Int
|
|
||||||
) {
|
|
||||||
Testnet(0, "testnet", BlockHeight(280_000), "testnet.lightwalletd.com", 9067),
|
|
||||||
Mainnet(1, "mainnet", BlockHeight(419_200), "mainnet.lightwalletd.com", 9067);
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun from(id: Int) = values().first { it.id == id }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<bool name="lightwalletd_allow_very_insecure_connections">false</bool>
|
|
||||||
</resources>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="sdk_test_message">Library linking is working!</string>
|
|
||||||
</resources>
|
|
|
@ -1,6 +1,5 @@
|
||||||
package cash.z.ecc.android.sdk.model
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
import cash.z.ecc.android.sdk.type.ZcashNetwork
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package cash.z.ecc.android.sdk.model
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class LightWalletEndpointTest {
|
||||||
|
@Test
|
||||||
|
fun requireSecureMainnet() {
|
||||||
|
assertTrue(LightWalletEndpoint.Mainnet.isSecure)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun requireSecureTestnet() {
|
||||||
|
assertTrue(LightWalletEndpoint.Testnet.isSecure)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue