Blackbox Devlog #10: prepaid card and tap-to-pay support added
Prepaid card support:
- A tap reads the card’s balance and counter, checks whether the sale is allowed, writes the new balance back, and signs the result; no server, no live transaction
- The terminal holds a debit key that can spend down a card but cannot create value; issuing and loading stay in the Vault, which holds the on-chain reserve behind each card
- Settlement is a separate, later act: the terminal journals every completed tap and batches them to the Vault when it can; until then it runs on an unsettled cap, bounding the worst case of a terminal that never phones home
- Currently a demo tier running on cheap NTAG cards with a custom MAC rather than the DESFire EV3 secure element the shipping card will use; disabled by default behind a compile-time flag
Handling failed taps:
- Every debit is written to a journal as an intent before the card is touched, removed only once the card write is confirmed; a card pulled mid-write, a power loss, a reader glitch each land in a state the terminal can name and recover from
- A write known not to have landed charges nothing; a write whose outcome is unknown parks until the same card is tapped again, resolving to exactly one charge or none
- Cards were yanked mid-write deliberately five times at the bench; the ledger came out with five charges, no doubles, no losses
- A sale cancelled at the instant of card write raises a flag the cashier must acknowledge, and the same card is refused a second tap until they do; the guard is held until cleared, not on a timer
Vouchers and staff keys:
- Item vouchers put a product rather than a balance on a tag, each backed by a chain cell that closes automatically once settlement lands
- Staff keys use the cryptographic originality signature NXP puts on genuine NTAG silicon; a price override requires a staff tag. The demo cards turned out to be counterfeit and cannot produce this signature, which is precisely why staff authorisation uses it
Bug: UI freeze under concurrent flash writes:
- The confirmation screen began freezing hard after a successful card debit followed immediately by a settlement sync
- Cause: an SPI flash write on the ESP32-S3 briefly stalls the other CPU core; the journal task was unpinned, so it ran on the core opposite the UI, dropping the UI’s clock tick mid-sleep
- Fix: pin flash-writing tasks to the same core as the UI, so the stall lands on the networking core; seventeen hours of uptime and a full bench run with no recurrence. The same latent bug was found and fixed in the Bitcoin header path before it surfaced
Also:
Add Item form now has a Scan barcode button that arms the scanner in place and drops the code into the field, keeping name and price already typed
Space bar on the Add Item keyboard was hidden under the footer bar; fixed
Next: watchdog for a genuinely wedged terminal, certificate pinning so settlement cannot be spoofed on a hostile network, on-device voucher and staff key support, and the DESFire secure-element card once stock arrives.
Full devlog: blackbox.wyltekindustries.com
Prepaid card support:
- A tap reads the card’s balance and counter, checks whether the sale is allowed, writes the new balance back, and signs the result; no server, no live transaction
- The terminal holds a debit key that can spend down a card but cannot create value; issuing and loading stay in the Vault, which holds the on-chain reserve behind each card
- Settlement is a separate, later act: the terminal journals every completed tap and batches them to the Vault when it can; until then it runs on an unsettled cap, bounding the worst case of a terminal that never phones home
- Currently a demo tier running on cheap NTAG cards with a custom MAC rather than the DESFire EV3 secure element the shipping card will use; disabled by default behind a compile-time flag
Handling failed taps:
- Every debit is written to a journal as an intent before the card is touched, removed only once the card write is confirmed; a card pulled mid-write, a power loss, a reader glitch each land in a state the terminal can name and recover from
- A write known not to have landed charges nothing; a write whose outcome is unknown parks until the same card is tapped again, resolving to exactly one charge or none
- Cards were yanked mid-write deliberately five times at the bench; the ledger came out with five charges, no doubles, no losses
- A sale cancelled at the instant of card write raises a flag the cashier must acknowledge, and the same card is refused a second tap until they do; the guard is held until cleared, not on a timer
Vouchers and staff keys:
- Item vouchers put a product rather than a balance on a tag, each backed by a chain cell that closes automatically once settlement lands
- Staff keys use the cryptographic originality signature NXP puts on genuine NTAG silicon; a price override requires a staff tag. The demo cards turned out to be counterfeit and cannot produce this signature, which is precisely why staff authorisation uses it
Bug: UI freeze under concurrent flash writes:
- The confirmation screen began freezing hard after a successful card debit followed immediately by a settlement sync
- Cause: an SPI flash write on the ESP32-S3 briefly stalls the other CPU core; the journal task was unpinned, so it ran on the core opposite the UI, dropping the UI’s clock tick mid-sleep
- Fix: pin flash-writing tasks to the same core as the UI, so the stall lands on the networking core; seventeen hours of uptime and a full bench run with no recurrence. The same latent bug was found and fixed in the Bitcoin header path before it surfaced
Also:
Add Item form now has a Scan barcode button that arms the scanner in place and drops the code into the field, keeping name and price already typed
Space bar on the Add Item keyboard was hidden under the footer bar; fixed
Next: watchdog for a genuinely wedged terminal, certificate pinning so settlement cannot be spoofed on a hostile network, on-device voucher and staff key support, and the DESFire secure-element card once stock arrives.
Full devlog: blackbox.wyltekindustries.com