Giter Club home page Giter Club logo

nighthawk-wallet-android's People

Contributors

gmale avatar imichaelmiers avatar mandeepbhalothia avatar nighthawk24 avatar pacu avatar poussinou avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nighthawk-wallet-android's Issues

Add language translations

Support for the top 10 languages

  1. Mandarin Chinese – 882 million

  2. Spanish – 325 million

  3. English – 312-380 million

  4. Arabic – 206-422 million

  5. Hindi – 181 million

  6. Portuguese – 178 million

  7. Bengali – 173 million

  8. Russian – 146 million

  9. Japanese 128 million

  10. German – 96 million

v1.0.18 Prod Crash kotlin.UninitializedPropertyAccessException

kotlin.UninitializedPropertyAccessException

kotlin.UninitializedPropertyAccessException: 
  at com.nighthawkapps.wallet.android.ui.MainActivity.getSynchronizerComponent (MainActivity.kt:98)
  at com.nighthawkapps.wallet.android.ui.receive.ReceiveFragment$$special$$inlined$viewModel$1.getValue (ViewModelExt.kt:63)
  at com.nighthawkapps.wallet.android.ui.receive.ReceiveFragment$$special$$inlined$viewModel$1.getValue (ViewModelExt.kt:8)
  at com.nighthawkapps.wallet.android.ui.receive.ReceiveFragment.getViewModel (Unknown Source:2)
  at com.nighthawkapps.wallet.android.ui.receive.ReceiveFragment.access$getViewModel$p (ReceiveFragment.kt:16)
  at com.nighthawkapps.wallet.android.ui.receive.ReceiveFragment$onResume$1.invokeSuspend (ReceiveFragment.kt:38)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:201)
  at android.app.ActivityThread.main (ActivityThread.java:6864)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:873)

Add auto-rescan on upgrade

As a user with a broken wallet, I'd like to have my wallet "just work" after an upgrade so that I have confidence that Nighthawk is functional and ready for use.

Criteria:

  • The Android wallet should follow an approach similar to iOS, where an attempt is made to automatically fix wallets upon upgrading to the latest version
  • On the iOS side, failed transactions are not cleared. On Android, they are cleared after 20 blocks so we cannot take the exact same approach
  • The plan is to automatically rescan back to the first unspent note for all users that upgrade
  • This rescan MUST NOT happen on every launch. Instead, it should only occur upon upgrade.

UX improvement: Start calculating proof while still on confirmation view

Proof calculation can take several seconds, and the following "flow optimization" will make user feel that it's much faster.

The app already contains a send confirmation view, which is shown after user taps the send button. Most of the users will spend some time on the confirmation view, to validate that the address and amount are correct. That's when proof calculation should start in the background. By the time the user taps confirm, the proof will already be partially [or perhaps even fully] calculated. As a result, the time between user's confirmation action and transaction being broadcasted will be much shorter, or even instant.

Fix Build Warnings

Fix build warnings in the files:

SynchronizerModule.kt
ViewModelExt.kt
CurrencyFormatter.kt
Dialogs.kt
EditText.kt
Extensions.kt
Int.kt
LifeCycleOwner.kt
View.kt
MainActivity.kt
TransactionAdapter.kt
TransactionViewHolder.kt
TransactionsFooter.kt
HomeFragment.kt
HomeViewModel.kt
ScanFragment.kt
SendFragment.kt
SendViewModel.kt
BackupFragment.kt
SettingsFragment.kt
SettingsViewModel.kt
MemoUtil.kt

v1.0.19 Crash java.lang.ArrayIndexOutOfBoundsException

Bug vs expected behavior
App keeps crashing after opening

Device:
Samsung Galaxy A01
Android 10 (SDK 29)
brightness_1

Crash:

java.lang.ArrayIndexOutOfBoundsException: 
  at com.nighthawkapps.wallet.android.ui.detail.TransactionViewHolder.getSender (TransactionViewHolder.kt:178)
  at com.nighthawkapps.wallet.android.ui.detail.TransactionViewHolder$bindTo$1.invokeSuspend (TransactionViewHolder.kt:73)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith (DispatchedContinuation.kt:349)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable (Cancellable.kt:30)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default (Cancellable.kt:27)
  at kotlinx.coroutines.CoroutineStart.invoke (CoroutineStart.kt:110)
  at kotlinx.coroutines.AbstractCoroutine.start (AbstractCoroutine.kt:158)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch (Builders.common.kt:56)
  at kotlinx.coroutines.BuildersKt.launch (Unknown Source:1)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default (Builders.common.kt:49)
  at kotlinx.coroutines.BuildersKt.launch$default (Unknown Source:1)
  at com.nighthawkapps.wallet.android.ui.detail.TransactionViewHolder.bindTo (TransactionViewHolder.kt:34)
  at com.nighthawkapps.wallet.android.ui.detail.TransactionAdapter.onBindViewHolder (TransactionAdapter.kt:43)
  at com.nighthawkapps.wallet.android.ui.detail.TransactionAdapter.onBindViewHolder (TransactionAdapter.kt:10)
  at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder (RecyclerView.java:7254)
  at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder (RecyclerView.java:7337)
  at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline (RecyclerView.java:6194)
  at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline (RecyclerView.java:6460)
  at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:6300)
  at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:6296)
  at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next (LinearLayoutManager.java:2330)
  at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk (LinearLayoutManager.java:1631)
  at androidx.recyclerview.widget.LinearLayoutManager.fill (LinearLayoutManager.java:1591)
  at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren (LinearLayoutManager.java:668)
  at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2 (RecyclerView.java:4309)
  at androidx.recyclerview.widget.RecyclerView.dispatchLayout (RecyclerView.java:4012)
  at androidx.recyclerview.widget.RecyclerView.onLayout (RecyclerView.java:4578)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at androidx.constraintlayout.widget.ConstraintLayout.onLayout (ConstraintLayout.java:1865)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:332)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:270)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:332)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:270)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:332)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:270)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1829)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1673)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1582)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:332)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:270)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1829)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1673)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1582)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:332)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:270)
  at com.android.internal.policy.DecorView.onLayout (DecorView.java:1062)
  at android.view.View.layout (View.java:23754)
  at android.view.ViewGroup.layout (ViewGroup.java:7277)
  at android.view.ViewRootImpl.performLayout (ViewRootImpl.java:3679)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:3139)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:2200)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:8999)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:996)
  at android.view.Choreographer.doCallbacks (Choreographer.java:794)
  at android.view.Choreographer.doFrame (Choreographer.java:729)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:981)
  at android.os.Handler.handleCallback (Handler.java:883)
  at android.os.Handler.dispatchMessage (Handler.java:100)
  at android.os.Looper.loop (Looper.java:237)
  at android.app.ActivityThread.main (ActivityThread.java:7860)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:493)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)

Optional backup of seed words

Explore and add support for encrypted backup of seed words to user's choice of cloud.

Feature to include adding a password to the text file containing the seed words and then allowing the user to get the file and then decide to store it in the phone or a cloud service via android intent.

The encrypted file should be decrypt-able in iOS version of Nighthawk

Explore:
https://github.com/tozny/java-aes-crypto
http://www.jasypt.org

Seed phrase used for Zecwallet Lite not displaying any balance

Bug vs expected behavior
I initiated my NightHawk wallet with the 24 words seed phrase I use also for Zecwallet Lite. No value is displayed, despite I have some funds in Zecwallet Lite. I checked the seed several times and it matches exactly.

**Device **

  • Android Device: Samsung A50 (SM-A505FN)
  • Android Version 10

Birthday height defaults to 930000

Bug vs expected behavior
I'm trying to restore a ZIP-32 seed and am entering a birthday height that's past 1080000. NHW ignores this height defaults to rescanning all blocks since 930000.

Device (please complete the following information):

  • Android Device: Pixel 4a
  • Android Version: 11

To Reproduce
Steps to reproduce the behavior:

  1. Launch Nighthawk Wallet, choose to restore a wallet, enter your seed, enter a birthday height of 1080309.
  2. Observe that the wallet is downloading a lot of blocks.
  3. Go to settings, backup wallet, view seed, and see birthday height of 930 000.

While syncing block headers on app start, show wallet balance based on the last known state

Is your feature request related to a problem? Please describe.

When the app is launched and it is syncing the latest block headers, instead showing wallet balance, the home screen currently shows "Updating Available".

Most users don't use the same seed for different wallets, so it is safe to assume that their balance hasn't changed outside of the wallet, and show the last known balance while syncing.

Describe the solution you'd like

Show the last known balance while syncing.

When I click on the "Send Money" button, the app closes. 2.0.05

I don't have a zec

FATAL EXCEPTION: main
Process: com.nighthawkapps.wallet.android, PID: 3399
java.lang.IllegalArgumentException: Zatoshi must be in the range [0, 2100000000000000]
at cash.z.ecc.android.sdk.model.Zatoshi.(Zatoshi.kt:12)
at cash.z.ecc.android.sdk.model.Zatoshi.minus(Zatoshi.kt:17)
at com.nighthawkapps.wallet.android.ui.send.SendEnterAmountFragment.onBalanceUpdated(SendEnterAmountFragment.kt:254)
at com.nighthawkapps.wallet.android.ui.send.SendEnterAmountFragment.access$onBalanceUpdated(SendEnterAmountFragment.kt:29)
at com.nighthawkapps.wallet.android.ui.send.SendEnterAmountFragment$onViewCreated$1$1$2$1.emit(SendEnterAmountFragment.kt:53)
at com.nighthawkapps.wallet.android.ui.send.SendEnterAmountFragment$onViewCreated$1$1$2$1.emit(SendEnterAmountFragment.kt:52)
at kotlinx.coroutines.flow.StateFlowImpl.collect(StateFlow.kt:398)
at kotlinx.coroutines.flow.ReadonlyStateFlow.collect(Unknown Source:2)
at com.nighthawkapps.wallet.android.ui.send.SendEnterAmountFragment$onViewCreated$1$1$2.invokeSuspend(SendEnterAmountFragment.kt:52)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:376)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at androidx.lifecycle.RepeatOnLifecycleKt$repeatOnLifecycle$3$1$1$1.onStateChanged(RepeatOnLifecycle.kt:106)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
at androidx.fragment.app.FragmentViewLifecycleOwner.handleLifecycleEvent(FragmentViewLifecycleOwner.java:96)
at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:703)
at androidx.fragment.app.Fragment.restoreViewState(Fragment.java:3151)
at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:3142)
at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:579)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:264)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:210)
at android.os.Looper.loop(Looper.java:299)
at android.app.ActivityThread.main(ActivityThread.java:8261)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@6f2524f, Dispatchers.Main.immediate]

Device

miui 13.5
android 12
api 31

When I click on "open browser" after clicking on moonpay the application closes. 2.0.05

FATAL EXCEPTION: main
Process: com.nighthawkapps.wallet.android, PID: 24264
java.lang.IllegalArgumentException: No map entry found for com.nighthawkapps.wallet.android.ui.transfer.TransferViewModel. Verify that this ViewModel has been added to the ViewModelModule. [class com.nighthawkapps.wallet.android.ui.MainViewModel, class com.nighthawkapps.wallet.android.ui.home.HomeViewModel, class com.nighthawkapps.wallet.android.ui.send.SendViewModel, class com.nighthawkapps.wallet.android.ui.history.HistoryViewModel, class com.nighthawkapps.wallet.android.ui.receive.ReceiveViewModel, class com.nighthawkapps.wallet.android.ui.scan.ScanViewModel, class com.nighthawkapps.wallet.android.ui.profile.ProfileViewModel, class com.nighthawkapps.wallet.android.ui.setup.SettingsViewModel, class com.nighthawkapps.wallet.android.ui.home.BalanceDetailViewModel, class com.nighthawkapps.wallet.android.ui.send.AutoShieldViewModel, class com.nighthawkapps.wallet.android.ui.setup.PasswordViewModel, class com.nighthawkapps.wallet.android.ui.setup.FiatCurrencyViewModel, class com.nighthawkapps.wallet.android.ui.setup.SyncNotificationViewModel, class com.nighthawkapps.wallet.android.ui.setup.ExternalServicesViewModel]
at com.nighthawkapps.wallet.android.di.viewmodel.ViewModelFactory.create(ViewModelFactory.kt:12)
at androidx.lifecycle.ViewModelProvider$Factory$-CC.$default$create(ViewModelProvider.kt:83)
at com.nighthawkapps.wallet.android.di.viewmodel.ViewModelFactory.create(Unknown Source:0)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:187)
at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.kt:153)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment$special$$inlined$viewModel$1.getValue(ViewModelExt.kt:13)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment$special$$inlined$viewModel$1.getValue(ViewModelExt.kt:8)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment.getTransferViewModel(TopUpFragment.kt:21)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment.access$getTransferViewModel(TopUpFragment.kt:19)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment$onMoonPayClicked$1.invoke(TopUpFragment.kt:54)
at com.nighthawkapps.wallet.android.ui.topup.TopUpFragment$onMoonPayClicked$1.invoke(TopUpFragment.kt:48)
at com.nighthawkapps.wallet.android.ui.base.BaseFragment.showMaterialDialog$lambda$2$lambda$1(BaseFragment.kt:87)
at com.nighthawkapps.wallet.android.ui.base.BaseFragment.$r8$lambda$CPU6MX0eD6wJjtwEgt-f5JFMmwg(Unknown Source:0)
at com.nighthawkapps.wallet.android.ui.base.BaseFragment$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:210)
at android.os.Looper.loop(Looper.java:299)
at android.app.ActivityThread.main(ActivityThread.java:8261)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1045)

Device
miui 13.0.5
android 12
api 31

New wallet birthday hardcoded to block 1,290,000

Bug vs expected behavior

This could be a regression of issue #17

I created a wallet a few days ago. The app showed block 1,290,000 as the wallet birthday block, even though at that time the latest block was 1,345,221.

Could this be related to the issue #20, where the slow initial sync could be attributed to the app trying to sync way too many blocks headers than necessary? In my case, the initial sync was indeed too slow. I'd say it took about 10 minutes or even longer.

Is that what wallet birthday is used for -- to know how many block in the past to sync when restoring a wallet?

Nighthawk version
1.0.22

Device

  • Android Device: OnePlus 3
  • Android Version 9

To Reproduce

  1. Install app
  2. Create new wallet

Idea: Allow users to choose which txns to collect memos for

Is your feature request related to a problem? Please describe.

Lightwalletd can 'learn' which txns belong to a client by watching which ones they collect memos for.

Memos are nice, but they're not essential.

Describe the solution you'd like

A user defined 'filter' so users can set a limit (in ZEC), if a txn is less/more than the limit then the memos are not automatically fetched from the server. A tickbox 'dont automatically collect memos' would also work.

Describe alternatives you've considered

The transaction list could also allow the memo to be fetched for a specific transaction.

Several block confirmations currently required for funds to become available

Is your feature request related to a problem? Please describe.

This is definitely my main issue with Nighthawk wallet. After a block with incoming transaction has been mined, it takes several [8 or more?] block confirmations in order for the wallet to "unlock" those funds, show them as available and allow me to use them in an outgoing transaction.

To make things even worse, after making an outgoing transaction, due to the nature of UTXO-based systems, all the funds that were input in my outgoing transaction are excluded from the available balance, until 8 blocks are mined. For example, if I have 1 UTXO of 10 ZEC and send 1 ZEC in my next transaction, the whole 10 ZEC will be used as transaction input and my wallet will show a balance of 0 ZEC until my outgoing transaction had 8 confirmations 😬

This could be very scary UX for people who are new to crypto, thinking that all the funds from their wallet disappeared [hacked, stolen?] after they made 1 small outgoing transaction.

It is unlikely that this block confirmation thing is a requirement from ECC, as I haven't seen it in Zecwallet Lite, nor in any other mobile crypto wallet. I understand security and how SPV nodes work, but I don't think that such security measure is required on the client side, while protocol allows users to immediately spend UTXOs after they are mined in the first block.

Describe the solution you'd like

  1. Show balance updates as soon as a transaction is in the mempool, both for incoming and outgoing transactions.
  2. Show different values for total and spendable [available] funds only in send view, while balance view should always show the total of available + pending funds.
  3. Allow users to spend those new coins as soon as the incoming transaction is mined in the block.

Describe alternatives you've considered

To use Zecwallet Lite instead, as it lets me send funds as soon as the block is mined 😉

Insufficient funds message shown when there were sufficient funds for the transaction and transaction was successfully sent

Bug vs expected behavior

The error message "Oops! Failed to send due to insufficient funds!" pops out when sending ZEC. Not sure what triggered the message, as there were sufficient funds and I could see the transaction in the mempool immediately after. So I didn't even have to retry the transaction. This happened at least twice.

Nighthawk version
1.0.23

Device

  • Android Device: OnePlus 3
  • Android Version 9

To Reproduce

  1. Go to "Send Zcash"
  2. Complete the form with amount that is lower than your balance
  3. Tap on Send

Integrate latest SDK version 1.3.0-*

The next version of the SDK has lots of breaking changes, including, most significantly moving from two builds of the library on JCenter to just one on Maven Central. Integrating this should be a bit easier for me since I'm familiar with all the changes and also possibly helpful in case more changes are required to support nighthawk's use case.

Criteria:

  • The app builds with the latest version of the SDK
  • Any maintained tests are not newly broken by the transition
  • Sending / Receiving still work
  • Installing the new build on top of an old build migrates without crashing

Speed up wallet sync

Is your feature request related to a problem? Please describe.
There are two related problems:

  • Initial sync when a new wallet is created
  • Subsequent syncs when the wallet is opened

In the first case, it took my wallet 40 minutes for the initial sync. Yes, 40 minutes before I could use the wallet after I first installed it.

In the second case, I open the wallet about once per week and on average it takes 20 minutes before I can use the wallet.

Describe the solution you'd like
I want the wallet to be usable within a few seconds after opening it. I don't know for sure how to make this happen but this is how the wallet should work while still maintaining privacy guarantees.

Describe alternatives you've considered
Idea for the initial sync problem: if the wallet is new, there should be no need to sync anything.
Only sync from that point forward. This would enable the wallet to be usable right away.

Idea for the subsequent sync problem: have the wallet sync in the background from time to time, that way the next way the user opens the wallet it is most likely already almost synced and the user can either use the wallet right away or only have to wait a short amount of time for the wallet to sync before it is usable.

Another complementary idea (not necessarily a replacement for the above) is to allow the user to pair the wallet with their own full node, ideally over Tor for privacy and NAT traversal benefits, so that they can instantaneously get their wallet balance info from their own full node.

chore: update SideShift dialogue box copy

Current copy:

Your Z-Address has been copied to the clipboard.

Select "Open Browser" below and paste your address into the SideShift Page and select Shielded Zcash as the receiving address

Suggested copy:

Your Z-address has been copied to the clipboard.

Choose 'Open Browser' below, select 'Zcash (Shielded)' as the receiving coin on the SideShift page, and then paste your Z-address.

Send Flow shows error message while sending funds.

To Reproduce
Steps to reproduce the behavior:

  1. Send Funds
  2. See incorrect message of "Oops! Failed to send due to insufficient funds!"
  3. User is stuck on the send screen with animation when the funds are actually sent out.

v1.0.19 Crash android.database.sqlite.SQLiteDatabaseCorruptException

Device:
Realme realme X2Pro
brightness_1
Android 10 (SDK 29)

android.database.sqlite.SQLiteDatabaseCorruptException: 
  at android.database.sqlite.SQLiteConnection.nativeExecute (Native Method)
  at android.database.sqlite.SQLiteConnection.execute (SQLiteConnection.java:648)
  at android.database.sqlite.SQLiteSession.beginTransactionUnchecked (SQLiteSession.java:325)
  at android.database.sqlite.SQLiteSession.beginTransaction (SQLiteSession.java:300)
  at android.database.sqlite.SQLiteDatabase.beginTransaction (SQLiteDatabase.java:568)
  at android.database.sqlite.SQLiteDatabase.beginTransaction (SQLiteDatabase.java:478)
  at androidx.sqlite.db.framework.FrameworkSQLiteDatabase.beginTransaction (FrameworkSQLiteDatabase.java:69)
  at androidx.room.RoomDatabase.internalBeginTransaction (RoomDatabase.java:488)
  at androidx.room.RoomDatabase.beginTransaction (RoomDatabase.java:471)
  at androidx.room.paging.LimitOffsetDataSource.loadInitial (LimitOffsetDataSource.java:161)
  at androidx.paging.PositionalDataSource.loadInitial$paging_common (PositionalDataSource.kt:362)
  at androidx.paging.PositionalDataSource.load$paging_common (PositionalDataSource.kt:339)
  at androidx.paging.LegacyPagingSource$load$2.invokeSuspend (LegacyPagingSource.kt:116)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
  at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)

Initial wallet scan never completes with Rust error

Bug vs expected behavior
Expected the wallet to sync normally, but it didn't even error out initially, it just never showed sent funds. Upon inspecting it finally threw an error and cannot complete sync.

Device (please complete the following information):

  • Android Device: Pixel 6
  • Android Version 12

To Reproduce
Steps to reproduce the behavior:

  1. Create a new wallet
  2. Wallet never syncs
  3. Do "full restore"
  4. Wallet now complains it cannot sync

Screenshots
image

subaddresses.

Describe the solution you'd like
as in monerujo, I want you to be able to create several transparent and protected addresses for more privacy

and, I want to be able to transfer from subaddresses to other zec addresses

when you send zec to a subaddress, the subaddress will send to the main address

when sending to someone else's zec address, you will be able to choose whether to send through the main address or the subaddress

the app will be able to create many sub-addresses for one person

--

all this is already implemented in monerujo

Bad label on sending UI : Says 'MEMO', should be 'MIN'

Bug vs expected behavior
What is the bug? What did you expected to happen instead?

When sending a transaction there's a button to send the max amount, to the left of that there's a button that sends the minimum amount..... but its not labelled correctly (says MEMO)

Device (please complete the following information):
Android: Nokia One

v1.0.19 Crash cash.z.ecc.android.sdk.exception.CompactBlockProcessorException$FailedScan

Device
Realme realme X2Pro
brightness_1
Android 10 (SDK 29)

cash.z.ecc.android.sdk.exception.CompactBlockProcessorException$FailedScan: 
  at cash.z.ecc.android.sdk.block.CompactBlockProcessor$scanNewBlocks$2.invokeSuspend (CompactBlockProcessor.kt:531)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.DispatchedTask.run (DispatchedTask.kt:106)
  at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely (CoroutineScheduler.kt:571)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask (CoroutineScheduler.kt:750)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker (CoroutineScheduler.kt:678)
  at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run (CoroutineScheduler.kt:665)
Caused by: java.lang.RuntimeException: 
  at cash.z.ecc.android.sdk.jni.RustBackend.scanBlockBatch (Native Method)
  at cash.z.ecc.android.sdk.jni.RustBackend.access$scanBlockBatch (RustBackend.kt:18)
  at cash.z.ecc.android.sdk.jni.RustBackend$Companion.scanBlockBatch (RustBackend.kt:1)
  at cash.z.ecc.android.sdk.jni.RustBackend$Companion.access$scanBlockBatch (RustBackend.kt:205)
  at cash.z.ecc.android.sdk.jni.RustBackend.scanBlocks (RustBackend.kt:111)
  at cash.z.ecc.android.sdk.block.CompactBlockProcessor$scanNewBlocks$2.invokeSuspend (CompactBlockProcessor.kt:536)

Show Notification when receiving ZEC

For each pending transaction that the app gets a callback for show X ZEC in the Notification.

We can pop a local notification with the ZEC amount received when we have a pending transaction to call user's attention.

Show "Received X.XXXX ZEC" each time a pending transaction is received by the client.

User LockBox to store incoming pending transaction to only show notification once.
Clear LockBox for notifications every time the app start.

'Reset to default host' button non-functional

On Nighthawk v2.0.02 (F-Droid), one can successfully change and update the server.

However, unexpectedly, the 'reset to default host' button is non-functional.

No on-press change is registered, nor on-screen errors thrown, and the last-set server remains current.

Simplify UX by not mentioning "available" funds on home view and balance view

Is your feature request related to a problem? Please describe.

This is loosely related to #79, where dropping the requirement for 8 block confirmations would make funds available much faster and remove the need to differentiate between available and unavailable funds.

The only moment when a user should be informed that there is a difference between available and pending funds is on the send view, when they are making a new transaction.

Most of the time, users don't spend funds immediately after receiving. For them all the funds will be available all the time. Not being confused with what "available funds" really means will be a nice UX improvement.

Describe the solution you'd like

  1. Instead of using the word "available" consider using "spendable". I think it is more descriptive to the users.
  2. Home view and balance view should show total funds, including any pending transaction.
  3. Send view should be the only one to differentiate between total funds and spendable funds.

Wallet history does not list unshielded deposit transaction

Bug vs expected behavior

I've transferred some ZEC to my Nighthawk wallet from an exchange which supports only withdrawals using transparent transactions.

I could see the coins in my wallet balance, but that initial transparent transaction does not show in wallet history section. In fact, the view clearly says that it is wallet history for the specific shielded address. All subsequent outgoing and incoming shielded transactions are shown correctly. So, the view does not really show wallet history as it states, but an address history instead.

I think that transaction history should not be filtered per address type, but instead it should show all transactions to and from any address managed by my wallet, no matter which type of address is used.

Nighthawk version
1.0.23

Device (please complete the following information):

  • Android Device: OnePlus 3
  • Android Version 9

To Reproduce

  1. Make a transfer to your wallet's transparent address
  2. Go to Wallet History
  3. "Received From" transaction is not shown in the list, while all transactions sent to my shielded address are shown

v1.0.18 Prod Crash java.lang.IllegalStateException

java.lang.IllegalStateException: 
  at com.nighthawkapps.wallet.android.ui.setup.WalletSetupViewModel.storeWallet (WalletSetupViewModel.kt:198)
  at com.nighthawkapps.wallet.android.ui.setup.WalletSetupViewModel.importWallet (WalletSetupViewModel.kt:101)
  at com.nighthawkapps.wallet.android.ui.setup.RestoreFragment$importWallet$$inlined$apply$lambda$1.invokeSuspend (RestoreFragment.kt:111)
  at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith (ContinuationImpl.kt:33)
  at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith (DispatchedContinuation.kt:349)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable (Cancellable.kt:30)
  at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default (Cancellable.kt:27)
  at kotlinx.coroutines.CoroutineStart.invoke (CoroutineStart.kt:110)
  at kotlinx.coroutines.AbstractCoroutine.start (AbstractCoroutine.kt:158)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch (Builders.common.kt:56)
  at kotlinx.coroutines.BuildersKt.launch (Unknown Source:1)
  at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default (Builders.common.kt:49)
  at kotlinx.coroutines.BuildersKt.launch$default (Unknown Source:1)
  at com.nighthawkapps.wallet.android.ui.setup.RestoreFragment.importWallet (RestoreFragment.kt:109)
  at com.nighthawkapps.wallet.android.ui.setup.RestoreFragment.onDone (RestoreFragment.kt:100)
  at com.nighthawkapps.wallet.android.ui.setup.RestoreFragment.access$onDone (RestoreFragment.kt:21)
  at com.nighthawkapps.wallet.android.ui.setup.RestoreFragment$onViewCreated$1.onClick (RestoreFragment.kt:49)
  at android.view.View.performClick (View.java:8160)
  at android.widget.TextView.performClick (TextView.java:16222)
  at com.google.android.material.button.MaterialButton.performClick (MaterialButton.java:1119)
  at android.view.View.performClickInternal (View.java:8137)
  at android.view.View.access$3700 (View.java:888)
  at android.view.View$PerformClick.run (View.java:30236)
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:246)
  at android.app.ActivityThread.main (ActivityThread.java:8506)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.