Colibri is a free and open source DIY project, with the goal to enable everyone with $5 and access to a laptop and Internet to create their own secure hardware wallet, using off-the-shelf hardware development boards.
The project aims to achieve this by
- using free, beginner-friendly tools and configuration options: everything can be built with Arduino IDE only
- utilizing cheap and widely available ESP32 development boards: one can get them for as little as ~$3
- building by the principle that "unhackable" hardware doesn't exist: any valuable data is encrypted to make it functionally impossible to extract instead
Version 0.1.X
is targeted to release early 2025, and will focus on getting the Colibri core ready - creating a secure hardware keystore and communication interface, and adding support for most Ethereum-compatible networks.
It's supposed to run on most common ESP32 development boards, with a intuitively designed UI and reasonable security despite the lack of a display.
Version 0.2.X
will introduce support for a wide range of display types commonly used by makers and pre-built into dev kits. This will also improve security, allowing users to verify transaction parameters, typing passwords on the device directly and recover stored mnemonics.
0.0.2 - 0.0.X
pre-alpha, public preview - see also changelog.
- build and flash the firmware with Arduino IDE (tested with ESP32-C3 & -S3)
- communicate with wallet via the BLE interface (JSON-RPC)
- use the (insecure) debug serial interface
- set a password to encrypt wallet storage
- generate truly random mnemonics and add existing ones
- store up to 30 encrypted mnemonics and switch between them
- use any HD path, and BIP32 passphrases
- sign Ethereum messages
- sign Ethereum typed data
- sign Ethereum transactions
Colibri doesn't require prior knowledge in hardware, or complicated tooling. It can be built with Arduino IDE only, a beginner-friendly environment to program microcontrollers. Anyone willing to bear with some initial setup and following step-by-step tutorials should be able to create their own hardware wallet quickly.
Colibri is built to support a wide range of ESP32 chips and boards, not just specific hardware configurations. You can get these boards really cheap on Aliexpress (e.g. the Supermini board we use in development), or on Amazon for a bit more money.
The following Espressif chips are supported:
- ESP32-C3
- ESP32-S3
- ESP32 ("classic")
The minimum requirements for your development board are:
- at least one programmable button (RST/EN is not enough)
- one programmable LED (simple, or Neopixel RGB)
- Bluetooth Low Energy support (no
ESP32-S2
support yet)
-
Go to
File > Preferences
and enable "Show files inside sketches" and "Show verbose output during compile" -
Connect your ESP32 dev board via USB
-
Change the target board in Arduino IDE (
Tools > Board > esp32 > ESP32XX Dev Module
, where "XX" is your ESP32 chip type; or select whatever fits your hardware better) and set the port (Tools > Port
) -
Try uploading the default
Blink
sketch to your board to verify everything is working as it should (File > Examples > 01. Basic > Blink
) -
Try these and these tips in case you're running into any connection issues. Most common issues:
- Wrong port selected in
Tools > Port
- Some boards require you to put them in flash mode manually (hold BOOT button, then press RST/EN button)
- Missing drivers on Windows/macOS
- Required user group permission on Linux
- Wrong port selected in
-
Clone or download this repository
-
Copy or symlink the contents of
firmware/lib
to<user>/Documents/Arduino/libraries
(Windows, macOS) or<user>/Arduino/libraries
(Linux)- In case you have some of the libraries installed already, please delete them and use the exact version from the repo
- Do not update these libraries if prompted by Arduino IDE
-
Open
firmware/colibri/colibri.ino
in Arduino IDE -
Navigate to the tab
config_board.h
- Either pick one of the preset board-configuration by uncommenting it (more boards coming soon!)
- Or set your own board configuration below (configure at least the pins for
LED_GPIO
andBUTTON_GPIO_OK
)
-
Only if you want to use the (insecure) debugging features (logs, serial interface), set the following in Arduino IDE. Make sure they're not set for your production builds:
Tools > USB CDC On Boot: Enabled
Tools > Core Debug Level: Debug
-
Make sure your board is connected and the right board type and port are selected in Arduino IDE
-
Click on "Upload" to build and flash Colibri
Colibri uses a modular structure to make it easy to add new hardware interfaces (e.g. BLE). At their core, all interfaces share the same JSON-RPC commands.
No matter which interface you're using to connect to your device, you can start out with this command to get an overview of all available methods and their parameters:
{ "method": "listMethods" }
Every interface has slightly different requirements to establish a connection.
To connect to your wallet via BLE, you need to pair your device first in your operating system's Bluetooth settings. When prompted for a pairing code, enter 200913
(you can change the default key in config_custom.h
). On devices with screens, it will be randomly generated and displayed.
Now that your wallet is connected and paired, you can use an app like e.g. nRF Connect to send commands to it.
The device exposes a GATT service with the UUID 31415926-5358-9793-2384-626433832795
, with two characteristics:
C001
: write your JSON-RPC command to this fieldC000
: you can read the JSON-RPC response from this field (turn on notifications for best results)
A more user-friendly way to use the BLE interface is coming soon.
If you've enabled debugging features for your build, the serial interface should automatically connect to your host PC, and you should be able to use Arduino IDE's Serial Monitor to send commands and receive responses (if not, dis- and reconnect the board and/or restart Arduino IDE).
Some actions require confirmation on the hardware, you'll notice the led start flashing. If your device has two buttons, press Ok to approve or Cancel to reject. If you only have one, double-click to approve or long-press to cancel.
Additionally the following actions can be triggered on the device directly:
- Hold down Cancel to lock your idle wallet. If it's locked already, it will reboot the device instead.
- Quickly press Cancel ten times to trigger a complete wipe of the device.
First we need to set a password for our wallet. This is used to encrypt all sensitive information on the device, so choosing a secure password is crucial for the security of your device. We recommend using a Diceware password with at least 3-4 random words.
{ "method": "setPassword", "params": ["CorrectHorseBatteryStaple"] }
Next we need to generate or add a mnemonic seed phrase to our wallet. Use a metal seed storage to back up your seed phrase - we recommend SAFU Ninja as a cheap and reliable DIY solution.
// generate a 24-word mnemonic
{ "method": "createMnemonic" }
// generate a 12-word mnemonic
{ "method": "createMnemonic", "params": [12] }
// add a 12/18/24 word mnemonic:
{ "method": "addMnemonic", "params": ["your seed phrase goes here"] }
All done! Next time we want to use our wallet, we'll need to unlock it first:
{ "method": "unlock", "params": ["CorrectHorseBatteryStaple"] }
To select a specific wallet, you can use
// use your second stored mnemonic for signing, with default settings:
{ "method": "selectWallet", "params": [2] }
// this call also returns additional info for the wallet, like the address, pubkey and HD path.
// ...or be more specific:
{ "method": "selectWallet", "params": [1, "m/44'/60'/0'/0/2", "optionalPassphrase"] }
// params:
// - id of seed phrase to use (here: 1)
// - optional wallet HD path (here: Ethereum, wallet index 2)
// - optional BIP32 passphrase
To e.g. sign a personal message, try
{ "method": "eth_signMessage", "params": ["Hello world!"] }
Full JSON-RPC docs coming soon.
0.1.x
:
- Core firmware with minimal UI for a variety of boards
- Secure keystore
- JSON-RPC core interface
- BLE interface
- Ethereum signing
- Trusted companion webapp for wallet setup
- Proof of concept 3rd-party wallet integration
0.2.x
:
- Display integration and GUI
- Show transaction data on device
- Recover seed phrase on device
- Enter password on device
- More presets for common dev-boards
- Typescript SDK
- 3rd-party wallet integrations
to be prioritized
:
- Encrypted USB interface (WebUSB and/or HID)
- Bitcoin signing
- Python SDK
- Airgapped interface (camera + QR codes)
- Platform.io build setup
- Secure Boot
We're looking for contributors and sponsors to help bootstrap Colibri and make it a viable option for everyday crypto usage. Valuable extensions to the project, once the core product is functional:
- App to setup/manage/update your wallet
- Support for more coins and chains (e.g. Bitcoin, Solana, Monero)
- 3rd party wallet integrations (e.g. MetaMask, Bitcoin HWI)
- Libraries and SDKs for builders (e.g. Typescript, Python)
- New hardware interfaces (e.g. USB support, airgap via camera/QR codes)
- Support channels for builders, users and the community
- Learning materials, content of all kinds
- created by xtools-at (© 2024)
- inspired by ricmoo's Firefly Arduino Wallet
- preliminary work: ESP-5791 - Physical backed tokens with ESP32
- Arduino IDE 2.3.2 (w/ Arduino CLI 0.35.3)
- Espressif ESP32 Arduino Core
esp32
3.0.7 (w/ ESP-IDF 5.1)
Colibri is licensed under the AGPL 3.0 - GNU Affero General Public License
Colibri is still under development and hasn't been peer-reviewed, or audited for security yet. Use at your own risk, and do not use your real keys (yet). The software is provided “as-is,” without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.