Field note
Building CQR Vault: Keeping Financial State Consistent in Real Time
Database transactions, WebSocket updates, and the work of connecting a precious-metals platform across mobile, web and administration.
- WebSockets
- React Native
- Next.js
- Fintech
- Precious metals
- Real-time
CQR Vault brought three kinds of live activity into the same product: conversations between users, events from the application, and changing metal prices. We used WebSockets for all three. Alongside them, we built wallet functionality and the workflows through which users could manage and transfer assets.
The difficult part was maintaining state. A financial operation had to produce a coherent result in the database, and the application had to present information that made sense as users interacted with it. A changing price, a new message and an update about an operation could all demand attention from the interface, while carrying very different meanings.
I led development on CQR Vault at KryptoMind, working across the mobile application, web experience and admin panel. The work described here was a team effort. My involvement across those interfaces meant dealing with both the operations behind the product and the way people encountered their results.
The operating model behind the application
CQR Vault combined digital-asset functionality with precious-metals workflows, including gold and silver. The client managed the physical metal reserves himself in secure storage. Our software maintained the application records and the operations performed against them.
Those operations were maintained in the database using database transactions. They involved no on-chain processing. The product also included decentralized wallet functionality, alongside the database-managed workflows discussed here.
This operating model placed the responsibility for application state in our own system. The database recorded the outcome of an operation. The mobile app, web app and admin panel provided different ways to interact with that information. WebSockets carried live communication and updates between the application and its connected users.
Using database transactions to preserve an operation
We used database transactions to maintain the state of the operations handled within CQR Vault. They provided a boundary around related database changes.
A simplified transfer illustrates why that boundary matters. An operation might involve reducing one recorded holding, increasing another and recording what took place. Those changes need to describe one outcome. If only some of them persist, the database can contain individually valid records that collectively represent an incomplete operation.
The relevant property is transaction atomicity: the changes included in a transaction commit together, or the transaction is rolled back. This gives an application a way to preserve a group of related writes as one unit.
Choosing that unit is an application-design decision. The application has to identify which changes belong together and what conditions make the operation valid. Atomicity preserves the grouping of writes it receives; the business rules determine whether those writes describe an acceptable outcome.
Concurrency adds another concern. The behavior of overlapping operations depends on the database's transaction isolation and the way the application reads and updates data. Atomicity explains whether a group of changes takes effect together. Isolation concerns how concurrent transactions interact. Both matter when reasoning about financial state.
Three uses of WebSockets, three meanings of an update
We built real-time user chat, application events and live metal-rate updates using WebSockets. The protocol provides two-way communication over an established connection, giving the application a channel for exchanging messages as activity occurs.
Within CQR Vault, the three features used that capability for different purposes:
Swipe horizontally to view the full table.
| Live feature | What the update represented | Its role in the product |
|---|---|---|
| User chat | A message exchanged between participants | Supporting conversation within the platform |
| Application events | Information about activity or an operation | Keeping users informed about changes relevant to them |
| Metal rates | New price information | Providing current market context for the metal-related experience |
These features used the same protocol, while the information had different lifetimes. A conversation accumulates messages. A current-price display can be superseded by a newer rate. Information about a financial operation has to be interpreted against that operation's progress and recorded outcome.
That made the interpretation of a message part of the state-management problem. A client needed to know what had changed and how that change related to the information it was already presenting.
The difficult boundary between recorded state and visible state
Maintaining state was the most demanding part of this work. A stored result and the screen that displays it have different lifecycles.
A database transaction establishes a stored result. A connected client learns about activity through responses and events, then represents that information in its own state. The user experiences the operation through that representation: what the screen shows, what it says has happened and what action appears available next.
The boundary has two useful failure cases to consider. If a system announces success before its database transaction commits, the transaction could subsequently fail. If it commits successfully and then fails to deliver the update, the stored result exists while a client may still show an older view. These are general consequences of coordinating database writes and event notifications.
Those cases explain why database completion and client visibility have to be reasoned about separately. The database transaction protects the changes within its scope. Communicating the result involves the application's event handling and the receiving client.
The meaning of an event therefore matters as much as its arrival. Information that a request has been received carries a different promise from information that the requested change has been recorded successfully. A user-facing status needs to preserve that difference.
For CQR Vault, that relationship connected the database work to the live features: an action, its recorded outcome and the information presented about it all belonged to the same user experience. The complexity lay in maintaining a coherent account of the operation as it moved through those parts of the application.
The distinction also affects how a problem should be understood. An incorrect stored result and an outdated screen call for investigation in different parts of the system. Both can appear to a user as an incorrect balance or status. Reasoning about them requires following the operation through the application, rather than judging its state from one visible value alone.
Live metal rates added another kind of changing state
Metal rates were a separate source of live information. We delivered those updates through WebSockets as part of the precious-metals experience.
Price information changes for reasons independent of a user's actions. A person can hold the same quantity of an asset while its market price changes. That creates two distinct concepts for the application to represent: the recorded quantity and the current price information associated with it.
This distinction is especially useful in a product that combines asset management with a live market view. A change in a displayed value can reflect a new rate, an asset operation or both. The interface needs enough context for the user to understand what changed.
The rate feed introduced a timeline independent of the application's own operations. A new price could arrive without a user buying, selling or transferring anything. Handling those updates alongside financial activity required a clear understanding of which values described holdings and which described the market.
Building the mobile, web and administrative experiences
Our client work used React Native for the mobile application and React with Next.js for the web interfaces. We also built the admin panel. Working across these surfaces made the relationship between application state and presentation a recurring concern.
Mobile adds an application lifecycle to that problem. A React Native app can move between foreground and background states. A user's attention can leave the app while activity continues elsewhere in the system. That makes the freshness of the displayed information a separate consideration from whether the screen itself has been rendered successfully.
The web experience presents another view of the same product. Users need the meaning of an operation to remain understandable across interfaces, even when the screens and interaction patterns differ. A status has to communicate the same underlying outcome wherever it is presented.
Administration introduces an operational perspective. The user is concerned with their own action and its result; an administrator needs the context relevant to managing the platform. Building both sides makes the quality of the underlying state model consequential beyond a single screen. It affects how the product can be understood and operated.
What building CQR Vault required
The team delivered a product spanning mobile, web and administration, with wallet functionality, user chat, live application events and metal-rate updates. Database transactions supported the financial operations maintained inside the platform, while the client remained responsible for managing the physical reserves.
Working across those parts made state management a product responsibility for me. A financial feature needed to be understood through the action a user initiated, the changes the system recorded and the account of those changes that the user eventually saw. Following that state through the application connected my work on the underlying operations to the mobile, web and administrative experiences we delivered.