bitcoindevkit / bdk

A modern, lightweight, descriptor-based wallet library written in Rust!
Other
857 stars 307 forks source link

Cloud backup solution for BDK #484

Open rajarshimaitra opened 2 years ago

rajarshimaitra commented 2 years ago

Description

BDK is a descriptor based wallet. To regenerate and already existing wallet, the wallet descriptor (public key descriptor for watch only wallet) needs to be imported in BDK. Currently BDK uses local file storage to store the descriptor and other wallet related data. For mobile devices its better to create encrypted descriptor backups and store them in some cloud storage platform like google drive etc. This project’s aim is to create a native cloud storage solution with password based encryption within the BDK library itself. **Expected Outcomes**

Resources

There are few existing cloud storage frameworks available that can be used directly or used as a reference to write a custom framework. - https://github.com/synonymdev/backpack-host - https://github.com/BlueWallet/bytes-store - https://github.com/photon-sdk/photon-keyserver **Skills Required**

Mentor(s)

Difficulty : Medium

Competency Test (optional)

LLFourn commented 2 years ago

Description

BDK is a descriptor based wallet. To regenerate and already existing wallet, the wallet descriptor (public key descriptor for watch only wallet) needs to be imported in BDK. Currently BDK uses local file storage to store the descriptor and other wallet related data.

I don't think we actually store the descriptor anywhere?

rajarshimaitra commented 2 years ago

I don't think we actually store the descriptor anywhere?

Probably true, though I have to check what exactly is there in the DB. But in case of backing up in cloud, do we need only the seed, or the full descriptor itself? In our local DB we store all the required data to regenerate the addresses. But in cloud we won't be able to store that much, so my thinking was putting the descriptor there from which to regenerate the wallet would be the way to go. Open to more suggestions.

PS: This project proposals are still in draft and can be modified as required. Thus posted as issues for further discussions.

afilini commented 2 years ago

Yeah, the descriptor isn't stored anywhere at the moment, the rationale behind it is that it's very hard to "do it right" in a way that works and is safe on every platform, because there are very different requirements (i.e. on mobile you have a system keychain generally, on desktop every app runs as the same user, so you should encrypt the file manually etc).

But at this point with the library becoming more mature I think it makes sense to also start getting into this, ideally again in a separate package to avoid adding too much stuff here (bdk-keychain maybe?).

Some of the "keychains" i have in mind are:

rajarshimaitra commented 2 years ago

Makes sense. Do you think the first step should be to implement the keychain then go for cloud storage backup? Or this things can be done independently? Whatever is the descriptor storage scheme we come up with, we would need some generic cloud stuffs anyway I think?

afilini commented 2 years ago

For "keychain" i just mean something that can store secrets, it doesn't have to be anything fancy.

We should already have everything we need within bdk, there's this trait that can be implemented on a struct and it makes it usable as a wallet descriptor: https://docs.rs/bdk/latest/bdk/descriptor/trait.IntoWalletDescriptor.html

Different "keychains" could have different flows. For example, the way I would implement the simple "encrypted file" keychain would be by having two structs EncryptedFile and UnlockedEncryptedFile. The former has a method to "unlock" the keychain, and if the passphrase is correct it returns an instance of the latter, which implements IntoWalletDescriptor.

So in the end you can do:

let encrypted_descriptor = EncryptedFile::load(path)?;
let wallet = Wallet::new(encrypted_descriptor.unlock(password)?, ....)?;

Alternatively if we don't want to have two types we could have one with a phantom data generic, like EncryptedFile<Locked> and EncryptedFile<Unlocked>.

The same should be done for every keychain type, probably with the exception of the plaintext file because there's nothing to unlock, you can just load it and use it.

I'm not sure which one is the best to start with. I guess it also depends on the kind of demand we have. The plaintext/encrypted file storage should be pretty easy, then the cloud storage and mobile biometrics keychain are more complex, I'm not sure which one has more priority.

rajarshimaitra commented 2 years ago

I think if the students can get up to "create plaintext wallet file and store it up on the cloud" that can be a good milestone. Though not entirely complete, we can then extend it up to encrypted file and mobile storage stuffs later.

afilini commented 2 years ago

I wouldn't ask the students to implement what you've described because realistically it would never be used, it would be too dangerous (and I don't think it's that satisfying to work on something that you know will probably never be used). I would say some more realistic and probably challenging options are:

  1. Write the general structure for generic keychains (all the traits/structs etc) and implement a very simple one, like a plaintext local file as a "demo". Implement more complex one if there's time (like the encrypted file)
  2. Implement photon or a different cloud storage mechanism in rust, and if there's time also try to integrate it in bdk by implementing (1), otherwise we will do that ourselves
  3. Implement the mobile keychain thing in rust and again if there's time also implement (1) to integrate it in bdk, otherwise we will do it later

I think all three should be more or less equally challenging, and it could be up to the individual student to pick the one that aligns with his personal interest better.

  1. Is just pure rust, but it requires designing an API which is not trivial and needs some care and forward-thinking
  2. This is more "cryptographically-heavy" code, still pure rust
  3. This involves working with mobile native sdks, either android or ios (or both if there's time). Less rust and more cross-platform integration

All three sub-tasks are very useful for us, especially if the student(s) decide to keep working on them even after the SoB is done

notmandatory commented 2 years ago

I confirmed with @rajarshimaitra and we're removing this as a SoB project. Maybe we can adapt this into a new issue based on above comments.