Updated to the newly refactored (and published) SDK.

This commit is contained in:
Kevin Gorham 2020-06-10 07:49:38 -04:00
parent 901db38ee0
commit 4c4ef46efe
No known key found for this signature in database
GPG Key ID: CCA55602DF49FC38
39 changed files with 347 additions and 218 deletions

View File

@ -11,9 +11,10 @@ apply plugin: 'com.google.firebase.firebase-perf'
archivesBaseName = 'zcash-android-wallet' archivesBaseName = 'zcash-android-wallet'
group = 'cash.z.ecc.android' group = 'cash.z.ecc.android'
version = '1.0.0-alpha25' version = '1.0.0-alpha28'
android { android {
ndkVersion "21.1.6352462"
compileSdkVersion Deps.compileSdkVersion compileSdkVersion Deps.compileSdkVersion
buildToolsVersion Deps.buildToolsVersion buildToolsVersion Deps.buildToolsVersion
viewBinding.enabled = true viewBinding.enabled = true
@ -27,7 +28,6 @@ android {
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
testInstrumentationRunnerArguments clearPackageData: 'true' testInstrumentationRunnerArguments clearPackageData: 'true'
multiDexEnabled true multiDexEnabled true
// manifestPlaceholders = [rollbarToken: properties["rollbarToken"]]
} }
flavorDimensions 'network' flavorDimensions 'network'
productFlavors { productFlavors {
@ -112,30 +112,40 @@ dependencies {
implementation project(':feedback') implementation project(':feedback')
implementation project(':mnemonic') implementation project(':mnemonic')
implementation project(':lockbox') implementation project(':lockbox')
implementation project(':sdk')
implementation project(':chipsinputlayout') implementation project(':chipsinputlayout')
// Zcash // Zcash
implementation 'com.github.zcash:zcash-android-wallet-plugins:1.0.0' implementation Deps.Zcash.ANDROID_WALLET_PLUGINS
zcashtestnetImplementation Deps.Zcash.Sdk.TESTNET
zcashmainnetImplementation Deps.Zcash.Sdk.MAINNET
// Kotlin // Kotlin
implementation Deps.Kotlin.STDLIB implementation Deps.Kotlin.STDLIB
// Android // Android
implementation Deps.AndroidX.ANNOTATION
implementation Deps.AndroidX.APPCOMPAT implementation Deps.AndroidX.APPCOMPAT
implementation Deps.AndroidX.CORE_KTX
implementation Deps.AndroidX.CONSTRAINT_LAYOUT implementation Deps.AndroidX.CONSTRAINT_LAYOUT
implementation Deps.AndroidX.Lifecycle.LIFECYCLE_RUNTIME_KTX implementation Deps.AndroidX.CORE_KTX
implementation Deps.AndroidX.FRAGMENT_KTX
implementation Deps.AndroidX.LEGACY
implementation Deps.AndroidX.PAGING
implementation Deps.AndroidX.CameraX.CAMERA2
implementation Deps.AndroidX.CameraX.CORE
implementation Deps.AndroidX.CameraX.LIFECYCLE
implementation Deps.AndroidX.CameraX.View.EXT
implementation Deps.AndroidX.CameraX.View.VIEW
implementation Deps.AndroidX.Lifecycle.LIFECYCLE_EXTENSIONS implementation Deps.AndroidX.Lifecycle.LIFECYCLE_EXTENSIONS
implementation Deps.AndroidX.Lifecycle.LIFECYCLE_RUNTIME_KTX
implementation Deps.AndroidX.Navigation.FRAGMENT_KTX implementation Deps.AndroidX.Navigation.FRAGMENT_KTX
implementation Deps.AndroidX.Navigation.UI_KTX implementation Deps.AndroidX.Navigation.UI_KTX
implementation "androidx.room:room-ktx:2.2.3" implementation Deps.AndroidX.Room.ROOM_KTX
implementation "androidx.paging:paging-runtime-ktx:2.1.1" kapt Deps.AndroidX.Room.ROOM_COMPILER
implementation 'com.google.guava:guava:27.0.1-android'
kapt "androidx.room:room-compiler:2.2.3"
// Google // Google
implementation Deps.Google.GUAVA
implementation Deps.Google.MATERIAL implementation Deps.Google.MATERIAL
implementation Deps.Google.ML_VISION // QR Scanner
// Dagger // Dagger
implementation Deps.Dagger.ANDROID_SUPPORT implementation Deps.Dagger.ANDROID_SUPPORT
@ -143,44 +153,26 @@ dependencies {
kapt Deps.Dagger.COMPILER kapt Deps.Dagger.COMPILER
// grpc-java // grpc-java
implementation "io.grpc:grpc-okhttp:1.25.0" implementation Deps.Grpc.ANDROID
implementation "io.grpc:grpc-android:1.25.0" implementation Deps.Grpc.OKHTTP
implementation "io.grpc:grpc-protobuf-lite:1.25.0" implementation Deps.Grpc.PROTOBUG
implementation "io.grpc:grpc-stub:1.25.0" implementation Deps.Grpc.STUB
implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation Deps.JavaX.JAVA_ANNOTATION
// solves error: Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules jetified-guava-26.0-android.jar (com.google.guava:guava:26.0-android) and listenablefuture-1.0.jar (com.google.guava:listenablefuture:1.0)
// per this recommendation from Chris Povirk, given guava's decision to split ListenableFuture away from Guava: https://groups.google.com/d/msg/guava-discuss/GghaKwusjcY/bCIAKfzOEwAJ
implementation 'com.google.guava:guava:27.0.1-android'
// Analytics // Analytics (for dogfooding/crash-reporting/feedback only on internal team builds)
implementation 'com.mixpanel.android:mixpanel-android:5.6.3' implementation Deps.Analytics.CRASHLYTICS
implementation 'com.google.firebase:firebase-analytics:17.2.2' implementation Deps.Analytics.CRASHLYTICS_NDK
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' implementation Deps.Analytics.FIREBASE
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.1.1' implementation Deps.Analytics.FIREBASE_PERF
implementation 'com.google.firebase:firebase-perf:19.0.5' implementation Deps.Analytics.MIXPANEL
// QR Scanning
implementation 'com.google.firebase:firebase-ml-vision:24.0.1'
implementation 'androidx.camera:camera-core:1.0.0-alpha10'
implementation 'androidx.camera:camera-camera2:1.0.0-alpha10'
implementation "androidx.camera:camera-view:1.0.0-alpha07"
implementation "androidx.camera:camera-extensions:1.0.0-alpha07"
implementation "androidx.camera:camera-lifecycle:1.0.0-alpha10"
// Misc. // Misc.
implementation 'com.airbnb.android:lottie:3.1.0' implementation Deps.Misc.LOTTIE
implementation 'com.facebook.stetho:stetho:1.5.1'
// check for build errors at https://jitpack.io/com/github/gmale/chips-input-layout/<version>/build.log
// implementation 'com.github.gmale:chips-input-layout:4750760a7222bc04ca48266b387456d2b03541a7'
implementation 'androidx.annotation:annotation:1.1.0'
// Tests // Tests
testImplementation Deps.Test.COROUTINES_TEST
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation Deps.Test.JUNIT testImplementation Deps.Test.JUNIT
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0" testImplementation Deps.Test.MOKITO
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.3'
androidTestImplementation Deps.Test.Android.JUNIT androidTestImplementation Deps.Test.Android.JUNIT
androidTestImplementation Deps.Test.Android.ESPRESSO androidTestImplementation Deps.Test.Android.ESPRESSO
} }

View File

@ -5,7 +5,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.lockbox.LockBox
import cash.z.ecc.kotlin.mnemonic.Mnemonics import cash.z.ecc.kotlin.mnemonic.Mnemonics
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import okio.Buffer import okio.Buffer
import okio.GzipSink import okio.GzipSink
import okio.Okio import okio.Okio

View File

@ -8,10 +8,10 @@ import androidx.camera.core.CameraXConfig
import cash.z.ecc.android.di.component.AppComponent import cash.z.ecc.android.di.component.AppComponent
import cash.z.ecc.android.di.component.DaggerAppComponent import cash.z.ecc.android.di.component.DaggerAppComponent
import cash.z.ecc.android.feedback.FeedbackCoordinator import cash.z.ecc.android.feedback.FeedbackCoordinator
import cash.z.wallet.sdk.ext.SilentTwig import cash.z.ecc.android.sdk.ext.SilentTwig
import cash.z.wallet.sdk.ext.TroubleshootingTwig import cash.z.ecc.android.sdk.ext.TroubleshootingTwig
import cash.z.wallet.sdk.ext.Twig import cash.z.ecc.android.sdk.ext.Twig
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.* import kotlinx.coroutines.*
import javax.inject.Inject import javax.inject.Inject

View File

@ -4,7 +4,7 @@ import cash.z.ecc.android.ZcashWalletApp
import cash.z.ecc.android.di.annotation.ActivityScope import cash.z.ecc.android.di.annotation.ActivityScope
import cash.z.ecc.android.di.annotation.SynchronizerScope import cash.z.ecc.android.di.annotation.SynchronizerScope
import cash.z.ecc.android.di.module.InitializerModule import cash.z.ecc.android.di.module.InitializerModule
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Subcomponent import dagger.Subcomponent

View File

@ -3,8 +3,8 @@ package cash.z.ecc.android.di.component
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import cash.z.ecc.android.di.annotation.SynchronizerScope import cash.z.ecc.android.di.annotation.SynchronizerScope
import cash.z.ecc.android.di.module.SynchronizerModule import cash.z.ecc.android.di.module.SynchronizerModule
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import dagger.BindsInstance import dagger.BindsInstance
import dagger.Subcomponent import dagger.Subcomponent
import javax.inject.Named import javax.inject.Named

View File

@ -1,7 +1,7 @@
package cash.z.ecc.android.di.module package cash.z.ecc.android.di.module
import android.content.Context import android.content.Context
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.Reusable import dagger.Reusable

View File

@ -2,8 +2,8 @@ package cash.z.ecc.android.di.module
import android.content.Context import android.content.Context
import cash.z.ecc.android.di.annotation.SynchronizerScope import cash.z.ecc.android.di.annotation.SynchronizerScope
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides

View File

@ -0,0 +1,85 @@
package cash.z.ecc.android.ext
import android.app.ActivityManager
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.provider.Settings
import androidx.core.content.getSystemService
import com.google.android.material.dialog.MaterialAlertDialogBuilder
fun Context.showClearDataConfirmation(onDismiss: () -> Unit = {}, onCancel: () -> Unit = {}): Dialog {
return MaterialAlertDialogBuilder(this)
.setTitle("Nuke Wallet?")
.setMessage("WARNING: Potential Loss of Funds\n\nClearing all wallet data and can result in a loss of funds, if you cannot locate your correct seed phrase.\n\nPlease confirm that you have your 24-word seed phrase available before proceeding.")
.setCancelable(false)
.setPositiveButton("Cancel") { dialog, _ ->
dialog.dismiss()
onDismiss()
onCancel()
}
.setNegativeButton("Erase Wallet") { dialog, _ ->
dialog.dismiss()
onDismiss()
getSystemService<ActivityManager>()?.clearApplicationUserData()
}
.show()
}
fun Context.showUninitializedError(error: Throwable? = null, onDismiss: () -> Unit = {}): Dialog {
return MaterialAlertDialogBuilder(this)
.setTitle("Wallet Improperly Initialized")
.setMessage("This wallet has not been initialized correctly! Perhaps an error occurred during install.\n\nThis can be fixed with a reset. First, locate your backup seed phrase, then CLEAR DATA and reimport it.")
.setCancelable(false)
.setPositiveButton("Exit") { dialog, _ ->
dialog.dismiss()
onDismiss()
if (error != null) throw error
}
.setNegativeButton("Clear Data") { dialog, _ ->
showClearDataConfirmation(onDismiss, onCancel = {
// do not let the user back into the app because we cannot recover from this case
showUninitializedError(error, onDismiss)
})
}
.show()
}
fun Context.showScanFailure(error: Throwable?, onCancel: () -> Unit = {}, onDismiss: () -> Unit = {}): Dialog {
val message = if (error == null) {
"Unknown error"
} else {
"${error.message}${if (error.cause != null) "\n\nCaused by: ${error.cause}" else ""}"
}
return MaterialAlertDialogBuilder(this)
.setTitle("Scan Failure")
.setMessage(message)
.setCancelable(true)
.setPositiveButton("Retry") { d, _ ->
d.dismiss()
onDismiss()
}
.setNegativeButton("Ignore") { d, _ ->
d.dismiss()
onCancel()
onDismiss()
}
.show()
}
fun Context.showCriticalProcessorError(error: Throwable?, onRetry: () -> Unit = {}): Dialog {
return MaterialAlertDialogBuilder(this)
.setTitle("Processor Error")
.setMessage(error?.message ?: "Critical error while processing blocks!")
.setCancelable(false)
.setPositiveButton("Retry") { d, _ ->
d.dismiss()
onRetry()
}
.setNegativeButton("Exit") { dialog, _ ->
dialog.dismiss()
throw error ?: RuntimeException("Critical error while processing blocks and the user chose to exit.")
}
.show()
}

View File

@ -3,9 +3,9 @@ package cash.z.ecc.android.ext
import android.view.inputmethod.EditorInfo.IME_ACTION_DONE import android.view.inputmethod.EditorInfo.IME_ACTION_DONE
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import cash.z.wallet.sdk.ext.convertZecToZatoshi import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.wallet.sdk.ext.safelyConvertToBigDecimal import cash.z.ecc.android.sdk.ext.safelyConvertToBigDecimal
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
fun EditText.onEditorActionDone(block: (EditText) -> Unit) { fun EditText.onEditorActionDone(block: (EditText) -> Unit) {
this.setOnEditorActionListener { _, actionId, _ -> this.setOnEditorActionListener { _, actionId, _ ->

View File

@ -38,10 +38,10 @@ import cash.z.ecc.android.feedback.Report.Error.NonFatal.Reorg
import cash.z.ecc.android.feedback.Report.NonUserAction.FEEDBACK_STOPPED import cash.z.ecc.android.feedback.Report.NonUserAction.FEEDBACK_STOPPED
import cash.z.ecc.android.feedback.Report.NonUserAction.SYNC_START import cash.z.ecc.android.feedback.Report.NonUserAction.SYNC_START
import cash.z.ecc.android.feedback.Report.Tap.COPY_ADDRESS import cash.z.ecc.android.feedback.Report.Tap.COPY_ADDRESS
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.wallet.sdk.exception.CompactBlockProcessorException import cash.z.ecc.android.sdk.exception.CompactBlockProcessorException
import cash.z.wallet.sdk.ext.ZcashSdk import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -5,7 +5,7 @@ import android.view.ViewGroup
import androidx.paging.PagedListAdapter import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import cash.z.ecc.android.R import cash.z.ecc.android.R
import cash.z.wallet.sdk.entity.ConfirmedTransaction import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
class TransactionAdapter<T : ConfirmedTransaction> : class TransactionAdapter<T : ConfirmedTransaction> :
PagedListAdapter<T, TransactionViewHolder<T>>( PagedListAdapter<T, TransactionViewHolder<T>>(

View File

@ -11,8 +11,8 @@ import cash.z.ecc.android.ui.MainActivity
import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.send.SendViewModel
import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX
import cash.z.ecc.android.ui.util.toUtf8Memo import cash.z.ecc.android.ui.util.toUtf8Memo
import cash.z.wallet.sdk.entity.ConfirmedTransaction import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.wallet.sdk.ext.* import cash.z.ecc.android.sdk.ext.*
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.nio.charset.Charset import java.nio.charset.Charset
import java.text.SimpleDateFormat import java.text.SimpleDateFormat

View File

@ -15,12 +15,12 @@ import cash.z.ecc.android.ext.toColoredSpan
import cash.z.ecc.android.feedback.Report import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.DETAIL_BACK import cash.z.ecc.android.feedback.Report.Tap.DETAIL_BACK
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.block.CompactBlockProcessor.WalletBalance import cash.z.ecc.android.sdk.block.CompactBlockProcessor.WalletBalance
import cash.z.wallet.sdk.entity.ConfirmedTransaction import cash.z.ecc.android.sdk.db.entity.ConfirmedTransaction
import cash.z.wallet.sdk.ext.collectWith import cash.z.ecc.android.sdk.ext.collectWith
import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.wallet.sdk.ext.toAbbreviatedAddress import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.launch import kotlinx.coroutines.launch

View File

@ -1,8 +1,8 @@
package cash.z.ecc.android.ui.detail package cash.z.ecc.android.ui.detail
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import javax.inject.Inject import javax.inject.Inject
class WalletDetailViewModel @Inject constructor() : ViewModel() { class WalletDetailViewModel @Inject constructor() : ViewModel() {

View File

@ -18,13 +18,13 @@ import cash.z.ecc.android.ui.home.HomeFragment.BannerAction.*
import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.send.SendViewModel
import cash.z.ecc.android.ui.setup.WalletSetupViewModel import cash.z.ecc.android.ui.setup.WalletSetupViewModel
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.NO_SEED import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.NO_SEED
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.Synchronizer.Status.* import cash.z.ecc.android.sdk.Synchronizer.Status.*
import cash.z.wallet.sdk.block.CompactBlockProcessor import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.wallet.sdk.ext.convertZecToZatoshi import cash.z.ecc.android.sdk.ext.convertZecToZatoshi
import cash.z.wallet.sdk.ext.safelyConvertToBigDecimal import cash.z.ecc.android.sdk.ext.safelyConvertToBigDecimal
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*

View File

@ -1,14 +1,14 @@
package cash.z.ecc.android.ui.home package cash.z.ecc.android.ui.home
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import cash.z.wallet.sdk.SdkSynchronizer import cash.z.ecc.android.sdk.SdkSynchronizer
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.Synchronizer.Status.* import cash.z.ecc.android.sdk.Synchronizer.Status.*
import cash.z.wallet.sdk.block.CompactBlockProcessor import cash.z.ecc.android.sdk.block.CompactBlockProcessor
import cash.z.wallet.sdk.exception.RustLayerException import cash.z.ecc.android.sdk.exception.RustLayerException
import cash.z.wallet.sdk.ext.ZcashSdk.MINERS_FEE_ZATOSHI import cash.z.ecc.android.sdk.ext.ZcashSdk.MINERS_FEE_ZATOSHI
import cash.z.wallet.sdk.ext.ZcashSdk.ZATOSHI_PER_ZEC import cash.z.ecc.android.sdk.ext.ZcashSdk.ZATOSHI_PER_ZEC
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import javax.inject.Inject import javax.inject.Inject

View File

@ -1,7 +1,7 @@
package cash.z.ecc.android.ui.home package cash.z.ecc.android.ui.home
import android.animation.ValueAnimator import android.animation.ValueAnimator
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.airbnb.lottie.LottieAnimationView import com.airbnb.lottie.LottieAnimationView
class MagicSnakeLoader( class MagicSnakeLoader(

View File

@ -19,8 +19,8 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Funnel.UserFeedback import cash.z.ecc.android.feedback.Report.Funnel.UserFeedback
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.ext.toAbbreviatedAddress import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okio.Okio import okio.Okio
import java.io.File import java.io.File

View File

@ -1,8 +1,8 @@
package cash.z.ecc.android.ui.profile package cash.z.ecc.android.ui.profile
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import javax.inject.Inject import javax.inject.Inject
class ProfileViewModel @Inject constructor() : ViewModel() { class ProfileViewModel @Inject constructor() : ViewModel() {

View File

@ -13,8 +13,8 @@ import cash.z.ecc.android.ext.onClickNavTo
import cash.z.ecc.android.feedback.Report import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.ext.toAbbreviatedAddress import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.roundToInt import kotlin.math.roundToInt

View File

@ -1,8 +1,8 @@
package cash.z.ecc.android.ui.receive package cash.z.ecc.android.ui.receive
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import javax.inject.Inject import javax.inject.Inject
class ReceiveViewModel @Inject constructor() : ViewModel() { class ReceiveViewModel @Inject constructor() : ViewModel() {

View File

@ -2,9 +2,9 @@ package cash.z.ecc.android.ui.scan
import androidx.camera.core.ImageAnalysis import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy import androidx.camera.core.ImageProxy
import cash.z.wallet.sdk.ext.retrySimple import cash.z.ecc.android.sdk.ext.retrySimple
import cash.z.wallet.sdk.ext.retryUpTo import cash.z.ecc.android.sdk.ext.retryUpTo
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.google.android.gms.tasks.Task import com.google.android.gms.tasks.Task
import com.google.firebase.ml.vision.FirebaseVision import com.google.firebase.ml.vision.FirebaseVision
import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcode import com.google.firebase.ml.vision.barcode.FirebaseVisionBarcode

View File

@ -3,12 +3,10 @@ package cash.z.ecc.android.ui.scan
import android.content.Context import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.camera.core.CameraSelector import androidx.camera.core.*
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import cash.z.ecc.android.R import cash.z.ecc.android.R
@ -18,11 +16,15 @@ import cash.z.ecc.android.di.viewmodel.viewModel
import cash.z.ecc.android.ext.onClickNavBack import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ext.onClickNavTo import cash.z.ecc.android.ext.onClickNavTo
import cash.z.ecc.android.feedback.Report import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.SCAN_BACK
import cash.z.ecc.android.feedback.Report.Tap.SCAN_RECEIVE
import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.send.SendViewModel
import com.crashlytics.android.Crashlytics
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
class ScanFragment : BaseFragment<FragmentScanBinding>() { class ScanFragment : BaseFragment<FragmentScanBinding>() {
@ -33,11 +35,15 @@ class ScanFragment : BaseFragment<FragmentScanBinding>() {
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider> private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
private var cameraExecutor: ExecutorService? = null
override fun inflate(inflater: LayoutInflater): FragmentScanBinding = override fun inflate(inflater: LayoutInflater): FragmentScanBinding =
FragmentScanBinding.inflate(inflater) FragmentScanBinding.inflate(inflater)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
if (cameraExecutor != null) cameraExecutor?.shutdown()
cameraExecutor = Executors.newSingleThreadExecutor()
binding.buttonReceive.onClickNavTo(R.id.action_nav_scan_to_nav_receive) { tapped(SCAN_RECEIVE) } binding.buttonReceive.onClickNavTo(R.id.action_nav_scan_to_nav_receive) { tapped(SCAN_RECEIVE) }
binding.backButtonHitArea.onClickNavBack() { tapped(SCAN_BACK) } binding.backButtonHitArea.onClickNavBack() { tapped(SCAN_BACK) }
@ -56,26 +62,67 @@ class ScanFragment : BaseFragment<FragmentScanBinding>() {
}, ContextCompat.getMainExecutor(context)) }, ContextCompat.getMainExecutor(context))
} }
override fun onDestroyView() {
super.onDestroyView()
cameraExecutor?.shutdown()
cameraExecutor = null
}
private fun bindPreview(cameraProvider: ProcessCameraProvider) { private fun bindPreview(cameraProvider: ProcessCameraProvider) {
Preview.Builder().setTargetName("Preview").build().let { preview -> // Most of the code here is adapted from: https://github.com/android/camera-samples/blob/master/CameraXBasic/app/src/main/java/com/android/example/cameraxbasic/fragments/CameraFragment.kt
preview.setSurfaceProvider(binding.preview.previewSurfaceProvider) // it's worth keeping tabs on that implementation because they keep making breaking changes to these APIs!
val cameraSelector = CameraSelector.Builder() // Get screen metrics used to setup camera for full screen resolution
.requireLensFacing(CameraSelector.LENS_FACING_BACK) val metrics = DisplayMetrics().also { binding.preview.display.getRealMetrics(it) }
.build() val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)
val rotation = binding.preview.display.rotation
val imageAnalysis = ImageAnalysis.Builder() val preview =
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) Preview.Builder().setTargetName("Preview").setTargetAspectRatio(screenAspectRatio)
.build() .setTargetRotation(rotation).build()
imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), QrAnalyzer { q, i -> val cameraSelector = CameraSelector.Builder()
onQrScanned(q, i) .requireLensFacing(CameraSelector.LENS_FACING_BACK)
}) .build()
val imageAnalysis = ImageAnalysis.Builder().setTargetAspectRatio(screenAspectRatio)
.setTargetRotation(rotation)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
imageAnalysis.setAnalyzer(cameraExecutor!!, QrAnalyzer { q, i ->
onQrScanned(q, i)
})
// Must unbind the use-cases before rebinding them
cameraProvider.unbindAll()
try {
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis) cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis)
preview.setSurfaceProvider(binding.preview.createSurfaceProvider())
} catch (t: Throwable) {
// TODO: consider bubbling this up to the user
Crashlytics.logException(t)
twig("Error while opening the camera: $t")
} }
} }
/**
* Adapted from: https://github.com/android/camera-samples/blob/master/CameraXBasic/app/src/main/java/com/android/example/cameraxbasic/fragments/CameraFragment.kt#L350
*/
private fun aspectRatio(width: Int, height: Int): Int {
val previewRatio = kotlin.math.max(width, height).toDouble() / kotlin.math.min(
width,
height
)
if (kotlin.math.abs(previewRatio - (4.0 / 3.0))
<= kotlin.math.abs(previewRatio - (16.0 / 9.0))) {
return AspectRatio.RATIO_4_3
}
return AspectRatio.RATIO_16_9
}
private fun onQrScanned(qrContent: String, image: ImageProxy) { private fun onQrScanned(qrContent: String, image: ImageProxy) {
resumedScope.launch { resumedScope.launch {
if (viewModel.isNotValid(qrContent)) image.close() // continue scanning if (viewModel.isNotValid(qrContent)) image.close() // continue scanning

View File

@ -1,8 +1,8 @@
package cash.z.ecc.android.ui.scan package cash.z.ecc.android.ui.scan
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import javax.inject.Inject import javax.inject.Inject
class ScanViewModel @Inject constructor() : ViewModel() { class ScanViewModel @Inject constructor() : ViewModel() {

View File

@ -16,9 +16,10 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Funnel.Send import cash.z.ecc.android.feedback.Report.Funnel.Send
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.block.CompactBlockProcessor.WalletBalance import cash.z.ecc.android.sdk.block.CompactBlockProcessor.WalletBalance
import cash.z.wallet.sdk.ext.* import cash.z.ecc.android.sdk.ext.*
import cash.z.ecc.android.sdk.validate.AddressType
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -85,9 +86,9 @@ class SendAddressFragment : BaseFragment<FragmentSendAddressBinding>(),
private fun onAddressChanged(address: String) { private fun onAddressChanged(address: String) {
resumedScope.launch { resumedScope.launch {
var type = when (sendViewModel.validateAddress(address)) { var type = when (sendViewModel.validateAddress(address)) {
is Synchronizer.AddressType.Transparent -> "This is a valid transparent address" to R.color.zcashGreen is AddressType.Transparent -> "This is a valid transparent address" to R.color.zcashGreen
is Synchronizer.AddressType.Shielded -> "This is a valid shielded address" to R.color.zcashGreen is AddressType.Shielded -> "This is a valid shielded address" to R.color.zcashGreen
is Synchronizer.AddressType.Invalid -> "This address appears to be invalid" to R.color.zcashRed is AddressType.Invalid -> "This address appears to be invalid" to R.color.zcashRed
} }
if (address == sendViewModel.synchronizer.getAddress()) type = if (address == sendViewModel.synchronizer.getAddress()) type =
"Warning, this appears to be your address!" to R.color.zcashRed "Warning, this appears to be your address!" to R.color.zcashRed

View File

@ -13,8 +13,8 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Funnel.Send import cash.z.ecc.android.feedback.Report.Funnel.Send
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.ext.toAbbreviatedAddress import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class SendConfirmFragment : BaseFragment<FragmentSendConfirmBinding>() { class SendConfirmFragment : BaseFragment<FragmentSendConfirmBinding>() {

View File

@ -12,10 +12,10 @@ import cash.z.ecc.android.ext.goneIf
import cash.z.ecc.android.feedback.Report import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.entity.* import cash.z.ecc.android.sdk.db.entity.*
import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.wallet.sdk.ext.toAbbreviatedAddress import cash.z.ecc.android.sdk.ext.toAbbreviatedAddress
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow

View File

@ -14,12 +14,13 @@ import cash.z.ecc.android.feedback.Report.MetricType.*
import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.lockbox.LockBox
import cash.z.ecc.android.ui.setup.WalletSetupViewModel import cash.z.ecc.android.ui.setup.WalletSetupViewModel
import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX import cash.z.ecc.android.ui.util.INCLUDE_MEMO_PREFIX
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.wallet.sdk.Synchronizer import cash.z.ecc.android.sdk.Synchronizer
import cash.z.wallet.sdk.entity.* import cash.z.ecc.android.sdk.db.entity.*
import cash.z.wallet.sdk.ext.ZcashSdk import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.ecc.android.sdk.ext.convertZatoshiToZecString
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import cash.z.ecc.android.sdk.validate.AddressType
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -94,7 +95,7 @@ class SendViewModel @Inject constructor() : ViewModel() {
} }
} }
suspend fun validateAddress(address: String): Synchronizer.AddressType = suspend fun validateAddress(address: String): AddressType =
synchronizer.validateAddress(address) synchronizer.validateAddress(address)
fun validate(maxZatoshi: Long?) = flow<String?> { fun validate(maxZatoshi: Long?) = flow<String?> {

View File

@ -18,7 +18,7 @@ import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITHOUT_BACKUP import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITHOUT_BACKUP
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.SEED_WITH_BACKUP
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach

View File

@ -21,8 +21,8 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Funnel.Restore import cash.z.ecc.android.feedback.Report.Funnel.Restore
import cash.z.ecc.android.feedback.Report.Tap.* import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.ext.ZcashSdk import cash.z.ecc.android.sdk.ext.ZcashSdk
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tylersuehr.chips.Chip import com.tylersuehr.chips.Chip
import com.tylersuehr.chips.ChipsAdapter import com.tylersuehr.chips.ChipsAdapter

View File

@ -11,7 +11,7 @@ import cash.z.ecc.android.feedback.Report
import cash.z.ecc.android.feedback.Report.Funnel.Restore import cash.z.ecc.android.feedback.Report.Funnel.Restore
import cash.z.ecc.android.ui.MainActivity import cash.z.ecc.android.ui.MainActivity
import cash.z.ecc.android.ui.setup.SeedWordChip import cash.z.ecc.android.ui.setup.SeedWordChip
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
class SeedWordAdapter : ChipsAdapter { class SeedWordAdapter : ChipsAdapter {

View File

@ -8,11 +8,11 @@ import cash.z.ecc.android.feedback.measure
import cash.z.ecc.android.lockbox.LockBox import cash.z.ecc.android.lockbox.LockBox
import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.* import cash.z.ecc.android.ui.setup.WalletSetupViewModel.WalletSetupState.*
import cash.z.ecc.kotlin.mnemonic.Mnemonics import cash.z.ecc.kotlin.mnemonic.Mnemonics
import cash.z.wallet.sdk.Initializer import cash.z.ecc.android.sdk.Initializer
import cash.z.wallet.sdk.Initializer.DefaultBirthdayStore import cash.z.ecc.android.sdk.Initializer.DefaultBirthdayStore
import cash.z.wallet.sdk.Initializer.DefaultBirthdayStore.Companion.ImportedWalletBirthdayStore import cash.z.ecc.android.sdk.Initializer.DefaultBirthdayStore.Companion.ImportedWalletBirthdayStore
import cash.z.wallet.sdk.Initializer.DefaultBirthdayStore.Companion.NewWalletBirthdayStore import cash.z.ecc.android.sdk.Initializer.DefaultBirthdayStore.Companion.NewWalletBirthdayStore
import cash.z.wallet.sdk.ext.twig import cash.z.ecc.android.sdk.ext.twig
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow

View File

@ -2,7 +2,7 @@ package cash.z.ecc.android
import cash.z.ecc.android.feedback.Feedback import cash.z.ecc.android.feedback.Feedback
import cash.z.ecc.android.ui.send.SendViewModel import cash.z.ecc.android.ui.send.SendViewModel
import cash.z.wallet.sdk.entity.* import cash.z.ecc.android.sdk.entity.*
import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.verifyZeroInteractions import com.nhaarman.mockitokotlin2.verifyZeroInteractions
import com.nhaarman.mockitokotlin2.whenever import com.nhaarman.mockitokotlin2.whenever

View File

@ -1,9 +1,6 @@
import cash.z.ecc.android.Deps import cash.z.ecc.android.Deps
buildscript { buildscript {
ext {
kotlin_version = '1.3.61'
}
repositories { repositories {
google() google()
jcenter() jcenter()
@ -12,7 +9,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.6.0-rc02' classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.google.gms:google-services:4.3.3' classpath 'com.google.gms:google-services:4.3.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Deps.kotlinVersion}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Deps.kotlinVersion}"
classpath 'io.fabric.tools:gradle:1.31.2' classpath 'io.fabric.tools:gradle:1.31.2'

View File

@ -3,7 +3,7 @@ package cash.z.ecc.android
object Deps { object Deps {
// For use in the top-level build.gradle which gives an error when provided // For use in the top-level build.gradle which gives an error when provided
// `Deps.Kotlin.version` directly // `Deps.Kotlin.version` directly
const val kotlinVersion = "1.3.61" const val kotlinVersion = "1.3.72"
const val compileSdkVersion = 29 const val compileSdkVersion = 29
const val buildToolsVersion = "29.0.2" const val buildToolsVersion = "29.0.2"
@ -11,18 +11,34 @@ object Deps {
const val targetSdkVersion = 29 const val targetSdkVersion = 29
object AndroidX { object AndroidX {
const val ANNOTATION = "androidx.annotation:annotation:1.1.0"
const val APPCOMPAT = "androidx.appcompat:appcompat:1.1.0" const val APPCOMPAT = "androidx.appcompat:appcompat:1.1.0"
const val CORE_KTX = "androidx.core:core-ktx:1.1.0"
const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout:1.1.3" const val CONSTRAINT_LAYOUT = "androidx.constraintlayout:constraintlayout:1.1.3"
const val CORE_KTX = "androidx.core:core-ktx:1.1.0"
const val FRAGMENT_KTX = "androidx.fragment:fragment-ktx:1.1.0-beta01" const val FRAGMENT_KTX = "androidx.fragment:fragment-ktx:1.1.0-beta01"
const val LEGACY = "androidx.legacy:legacy-support-v4:1.0.0"
const val MULTIDEX = "androidx.multidex:multidex:2.0.1" const val MULTIDEX = "androidx.multidex:multidex:2.0.1"
const val PAGING = "androidx.paging:paging-runtime-ktx:2.1.2"
object CameraX : Version("1.0.0-beta04") {
val CAMERA2 = "androidx.camera:camera-camera2:1.0.0-beta04"
val CORE = "androidx.camera:camera-core:1.0.0-beta04"
val LIFECYCLE = "androidx.camera:camera-lifecycle:1.0.0-beta04"
object View : Version("1.0.0-alpha11") {
val EXT = "androidx.camera:camera-extensions:1.0.0-alpha11"
val VIEW = "androidx.camera:camera-view:1.0.0-alpha11"
}
}
object Lifecycle : Version("2.2.0-rc02") {
val LIFECYCLE_RUNTIME_KTX = "androidx.lifecycle:lifecycle-runtime-ktx:$version"
val LIFECYCLE_EXTENSIONS = "androidx.lifecycle:lifecycle-extensions:$version"
}
object Navigation : Version("2.2.0") { object Navigation : Version("2.2.0") {
val FRAGMENT_KTX = "androidx.navigation:navigation-fragment-ktx:$version" val FRAGMENT_KTX = "androidx.navigation:navigation-fragment-ktx:$version"
val UI_KTX = "androidx.navigation:navigation-ui-ktx:$version" val UI_KTX = "androidx.navigation:navigation-ui-ktx:$version"
} }
object Lifecycle: Version("2.2.0-rc02") { object Room : Version("2.2.5") {
val LIFECYCLE_RUNTIME_KTX = "androidx.lifecycle:lifecycle-runtime-ktx:$version" val ROOM_COMPILER = "androidx.room:room-compiler:$version"
val LIFECYCLE_EXTENSIONS = "androidx.lifecycle:lifecycle-extensions:$version" val ROOM_KTX = "androidx.room:room-ktx:$version"
} }
} }
object Dagger : Version("2.25.2") { object Dagger : Version("2.25.2") {
@ -31,35 +47,61 @@ object Deps {
val COMPILER = "com.google.dagger:dagger-compiler:$version" val COMPILER = "com.google.dagger:dagger-compiler:$version"
} }
object Google { object Google {
// solves error: Duplicate class com.google.common.util.concurrent.ListenableFuture found in modules jetified-guava-26.0-android.jar (com.google.guava:guava:26.0-android) and listenablefuture-1.0.jar (com.google.guava:listenablefuture:1.0)
// per this recommendation from Chris Povirk, given guava's decision to split ListenableFuture away from Guava: https://groups.google.com/d/msg/guava-discuss/GghaKwusjcY/bCIAKfzOEwAJ
const val GUAVA = "com.google.guava:guava:27.0.1-android"
const val MATERIAL = "com.google.android.material:material:1.1.0-beta01" const val MATERIAL = "com.google.android.material:material:1.1.0-beta01"
// QR Scanner
const val ML_VISION = "com.google.firebase:firebase-ml-vision:24.0.3"
}
object Grpc : Version("1.25.0") {
val ANDROID = "io.grpc:grpc-android:$version"
val OKHTTP = "io.grpc:grpc-okhttp:$version"
val PROTOBUG = "io.grpc:grpc-protobuf-lite:$version"
val STUB = "io.grpc:grpc-stub:$version"
}
object Analytics { // for dogfooding/crash-reporting/feedback only on internal team builds
val CRASHLYTICS = "com.crashlytics.sdk.android:crashlytics:2.10.1"
val CRASHLYTICS_NDK = "com.crashlytics.sdk.android:crashlytics-ndk:2.1.1"
val FIREBASE = "com.google.firebase:firebase-analytics:17.4.3"
val FIREBASE_PERF = "com.google.firebase:firebase-perf:19.0.7"
val MIXPANEL = "com.mixpanel.android:mixpanel-android:5.6.3"
} }
object JavaX { object JavaX {
const val INJECT = "javax.inject:javax.inject:1" const val INJECT = "javax.inject:javax.inject:1"
const val JAVA_ANNOTATION = "javax.annotation:javax.annotation-api:1.3.2"
} }
object Kotlin : Version(kotlinVersion) { object Kotlin : Version(kotlinVersion) {
val STDLIB = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version" val STDLIB = "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$version"
object Coroutines : Version("1.3.2") { object Coroutines : Version("1.3.2") {
val ANDROID = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version" val ANDROID = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$version"
val CORE = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version" val CORE = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$version"
val TEST = "org.jetbrains.kotlinx:kotlinx-coroutines-test:$version" val TEST = "org.jetbrains.kotlinx:kotlinx-coroutines-test:$version"
} }
} }
object Zcash { object Zcash {
val ANDROID_WALLET_PLUGINS = "com.github.zcash:zcash-android-wallet-plugins:1.0.1" const val ANDROID_WALLET_PLUGINS = "cash.z.ecc.android:zcash-android-wallet-plugins:1.0.0"
const val KOTLIN_BIP39 = "cash.z.ecc.android:kotlin-bip39:1.0.0-beta08"
object Sdk : Version("1.1.0-beta01") {
val MAINNET = "cash.z.ecc.android:sdk-mainnet:$version"
val TESTNET = "cash.z.ecc.android:sdk-testnet:$version"
}
} }
object Misc { object Misc {
const val LOTTIE = "com.airbnb.android:lottie:3.1.0"
object Plugins { object Plugins {
val SECURE_STORAGE = "de.adorsys.android:securestoragelibrary:1.2.2" const val SECURE_STORAGE = "de.adorsys.android:securestoragelibrary:1.2.2"
val ANDROID_BIP39 = "cash.z.ecc.android:android-bip39:1.0.0-beta07" const val QR_SCANNER = "com.google.zxing:core:3.2.1"
val QR_SCANNER = "com.google.zxing:core:3.2.1"
} }
} }
object Test { object Test {
const val JUNIT = "junit:junit:4.12" const val JUNIT = "junit:junit:4.12"
const val MOKITO = "junit:junit:4.12"
const val COROUTINES_TEST = "junit:junit:4.12"
object Android { object Android {
const val JUNIT = "androidx.test.ext:junit:1.1.1" const val JUNIT = "androidx.test.ext:junit:1.1.1"
const val ESPRESSO = "androidx.test.espresso:espresso-core:3.2.0" const val ESPRESSO = "androidx.test.espresso:espresso-core:3.2.0"
} }
} }
} }

View File

@ -1,6 +1,6 @@
#Tue Jan 07 12:00:21 EST 2020 #Fri May 29 19:00:53 EDT 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

View File

@ -8,7 +8,7 @@ dependencies {
// Zcash // Zcash
implementation Deps.Zcash.ANDROID_WALLET_PLUGINS implementation Deps.Zcash.ANDROID_WALLET_PLUGINS
implementation Deps.Misc.Plugins.ANDROID_BIP39 implementation Deps.Zcash.KOTLIN_BIP39
testImplementation Deps.Test.JUNIT testImplementation Deps.Test.JUNIT
} }

View File

@ -1,57 +1,22 @@
package cash.z.ecc.kotlin.mnemonic package cash.z.ecc.kotlin.mnemonic
import cash.z.android.plugin.MnemonicPlugin import cash.z.android.plugin.MnemonicPlugin
import cash.z.ecc.android.bip39.Mnemonics
import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode import cash.z.ecc.android.bip39.Mnemonics.MnemonicCode
import cash.z.ecc.android.bip39.Mnemonics.WordCount import cash.z.ecc.android.bip39.Mnemonics.WordCount
import cash.z.ecc.android.bip39.toEntropy import cash.z.ecc.android.bip39.toEntropy
import cash.z.ecc.android.bip39.toSeed import cash.z.ecc.android.bip39.toSeed
import java.util.* import java.util.*
import java.util.Locale.ENGLISH
import javax.inject.Inject import javax.inject.Inject
class Mnemonics @Inject constructor(): MnemonicPlugin { class Mnemonics @Inject constructor() : MnemonicPlugin {
override fun fullWordList(languageCode: String): List<String> { override fun fullWordList(languageCode: String) = Mnemonics.getCachedWords(Locale.ENGLISH.language)
return cash.z.ecc.android.bip39.Mnemonics.getCachedWords(Locale.ENGLISH.language) override fun nextEntropy(): ByteArray = WordCount.COUNT_24.toEntropy()
} override fun nextMnemonic(): CharArray = MnemonicCode(WordCount.COUNT_24).chars
override fun nextMnemonic(entropy: ByteArray): CharArray = MnemonicCode(entropy).chars
override fun nextEntropy(): ByteArray { override fun nextMnemonicList(): List<CharArray> = MnemonicCode(WordCount.COUNT_24).words
return WordCount.COUNT_24.toEntropy() override fun nextMnemonicList(entropy: ByteArray): List<CharArray> = MnemonicCode(entropy).words
} override fun toSeed(mnemonic: CharArray): ByteArray = MnemonicCode(mnemonic).toSeed()
override fun toWordList(mnemonic: CharArray): List<CharArray> = MnemonicCode(mnemonic).words
override fun nextMnemonic(): CharArray {
return nextMnemonic(nextEntropy())
}
override fun nextMnemonic(entropy: ByteArray): CharArray {
return MnemonicCode(entropy).chars
}
override fun nextMnemonicList(): List<CharArray> {
return nextMnemonicList(nextEntropy())
}
override fun nextMnemonicList(entropy: ByteArray): List<CharArray> {
return MnemonicCode(entropy).map { it.toCharArray() }
}
override fun toSeed(mnemonic: CharArray): ByteArray {
return MnemonicCode(mnemonic).toSeed()
}
override fun toWordList(mnemonic: CharArray): List<CharArray> {
val wordList = mutableListOf<CharArray>()
var cursor = 0
repeat(mnemonic.size) { i ->
val isSpace = mnemonic[i] == ' '
if (isSpace || i == (mnemonic.size - 1)) {
val wordSize = i - cursor + if (isSpace) 0 else 1
wordList.add(CharArray(wordSize).apply {
repeat(wordSize) {
this[it] = mnemonic[cursor + it]
}
})
cursor = i + 1
}
}
return wordList
}
} }

View File

@ -1,4 +1,3 @@
rootProject.name='Zcash Wallet' rootProject.name='Zcash Wallet'
include ':app', ':qrecycler', ':feedback', ':mnemonic', ':lockbox', ':sdk', ':chipsinputlayout' include ':app', ':qrecycler', ':feedback', ':mnemonic', ':lockbox', ':chipsinputlayout'
project(":sdk").projectDir = file("../zcash-android-wallet-sdk")
project(":chipsinputlayout").projectDir = file("../../clones/chips-input-layout/library") project(":chipsinputlayout").projectDir = file("../../clones/chips-input-layout/library")