From 25945a5ef9fe05f117b1e4bd04a46c2391bc7f95 Mon Sep 17 00:00:00 2001 From: Kevin Gorham Date: Sun, 16 Jun 2019 00:53:48 -0400 Subject: [PATCH] checkpoint: things are back functional after some heavy re-writing --- .../wallet/di/module/SynchronizerModule.kt | 65 ++++++--- .../data/PersistentTransactionManager.kt | 35 +++++ .../data/PersistentTransactionSender.kt | 136 ++++++++++++------ .../wallet/data/RawTransactionEncoder.kt | 8 ++ .../wallet/data/RawTransactionFactory.kt | 8 -- .../android/wallet/data/StableSynchronizer.kt | 90 +++++++++--- .../android/wallet/data/TransactionManager.kt | 83 +++++++---- .../android/wallet/data/TransactionSender.kt | 6 +- .../wallet/data/WalletTransactionEncoder.kt | 16 +++ .../wallet/ui/activity/MainActivity.kt | 26 ++-- .../wallet/ui/fragment/ProgressFragment.kt | 3 +- .../wallet/ui/fragment/ReceiveFragment.kt | 14 +- .../wallet/ui/fragment/SyncFragment.kt | 2 +- .../wallet/ui/fragment/Zcon1HomeFragment.kt | 9 +- .../wallet/ui/presenter/BalancePresenter.kt | 4 +- .../wallet/ui/presenter/HistoryPresenter.kt | 5 +- .../wallet/ui/presenter/HomePresenter.kt | 31 ++-- .../wallet/ui/presenter/MainPresenter.kt | 23 +-- .../wallet/ui/presenter/ProgressPresenter.kt | 6 +- .../wallet/ui/presenter/SendPresenter.kt | 3 +- .../ui/presenter/TransactionPresenter.kt | 5 +- .../cash/z/android/wallet/ui/util/Broom.kt | 54 ++----- 22 files changed, 403 insertions(+), 229 deletions(-) create mode 100644 zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionManager.kt create mode 100644 zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionEncoder.kt delete mode 100644 zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionFactory.kt create mode 100644 zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/WalletTransactionEncoder.kt diff --git a/zcash-android-wallet-app/app/src/debug/java/cash/z/android/wallet/di/module/SynchronizerModule.kt b/zcash-android-wallet-app/app/src/debug/java/cash/z/android/wallet/di/module/SynchronizerModule.kt index afbb7ce..e9e8dab 100644 --- a/zcash-android-wallet-app/app/src/debug/java/cash/z/android/wallet/di/module/SynchronizerModule.kt +++ b/zcash-android-wallet-app/app/src/debug/java/cash/z/android/wallet/di/module/SynchronizerModule.kt @@ -6,15 +6,16 @@ import cash.z.android.wallet.BuildConfig import cash.z.android.wallet.ChipBucket import cash.z.android.wallet.InMemoryChipBucket import cash.z.android.wallet.ZcashWalletApplication -import cash.z.android.wallet.data.StaticTransactionRepository +import cash.z.android.wallet.data.* import cash.z.android.wallet.extention.toDbPath -import cash.z.android.wallet.sample.* +import cash.z.android.wallet.sample.CarolWallet import cash.z.android.wallet.sample.SampleProperties.COMPACT_BLOCK_PORT import cash.z.android.wallet.sample.SampleProperties.DEFAULT_BLOCK_POLL_FREQUENCY_MILLIS import cash.z.android.wallet.sample.SampleProperties.DEFAULT_SERVER import cash.z.android.wallet.sample.SampleProperties.DEFAULT_TRANSACTION_POLL_FREQUENCY_MILLIS import cash.z.android.wallet.sample.SampleProperties.PREFS_SERVER_NAME -import cash.z.android.wallet.sample.SampleProperties.PREFS_WALLET_DISPLAY_NAME +import cash.z.android.wallet.sample.Servers +import cash.z.android.wallet.sample.WalletConfig import cash.z.android.wallet.ui.util.Broom import cash.z.wallet.sdk.block.* import cash.z.wallet.sdk.data.* @@ -28,6 +29,7 @@ import cash.z.wallet.sdk.service.LightWalletGrpcService import cash.z.wallet.sdk.service.LightWalletService import dagger.Module import dagger.Provides +import dagger.android.DispatchingAndroidInjector import javax.inject.Named import javax.inject.Singleton @@ -168,30 +170,30 @@ internal object SynchronizerModule { fun provideManager(wallet: Wallet, repository: TransactionRepository, service: LightWalletService): ActiveTransactionManager { return ActiveTransactionManager(repository, service, wallet) } - - @JvmStatic - @Provides - @Singleton - fun provideSynchronizer( - processor: CompactBlockProcessor, - repository: TransactionRepository, - manager: ActiveTransactionManager, - wallet: Wallet - ): Synchronizer { - return SdkSynchronizer(processor, repository, manager, wallet, DEFAULT_STALE_TOLERANCE) - } +// +// @JvmStatic +// @Provides +// @Singleton +// fun provideSynchronizer( +// processor: CompactBlockProcessor, +// repository: TransactionRepository, +// manager: ActiveTransactionManager, +// wallet: Wallet +// ): Synchronizer { +// return SdkSynchronizer(processor, repository, manager, wallet, DEFAULT_STALE_TOLERANCE) +// } @JvmStatic @Provides @Singleton fun provideBroom( - service: LightWalletService, + sender: TransactionSender, wallet: Wallet, rustBackend: RustBackendWelding, walletConfig: WalletConfig ): Broom { return Broom( - service, + sender, rustBackend, walletConfig.cacheDbName, wallet @@ -204,4 +206,33 @@ internal object SynchronizerModule { fun provideChipBucket(): ChipBucket { return InMemoryChipBucket() } + + + @JvmStatic + @Provides + @Singleton + fun provideTransactionManager(): TransactionManager { + return PersistentTransactionManager() + } + + @JvmStatic + @Provides + @Singleton + fun provideTransactionSender(manager: TransactionManager, service: LightWalletService): TransactionSender { + return PersistentTransactionMonitor(manager, service) + } + + @JvmStatic + @Provides + @Singleton + fun provideTransactionEncoder(wallet: Wallet, repository: TransactionRepository): RawTransactionEncoder { + return WalletTransactionEncoder(wallet, repository) + } + + @JvmStatic + @Provides + @Singleton + fun provideDataSynchronizer(wallet: Wallet, encoder: RawTransactionEncoder, sender: TransactionSender) : DataSyncronizer { + return StableSynchronizer(wallet, encoder, sender) + } } diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionManager.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionManager.kt new file mode 100644 index 0000000..b1fabc8 --- /dev/null +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionManager.kt @@ -0,0 +1,35 @@ +package cash.z.android.wallet.data + +import cash.z.wallet.sdk.data.twig +import cash.z.wallet.sdk.service.LightWalletService + +class PersistentTransactionManager: TransactionManager { + init { + + } + + override suspend fun manageCreation(encoder: RawTransactionEncoder, value: Long, toAddress: String, memo: String) { + twig("managing the creation of a transaction") + encoder.create(value, toAddress, memo) + + } + + override suspend fun manageSubmission(service: LightWalletService, rawTransaction: ByteArray) { + try { + // TODO: stuff before you send + twig("managing the preparation to submit transaction") + val response = service.submitTransaction(rawTransaction) + twig("management of submit transaction completed with response: ${response.errorCode}: ${response.errorMessage}") + // TODO: stuff after sending + if (response.errorCode < 0) { + } else { + } + } catch (t: Throwable) { + twig("error while managing submitting transaction: ${t.message}") + } + } + + override suspend fun getAllPending(): List { + return listOf() + } +} \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionSender.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionSender.kt index 763631e..4281c96 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionSender.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/PersistentTransactionSender.kt @@ -1,51 +1,31 @@ package cash.z.android.wallet.data +import cash.z.wallet.sdk.data.twig import cash.z.wallet.sdk.service.LightWalletService -import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.channels.actor -import kotlinx.coroutines.launch - -class PersistentTransactionSender( - private val manager: TransactionManager, - private val factory: RawTransactionFactory -) : TransactionSender { - - /** - * Generates newly persisted information about a transaction so that other processes can send. - */ - override fun sendToAddress(zatoshi: Long, toAddress: String, memo: String, fromAccountId: Int) { - val txId = manager.new() // creates a new transaction with a lifecycle of CREATING - try { - val rawTransaction = factory.create(zatoshi, toAddress, memo) - manager.setRawTransaction(txId, rawTransaction) // returns new transaction with lifecycle of CREATED - } catch (t: Throwable) { - manager.setCreationError(txId, t.message.toTxError()) - return - } - } -} class PersistentTransactionMonitor ( - private val scope: CoroutineScope, private val manager: TransactionManager, private val service: LightWalletService -) { - private val channel: SendChannel +) : TransactionSender { + private lateinit var channel: SendChannel + private var monitoringJob: Job? = null + private val initialMonitorDelay = 45_000L - init { - channel = scope.startActor() - } - - fun update() = scope.launch { - channel.send(SubmitPending) + fun CoroutineScope.requestUpdate() = launch { + if (!channel.isClosedForSend) { + channel.send(SubmitPending) + } } /** * Start an actor that listens for signals about what to do with transactions. This actor's lifespan is within the * provided [scope] and it will live until the scope is cancelled. */ - fun CoroutineScope.startActor() = actor { + private fun CoroutineScope.startActor() = actor { var pendingTransactionDao = 0 // actor state: for (msg in channel) { // iterate over incoming messages when (msg) { @@ -54,27 +34,59 @@ class PersistentTransactionMonitor ( } } - private fun submitPendingTransactions() { - val transactions = manager.getAllPendingRawTransactions().forEach { (txId, rawTransaction) -> - submitPendingTransaction(txId, rawTransaction) + private fun CoroutineScope.startMonitor() = launch { + while (!channel.isClosedForSend && isActive) { + delay(calculateDelay()) + requestUpdate() } + twig("TransactionMonitor stopping!") } - private fun submitPendingTransaction(txId: Long, rawTransaction: ByteArray) { - try { - manager.setSubmissionStarted(txId) - val response = service.submitTransaction(rawTransaction) - if (response.errorCode < 0) { - manager.setSubmissionComplete(txId, false, response.errorMessage.toTxError()) - } else { - manager.setSubmissionComplete(txId, true) + private fun calculateDelay(): Long { + return initialMonitorDelay + } + + override fun start(scope: CoroutineScope) { + twig("TransactionMonitor starting!") + channel = scope.startActor() + monitoringJob?.cancel() + monitoringJob = scope.startMonitor() + } + + override fun stop() { + channel.close() + monitoringJob?.cancel()?.also { monitoringJob = null } + } + + /** + * Generates newly persisted information about a transaction so that other processes can send. + */ + override suspend fun sendToAddress( + encoder: RawTransactionEncoder, + zatoshi: Long, + toAddress: String, + memo: String, + fromAccountId: Int + ) = withContext(IO) { + manager.manageCreation(encoder, zatoshi, toAddress, memo) + requestUpdate() + Unit + } + + /** + * Submit all pending transactions that have not expired. + */ + private suspend fun submitPendingTransactions() = withContext(IO) { + twig("received request to submit pending transactions") + with(manager) { + getAllPending().also { twig("found ${it.size} pending txs to submit") }.forEach { rawTx -> + manageSubmission(service, rawTx) } - } catch (t: Throwable) { - manager.setSubmissionComplete(txId, false, t.message.toTxError()) } } } + sealed class TransactionUpdateRequest object SubmitPending : TransactionUpdateRequest() @@ -97,4 +109,38 @@ SUBMITTED INVALID ** attempting submission ** attempted submission + +bookkeeper, register, treasurer, mint, ledger + + + private fun checkTx(transactionId: Long) { + if (transactionId < 0) { + throw SweepException.Creation + } else { + twig("successfully created transaction!") + } + } + + private fun checkRawTx(transactionRaw: ByteArray?) { + if (transactionRaw == null) { + throw SweepException.Disappeared + } else { + twig("found raw transaction in the dataDb") + } + } + + private fun checkResponse(response: Service.SendResponse) { + if (response.errorCode < 0) { + throw SweepException.IncompletePass(response) + } else { + twig("successfully submitted. error code: ${response.errorCode}") + } + } + + sealed class SweepException(val errorMessage: String) : RuntimeException(errorMessage) { + object Creation : SweepException("failed to create raw transaction") + object Disappeared : SweepException("unable to find a matching raw transaction. This means the rust backend said it created a TX but when we looked for it in the DB it was missing!") + class IncompletePass(response: Service.SendResponse) : SweepException("submit failed with error code: ${response.errorCode} and message ${response.errorMessage}") + } + */ \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionEncoder.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionEncoder.kt new file mode 100644 index 0000000..547d92c --- /dev/null +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionEncoder.kt @@ -0,0 +1,8 @@ +package cash.z.android.wallet.data + +interface RawTransactionEncoder { + /** + * Creates a raw transaction that is unsigned. + */ + suspend fun create(zatoshi: Long, toAddress: String, memo: String = ""): ByteArray +} \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionFactory.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionFactory.kt deleted file mode 100644 index a71ddba..0000000 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/RawTransactionFactory.kt +++ /dev/null @@ -1,8 +0,0 @@ -package cash.z.android.wallet.data - -interface RawTransactionFactory { - /** - * Creates a raw transaction that is unsigned. - */ - fun create(value: Long, toAddress: String, memo: String = ""): ByteArray -} \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/StableSynchronizer.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/StableSynchronizer.kt index 4bc4379..fb63966 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/StableSynchronizer.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/StableSynchronizer.kt @@ -1,30 +1,71 @@ package cash.z.android.wallet.data -import androidx.lifecycle.LifecycleOwner -import cash.z.android.wallet.ui.util.BaseLifecycleObserver +import cash.z.wallet.sdk.data.ActiveTransaction +import cash.z.wallet.sdk.data.TransactionState +import cash.z.wallet.sdk.data.twig +import cash.z.wallet.sdk.secure.Wallet +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.channels.ConflatedBroadcastChannel +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.withContext +import javax.inject.Inject /** * A synchronizer that attempts to remain operational, despite any number of errors that can occur. - * - * @param lifecycleOwner the lifecycle to observe while synchronizing */ -class StableSynchronizer( - private val lifecycleOwner: LifecycleOwner, - sender: TransactionSender -) : BaseLifecycleObserver(), TransactionSender by sender { - init { - lifecycleOwner.lifecycle.addObserver(this) +@ExperimentalCoroutinesApi +class StableSynchronizer @Inject constructor( + private val wallet: Wallet, + private val encoder: RawTransactionEncoder, + private val sender: TransactionSender +) : DataSyncronizer { + + private val balanceChannel = ConflatedBroadcastChannel() + private val progressChannel = ConflatedBroadcastChannel() + private val pendingChannel = ConflatedBroadcastChannel>() + + override fun start(scope: CoroutineScope) { + twig("Staring sender!") + sender.start(scope) } - // - // Lifecycle - // - - override fun onCreate(owner: LifecycleOwner) { - + override fun stop() { + sender.stop() } - override fun onDestroy(owner: LifecycleOwner) { + + // + // Channels + // + + override fun balances(): ReceiveChannel { + return balanceChannel.openSubscription() + } + + override fun progress(): ReceiveChannel { + return progressChannel.openSubscription() + } + + override fun pendingTransactions(): ReceiveChannel> { + return pendingChannel.openSubscription() + } + + + // + // Send / Receive + // + + override suspend fun getAddress(accountId: Int): String = withContext(IO) { wallet.getAddress() } + + override suspend fun sendToAddress( + zatoshi: Long, + toAddress: String, + memo: String, + fromAccountId: Int + ) = withContext(IO) { + sender.sendToAddress(encoder, zatoshi, toAddress, memo, fromAccountId) } @@ -34,13 +75,22 @@ class StableSynchronizer( // override fun transactions(): Flow { // } // -// override fun balance(): Flow { -// } -// // override fun progress(): Flow { // } // // override fun status(): Flow { // } +} + +interface DataSyncronizer { + fun start(scope: CoroutineScope) + fun stop() + + suspend fun getAddress(accountId: Int = 0): String + suspend fun sendToAddress(zatoshi: Long, toAddress: String, memo: String = "", fromAccountId: Int = 0) + + fun balances(): ReceiveChannel + fun progress(): ReceiveChannel + fun pendingTransactions(): ReceiveChannel> } \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionManager.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionManager.kt index 7297df0..9a3c46d 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionManager.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionManager.kt @@ -1,37 +1,64 @@ package cash.z.android.wallet.data +import cash.z.wallet.sdk.service.LightWalletService +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract + +/** + * Manage transactions with the main purpose of reporting which ones are still pending, particularly after failed + * attempts or dropped connectivity. The intent is to help see transactions through to completion. + */ interface TransactionManager { - /** - * Initialize a transaction and return its ID. - * - * @return the id of the transaction to use with subsequent calls to this manager instance. - */ - fun new(): Long + suspend fun manageCreation(encoder: RawTransactionEncoder, value: Long, toAddress: String, memo: String) + suspend fun manageSubmission(service: LightWalletService, rawTransaction: ByteArray) + suspend fun getAllPending(): List +// +// /** +// * Initialize a transaction and return its ID. +// * +// * @return the id of the transaction to use with subsequent calls to this manager instance. +// */ +// fun new(): Long +// +// /** +// * Set the rawTransaction data for the given transaction. Typically, this would transition the state of the +// * transaction to something like CREATED. Some implementations might derive the state, based on whether this raw +// * transaction data has been provided. +// * +// * @param txId the id of the transaction to update +// * @param rawTransaction the raw transaction data +// */ +// fun setRawTransaction(txId: Long, rawTransaction: ByteArray) +// +// /** +// * Signal that there has been an error while attempting to create a transaction. +// * +// * @param txId the id of the transaction to update +// * @param error information about the error that occurred +// */ +// fun setCreationError(txId: Long, error: TransactionError) +// +// fun setSubmissionStarted(txId: Long) +// fun setSubmissionComplete(txId: Long, isSuccess: Boolean, error: TransactionError? = null) +// fun getAllPendingRawTransactions(): Map - /** - * Set the rawTransaction data for the given transaction. Typically, this would transition the state of the - * transaction to something like CREATED. Some implementations might derive the state, based on whether this raw - * transaction data has been provided. - * - * @param txId the id of the transaction to update - * @param rawTransaction the raw transaction data - */ - fun setRawTransaction(txId: Long, rawTransaction: ByteArray) - - /** - * Signal that there has been an error while attempting to create a transaction. - * - * @param txId the id of the transaction to update - * @param error information about the error that occurred - */ - fun setCreationError(txId: Long, error: TransactionError) - - fun setSubmissionStarted(txId: Long) - fun setSubmissionComplete(txId: Long, isSuccess: Boolean, error: TransactionError? = null) - fun getAllPendingRawTransactions(): Map } interface TransactionError { val message: String -} \ No newline at end of file +} + +data class PendingTransaction( + val id: Long = -1, + val isMined: Boolean = false, + val hasRaw: Boolean = false, + val submitCount: Int = 0, + val expiryHeight: Int = -1, + val expiryTime: Long = -1, + val errorMessage: String? = null +) + +fun PendingTransaction.isFailure(): Boolean { + return errorMessage != null +} diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionSender.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionSender.kt index 7d8387d..cdd76b3 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionSender.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/TransactionSender.kt @@ -1,5 +1,9 @@ package cash.z.android.wallet.data +import kotlinx.coroutines.CoroutineScope + interface TransactionSender { - fun sendToAddress(zatoshi: Long, toAddress: String, memo: String, fromAccountId: Int) + fun start(scope: CoroutineScope) + fun stop() + suspend fun sendToAddress(encoder: RawTransactionEncoder, zatoshi: Long, toAddress: String, memo: String = "", fromAccountId: Int = 0) } \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/WalletTransactionEncoder.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/WalletTransactionEncoder.kt new file mode 100644 index 0000000..55d4ca8 --- /dev/null +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/data/WalletTransactionEncoder.kt @@ -0,0 +1,16 @@ +package cash.z.android.wallet.data + +import cash.z.wallet.sdk.data.TransactionRepository +import cash.z.wallet.sdk.secure.Wallet +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.withContext + +class WalletTransactionEncoder( + private val wallet: Wallet, + private val repository: TransactionRepository +) : RawTransactionEncoder { + override suspend fun create(zatoshi: Long, toAddress: String, memo: String): ByteArray = withContext(IO) { + val transactionId = wallet.createRawSendTransaction(zatoshi, toAddress, memo) + repository.findTransactionById(transactionId)?.raw!! + } +} \ No newline at end of file diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/activity/MainActivity.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/activity/MainActivity.kt index bc6b953..84ff5c1 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/activity/MainActivity.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/activity/MainActivity.kt @@ -17,12 +17,13 @@ import androidx.navigation.Navigation import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.navigateUp import cash.z.android.wallet.* +import cash.z.android.wallet.data.DataSyncronizer +import cash.z.android.wallet.data.StableSynchronizer import cash.z.android.wallet.databinding.ActivityMainBinding import cash.z.android.wallet.di.annotation.ActivityScope import cash.z.android.wallet.extention.Toaster import cash.z.android.wallet.extention.alert import cash.z.android.wallet.extention.copyToClipboard -import cash.z.android.wallet.sample.WalletConfig import cash.z.android.wallet.ui.fragment.ScanFragment import cash.z.android.wallet.ui.presenter.BalancePresenter import cash.z.android.wallet.ui.presenter.MainPresenter @@ -34,10 +35,11 @@ import cash.z.android.wallet.ui.util.Analytics.Tap.* import cash.z.android.wallet.ui.util.Analytics.trackAction import cash.z.android.wallet.ui.util.Analytics.trackFunnelStep import cash.z.android.wallet.ui.util.Broom -import cash.z.wallet.sdk.data.Synchronizer import cash.z.wallet.sdk.data.twig import cash.z.wallet.sdk.ext.convertZatoshiToZecString +import dagger.Binds import dagger.Module +import dagger.Provides import dagger.android.ContributesAndroidInjector import kotlinx.coroutines.launch import javax.inject.Inject @@ -46,14 +48,11 @@ import kotlin.random.Random class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.BarcodeCallback, MainPresenter.MainView { @Inject - lateinit var synchronizer: Synchronizer + lateinit var synchronizer: DataSyncronizer @Inject lateinit var mainPresenter: MainPresenter - @Inject - lateinit var walletConfig: WalletConfig - @Inject lateinit var broom: Broom @@ -72,14 +71,13 @@ class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.Bar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + this.lifecycle + chipBucket.restore() binding = DataBindingUtil.setContentView(this, R.layout.activity_main) binding.activity = this initAppBar() loadMessages = generateFunLoadMessages().shuffled() - synchronizer.start(this) - synchronizer.onSynchronizerErrorListener = ::onSynchronizerError - balancePresenter = BalancePresenter() } @@ -92,7 +90,8 @@ class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.Bar super.onResume() chipBucket.restore() launch { - balancePresenter.start(this, synchronizer) + synchronizer.start(this) + balancePresenter.start(this, synchronizer.balances()) mainPresenter.start() } } @@ -106,7 +105,6 @@ class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.Bar override fun onDestroy() { super.onDestroy() - synchronizer.stop() Analytics.clear() } @@ -421,7 +419,7 @@ class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.Bar } override fun orderUpdated(processing: MainPresenter.PurchaseResult.Processing) { - Toaster.short(processing.state.toString()) + Toaster.short(processing.pendingTransaction.toString()) } fun onSynchronizerError(error: Throwable?): Boolean { @@ -454,7 +452,9 @@ class MainActivity : BaseActivity(), Animator.AnimatorListener, ScanFragment.Bar fun copyAddress(view: View) { trackAction(TAPPED_COPY_ADDRESS) Toaster.short("Address copied!") - copyToClipboard(synchronizer.getAddress()) + launch { + copyToClipboard(synchronizer.getAddress()) + } } diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ProgressFragment.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ProgressFragment.kt index 0274462..fae5b01 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ProgressFragment.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ProgressFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.View import android.widget.ProgressBar import androidx.annotation.IdRes +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.ui.presenter.ProgressPresenter import cash.z.wallet.sdk.data.Synchronizer import kotlinx.coroutines.launch @@ -15,7 +16,7 @@ abstract class ProgressFragment( ProgressPresenter.ProgressView { @Inject - protected lateinit var synchronizer: Synchronizer + protected lateinit var synchronizer: DataSyncronizer protected lateinit var progressPresenter: ProgressPresenter private lateinit var progressBar: ProgressBar diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ReceiveFragment.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ReceiveFragment.kt index 7958883..98c7ebb 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ReceiveFragment.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/ReceiveFragment.kt @@ -10,12 +10,14 @@ import android.view.ViewGroup import android.widget.TextView import cash.z.android.qrecycler.QRecycler import cash.z.android.wallet.R +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.di.annotation.FragmentScope import cash.z.android.wallet.ui.util.AddressPartNumberSpan import cash.z.wallet.sdk.data.Synchronizer import dagger.Module import dagger.android.ContributesAndroidInjector import kotlinx.android.synthetic.main.fragment_receive.* +import kotlinx.coroutines.launch import javax.inject.Inject /** @@ -27,7 +29,7 @@ class ReceiveFragment : BaseFragment() { lateinit var qrecycler: QRecycler @Inject - lateinit var synchronizer: Synchronizer + lateinit var synchronizer: DataSyncronizer lateinit var addressParts: Array @@ -61,7 +63,9 @@ class ReceiveFragment : BaseFragment() { super.onResume() // TODO: replace these with channels. For now just wire the logic together - onAddressLoaded(loadAddress()) + launch { + onAddressLoaded(synchronizer.getAddress()) + } // converter.scanBlocks() } @@ -85,12 +89,6 @@ class ReceiveFragment : BaseFragment() { addressParts[index].text = textSpan } - - // TODO: replace with tiered load. First check memory reference (textview contents?) then check DB, then load from JNI and write to DB - private fun loadAddress(): String { - return synchronizer.getAddress() - } - } @Module diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/SyncFragment.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/SyncFragment.kt index 1ac2bc0..c934144 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/SyncFragment.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/SyncFragment.kt @@ -66,7 +66,7 @@ class SyncFragment : ProgressFragment(R.id.progress_sync) { (view?.parent as? ViewGroup)?.doOnPreDraw { startPostponedEnterTransition() } - synchronizer.onSynchronizerErrorListener = ::onSynchronizerError +// synchronizer.onSynchronizerErrorListener = ::onSynchronizerError } override fun onResume() { diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/Zcon1HomeFragment.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/Zcon1HomeFragment.kt index 6ffe5de..26baf83 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/Zcon1HomeFragment.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/fragment/Zcon1HomeFragment.kt @@ -19,6 +19,7 @@ import cash.z.android.wallet.ui.presenter.BalancePresenter import cash.z.android.wallet.ui.presenter.TransactionPresenter import cash.z.android.wallet.ui.presenter.TransactionPresenterModule import cash.z.wallet.sdk.dao.WalletTransaction +import cash.z.wallet.sdk.data.twig import cash.z.wallet.sdk.ext.MINERS_FEE_ZATOSHI import cash.z.wallet.sdk.ext.convertZatoshiToZecString import cash.z.wallet.sdk.secure.Wallet @@ -114,10 +115,6 @@ class Zcon1HomeFragment : BaseFragment(), BalancePresenter.BalanceView, Transact override fun onResume() { super.onResume() chipBucket.setOnBucketChangedListener(this) - } - - override fun onStart() { - super.onStart() mainActivity?.balancePresenter?.addBalanceView(this) chipBucket.setOnBucketChangedListener(this) launch { @@ -125,8 +122,8 @@ class Zcon1HomeFragment : BaseFragment(), BalancePresenter.BalanceView, Transact } } - override fun onStop() { - super.onStop() + override fun onPause() { + super.onPause() mainActivity?.balancePresenter?.removeBalanceView(this) chipBucket.removeOnBucketChangedListener(this) transactionPresenter.stop() diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/BalancePresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/BalancePresenter.kt index 7cefb6a..406bd7f 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/BalancePresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/BalancePresenter.kt @@ -29,12 +29,12 @@ class BalancePresenter { // LifeCycle // - fun start(scope: CoroutineScope, synchronizer: Synchronizer) { + fun start(scope: CoroutineScope, balanceChannel: ReceiveChannel) { Twig.sprout("BalancePresenter") twig("balancePresenter starting!") balanceJob?.cancel() balanceJob = Job() - balanceJob = scope.launchBalanceBinder(synchronizer.balances()) + balanceJob = scope.launchBalanceBinder(balanceChannel) } fun stop() { diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HistoryPresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HistoryPresenter.kt index 4834b4b..9d50826 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HistoryPresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HistoryPresenter.kt @@ -1,5 +1,6 @@ package cash.z.android.wallet.ui.presenter +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.di.annotation.FragmentScope import cash.z.android.wallet.ui.fragment.HistoryFragment import cash.z.android.wallet.ui.presenter.Presenter.PresenterView @@ -19,7 +20,7 @@ import kotlin.coroutines.CoroutineContext class HistoryPresenter @Inject constructor( private val view: HistoryFragment, - private var synchronizer: Synchronizer + private var synchronizer: DataSyncronizer ) : Presenter { private var job: Job? = null @@ -32,7 +33,7 @@ class HistoryPresenter @Inject constructor( job?.cancel() job = Job() twig("historyPresenter starting!") - view.launchTransactionBinder(synchronizer.allTransactions()) +// view.launchTransactionBinder(synchronizer.allTransactions()) } override fun stop() { diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HomePresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HomePresenter.kt index bd75db0..6faf1d5 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HomePresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/HomePresenter.kt @@ -1,5 +1,6 @@ package cash.z.android.wallet.ui.presenter +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.di.annotation.FragmentScope import cash.z.android.wallet.extention.alert import cash.z.android.wallet.ui.fragment.HomeFragment @@ -18,7 +19,7 @@ import javax.inject.Singleton class HomePresenter @Inject constructor( private val view: HomeFragment, - private val synchronizer: Synchronizer + private val synchronizer: DataSyncronizer ) : Presenter { private var job: Job? = null @@ -32,15 +33,15 @@ class HomePresenter @Inject constructor( } override suspend fun start() { - job?.cancel() - job = Job() - twig("homePresenter starting! from ${this.hashCode()}") - with(view) { - launchBalanceBinder(synchronizer.balances()) - launchTransactionBinder(synchronizer.allTransactions()) - launchActiveTransactionMonitor(synchronizer.activeTransactions()) - } - synchronizer.onSynchronizerErrorListener = view::onSynchronizerError +// job?.cancel() +// job = Job() +// twig("homePresenter starting! from ${this.hashCode()}") +// with(view) { +// launchBalanceBinder(synchronizer.balances()) +// launchTransactionBinder(synchronizer.allTransactions()) +// launchActiveTransactionMonitor(synchronizer.activeTransactions()) +// } +// synchronizer.onSynchronizerErrorListener = view::onSynchronizerError } override fun stop() { @@ -99,11 +100,11 @@ class HomePresenter @Inject constructor( } fun onCancelActiveTransaction(transaction: ActiveSendTransaction) { - twig("requesting to cancel send for transaction ${transaction.internalId}") - val isTooLate = !synchronizer.cancelSend(transaction) - if (isTooLate) { - view.onCancelledTooLate() - } +// twig("requesting to cancel send for transaction ${transaction.internalId}") +// val isTooLate = !synchronizer.cancelSend(transaction) +// if (isTooLate) { +// view.onCancelledTooLate() +// } } } diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/MainPresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/MainPresenter.kt index 75f3783..90471d0 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/MainPresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/MainPresenter.kt @@ -1,5 +1,8 @@ package cash.z.android.wallet.ui.presenter +import cash.z.android.wallet.data.DataSyncronizer +import cash.z.android.wallet.data.PendingTransaction +import cash.z.android.wallet.data.isFailure import cash.z.android.wallet.ui.activity.MainActivity import cash.z.android.wallet.ui.presenter.Presenter.PresenterView import cash.z.wallet.sdk.data.* @@ -13,7 +16,7 @@ import javax.inject.Inject class MainPresenter @Inject constructor( private val view: MainActivity, - private val synchronizer: Synchronizer + private val synchronizer: DataSyncronizer ) : Presenter { interface MainView : PresenterView { @@ -34,7 +37,7 @@ class MainPresenter @Inject constructor( purchaseJob?.cancel() purchaseJob = Job() - purchaseJob = view.launchPurchaseBinder(synchronizer.activeTransactions()) + purchaseJob = view.launchPurchaseBinder(synchronizer.pendingTransactions()) } override fun stop() { @@ -43,7 +46,7 @@ class MainPresenter @Inject constructor( purchaseJob?.cancel()?.also { purchaseJob = null } } - fun CoroutineScope.launchPurchaseBinder(channel: ReceiveChannel>) = launch { + private fun CoroutineScope.launchPurchaseBinder(channel: ReceiveChannel>) = launch { twig("main purchase binder starting!") for (new in channel) { twig("main polled a purchase info") @@ -57,18 +60,18 @@ class MainPresenter @Inject constructor( // Events // - private fun bind(activeTransactions: Map) { - val newestState = activeTransactions.entries.last().value - if (newestState is TransactionState.Failure) { - view.orderFailed(PurchaseResult.Failure(newestState.reason)) + private fun bind(activeTransactions: List) { + val newest = activeTransactions.last() + if (newest.isFailure()) { + view.orderFailed(PurchaseResult.Failure(newest.errorMessage)) } else { - view.orderUpdated(PurchaseResult.Processing(newestState)) + view.orderUpdated(PurchaseResult.Processing(newest)) } } sealed class PurchaseResult { - data class Processing(val state: TransactionState = TransactionState.Creating) : PurchaseResult() - data class Failure(val reason: String = "") : PurchaseResult() + data class Processing(val pendingTransaction: PendingTransaction) : PurchaseResult() + data class Failure(val reason: String? = "") : PurchaseResult() } } diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/ProgressPresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/ProgressPresenter.kt index d9f63d6..7557fff 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/ProgressPresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/ProgressPresenter.kt @@ -1,5 +1,6 @@ package cash.z.android.wallet.ui.presenter +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.ui.presenter.Presenter.PresenterView import cash.z.wallet.sdk.data.Synchronizer import cash.z.wallet.sdk.data.Twig @@ -11,7 +12,7 @@ import kotlin.coroutines.CoroutineContext class ProgressPresenter @Inject constructor( private val view: ProgressView, - private var synchronizer: Synchronizer + private var synchronizer: DataSyncronizer ) : Presenter { private var job: Job? = null @@ -29,7 +30,6 @@ class ProgressPresenter @Inject constructor( job?.cancel() job = Job() Twig.sprout("ProgressPresenter") - twig("starting") view.launchProgressMonitor(synchronizer.progress()) } @@ -40,7 +40,7 @@ class ProgressPresenter @Inject constructor( } private fun CoroutineScope.launchProgressMonitor(channel: ReceiveChannel) = launch { - twig("progress monitor starting on thread ${Thread.currentThread().name}!") + twig("Progress monitor starting") for (i in channel) { bind(i) } diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/SendPresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/SendPresenter.kt index 635e664..7a33c26 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/SendPresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/SendPresenter.kt @@ -1,6 +1,7 @@ package cash.z.android.wallet.ui.presenter import cash.z.android.wallet.R +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.di.annotation.FragmentScope import cash.z.android.wallet.extention.toAppString import cash.z.android.wallet.sample.SampleProperties @@ -23,7 +24,7 @@ import javax.inject.Inject class SendPresenter @Inject constructor( private val view: SendFragment, - private val synchronizer: Synchronizer + private val synchronizer: DataSyncronizer ) : Presenter { interface SendView : PresenterView { diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/TransactionPresenter.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/TransactionPresenter.kt index fa1a0c3..8d7f0e6 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/TransactionPresenter.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/presenter/TransactionPresenter.kt @@ -1,5 +1,6 @@ package cash.z.android.wallet.ui.presenter +import cash.z.android.wallet.data.DataSyncronizer import cash.z.android.wallet.ui.fragment.Zcon1HomeFragment import cash.z.android.wallet.ui.presenter.Presenter.PresenterView import cash.z.wallet.sdk.dao.WalletTransaction @@ -14,7 +15,7 @@ import javax.inject.Inject class TransactionPresenter @Inject constructor( private val view: Zcon1HomeFragment, - private val synchronizer: Synchronizer + private val synchronizer: DataSyncronizer ) : Presenter { interface TransactionView : PresenterView { @@ -35,7 +36,7 @@ class TransactionPresenter @Inject constructor( transactionJob?.cancel() transactionJob = Job() // transactionJob = view.launchPurchaseBinder(synchronizer.activeTransactions()) - transactionJob = view.launchTransactionBinder(synchronizer.allTransactions()) +// transactionJob = view.launchTransactionBinder(synchronizer.allTransactions()) } override fun stop() { diff --git a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/util/Broom.kt b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/util/Broom.kt index 4b38b6d..3b03d3c 100644 --- a/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/util/Broom.kt +++ b/zcash-android-wallet-app/app/src/main/java/cash/z/android/wallet/ui/util/Broom.kt @@ -1,20 +1,16 @@ package cash.z.android.wallet.ui.util -import cash.z.android.wallet.PokerChip import cash.z.android.wallet.ZcashWalletApplication import cash.z.android.wallet.data.StaticTransactionRepository +import cash.z.android.wallet.data.TransactionSender +import cash.z.android.wallet.data.WalletTransactionEncoder import cash.z.android.wallet.extention.toDbPath import cash.z.android.wallet.extention.tryIgnore -import cash.z.android.wallet.sample.SampleProperties -import cash.z.wallet.sdk.data.PollingTransactionRepository -import cash.z.wallet.sdk.data.TransactionRepository import cash.z.wallet.sdk.data.Twig import cash.z.wallet.sdk.data.twig import cash.z.wallet.sdk.ext.MINERS_FEE_ZATOSHI import cash.z.wallet.sdk.jni.RustBackendWelding -import cash.z.wallet.sdk.rpc.Service import cash.z.wallet.sdk.secure.Wallet -import cash.z.wallet.sdk.service.LightWalletService import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.File @@ -22,7 +18,7 @@ import kotlin.properties.Delegates import kotlin.properties.ReadOnlyProperty class Broom( - private val service: LightWalletService, + private val sender: TransactionSender, private val rustBackend: RustBackendWelding, private val cacheDbName: String, private val appWallet: Wallet @@ -39,7 +35,7 @@ class Broom( // cloneCachedBlocks() // optional? try { - val wallet = initWallet(walletSeedProvider) + val encoder = initEncoder(walletSeedProvider) // verify & scan //TODO: for now, assume validation is happening elsewhere and just scan here Twig.sprout("broom-scan") @@ -48,12 +44,7 @@ class Broom( Twig.clip("broom-scan") if (scanResult) { twig("successfully scanned blocks! Ready to sweep!!!") - val memo = "swag shirt test" - val address = "ztestsapling1yu2zy9aanf8pjf2qvm4qmn4k6q57y2d9fcs3vz0guthxx3m2aq57qm6hkx0580m9u9635xh6ttr" -// val address = appWallet.getAddress() - val transactionId = wallet.createRawSendTransaction(amount, address).also { checkTx(it) } - val transactionRaw: ByteArray? = repository.findTransactionById(transactionId)?.raw.also { checkRawTx(it) } - service.submitTransaction(transactionRaw!!).also { checkResponse(it) } + sender.sendToAddress(encoder, amount, appWallet.getAddress()) } else { twig("failed to scan!") } @@ -67,34 +58,10 @@ class Broom( } } - private fun checkTx(transactionId: Long) { - if (transactionId < 0) { - throw SweepException.Creation - } else { - twig("successfully created transaction!") - } - } - - private fun checkRawTx(transactionRaw: ByteArray?) { - if (transactionRaw == null) { - throw SweepException.Disappeared - } else { - twig("found raw transaction in the dataDb") - } - } - - private fun checkResponse(response: Service.SendResponse) { - if (response.errorCode < 0) { - throw SweepException.IncompletePass(response) - } else { - twig("successfully submitted. error code: ${response.errorCode}") - } - } - - private fun initWallet(seedProvider: ReadOnlyProperty): Wallet { + private fun initEncoder(seedProvider: ReadOnlyProperty): WalletTransactionEncoder { // TODO: maybe let this one live and make a new one? DATA_DB_PATH.absoluteFile.delete() - return Wallet( + val wallet = Wallet( ZcashWalletApplication.instance, rustBackend, DATA_DB_PATH.absolutePath, @@ -107,6 +74,7 @@ class Broom( it.initialize() } } + return WalletTransactionEncoder(wallet, repository) } companion object { @@ -114,10 +82,4 @@ class Broom( private val DATA_DB_PATH: File = ZcashWalletApplication.instance.getDatabasePath(DATA_DB_NAME) } - - sealed class SweepException(val errorMessage: String) : RuntimeException(errorMessage) { - object Creation : SweepException("failed to create raw transaction") - object Disappeared : SweepException("unable to find a matching raw transaction. This means the rust backend said it created a TX but when we looked for it in the DB it was missing!") - class IncompletePass(response: Service.SendResponse) : SweepException("submit failed with error code: ${response.errorCode} and message ${response.errorMessage}") - } }