MyNEX Docs / Overview
v1 API Sandbox-first
Platform documentation

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.

MyNEX's answer

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

01

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.

02

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.

03

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.

Mobile App Flutter · iOS / Android Admin Console Vue 3 + TypeScript Backend API Go · Fiber · GORM · cmd/server PostgreSQL ledger, wallets, ops Redis sessions, quotes, PIN locks Solana SPL Token NAQD primary chain (sandbox default) Polygon ERC-20 NAQD secondary chain (sandbox default) Stripe · Apple Pay · Google Pay Payment providers (sandbox default) BML · MIB · SBI · BOC Maldivian bank rails (local_bank) Metals-API · CoinGecko XAG/USD oracle sources Touch 'n Go eWallet (MY) Partner rail — sandbox implementation Every external integration sits behind a Go interface (PaymentProvider, ChainClient, CardProcessor, PartnerRail) with a sandbox implementation selected by env config — see Architecture.
Two frontends, one Go backend, one Postgres, one Redis — every external integration is optional and sandboxed by default.

Tech stack

LayerTechnologyNotes
Backend APIGo 1.23, Fiber, GORM, decimal.Decimal for moneySingle binary, cmd/server/main.go; monolith, not microservices
DatabasePostgreSQL 15GORM AutoMigrate on every boot — no separate migration framework in active use
Cache / sessionsRedis 7sessions, rate limiting, PIN lockouts, FX/partner quote TTLs, idempotency locks, event fan-out is in-process, not Redis pub/sub
Mobile appFlutter, Provider, go_router, DioiOS + Android, biometric + PIN security, design-token theme system
Admin consoleVue 3 (Composition API), Pinia, TypeScript, Tailwind CSS, Chart.jsRBAC-gated views, native WebSocket client with reconnect/backoff
NAQD chainsSolana SPL Token (primary), Polygon ERC-20 (secondary)Custodial treasury address per chain; sandbox in-memory chain by default
PaymentsStripe, Apple Pay, Google Pay, local bank gatewayAll behind one PaymentProvider interface; sandbox provider needs no keys
Reverse proxynginxdeploy/nginx/nginx.conf — routes /api, /ws, static admin SPA
ContainersDocker Compose (prod + dev)deploy/docker-compose.yml / docker-compose.dev.yml

Repository layout

my_nex/
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
A note on docs/wiring/*.md

The 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

PageWhat's in it
ArchitecturePackage map, request lifecycle (CORS → rate limit → auth → idempotency → handler), the provider-interface philosophy, background workers
The LedgerDouble-entry accounts, locking, worked examples for every money-moving flow, the card-hold design
Data FlowsSeven end-to-end sequence diagrams: top-up, P2P, NAQD mint, on-chain withdrawal, card auth→capture, TnG reload, admin WebSocket
API ReferenceEvery registered route grouped by domain, the envelope + error vocabulary, idempotency semantics, the WebSocket event catalog
SecurityJWT architecture, PIN guard, 2FA, RBAC, maker-checker, mobile security posture, known limitations — stated honestly
NAQDPeg math, oracle aggregation + fallback, custodial chain design, reserve accounting, mint/burn/withdraw lifecycles
Mobile AppFlutter architecture, design tokens, feature module map, what's real vs. not-yet-built
Admin ConsoleModule map, RBAC-driven UI, the WebSocket live layer and its current gaps
RunbookPrerequisites, make targets, docker compose, sandbox mode, going-live checklist, full env var reference