Crypto asset trust management platform: landing, investor dashboard and admin
Investors see their balance, trades and fees on live data from the trading terminal, and the website calculator uses the same code as the server — the numbers match everywhere.
In short: in eight weeks (August–September 2026) we built a complete platform for a crypto asset trust management company: a public website with a calculator, an investor dashboard fed by MetaTrader 5, a separate admin panel reachable only over VPN, an AI support chat and a mobile app. The high-water-mark fee is calculated by one shared code package on the website and on the server, so the numbers are identical everywhere.
The client and the brief
The client is a Ukrainian company that manages investors’ crypto assets under contract (we will name it once the client approves). It came with a detailed specification covering:
- a public website: how it works, strategies, security, team, FAQ and a returns and fee calculator;
- an investor dashboard: balance, trades, open positions, monthly fees, reports and contracts;
- a closed admin panel for operators;
- high-water-mark fees: a performance fee is charged only on new profit above the account’s previous peak.
The key acceptance requirement: the website calculator, the dashboard and the reports must show the same numbers.
Constraints
- Money and trust. A fee calculation error means a dispute with an investor, and every promise on the website has to be true.
- Sensitive data. Trading account passwords, tokens and client data. One investor must never see another’s account.
- Terminals run in-house. Trading happens in MetaTrader 5 terminals hosted by the company. The dashboard has to read from the terminal, not from manual reports.
- Several ways to connect an account. The spec listed multiple models — deposit, API key and future ones — to be added without rewriting the core.
- A small team. One stack, so a single full-stack developer can maintain it.
The solution: architecture and stack
A TypeScript monorepo (pnpm workspaces and Turborepo). One language on the front end and back end gave us the most important thing: shared fee code.
| Part | Technology | What it does |
|---|---|---|
| Website and dashboard | Next.js (App Router), React | Landing pages, calculator, investor dashboard |
| Core API | NestJS, PostgreSQL | Users, accounts, terminal data intake, fees, contracts, support |
| Admin panel | A separate NestJS service | Statistics, users, blocking, sessions, contracts, audit log |
| Fee engine | A standalone pure TypeScript package | Monthly high-water-mark calculation, identical on the site and the server |
| Connection models | A contract package and a registry | A new way to connect an account is a new module; the core stays untouched |
| Infrastructure | Docker, Caddy, OpenVPN | Images built locally and shipped to the server; the admin lives only on the VPN network |
Stage 1. Foundations and the fee engine
Architecture first: the monorepo, the fee engine package with tests against a reference data set and edge cases, the connection model contract with its registry, and the first two models as plugins. A dedicated CI check stops anyone from quietly changing the fee rate in code.
Stage 2. The public website
A design system built on CSS tokens with light and dark themes, a home page of 16 sections and nine pages following the spec’s sitemap, and a live equity chart with the high-water-mark line. The calculator imports the same package as the server. A disclaimer sits under the return projection, and we reviewed the copy so the site never claims more than the platform does. Later the site moved to a black-and-white palette with a yellow accent, and fonts are self-hosted.
Stage 3. MetaTrader 5 integration
- An Expert Advisor in the terminal sends a full account snapshot to the server; trades are stored by ticket number, so re-sending never creates duplicates.
- Every account has its own ingest token, and the token alone decides which account the data is written to.
- Data intake is abstract: a new trading platform is a new adapter, while storage, snapshots and fees stay the same.
- Clients never type a broker’s technical server name: they pick the broker from a list and an operator enters the exact name after the terminal logs in. A terminal logged into the wrong account is flagged immediately.
Stage 4. The investor dashboard
Google sign-in with a server-side session, a KPI dashboard, a 12-month equity chart, live trades and open positions, a monthly fee statement, contracts and invoices. The dashboard tells “failed to load” apart from “no data yet”: there are no mock-ups, and an empty state says so honestly.
Stage 5. Admin, AI support and mobile
- The admin panel is a separate service with no public port: access requires a VPN profile issued by the company plus an operator login with attempt limits. Every action is written to an audit log in the same transaction as the change. Blocking a user ends all their sessions immediately but does not stop trading on the account.
- An AI support chat in the dashboard with streaming replies. The model runs locally in Docker or through any OpenAI-compatible provider, and everything it knows lives in a single knowledge file.
- Mobile: the dashboard installs as a PWA with a bottom tab bar, there is an Android app (Trusted Web Activity) and a home-screen profile for iPhone. Trading notifications arrive via a Telegram bot and push.
Challenges and how we solved them
- Identical numbers everywhere. Instead of two implementations of the formula (site and server), one tested package. The acceptance criterion is met by architecture, not by manual reconciliation.
- Trading passwords. Encrypted with AES-256-GCM, never returned to the browser, and wiped once the contract is running if nobody revealed them.
- Client isolation. Each account is tied to its owner, the API never returns someone else’s account, and a strict Content Security Policy lets the browser talk only to its own domain.
- Spoofing the AI chat context. The browser sends only the new message and the server loads history from the database, so nobody can inject a fake assistant reply or system instruction. Limits apply per user, overall and per IP address.
- Google sign-in inside the app. Google blocks sign-in in a plain WebView, so the Android app uses Trusted Web Activity: it runs on Chrome, and new website features appear without re-publishing the APK.
Results
We do not publish the platform’s financial or business metrics; they belong to the client. What the company got:
- investors see real terminal data in the dashboard, not mock-ups;
- fees are transparent and identical on the site, in the dashboard and in reports;
- the admin panel is unreachable from the internet, and every operator action leaves a trace;
- new connection models and trading platforms are added as modules;
- the dashboard works on a phone like an app.
Scope: 124 commits between 3 August and 25 September 2026, from an empty repository to production with a one-script deploy.
What you can apply to your business
- If a number matters, calculate it in one place. A package shared by front end and back end removes a whole class of discrepancies.
- Your admin panel does not need to face the internet. A VPN and a closed network beat any password.
- Design for extension: plugins and adapters are cheaper than rewriting the core.
- An honest empty state beats demo data a client may mistake for the real thing.
- PWA and TWA put your product on a phone without a separate native build.
Wondering whether an AI assistant would help your customers? Start with our piece on AI agents for business.
Related services and reading
- Web platforms and SaaS: dashboards, roles, integrations
- Business process automation and AI services
- Problem: you’ve outgrown your tools
- Another platform: a digital AI university
Planning a client portal or a financial service? Send us your spec or describe the idea and we will review the architecture and estimate the phases.
