MyNEX — a Maldivian e-wallet, a silver stablecoin, and a way around the dollar shortage
MyNEX is a full-stack e-wallet platform: a Go backend with a double-entry ledger at its
core, a Flutter mobile app, and a Vue 3 admin console. This site documents the system as
it actually exists in the repository today — every claim here has been checked against
mynex-backend/internal, mynex_mobile/lib and mynex-admin/src,
not just against the design docs.
Why MyNEX exists — the Maldivian dollar crisis
The Maldives runs a chronic USD shortage. The rufiyaa's official peg sits at 15.42 MVR/USD, but the parallel/street market trades 18.5–18.9 — a persistent, double-digit gap between the rate the government publishes and the rate anyone can actually get dollars at. Since June 2025, banks must surrender 90% of their FX proceeds to the Maldives Monetary Authority, which chokes the supply of dollars available to ordinary banks even further.
The practical effect lands on individuals and businesses: Bank of Maldives caps USD card spending (limits that swing between roughly $100 and ~$1,500/month by customer tier) and caps digital foreign payments at 30 transactions/month. Subscriptions, travel, overseas education, e-commerce, and topping up an e-wallet while transiting through a hub like Malaysia all become genuinely hard to pay for — not because people lack money, but because they lack accessible dollars.
Give Maldivians a store of value that is neither scarce USD nor inflation/peg-exposed MVR, and cross-border payment rails that settle without needing a bank's dollar allocation at all.
Three pillars
The e-wallet
Multi-currency wallets (MVR / USD / NAQD), P2P transfers, QR pay, bill pay, top-ups from bank transfer, card, Apple Pay, Google Pay and crypto — the day-to-day product.
NAQD — the silver coin
1 NAQD = 1 gram of silver, priced off a live XAG/USD oracle. Solana SPL primary, Polygon ERC-20 secondary, custodial-first. A store of value outside both MVR and USD.
Cross-border rails
Virtual/physical cards and partner rails — first corridor Touch 'n Go eWallet reload (Malaysia) — so users spend abroad funded from their wallet, not a bank's dollar quota.
Component map
One Go binary (cmd/server) is the entire backend — no microservices, no
message queue. It talks to Postgres for durable state, Redis for sessions/rate-limits/quote
caches, and a set of external integrations that are all sandboxed by default
(see Runbook → Sandbox mode). Two independent frontends —
the Flutter mobile app and the Vue admin console — talk to it over the same versioned REST
API plus one WebSocket for the admin dashboard.
Tech stack
| Layer | Technology | Notes |
|---|---|---|
| Backend API | Go 1.23, Fiber, GORM, decimal.Decimal for money | Single binary, cmd/server/main.go; monolith, not microservices |
| Database | PostgreSQL 15 | GORM AutoMigrate on every boot — no separate migration framework in active use |
| Cache / sessions | Redis 7 | sessions, rate limiting, PIN lockouts, FX/partner quote TTLs, idempotency locks, event fan-out is in-process, not Redis pub/sub |
| Mobile app | Flutter, Provider, go_router, Dio | iOS + Android, biometric + PIN security, design-token theme system |
| Admin console | Vue 3 (Composition API), Pinia, TypeScript, Tailwind CSS, Chart.js | RBAC-gated views, native WebSocket client with reconnect/backoff |
| NAQD chains | Solana SPL Token (primary), Polygon ERC-20 (secondary) | Custodial treasury address per chain; sandbox in-memory chain by default |
| Payments | Stripe, Apple Pay, Google Pay, local bank gateway | All behind one PaymentProvider interface; sandbox provider needs no keys |
| Reverse proxy | nginx | deploy/nginx/nginx.conf — routes /api, /ws, static admin SPA |
| Containers | Docker Compose (prod + dev) | deploy/docker-compose.yml / docker-compose.dev.yml |
Repository layout
my_nex/
├── mynex-backend/ Go API — Fiber, GORM/Postgres, Redis
│ ├── cmd/
│ │ ├── server/ the actual entrypoint (main.go)
│ │ ├── migrate/ manual AutoMigrate trigger (CLI)
│ │ └── tools/ seed_admin, seed_exchange_rates, reconcile, demo/test users
│ ├── internal/
│ │ ├── api/ routes, middleware, handlers
│ │ ├── core/ config, database, apperr, utils
│ │ ├── models/ GORM models
│ │ ├── ledger/ double-entry ledger engine
│ │ ├── auth-service/ user-service/ kyc-service/
│ │ ├── wallet-service/ fx-service/
│ │ ├── payment-service/ (+ providers/)
│ │ ├── oracle-service/ stablecoin-service/ blockchain-service/
│ │ ├── card-service/ partner-service/
│ │ ├── notification-service/ admin-service/
│ │ ├── pinguard/ transaction PIN guard
│ │ └── events/ in-process pub/sub bus
│ └── migrations/ present but empty — schema is AutoMigrate-only
├── mynex_mobile/ Flutter app (lib/core, lib/features/*)
├── mynex-admin/ Vue 3 + TS admin console (src/)
├── deploy/ docker-compose (prod + dev), nginx config
├── docs/ blueprint, API contract, wiring notes, this site
└── scripts/ run_backend.sh, run_flutter.sh convenience wrappers
docs/wiring/*.mdThe four wiring documents under docs/wiring/ were written mid-build, when
several route groups, workers and AutoMigrate entries genuinely weren't wired up yet and the
docs said so ("not called from routes.go yet"). As of this snapshot, every one of
those integration steps has landed — every route group is mounted, every worker
starts, every model auto-migrates. Read those documents as a build changelog / design-rationale
record, not as a live TODO list. This site reflects the current, wired-up state.
How to read this site
| Page | What's in it |
|---|---|
| Architecture | Package map, request lifecycle (CORS → rate limit → auth → idempotency → handler), the provider-interface philosophy, background workers |
| The Ledger | Double-entry accounts, locking, worked examples for every money-moving flow, the card-hold design |
| Data Flows | Seven end-to-end sequence diagrams: top-up, P2P, NAQD mint, on-chain withdrawal, card auth→capture, TnG reload, admin WebSocket |
| API Reference | Every registered route grouped by domain, the envelope + error vocabulary, idempotency semantics, the WebSocket event catalog |
| Security | JWT architecture, PIN guard, 2FA, RBAC, maker-checker, mobile security posture, known limitations — stated honestly |
| NAQD | Peg math, oracle aggregation + fallback, custodial chain design, reserve accounting, mint/burn/withdraw lifecycles |
| Mobile App | Flutter architecture, design tokens, feature module map, what's real vs. not-yet-built |
| Admin Console | Module map, RBAC-driven UI, the WebSocket live layer and its current gaps |
| Runbook | Prerequisites, make targets, docker compose, sandbox mode, going-live checklist, full env var reference |