Skip to content

(android) Support for multiple wallets#742

Merged
dpad85 merged 44 commits intomasterfrom
android-multiple-wallets
Sep 26, 2025
Merged

(android) Support for multiple wallets#742
dpad85 merged 44 commits intomasterfrom
android-multiple-wallets

Conversation

@dpad85
Copy link
Member

@dpad85 dpad85 commented Sep 3, 2025

This PR adds support for multiple wallets within a single Android Phoenix application. It's the Android pendant of the iOS PR #731.

In addition to the multiple wallets feature, this PR reworks how the app starts the node(s) which should fix several stability issues regarding background processing.

Currently, this version is able to run several LN nodes in parallel. It means you can receive from several wallets at the same time, which is nice, but it certainly has a performance cost (esp. because of multiple CurrencyManager running) which is yet TBD.

Customising a wallet

You can attach a name and an avatar to a wallet. A random avatar is picked by default. Note that it's a bit different from the iOS version: here the avatar can only be an emoji, not an image, but it makes things simpler and also looks good.

image image image

Switching wallets

Tapping on the wallet in the settings screen lets the user switch from one wallet to another. Or create a new wallet.

image

Selecting a wallet at startup

The user picks which wallet to use when starting the app (unless a default wallet has been defined, then the selector screen is skipped).

image image

Viewing the wallet info on key screens

When receiving a payment, or sending a payment, the current wallet avatar is displayed to let the user know which wallets is going to be affected, with some details relevant to the current flow.

image image image

Hidden wallet

This feature is WIP. It will let you hide a wallet ; only when entering this wallet's PIN code will the app open it.

Background payments

When receiving payments in the background, the payment notification tells you which wallet received the funds.

image

dpad85 and others added 20 commits July 11, 2025 14:51
Also reorganized the Settings menus to match the iOS app.
This commit prepares the app for supporting multiple wallets. The seed
file can now store multiple mnemonics. The app is also not tied to a
single business object anymore, it can host and track several at the
same time.

Due to this change, the mechanism to start the business has been reworked.
This also fixes long standing issues coming from the legacy app where the
business was somehow tied to the foreground service and caused problems with
the background workers. We now use a singleton that can be accessed safely
from anywhere including the workers.

This commit is a WIP.
These files are also placed in their own package folder.
Depending on the device locale, the decimal separator may be a comma
or a dot character. If it's a comma it causes problems when converting
the string input to a Double, because the method expects a dot.

This commit also prevents entering more than 2 decimals for fiat amounts
in the currency converter. It caused a problem where the additional 3rd
decimal (which is actually not visible) would cause the underlying amount
to be updated, which in turn refreshes the fiat amount ; it makes the UX
look very weird.
Fixed issues with wallet reset and wallet creation
Move wallet UI components to correct package
Added a DataStoreManager to load/unload a preference file per
node id. Migration is not done yet.

Removed the global ambient userPrefs, instead use a nullable
LocalUserPrefs ambient that is updated when the active wallet
changes.
The screenlock mechanism now works by resetting the active wallet
which redirects to the startup screen. Entering the PIN/fingerprint
is handled by the startup screen.

Internal preferences are now per-wallet. Some preferences have been
moved to the global prefs.

Wallets now have an emoji avatar.
Removed the 3-dots button for the active wallet. Instead, the
currently active wallet is handled differently in the available
wallets list.

Also remove the deterministic random avatar, instead wallet meta
are created at startup if missing with a random avatar.
Screenlock is not tied to the wallet selector anymore, instead it
is tied to the startup screen. The startup screen is redesigned
with a simpler logic, where the active wallet is set explicitly.

Fixed issues with default wallet loading, and also start the wallet
if there's only one available.
This is more maintainable than a simple String. Also, this wallet id
is now the hash160 of the node id which is better for privacy and
also needed to handle the FCM messages.
This parameter was introduced and used only by the Android app because of
long standing issues with the background system, which have been fixed with
the multiple wallets support update.
Also decoupled the foreground service notification from the notifications
for received payments.
@dpad85 dpad85 marked this pull request as draft September 3, 2025 16:40
Factorised some code, though not all of it to keep some flexiliby.
The headless state is now tracked per business. This avoid shutting
down all businesses when the foreground service shuts down.

Business monitoring jobs are now tracked with a type.
Also restored the watcher for the system notification permissions.
Removed scope from view models, and removed ambients shorthands that
assumed non-nullability too eagerly (e.g. business). This was causing
crashes when the device was rotated, or theme changed, because the
app was expecting values to exist in some screens, but they were not
yet restored.

Also, added a dialog to setup connection options when creating or
restoring a wallet.
This business graph contains all the business dependent routes
(which are using the custom businessComposable method).

The payments view model is owned by this graph, which prevents
creating a new view model when leaving the home screen, or the
payments history screen. Instead we reuse the existing vm.
A wallet should be automatically picked and started in some cases
which do not only depends on whether there's only 1 single wallet,
or if there's a default wallet. It also depends on how the app
got into the "locked" state.

For example, if the scren/device goes to sleep, the wallet should be
automatically locked, and as soon as the screen is on again, the
wallet that was used before should be loaded again, as soon as possible.
Also fix the notices viewmodel owner, and add a short message for this
specific notification.
Also fixed deeplink for swap-in wallet.
@dpad85 dpad85 marked this pull request as ready for review September 22, 2025 14:26
@dpad85 dpad85 requested a review from robbiehanson September 22, 2025 14:26
@dpad85
Copy link
Member Author

dpad85 commented Sep 22, 2025

@robbiehanson It's unrelated to the multiple wallet change, but I've also modified the balance display in the Home screen when there is no active channels but there's funds in the swap-in and/or the final wallet. It avoids displaying a big "0 sat" balance when channels get closed, which can be scary and confusing.

Note that in the nominal case, if you have funds on LN channels, the balance display is the same as before. The on-chain balance (swap-in or final) would still be displayed below the normal balance.

image image

I've also added an explicit "Spend" button for the Final wallet in the on-chain balance dialog. From what a few users report, it was not obvious that the Final wallet section could be clicked to spend the funds.

image

@dpad85 dpad85 merged commit 6ffb375 into master Sep 26, 2025
@dpad85 dpad85 deleted the android-multiple-wallets branch September 26, 2025 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants