ACINQ / phoenix

Phoenix is a self-custodial Bitcoin wallet using Lightning to send/receive payments.
https://phoenix.acinq.co
Apache License 2.0
619 stars 93 forks source link

Support taproot addresses and rotation #516

Closed dpad85 closed 4 months ago

dpad85 commented 4 months ago

Support for taproot addresses

Phoenix now shows a taproot address by default for swap-ins (on-chain deposits to Phoenix). Taproot addresses are more private (observers won't know funds sent there are for LN channels) and are cheaper (~15% less fee, and once channels also support taproot, it could be up to 30% less expensive in total).

image

Backward compat with legacy addresses

Phoenix will still be able to swap funds sent on the legacy address, even if it's not the preferred way. User can also switch back to the legacy address for deposits from wallets/services that don't support taproot.

image image image

Address rotation

Taproot addresses are rotated, which also improves privacy besides the taproot features - see https://github.com/ACINQ/lightning-kmp/pull/584 for details.

It means that Phoenix will synchronise its view of the swap-in wallet at startup to find the last unused address, and avoid address reuse. This synchronisation can take time (dozens of seconds if many addresses), during which the UI should still display an address (for good UX).

@robbiehanson To do so, the last known unused index should be stored in the preferences, and used at startup to provide an address to the UI:

keyManager.swapInOnChainWallet.getSwapInProtocol(index).address(chain)

Then listen to Peer.swapInWallet.swapInAddressFlow and use that address at collect (which should be the same address as calculated before, unless a payment was made while the app was off).

Show used addresses

The user can check his addresses in Settings > Wallet info > Swap addresses.

image image

These addresses are exposed in Peer.swapInWallet.wallet.walletStateFlow. Note that the legacy address is contained in that flow (using a AddressMeta.Single meta).

Also, this flow only exposes the adresses that have been used, + the first unused address. It does not list other unused addresses.

dpad85 commented 4 months ago

Note that this PR will have to be rebased on kotlin 1.9.

sstone commented 4 months ago

side-note: The phoenix-legacy app cannot compute swap-in addresses for the new taproot-based protocol, but it should be easy to implement if needed:

This will make the old version of eclair-core used by the legacy app depend on kotlin 1.9 but I understand that it is not a problem as the legacy app is already using kotlin 1.9.