connector), one reads (listener), all keys in Fireblocks. The
chain is the slow async edge. Web3 is a backend concern; the UI is orchestration + monitoring.
WRITE: Dashboard FE ─REST▶ token-service/asset-adapter ─Bus▶ connector ▶ Fireblocks ▶ CHAIN READ: CHAIN ─events▶ listener ▶ DB + TRANSFER_EVENT_TOPIC ▶ token-service ▶ recon
| Networks | EVM (Ethereum, Polygon, Avalanche), XRPL, Stellar, Solana (Token-2022) — main+test |
| Custody/signing | Fireblocks (@fireblocks/ts-sdk); keys never leave vaults (MPC/TSS) |
| EVM library | viem |
| RPC | Alchemy / QuickNode / Blockdaemon (per-network from DB) |
| Token standard | ERC20F & ERC20MN01 (proxy + impl) + separate AllowList contract; native on XRP/XLM/SOL |
| Service | Role |
|---|---|
| connector (TS) | Only writer. Consumes DEPLOY/CHAIN_ACTION queues; deploy, MINT, BURN, TRANSFER, DIVIDEND, trustlines, Solana freeze. Per-chain handlers; SHA-512 idempotency; writes transaction_out. |
| listener (TS) | Only reader. Per-chain event subscriptions → normalize to ChainEvent (TRANSFER/WHITELIST) → DB + TRANSFER_EVENT_TOPIC. |
| token-service (Express) | REST token lifecycle: subscribe/redeem/dividend/orders. Whitelist/KYC + limits. Escrow (subscribe=mint, redeem=burn). DvP with FundNode. Fireblocks webhooks (JWS-verified). |
| asset-adapter (Spring) | Deployment state-machine (per-chain deployment.yml); processes MINT_SUPPLY/BURN_SUPPLY/TRANSFER/CLONE into distribution records. |
| mna-service (NestJS) | Provisions Fireblocks vaults/addresses; FIREBLOCKS vs BYO wallets; gas auto-fuel; token↔wallet binding. Maker-checker on every op. |
| recon-service | Reconciles on-chain (transaction_out, distributionOut) vs off-chain ledger → MATCHED/UNMATCHED. |
dashboard (Next.js): issuance forms, manage (subscribe/redeem/transfer/mint/burn/whitelist),
monitor (tx history, holder registry, explorer links), holdings. Uses bignumber.js + mnxp; no raw web3.
admin (React/Vite): wallet/network lifecycle, maker-checker (202 + changeRequestId). Only web3 use: viem getAddress/isAddress for checksum validation.
connector + token-service + asset-adapter + gatekeeper collapse into gateway-backend
(already has src/infra/blockchain/ with the same Fireblocks/viem handlers). Only listener
and recon stay separate. "The blockchain client" becomes an in-process module.