Modifications to configuration and tests.
This commit is contained in:
parent
f81c6b2dff
commit
cdcc39121b
|
@ -8,7 +8,7 @@ apply plugin: 'kotlin-kapt'
|
|||
|
||||
archivesBaseName = 'zcash-android-wallet'
|
||||
group = 'cash.z.ecc.android'
|
||||
version = '1.0.0-alpha03'
|
||||
version = '1.0.0-alpha04'
|
||||
|
||||
android {
|
||||
compileSdkVersion Deps.compileSdkVersion
|
||||
|
@ -18,10 +18,12 @@ android {
|
|||
applicationId 'cash.z.ecc.android'
|
||||
minSdkVersion Deps.minSdkVersion
|
||||
targetSdkVersion Deps.targetSdkVersion
|
||||
versionCode = 1_00_00_003
|
||||
versionCode = 1_00_00_004
|
||||
// last digits are alpha(0XX) beta(2XX) rc(4XX) release(8XX). Ex: 1_08_04_401 is an release candidate build of version 1.8.4 and 1_08_04_800 would be the final release.
|
||||
versionName = "$version"
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
testInstrumentationRunnerArguments clearPackageData: 'true'
|
||||
multiDexEnabled true
|
||||
}
|
||||
flavorDimensions 'network'
|
||||
productFlavors {
|
||||
|
@ -40,11 +42,13 @@ android {
|
|||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
useProguard false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
minifyEnabled true
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
useProguard false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
|
@ -82,6 +86,7 @@ dependencies {
|
|||
implementation project(':feedback')
|
||||
implementation project(':mnemonic')
|
||||
implementation project(':lockbox')
|
||||
implementation project(':sdk')
|
||||
|
||||
// Kotlin
|
||||
implementation Deps.Kotlin.STDLIB
|
||||
|
@ -102,6 +107,11 @@ dependencies {
|
|||
kapt Deps.Dagger.ANDROID_PROCESSOR
|
||||
kapt Deps.Dagger.COMPILER
|
||||
|
||||
// Testing these BIP39 dependencies
|
||||
implementation 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
implementation 'io.github.novacrypto:BIP39:2019.01.27'
|
||||
implementation 'io.github.novacrypto:securestring:2019.01.27'
|
||||
|
||||
// grpc-java
|
||||
implementation "io.grpc:grpc-okhttp:1.21.0"
|
||||
implementation "io.grpc:grpc-android:1.21.0"
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
-dontobfuscate
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Reports
|
||||
-printusage build/outputs/logs/R8-removed-code-report.txt
|
||||
-printseeds build/outputs/logs/R8-entry-points-report.txt
|
||||
|
||||
## Okio
|
||||
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||
|
||||
#-keep class cash.z.** { *; }
|
|
@ -3,16 +3,116 @@ package cash.z.ecc.android.integration
|
|||
import android.content.Context
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import cash.z.ecc.android.lockbox.LockBox
|
||||
import cash.z.ecc.kotlin.mnemonic.Mnemonics
|
||||
import cash.z.wallet.sdk.Initializer
|
||||
import okio.Buffer
|
||||
import okio.GzipSink
|
||||
import okio.Okio
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IntegrationTest {
|
||||
|
||||
private lateinit var appContext: Context
|
||||
private val mnemonics = Mnemonics()
|
||||
private val phrase =
|
||||
"human pulse approve subway climb stairs mind gentle raccoon warfare fog roast sponsor" +
|
||||
" under absorb spirit hurdle animal original honey owner upper empower describe"
|
||||
|
||||
@Before
|
||||
fun start() {
|
||||
appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSeed_generation() {
|
||||
val seed = mnemonics.toSeed(phrase.toCharArray())
|
||||
assertEquals(
|
||||
"Generated incorrect BIP-39 seed!",
|
||||
"f4e3d38d9c244da7d0407e19a93c80429614ee82dcf62c141235751c9f1228905d12a1f275f" +
|
||||
"5c22f6fb7fcd9e0a97f1676e0eec53fdeeeafe8ce8aa39639b9fe",
|
||||
seed.toHex()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSeed_storage() {
|
||||
val seed = mnemonics.toSeed(phrase.toCharArray())
|
||||
val lb = LockBox(appContext)
|
||||
lb.setBytes("seed", seed)
|
||||
assertTrue(seed.contentEquals(lb.getBytes("seed")!!))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPhrase_storage() {
|
||||
val lb = LockBox(appContext)
|
||||
val phraseChars = phrase.toCharArray()
|
||||
lb.setCharsUtf8("phrase", phraseChars)
|
||||
assertTrue(phraseChars.contentEquals(lb.getCharsUtf8("phrase")!!))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPhrase_maxLengthStorage() {
|
||||
val lb = LockBox(appContext)
|
||||
// find and expose the max length
|
||||
var acceptedSize = 256
|
||||
while (acceptedSize > 0) {
|
||||
try {
|
||||
lb.setCharsUtf8("temp", nextString(acceptedSize).toCharArray())
|
||||
break
|
||||
} catch (t: Throwable) {
|
||||
}
|
||||
acceptedSize--
|
||||
}
|
||||
|
||||
val maxSeedPhraseLength = 8 * 24 + 23 //215 (max length of each word is 8)
|
||||
assertTrue(
|
||||
"LockBox does not support the maximum length seed phrase." +
|
||||
" Expected: $maxSeedPhraseLength but was: $acceptedSize",
|
||||
acceptedSize > maxSeedPhraseLength
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAddress() {
|
||||
val seed = mnemonics.toSeed(phrase.toCharArray())
|
||||
val initializer = Initializer(appContext).apply {
|
||||
new(seed, overwrite = true)
|
||||
}
|
||||
assertEquals(
|
||||
"Generated incorrect z-address!",
|
||||
"zs1gn2ah0zqhsxnrqwuvwmgxpl5h3ha033qexhsz8tems53fw877f4gug353eefd6z8z3n4zxty65c",
|
||||
initializer.rustBackend.getAddress()
|
||||
)
|
||||
initializer.clear()
|
||||
}
|
||||
|
||||
|
||||
private fun ByteArray.toHex(): String {
|
||||
val sb = StringBuilder(size * 2)
|
||||
for (b in this)
|
||||
sb.append(String.format("%02x", b))
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun String.gzip(): ByteArray {
|
||||
val result = Buffer()
|
||||
val sink = Okio.buffer(GzipSink(result))
|
||||
sink.use {
|
||||
sink.write(toByteArray())
|
||||
}
|
||||
return result.readByteArray()
|
||||
}
|
||||
|
||||
fun nextString(length: Int): String {
|
||||
val allowedChars = "ACGT"
|
||||
return (1..length)
|
||||
.map { allowedChars.random() }
|
||||
.joinToString("")
|
||||
}
|
||||
}
|
|
@ -4,6 +4,9 @@ import android.content.Context
|
|||
import android.os.Build
|
||||
import cash.z.ecc.android.di.DaggerAppComponent
|
||||
import cash.z.ecc.android.feedback.FeedbackCoordinator
|
||||
import cash.z.wallet.sdk.ext.TroubleshootingTwig
|
||||
import cash.z.wallet.sdk.ext.Twig
|
||||
import cash.z.wallet.sdk.ext.twig
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.DaggerApplication
|
||||
import javax.inject.Inject
|
||||
|
@ -23,7 +26,7 @@ class ZcashWalletApp : DaggerApplication() {
|
|||
super.onCreate()
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(ExceptionReporter(Thread.getDefaultUncaughtExceptionHandler()))
|
||||
// Twig.plant(TroubleshootingTwig())
|
||||
Twig.plant(TroubleshootingTwig())
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,6 +49,7 @@ class ZcashWalletApp : DaggerApplication() {
|
|||
override fun uncaughtException(t: Thread?, e: Throwable?) {
|
||||
// trackCrash(e, "Top-level exception wasn't caught by anything else!")
|
||||
// Analytics.clear()
|
||||
twig("Uncaught Exception: $e")
|
||||
ogHandler.uncaughtException(t, e)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package cash.z.ecc.android
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import kotlin.math.round
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class ScratchPad {
|
||||
|
||||
val t get() = System.currentTimeMillis()
|
||||
var t0 = 0L
|
||||
val Δt get() = t - t0
|
||||
|
||||
@Test
|
||||
fun testMarblesCombine() = runBlocking {
|
||||
var started = false
|
||||
val flow = flowOf(1, 2, 3, 4, 5, 6, 7, 8, 9).onEach {
|
||||
delay(100)
|
||||
if (!started) {
|
||||
t0 = t
|
||||
started = true
|
||||
}
|
||||
println("$Δt\temitting $it");
|
||||
}
|
||||
val flow2 = flowOf("a", "b", "c", "d", "e", "f").onEach { delay(150); println("$Δt\temitting $it")}
|
||||
val flow3 = flowOf("A", "B").onEach { delay(450); println("$Δt\temitting $it")}
|
||||
combine(flow, flow2, flow3) { i, s, t -> "$i$s$t" }.onStart {
|
||||
t0 = t
|
||||
}.collect {
|
||||
// if (!started) {
|
||||
// println("$Δt until first emission")
|
||||
// t0 = t
|
||||
// started = true
|
||||
// }
|
||||
println("$Δt\t$it") // Will print "1a 2a 2b 2c"
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMarblesScan() = runBlocking {
|
||||
val flow = flowOf(1, 2, 3, 4, 5)
|
||||
|
||||
flow.scanReduce { accumulator, value ->
|
||||
println("was: $accumulator now: $value")
|
||||
value
|
||||
}.collect {
|
||||
println("got $it")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
rootProject.name='Zcash Wallet'
|
||||
include ':app', ':qrecycler', ':feedback', ':mnemonic', ':lockbox'
|
||||
include ':app', ':qrecycler', ':feedback', ':mnemonic', ':lockbox', ':sdk'
|
||||
project(":sdk").projectDir = file("../zcash-android-wallet-sdk")
|
Loading…
Reference in New Issue