208 lines
7.7 KiB
Kotlin
208 lines
7.7 KiB
Kotlin
package cash.z.wallet.sdk.sample.demoapp
|
|
|
|
import androidx.test.platform.app.InstrumentationRegistry
|
|
import cash.z.ecc.android.sdk.Synchronizer
|
|
import cash.z.ecc.android.sdk.demoapp.util.fromResources
|
|
import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
|
|
import cash.z.ecc.android.sdk.ext.toHex
|
|
import cash.z.ecc.android.sdk.internal.Twig
|
|
import cash.z.ecc.android.sdk.model.Account
|
|
import cash.z.ecc.android.sdk.model.BlockHeight
|
|
import cash.z.ecc.android.sdk.model.Mainnet
|
|
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 co.electriccoin.lightwallet.client.LightWalletClient
|
|
import co.electriccoin.lightwallet.client.model.BlockHeightUnsafe
|
|
import co.electriccoin.lightwallet.client.model.CompactBlockUnsafe
|
|
import co.electriccoin.lightwallet.client.model.LightWalletEndpoint
|
|
import co.electriccoin.lightwallet.client.model.Response
|
|
import co.electriccoin.lightwallet.client.new
|
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|
import kotlinx.coroutines.flow.filterIsInstance
|
|
import kotlinx.coroutines.flow.map
|
|
import kotlinx.coroutines.flow.onEach
|
|
import kotlinx.coroutines.flow.toList
|
|
import kotlinx.coroutines.runBlocking
|
|
import kotlinx.coroutines.test.runTest
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Assert.assertFalse
|
|
import org.junit.Assert.assertTrue
|
|
import org.junit.Ignore
|
|
import org.junit.Test
|
|
|
|
/**
|
|
* Sample code to demonstrate key functionality without UI, inspired by:
|
|
* https://github.com/EdgeApp/eosjs-node-cli/blob/paul/cleanup/app.js
|
|
*/
|
|
class SampleCodeTest {
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Seed derivation
|
|
@Ignore("This test is not implemented")
|
|
@Test
|
|
fun createBip39Seed_fromSeedPhrase() {
|
|
// TODO: log(seedPhrase.asRawEntropy().asBip39seed())
|
|
}
|
|
|
|
@Ignore("This test is not implemented")
|
|
@Test
|
|
fun createRawEntropy() {
|
|
// TODO: call: Mnemonic::from_phrase(seed_phrase, Language::English).unwrap().entropy()
|
|
// log(seedPhrase.asRawEntropy())
|
|
}
|
|
|
|
@Ignore("This test is not implemented")
|
|
@Test
|
|
fun createBip39Seed_fromRawEntropy() {
|
|
// get the 64 byte bip39 entropy
|
|
// TODO: call: bip39::Seed::new(&Mnemonic::from_entropy(&seed_bytes, Language::English).unwrap(), "")
|
|
// log(rawEntropy.asBip39Seed())
|
|
}
|
|
|
|
@Ignore("This test is not implemented")
|
|
@Test
|
|
fun deriveSeedPhraseFrom() {
|
|
// TODO: let mnemonic = Mnemonic::from_entropy(entropy, Language::English).unwrap();
|
|
// log(entropy.asSeedPhrase())
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Get Address
|
|
@Test
|
|
fun getAddress() = runBlocking {
|
|
val address = synchronizer.getUnifiedAddress()
|
|
assertFalse(address.isBlank())
|
|
log("Address: $address")
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Derive address from Extended Full Viewing Key
|
|
@Test
|
|
fun getAddressFromViewingKey() {
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Query latest block height
|
|
@Test
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
fun getLatestBlockHeightTest() = runTest {
|
|
// Test the result, only if there is no server communication problem.
|
|
runCatching {
|
|
LightWalletClient.new(context, lightwalletdHost).getLatestBlockHeight()
|
|
}.onFailure {
|
|
Twig.debug(it) { "Failed to retrieve data" }
|
|
}.onSuccess {
|
|
assertTrue(it is Response.Success<BlockHeightUnsafe>)
|
|
Twig.debug { "Latest Block: ${(it as Response.Success<BlockHeightUnsafe>).result}" }
|
|
}
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Download compact block range
|
|
@Test
|
|
@OptIn(ExperimentalCoroutinesApi::class)
|
|
fun getBlockRange() = runTest {
|
|
val blockRange = BlockHeightUnsafe(
|
|
BlockHeight.new(
|
|
ZcashNetwork.Mainnet,
|
|
500_000
|
|
).value
|
|
)..BlockHeightUnsafe(
|
|
(
|
|
BlockHeight.new(
|
|
ZcashNetwork.Mainnet,
|
|
500_009
|
|
).value
|
|
)
|
|
)
|
|
|
|
val lightWalletClient = LightWalletClient.new(context, lightwalletdHost)
|
|
|
|
// Test the result, only if there is no server communication problem.
|
|
runCatching {
|
|
lightWalletClient.getBlockRange(blockRange)
|
|
}.onFailure {
|
|
Twig.debug(it) { "Failed to retrieve data" }
|
|
}.onSuccess {
|
|
it.onEach { response ->
|
|
assert(response is Response.Success) { "Server communication failed." }
|
|
}
|
|
.filterIsInstance<Response.Success<CompactBlockUnsafe>>()
|
|
.map { response ->
|
|
response.result
|
|
}.toList()
|
|
.also { blocks ->
|
|
assertEquals(blockRange.endInclusive.value - blockRange.start.value, blocks.count())
|
|
|
|
blocks.forEachIndexed { i, block ->
|
|
log("Block #$i: height:${block.height} hash:${block.hash.toHex()}")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Query account outgoing transactions
|
|
@Test
|
|
fun queryOutgoingTransactions() {
|
|
}
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Query account incoming transactions
|
|
@Test
|
|
fun queryIncomingTransactions() {
|
|
}
|
|
|
|
// // ///////////////////////////////////////////////////
|
|
// // Create a signed transaction (with memo)
|
|
// @Test fun createTransaction() = runBlocking {
|
|
// val rustBackend = RustBackend.init(context)
|
|
// val repository = PagedTransactionRepository(context)
|
|
// val encoder = WalletTransactionEncoder(rustBackend, repository)
|
|
// val spendingKey = DerivationTool.deriveSpendingKeys(seed, ZcashNetwork.Mainnet)[0]
|
|
//
|
|
// val amount = 0.123.convertZecToZatoshi()
|
|
// val address = "ztestsapling1tklsjr0wyw0d58f3p7wufvrj2cyfv6q6caumyueadq8qvqt8lda6v6tpx474rfru9y6u75u7qnw"
|
|
// val memo = "Test Transaction".toByteArray()
|
|
//
|
|
// val encodedTx = encoder.createTransaction(spendingKey, amount, address, memo)
|
|
// assertTrue(encodedTx.raw.isNotEmpty())
|
|
// log("Transaction ID: ${encodedTx.txId.toHex()}")
|
|
// }
|
|
|
|
// ///////////////////////////////////////////////////
|
|
// Create a signed transaction (with memo) and broadcast
|
|
@Test
|
|
fun submitTransaction() = runBlocking {
|
|
val amount = 0.123.convertZecToZatoshi()
|
|
val address = "ztestsapling1tklsjr0wyw0d58f3p7wufvrj2cyfv6q6caumyueadq8qvqt8lda6v6tpx474rfru9y6u75u7qnw"
|
|
val memo = "Test Transaction"
|
|
val spendingKey = DerivationTool.getInstance().deriveUnifiedSpendingKey(seed, ZcashNetwork.Mainnet, Account.DEFAULT)
|
|
synchronizer.sendToAddress(spendingKey, amount, address, memo)
|
|
}
|
|
|
|
// /////////////////////////////////////////////////////
|
|
// Utility Functions
|
|
// ////////////////////////////////////////////////////
|
|
|
|
companion object {
|
|
private val seed = "Insert seed for testing".toByteArray()
|
|
private val lightwalletdHost = LightWalletEndpoint.Mainnet
|
|
|
|
private val context = InstrumentationRegistry.getInstrumentation().targetContext
|
|
private val synchronizer: Synchronizer = run {
|
|
val network = ZcashNetwork.fromResources(context)
|
|
Synchronizer.newBlocking(
|
|
context,
|
|
network,
|
|
lightWalletEndpoint = LightWalletEndpoint.defaultForNetwork(network),
|
|
seed = seed,
|
|
birthday = null
|
|
)
|
|
}
|
|
|
|
fun log(message: String?) = Twig.debug { message ?: "null" }
|
|
}
|
|
}
|