Bachelor’s thesis · MFF UK · 2026

A multisig Bitcoin wallet, signed on a Trezor

Graded Excellent and nominated by the supervisor for a special award.

An Android wallet for Bitcoin accounts that need several people to approve each payment, where every signature is made on a Trezor. The whole system is built around one constraint: the backend coordinates the cosigners but never holds key material and never signs.

Code · Thesis (100 pages, in Czech) · supervised by RNDr. Filip Zavoral, Ph.D. · defended 18 Jun 2026

01

What it looks like

  1. The start screen: connect a Trezor, on mainnet or testnet 1Connect a Trezor
  2. The app showing a 2-of-3 multisig wallet on testnet 2A 2-of-3 wallet
  3. Coin control: the unspent outputs, each with a checkbox to choose it 3Coin control
  4. A transaction waiting for signatures, 0 of 2, with a Sign with Trezor button 4Each cosigner signs on a Trezor
  5. A transaction with 2 of 2 signatures, ready to broadcast 5Enough signatures, then broadcast

No wallet I compared combined native multisig management, coin control and direct Trezor Connect integration on Android. Sparrow, the reference for multisig UX, has no mobile version at all.

02

How it works

Because signing happens on a Trezor over the Trezor Connect deeplink API, the backend cannot hand a signing library a transaction and take back a signature. It has to do that library’s work itself. I wrote the PSBT (BIP-174) binary encoding and parsing, the multisig P2WSH witness script and the bech32 encoder by hand; BIP-32 derivation comes from bitcoinj. Keys are ordered per BIP-67 on BIP-48 paths, each cosigner’s signature is placed at its BIP-67 position, and the last cosigner’s Trezor outputs the complete signed transaction, which the backend broadcasts. Coin control is built in.

The backend is seven Kotlin/Ktor microservices on PostgreSQL under Docker Compose; the app is Jetpack Compose. The 123 backend test methods run in GitHub Actions. They pin keys and addresses to the published BIP-32, BIP-84, BIP-173 and BIP-350 test vectors and check token rotation for races.

I also wrote a four-attack threat model for how the app handles Trezor Connect deeplink callbacks, and implemented the mitigations. Any app on the phone can invoke the callback, so each request carries a one-time random id that the callback has to echo back; signatures from the wrong device force a logout; and if Android kills the app mid-signing, the callback that arrives later is rejected and the user signs again. The channel fails closed instead of trusting a callback it cannot verify.

03

What a Trezor demands

The wallet runs any M-of-N policy from 2-of-3 up to 15-of-15 on testnet (the 15-of-15 on the Trezor emulator) and has been used on mainnet with real funds. Getting there means meeting everything a hardware wallet checks before it agrees to sign, which no mocked test will tell you. Three examples:

  • BIP-67 ordering per derived address. The cosigner keys have to be sorted again for every address, not once per wallet. At the first address both orders happen to match, so the difference only shows on a real multi-input spend, where the network rejects a wrongly ordered script.
  • The full previous transaction in every input (PSBT_IN_NON_WITNESS_UTXO). Trezor firmware requires it as a defense against an attack that tricks the device into approving an arbitrarily large fee.
  • Derivation paths on change outputs. Without them the device cannot prove the change belongs to the wallet, and shows it to the user as a payment to a stranger.

Each of these is pinned by a named test in the repository.

04

Testing and docs

The automated tests cover the backend, where the consensus-critical logic lives; the Compose app is tested by hand on testnet and mainnet. The design documents and the thesis are in Czech; the repository README is the English summary.

05

What the reviewers wrote

Both official reviews are public on the university repository. Short excerpts, translated from Czech:

“Overall, I consider the thesis to be of exceptional quality.”

“He independently studied a large body of standards and technical documentation and, based on them, designed and implemented a software wallet supporting advanced features of Bitcoin technologies, a combination that no existing mobile wallet offers.”

“I consider the thesis above standard both in its scope and especially in the technical depth of its execution.”

“I consider the architecture design very well done and appropriate to the nature of the application.”

The opponent rated the code quality as standard, noting that style consistency, structure and documentation could be improved in places, though he did not consider this significant given the scope of the protocols.

Questions about any of it: hi@kubadvorak.com. Back to the home page.