Better Wallet Pi · v0.1.0
Doc  BW-PI / SPEC 0.1
Issue  2026-04-27
Class  Reference design
Status   PROTOTYPE

Open-source · Stellar-first · Air-gapped · Raspberry Pi

A Stellar wallet that cannot connect to anything.

Better Wallet Pi is a buildable reference design for signing Stellar SEP-7 transaction requests over QR codes — never over the wire. Ethereum EIP-4527 support is included too, but Stellar is the main path: scan a web+stellar: URI, review the XDR intent, sign offline, and return the signed envelope by QR. No driver. No companion app. No cable.

Primary path
Stellar
Ethereum
Network surface
0 / 0
Standards
SEP-7 · SLIP-10
EIP-4527 · BIP-39
Orthographic illustration of the Better Wallet Pi device with labelled callouts.
FIG · 01
SCALE 1:1
SIGN DENY AIR-GAPPED BW-PI/0.1.0 A B C D
A
3.5″ SPI display
B
UR-capable camera
C
Confirm · GPIO 17
D
Deny · GPIO 27
SYS STATUS / AIR-GAPPED
RT 00:00:13.27
camera_loop idle · awaiting UR frame frame 03 / 24 · part 0x4a frame 11 / 24 · part 0x9c frame 24 / 24 · reassembled
state_machine READY PARSE_REQUEST · eth-sign-request AWAIT_CONFIRM · gpio SIGNING · eth · 65 bytes EMIT_SIGNATURE · UR PARSE_REQUEST · web+stellar: SEP-7 SIGNING · xlm · ed25519 EMIT_SIGNATURE · xdr
xlm_parser idle envelope · payment op envelope · 1 op · 100 stroops fee idle
display_loop rendering home rendering tx detail rendering signature QR · part 02 rendering signature QR · part 12
gpio_loop listening · pin 17 · pin 27 pin 17 high · CONFIRM listening · pin 17 · pin 27
> bw-pi await scan
/xlm transport SEP-7 URI
/xlm compat any SEP-7 emitter
/xlm out signed envelope XDR
/eth transport EIP-4527 · UR
/host Raspberry Pi 4 / CM4
/network none

Most hardware wallets ship with closed firmware, a proprietary chip, and a USB cable. This one ships with none of those.

  1. 01

    No path in.

    WiFi and Bluetooth are disabled in firmware. There is no USB data path. The device cannot phone home — there is no home to call.

  2. 02

    Light in. Light out.

    Animated UR fountain-encoded QR carries the transaction in. A second QR carries the 65-byte signature out. Nothing else crosses.

  3. 03

    No mystery chips.

    Every line of the signing path is open-source Python on commodity silicon. Read it, run it, fork it, build it.

§ 02 / Architecture

Two devices. One photon-thick channel.

The signing flow is a closed loop with exactly one boundary. Bytes never cross it. Only the camera and the screen do — whether the payload is an animated eth-sign-request UR or a single-frame web+stellar: SEP-7 URI.

Online · Networked

A

Your laptop, in the world.

  • 01

    A wallet or composer builds the unsigned transaction — xlm via Stellar Lab or any SEP-7 emitter, eth via MetaMask.

  • 02

    It is rendered as a QR — single-frame web+stellar: for XLM, animated UR for ETH.

  • 06

    Camera scans the signed result and broadcasts via the chain's normal path.

AIR GAP

UR · light only

no packets

Offline · Air-gapped

B

The Pi, in a Faraday calm.

  • 03

    Camera decodes the QR. UR fragments fountain-reassemble; SEP-7 URIs pass through verbatim.

  • 04

    Human-readable summary on the 3.5″ screen. SIGN or DENY by hand.

  • 05

    Dispatch by request type: eth_account.sign or stellar_sdk.Keypair.sign. Signed payload goes back as QR.

§ 03 / Chains

Stellar first. Ethereum too. Different curves. Different transports. Same air gap.

Stellar is the lead workflow because SEP-7 gives the project a clean, QR-native signing request. Ethereum remains supported through the Keystone-style EIP-4527 path.

Stellar

/xlm
Curve
Ed25519
Derivation
SLIP-10 · m/44'/148'/0'
Tx encoding
XDR (binary, schema-defined)
Transport
SEP-7 URI (single QR)
Compatible
any wallet that emits SEP-7 — see note
Out
Signed envelope XDR

Ethereum

/eth
Curve
secp256k1
Derivation
BIP-32 · m/44'/60'/0'/0/0
Tx encoding
RLP · EIP-1559
Transport
EIP-4527 UR (animated QR)
Compatible
MetaMask · Rabby — Keystone import
Out
65-byte signature · r ‖ s ‖ v

A note

No major Stellar wallet (Lobstr, Freighter, Albedo) ships a hardware-import flow comparable to MetaMask's Keystone integration today. The Pi accepts a web+stellar:tx?xdr=… URI scanned from any SEP-7 producer, signs it, and emits the signed envelope XDR by QR. You then broadcast the result via Horizon, Stellar Lab, or your wallet's submit-signed-tx flow.

Read SEP-7 ↗

§ 04 / Source of truth

One dispatcher. Two chains.

Verbatim from wallet/__init__.py. Every signing call in the project — Stellar or Ethereum — passes through these ten lines. Anything else is a bug.

wallet/__init__.py · read-only
view raw ↗
38 # ── signing ─────────────────────────────────────────
39 def sign(self, request):
40 """Dispatch to the right chain. Returns chain-specific bytes/str."""
41 if isinstance(request, EthSignRequest):
42 return _eth.sign(self.eth_account, request)
43 if isinstance(request, XlmSignRequest):
44 return _xlm.sign(self.xlm_keypair, request)
45 raise ValueError(
46 f"unsupported sign request type: {type(request).__name__}"
47 )

§ 05 / Cornerstones

Claims are easy to write. These are the structural decisions that make them hold.

We don't ask you to trust the marketing. We ask you to read the file path next to each claim, and verify it for yourself.

  1. § 05.1

    No WiFi. No Bluetooth. No USB data.

    Network silicon is disabled at the firmware level via the Raspberry Pi config overlay. There is no driver path to enable it from userspace. CM4 no-wireless variants remove the silicon entirely.

    config.txt :: dtoverlay=disable-wifi,disable-bt
  2. § 05.2

    PIN-stretched encrypted mnemonic.

    The keystore stores the BIP-39 mnemonic, encrypted with AES-256-GCM keyed by a scrypt-stretched PIN. The mnemonic is the single source of truth — both the secp256k1 eth_account and the Ed25519 stellar_sdk Keypair are re-derived from it on unlock. No private key persists on disk.

    wallet/keystore.py · AES-GCM
  3. § 05.3

    BIP-39 recovery, day one. Both chains.

    A 12-word mnemonic is generated on first boot and shown once for offline backup. Ethereum derives at m/44'/60'/0'/0/0 (BIP-32 secp256k1); Stellar at m/44'/148'/0' (SLIP-10 Ed25519). One backup, two chains.

    wallet/derive.py · BIP-32 + SLIP-10
  4. § 05.4

    Hard module isolation.

    Only state/machine.py is permitted to import wallet/. The boundary is checked architecturally. Adding networking, USB, or Bluetooth code anywhere is a project-level rule, not a convention.

    state/machine.py · sole importer
  5. § 05.5

    Fully auditable.

    Every line of the signing path is open-source Python. The eth path leans on eth_account; the xlm path leans on stellar-sdk. No closed firmware. No secure element you have to take on faith. Read it before you trust it.

    github.com/pettiboy/better-wallet-pi

§ 06 / Hardware

A reference design. Not a product.

There is no SKU. There is no shipping date. There is a list of commodity parts, an SD-card image, and a repository whose every screw and every line is yours to inspect.

BILL OF MATERIALS

approx US$ 80–120

REF PART DETAIL QTY
PI Raspberry Pi 4 or CM4 (no-wireless) for production ×1
DSP 3.5″ SPI touchscreen 480 × 320 · ADS7846 · tft35a overlay ×1
CAM Pi Camera Module libcamera · ribbon variant recommended ×1
BTN Momentary push buttons GPIO 17 (sign) · GPIO 27 (deny) ×2
SD microSD card 8 GB · Class 10 minimum ×1
PSU USB-C power supply 5 V · 3 A · power-only, no data ×1

OUTCOME

Hardware whose every screw is yours to inspect.

Source the parts. Flash the SD card. Solder two buttons. You now hold a hardware wallet whose entire trust chain you can audit, fork, and rebuild from scratch.

A note, plainly

This is a Phase 1 prototype. The architecture is built for the right reasons, but no external audit has been performed and the code has not been hardened against side-channel attacks. Use a testnet account before anything else.

§ 07 / Datasheet

No mystery. No magic.

A small surface area of well-understood, off-the-shelf components.

Software

Language
Python 3.11+ · asyncio
xlm crypto
stellar-sdk · pynacl
eth crypto
eth-account · bip32utils
QR transport
pyzbar · foundation-ur
Display
pygame · framebuffer (/dev/fb1)
Camera
picamera2 (libcamera)

Standards

xlm transport
SEP-7 URI scheme
eth transport
EIP-4527 · UR (BC-UR)
typed data
EIP-712
mnemonic
BIP-39 · 12 words
xlm path
SLIP-10 · m/44'/148'/0'
eth path
BIP-32 · m/44'/60'/0'/0/0

Compatibility

Stellar
xlm · any SEP-7 emitter
MetaMask
eth · Keystone import
Rabby
eth · Keystone import
EVM
all chains via chain_id
curves
Ed25519 · secp256k1
license
open source · see repo

§ 08 / Questions

The uncomfortable answers, first.

01 Is this ready to hold real funds today?

No, and we will not pretend otherwise. Better Wallet Pi is a Phase 1 Python prototype. Use a testnet account first — Goerli/Sepolia for Ethereum, the Stellar testnet for XLM. The architecture is built for the right reasons, but no external audit has been performed and the code has not been hardened against side-channel attacks.

02 Which Ethereum wallets does it work with?

MetaMask and Rabby today, via the Keystone hardware-wallet account-import flow. Anything that speaks EIP-4527 UR transport should work in principle.

03 Which Stellar wallets does it work with?

Today, none of the major Stellar wallets — Lobstr, Freighter, Albedo — ship a hardware-wallet flow comparable to MetaMask's Keystone integration. The Pi instead accepts SEP-7 transaction URIs, produced by tools like Stellar Lab, custom scripts, or any wallet that emits a web+stellar:tx?xdr=... QR. The Pi returns a signed envelope XDR by QR, which you then submit via Horizon or your wallet's "submit signed transaction" flow.

04 Why support Stellar specifically?

Stellar is the lead workflow because it has a clean, standardized signing-request URI format (SEP-7) and an open-source SDK with first-class mnemonic + Ed25519 derivation. It demonstrates the air-gap pattern without needing a proprietary companion app or a USB-style hardware-wallet session.

05 How is this different from a Ledger or Trezor?

Ledger and Trezor ship sealed devices with proprietary firmware and a USB cable into a host computer. Better Wallet Pi is open hardware you build yourself, has no USB data path at all, and has no closed components in the signing path.

06 Why a Raspberry Pi?

It is cheap, widely available, well documented, and auditable. The CM4 no-wireless variant is recommended for production builds because the network silicon is physically absent — not just disabled in software.

07 Has the code been audited?

Not externally. Open source means you can audit it yourself — and you should, before trusting it with non-trivial value. The codebase is small and the security boundaries are explicit.

08 Can I contribute?

Yes — issues and pull requests welcome on GitHub. The project follows one strict architectural rule: only state/machine.py may import wallet/. Read CONTEXT.md before sending a PR.

§ 09 / Coda

Don't trust.
Verify.
Then build it.

The repository is the source of truth. The website is the menu; the menu is not the meal. Star it, fork it, audit it, build it.