|
| 1 | +--- |
| 2 | +title: "Command Line introduction to Bitcoin Wallet Development using bdk-cli" |
| 3 | +description: "Intro to bdk-cli and wallet dev" |
| 4 | +authors: |
| 5 | + - waterst0ne |
| 6 | +date: "2022-09-22" |
| 7 | +tags: ["bdk-cli", "basics", "novice"] |
| 8 | +--- |
| 9 | +## Tutorial Goals |
| 10 | +- The goal for this tutorial is to introduce you to [bdk-cli](https://github.com/bitcoindevkit/bdk-cli), a powerful command-line program. You will be exposed to many of the basic skills that go into creating and managing bitcoin wallets. |
| 11 | +- If you've read most of the ["Mastering Bitcoin"](https://github.com/bitcoinbook/bitcoinbook) book, this tutorial could serve as a stepping stone into your Bitcoin wallet development journey. |
| 12 | + |
| 13 | +- This short tutorial will expose you to the [`bdk library` ](https://docs.rs/bdk/latest/bdk/) and the practical knowledge needed for bitcoin wallet development. As a consequence you will deepen your technical understanding about bitcoin and the bdk library. |
| 14 | + |
| 15 | +- BDK also has [language-bindings](https://github.com/bitcoindevkit/bdk-ffi) for **Kotlin/Java, Swift, Python** which enable the use of BDK's **Rust** library as an API. You can later use these similar steps to create your own bitcoin mobile, desktop or even WebApp by using the bdk-ffi language bindings. |
| 16 | + |
| 17 | +*** |
| 18 | + |
| 19 | +## A few things before you begin: |
| 20 | + |
| 21 | +- Three things to look out for in each step of the tutorial: |
| 22 | + - 1) :arrow_forward: / :large_orange_diamond: - Commands for the Terminal or Shell |
| 23 | + - 2) :+1: - Preview of the command output. Note, not all commands will output code. |
| 24 | + - 3) Preview Video of the tutorial for reference of what things should look like in action. |
| 25 | + |
| 26 | +*** |
| 27 | +### Outline of Tutorial and Installation notes: |
| 28 | + |
| 29 | +### Brief Outline of Tutorial |
| 30 | +- Step 1: Creating a mnemonic word list + XPRV (Extended Private Key) |
| 31 | +- Step 2: Generate testnet Receive Address |
| 32 | +- Step 3: Send funds to newly generated address |
| 33 | +- Step 4: Sync Wallet |
| 34 | +- Step 5: Check Balance of Wallet |
| 35 | +- Step 6: Create a Transaction (PSBT) |
| 36 | +- Step 7: Sign the Transaction (PSBT) |
| 37 | +- Step 8: Broadcast Transaction |
| 38 | + |
| 39 | +*** |
| 40 | +### Rust and Cargo installation: |
| 41 | +- [Rust and Cargo Installation](https://rustup.rs/) |
| 42 | + |
| 43 | +*** |
| 44 | +### `bdk-cli` installation: |
| 45 | +- Download the [`bdk-cli` github repository locally](https://github.com/bitcoindevkit/bdk-cli.git) |
| 46 | + - Enter the folder `cd bdk-cli` |
| 47 | + - Install `cargo install --path . --features electrum,repl,compiler ` |
| 48 | + - Once installation is done exit and reopen your terminal (command-line interface) |
| 49 | + |
| 50 | +### Emoji Legend: |
| 51 | + |
| 52 | +:arrow_forward: : Unix/Linux Commands to copied and pasted |
| 53 | +:large_orange_diamond: : Windows Powershell Commands to copied and pasted |
| 54 | +:+1: : Output/ preview of code |
| 55 | + |
| 56 | +*** |
| 57 | +## Step 0: Check Version of bdk-cli |
| 58 | +:arrow_forward: / :large_orange_diamond: `bdk-cli -V` |
| 59 | +:+1: The output below confirms the command was successful. |
| 60 | +``` |
| 61 | +bdk-cli 0.6.0 |
| 62 | +``` |
| 63 | + |
| 64 | + |
| 65 | + |
| 66 | + |
| 67 | +### Preview of bdk-cli help menu |
| 68 | +:arrow_forward: / :large_orange_diamond: `bdk-cli --help` |
| 69 | +:+1: The output below confirms the command was successful. |
| 70 | + |
| 71 | +```shell |
| 72 | +The BDK Command Line Wallet App |
| 73 | + |
| 74 | +bdk-cli is a light weight command line bitcoin wallet, powered by BDK. This app can be used as a playground as well as |
| 75 | +testing environment to simulate various wallet testing situations. If you are planning to use BDK in your wallet, bdk- |
| 76 | +cli is also a great intro tool to get familiar with the BDK API. |
| 77 | + |
| 78 | +But this is not just any toy. bdk-cli is also a fully functioning bitcoin wallet with taproot support! |
| 79 | + |
| 80 | +For more information checkout <https://bitcoindevkit.org/> |
| 81 | + |
| 82 | +USAGE: |
| 83 | + bdk-cli [OPTIONS] <SUBCOMMAND> |
| 84 | + |
| 85 | +FLAGS: |
| 86 | + -h, --help Prints help information |
| 87 | + -V, --version Prints version information |
| 88 | + |
| 89 | +OPTIONS: |
| 90 | + -d, --datadir <DATADIR> Sets the wallet data directory. Default value : "~/.bdk-bitcoin |
| 91 | + -n, --network <NETWORK> Sets the network [default: testnet] [possible values: bitcoin, testnet, signet, regtest] |
| 92 | +
|
| 93 | +SUBCOMMANDS: |
| 94 | + compile Compile a miniscript policy to an output descriptor |
| 95 | + help Prints this message or the help of the given subcommand(s) |
| 96 | + key Subcommands for Key operations |
| 97 | + repl Options to configure a SOCKS5 proxy for a blockchain client connection |
| 98 | + wallet Wallet subcommands that can be issued without a blockchain backend |
| 99 | +``` |
| 100 | + --- |
| 101 | + |
| 102 | +## Step 1: Seed Generate |
| 103 | +
|
| 104 | +### 1a: Mnemonic word-list + XPRV (Exteneded Private Key) :key: |
| 105 | +
|
| 106 | +Linux/Terminal: |
| 107 | +:arrow_forward: `bdk-cli key generate | tee key.json` |
| 108 | +
|
| 109 | +Windows Powershell: |
| 110 | +:large_orange_diamond: `bdk-cli key generate | Out-File -FilePath "key.json"` |
| 111 | + |
| 112 | +```shell |
| 113 | +{ |
| 114 | + "fingerprint": "42b15d2f", |
| 115 | + "mnemonic": "party salon worth satoshi envelope suggest garlic dry add pitch throw clap keen narrow antique oyster ketchup purchase gasp visual work venue fog crater", |
| 116 | + "xprv": "tprv8ZgxMBicQKsPdwpamtjqMFpYRTafnE1bN2SphLEybCtRKakk6S1TgQCsZgiBwJuJNWe3jYdgVCTsKf9weMxj6tW4zNNKWptykszJpS2L8wE" |
| 117 | +} |
| 118 | +``` |
| 119 | +
|
| 120 | + |
| 121 | +
|
| 122 | +*** |
| 123 | +### 1b: Save XPRV (Extended Private Key) into environment variable |
| 124 | +Linux/Terminal: |
| 125 | +:arrow_forward: `export XPRV_00=$(cat key.json | jq -r .xprv)` |
| 126 | +
|
| 127 | +Windows Powershell: |
| 128 | +
|
| 129 | +:large_orange_diamond: `$json = Get-Content -Path .\key.json | ConvertFrom-Json` |
| 130 | +
|
| 131 | +:large_orange_diamond: `$mykeyValue = $json.xprv` |
| 132 | +
|
| 133 | +:large_orange_diamond: `[System.Environment]::SetEnvironmentVariable('XPRV',$mykeyValue, 'Process')` |
| 134 | +
|
| 135 | + |
| 136 | +
|
| 137 | +*** |
| 138 | +### 1c: Verify environment variable XPRV_00 is active |
| 139 | +Linux/Terminal: |
| 140 | +:arrow_forward: `env | grep XPRV` |
| 141 | +
|
| 142 | +Windows Powershell: |
| 143 | +:large_orange_diamond: `$env:XPRV` |
| 144 | +
|
| 145 | + |
| 146 | +
|
| 147 | +*** |
| 148 | +### 1d: Create Descriptor and Save into environment variable |
| 149 | +
|
| 150 | +Linux/Terminal: |
| 151 | +:arrow_forward: `export my_descriptor="wpkh($XPRV_00/84h/1h/0h/0/*)"` |
| 152 | +
|
| 153 | +Windows Powershell: |
| 154 | +:large_orange_diamond: `[System.Environment]::SetEnvironmentVariable('my_descriptor', "wpkh($env:XPRV/84h/1h/0h/0/*)", 'Process')` |
| 155 | +
|
| 156 | +
|
| 157 | +
|
| 158 | + |
| 159 | +
|
| 160 | +*** |
| 161 | +### 1e: Verify environment variable my_descriptor is active |
| 162 | +
|
| 163 | +Linux/Terminal: |
| 164 | +:arrow_forward: `env | grep my_descriptor` |
| 165 | +
|
| 166 | +Windows Powershell: |
| 167 | +:large_orange_diamond: `$env:my_descriptor ` |
| 168 | +
|
| 169 | + |
| 170 | +
|
| 171 | +
|
| 172 | +
|
| 173 | +*** |
| 174 | +## Step 2: Generate Receive-Address |
| 175 | +Linux/Terminal: |
| 176 | +
|
| 177 | +:arrow_forward: `bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_new_address` |
| 178 | +
|
| 179 | +Windows Powershell: |
| 180 | +:large_orange_diamond:`bdk-cli wallet --descriptor $env:my_descriptor get_new_address` |
| 181 | +
|
| 182 | +
|
| 183 | +
|
| 184 | + |
| 185 | +
|
| 186 | +
|
| 187 | +
|
| 188 | +:+1: The output below confirms the command was successful. |
| 189 | +
|
| 190 | +```shell |
| 191 | +{ |
| 192 | + "address": "tb1qrh4sq5va0unqtxyfv8al9lz3sna3988cj59uya" |
| 193 | +} |
| 194 | +``` |
| 195 | +
|
| 196 | +*** |
| 197 | +## Step 3: Send testnet bitcoin to the newly created receive-address |
| 198 | +Use a faucet to send funds to your newly created address. Here is a link to one: [Bitcoin Testnet Faucet](https://bitcoinfaucet.uo1.net) |
| 199 | +
|
| 200 | +*** |
| 201 | +## Step 4: Sync the wallet |
| 202 | +Linux/Terminal: |
| 203 | +:arrow_forward: ```bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sync``` |
| 204 | +
|
| 205 | +Windows Powershell: |
| 206 | +:large_orange_diamond: ``` bdk-cli wallet --descriptor $env:my_descriptor sync``` |
| 207 | +
|
| 208 | +
|
| 209 | +:+1: The output below confirms the command was successful. |
| 210 | +
|
| 211 | +```shell |
| 212 | +{} |
| 213 | +``` |
| 214 | +
|
| 215 | + |
| 216 | +
|
| 217 | +*** |
| 218 | +## Step 5: Check the balance |
| 219 | +
|
| 220 | +Linux/Terminal: |
| 221 | +:arrow_forward: `bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor get_balance ` |
| 222 | +
|
| 223 | +Windows Powershell: |
| 224 | +:large_orange_diamond: |
| 225 | +`bdk-cli wallet --descriptor $env:my_descriptor get_balance` |
| 226 | +
|
| 227 | +:::tip |
| 228 | +Note: The balance will only show after the transaction has been confirmed in a block at least once. |
| 229 | +::: |
| 230 | +
|
| 231 | +:+1: The output below confirms the command was successful: |
| 232 | +```shell |
| 233 | +{ |
| 234 | + "satoshi": { |
| 235 | + "confirmed": 100000, |
| 236 | + "immature": 0, |
| 237 | + "trusted_pending": 0, |
| 238 | + "untrusted_pending": 0 |
| 239 | + } |
| 240 | +} |
| 241 | +``` |
| 242 | +
|
| 243 | + |
| 244 | +
|
| 245 | +*** |
| 246 | +## Step 6: Create Transaction (PSBT) |
| 247 | +
|
| 248 | +To create a PSBT (partially-signed-bitcoin-transaction) run the command: |
| 249 | +
|
| 250 | +Linux/Terminal: |
| 251 | +:arrow_forward: `bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor create_tx --to tb1qw2c3lxufxqe2x9s4rdzh65tpf4d7fssjgh8nv6:50000` |
| 252 | +
|
| 253 | +
|
| 254 | +Windows Powershell: |
| 255 | +:large_orange_diamond: |
| 256 | +` bdk-cli wallet --descriptor $env:my_descriptor create_tx --to tb1qjk6n943uwhqhdf7en600tnwxpslvwtr0udsehp:0 --send_all` |
| 257 | + |
| 258 | +
|
| 259 | +:+1: The output below confirms the command was successful. |
| 260 | +
|
| 261 | +```shell |
| 262 | +{ |
| 263 | + "details": { |
| 264 | + "confirmation_time": null, |
| 265 | + "fee": 113, |
| 266 | + "received": 0, |
| 267 | + "sent": 123000, |
| 268 | + "transaction": null, |
| 269 | + "txid": "029173d76253e3441f9dc26f91e6ef30dff486848e91a7941f0cacd0af25ee30" |
| 270 | + }, |
| 271 | + "psbt": "cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAAAAA==" |
| 272 | +} |
| 273 | +``` |
| 274 | +
|
| 275 | +*** |
| 276 | +### 6a: export PSBT to environment-variable |
| 277 | +Linux/Terminal: |
| 278 | + :arrow_forward: `export PSBT="PASTE_PSBT_HERE"` |
| 279 | +
|
| 280 | +
|
| 281 | +Windows Powershell: |
| 282 | +:large_orange_diamond:`[System.Environment]::SetEnvironmentVariable('PSBT',"PASTE_PSBT_HERE",'Process')` |
| 283 | + |
| 284 | +
|
| 285 | +*** |
| 286 | +## Step 7: Sign Transaction (PSBT) |
| 287 | +
|
| 288 | +Linux/Terminal: |
| 289 | +:arrow_forward: ` bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor sign --psbt $PSBT` |
| 290 | +
|
| 291 | +Windows Powershell: |
| 292 | +:large_orange_diamond:`bdk-cli wallet --descriptor $env:my_descriptor sign --psbt $env:PSBT` |
| 293 | +
|
| 294 | +
|
| 295 | +- DON'T FORGET to COPY the PSBT for the next step |
| 296 | +
|
| 297 | + |
| 298 | +
|
| 299 | +
|
| 300 | +:+1: The output below confirms the command was successful. |
| 301 | +
|
| 302 | +
|
| 303 | +
|
| 304 | +```shell |
| 305 | +{ |
| 306 | + "is_finalized": true, |
| 307 | + "psbt": "cHNidP8BAFUBAAAAAak8uMR3UGkAGUKWsq8Mv45qg2fdD93JQRIsa2P0wFloAQAAAAD/////AQfgAQAAAAAAGXapFDRKD0jKFQ7CuQOBdmC5tosTpnAmiKwAAAAAAAEA3gIAAAAAAQFY9sVfEEbyjrHXSlxXDxL+71WOMnsPpVElwk+3E/J9vAAAAAAA/v///wIYZRIAAAAAABYAFBKYf7yF+ss6EFdw2rDZTfdLhep8eOABAAAAAAAWABQd6wBRnX8mBZiJYfvy/FGE+xKc+AJHMEQCIFSIkvEUI9yUgEw4JocRs1aiVsBlKKXrOQaQb3XFqR21AiBqiEVzCVVSRGjckyPDgAQBnOdSzBYR6Rw6KFcCP+E27wEhAwIlXdfM2WYnYa36Hp4MS6YkplBAgBsb1tYG9NiWFWTKzPYhAAEBH3jgAQAAAAAAFgAUHesAUZ1/JgWYiWH78vxRhPsSnPgiAgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6S0gwRQIhALWkBRSJzxuf0od4tPu3qFmEfJ2Y+/QBGtfjSFObWsPeAiA4QJx8Rk5pacrjHv5EOdw6RNHXcdtepFs+m0/Za/h0UQEiBgP80FpaWYQzGzCnNI9blXbei61YpAmtoezMRxpVvBJ6SxgTizKsVAAAgAEAAIAAAACAAAAAAAAAAAABBwABCGwCSDBFAiEAtaQFFInPG5/Sh3i0+7eoWYR8nZj79AEa1+NIU5taw94CIDhAnHxGTmlpyuMe/kQ53DpE0ddx216kWz6bT9lr+HRRASED/NBaWlmEMxswpzSPW5V23outWKQJraHszEcaVbwSeksAAA==" |
| 308 | +} |
| 309 | +``` |
| 310 | +
|
| 311 | +*** |
| 312 | +### 7a: export signed psbt to environment variable |
| 313 | +Linux/Terminal: |
| 314 | +:arrow_forward: `export SIGNED_PSBT="Paste_PSBT_HERE"` |
| 315 | +
|
| 316 | +Windows Powershell: |
| 317 | +:large_orange_diamond: |
| 318 | +` $env:PSBTSIGNED = "STRINGHERE"` |
| 319 | + |
| 320 | +
|
| 321 | +*** |
| 322 | +## Step 8: Broadcast Transaction |
| 323 | +Linux/Terminal: |
| 324 | +:arrow_forward: `bdk-cli wallet --wallet wallet_name --descriptor $my_descriptor broadcast --psbt $SIGNED_PSBT` |
| 325 | +
|
| 326 | +Windows Powershell: |
| 327 | +:large_orange_diamond: |
| 328 | +` bdk-cli wallet --descriptor $env:my_descriptor broadcast --psbt $env:PSBTSIGNED` |
| 329 | +
|
| 330 | + |
| 331 | +
|
| 332 | + |
| 333 | +:+1: The output below confirms the command was successful. |
| 334 | +
|
| 335 | +```shell |
| 336 | +{ |
| 337 | + "txid": "a0877b7ce91ea6d141ba63277673f5bdf0edfdd45f91a39ba1a1ace15f839b52" |
| 338 | +} |
| 339 | +``` |
| 340 | +
|
| 341 | +- Verify transcation in the memory pool on testnet [Mempool-testnet!](https://mempool.space/testnet) |
| 342 | + |
| 343 | +:::tip |
| 344 | +Run sync one more time and see that the balance has decreased. |
| 345 | +::: |
| 346 | +
|
| 347 | +*** |
| 348 | +
|
| 349 | +## Resources |
| 350 | +- [BIP-32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) |
| 351 | +- [BIP: 39 - Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) |
| 352 | +- [BIP: 44 - Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) |
| 353 | +- [BIP: 84 - Derivation scheme for P2WPKH based accounts](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki) |
| 354 | +- [BIP: 174 - Partially Signed Bitcoin Transaction Format](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) |
| 355 | +- [What are Descriptors and miniscript?](https://blog.summerofbitcoin.org/miniscript-policy-descriptors-hidden-powers-of-bitcoin/) |
| 356 | +- [Master Private Key and Extended Private Key](https://bitcoin.stackexchange.com/questions/97242/bip39-tool-bip32-extended-private-key-vs-bip32-root-key) |
| 357 | +- [Minsc A Miniscript-based scripting language for Bitcoin contracts](https://min.sc) |
0 commit comments