Merge #103: README.md and CONTRIBUTING.md
b4f6bbd8ffa722c48725fc724ca6cb1a4cf0b116 Add a README, finally. (Antoine Poinsot)
2663d970c77c7c13da8f39c3059123ef231b1787 Add a CONTRIBUTING.md (Antoine Poinsot)
f5ff0fad362a20d97d4ccc7fc5926bbfab50ec3a daemon: 'revaultd' name usage leftovers (Antoine Poinsot)
Pull request description:
Starting the documentation effort with those two main files. I'll address both a dedicated document about building the software and another dedicated document about recovering from descriptor backup in a follow-up.
ACKs for top commit:
darosior:
self-ACK b4f6bbd8ffa722c48725fc724ca6cb1a4cf0b116
Tree-SHA512: 58172527d6c09b718f9b15989fe976ceb4c20192bd8dfc7ee2cc9c683f8add19ef184869e1ab285c3d025b5ed6d69c6e9f3eaf5fc3f8e9a29ba632c0e3cae2d9
This commit is contained in:
commit
18771b62a8
75
CONTRIBUTING.md
Normal file
75
CONTRIBUTING.md
Normal file
@ -0,0 +1,75 @@
|
||||
# Contributing to Liana
|
||||
|
||||
Anyone is welcome to contribute to Liana regardless of any arbitrary criterion. Contribution are
|
||||
only judged based on their technical relevance and quality.
|
||||
|
||||
Note that the development of Bitcoin software requires a high level of rigor, so it could take some
|
||||
time (and backs and forths) to polish a contribution before it's ready for merge.
|
||||
|
||||
|
||||
## Communication
|
||||
|
||||
Most of the communication is done on GitHub or on the [`#revault` IRC channel on
|
||||
Libera](https://web.libera.chat/?channels=#revault).
|
||||
|
||||
If you plan to contribute a non-trivial change, consider discussing it in the IRC channel or in a
|
||||
Github issue before going forward with the implementation.
|
||||
|
||||
|
||||
## Looking for contributions
|
||||
|
||||
If you are looking for first time contributions, you can `git grep` for `FIXME`s and `TODO`s
|
||||
as well as checking out the [good first issues](https://github.com/revault/liana/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
|
||||
on the issue tracker.
|
||||
|
||||
|
||||
# Workflow
|
||||
|
||||
The codebase is maintained using the "contributor workflow" where everyone
|
||||
without exception contributes patch proposals using "pull requests" (PRs). This
|
||||
facilitates social contribution, easy testing and peer review.
|
||||
|
||||
In general, [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention)
|
||||
and diffs should be easy to read. For this reason, do not mix any formatting
|
||||
fixes or code moves with actual code changes.
|
||||
Make sure each individual commit is hygienic: that it builds successfully
|
||||
on its own without warnings, errors, regressions, or test failures.
|
||||
|
||||
Commit messages should be verbose by default consisting of a short subject line,
|
||||
a blank line and detailed explanatory text as separate paragraph(s), unless the
|
||||
title alone is self-explanatory. Commit messages should be helpful to people
|
||||
reading your code in the future, so explain the reasoning for your decisions. For
|
||||
more guidelines about writing commit messages, see this [blog post](https://cbea.ms/git-commit/).
|
||||
|
||||
If your pull request contains fixup commits (commits that change the same line of code repeatedly) or too fine-grained
|
||||
commits, you may be asked to [squash](https://git-scm.com/docs/git-rebase#_interactive_mode) your commits
|
||||
before it will be merged.
|
||||
|
||||
Patchsets should always be focused. For example, a pull request could add a
|
||||
feature, fix a bug, or refactor code; but not a mixture. Please also avoid super
|
||||
pull requests which attempt to do too much, are overly large, or overly complex
|
||||
as this makes review difficult. Instead, prefer opening different focused pull requests.
|
||||
|
||||
Anyone may participate in peer review which is expressed by comments in the pull
|
||||
request. Typically reviewers will review the code for obvious errors, as well as
|
||||
test out the patch set and opine on the technical merits of the patch. PR should
|
||||
be reviewed first on the conceptual level before focusing on code style or grammar
|
||||
fixes.
|
||||
|
||||
Any new contributed feature must come with tests. Preferably both an integration/functional tests
|
||||
demonstrating its usage in a blackbox manner (for instance calling an RPC command under different
|
||||
conditions), as well as unit tests exercising specific parts of the logic (for instance a database
|
||||
query).
|
||||
|
||||
|
||||
# Code
|
||||
|
||||
## Minimum Supported Rust Version
|
||||
|
||||
`minisafed` should always compile and pass tests using **Rust 1.48**.
|
||||
|
||||
## Style
|
||||
|
||||
To avoid endless bikeshedding, just use [`rustfmt`](https://github.com/rust-lang/rustfmt).
|
||||
|
||||
[Clippy](https://github.com/rust-lang/rust-clippy) is also often your friend.
|
||||
147
README.md
Normal file
147
README.md
Normal file
@ -0,0 +1,147 @@
|
||||
# Liana
|
||||
|
||||
*The missing safety net for your bitcoins*.
|
||||
|
||||
|
||||
## About
|
||||
|
||||
Liana is a simple Bitcoin wallet that features a timelocked recovery path for all your coins. That
|
||||
is, your coins are spendable as with a regular wallet but a secondary key becomes available after a
|
||||
configurable period of time should the primary one not be accessible anymore.
|
||||
|
||||
Liana can be used for inheritance, where the owner of the coins is holding the primary key and the
|
||||
heir the secondary one. It can also be leveraged for recovery where a single person is holding both
|
||||
but different tradeoffs can be made between the backup(s) of the directly accessible and timelocked
|
||||
keys.
|
||||
|
||||
Liana is still under heavy development. Apart from the regular wallet features that are planned, we
|
||||
intend to implement the possibility to have multiple keys per spending path (multisig) as well as
|
||||
multiple timelocked paths (for instance for decaying multisigs). We also intend to switch to using
|
||||
Taproot as soon as possible, for enhanced privacy.
|
||||
|
||||
**As such please consider Liana to be beta software.**
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
As a Bitcoin wallet, Liana needs to be able to connect to the Bitcoin network. The software has been
|
||||
developed such as multiple ways to connect to the Bitcoin network may be available. However for now
|
||||
only the connection through `bitcoind` is implemented.
|
||||
|
||||
Therefore in order to use Liana you need to have Bitcoin Core running on your machine for the
|
||||
desired network. The `bitcoind` installation may be pruned (note this may affect block chain
|
||||
rescans) up to the maximum (around 550MB of blocks).
|
||||
|
||||
The minimum supported version of Bitcoin Core is `24.0`. If you don't have Bitcoin Core installed on
|
||||
your machine yet, you can download it [there](https://bitcoincore.org/en/download/).
|
||||
|
||||
### Installing the software
|
||||
|
||||
TODO: download links
|
||||
|
||||
TODO: link to a longer-form document in the doc/ folder containing the different build methods.
|
||||
|
||||
### Setting up a wallet
|
||||
|
||||
If you are using the GUI, you can just start the program. It will spawn an installer that will guide
|
||||
you through the process of setting up a new wallet.
|
||||
|
||||
If you are using the daemon, you will need to specify its configuration as a TOML file. There is a
|
||||
documented example of such a configuration file in the [`contrib/` folder](contrib/lianad_config_example.toml).
|
||||
Then you can start the daemon like so:
|
||||
```
|
||||
lianad --conf /path/to/your/conf.toml
|
||||
```
|
||||
|
||||
#### The script descriptor
|
||||
|
||||
**MAKE SURE TO BACK UP YOUR DESCRIPTOR**
|
||||
|
||||
In Bitcoin, the conditions for spending a certain amount of coins are expressed using a
|
||||
[Script](https://en.bitcoin.it/wiki/Script). In order to be able to recover your coins, you need to
|
||||
back up both:
|
||||
- The Script template, in the form of a standard [Output Script
|
||||
Descriptor](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki)
|
||||
- The private key corresponding to the public key used in the Script
|
||||
|
||||
By so doing, any software that understands the Output Script Descriptor standard will be able to
|
||||
retrieve your coins. By using your private key you would then be able to sign a transaction spending
|
||||
them.
|
||||
|
||||
But **without the descriptor you won't be able to recover from your backup**. Note however it is
|
||||
simpler to have redundancy for your descriptor backup. A thief getting access to it will be able to
|
||||
learn your balance (and transaction history), but **will not be able to steal your funds**.
|
||||
Therefore you may afford a greater number of backups of your descriptor(s) and using less secure
|
||||
mediums than for storing your private key.
|
||||
|
||||
### Using a wallet
|
||||
|
||||
You can use Liana just like a regular wallet. Just be aware that if you are using a relative
|
||||
timelock (the only type of timelocks supported for now), time starts ticking when you receive a
|
||||
payment. That is if you want the recovery path to never be available, all coins must be spent
|
||||
at least once every `N` blocks. (With `N` the configured value of the timelock.)
|
||||
|
||||
For now, only the Ledger and Specter DIY signing devices are supported. We may add the possibility
|
||||
to use Liana as a "hot" wallet in the future (i.e. with a private key directly on the laptop).
|
||||
|
||||
If you are using the GUI, it should be intuitive what menu to use depending on your intention. If it
|
||||
is not, bug report are very welcome so [feel free to report it](https://github.com/revault/liana/issues)! :)
|
||||
|
||||
If you are using the daemon, you can use the `liana-cli` binary to send commands to it. It will need
|
||||
the path to the same configuration as the daemon. You can find a full documentation of the JSONRPC
|
||||
API exposed by `lianad` at [`doc/API.md`](doc/API.md). For instance:
|
||||
```
|
||||
$ liana-cli --conf ./testnet_config.toml getinfo
|
||||
{
|
||||
"result": {
|
||||
"blockheight": 2406973,
|
||||
"descriptors": {
|
||||
"main": {
|
||||
"change_desc": "wsh(or_d(pk([92162c45]tpubD6NzVbkrYhZ4WzTf9SsD6h7AH7oQEippXK2KP8qvhMMqFoNeN5YFVi7vRyeRSDGtgd2bPyMxUNmHui8t5yCgszxPPxMafu1VVzDpg9aruYW/1/*),and_v(v:pkh(tpubD6NzVbkrYhZ4Wdgu2yfdmrce5g4fiH1ZLmKhewsnNKupbi4sxjH1ZVAorkBLWSkhsjhg8kiq8C4BrBjMy3SjAKDyDdbuvUa1ToAHbiR98js/1/*),older(2))))#5rx53ql7",
|
||||
"multi_desc": "wsh(or_d(pk([92162c45]tpubD6NzVbkrYhZ4WzTf9SsD6h7AH7oQEippXK2KP8qvhMMqFoNeN5YFVi7vRyeRSDGtgd2bPyMxUNmHui8t5yCgszxPPxMafu1VVzDpg9aruYW/<0;1>/*),and_v(v:pkh(tpubD6NzVbkrYhZ4Wdgu2yfdmrce5g4fiH1ZLmKhewsnNKupbi4sxjH1ZVAorkBLWSkhsjhg8kiq8C4BrBjMy3SjAKDyDdbuvUa1ToAHbiR98js/<0;1>/*),older(2))))#uact7s3g",
|
||||
"receive_desc": "wsh(or_d(pk([92162c45]tpubD6NzVbkrYhZ4WzTf9SsD6h7AH7oQEippXK2KP8qvhMMqFoNeN5YFVi7vRyeRSDGtgd2bPyMxUNmHui8t5yCgszxPPxMafu1VVzDpg9aruYW/0/*),and_v(v:pkh(tpubD6NzVbkrYhZ4Wdgu2yfdmrce5g4fiH1ZLmKhewsnNKupbi4sxjH1ZVAorkBLWSkhsjhg8kiq8C4BrBjMy3SjAKDyDdbuvUa1ToAHbiR98js/0/*),older(2))))#d693mvvd"
|
||||
}
|
||||
},
|
||||
"network": "testnet",
|
||||
"rescan_progress": null,
|
||||
"sync": 1.0,
|
||||
"version": "0.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note also that you might connect the GUI to a running `lianad`. If the GUI detects a daemon is
|
||||
already running, it will plug to it and communicate through the JSONRPC API.
|
||||
|
||||
|
||||
### Wallet recovery
|
||||
|
||||
TODO: have a longer form document on recovery through the recovery path.
|
||||
|
||||
|
||||
## About the software project
|
||||
|
||||
Liana is an open source project. It is [hosted at Github](https://github.com/revault/liana).
|
||||
|
||||
Contributions are very welcome. For guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||
|
||||
Liana is separated in two main components: the daemon and the Graphical User Interface.
|
||||
|
||||
### Liana daemon
|
||||
|
||||
The daemon contains the core logic of the wallet. It is both a library (a Rust crate) that exposes a
|
||||
command interface and a standalone UNIX daemon that exposes a JSONRPC API through a Unix Domain
|
||||
Socket.
|
||||
|
||||
The code for the daemon can be found in the [`src/`](src/) folder at the root of this repository.
|
||||
|
||||
### Liana GUI
|
||||
|
||||
The GUI contains both an installer that guides a user through setting up a Liana wallet, as well as
|
||||
a graphical interface to the daemon using the [`iced`](https://github.com/iced-rs/iced/) library.
|
||||
|
||||
The code for the GUI can be found in the [`gui/src/`](gui/src) folder.
|
||||
|
||||
## License
|
||||
|
||||
Released under the BSD 3-Clause Licence. See the [LICENCE](LICENCE) file.
|
||||
38
contrib/lianad_config_example.toml
Normal file
38
contrib/lianad_config_example.toml
Normal file
@ -0,0 +1,38 @@
|
||||
# Whether to run the process as a UNIX daemon (double fork magic)
|
||||
daemon = false
|
||||
|
||||
# (Optional) Path to the folder where we should store the application data.
|
||||
# Defaults to `.lianad` in your home folder.
|
||||
data_dir = "/home/wizardsardine/.lianad"
|
||||
|
||||
# How verbose logging should be (one of "error", "warn", "info", "debug", "trace")
|
||||
log_level = "debug"
|
||||
|
||||
# The wallet descriptor. It must be a Segwit v0 Pay-To-Witness-Script-Hash (`wsh()`) descriptor
|
||||
# corresponding to a `or(pk(A),and(pk(B),older(X)))` policy (either public key A can spend immediately
|
||||
# or public key B can spend after X blocks).
|
||||
# The public keys must be valid extend keys ("xpubs") ending with a wildcard (i.e. can be derived
|
||||
# from). The public keys must be multipath expressions with exactly the `0` and `1` derivation indexes,
|
||||
# that is having a derivation step which is `/<0;1>` before the last step. This is in order to be able
|
||||
# to derive deposit and change addresses from the same descriptor.
|
||||
# The extended public keys must be encoded for the network the daemon is to be run (i.e. "xpub"s for the
|
||||
# main network and "tpub"s for everything else).
|
||||
#
|
||||
# YOUR DESCRIPTOR IS UNIQUE AND MUST BE BACKED UP, WITHOUT IT YOU WONT BE ABLE TO RECOVER YOUR FUNDS.
|
||||
#
|
||||
main_descriptor = "wsh(or_d(pk([92162c45]tpubD6NzVbkrYhZ4WzTf9SsD6h7AH7oQEippXK2KP8qvhMMqFoNeN5YFVi7vRyeRSDGtgd2bPyMxUNmHui8t5yCgszxPPxMafu1VVzDpg9aruYW/<0;1>/*),and_v(v:pkh(tpubD6NzVbkrYhZ4Wdgu2yfdmrce5g4fiH1ZLmKhewsnNKupbi4sxjH1ZVAorkBLWSkhsjhg8kiq8C4BrBjMy3SjAKDyDdbuvUa1ToAHbiR98js/<0;1>/*),older(2))))#uact7s3g"
|
||||
|
||||
# This section is the configuration related to the Bitcoin backend.
|
||||
# On what network shall it operate?
|
||||
# How often should it poll the Bitcoin backend for updates?
|
||||
[bitcoin_config]
|
||||
network = "testnet"
|
||||
poll_interval_secs = 30
|
||||
|
||||
# This section is specific to the bitcoind implementation of the Bitcoin backend. This is the only
|
||||
# implementation available for now.
|
||||
# In order to be able to connect to bitcoind, it needs to know on what port it is listening as well
|
||||
# as where the authentication cookie is located.
|
||||
[bitcoind_config]
|
||||
addr = "127.0.0.1:18332"
|
||||
cookie_path = "/home/wizardsardine/.bitcoin/testnet3/.cookie"
|
||||
@ -24,7 +24,7 @@ const RPC_SOCKET_TIMEOUT: u64 = 180;
|
||||
// A retry happens every 1 second, this makes us give up after one minute.
|
||||
const BITCOIND_RETRY_LIMIT: usize = 60;
|
||||
|
||||
// The minimum bitcoind version that can be used with revaultd.
|
||||
// The minimum bitcoind version that can be used with lianad.
|
||||
const MIN_BITCOIND_VERSION: u64 = 239900;
|
||||
|
||||
/// An error in the bitcoind interface.
|
||||
@ -591,7 +591,7 @@ impl BitcoinD {
|
||||
}
|
||||
|
||||
pub fn sync_progress(&self) -> f64 {
|
||||
// TODO: don't harass revaultd, be smarter like in revaultd.
|
||||
// TODO: don't harass lianad, be smarter like in revaultd.
|
||||
roundup_progress(
|
||||
self.block_chain_info()
|
||||
.get("verificationprogress")
|
||||
|
||||
@ -305,7 +305,7 @@ impl DaemonHandle {
|
||||
if config.daemon {
|
||||
log::info!("Daemonizing");
|
||||
let log_file = data_dir.as_path().join("log");
|
||||
let pid_file = data_dir.as_path().join("revaultd.pid");
|
||||
let pid_file = data_dir.as_path().join("lianad.pid");
|
||||
unsafe {
|
||||
daemonize::daemonize(&data_dir, &log_file, &pid_file)
|
||||
.map_err(StartupError::Daemonization)?;
|
||||
|
||||
@ -174,7 +174,7 @@ class UnixDomainSocketRpc(object):
|
||||
return json.loads(buff)
|
||||
except json.JSONDecodeError:
|
||||
# There is more to read, continue
|
||||
# FIXME: this is a workaround for large reads taken from revaultd.
|
||||
# FIXME: this is a workaround for large reads taken from lianad.
|
||||
# We should use the '\n' marker instead since lianad uses that.
|
||||
continue
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user