Open-source airgapped hardware wallet with clear signing for safer self-custody

Better Wallet is an open-source, DIY hardware wallet project focused on safer self-custody through clear signing and offline-first architecture. Instead of asking users to approve opaque payloads, it shows human-readable transaction on device so users understand exactly what they are signing. The prototype combines Raspberry Pi hardware, NFC-based interaction, and a custom mobile app to create smoother, more secure signing flows across Solana and EVM-style workflows. The goal is to make auditable, developer-friendly hardware wallet security accessible to more people. The new hardware , firmware and app has been developed from scratch at ethglobal NYC
Better Wallet NFC is an air-gapped signing prototype. The core idea is simple: use NFC as the only bridge between a phone and a hardware wallet, so sensitive signing never depends on Bluetooth, USB, or internet connectivity during approval.
In practice, the experience is a two-tap flow:
Below is the full breakdown of how this came together across hardware, firmware, and app layers.
The hardware wallet runs on a Raspberry Pi 5 connected to:
One practical challenge was bus contention and stability. To keep touch and NFC reliable at the same time, the PN532 was moved to I2C bus 3 (GPIO6/GPIO7), while the GT911 remained on I2C bus 1. That separation removed intermittent conflicts during active use.
Display rendering runs over SPI with KMS/DRM, and the wallet UI is rendered fullscreen via Pygame in a kiosk-style mode.
EREMOTEIO-style edge cases, which required defensive handling.pinctrl shell reset if RPi.GPIO is unavailable.The firmware/runtime is Python-based and organized into clear responsibilities: hardware setup, NFC transport, signing logic, and UI orchestration.
Instead of high-level NDEF, we used a low-level APDU-style exchange with a custom AID. This gave full control over chunking, retries, and flow state:
0x01 asks phone for total payload length0x02 + offset reads a chunk from phone0x03 + bytes writes a chunk back to phone0x04 commits transfer and triggers phone-side eventChunks are intentionally capped at about 200 bytes to stay safely inside PN532 frame limits. That made large payload handling predictable and robust.
sign_request JSON.This layer also includes automatic recovery logic for transport errors and transient card movement events, so the experience remains stable instead of failing hard.
The mobile app is built with React Native + Expo, but with native Android code for HCE (Host Card Emulation). This is important: Expo Go is not enough for this architecture because direct APDU handling needs native service access.
HostApduService for Android HCEThis project is intentionally practical. The final architecture combines custom APDU chunking, explicit two-tap UX states, and aggressive transport recovery so the system works on real hardware, not just ideal conditions.
The most "hacky" parts, like I2C bus juggling and reset fallbacks, were the exact fixes that made the prototype dependable. Those choices are a key reason the demo feels smooth and trustworthy even on commodity components.

