Introduction
OpenBMT is a Bitcoin checkout system for shops. The cashier enters a sale amount, the customer scans a payment code, and the money goes to the shop’s wallet. The cashier then closes the order in the shop’s existing point-of-sale system (POS).
OpenBMT is pre-release. It has had internal review only and no independent security audit. Do not use it with real funds.
The shop’s devices
OpenBMT has three Android apps and an optional server:
| Part | Job |
|---|---|
| Counter app | Displays the sale and payment code, watches for payment, and tells the cashier what has been checked. It holds no wallet signing key. |
| Owner app | Tracks the shop’s coins and prepares refunds, cash-outs and settings changes. |
| Key app | Holds a second wallet key on a separate device. It reviews spends, address batches and changes that loosen the shop’s limits. |
| Box | Relays messages between the shop’s devices and reads POS orders. The shop runs it; it holds no wallet key. |
The shop holds all three keys to its wallet, and any two are needed to spend. OpenBMT and Avila Labs hold none of them. Keeping the keys on separate devices prevents a single stolen phone from being enough to spend the money. The wallet chapter explains the other conditions this protection depends on, including work that is still unfinished.
The wallet uses a standard output descriptor: a description that other wallet software can read. Recovery therefore does not require OpenBMT to remain available.
Payments and records
OpenBMT checks payments directly through the Bitcoin network and can add a check from the shop’s own node. The counter identifies whether information came from its peer check, the Box or the node. Getting paid explains these reports and the risk of handing over goods before a payment confirms.
There is no OpenBMT account, hosted balance or payment processor between the customer and the wallet. If the shop wants dollars, it chooses an exchange and approves a transaction to it. OpenBMT prepares that transaction; it does not exchange the money.
The accounting export reports what is in the records and follows United States rules only. It does not provide tax advice.
What is built today
“Built” means the code exists and has passed tests on a desktop or against Bitcoin Core on a test network. The Android apps have started on an emulator but have not been tried on a phone. “Planned” means a feature is in the design; “Not built yet” marks something that is still absent.
| Part | Status |
|---|---|
| Shared wallet, address batches, settings, signed records and instant acceptance | Built |
| Key app signing rules | Built |
| Counter sale handling and Bitcoin peer client | Built; tested against Bitcoin Core on a test network |
| Owner coin view, refund queue, spending and approval session | Built; tested against Bitcoin Core on a test network |
| Counter, Owner and Key Android apps | First builds; started on an emulator, not run on a phone |
| Box and its container, Umbrel and StartOS packages | Built; container image smoke-tested, Umbrel and StartOS packages not run on a device |
| NFC tap to pay | Not built yet |
| Square and Clover order matching | Built, read-only; based on vendor documentation, not tested with a real seller account |
| Lightning through the shop’s own node | Built at the counter; not run against a real node |
| Books and exports | Built as a library; no books screen in the apps |
| Recovery kit printing | Not built yet; the Key app can check a scanned wallet description against its own |
| Push wake-ups, a full node on the Box and a hosted Box | Not built yet |
| Reproducible builds and a second holder of the Key app’s release key | Not in place yet |
The chapters under “Using OpenBMT”, including setup, the Box, refunds, books and cash-out, have not been written yet.
Checking the implementation
This handbook is written for shop owners and managers. References such as
SR-34 and CR-15 are for readers who want to check the implementation:
they identify rules in the repository’s docs/ folder, with corresponding
test names in the code. When a claim is marked “not verified”, the text
states what was checked and what remains unknown.
Why accept bitcoin
A shop accepting bitcoin directly receives the payment in its own wallet, without a processor taking a percentage or controlling the payout. It also takes responsibility for its keys, network fees and the value of the bitcoin it keeps. Whether this is useful depends on the shop’s customers and costs. OpenBMT does not recommend buying or holding bitcoin as an investment and makes no price prediction.
Processing and network fees
A $20 card sale on Square’s United States Free plan costs $0.67: 2.6% of $20 is $0.52, plus $0.15. At 1,000 such sales a month, that is $670 a month or $8,040 a year, before dispute or payout fees.
Square’s pricing, read on 2026-11-11, lists:
| Payment | Rate |
|---|---|
| In person: tap, dip or swipe, Free plan | 2.6% + 15 cents |
| In person, Plus plan | 2.5% + 15 cents |
| In person, Premium plan | 2.4% + 15 cents |
| Keyed in or card on file | 3.5% + 15 cents |
| Online or invoice, Free plan | 3.3% + 30 cents |
| Card issued outside the United States | Additional 1.5% |
Stripe’s page, read the same day, lists 2.9% + 30 cents for a domestic online card payment, another 1.5% for an international card and another 1% for currency conversion.
An on-chain payment to an OpenBMT wallet has no processor fee. The customer pays to send it; the shop pays a network fee when it later spends the receipt, cashes out or consolidates receipts. That fee depends on transaction size and the current fee rate rather than the sale amount.
On 2026-11-11, mempool.space listed a fastest rate of 4 satoshis per virtual byte. A spend from one receipt in the shop’s two-of-three wallet to two outputs, payment and change, is 201 virtual bytes: 804 satoshis at that rate. The size is calculated from the weight rules in BIP 141. Each additional receipt spent adds 104.5 virtual bytes (design section 9).
During a fee spike, spending a small receipt can cost more than it is worth. A shop can set a minimum on-chain sale or use its own Lightning node for small purchases, avoiding a separate on-chain receipt for each sale. Lightning has routing fees: the mempool.space snapshot of 2026-08-30 showed a median channel charge of 500 millisatoshi plus 100 parts per million. Check https://mempool.space/ for current rates. Getting paid describes both options.
Disputes and refunds
Card disputes can reach well beyond the day of sale. The Visa Core Rules, 24 October 2026 edition, allow a card-fraud dispute up to 120 calendar days after processing. For goods or services not received, the period runs from expected delivery and ends no later than 540 days after the transaction.
Stripe charges $15 when a dispute arrives and retains it even if the merchant wins. Countering costs another $15, returned only on a win. The disputed amount is held for the process, which Stripe says can take 2 to 3 months. Square lists no dispute fee, but holds the funds immediately and keeps its processing fee when the payer wins.
A payer or bank cannot pull back a bitcoin payment confirmed in a block. A refund requires the shop to send a new payment. A chain reversal remains possible, becoming less likely as blocks accumulate; no depth makes it impossible.
Before confirmation, the sender can replace a payment. Above the instant limit, OpenBMT waits for a block. Below it, the shop accepts the risk that a customer could cancel during the roughly ten-minute wait, with the loss bounded by the limit. See Getting paid for the checks and exposure budget.
Payouts and reserves
Card processors can hold funds under their published terms:
- Square can delay payouts during chargebacks, withhold funds or require a reserve. Its rolling-reserve page names advance payment before delivery, high dispute rates and a lack of processing history as factors.
- PayPal can place a reserve on a business account at any time. A risk-based hold generally lasts up to 21 days, and a balance can be held for up to 180 days. Its rolling-reserve example holds 10% of payments for 90 days.
- Stripe says reserve funds cannot be paid out or transferred.
Square’s default payout is the next business day; instant transfer costs 1.95%. Stripe’s standard United States payout is 2 business days after payment; instant payout costs 1.5%.
OpenBMT receives the money in the shop’s wallet. There is no payout to request, and no company holds a wallet key or has a switch to stop receipt. A company cannot freeze that wallet. The shop must keep its own access: losing two keys makes the money unspendable, and approving a bad spend cannot be reversed. The wallet chapter and Operating precautions explain the precautions.
Merchant accounts
A card merchant applies to a processor, supplies identity and bank details, and accepts its terms. The processor decides whether to serve the shop and can later close the account.
OpenBMT needs the shop’s phones and, optionally, a Box. There is no sign-up, identity check or company approval. The shop’s tax, licensing and trade obligations still apply. What OpenBMT will never do explains the account policy.
Supply and price
The Federal Reserve states a goal of “inflation of 2 percent over the longer run”, measured by the personal consumption expenditures price index (read 2026-11-11). At that rate, a dollar held for ten years buys about 18% less: 1 / 1.02^10 = 0.82. Higher inflation would erode it further.
Bitcoin’s block reward began at 50 bitcoin and halves every 210,000
blocks, about four years. Total issuance therefore cannot reach 21 million.
Bitcoin Core computes this in GetBlockSubsidy in src/validation.cpp,
using the interval in src/kernel/chainparams.cpp. Full nodes reject blocks
that pay too much. An operator who keeps the existing rules continues to
reject excess issuance; publishing different rules cannot force adoption.
This supply schedule does not stabilize the dollar price. Bitcoin has risen and fallen sharply. A shop holding receipts bears both directions of that movement, and chooses how much to retain or cash out. OpenBMT does not convert the money. Cash-out is an owner-approved transaction to the chosen exchange; its walkthrough will be in the next part.
Running the system
The shop operates its own phones and optional Box, keeping them charged, updated and protected. Small on-chain purchases can be uneconomic; its own Lightning node is an option, but the counter integration has not been tested against a real node. OpenBMT is pre-release and has had no independent audit. Do not use it with real funds.
Fewer customers pay with bitcoin than with cards. OpenBMT makes no claim about adoption numbers. Treat it as an additional payment method when planning for the shop’s customers.
United States tax records
The following is information, not tax advice. Ask a tax professional about your situation. OpenBMT’s accounting export follows United States rules only.
Under IRS Notice 2014-21, Q&A-3 and Q&A-4, bitcoin received for goods or services is income at its dollar fair market value on the day received. That value is also the shop’s basis. The IRS digital-assets page, reviewed 2 September 2026, treats digital assets as property rather than currency. Selling or spending them can create a gain or loss.
Brokers file Form 1099-DA about their customers; a shop does not file it for its own sales. Form 8300 reports cash above $10,000 received in a trade or business. IRS Announcement 2024-4 says digital assets do not count toward that threshold until regulations are published. No final regulation was found on 2026-11-11; check irs.gov for the current rule.
Customers and privacy
A customer holding bitcoin can pay a shop that accepts it. A foreign-issued card carries a foreign-exchange fee; bitcoin has no such fee, while the customer still pays the network fee.
A payment contains no customer name or shop bank details. The wallet description stays on the shop’s devices, and OpenBMT does not give its addresses to a company. Anyone with an address or transaction ID can, however, inspect linked payments on Bitcoin’s public ledger. Privacy describes what the POS vendor and network still see.
Sources
Each page below was read on 2026-11-11.
- Square pricing: https://squareup.com/us/en/pricing
- Square deposits: https://squareup.com/help/us/en/article/3807-deposit-options-with-square
- Square disputes: https://squareup.com/help/us/en/article/3882-payment-disputes-walkthrough
- Square payment terms: https://squareup.com/us/en/legal/general/payment
- Square reserves: https://squareup.com/help/us/en/article/6832-reserves-faq
- Stripe pricing: https://stripe.com/pricing
- Stripe disputes: https://docs.stripe.com/disputes/how-disputes-work
- Stripe balances and reserves: https://docs.stripe.com/payments/balances
- Visa Core Rules, 24 October 2026 edition, section 11.8.2.4 and condition 13.1: https://usa.visa.com/dam/VCOM/download/about-visa/visa-rules-public.pdf
- PayPal User Agreement: https://www.paypal.com/us/legalhub/paypal/useragreement-full
- Federal Reserve, inflation goal: https://www.federalreserve.gov/faqs/economy_14400.htm
- Bitcoin Core block reward: https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp and https://github.com/bitcoin/bitcoin/blob/master/src/kernel/chainparams.cpp
- IRS Notice 2014-21: https://www.irs.gov/pub/irs-drop/n-14-21.pdf
- IRS digital assets: https://www.irs.gov/filing/digital-assets
- IRS Announcement 2024-4: https://www.irs.gov/pub/irs-drop/a-24-04.pdf
- IRS Form 8300: https://www.irs.gov/businesses/small-businesses-self-employed/form-8300-and-reporting-cash-payments-of-over-10000
- Transaction weight (BIP 141): https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
- Fee rates: https://mempool.space/api/v1/fees/recommended
- Lightning fee snapshot (dated 2026-08-30): https://mempool.space/api/v1/lightning/statistics/latest
Design choices
OpenBMT separates the work done at the counter from control of the wallet. That separation determines which devices hold keys, which services the shop depends on, and what the cashier can approve.
Keys and counter access
The counter displays payment requests and watches for receipts. It has no key that can spend the shop’s money and does not display the wallet balance. Refunds and cash-outs go through the owner phone and a second signer. Compromising the counter should not give someone the wallet.
The shop holds three keys, with any two needed to spend. No device may hold two of them or cause a second key to sign without a review on that key’s own device. The Key app checks spends and address batches independently of the owner phone. It also approves settings changes that allow more risk. The remaining release and device-testing conditions are explained in The wallet and its keys.
Services and custody
There is no OpenBMT account or server through which payments pass. The counter checks the Bitcoin network directly, with an optional additional check from the shop’s own node. The wallet uses open standards so the shop can recover it with other software.
OpenBMT excludes services that could hold, move, freeze or redirect the shop’s funds, or obtain its keys, wallet description or addresses. These are permanent exclusions, including optional integrations. They ruled out co-signed instant payments, whose signer group could freeze funds and see spends, and third-party Lightning swaps, whose provider would see the amount, timing and both sides of each swap.
The POS vendor still sees its orders, and an exchange sees deposits sent to it. Privacy lists the other contacts. Any optional service that saw metadata alone would have to be off by default, disclose that exposure where it is selected, and appear in that list. No such service is offered today.
Shop settings
The owner chooses keys, a node and waiting periods. Configuration should use plain questions and a recommended option, with unsafe combinations excluded. The cashier works within those settings. Confusing checkout behavior is a problem for OpenBMT to fix.
For on-chain payments, accepting a small sale before a block is an owner-selected risk, bounded by the instant limit and exposure budget. Sales above those limits wait for a block. The owner can choose the risk without asking a cashier to judge the Bitcoin network during a sale.
Bitcoin only
OpenBMT is built for receiving and holding bitcoin. Its currency choice rests on Bitcoin’s monetary rules and the network enforcing them. The bitcoin-only policy explains that choice and why it excludes other independently mined currencies as well as issuer-controlled tokens.
Payment reports
Seeing an unconfirmed transaction, finding it in a block and checking it
against the shop’s own node provide different evidence. The counter must
keep those reports distinct (CR-105, docs/screens/counter.md).
Getting paid explains the
labels.
No screen says “fully verified”. “Settled” and “final” mean the shop’s chosen refund depth; they do not mean a reversal is impossible. Conditions and unverified details must also be stated beside claims in the handbook.
OpenBMT has had four internal design reviews. It still needs device testing, outside code review and an independent security audit. Setup time and most speed measurements are also unfinished; see Limits and risks.
What OpenBMT will never do
These restrictions apply to future versions as well as the current design. Some depend on release safeguards that are still unfinished; those limits are stated here. The design choices explain how they shape the checkout system.
Never anything but bitcoin
OpenBMT accepts BTC on the Bitcoin network, and bitcoin over the shop’s own Lightning node. Other currencies, stablecoins and tokens on any layer are excluded.
Why Bitcoin
OpenBMT’s starting point is money whose supply the holder can verify and whose rules do not depend on an issuer’s discretion. Bitcoin’s issuance schedule approaches a limit of 21 million. A full node checks that schedule itself and rejects a block that creates too much, even if miners produced it. Developers can publish different software, but cannot make a holder’s node accept different rules.1
A supply limit is useful only while people enforce it. The currency also needs miners doing the work that protects settlement and people willing to hold and accept it. OpenBMT regards Bitcoin’s record of enforcing its issuance rules, independent validation and established use as the strongest basis for money. That judgment is why the project builds on this network; a supply cap or proof-of-work algorithm alone is not enough.2
Other monetary networks
Other currencies can also use proof of work, cap their supply and let anyone verify issuance without a central issuer. Those properties do not make the currencies interchangeable. Each network settles its own asset under its own rules.3
Copying Bitcoin’s code or specifying another supply cap does not by itself reproduce the people choosing to use Bitcoin, the mining work protecting its current payments, or their continued agreement on its rules. A chain split can share the earlier ledger, but the networks follow separate rules and settle different currencies after the split. Creating those currencies does not create more BTC on the Bitcoin ledger.4
Independent verification also depends on what it costs to run a node. More transaction data has to be downloaded and checked; increasing base-layer capacity can make that work more demanding. OpenBMT favors keeping verification practical for the shop.5
OpenBMT gives greater weight to preserving Bitcoin’s monetary rules and independent verification than to a different chain’s block interval or advertised transaction fee. Lower fees alone are not a reason to ask the shop to receive another currency. For small purchases, the supported alternative is bitcoin through the shop’s own Lightning node. For on-chain payments, the shop can set a minimum sale and choose how many confirmations to wait for.
Tokens, sidechains and mints
An issuer-controlled token introduces another objection: its issuer may retain powers over issuance, redemption or transfers. Those powers create a dependence on that issuer, in addition to the reasons for choosing BTC over another currency.
The exclusion includes tokens on Lightning, Taproot Assets and RGB. A token carried over Bitcoin-related infrastructure is still a different asset. Federated sidechains such as Liquid require a federation to hold the coins, and ecash mints such as Cashu or Fedimint hold money while issuing claims against it. OpenBMT does not accept those claims as payment.
The wallet is native segwit, two of three (SR-60). The Key app rejects
data outputs, non-standard scripts and inputs containing Taproot fields
(SR-22, SR-06), and refuses transactions carrying tokens. Lightning
accepts bitcoin invoices from the shop’s own node only (LN-01). The
checks follow the currency choice described above.
Bitcoin still has price risk and fees. Choosing it does not establish a stable purchasing power or remove the payment risks described in Getting paid. The exclusions are not trials or features waiting for a later release.
Never custody
Neither OpenBMT nor Avila Labs holds a shop’s wallet key or balance, and there is no hosted wallet. A processor’s failure, sanction or account freeze therefore cannot lock up money held in the shop’s own wallet.
The Owner app holds key 1 and no other secret key (OA-08); the Key app
holds key 2. The counter cannot sign a spend. Its refund request is a
record, not a payment (CR-60). The Box holds no wallet description,
address, transaction ID or key that signs for the shop (BX-04).
The shop takes responsibility for lost and stolen devices; see The wallet and its keys. Avila Labs will hold app release keys, which are separate from wallet keys. A malicious app release remains a risk: the Key app is separate, but its independent release-key holder has not been named.
Never an account or an identity check
OpenBMT requires no sign-up or KYC. An account could be closed, frozen, subpoenaed or breached, and software that holds no funds for a shop should not need its identity.
A device identifies itself with a key it generates. Staff names on the
counter are labels entered by the shop, without identity verification
(CR-156). There is no OpenBMT account or payment server.
The shop still deals with accounts at its POS vendor and chosen exchange. Those companies have their own sign-up and checks. OpenBMT neither asks for those accounts nor sees them.
Never a third party deciding where money goes
Only the shop’s devices can choose its payment addresses. A counter
accepts address batches signed by two separate devices, checked against
the roots pinned at pairing (CR-02, design section 5.1). It cannot make
an address of its own, and the Box cannot choose or alter one (BX-04).
An address-selection server would have the power to substitute a thief’s
address.
OpenBMT also excludes public Electrum and Esplora indexers. Giving one the
shop’s addresses would reveal its sales and let the server link them.
The counter instead requests compact block filters and blocks without
sending an address or script (NR-60).
Peers can still observe which blocks it requests or withhold information.
Several peers from different network groups make interference harder,
but cannot eliminate it. The counter reports when it lacks enough
information (NR-61; docs/NETWORK-RULES.md, section 8).
Never telemetry, analytics or crash upload
OpenBMT does not send the publisher the shop’s sales activity. The Key
app has camera permission only, with no network permission; a build check
fails if its manifest changes. The Counter and Owner apps have network
permission only for the contacts listed in the design: Bitcoin peers, price
sources, POS reads, and the shop’s own Box and node. The Owner app itself
opens no connection beyond the proxy greeting and till read (OA-15).
Privacy lists all contacts.
These rules and manifest checks have not had outside review. They cannot control a compromised device or an operating system that leaks data. To share crash information, the shop must export a local log and send it manually.
Never automatic updates, and never a remote switch
The owner must choose to install an update. Automatic installation would let the publisher, or someone taking over its releases, change the shop’s devices without that choice. The apps have no update check and no background service, receiver or provider to run one; each app’s manifest check verifies this.
There is no OpenBMT service for a remote switch. Counter commands require
the owner phone’s signature and sequence numbers that prevent replay
(CR-14).
The Box ships as a container without an updater. Its host, such as a mini PC, Umbrel or StartOS, controls its own update behavior. The shop must manage that there.
The Key app’s proposed signed release manifest, install-date delay, F-Droid and signed-file distribution, and reproducible builds are planned. Google Play distribution is excluded.
Never a Lightning service provider holding the shop’s channels
Lightning connects to the shop’s existing LND or Core Lightning node. OpenBMT does not run, rent or select one (design section 8). A provider holding the channels would hold the money and see every payment. The same reason excluded third-party swaps.
The node’s public key is in the signed settings. Naming or changing it
needs the Key app’s co-signature, and each invoice must be signed by that
key (LN-03, LN-17). Setup checks that the counter’s credential permits
invoices only (LN-04 to LN-20).
OpenBMT cannot establish who actually operates the named node. If the shop chooses a hosting company’s node, that company holds its channels. OpenBMT offers no such provider. Setup explains that the shop must manage liquidity, updates and backups. The counter integration is built but has never been run against a real node.
Never calling an unconfirmed payment final
An unconfirmed payment can be replaced by its sender. The fixed counter
states (CR-10) therefore show “Paid” with “it could still be undone”
when accepting before a block. A payment is confirmed at the shop’s
confirmation depth; “final” refers only to its refund depth. The books
count it as money at that refund depth (CR-31). More blocks reduce the
chance of reversal without making it impossible.
Each screen identifies its check (CR-105). The own-node label requires
both the shop’s node and the counter’s light client to see the payment
(CR-104). OpenBMT will not say “fully verified” without a report from
the shop’s own node.
Never closed source
The code, rules and design are published under the MIT licence in
LICENSE. A shop should be able to read the source, build it and check
what it is being asked to install. The dependency policy accepts only
licences on its published list (docs/DEPENDENCIES.md, rule 6).
Dependencies retain their own licences. OpenBMT does not publish the phone’s operating system or Orbot, the separate app needed for Tor. Reproducible builds, which would let someone check a released app against the source, are not built yet.
-
Bitcoin Core validation explains full-node enforcement of the supply limit. The Bitcoin FAQ describes voluntary adoption of protocol rules. Read 2026-11-11. ↩
-
The Bitcoin developer guide describes independent validation and proof of work. The Bitcoin FAQ on value explains the role of acceptance and adoption. The judgment about which network OpenBMT should use is the project’s. Read 2026-11-11. ↩
-
Examples of independently mined currencies are described in the Bitcoin Cash protocol documentation and Litecoin proof-of-work reference. Read 2026-11-11. ↩
-
The Bitcoin developer guide on consensus changes explains how incompatible rules can split a chain. The distinction between copying software and reproducing a monetary network follows from those separate rules and participants. Read 2026-11-11. ↩
-
Bitcoin Core’s capacity discussion explains the validation costs involved in increasing capacity and the use of payment channels to reduce on-chain data. Published 2015-12-23; read 2026-11-11. This is a design tradeoff, not a measurement of current node costs. ↩
The wallet and its keys
OpenBMT uses a wallet with three keys. Spending requires any two of them, so losing one phone need not lose the money. The protection depends on keeping the keys apart and having the second device check what it signs.
OpenBMT has had internal review only and no independent security audit. The apps have not been run on a phone. Do not use it with real funds.
The wallet: two of three
One key cannot spend. If one key is lost, the other two can move the money to a new wallet. If two are lost, the money cannot be spent. Two keys held by the same person or device are also enough to spend, regardless of the roles assigned in OpenBMT.
The wallet uses native segwit sortedmulti with three different keys
(SR-60). Its standard output descriptor can be read by other wallet
software. A restore drill rebuilt the wallet and found its payments in
Bitcoin Core on a test network; the recovery kit is described below.
The three keys
| Key | Kept on | Held by |
|---|---|---|
| Key 1 | The owner’s Android phone, in the Owner app | The owner |
| Key 2 | A separate phone running the Key app by default; a hardware wallet or offline computer is an alternative in the design | The owner or a manager |
| Key 3 | Words on steel, away from the shop; generated outside OpenBMT | The owner, stored separately |
Write down the words for keys 2 and 3 and store them separately. A phone whose PIN is unknown, with no written words available, counts as a lost key. After losing any key, use the remaining two to move to a new wallet.
Three rules about the keys
A device may neither hold two keys nor cause a second key to sign without that key’s own device displaying and checking the transaction. This is what the design means by “drive” a key. Otherwise, malware on one device could spend the wallet with one routine approval tap. The apps do not offer a setup that breaks this rule.
Key 2 must run different software from key 1. Running the same build on both would let one bad update affect both signatures. The default is the separate Key app, with its own code base. A hardware wallet or another publisher’s signer is also acceptable under the design.
Key 3 must be generated outside OpenBMT. The design allows another publisher’s wallet on the counter tablet before it becomes a counter: put the tablet in airplane mode, generate the key, then factory-reset it. A hardware wallet provides stronger separation. The Key app receives only key 3’s public key and origin by QR code. It never generates or displays key 3’s words; its screen says “do this step alone”.
The Key app rejects a secret key, a single-signature form, or a key 3 that
matches key 2 (SR-64 to SR-67). Exactly one key in the registered wallet
must match the imported key 3. The app also compares its own slots byte
for byte before registration.
These checks do not yet establish independence between the apps’ releases. One publisher signs both apps, and the second, independent holder of the Key app’s release key has not been named. Until that changes, use a hardware wallet or another publisher’s signer for key 2 as the design recommends. The claim that no single component can spend the wallet does not hold today. Limits and risks explains the launch conditions.
Hardware wallets and an offline computer as key 2 are still planned. Spending with a hardware key 2 has not been tried on real hardware. The Key app can run on a separate phone as an approver. Its refusal to run with debugging or an accessibility service enabled, and its screenshot blocking, are checks in its own software. A malicious build could omit them, and the phone displaying the words could retain them. A hardware wallet reduces that dependence on the phone.
How a key is made
For key 1 in the Owner app and key 2 in the Key app, you can let the device generate a key, use dice or coin throws, or enter words you already hold. The two methods based on throws mix nothing else in, so the same throws produce the same words in other tools. These methods are built but have not been run on a phone. Key 1 has no seed words by default; the design leaves that choice open for review.
Roles: owner, manager, cashier
| Role | Can do | Cannot do |
|---|---|---|
| Owner | Tighten settings; queue loosening changes; add or remove counters; approve refunds and cash-outs with key 2; see balances and books | Loosen settings without the Key app’s co-signature |
| Manager | Override a red screen within a dollar ceiling, with the action logged and counted; approve large refunds at the counter by PIN | Change money settings, pair devices, see the wallet balance or move money alone |
| Cashier | Create or cancel sales; request refunds; override red screens within the per-sale instant limit and daily override cap; see sales totals | Approve money movements, change settings, dismiss the cancel alarm or see wallet balances |
The counter shows settings read-only and never displays the wallet balance.
It enforces the override and refund limits (CR-21, CR-69). Cashier
actions need no PIN; manager actions require the manager’s PIN (CR-86).
Only the owner can clear a cancel alarm, with a signed command (CR-14).
There is one manager PIN, 6 to 12 digits long. After a wrong attempt, the wait rises from 1 second to 2, 4, 8 and so on, up to 5 minutes. It does not lock the manager out for longer. The counter holds no wallet key and has no wipe.
The counter also keeps up to 30 cashier names, each with a 4 to 8 digit
PIN. This list is local, is outside the signed settings, and is lost with
the phone (CR-156). It deters casual access. Separate accounts for
multiple managers are not built yet.
Loosening needs the Key app; tightening does not
Raising the instant limit, reducing the confirmation depth or increasing a refund cap allows more risk. Adding a counter or Lightning node, or removing a check or alert, does too. OpenBMT calls these changes loosening. Lowering a limit, requiring more confirmations or removing a counter is tightening.
A tightening change takes effect immediately on the owner phone with key
1’s signature. A loosening change waits in the approval queue. The Key
app displays each old and new value and marks its direction; both devices
must sign before the change counts. Counters require both signatures.
The initial settings count as loosening in every field (AS-27).
Counters also check that the settings version is above the floor recorded
at pairing (CR-94). Some bounds cannot be exceeded regardless of who
signs: underpayment tolerance cannot exceed 5%; confirmation depth cannot
be below one block; the heartbeat interval must be between one minute and
one hour; and counter shares cannot total more than 100%.
A hardware key 2 may be unable to sign settings. The design proposes a delay measured on each counter’s own header chain as a fallback, but that is not built. A spare Key app acting as an approver preserves the second signature. Without that approver, settings changes depend on the owner phone alone, which the screens disclose.
The approval session
The Owner app queues refunds, cash-outs, address batches, loosening changes, counter pairings and health checks. Queuing does not move money. When you have key 2 available, open an approval session:
- Transfer the queue from the owner phone as an animated BC-UR QR code or a file on USB-C or an SD card. BC-UR is also used by Sparrow and hardware wallets. The Key app needs no network connection.
- Review each item on the Key app and approve or decline it. Undecided
items are declined (
AS-30). - Transfer the signed reply back by QR code or file. The owner phone adds key 1’s signature and sends the result.
The Key app has neither sales records nor its own price source. It labels every dollar figure as information from the owner phone. Its spending limits are therefore in satoshis, and it checks the transaction itself. For every spend it requires:
- A plain version-0 PSBT containing the full previous transaction for every
input. This lets it check the input amounts (
SR-01,SR-10). - Inputs belonging to the registered wallet, checked by deriving their
scripts (
SR-12). - Outputs consisting only of change it derived, allowlisted destinations,
or other destinations within its ceilings (
SR-20toSR-22). - A change index within 20 of the highest index it has signed (
SR-34). - Fees below both its rate and absolute ceilings. Each ceiling has a fixed
bound another device cannot change (
SR-40toSR-42). - Amounts within its per-transaction, daily and weekly ceilings (
SR-35,SR-36).
The initial ceilings are guesses marked “to tune” (SR-38):
| Destination | Per transaction | Per day | Per week |
|---|---|---|---|
| Not on the allowlist | 100,000 satoshis | 300,000 satoshis | 1,000,000 satoshis |
| On the allowlist | 5,000,000 satoshis | 10,000,000 satoshis | 30,000,000 satoshis |
They can be changed only on the Key app’s own screen. To enroll a cash-out
destination, scan the exchange’s deposit code with the Key app’s camera,
then wait 24 hours on that device’s clock (SR-30).
The Key app counts signatures rather than confirmed spends. It may count
more than was actually spent, but cannot undercount (SR-33). It cannot
check the owner phone’s claim that a refund is for sale 123 or is no more
than the customer paid. The ceilings limit the cost of a false claim.
Someone with the unlocked Key app device can move its clock forward and end the destination wait early. A malicious Key app build could ignore all its checks. The separate release key, independent holder, reproducible builds and independent rebuilder intended to address that risk are not in place yet.
Weekly or monthly approval reminders are not built. The Owner app runs only while open and does not send notifications.
Address batches
The counter receives a contiguous range of addresses without receiving the wallet description. The owner phone signs this batch with key 1. The Key app derives the addresses from its own wallet copy and co-signs. The counter accepts only a batch with both signatures and uses each address once. If none remain, it must stop offering Bitcoin rather than reuse one.
The Key app saves the highest signed index before releasing its signature.
A crash may waste an index, but cannot cause reuse (SR-70, design section
5.1). A batch contains at least 1,000 addresses (CR-96). Every address
shown remains watched for late payments.
The counter reads the two roots from the Key app’s own screen and pins
them at pairing. It then generates a fresh random number.
The counter displays four words derived from those roots, the wallet,
the counter’s key and the random number. The owner compares them with the
words on the Key app. The words carry 44 bits and undergo about a million
hashing rounds; they help a person check the pairing. The software also
compares full hashes (CR-91 to CR-98).
A stolen counter exposes the addresses in its batch, including future ones. This can reveal incoming payments and their timing, but does not reveal the wallet’s history, keys or access to its funds.
The instant limit and the exposure total
An unconfirmed payment can be replaced. The per-sale instant limit and shop-wide exposure budget cap how much the shop accepts before the first block. Getting paid gives the defaults and acceptance checks. These limits bound losses from failed instant sales; they cannot prevent every failure.
The design also proposes a screen saying “If every instant sale failed you would lose at most $X”, where X is the exposure budget plus the override ceilings. That combined total screen is not built yet.
When a phone is lost or stolen
The owner phone holds only key 1. A thief needs a second key to spend. Its key file is protected by a PIN of at least 6 digits or a passphrase of at least 8 characters. Argon2id uses 64 MiB and 3 passes, together with an Android Keystore key. The key files are excluded from cloud backup and device transfer.
Wrong attempts are recorded in a separate file. After the fifth wrong
attempt, the next try must wait 30 seconds. Further wrong attempts increase
the wait to 1 minute, 5 minutes, 15 minutes and 1 hour. The
tenth wrong attempt wipes key 1 from the phone. The screen explains that
the other two keys can still spend and gives the next steps (LC-01 to
LC-06, OA-60 to OA-65).
After losing the owner phone, move all funds to a new wallet with a new key
in that slot. The designed “Move to a new wallet” button, sweep and counter
re-pairing are planned. Today, the Key app treats a different wallet as a
fresh setup with empty state (SR-63).
The spare phone has the same lock and wipe (SR-71 to SR-77). Restore
key 2 from its written words to a new Key app. This starts with no
destinations, the initial ceilings and indexes at zero. All signing rules
still apply (SR-39); recovery has no mode that loosens them.
A lost counter holds neither a signing key nor the wallet description. Remove it from the owner phone, which is a tightening change, and pair a replacement. Its pairing record and manager PIN file are sealed with the Android Keystore.
A six-digit PIN has a million possible values. A computer with the locked
file could try them at the cost of Argon2 for each attempt. The additional
Keystore key requires the phone, and the app wipes after ten wrong tries
(LC-07, “What these rules do not do”). The app reports a software-only
Keystore when the phone has one. These controls depend on the software
running as intended: a rooted phone or hostile keyboard or accessibility
service can read what is displayed or typed.
The recovery kit
The proposed kit is one printed page with the wallet description and its checksum, four checksum words, the first block height, an explicit address range to import, “any two of three”, key locations and holders, and restore instructions. It contains no secret keys or seed words.
The Key app can scan the printed description and compare it byte for byte with its own. A different description with matching four words gets the most serious warning. This check is built but has not been run on a phone; it does not check the kit’s other fields. Generating and printing the kit is not built.
The Bitcoin Core restore drill passed on a test network. It established four requirements for the eventual instructions: import the specified address range rather than a default; mark the receive descriptor inactive; request version-0 PSBTs; and give the signer wallet the same range. Core finds the coins and builds the transaction without reading seed words. A separate signer that reads the words signs it.
The Sparrow restore has not been run. The kit’s restore instructions are withheld until that test is done. An annual physical check that key 3’s words remain present and readable is also in the design, not the software.
Getting paid
The counter’s sale handling is built and has been tested against Bitcoin Core on a test network. The Android app is a first build and has not been run on a phone.
An on-chain sale, as built
- Ring up the order in the POS.
- Enter the amount on the counter’s keypad in the shop’s currency. The POS does not start the counter automatically.
- Show the customer the payment code. The screen also displays the amount and the address’s first and last characters in large type.
- The customer scans the code and approves the payment in their wallet.
- When the counter turns green, close the POS order with the shop’s “Bitcoin” tender.
The code is a standard bitcoin: payment request, so any wallet that reads
that format can pay it. Each sale gets a new address, saved before it is
displayed (CR-01 to CR-09). If the connection is down, the counter stops
offering Bitcoin and asks the cashier to take another payment type
(CR-01).
Customers must scan today. NFC tap to pay is not built; the design proposes an NFC tag for Android customers. The manifest checks currently fail the build if an NFC permission appears.
Square and Clover support read-only order matching. The POS closes the
order, and the owner phone matches each Bitcoin tender to a counter sale
under docs/POS-RULES.md. The amount still comes from the cashier’s entry.
Matching can flag a discrepancy but cannot prove that goods were handed
over for a payment (section 10 of those rules). Both readers were written
from vendor documentation and have not been tried with real seller
accounts. A Clover custom tender button and Lightspeed gateway are planned.
The states a cashier sees
| Heading on the counter | Color | Meaning |
|---|---|---|
| Not paid yet | Blue | Nothing has arrived. |
| Part paid | Blue | Less than needed has arrived. Ask for the rest or cancel. |
| Waiting (with the reason, such as “Waiting: over the limit”) | Blue | A payment arrived and waits for a block. The screen says why. |
| Paid (before a block) | Green | Accepted at once within the instant limit. The screen says it could still be undone and which check accepted it. |
| Accepted by a person | Green | A cashier or manager accepted it by hand (an override). |
| Paid (in a block) | Green | The payment is in a block at the shop’s depth. |
| Paid (settled) | Green | At the shop’s refund depth: a refund can be paid out if asked. |
| Paid over Lightning | Green | The shop’s own node has the money. |
| Do not hand over | Red | The payment was replaced, its block was dropped, or the counter cannot check. |
| Needs a person | Red | The sale holds more than the counter can judge. |
| Expired, Cancelled | Neutral | Ended with nothing received. |
A non-final state explains both the reason and the next step. Waiting is
blue; it does not use the red warning screen. The complete wording is in
docs/screens/counter.md, generated from the code.
The confirmation depth starts at 1 block and the refund depth at 6. You
can change either, but cannot set either below 1. The counter recalculates
the displayed state from the watcher’s facts each time (CR-10 to
CR-12).
Which check saw the payment
The source line tells you who saw the payment, separately from its state:
| Check line | Evidence |
|---|---|
| “Light check” | The counter’s own check through Bitcoin peers saw the payment. |
| “Your Box reports it” | Only the Box has reported it so far. |
| “Your Box and light check” | Both have seen it. |
| “Your node and light check” | Both the shop’s own node and the light check have seen it. |
An own-node report alone is insufficient for the own-node label: the
counter’s light check must also see the payment (CR-104, CR-105).
What “instant” means, and the limit that bounds it
An unconfirmed payment can be replaced by its sender. Accepting one means handing over goods before the first block, with a limit on the loss the shop is willing to take.
The initial limits are:
| Check | Per sale | Outstanding total for the shop | Check line |
|---|---|---|---|
| Light check | $10 | $50 | “Light check” |
| Own node and light check | $25 | $100 | “Your node and light check” |
| Box only | $10 | $50 | “Your Box reports it” |
The light check is the default. These figures are guesses marked “to tune”, not measured risk estimates. Limits are enforced in satoshis and displayed in dollars. You can change any of them, including to zero to disable instant acceptance. Raising one needs approval as a loosening change.
Before accepting instantly, the counter checks all of the following
(policy, CR-12, CR-50):
- The amount at risk is below the per-sale limit. It uses the greater of the sale amount and the amount received: paying $5,000 for a $10 sale exposes $5,000.
- Its allocated share of the shop’s outstanding budget has room. A payment leaves this total at its first confirmation or through the owner’s action, never by timeout.
- No conflicting spend has been seen for 8 seconds.
- The light check has enough peers in different network groups, some serving compact filters, a current header chain and a sensible clock.
- The owner phone’s signed heartbeat is recent; the initial interval is 10 minutes.
- The order is being paid at the counter, rather than remotely.
- Instant acceptance is not paused. One cancel pauses it for 1 hour. A second within 24 hours disables it until the owner resets it.
- Tor is on if customers can join the shop’s Wi-Fi.
A replaced payment turns the screen red and triggers a loud alarm. Only the owner can clear it. The counter saves a signed record of both the original payment and its replacement.
The light check cannot inspect the inputs or fee of an unconfirmed payment. Different peer groups and conflict monitoring help, but the cap is what limits the shop’s loss from a fake or cancelled payment. A cancel sent privately to a miner becomes visible only when its block arrives. The screen names which check accepted the payment.
The heartbeat detects a dead or disconnected owner watcher. It comes from
the same software family and does not protect against a bad build
(CR-56). In the current apps it travels through a relay, normally the
Box. A newly created wallet has no relay configured, and neither app has
a background service. Instant acceptance therefore needs both the Owner
and Counter apps open and linked.
The initial settings assume customers can join the Wi-Fi and leave Tor off. Instant stays off until the owner answers that question. There is no public measurement of double-spend rates since full replace-by-fee on which to base the defaults; choose limits the shop can afford to lose.
Confirmations, the refund depth, and the red screen
At the confirmation depth, the screen says “Paid” and “The payment is in
a block.” At the refund depth it says “Paid” and “The payment is settled,
so a refund can be paid out if the customer asks.” The books count the
sale as money only at the refund depth (CR-31).
If the payment is replaced, dropped, or loses its block in a reorganization, the counter shows “Do not hand over goods”. It reports what it observed: “A different payment replaced this one” or “A block that confirmed this payment was replaced”. It does not guess the cause.
A cashier may override a red screen within the per-sale instant limit
and daily cap. A manager may override within a dollar ceiling. Each
override records the person’s name, time and amount, counts toward the
exposure total, and is refused when that total is full (CR-20 to
CR-22).
Late and wrong payments
| Event | What happens |
|---|---|
| Underpayment | The screen shows, for example, “Paid $8.00 of $10.00”. Ask for the rest with a new code, or cancel. The tolerance starts at 0.5% and cannot exceed 5%. |
| Overpayment | The sale is paid and the surplus is recorded as owed to the customer (CR-16). |
| Late payment | A payment to an expired or cancelled sale is recorded and flagged to the owner. It never turns another sale green (CR-19). Shown addresses remain watched until their sales settle. |
| Dust | Less than 1,000 satoshis in total is logged without changing the sale. |
| No confirmation after 2 hours | The screen adds “stuck: not confirming” and the sale stays open (CR-18). |
| Nothing received after 15 minutes | The sale expires. |
The price is locked for 5 minutes at a time. It refreshes automatically
without changing the address. It comes from at least two public sources
that must agree; only United States dollars are supported
(docs/RATE-RULES.md).
Customers request refunds at the counter. Refunds are paid in an approval session; the walkthrough belongs to the next part of the handbook.
Small sales and the shop’s own Lightning node
An on-chain fee does not scale with the sale amount, so it can be large relative to a small purchase. A Lightning-only wallet also cannot pay an on-chain address. The counter tells customers “This shop takes on-chain bitcoin”.
You can set a minimum on-chain sale. Below it, the cashier must take another
payment type (CR-75). There is no minimum by default. Each receipt also
costs the shop a fee when spent later, which is another reason to set one.
Alternatively, a shop already running LND or Core Lightning can let the counter display a code with both an on-chain address and a Lightning invoice. A Lightning payment is final immediately at any amount, without the instant limit. This counter integration is built but has never been run against a real node.
The shop must operate the node and manage liquidity, updates and backups.
OpenBMT does not do that work. Eclair is unsupported (LN-02), and
third-party swap providers are excluded from the payment path.
Privacy
A Bitcoin payment need not carry a customer’s name, but its transaction is public. An address or transaction ID can let someone connect that payment to other activity. OpenBMT keeps these details out of the POS and ordinary accounting exports, and does not upload analytics or crash data.
This network behavior is built. It has been checked against Bitcoin Core and observed on test and live networks. The apps have not been run on a phone.
Who sees what
| Party | What it sees | What you can do |
|---|---|---|
| Bitcoin peers used by the light check | The counter’s network address, that it follows the chain, and the blocks it requests | Use Tor; add the shop’s own node |
| Internet provider or carrier | That the device speaks Bitcoin and when; with Tor, that it uses Tor | Use Tor |
| DNS seeds used to find peers | The address of a device looking for peers | With Tor, seed lookups stay inside Tor rather than reaching the phone’s resolver |
| Price sources | Price requests and their timing, without a sale or address | Fetch over Tor; requests already run every 60 seconds rather than in response to sales |
| POS vendor | Every order, amount and “Bitcoin” tender, without an address or transaction ID | The vendor necessarily sees its own orders |
| An outside Box host | Order amounts and timing, without addresses, transaction IDs or the wallet description | Run the Box yourself; a hosted Box is not built yet |
| Push services | Nothing; push wake-ups are not built yet | |
| App download host | The downloader’s network address and requested version | Download over Tor |
| Customer’s phone | The address and amount for that sale | OpenBMT uses a fresh address for each sale |
| Cash-out exchange | Its deposit and the coins the owner chooses to send | Use coin control; see the accounting section below |
The counter never sends a shop address or script to a Bitcoin peer
(NR-60). It requests compact block filters, then whole blocks when a
filter matches. This reveals interest in those blocks. While waiting for
a payment’s first block, it also downloads every new block in full:
a cancelling spend is absent from the filters it could match (NR-44).
These requests do not completely conceal which blocks interest the shop
(NR-61).
Tor
With the counter’s Tor switch on, all connections, including Bitcoin peers
and price sources, go through Orbot. Orbot is a separate Android app and
must be running. If it is unavailable, the counter reports the problem
and sends nothing around it (CR-87).
The Owner app always uses Tor and will not start if Orbot is not answering
(OA-05). That includes broadcasting spends and refunds. Its behavior
does not depend on the counter’s switch.
The counter switch is off by default for speed. If customers can join its network, instant acceptance requires Tor, because a customer on the same network could feed the counter false data.
Peers use encrypted BIP324 transport when they support it. This conceals
requests from a passive listener but does not establish the peer’s
identity (NR-62). Tor hides the device’s address from peers; it does
not hide that the traffic belongs to a Bitcoin wallet (OA section 9).
Onion peers are grouped coarsely, so two onion peers do not establish two
independent operators (docs/NETWORK-RULES.md, section 8).
The shop’s own node
You can run Bitcoin Core on a Box, Umbrel, StartOS or a computer at home, and have the counter check payments against it. The node adds a check; it does not replace the counter’s light client.
The current counter accepts an own-node connection only at a Tor v3
address. The address authenticates the node through its public key. A
local-network address or plain internet address is not enough to establish
who answers, so it is not accepted as the own node (NR-98, NR-99,
CR-100 to CR-102). The counter retains its own header chain from random
peers, preventing a Box from inventing a confirmation.
The Box
The Box relays sealed messages between the shop’s devices, reads the POS and matches orders to sales. It can be reached on the local network or through an onion address. Only the recipient can read a relayed message.
It sees order amounts in the shop’s currency and their timing, as the POS
vendor does. It holds no wallet key and sees no address, transaction ID
or wallet description (BX-04, BX-40). A host can nevertheless estimate
payments by combining the orders with a public Bitcoin price. Run the
Box yourself to keep that information inside the shop
(docs/BOX-RULES.md, section 6).
The books and the export
The accountant’s export contains opaque sale IDs. It excludes transaction IDs, addresses and satoshi amounts, as do all POS fields, because those would let the recipient trace payments on the public ledger. The full ledger contains those details and is shown behind a warning.
Spending several receipts in one transaction links them on the blockchain. Someone who paid the shop, or an exchange receiving the spend, can then see that the receipts belong to one wallet. Consolidating receipts has the same effect. The app warns when offering a merge (design section 9).
Wallet fingerprints
Transactions can also reveal which wallet software built them. OpenBMT does not claim to hide that fingerprint. A wallet fingerprint detector is listed at https://btcmaxis.com/bitcoin-information/privacy.html (read 2026-11-11).
Limits and risks
OpenBMT has had internal review only and no independent security audit. None of the Android apps has been run on a phone. Do not use it with real funds.
What the protection claims, and when it does not hold
The wallet design is intended to withstand one compromised OpenBMT component, device or person without allowing a spend. That requires both of these conditions:
- Key 3 is generated outside OpenBMT software and away from the key 2 device.
- An independent second person holds the Key app’s release key.
The first is part of the setup design. The second is unmet: no second holder has been named. Reproducible builds and an independent rebuilder are also launch requirements and are not in place. The single-component protection claim does not hold today; the documents and screens say so.
Even with those conditions met, protecting the wallet does not prevent every loss at the counter. Limits bound the exposure of sales proceeds and goods, and the owner must reconcile records to catch a bad counter, app build or Box.
The threat model in plain words
| Incident | Potential loss | Protection and its limit |
|---|---|---|
| One phone stolen | One of the three keys; insufficient to spend alone | PIN, wipe and two remaining keys |
| Two keys stolen | The wallet | Keep the owner phone, spare phone and off-site steel words apart |
| Malicious main-app build | Wrong addresses or false “Paid” screens | Key app co-signing, separate release key and manual updates; release separation is incomplete |
| Counter displays its own address and reports payment | Sales proceeds until detected | Owner matching of orders to funds and the monthly outside check |
| Customer cancels an instant payment | Up to the instant limit | Per-sale and exposure limits, alarm, signed cancel record and pause |
| Hostile cashier | Up to the cashier’s caps | Per-sale and daily caps, exposure total and names in signed records |
| Compromised or hosted Box | False payment notices or withheld messages | It cannot spend, select addresses or close an order without the counter’s signature; owner independently matches orders |
| Refund sent to the wrong destination | Up to the Key app’s ceilings | Satoshi ceilings, allowlist enrollment on the Key app and review on both devices |
| Recovery kit lost along with one key | Wallet cannot be spent | Two keys are still required; reminders and inspection remain design-only |
| All reachable peers controlled by an attacker | False sightings or missed conflicts | Distinct network groups, own-node checks and disabling instant when checks are unhealthy |
What the light check cannot see
The light check asks Bitcoin peers directly. For an unconfirmed payment,
it cannot inspect input amounts, establish whether the inputs are
confirmed, or calculate the fee rate. It monitors conflicting spends and
requires different peer network groups. It does not execute scripts or
check each transaction’s coins within a block (docs/WATCHER-RULES.md,
section 8). Confirmation depth is therefore a choice about how much work
must accumulate above the payment.
An attacker controlling every reachable peer controls what the counter
sees. Distinct network groups, stored long-lived peers and Tor make this
harder without ruling it out (docs/NETWORK-RULES.md, section 8).
On signet, the header check verifies work only. Test-network results do not establish protection for real funds.
What the PIN does not stop
The phone’s key file is locked behind the PIN, and guessing is slowed. That does not protect against someone using an unlocked phone, restoring an older stored file, or obtaining both the file and the Keystore material needed for offline guessing.
A rooted phone, hostile keyboard or accessibility service can read input or displayed data. The Key app refuses to run with debugging or an accessibility service enabled, but that refusal is enforced by the app itself. A cashier PIN on the counter deters casual access only.
Phone and hardware risks
The apps run only while open. The Owner app does not follow the chain when closed, and the counter must stay open and plugged in. The Owner and Counter apps need Orbot, a separate Android app, to use Tor. Some phones offer a software-only Keystore; the app reports this on screen. The design assumes the phone is not already controlled by an attacker.
Android versions may handle wallet opening from an NFC tag differently. Tap to pay is not built and this behavior is untested.
Unverified items
| Area | What remains unknown |
|---|---|
| Hardware signers, experiment E8 | Coldcard, Jade, Passport and Keystone have not been tested for wallet acceptance, change checks or full previous-transaction requirements. Large QR transfer frame counts are unmeasured. Bitcoin Core was tested as a second signer on a test network; Sparrow was not. |
| POS readers, E5 and E6 | No real Square or Clover seller account has been used. Square’s custom-tender order fee is unknown from its pages. Clover’s virtual-currency app rules could not be read. |
| Lightning | Request and response formats came from source and documentation. No real node has been run. |
| Sparrow recovery | No restore has been run. |
| NFC tap, E1 and E10 | Not built. |
| Timings | Setup time, time to “Seen”, battery use and bandwidth have not been measured. |
| Competitor figures in the design | Marked “to verify” and excluded from merchant screens until sourced. The processor fees in Why bitcoin came from their own pages, read 2026-11-11, and may change. |
The monthly outside check
Once a month, open the recovery kit’s wallet description as watch-only in Sparrow or Bitcoin Core. Compare the receipts with the POS Bitcoin-tender total. This is the only check independent of OpenBMT’s software, and the only one that catches a counter or main-app build substituting its own address while claiming payment.
The estimate is five minutes; it has not been measured. In-app reminders and instructions are planned.
The audit status
The four internal design reviews examined remote theft, insiders, hostile customers, wallet engineering, privacy, adversarial behavior and recovery. They also checked single-component compromise and compared the first implementation with the design. They were not an independent audit.
Device testing, outside code review and an independent security audit remain necessary before OpenBMT can be considered for real funds.
Operating precautions
OpenBMT is pre-release and has had internal review only. No independent security audit has been done. Do not use it with real funds.
For general self-custody guidance from the same bitcoin purist position, see https://btcmaxis.com/. The pages linked here were read on 2026-11-11. Some procedures below remain part of OpenBMT’s design rather than controls the software enforces.
Keys
Keep key 1 on the owner phone, key 2 on a separate phone or hardware signer stored away from it, and key 3 away from the shop. Any two can spend. Storing two together removes the protection against losing or compromising one location.
Record each set of words alone, in separate sittings with nobody watching. Never keep key 2’s words with key 3’s. Use steel. Paper burns and tears, and writing can fade. As the linked guidance puts it, “Paper is not an acceptable form of backup because it is so fragile” (https://btcmaxis.com/bitcoin-information/recommended-wallets.html, read 2026-11-11). If paper is needed while stamping the steel, compare the steel with the phone, then destroy the paper. Do not retain paper as a backup.
Generate key 3 outside OpenBMT, offline, on a device holding no other key, or use a hardware wallet. Factory-reset a phone or tablet used for this step afterward.
Until an independent second person holds the Key app’s release key, prefer a hardware signer or another publisher’s signer for key 2. Hardware signers are planned and have not been tried. Before choosing one, read its public disclosure history. The “Historic Wallet Failures” list on the recommended-wallets page collects reported hardware-wallet flaws (read 2026-11-11).
Keep a current, dated recovery kit with the wallet description away from the shop, and check the description by scanning it with the Key app. Kit printing is not built yet. Once a year, inspect key 3 without exposing the words: check that the steel is still present, readable and safely kept.
PINs
Use at least six digits for the locks on keys 1 and 2, preferably a passphrase of eight characters or more. The tenth wrong attempt wipes the key from that phone. Never keep a PIN beside the words.
Cashier PINs should differ from the manager PIN. Change any PIN a former employee knew.
The phone
Keep the operating system updated and the screen lock enabled. Install apps only from known sources; do not sideload apps onto the owner or Key phone. A hostile keyboard or accessibility service can read input. The Key app refuses to run with an accessibility service enabled.
Keep the spare phone in airplane mode with no accounts on it. Leave cloud backup off for the apps. They deliberately exclude key files: each is wrapped with a key in that phone’s Keystore, so its copy could not be opened on another phone.
Tor and the shop’s own node
If customers can join the counter’s Wi-Fi, enable Tor or use cellular instead. Instant acceptance on a shared network requires Tor. The apps need Orbot running to use it.
Run your own node if you can. The counter accepts it as an own-node check only through a Tor v3 address.
The instant limit
Set the instant limit to an amount the shop can afford to lose. The default light-check limits are first guesses. Zero disables instant acceptance and makes the sale wait for a block. Overrides also count toward the exposure total.
For a large sale, the Bitcoin Confirmation Risk Calculator linked on https://btcmaxis.com/bitcoin-information/security.html (read 2026-11-11) can help choose how many confirmations to wait for. It does not change what the shop can afford to lose before confirmation.
Seed splitting
Do not split a key’s words with Seed XOR, Penlock or similar tools. The two-of-three wallet already distributes control across three keys. Splitting one adds pieces that can be lost. The linked security guidance advises “keep it as simple as possible” (https://btcmaxis.com/bitcoin-information/security.html, read 2026-11-11).
If the owner dies or cannot act
Choose who should be able to act and make sure they can reach two of the three keys. Keys 1 and 2 are on devices; key 3 is on steel. Leave the recovery kit where those people can find it: the wallet description lets other software locate the funds.
A sealed letter can state where each key is kept without containing the words themselves. OpenBMT has no company that can reset a key or open the wallet. Without access to two keys, nobody can restore it. Ask a lawyer whether a will or trust should name the people who can act.
The security page links inheritance resources: https://btcmaxis.com/bitcoin-information/security.html (read 2026-11-11).
Cash-out and what the shop keeps
If keeping bitcoin, move it regularly from the shop wallet to long-term storage the shop controls. Leave only working amounts in the wallet the counters pay into, and approve the transfers in an approval session.
Enroll a cash-out destination by scanning it on the Key app, then wait 24 hours. Consolidating small receipts links them on the public ledger; do it deliberately, when fees are low.
Staff
Give each cashier a name and PIN so the records identify who acted. The cashier list is local to that counter phone. There is currently one manager PIN; give it only to the person running the counter.
If a phone is lost
| Phone | Response |
|---|---|
| Owner | Treat the loss as urgent and follow the recovery kit. The phone holds one key of three. Moving to a new wallet is the designed response, but the “Move to a new wallet” feature is not built yet. |
| Spare Key phone | Restore key 2 from its words on a new phone. The restored Key app starts with its initial ceilings. |
| Counter | Remove it on the owner phone and pair a replacement. |
Test recovery first
Test restoration with a small amount before depending on the wallet for more. A Bitcoin Core restore has been run on a test network; a Sparrow restore has not. Both are used watch-only: the keys never go into them. The linked guidance advises newcomers against putting keys in a node’s built-in wallet.
Each month, open the wallet description watch-only in Sparrow or Bitcoin Core and compare the receipts with the POS Bitcoin-tender total. This checks the records using software outside OpenBMT.
Verify what you download
Check the app’s signature and published hash before installation. Reproducible builds are not available yet. The hash establishes that you have the file the publisher released; it cannot establish that the build matches the source.
Glossary
Address batch. A contiguous range of receive addresses assigned to one counter, signed by key 1 and co-signed by the Key app.
Approval session. The owner reviews queued items with key 2 available. The owner phone presents them; the Key app checks and signs the approved items. Money movements and loosening changes require a session.
Approver. A Key app holding an identity key but no wallet key, used when key 2 is a hardware wallet.
BC-UR. A format used by Sparrow and hardware wallets to transfer data through animated QR codes.
BIP321. The standard for a bitcoin: payment request.
Box. The shop’s optional server for relaying device messages and reading POS orders. It holds no wallet key.
Change. Money returned to the shop’s wallet by its own spending transaction.
Compact block filter. A small summary used by a light client to find blocks that might contain a relevant transaction.
Confirmation. Inclusion of a payment in a block. The shop’s confirmation depth starts at 1 block and its refund depth at 6. A refund can be paid at the latter. Both show “Paid”, with text distinguishing the depth.
Counter. The phone or tablet displaying the sale and payment code. It holds no wallet signing key.
Descriptor (wallet description). Text describing how to derive the wallet’s addresses from its three public keys.
Exposure. Instant sales still waiting for their first block.
Full node. A computer that checks every block itself. Running one is optional for the shop.
Heartbeat. A signed message from the owner phone telling the counter that the owner’s watcher is running.
Instant. Acceptance before the first block, within the shop’s limit.
Key app. The separate app holding key 2 and providing the second approval.
Light check. A check through Bitcoin peers and compact block filters without running a full node.
Loosening / tightening. A settings change that permits more risk, or one that reduces it.
Multisig, two of three. A wallet requiring any two of its three keys to spend.
Orbot. A separate Android app providing Tor connections to other apps.
PSBT. A standard transaction file passed between signers.
Recovery kit. A printed page of wallet recovery information, without secret keys or seed words.
Release key. A key signing an app for distribution, separate from the wallet’s keys.
Reorganization (reorg). Replacement of blocks by a different set of blocks.
Root. An owner-phone or Key-app identity key pinned by a counter at pairing.
Satoshi (sat). One hundred-millionth of a bitcoin.
Tor. A network that hides where a connection originates.
xpub. A public key used to derive addresses without being able to spend.