Introduction
This summer, I've had the incredible opportunity to participate in the Summer of Bitcoin program. I have been working with my mentors, Dan Gould and Steve Myers, to implement functionality for sending payjoin transactions into the Bitcoin Dev Kit CLI (command-line interface) wallet. This project is especially interesting to me because of my passion for privacy technologies. Payjoin transactions significantly improve privacy by breaking the common-ownership heuristic that blockchain analysis firms typically use to identify individuals.
I first became interested in Bitcoin when I stumbled upon the Nashville Bitcoin Park community campus in September of 2022. Since then, I've become obsessed with the potential Bitcoin has to improve humanity and our financial system. I applied to the BDK-payjoin for the Summer of Bitcoin program in early spring and was accepted after multiple screening rounds. This post outlines what I have been doing since then.
NOTE: If you are anti-bitcoin, deeply think about all of the aspects of life that humans have innovated and improved upon throughout history. Why is it so crazy to expect that humanity will eventually improve upon our current system of money and store of value?
Payjoin and BDK - What are they? And why should you care?
A payjoin, also known as a P2EP (Pay-to-EndPoint), is a unique kind of Bitcoin transaction that enhances privacy more than a standard transaction. This concept might be confusing at first, so let's break it down.
In traditional Bitcoin transactions, only the sender contributes the inputs. However, in a payjoin transaction, both the sender and receiver supply inputs. This disrupts the commonly used method of blockchain analysis called the 'common input ownership heuristic'. By making it harder to track who owns which input, payjoin transactions add an extra layer of privacy. This is significant because it helps protect the financial privacy of users and enhances the fungibility of Bitcoin.
Furthermore, payjoin transactions are not just about improved privacy. They also have the potential to enhance the overall efficiency of the Bitcoin network.
How? By consolidating 'unspent transaction outputs' or UTXOs. This process can help streamline the network, making Bitcoin transactions smoother and faster.
The payjoin process - credit Bitcoin Design
The Bitcoin Development Kit, known as BDK, is a suite of tools specifically designed to assist developers in creating applications that can interact seamlessly with the Bitcoin network. Think of BDK as a foundational base for specialized wallets and various applications. It simplifies the development process by minimizing the intricate knowledge needed to establish a project.
As part of my goal, I’m aiming to guide wallet builders on how to incorporate payjoin functionality using the BDK. By demonstrating its implementation, I hope to become a valuable resource for other developers looking to integrate payjoin into their own wallets.
Initial Testing
As I embarked on this project, my initial efforts were centered around setting up a local regtest bitcoind node and carrying out local tests on both rust-payjoin and BDK-CLI. My first encounters with configuring the testing environment proved to be quite challenging, particularly because I had no prior experience with using bitcoin-cli in the terminal (command line bitcoin tool).
However, thanks to the valuable assistance from my mentors, I was able to overcome these hurdles.
After I tested rust-payjoin, I wrote the README for payjoin-cli based on my experience as a beginner. Payjoin-cli allowed me to understand the flow and expected behavior for a typical payjoin transaction.
Note: PSBT in Bitcoin stands for “Partially Signed Bitcoin Transaction”. This is essentially just a standard format that allows Bitcoin transactions to be constructed and signed in multiple steps by different entities.
Proposed Command
After forking the BDK-CLI repository and setting up my local development environment (I’ve been using VSCode for this project), I was able to begin implementing the logic necessary for handling a payjoin transaction.
My proposed command for sending a payjoin transaction in BDK-CLI:
send_payjoin
Sends a Payjoin Transaction. Takes a valid payjoin bip21 uri
syntax:
bdk-cli wallet send_payjoin --uri "[payjoin URI]"
Main Problem Faced - PSBTv2 fixes this!
Once I got reqwest to work with sending the HTTP request and handling the response, I was stuck on a "SigningError”. For multiple debugging sessions, I was unable to determine exactly why the PSBT wasn’t being signed correctly. I tried changing the BDK SignOptions to alter the signing behavior, but this was not the solution.
Eventually, the bug was discovered after tracing the code into a local copy of the BDK library. It turns out that the processed PSBT (the payjoin PSBT after adding the receiver’s input) was lacking the sender’s UTXO data. This was due to the spec of BIP78 “clearing all other data except the UTXO in the input key-value map”. Thanks, Dan for helping with that!
Since finalize_psbt() checks if the TxOut script in the PSBT matches the descriptor, the payjoin-processed PSBT wasn’t signing properly (it was missing important data). To fix this, I needed to implement a somewhat ‘hacky’ workaround. First, I saved a clone of the original PSBT before constructing the HTTP request. Then, after processing the response into the payjoin PSBT, I re-introduced the cloned original PSBT’s UTXO data before finalization. Now, the payjoin PSBT has sufficient UTXO data to sign properly within BDK.
Link to PR
My pull request hasn’t been officially merged yet but will be soon. I have tested the payjoin functionality and the behavior is as expected.
One thing to note is that the fee rate is currently hardcoded at 100 sats, but will eventually match the tx_builder’s.
In a future post, I will be detailing a fleshed-out explanation of how I implemented payjoin and break down the code. Also, I will thoroughly document the best way to locally test the functionality of send_payjoin in BDK-CLI.
What I’ve Learned
My interest and commitment to understanding the nuances of Bitcoin have only increased further from this experience. This project has provided me with hands-on experience in contributing to Bitcoin’s development, something that is incredibly valuable to me. This project has allowed me to explore my passion for privacy technologies and understand their significance in enhancing the overall functionality of the Bitcoin network.
Specifically, I have grown much more proficient at file management and utilizing command-line tools. This is important because the terminal (in my opinion) greatly increases productivity and offers more control over system operations. I make it my goal to use the command line over Finder whenever I can. Since BDK-CLI is a command-line application, I now understand how these tools are implemented from a developer’s perspective. My experience with BDK-CLI has provided insights into how command-line tools handle user input, execute commands, and manage errors. I touched on this in a previous blog post, but I truly believe that all undergraduate computer science curriculums should support (or even require) a command-line course. There is a definite need for today’s CS graduates to have a deep understanding of underlying system mechanics and the tools that enable them to interact most efficiently with these systems.
Since I utilized GitHub for the entirety of this project, I gained a more professional understanding of version control systems. Git is a platform that facilitates collaboration, code review, and version control—which are all fundamental aspects of software development. I initially wasn’t experienced with creating meaningful commit messages, but I have since grown more adept. This is a vital skill for effectively collaborating with other developers since a good commit message clearly communicates what changes were made and why. Finally, I have learned the importance of a clean commit history. It’s crucial to avoid cluttering the commit history with unnecessary changes (which is exactly what I did) to keep the project tidy.
Thank You
Special thanks to my mentors Steve Myers (BDK) and Dan Gould (PDK). These two made sure to help break down concepts so that I was able to understand them and truly learn. Their guidance went beyond just technical knowledge; they instilled in me the importance of approaching problems with curiosity, resilience, and a growth mindset. Also, thank you to Adi for running the Summer of Bitcoin program. Without this program, I wouldn’t have been able to contribute to such a meaningful project.
Cool Article
I just saw this today. Super short but cool read that highlights how Bitcoin mining can be used to help Paraguay profit from a surplus of energy.