This guide assumes you have a basic knowledge of the command line and are familiar with the bitcoin-cli
RPC client.
While not required, this guide was written using a bendir
directory for easier testing. If you want to follow the guide without using bendir
, it's recommended you alias bitcoin-cli
to bitcoin-cli -named -signet -datadir=<your testing datadir>
so you can copy-paste the commands directly from the guide. To use bendir for your testing environment:
git clone https://github.com/josibake/bendir.git
cp -r bendir silent-payments-testing
cd ~/silent-payments-testing
direnv allow
If this is your first time building Bitcoin Core from source, take a look at the build instructions for your system (build-*.md
in bitcoin/doc/). Once you're ready to build, checkout and compile #28453:
# in your bitcoin src directory
git fetch upstream pull/28453/head:silent-payments-testing-branch
git checkout silent-payments-testing-branch
# assuming you have the build dependencies installed
./autogen.sh
./configure
make
Once the build has finished, copy the binaries into your testing directory:
cp ~/bitcoin/src/bitcoind ~/silent-payments-testing/bin/
cp ~/bitcoin/src/bitcoin-cli ~/silent-payments-testing/bin/
Start bitcoind
on signet/regtest:
cd ~/silent-payments-testing
init signet
bitcoind -daemon
You are now ready to start testing!
Create a wallet:
bitcoin-cli createwallet "sp" silent_payments=true
Fund the wallet:
# mine some blocks if using regtest or get some coins from a signet faucet
bitcoin-cli getnewaddress
# can use https://signet.bc-2.jp or your faucet of choice to send coins to the address
Make a silent payment!
# you can use include_unsafe (instead of waiting for a block) if your signet coins are still unconfirmed
bitcoin-cli getnewaddress address_type="silent-payment"
bitcoin-cli sendtoaddress "<your silent payment address>" <amount> include_unsafe=true
Check the transaction:
bitcoin-cli gettransaction "txid" verbose=true
While silent payments is primarily a privacy improvement, it is also a UX improvment for Bitcoin and can enable cool new protocols like usernames for sending Bitcoin. Here is a small script to demonstrate:
#!/bin/bash
# Default to mainnet if no argument is provided
NETWORK="mainnet"
# Help text
display_help() {
echo "Usage: $0 [OPTION] EMAIL"
echo "Fetch payment information for a given email address."
echo ""
echo "Available options:"
echo " -signet, -regtest, -testnet, -mainnet Specify the network (default: mainnet)"
echo " -h, --help Display this help and exit"
exit 0
}
# Function to check and set the network
set_network() {
case $1 in
-signet|-regtest|-testnet|-mainnet)
NETWORK="${1#-}"
return 0
;;
-h|--help)
display_help
;;
*)
return 1
;;
esac
}
# If no arguments are provided, display help
if [ "$#" -eq 0 ]; then
display_help
fi
# Check the first and second arguments for the network flag or help
if ! set_network $1; then
set_network $2
EMAIL_ARG=$1
else
EMAIL_ARG=$2
fi
read user domain < <(echo $EMAIL_ARG | awk -F@ '{print $1, $2}')
# Fetch the JSON and check if the network exists in the structure
JSON=$(curl --max-time 3 -s -f https://$domain/.well-known/silent-payments/$user)
CURL_EXIT_STATUS=$?
if [ $CURL_EXIT_STATUS -ne 0 ]; then
echo "Error: Failed to fetch data from https://$domain/.well-known/silent-payments/$user"
echo "Are you sure $user@$domain has a silent payment address configured?"
exit 1
fi
if ! echo "$JSON" | jq -e --arg network "$NETWORK" 'has($network)' > /dev/null; then
echo "Error: $user does not have a $NETWORK silent payment address. Try one of:"
echo $JSON | jq
exit 1
fi
# Extract the value for the provided network
echo "$JSON" | jq -r --arg network "$NETWORK" '.[$network]'
If you don't understand the script that's okay. This script takes an email address and a network flag and fetches a silent payment address from the .well-known
directory of the domain. To use the script:
# if using bendir, this script is already available in aliases.
# otherwise, save the script in a file called `pay` and make it executable
vim pay
# copy the script
chmod +x pay
If you have a domain, you can put your silent payments address under the well-known directory like so:
# find the .well-known directory on your server and create a file at the following path
USERNAME="your_desired_username"
SILENT_PAYMENT_ADDRESS="your_silent_payment_address_here"
mkdir -p .well-known/silent-payments
# Echo the JSON content into the file
echo "{\"signet\": \"$SILENT_PAYMENT_ADDRESS\"}" > .well-known/silent-payments/$USERNAME
Now you can get your silent payment address with the pay
script:
pay user@domain -signet
And you can make payments from the command line:
bitcoin-cli sendtoaddress $(pay [email protected] -signet) <amount>
- Try using different RPCs, like
send
- Send to the same silent payment address multiple times and verify the addresses are different each time
- Send multiple UTXOs to the same address, then spend from that address multiple times and verify the silent payment outputs are always unique
- Verify you can detect an incoming silent payment in the mempool and in a block
- Verify you can detect previous silent payments when doing a wallet rescan
If you run into any issues or have questions, feel free to leave a comment on this gist!