Walletwasabi: Automated send to another (hardware) wallet after CoinJoin

Created on 26 Dec 2018  Â·  10Comments  Â·  Source: zkSNACKs/WalletWasabi

Below is a suggestion for a feature improvement to Wasabi wallet (WWIP?) that aims to make repeated use more automated, and save users time and mining fees in the process.

General Assumptions

I am relying on Wasabi Wallet to anonymize the bitcoins I have purchased from exchanges before putting them for long-term storage on a hardware wallet. I believe this represents a fairly standard use case and that therefore the proposed improvement will benefit a large number of Wasabi Wallet users.

Beside mixing coins for storage, Wasabi Wallet has important coin control features, and I recognize that many users will use the software because of them. My proposal will not influence the way this other standard use case is operated.

Pain Point

Based on ~6 months of use for the purpose described above, I have identified a single major inconvenience with the way Wasabi works: after each mix is complete, I need to move all new UTXOs by hand to another wallet for long-term storage.

A user who wants to move their mixed coins needs to perform a sequence of no less than 8 manual operations for each coin join output:

I. Within receiving wallet

  1. generate new receive address
  2. copy address to clipboard
  3. switch to Wasabi

II. Within Wasabi

  1. select single mixed output
  2. select max amount BTC
  3. select fee
  4. type password by hand
  5. press 'Send Transaction' button

Considering an average coin join output size of ~0.1 BTC, a user who wants to mix the (not unreasonably high) amount of 1.0 BTC would need to repeat the above process 9-10 times (depending on whether the change from the mixing is also returned to a different wallet).

Apart from requiring time and leaving some room for error (like forgetting to issue a new address and sending two or more mixed coins to the same address), the repatriation of funds also has costs: all mix outputs are 'taxed' with an additional mining fee when the user moves them for storage. Because we want to keep these outputs separate, we can't minimize fees by batching the sends the way the outputs of the coin join mixes themselves are batched together. So we pay more fees, and occupy precious ledger space.

Proposal for Sending Coin Join Outputs to External Wallet

I propose users are given the ability to select whether they want to receive their mixed coins back in Wasabi or at address(es) that belong to a different wallet.

Here is how I imagine such a procedure would work:

I. Preparation stage

  • User extracts the master public key from their receiving wallet※
  • User enters said public key into Wasabi (More on this below).

    - Wasabi stores the master public key and address offset in a similar fashion to other details it tracks, so that future coin joins sent to same wallet do not require user to re-enter address derivation by hand.

※ This assumes a HD wallet that supports bech32 addresses. As of December 2018, Electrum and Bitcoin Core support bech32. Among the hardware wallets, BitBox supports it; and Trezor, Ledger Nano and KeepKey support it in firmware but have not yet released apps, so the master public key can't be extracted just yet. Trezor+Electrum or Ledger+Electrum works fine.

II. Usage

Upon performing coin mixing, the user is given the choice to either proceed as before (mixed coins are returned to Wasabi) or to have the new outputs delivered to bech32 addresses derived from the master public key provided previously.

Projected Outcome

The end product of such batching operation will be freshly mixed coins, safely kept in reliable long-term storage without additional effort or cost to the user.

Benefits

  • The most obvious benefit is time; the user simply needs to queue the coins for mixing and leave the rest to the software.
  • The second benefit is cost; with the coins arriving at their desired destination directly after the coin join, it is no longer necessary to pay miner fee once more to shift them.
  • The third benefit is a small additional privacy gain. Assuming many people use the wallet to move their mixed coins to another storage, it will create a recognizable heuristic — a large multi-input/multi-output transaction with many identical outputs, followed by multiple single-input/single-output transactions that then remain unspent a long time may reveal linked ownership of addresses.
  • Finally, the user is just being a good neighborâ„¢: coin joins made with intend to store will occupy less space on the ledger.

Caveats

The proposed procedure requires from users a certain level of familiarity with how address generation works, and opens room for silly mistakes (e.g. sending multiple mixed coins to the same address, which negates the purpose of the coin join).

A fully functional option to enter external master public key should also allow the user to supply an address offset in case the provided derivation path already has been used to issue addresses and these now need to be skipped. However this requires knowledge on how address derivation work and offers users a big gun with which they can shoot themselves in the foot.

Implementation (UI/UX perspective)

I believe the easiest way to implement this feature is to extend the Generate Wallet dialog with an extra field called e.g. Enter ExtPubKey to send coin join outputs to external wallet. This has the advantage that people can knowingly maintain two Wasabi wallets in parallel: one for mixing coins prior to storage, another for spending with coin control.

Alternatively, the functionality can be implemented with a radio button in the CoinJoin dialog. E.g. Send coin join outputs back / Send coin join outputs to external wallet, with a new field for ExtPubKey entry appearing when the user chooses the second option. This has the advantage that users can make coin join sends to external wallets using the Wasabi wallet they have already generated.

Implementation (program logic)

I am not a programmer and have not looked into the code, but I assume it will be fairly straightforward to implement such logic that receive and change addresses are derived from the ExtPubKey generated at wallet creation time, while coin join output addresses are derived from the 3rd part ExtPubKey.

Comments & Suggestions

I will appreciate any comments! Thank you @nopara73 and @molnard for giving us this great Bitcoin tool.

featurenhancement questioresearch waiting for dependency

Most helpful comment

By the way concept ACK, but implementation NACK. If we want to support extpubkey send (including extpubkey mix) then we must support it properly and not do a half job, like only support bech32 extpubkey send.

All 10 comments

This assumes a HD wallet that supports bech32 addresse

It's a huge hack.

Wasabi cannot figure out which addresses hold money in the extpubkey.
That being said, I can see many workarounds, but all smells like a hack:

  1. Don't care about if there's already money there.
  2. Try to very slowly explore with backend requests the last address that still has money.
  3. Only spend to bech32 address chain.
  4. Let the user to tell manually which address has money on it already.
  5. etc...

For context: https://github.com/zkSNACKs/Meta#wasabi-wallet-under-the-hood

That being said, Wasabi's bech32 reliance should be somehow fixed in the future, because it is not a scaleable solution. It'll only take for a few years until the wallet slows down considerably.

By the way I'm very interested in send to extpubkey, I'm just not sure how it should be implemented yet, what is the most acceptable compromise, because there must be one.

A first step could be just to feed the tumbling with addresses to be the mix output. That's actually implemented today on the backend, but it'd add a bunch of complexity, so its place is on a tab called "Advanced CoinJoin" which is not yet created.

By the way concept ACK, but implementation NACK. If we want to support extpubkey send (including extpubkey mix) then we must support it properly and not do a half job, like only support bech32 extpubkey send.

Indicating reliance on bech32 as a prerequisite stems from my assumption that it was necessary for Wasabi to operate properly. I was just trying to pitch my idea too hard :)

Of course things would make best sense if all sorts of pubkey formats (XPUB, YPUB, ZPUB...) are supported.

Regarding this:

Wasabi cannot figure out which addresses hold money in the extpubkey.

I probably misunderstand the comment, but is it Wasabi's job to do that? Using a mixing service implies users know what they're doing and that they implicitly understand the importance of not reusing addresses.

Also, while I was writing this proposal, I was thinking at all times about the 'Multiple Accounts' feature which is prominently present in the interface of both the Trezor and Ledger Nano S hardware wallets. Creating a new account for mixed coins is something that can be explained very easily in a 500 word, 5 picture medium.com article — benefits, setup and everything — and it would cover probably 98% of potential use cases.

Getting a 'fresh' ExtPubKey guarantees no address reuse to begin with, and for future mixes the users will just keep drawing new addresses from there. Doing things this way (always starting with an unused ExtPubKey) could be the 'supported method' for this Wasabi feature.

Anyway: very happy to hear you ACK the concept, I hope we will have a working solution soon. I have little ability to contribute with coding but I could help with prototype testing or documentation if needed.

Indicating reliance on bech32 as a prerequisite stems from my assumption that it was necessary for Wasabi to operate properly. I was just trying to pitch my idea too hard :)

Yes, I realized, however outputs are non-issues, they can be anything, even an op-return:) Only inputs must be bech32. Well, they could even be p2sh segwit, but that's not implemented yet, mainly due to the blockchain scanning method we are using.

Generally I understand what you are saying and I agree that your suggestions would work. It's just they are not universal, they only apply to limited scenarios with a bunch of "if", that's why I classify them as hacks.

To illustrate a similar scenario where we got it wrong is that I didn't really want to build a wallet where seeds can be imported to other wallets and from other wallets, because of privacy reasons and because we must use more keys than other wallets. Yet we thought "oh well, we can do a "BIP84-like" design, so why not? Well, because people will consider it to be BIP84 and they will want to abuse it. And indeed it is happening and a bunch of questions and issues come up because of it. We should've built traditional BIP84 or something completely different, choosing a solution in the middle that covers 98% of BIP84 use cases has created more issues than the feature's usefulness.
The exact same thing happens, because we let users to use their own Tor instance. It creates more friction than the usefulness of this feature justifies.
(Of course we cannot back out any of these anymore.)
So I just don't want this to happen to a pay-2-extpubkey scheme, too.

users know what they're doing and that they implicitly understand the importance of not reusing addresses.

You'd be surprised:)

I could help with prototype testing or documentation if needed.

Again, I'm not convinced yet there was any sufficiently non-hacky way brought up to do this, but maybe I'm not thinking hard enough.
For example a fine way could be if we would do a scheme like:

  1. Take the suggested gap limit of BIP44 (or user supplied one.)
  2. During 24h the wallet slowly asks for addresses from the backend if there's money on them with different Tor identities as follows: ask backend for gap limit/2 address: does it have money on it? if yes then try with gap limit/2 * 1.5, if no then try gap limit/4 and so on until we find the first unused address and from that address we consider all the addresses unused, thus we could start pushing money to them from the mix.

Finally there's also the question of what happens if non-bech32 keys are used. Is this too much of a privacy risk? If the there are too few users doing this they may well stand out of the crowd and will be deanonymized.
Of course this only applies to mixes, not to sends.

A slightly less automated approach, and _slightly_ different to OP (sorry @drkskwlkr):

Would it be acceptable to be able to select e.g. 5 Zerolink Mixed Coin Outputs, and then provide Wasabi with 5 receive addresses In one go), and let Wasabi handle sending each Mixed Coin to to each address with the requested fee?

This would have the advantage that that OP's 9-10 steps need only be done once per batch send (although each tx is obviously still sent separately) and seems like it would be significantly easier to implement.

Wasabi could also use some anonymising method regarding the tx broadcast times so that they are not all correlated as being broadcast at the same instant.

For now, this seems to be the plan:

  1. Wasabi should load and watch all the wallets the same time.
  2. Wasabi should be able to send to another Wasabi wallet on the same computer with merge avoidance or PayJoin.
  3. Wasabi should be able to mix to another Wasabi wallet on the same computer.
  4. Wasabi should integrate hardware wallets with coinjoin disabled.

This is now possible since v1.1.11 using the Daemon. https://docs.wasabiwallet.io/using-wasabi/ColdWasabi.html#mix-to-another-wallet
But since it is not in the GUI yet so we can keep this issue open.

Yes, I agree we have to let's keep the issue open as it's not resolved only for power users (and there's a bug btw that it stops mixing before it should stop.) Anyhow, this is waiting for dependency, which is WabiSabi. In fact @yahiheb most if not all coinjoin feature requests should be made waiting for dependency.

Was this page helpful?
0 / 5 - 0 ratings