The problem
Universal Machine needed a backend that could serve a user base in the hundreds of thousands while a hardware-adjacent mobile client talked to it continuously. The unusual part was the client: a cross-platform React Native app using Bluetooth Low Energy, NFC and QR codes, which means the API had to tolerate clients that are intermittently connected, frequently retrying, and often operating on stale local state.
That is a different problem from ordinary web traffic. A browser client that loses connection simply fails a request; a BLE-driven mobile client will happily replay a half-finished interaction minutes later.
What I owned
I led and delivered the backend API, and I built the React Native client surfaces that consumed it, so I owned both sides of the contract. I also integrated the smart contract and wallet flows on the frontend.
Decisions and tradeoffs
Owning both sides let me push complexity to whichever side could absorb it more cheaply. For the intermittently-connected clients, that meant designing the mutating endpoints to be safely retryable rather than trying to make the mobile client’s connection reliable — you cannot fix BLE flakiness from the server, so the API had to assume duplicate delivery was normal rather than exceptional.
The cost of that choice is that every write path carries more bookkeeping, and the client has to hold onto request identity across app restarts. The alternative — treating retries as an error case and reconciling later — would have been faster to build and would have generated a long tail of support issues.
Outcome
The API went into production serving 400,000+ users and handling millions of requests. The same service backed the BLE, NFC and QR flows in the mobile app without a separate edge layer in front of it.