|
1 | 1 | # `payjoin-cli` |
2 | 2 |
|
3 | | -## A command-line payjoin client for bitcoind in Rust |
| 3 | +## A command-line payjoin client for [Bitcoin Core](https://github.com/bitcoin/bitcoin?tab=readme-ov-file) in Rust. |
4 | 4 |
|
5 | | -The `payjoin-cli` client enables sending and receiving of [BIP 78 Payjoin V1](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki) and [Draft BIP Payjoin V2](https://github.com/bitcoin/bips/pull/1483) transactions. By default it supports Payjoin V1, and the `v2` feature sends and receives both since the protocol is backwards compatible. The implementation is built on [Payjoin Dev Kit](https://payjoindevkit.org). |
| 5 | +`payjoin-cli` is the reference implementation for the payjoin protocol, written using the [Payjoin Dev Kit](https://payjoindevkit.org). |
| 6 | + |
| 7 | +It enables sending and receiving [BIP 78 Payjoin |
| 8 | +(v1)](https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki) and [Draft |
| 9 | +BIP 77 Async Payjoin (v2)](https://github.com/bitcoin/bips/pull/1483) |
| 10 | +transactions via `bitcoind`. By default it supports Payjoin v2, which is |
| 11 | +backwards compatible with v1. Enable the `v1` feature to disable Payjoin v2 to |
| 12 | +send and receive using only v1. |
| 13 | + |
| 14 | +While this code and design have had significant testing, it is still alpha-quality experimental software. Use at your own risk. |
6 | 15 |
|
7 | | -While this code and design has had significant testing, it is still alpha-quality experimental software. Use at your own risk. |
8 | 16 | Independent audit is welcome. |
9 | 17 |
|
10 | | -## Install `payjoin-cli` |
| 18 | +## Quick Start |
11 | 19 |
|
12 | | -```console |
13 | | -cargo install payjoin-cli --version $VERSION |
14 | | -``` |
| 20 | +Here's a minimal payjoin example using `payjoin-cli` with the `v2` feature connected to `bitcoind` on [regtest](https://developer.bitcoin.org/examples/testing.html#regtest-mode). This example uses [`nigiri`](https://github.com/vulpemventures/nigiri) to setup a regtest environment. |
15 | 21 |
|
16 | | -where `$VERSION` is the [latest version](https://crates.io/crates/payjoin-cli) of the `payjoin-cli` you wish to install. |
| 22 | +Payjoin `v2` allows for transactions to be completed asynchronously. Thus the sender and receiver do not need to be online at the same time to payjoin. Learn more about how `v2` works [here](https://payjoin.org/docs/how-it-works/payjoin-v2-bip-77). |
17 | 23 |
|
18 | | -Get a list of commands and options: |
| 24 | +To get started, install `nigiri`. Payjoin requires the sender and receiver each to have spendable [UTXOs](https://www.unchained.com/blog/what-is-a-utxo-bitcoin), so we'll create two wallets and fund each. |
19 | 25 |
|
20 | | -```console |
21 | | -payjoin-cli --help |
| 26 | +```sh |
| 27 | +cargo install nigiri |
| 28 | + |
| 29 | +nigiri rpc createwallet "sender" |
| 30 | +nigiri rpc createwallet "receiver" |
| 31 | + |
| 32 | +# We need 101 blocks for the UTXOs to be spendable due to the coinbase maturity requirement. |
| 33 | +nigiri rpc generatetoaddress $(nigiri rpc getnewaddress "sender") 101 |
| 34 | +nigiri rpc generatetoaddress $(nigiri rpc getnewaddress "receiver") 101 |
22 | 35 | ``` |
23 | 36 |
|
24 | | -Either pass config options from cli, or manually edit a `config.toml` file within directory you run `payjoin-cli` from. |
25 | | -Configure it like so: |
| 37 | +Great! Our wallets are setup, now let's do an async payjoin. |
26 | 38 |
|
27 | | -```toml |
28 | | -# config.toml |
29 | | -bitcoind_cookie = "/tmp/regtest1/bitcoind/regtest/.cookie" |
30 | | -# specify your wallet via rpchost connection string |
31 | | -bitcoind_rpchost = "http://localhost:18443/wallet/boom" |
32 | | - ``` |
| 39 | +### Install `payjoin-cli` |
33 | 40 |
|
34 | | -Your configuration details will vary, but you may use this as a template. |
| 41 | +```sh |
| 42 | +cargo install payjoin-cli --version $VERSION |
| 43 | +``` |
35 | 44 |
|
36 | | -## Test Payjoin 2 |
| 45 | +where `$VERSION` is the [latest version](https://crates.io/crates/payjoin-cli). |
37 | 46 |
|
38 | | -### Install `payjoin-cli` with the V2 feature |
| 47 | +Next, create a directory for the sender & receiver and create a `config.toml` file for each: |
39 | 48 |
|
40 | | -```console |
41 | | -cargo install payjoin-cli --version $VERSION --features v2 |
| 49 | +```sh |
| 50 | +mkdir sender receiver |
| 51 | +touch sender/config.toml receiver/config.toml |
42 | 52 | ``` |
43 | 53 |
|
44 | | -### V2 Configuration |
| 54 | +Edit the `config.toml` files. Note that the `v2` feature requires a payjoin directory server and OHTTP relay. |
45 | 55 |
|
46 | | -In addition to the rpc configuration above, specify relevant ohttp and payjoin directory configuration as follows: |
| 56 | +```toml |
| 57 | +# sender/config.toml |
| 58 | + |
| 59 | +# Nigiri uses the following RPC credentials |
| 60 | +[bitcoind] |
| 61 | +rpcuser = "admin1" |
| 62 | +rpcpassword = "123" |
| 63 | +rpchost = "http://localhost:18443/wallet/sender" |
| 64 | + |
| 65 | +# For v2, our config also requires a payjoin directory server and OHTTP relay |
| 66 | +[v2] |
| 67 | +pj_directory = "https://payjo.in" |
| 68 | +ohttp_relay = "https://pj.bobspacebkk.com" |
| 69 | +``` |
47 | 70 |
|
48 | 71 | ```toml |
49 | | -# config.toml |
50 | | -... |
51 | | -# a production payjoin directory server |
52 | | -pj_directory="https://payjo.in" |
53 | | -# payjo.in's ohttp_keys can now be fetched rather than configured ahead of time |
54 | | - # an ohttp relay with ingress to payjo.in |
55 | | -ohttp_relay="https://pj.bobspacebkk.com" |
| 72 | +# receiver/config.toml |
| 73 | + |
| 74 | +# Nigiri uses the following RPC credentials |
| 75 | +[bitcoind] |
| 76 | +rpcuser = "admin1" |
| 77 | +rpcpassword = "123" |
| 78 | +rpchost = "http://localhost:18443/wallet/receiver" |
| 79 | + |
| 80 | +# For v2, our config also requires a payjoin directory server and OHTTP relay |
| 81 | +[v2] |
| 82 | +pj_directory = "https://payjo.in" |
| 83 | +ohttp_relay = "https://pj.bobspacebkk.com" |
56 | 84 | ``` |
57 | 85 |
|
58 | | -### Asynchronous Operation |
| 86 | +Now, the receiver must generate an address to receive the payment. The format is: |
| 87 | + |
| 88 | +```sh |
| 89 | +payjoin-cli receive <AMOUNT_SATS> |
| 90 | +``` |
59 | 91 |
|
60 | | -Send and receiver state is saved to a database in the directory from which `payjoin-cli` is run. Once a send or receive session is started, it may resume using the `resume` argument if prior payjoin sessions have not yet complete. |
| 92 | +For example, to receive 10000 sats from our top-level directory: |
61 | 93 |
|
62 | | -```console |
63 | | -payjoin-cli resume |
| 94 | +```sh |
| 95 | +receiver/payjoin-cli receive 10000 |
64 | 96 | ``` |
65 | 97 |
|
66 | | -## Manual End to End Regtest Testing |
| 98 | +This will output a [bitcoin URI](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki) containing the receiver's address, amount, payjoin directory, and other session information the client needs. For example: |
| 99 | + |
| 100 | +```sh |
| 101 | +bitcoin:tb1qfttmt4z68cfyn2z25t3dusp03rq6gxrucfxs5a?amount=0.0001&pj=HTTPS://PAYJO.IN/EUQKYLU92GC6U%23RK1QFWVXS2LQ2VD4T6DUMQ0F4RZQ5NL9GM0EFWVHJZ9L796L20Z7SL3J+OH1QYP87E2AVMDKXDTU6R25WCPQ5ZUF02XHNPA65JMD8ZA2W4YRQN6UUWG+EX10T57UE``` |
67 | 102 |
|
68 | | -### Test Receive |
| 103 | +Note that the session can be paused by pressing `Ctrl+C`. The receiver can come back online and resume the session by running `payjoin-cli resume` again, and the sender may do a `send` against it while the receiver is offline. |
69 | 104 |
|
70 | | -Set up 2 local regtest wallets and fund them. This example uses "boom" and "ocean" |
| 105 | +### Send a Payjoin |
71 | 106 |
|
72 | | -Determine the RPC port specified in your bitcoind's `bitcoin.conf` |
73 | | -file. 18443 is the default. This can be set like so: |
| 107 | +Now, let's send the payjoin. Here is an example format: |
74 | 108 |
|
75 | | -```conf |
76 | | -rpcport = 18443 |
| 109 | +```sh |
| 110 | +payjoin-cli send <BIP21> --fee-rate <FEE_SAT_PER_VB> |
77 | 111 | ``` |
78 | 112 |
|
79 | | -From the directory you'll run `payjoin-cli`, assuming "boom" is the name of the receiving wallet, 18443 is the rpc port, and you wish to request 10,000 sats run: |
| 113 | +Where `<BIP21>` is the BIP21 URL containing the receiver's address, amount, payjoin directory, and OHTTP relay. Using the example from above: |
80 | 114 |
|
81 | | -```console |
82 | | -RUST_LOG=debug cargo run --features=_danger-local-https -- -r "http://localhost:18443/wallet/boom" receive 10000 |
| 115 | +```sh |
| 116 | +sender/payjoin-cli send "bitcoin:tb1qfttmt4z68cfyn2z25t3dusp03rq6gxrucfxs5a?amount=0.0001&pj=HTTPS://PAYJO.IN/EUQKYLU92GC6U%23RK1QFWVXS2LQ2VD4T6DUMQ0F4RZQ5NL9GM0EFWVHJZ9L796L20Z7SL3J+OH1QYP87E2AVMDKXDTU6R25WCPQ5ZUF02XHNPA65JMD8ZA2W4YRQN6UUWG+EX10T57UE" --fee-rate 1 |
83 | 117 | ``` |
84 | 118 |
|
85 | | -The default configuration listens for payjoin requests at `http://localhost:3000` and expects you to relay https requests there. |
86 | | -Payjoin requires a secure endpoint, either https and .onion are valid. In order to receive payjoin in a local testing environment one may enable the `_danger-local-https` feature which will provision a self-signed certificate and host the `https://localhost:3000` endpoint. Emphasis on HTTP**S**. |
| 119 | +Congratulations! You've completed a version 2 payjoin, which can be used for cheaper, more efficient, and more private on-chain payments. Additionally, because we're using `v2`, the sender and receiver don't need to be online at the same time to do the payjoin. |
87 | 120 |
|
88 | | -This will generate a payjoin capable bip21 URI with which to accept payjoin: |
| 121 | +## Configuration |
89 | 122 |
|
90 | | -```console |
91 | | -BITCOIN:BCRT1QCJ4X75DUNY4X5NAWLM3CR8MALM9YAUYWWEWKWL?amount=0.00010&pj=https://localhost:3000 |
92 | | -``` |
| 123 | +Config options can be passed from the command line, or manually edited in a `config.toml` file within the directory you run `payjoin-cli` from. |
93 | 124 |
|
94 | | -### Test Send |
| 125 | +see the |
| 126 | +[example.config.toml](https://github.com/payjoin/rust-payjoin/blob/fde867b93ede767c9a50913432a73782a94ef40b/payjoin-cli/example.config.toml) |
| 127 | +for inspiration. |
95 | 128 |
|
96 | | -Create a "sender" directory within `payjoin-cli`. Open a new terminal window and navigate to this directory. |
97 | 129 |
|
98 | | -Note: A wallet cannot payjoin with itself, one needs separate wallets. |
| 130 | +### Asynchronous Operation |
| 131 | +
|
| 132 | +Sender and receiver state is saved to a database in the directory from which `payjoin-cli` is run, called `payjoin.sled`. Once a send or receive session is started, it may resume using the `resume` argument if prior payjoin sessions have not yet complete. |
99 | 133 |
|
100 | | -Create another `config.toml` file in the directory the sender will run from and configure it as you did previously, except replace the receiver wallet name with the sender |
| 134 | +## Usage |
101 | 135 |
|
102 | | -Using the previously generated bip21 URI, run the following command |
103 | | -from the sender directory: |
| 136 | +Get a list of commands and options: |
104 | 137 |
|
105 | | -```console |
106 | | - RUST_LOG=debug cargo run --features=_danger-local-https -- send <BIP21> --fee-rate <FEE_SAT_PER_VB> |
| 138 | +```sh |
| 139 | +payjoin-cli --help |
107 | 140 | ``` |
108 | 141 |
|
109 | | -You should see the payjoin transaction occur and be able to verify the Partially Signed Bitcoin Transaction (PSBT), inputs, and Unspent Transaction Outputs (UTXOs). |
| 142 | +or with a subcommand e.g. |
110 | 143 |
|
111 | | -Congrats, you've payjoined! |
| 144 | +```sh |
| 145 | +payjoin-cli send --help |
| 146 | +``` |
0 commit comments