Great Hardware Wallet for Bitcoin for a Small Price
UPDATE: Check the 2024 update here
On this post, we present a guide on how to have a hardware wallet for less than €15, fully functional, and easy to use, without being bulky or shoddy. The process is quite accessible. You’ll only need an easily available Arduino development board, and by following the step-by-step instructions, we can successfully create our own device.
The recommended board is a TTGO T-Display, costing less than €15 on AliExpress, but with deals, it can go as low as €10 (or even around €5 on AliExpress for new users). The 4MB version is suitable; we’ve used the CH9102F, but both should work, including the TELEC.
Okay, with this little board and nothing else, let’s flash the Blockstream JADE software. It’s a BITCOIN ONLY wallet, but it’s one of our favorites. There’s an option to add a camera and battery, but to minimize cost and complexity, this guide uses it without a camera or battery, similar to a Ledger Nano S.
It’s essential to note that the software powering this hardware wallet (JADE) is open source, allowing us to install it on any compatible device. As a specific recommendation, the TTGO T-Display proves to be an excellent choice, offering an optimal balance between performance and practicality for this purpose.
Flashing and Software Signing:
First, access the Blockstream Jade GitHub page: https://github.com/Blockstream/Jade. All the steps are explained within this post, but you may want to check the official source as well. It’s recommended to use Linux-based systems, but it’s also possible with Windows or macOS, the same commands are used. Linux is preferred due to previous issues with Windows’ random number generator.
Ensure git and python are installed, if you are not sure, run the following command:
sudo apt install git python3-pip python3-venv
Then create the “esp” folder if it does not exist already:
mkdir esp
Now run the following commands:
cd ~/esp git clone -b v5.1.1 --recursive https://github.com/espressif/esp-idf.git
cd ~/esp/esp-idf && git checkout e088c3766ba440e72268b458a68f27b6e7d63986 && ./install.sh esp32
Finally, run this command to set up the environment variables:
. $HOME/esp/esp-idf/export.sh
Compile the Firmware:
Now it is time to compile the firmware. Clone the Jade repository:
git clone --recursive https://github.com/Blockstream/Jade.git $HOME/jade
Now we have to make sure that we know the device we’re using and configure the sdkconfig.defaults file accordingly. We have to look for our file within this folder:
Search for the following file, and copy it from the JADE folder’s configs subfolder to the root folder (/jade/).
Now we should delete (or rename differently) the original sdkconfig.defaults file, and rename the one we just copied, and name it “sdkconfig.defaults”.
Then, run the following command at the terminal:
cd $HOME/jade
Now if you do not have cmake installed, also run this command:
sudo apt install cmake
Finally, run this command to flash the firmware:
idf.py flash monitor
The firmware will now be flashed, and the device is operational. You may connect it to Sparrow, Electrum, or Blockstream Green.
But… as you can see, it doesn’t appear as a normal JADE when using Blockstream Green; it shows as DEV in red. In theory, it can be used this way, but it lacks Secure Boot. To add an extra layer of security, it’s recommended to enable Secure Boot.
Secure Boot
In order to implement secure boot, and configure the device as a regular JADE, we have to modify the sdkconfig.defaults file. First we have to add this line to the file:
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
Then we should delete the Debug Mode:
Also, if you want to remove Bluetooth functionality (which might make sense for this kind of hardware wallet, without any battery), add these lines:
CONFIG_APP_NO_BLOBS=y
CONFIG_MBEDTLS_ECP_RESTARTABLE=y
CONFIG_MBEDTLS_CMAC_C=yCO
And delete the following:
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
#CONFIG_BT_NIMBLE_ROLE_CENTRAL is not set
#CONFIG_BT_NIMBLE_ROLE_BROADCASTER is not set
#CONFIG_BT_NIMBLE_ROLE_OBSERVER is not set
CONFIG_BT_NIMBLE_NVS_PERSIST=y
#CONFIG_BT_NIMBLE_SM_LEGACY is not set
CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="j"
CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=11
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=517
CONFIG_BTDM_CTRL_BLE_MAX_CONN=1
#CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED is not set
Then, for Secure Boot configuration, add these lines:
CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE=y
CONFIG_SECURE_DISABLE_ROM_DL_MODE=y
CONFIG_SECURE_BOOT_SIGNING_KEY="PATH TO YOUR SIGNING KEY"
CONFIG_SECURE_BOOT=y
CONFIG_SECURE_FLASH_ENC_ENABLED=y
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
CONFIG_ESP32_REV_MIN_3=y
And delete this one:
CONFIG_EFUSE_VIRTUAL=y
Also make sure that CONFIG_ESP32_REV_MIN_3=y is not already present with REV_MIN_1
, in such case, delete it and leave REV_MIN_3 option only.
In the “Path to your signing key” line, you have to put the path to a signing key that has not been generated yet:
CONFIG_SECURE_BOOT_SIGNING_KEY="hideyourkeys-v2.pem"
Save and close the file.
Now it is time to generate the signing keys. In the terminal, execute the following command (note that you should name your file the same way as in the previosuly modified sdkconfig.defaults file, we named it hideyourkeys-v2):
espsecure.py generate_signing_key --version 2 ~/jade/hideyourkeys-v2.pem
The key file will be located at the same jade folder. If you chose another path, make sure that it is consistent with the sdkconfig.defaults file, and the relative path is correct in such file. Now run the following command, to setup the build configuration:
idf.py menuconfig
The following menu will show up:
In the menu, go to security settings, enable hardware secure boot in bootloader, choose the version, save, and close, the other features (Enable flash encription on boot, or Check Flash Encryption enabled on startup shall be marked as well). All these options shall be marked by default. In case they are not, download our Hardware Wallet Manual, and copy the ANNEX A configuration file, replace it in the sdkconfig.defaults file, and delete any previous sdkconfig files within the jade folder.
Note depending on the device you are using, you might be able to choose Secure Boot V1 or V2. It is preferable to use V2, in case it is available. Our devices support Secure Boot V2 (just like a retail Blockstream Jade), but just in case you are following this guide using another ESP32 device, only supporting Secure Boot V1.
Now it is time to connect the device. Once the device is connected, run:
idf.py bootloader
You will get a similar output like this one:
But the bootloader will also provide as a command that we should run. It should be similar to this one. Remove the port (-p (PORT)) and baud rate information (-b (460800)) before running it:
/home/xxx/.espressif/python_env/idf5.1_py3.10_env/bin/python ../esp/esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 2MB --flash_freq 40m 0x1000 build/bootloader/bootloader.bin
Note: We have seen that in some cases you might not get the prompt above, in such case, you might be able to flash it running the following command: idf.py bootloader bootloader-flash
Now, without unplugging the device, run the following:
idf.py build
If successful, the terminal will provide two commands to flash the build (note that the path marked in bold letters will vary on your computer):
/home/xxx/.espressif/python_env/idf5.1_py3.10_env/bin/python ../esp/esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x9000 build/partition_table/partition-table.bin 0xe000 build/ota_data_initial.bin 0x10000 build/jade.bin
“
or run "idf.py -p (PORT) flash
Now you should run any of the two previous commands from the build output. We recommend using the first one, and deleting the port and baud rate manually (marked in bold), unless you know such values:
/home/xxx/.espressif/python_env/idf5.1_py3.10_env/bin/python ../esp/esp-idf/components/esptool_py/esptool/esptool.py -p (PORT) -b 460800 --before default_reset --after no_reset --chip esp32 write_flash --flash_mode dio --flash_size 4MB --flash_freq 40m 0x9000 build/partition_table/partition-table.bin 0xe000 build/ota_data_initial.bin 0x10000 build/jade.bin
Now the device will be flashed, but it will stay in bootloader mode:
In order to reboot the device and leave bootloader state, run:
idf.py monitor
The device will restart, and it should no longer appear as a development device in Blockstream Green. It is very important to wait until the device is restarted before plugging it out, otherwise the device will brick. It might take a few minutes.
Pros & Cons
DISADVANTAGES:
- It’s tedious, requires tinkering, but following the steps takes less than 5 minutes.
- No camera functionality or battery, works like a Ledger Nano S, only plugged in.
- Updating is more tedious than the original (though you only have to type four commands).
ADVANTAGES:
- Very compact and cheap hardware wallet, not shoddy when using a case.
- An excellent Bitcoin-only wallet, for a very small price.
- It is a good alternative as a back-up device.
To enhance the appearance, various cases are available on AliExpress, ranging from €4 to €8. If you have a 3D printer, there are models online by searching for “ttgo t-display case.”
Update firmware
In case you need to update the firmware, plug the device and run the following commands:
cd $HOME/jade
git pull
idf.py build
python jade_ota.py --noagent
The device will present an update message to be confirmed, just as a regular JADE.
Factory Reset
In case you want to perform a factory reset (to set up a new wallet and delete the current one installed, for example) , when the Blockstream JADE logo appears, press both buttons, and you’ll get the option to perform a factory reset.
Conclusions
In our opinion, this is the most accessible way to have a fully functional hardware wallet for bitcoin, it is not the easiest solution, but it is a reasonable approach at a fair price.
If you have any questions or problems, feel free to reach out via email at [email protected] , you might also want to check our Hardware Wallet Manual, and our Hardware Wallet, in case you want to skip all this guide.