feat: split Z Ecosystem from OMNL/DBIS with separate builds and deploy
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m14s
CI/CD Pipeline / Security Scanning (push) Successful in 2m34s
CI/CD Pipeline / Lint and Format (push) Failing after 40s
CI/CD Pipeline / Terraform Validation (push) Failing after 24s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 26s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 37s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 22s
Validation / validate-genesis (push) Successful in 24s
Validation / validate-terraform (push) Failing after 24s
Validation / validate-kubernetes (push) Failing after 9s
Validation / validate-smart-contracts (push) Failing after 10s
Validation / validate-security (push) Failing after 1m22s
Validation / validate-documentation (push) Failing after 17s
Verify Deployment / Verify Deployment (push) Failing after 47s

Add VITE_ECOSYSTEM build profiles, Z-only nginx vhosts, standalone Z production stack script, and remove Z Chain from OMNL registry.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-07 05:17:40 -07:00
parent eaca1ee6ca
commit a2db92f3cb
27 changed files with 448 additions and 153 deletions

View File

@@ -3,6 +3,7 @@
"version": "1.2.0",
"updated": "2026-07-03",
"notes": [
"Z Ecosystem lives on zblockchainsystem.com — see config/z-ecosystem-links.v1.json",
"Public nginx exposes /settlement/* and /exchange/* without /api/v1/... prefix",
"Tunnel save file logs/public-url-{operator}.txt stores primary portal URL (Z Online Bank)",
"/omnl/* operator UIs ship in frontend dist (public/omnl) — portal-serve proxies /api to explorer",
@@ -96,11 +97,7 @@
"omnlBankHybx": "https://bank.omnl.hybxfinance.io",
"exchangeDbisMirror": "https://exchange.d-bis.org/trade",
"centralBankDbisMirror": "https://secure.d-bis.org/central-bank",
"forexDbisMirror": "https://forex.d-bis.org/trade",
"zEcosystem": "https://zblockchainsystem.com/z",
"zWallet": "https://zblockchainsystem.com/z-wallet",
"zSwap": "https://zblockchainsystem.com/swap",
"zOnlineBank": "https://zblockchainsystem.com/central-bank"
"forexDbisMirror": "https://forex.d-bis.org/trade"
},
"productionApis": {
"explorerRoot": "https://explorer.d-bis.org/api/v1",

View File

@@ -1,4 +1,4 @@
{.\scripts\deployment\deploy-z-ecosystem.ps1
{
"$schema": "OMNL Bank supported chains — 128-chain production registry",
"version": "1.0.0",
"brand": "OMNL Central Bank",
@@ -1242,26 +1242,6 @@
"complianceEnv": "OMNL_COMPLIANCE_CORE_900001",
"integrationRef": "config/onex-shiva-integration.v1.json"
},
{
"chainId": 900002,
"name": "Z Chain",
"type": "evm",
"nativeSymbol": "Z",
"tier": "primary",
"omnlRole": "z-chain",
"status": "active",
"rpcEnv": "CHAIN_900002_RPC_URL",
"explorerUrl": "https://explorer.z.omdnl.org",
"rpcDefault": "http://127.0.0.1:8546",
"settlement": {
"m2LoadEnabled": true,
"swapEnabled": true,
"bridgeEnabled": true,
"officeId": 29
},
"complianceEnv": "OMNL_COMPLIANCE_CORE_900002",
"integrationRef": "config/z-chain-integration.v1.json"
},
{
"chainId": 900003,
"name": "OMNL Expansion Slot 3",
@@ -2318,8 +2298,8 @@
}
],
"stats": {
"total": 128,
"active": 61,
"total": 127,
"active": 60,
"staged": 3,
"reserved": 64
}

View File

@@ -1,7 +1,7 @@
{
"$schema": "Z Chain on-chain deployment addresses (chainId 900002)",
"version": "1.0.0",
"updated": "2026-07-06",
"updated": "2026-07-07",
"chainId": 900002,
"network": "z-chain",
"status": "active",

View File

@@ -1,5 +1,5 @@
{
"$schema": "International Z Wallet + Z Chain — OMNL integration",
"$schema": "International Z Wallet + Z Chain — Z Ecosystem integration",
"version": "1.0.0",
"updated": "2026-07-05",
"brand": {

View File

@@ -0,0 +1,35 @@
{
"$schema": "Z Ecosystem link map — zblockchainsystem.com only",
"version": "1.0.0",
"updated": "2026-07-07",
"brand": "Z Blockchain System",
"publicUrl": "https://zblockchainsystem.com",
"routes": {
"hub": "/z",
"wallet": "/z-wallet",
"swap": "/swap",
"onlineBank": "/central-bank",
"zBotHealth": "/api/v1/z-bot/health",
"zWalletCorridors": "/api/v1/z-wallet/corridors",
"settlementHealth": "/settlement/health",
"zBankSettle": "/settlement/z-bank/settle-m0-m4"
},
"productionPortals": {
"zEcosystem": "https://zblockchainsystem.com/z",
"zWallet": "https://zblockchainsystem.com/z-wallet",
"zSwap": "https://zblockchainsystem.com/swap",
"zOnlineBank": "https://zblockchainsystem.com/central-bank"
},
"subdomains": {
"rpc": "https://rpc.zblockchainsystem.com",
"explorer": "https://explorer.zblockchainsystem.com"
},
"local": {
"frontend": "http://localhost:3002",
"zHub": "http://localhost:3002/z",
"zWallet": "http://localhost:3002/z-wallet",
"zBotHealth": "http://localhost:3000/api/v1/z-bot/health",
"settlementHealth": "http://localhost:3011/api/v1/settlement/health",
"chainRpc": "http://127.0.0.1:8546"
}
}

View File

@@ -1,6 +1,8 @@
# Z Ecosystem local overrides — copy to config/z-ecosystem.local.env
# Production portal: https://zblockchainsystem.com (separate from OMNL)
VITE_ECOSYSTEM=z
Z_SUPPORTED_CHAINS_CONFIG=config/z-supported-chains.v1.json
Z_ECOSYSTEM_PUBLIC_URL=https://zblockchainsystem.com
VITE_Z_ECOSYSTEM_URL=https://zblockchainsystem.com

View File

@@ -0,0 +1,27 @@
{
"$schema": "Z Chain supported chains — separate from OMNL 128-chain registry",
"version": "1.0.0",
"brand": "Z Blockchain System",
"primaryChainId": 900002,
"chains": [
{
"chainId": 900002,
"name": "Z Chain",
"type": "evm",
"nativeSymbol": "Z",
"tier": "primary",
"zRole": "settlement-hub",
"status": "active",
"rpcEnv": "CHAIN_900002_RPC_URL",
"explorerUrl": "https://explorer.zblockchainsystem.com",
"rpcDefault": "http://127.0.0.1:8546",
"settlement": {
"m2LoadEnabled": true,
"swapEnabled": true,
"bridgeEnabled": true
},
"complianceEnv": "Z_COMPLIANCE_CORE_900002",
"integrationRef": "config/z-chain-integration.v1.json"
}
]
}

View File

@@ -1,5 +1,10 @@
# Shared OMNL Bank proxy locations (include inside each server block)
# Z Ecosystem routes live on zblockchainsystem.com only
location ~ ^/(z|z-wallet)(/|$) {
return 302 https://zblockchainsystem.com$request_uri;
}
location /api/v1/ {
include /etc/nginx/omnl-portal-auth-current.conf.inc;
proxy_pass http://omnl_api/api/v1/;

View File

@@ -0,0 +1,56 @@
# Z Ecosystem — Z-only nginx locations (no OMNL consoles)
location /api/v1/ {
proxy_pass http://z_ecosystem_api/api/v1/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
location /settlement/ {
proxy_pass http://z_ecosystem_settlement/api/v1/settlement/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
location /exchange/ {
proxy_pass http://z_ecosystem_exchange/api/v1/exchange/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
# Block OMNL / DBIS-only SPA routes on Z domain
location ~ ^/(hub|office-24|trade|bridge|reserve|history|admin|docs|wallets|omnl)(/|$) {
return 404;
}
location /health {
return 200 'Z Ecosystem online — chain 900002';
add_header Content-Type text/plain;
}
location /assets/ {
proxy_pass http://z_ecosystem_frontend;
proxy_http_version 1.1;
proxy_set_header Host $host;
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://z_ecosystem_frontend;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
}

View File

@@ -1,6 +1,6 @@
# Z Ecosystem — zblockchainsystem.com (Z Chain, Wallet, Bot, Swap, Z Bank UI)
# Z Ecosystem — zblockchainsystem.com (Z Chain, Wallet, Bot, Swap, Z Bank)
# Deploy: scripts/deployment/deploy-z-domains.sh
# Shares upstreams with OMNL portal on :3000 / :3011 / :3012 / :3002
# Independent from OMNL / DBIS portals
upstream z_ecosystem_frontend {
server 127.0.0.1:3002;
@@ -30,62 +30,20 @@ server {
return 302 /z;
}
location /api/v1/ {
proxy_pass http://z_ecosystem_api/api/v1/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
include /etc/nginx/snippets/z-ecosystem-common-locations.conf;
}
location /settlement/ {
proxy_pass http://z_ecosystem_settlement/api/v1/settlement/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
server {
listen 80;
listen [::]:80;
server_name rpc.zblockchainsystem.com;
location /exchange/ {
proxy_pass http://z_ecosystem_exchange/api/v1/exchange/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /omnl/ {
proxy_pass http://z_ecosystem_api/omnl/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /reserve/ {
proxy_pass http://z_ecosystem_api/reserve/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /assets/ {
proxy_pass http://z_ecosystem_frontend;
proxy_http_version 1.1;
proxy_set_header Host $host;
expires 1y;
add_header Cache-Control "public, immutable";
}
add_header X-Z-Product "z-chain-rpc" always;
location / {
proxy_pass http://z_ecosystem_frontend;
proxy_pass http://127.0.0.1:8546;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Cache-Control "no-cache, no-store, must-revalidate" always;
proxy_read_timeout 120s;
}
}

View File

@@ -7,6 +7,10 @@
"dev": "vite",
"prebuild": "node scripts/sync-omnl-consoles.mjs",
"build": "node --max-old-space-size=4096 ./node_modules/vite/bin/vite.js build",
"build:omnl": "node --max-old-space-size=4096 ./node_modules/vite/bin/vite.js build",
"build:z": "node --max-old-space-size=4096 ./node_modules/vite/bin/vite.js build",
"prebuild:omnl": "node scripts/sync-omnl-consoles.mjs",
"prebuild:z": "node -e \"console.log('Z build — skipping OMNL console sync')\"",
"serve:portal": "node scripts/portal-serve.mjs",
"build:check": "tsc && NODE_OPTIONS='--max-old-space-size=4096' vite build",
"preview": "vite preview",

View File

@@ -12,8 +12,7 @@ const DIST = path.join(__dirname, '..', 'dist');
const PORT = Number(process.env.PORT || process.env.OMNL_BANK_FRONTEND_PORT || 3002);
const API_TARGET = process.env.TOKEN_AGGREGATION_URL || 'http://127.0.0.1:3000';
const SETTLEMENT_TARGET = process.env.SETTLEMENT_URL || process.env.SETTLEMENT_MIDDLEWARE_URL || 'http://127.0.0.1:3011';
const EXCHANGE_TARGET = process.env.EXCHANGE_URL || 'https://exchange.omdnl.org';
const EXCHANGE_TARGET = process.env.EXCHANGE_URL || '';
const MIME = {
'.html': 'text/html; charset=utf-8',
'.js': 'application/javascript; charset=utf-8',
@@ -103,17 +102,15 @@ const server = http.createServer((req, res) => {
);
}
if (url.startsWith('/exchange')) {
if (!EXCHANGE_TARGET) {
res.writeHead(404, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'not_available', message: 'Z Ecosystem only' }));
}
return proxyRequest(req, res, EXCHANGE_TARGET);
}
if (url.startsWith('/omnl/')) {
if (shouldServeOmnlStatic(url)) {
const file = resolveStatic(url);
if (file) {
const cache = url.startsWith('/omnl/static/') ? 'public, max-age=31536000, immutable' : 'no-cache';
return sendFile(res, file, cache);
}
}
return proxyRequest(req, res, API_TARGET);
res.writeHead(404, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'not_available', message: 'Z Ecosystem only' }));
}
const file = resolveStatic(url === '/' ? '/index.html' : url);

View File

@@ -1,4 +1,5 @@
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { useEffect } from 'react'
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ThirdwebProvider } from '@thirdweb-dev/react'
@@ -20,7 +21,9 @@ import ZEcosystemHubPage from './pages/ZEcosystemHubPage'
import ZWalletPage from './pages/ZWalletPage'
import Layout from './components/layout/Layout'
import OmnlProductLayout from './components/layout/OmnlProductLayout'
import ZProductLayout from './components/layout/ZProductLayout'
import ToastProvider from './components/ui/ToastProvider'
import { isZEcosystem, isOmnlEcosystem } from './config/ecosystemMode'
const queryClient = new QueryClient({
defaultOptions: {
@@ -37,6 +40,65 @@ const queryClient = new QueryClient({
})
const THIRDWEB_CLIENT_ID = import.meta.env.VITE_THIRDWEB_CLIENT_ID || '542981292d51ec610388ba8985f027d7'
function ExternalRedirect({ to }: { to: string }) {
useEffect(() => {
window.location.replace(to)
}, [to])
return null
}
function ZRoutes() {
return (
<Routes>
<Route
element={
<ThirdwebProvider clientId={THIRDWEB_CLIENT_ID}>
<ZProductLayout />
</ThirdwebProvider>
}
>
<Route path="/z" element={<ZEcosystemHubPage />} />
<Route path="/z-wallet" element={<ZWalletPage />} />
<Route path="/swap" element={<SwapPage />} />
<Route path="/central-bank" element={<CentralBankPage />} />
</Route>
<Route path="/" element={<Navigate to="/z" replace />} />
<Route path="*" element={<Navigate to="/z" replace />} />
</Routes>
)
}
function OmnlRoutes() {
return (
<Routes>
<Route element={<OmnlProductLayout />}>
<Route path="/hub" element={<HubPage />} />
<Route path="/central-bank" element={<CentralBankPage />} />
<Route path="/office-24" element={<Office24Page />} />
<Route path="/trade" element={<TradePage />} />
<Route path="/swap" element={<SwapPage />} />
</Route>
<Route
element={
<ThirdwebProvider clientId={THIRDWEB_CLIENT_ID}>
<Layout />
</ThirdwebProvider>
}
>
<Route path="/bridge" element={<BridgePage />} />
<Route path="/reserve" element={<ReservePage />} />
<Route path="/history" element={<HistoryPage />} />
<Route path="/admin" element={<AdminPanel />} />
<Route path="/docs" element={<DocsPage />} />
<Route path="/wallets" element={<WalletsDemoPage />} />
</Route>
<Route path="/z" element={<ExternalRedirect to="https://zblockchainsystem.com/z" />} />
<Route path="/z-wallet" element={<ExternalRedirect to="https://zblockchainsystem.com/z-wallet" />} />
<Route path="/" element={<Navigate to="/hub" replace />} />
</Routes>
)
}
function App() {
return (
<ErrorBoundary>
@@ -50,32 +112,7 @@ function App() {
>
<ToastProvider />
<AdminProvider>
<Routes>
<Route element={<OmnlProductLayout />}>
<Route path="/hub" element={<HubPage />} />
<Route path="/z" element={<ZEcosystemHubPage />} />
<Route path="/central-bank" element={<CentralBankPage />} />
<Route path="/office-24" element={<Office24Page />} />
<Route path="/trade" element={<TradePage />} />
<Route path="/swap" element={<SwapPage />} />
</Route>
<Route
element={
<ThirdwebProvider clientId={THIRDWEB_CLIENT_ID}>
<Layout />
</ThirdwebProvider>
}
>
<Route path="/bridge" element={<BridgePage />} />
<Route path="/reserve" element={<ReservePage />} />
<Route path="/history" element={<HistoryPage />} />
<Route path="/admin" element={<AdminPanel />} />
<Route path="/docs" element={<DocsPage />} />
<Route path="/wallets" element={<WalletsDemoPage />} />
<Route path="/z-wallet" element={<ZWalletPage />} />
</Route>
<Route path="/" element={<Navigate to="/hub" replace />} />
</Routes>
{isZEcosystem ? <ZRoutes /> : isOmnlEcosystem ? <OmnlRoutes /> : <OmnlRoutes />}
</AdminProvider>
</BrowserRouter>
</QueryClientProvider>

View File

@@ -22,10 +22,6 @@ export default function Layout() {
{ to: '/wallets', label: 'Wallets', active: isActive('/wallets') },
{ to: '/admin', label: 'Admin', active: isActive('/admin') },
{ to: '/docs', label: 'Developers', active: isActive('/docs') },
{ to: '/central-bank', label: 'Z Online Bank', active: isActive('/central-bank') },
{ to: '/office-24', label: 'O24 Central Bank', active: isActive('/office-24') },
{ to: '/trade', label: 'DBIS Trade', active: isActive('/trade') },
{ href: defaultFrontendExplorerUrl, label: 'Explorer' },
]
return (

View File

@@ -8,7 +8,7 @@ import MobileBottomNav from './MobileBottomNav';
const PRODUCTS: { path: string; label: string; icon: NasaIconName }[] = [
{ path: '/hub', label: 'DBIS Dashboard', icon: 'dashboard' },
{ path: '/central-bank', label: 'Z Online Bank', icon: 'central-bank' },
{ path: '/central-bank', label: 'Central Bank', icon: 'central-bank' },
{ path: '/office-24', label: 'O24 Central Bank', icon: 'office' },
{ path: '/trade', label: 'Trade', icon: 'trade' },
{ path: '/swap', label: 'Swap', icon: 'swap' },

View File

@@ -0,0 +1,81 @@
import { Link, Outlet, useLocation } from 'react-router-dom';
import { useRef, useState } from 'react';
import WalletConnect from '../wallet/WalletConnect';
import WalletDisconnectNotice from '../wallet/WalletDisconnectNotice';
import NasaIcon, { type NasaIconName } from '../icons/NasaIcon';
import MobileNavDrawer from './MobileNavDrawer';
import MobileBottomNav from './MobileBottomNav';
import { Z_ECOSYSTEM_PUBLIC_URL } from '../../config/zEcosystemDomain';
const PRODUCTS: { path: string; label: string; icon: NasaIconName }[] = [
{ path: '/z', label: 'Z Hub', icon: 'dashboard' },
{ path: '/z-wallet', label: 'Z Wallet', icon: 'wallet' },
{ path: '/swap', label: 'Swap', icon: 'swap' },
{ path: '/central-bank', label: 'Z Online Bank', icon: 'central-bank' },
];
export default function ZProductLayout() {
const location = useLocation();
const userInitiatedDisconnectRef = useRef(false);
const [menuOpen, setMenuOpen] = useState(false);
const isActive = (path: string) =>
path === '/z' ? location.pathname === '/z' : location.pathname.startsWith(path);
const drawerItems = PRODUCTS.map((p) => ({ to: p.path, label: p.label, active: isActive(p.path) }));
return (
<div className="omnl-app min-h-screen flex flex-col dbis-has-bottom-nav z-ecosystem-theme">
<WalletDisconnectNotice userInitiatedDisconnectRef={userInitiatedDisconnectRef} />
<header className="omnl-app-header mobile-nav-bar sticky top-0 z-50 border-b border-purple-500/30 safe-area-top bg-[#1a1624]">
<div className="max-w-[1600px] mx-auto px-3 sm:px-4 h-14 flex items-center gap-2 sm:gap-4">
<button
type="button"
className="md:hidden shrink-0 text-white p-2 min-h-[44px] min-w-[44px] rounded-lg hover:bg-white/10"
aria-label="Open menu"
aria-expanded={menuOpen}
onClick={() => setMenuOpen(true)}
>
</button>
<Link to="/z" className="flex items-center gap-2 shrink-0 min-w-0">
<span className="w-8 h-8 rounded-lg bg-purple-600 text-white font-bold flex items-center justify-center text-sm shrink-0">
Z
</span>
<span className="font-semibold hidden sm:inline text-sm truncate text-white">Z Blockchain System</span>
</Link>
<nav className="hidden md:flex items-center gap-1 flex-1 overflow-x-auto min-w-0" aria-label="Z Ecosystem">
{PRODUCTS.map(({ path, label, icon }) => (
<Link
key={path}
to={path}
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors whitespace-nowrap min-h-[40px] flex items-center gap-1.5 ${
isActive(path) ? 'bg-purple-600 text-white' : 'text-[#848e9c] hover:text-white hover:bg-white/5'
}`}
>
<NasaIcon name={icon} size={14} />
{label}
</Link>
))}
</nav>
<div className="shrink-0 max-w-[45%] sm:max-w-none ml-auto">
<WalletConnect onBeforeDisconnect={() => { userInitiatedDisconnectRef.current = true; }} />
</div>
</div>
</header>
<MobileNavDrawer open={menuOpen} onClose={() => setMenuOpen(false)} title="Z Ecosystem" items={drawerItems} />
<MobileBottomNav onOpenMenu={() => setMenuOpen(true)} />
<main className="flex-1">
<Outlet />
</main>
<footer className="text-center text-xs text-[#6b7280] py-3 border-t border-white/5">
{Z_ECOSYSTEM_PUBLIC_URL.replace(/^https?:\/\//, '')}
</footer>
</div>
);
}

View File

@@ -13,14 +13,12 @@ export type EcosystemLink = {
accent?: EcosystemLinkAccent;
};
/** In-app React routes (same origin) */
/** In-app React routes (OMNL / DBIS — no Z products) */
export const IN_APP_LINKS: EcosystemLink[] = [
{ id: 'bridge', label: 'Bridge', description: 'Cross-chain bridge, CCIP, XRPL, trustless', icon: 'bridge', href: '/bridge', accent: 'teal' },
{ id: 'swap', label: 'Digital Swap', description: 'M2 load, token swap, settlement rails', icon: 'swap', href: '/swap', accent: 'blue' },
{ id: 'trade', label: 'DBIS Trade', description: 'Markets, order book, spot trading', icon: 'trade', href: '/trade', accent: 'gold' },
{ id: 'central-bank', label: 'Z Online Bank', description: 'Zardasht banking · balances & payments', icon: 'central-bank', href: '/central-bank', accent: 'green' },
{ id: 'z-full-settlement', label: 'Z M0-M4 settlement', description: 'Full money-supply settlement panel', icon: 'money', href: '/central-bank#z-full-settlement', accent: 'green' },
{ id: 'wire-protocols', label: 'Wire protocols', description: 'MT102, MT103 LC, SBLC, BG settlement', icon: 'terminal', href: '/central-bank#z-settlement-protocols', accent: 'gold' },
{ id: 'central-bank', label: 'Central Bank', description: 'OMNL balances & payments', icon: 'central-bank', href: '/central-bank', accent: 'green' },
{ id: 'office-24', label: 'Office 24 Central Bank', description: '128-bank corridors · IPSAS settlement', icon: 'office', href: '/office-24', accent: 'purple' },
{ id: 'reserve', label: 'Reserve', description: 'Coverage, attestation, peg status', icon: 'money', href: '/reserve', accent: 'green' },
{ id: 'history', label: 'History', description: 'Bridge transfer lookup & tracking', icon: 'ledger', href: '/history', accent: 'slate' },
@@ -30,7 +28,7 @@ export const IN_APP_LINKS: EcosystemLink[] = [
{ id: 'hub', label: 'DBIS Dashboard', description: 'All apps, consoles & API links', icon: 'dashboard', href: '/hub', accent: 'green' },
];
/** Primary apps shown in dashboard quick-access strip */
/** Primary apps shown in dashboard quick-access strip (OMNL only) */
export const FEATURED_APP_LINKS: EcosystemLink[] = [
IN_APP_LINKS.find((l) => l.id === 'central-bank')!,
IN_APP_LINKS.find((l) => l.id === 'bridge')!,
@@ -48,10 +46,10 @@ export const OPERATOR_CONSOLE_LINKS: EcosystemLink[] = [
{ id: 'token-admin', label: 'Token Aggregation API', description: 'API catalog JSON', icon: 'ledger', href: '/api/v1/omnl/catalog', accent: 'teal' },
];
/** Public production portals */
/** Public production portals (OMNL / DBIS) */
export const PUBLIC_PORTAL_LINKS: EcosystemLink[] = [
{ id: 'pub-bank', label: 'Z Online Bank', description: 'online.omdnl.org', icon: 'globe', href: 'https://online.omdnl.org/central-bank', external: true, accent: 'green' },
{ id: 'pub-cb', label: 'Central Bank', description: 'secure.omdnl.org', icon: 'central-bank', href: 'https://secure.omdnl.org/central-bank', external: true, accent: 'green' },
{ id: 'pub-online', label: 'Online banking', description: 'online.omdnl.org', icon: 'globe', href: 'https://online.omdnl.org/central-bank', external: true, accent: 'green' },
{ id: 'pub-o24', label: 'Office 24 Central Bank', description: 'office24.omdnl.org', icon: 'office', href: 'https://office24.omdnl.org/office-24', external: true, accent: 'purple' },
{ id: 'pub-trade', label: 'Exchange', description: 'exchange.omdnl.org', icon: 'trade', href: 'https://exchange.omdnl.org/trade', external: true, accent: 'gold' },
{ id: 'pub-forex', label: 'Forex', description: 'forex.omdnl.org', icon: 'trade', href: 'https://forex.omdnl.org/trade', external: true, accent: 'gold' },

View File

@@ -0,0 +1,9 @@
/** Build profile: `z` = Z Blockchain System only; `omnl` = DBIS / OMNL only */
export type EcosystemMode = 'z' | 'omnl';
const raw = (import.meta.env.VITE_ECOSYSTEM as string | undefined)?.trim().toLowerCase();
export const ECOSYSTEM_MODE: EcosystemMode = raw === 'z' ? 'z' : 'omnl';
export const isZEcosystem = ECOSYSTEM_MODE === 'z';
export const isOmnlEcosystem = ECOSYSTEM_MODE === 'omnl';

View File

@@ -4,10 +4,7 @@ import { GUOSMM_NOTICES } from '../config/guosmmNotices';
import { Z_ECOSYSTEM_PORTAL_LINKS } from '../config/ecosystemLinks';
const BANKING: { path: string; label: string; icon: NasaIconName }[] = [
{ path: '/central-bank', label: 'Z Online Bank / Central Bank', icon: 'central-bank' },
{ path: '/central-bank#z-full-settlement', label: 'M0→M4 settlement', icon: 'money' },
{ path: '/central-bank#z-settlement-protocols', label: 'Wire & chain protocols', icon: 'network' },
{ path: '/central-bank#z-settlement-protocols-chains', label: '128-chain matrix', icon: 'network' },
{ path: '/central-bank', label: 'Central Bank', icon: 'central-bank' },
{ path: '/office-24', label: 'Office 24', icon: 'office' },
{ path: '/trade', label: 'DBIS Trade', icon: 'trade' },
{ path: '/swap', label: 'Digital Swap', icon: 'swap' },

View File

@@ -81,8 +81,8 @@ log " Central Bank: https://secure.d-bis.org/central-bank"
log " Online banking: https://online.omdnl.org/central-bank"
log " Office 24: https://office24.omdnl.org/office-24"
log " DBIS Trade: https://exchange.d-bis.org/trade"
log " Digital Swap: https://zblockchainsystem.com/swap"
log " Z Ecosystem: https://zblockchainsystem.com/z"
log " Digital Swap: https://exchange.omdnl.org/trade (OMNL) | Z: https://zblockchainsystem.com/swap"
log " Z Ecosystem: https://zblockchainsystem.com/z (separate product)"
log "=== Health ==="
curl -sf http://127.0.0.1:3011/api/v1/settlement/health | head -c 120 || true
echo

View File

@@ -0,0 +1,102 @@
#!/usr/bin/env bash
# Build and start Z Ecosystem stack only (no OMNL portal deploy).
set -euo pipefail
REPO_DIR="${Z_ECOSYSTEM_ROOT:-$HOME/smom-dbis-138}"
LOG_DIR="${Z_ECOSYSTEM_LOG_DIR:-$HOME/z-ecosystem/logs}"
ENV_FILE="${Z_ECOSYSTEM_ENV:-$REPO_DIR/config/z-ecosystem.local.env}"
FRONTEND_PORT="${Z_ECOSYSTEM_FRONTEND_PORT:-3002}"
log() { echo "[$(date -Iseconds)] $*"; }
mkdir -p "$LOG_DIR"
cd "$REPO_DIR"
if [[ -f "$REPO_DIR/.env" ]]; then
set -a; set +u; source "$REPO_DIR/.env"; set -u; set +a
fi
if [[ -f "$ENV_FILE" ]]; then
set -a; set +u; source "$ENV_FILE"; set -u; set +a
fi
export VITE_ECOSYSTEM=z
export VITE_ENABLE_Z_WALLET=true
export OMNL_SUPPORTED_CHAINS_CONFIG="${Z_SUPPORTED_CHAINS_CONFIG:-$REPO_DIR/config/z-supported-chains.v1.json}"
export SETTLEMENT_MIDDLEWARE_CONFIG="${SETTLEMENT_MIDDLEWARE_CONFIG:-$REPO_DIR/config/settlement-middleware.production.v1.json}"
export CHAIN_900002_RPC_URL="${CHAIN_900002_RPC_URL:-https://rpc.zblockchainsystem.com}"
export VITE_RPC_URL_900002="${VITE_RPC_URL_900002:-$CHAIN_900002_RPC_URL}"
export VITE_Z_CHAIN_EXPLORER_URL="${VITE_Z_CHAIN_EXPLORER_URL:-https://explorer.zblockchainsystem.com}"
export VITE_Z_ECOSYSTEM_URL="${VITE_Z_ECOSYSTEM_URL:-https://zblockchainsystem.com}"
export VITE_TOKEN_AGGREGATION_URL="${VITE_TOKEN_AGGREGATION_URL:-/api/v1}"
export VITE_SETTLEMENT_MIDDLEWARE_URL="${VITE_SETTLEMENT_MIDDLEWARE_URL:-/settlement}"
export VITE_DBIS_EXCHANGE_URL="${VITE_DBIS_EXCHANGE_URL:-/exchange}"
build_pkg() {
local dir="$1"
log "Building $dir..."
cd "$REPO_DIR/$dir"
NODE_ENV=development npm install --no-fund --no-audit
npm run build
}
for dir in packages/integration-foundation packages/settlement-core \
services/token-aggregation services/settlement-middleware services/dbis-exchange; do
build_pkg "$dir"
done
log "Building Z frontend (VITE_ECOSYSTEM=z)..."
cd "$REPO_DIR/frontend-dapp"
unset VITE_OMNL_API_KEY
if command -v pnpm >/dev/null 2>&1; then
pnpm install --frozen-lockfile 2>/dev/null || pnpm install
VITE_ECOSYSTEM=z pnpm run build:z
else
npm install
VITE_ECOSYSTEM=z npm run build:z
fi
start_svc() {
local name="$1"
local dir="$2"
local port="$3"
local cmd="$4"
log "Starting $name on :$port"
cd "$REPO_DIR/$dir"
pkill -f "smom-dbis-138/$dir" 2>/dev/null || true
fuser -k "${port}/tcp" 2>/dev/null || true
sleep 1
nohup env \
SETTLEMENT_MIDDLEWARE_CONFIG="$SETTLEMENT_MIDDLEWARE_CONFIG" \
OMNL_SUPPORTED_CHAINS_CONFIG="$OMNL_SUPPORTED_CHAINS_CONFIG" \
Z_SUPPORTED_CHAINS_CONFIG="$OMNL_SUPPORTED_CHAINS_CONFIG" \
TOKEN_AGGREGATION_URL="${TOKEN_AGGREGATION_URL:-http://127.0.0.1:3000}" \
CHAIN_900002_RPC_URL="$CHAIN_900002_RPC_URL" \
AZURE_OPENAI_ENDPOINT="${AZURE_OPENAI_ENDPOINT:-}" \
AZURE_OPENAI_API_KEY="${AZURE_OPENAI_API_KEY:-}" \
AZURE_OPENAI_DEPLOYMENT="${AZURE_OPENAI_DEPLOYMENT:-}" \
AZURE_OPENAI_API_VERSION="${AZURE_OPENAI_API_VERSION:-2024-02-15-preview}" \
bash -c "$cmd" >"$LOG_DIR/$name.log" 2>&1 &
echo $! >"$LOG_DIR/$name.pid"
}
start_svc token-aggregation services/token-aggregation 3000 "npm run start"
sleep 2
start_svc settlement-middleware services/settlement-middleware 3011 "npm run start"
sleep 2
start_svc dbis-exchange services/dbis-exchange 3012 "npm run start"
sleep 2
pkill -f "serve -s.*$FRONTEND_PORT" 2>/dev/null || true
cd "$REPO_DIR/frontend-dapp"
nohup npx --yes serve -s dist -l "$FRONTEND_PORT" >"$LOG_DIR/frontend.log" 2>&1 &
echo $! >"$LOG_DIR/frontend.pid"
sleep 5
log "Z health checks..."
curl -sf "http://127.0.0.1:3000/api/v1/z-bot/health" | head -c 200 || true
echo
curl -sf "http://127.0.0.1:3011/api/v1/settlement/health" | head -c 200 || true
echo
curl -sf -o /dev/null -w "z-hub=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/z"
curl -sf -o /dev/null -w "z-wallet=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/z-wallet"
log "Z stack ready on :$FRONTEND_PORT"

View File

@@ -98,18 +98,17 @@ cd "$REPO_DIR/frontend-dapp"
export VITE_TOKEN_AGGREGATION_URL="${VITE_TOKEN_AGGREGATION_URL:-/api/v1}"
export VITE_SETTLEMENT_MIDDLEWARE_URL="${VITE_SETTLEMENT_MIDDLEWARE_URL:-/settlement}"
export VITE_DBIS_EXCHANGE_URL="${VITE_DBIS_EXCHANGE_URL:-/exchange}"
export VITE_ENABLE_Z_WALLET="${VITE_ENABLE_Z_WALLET:-true}"
export VITE_RPC_URL_900002="${VITE_RPC_URL_900002:-${CHAIN_900002_RPC_URL:-https://rpc.zblockchainsystem.com}}"
export VITE_Z_CHAIN_EXPLORER_URL="${VITE_Z_CHAIN_EXPLORER_URL:-https://explorer.zblockchainsystem.com}"
export VITE_Z_ECOSYSTEM_URL="${VITE_Z_ECOSYSTEM_URL:-https://zblockchainsystem.com}"
export VITE_ECOSYSTEM="${VITE_ECOSYSTEM:-omnl}"
export VITE_ENABLE_Z_WALLET="${VITE_ENABLE_Z_WALLET:-false}"
unset VITE_RPC_URL_900002 VITE_Z_CHAIN_EXPLORER_URL VITE_Z_ECOSYSTEM_URL
# Never embed operator API keys in production frontend — nginx injects server-side.
unset VITE_OMNL_API_KEY
if command -v pnpm >/dev/null 2>&1; then
pnpm install --frozen-lockfile 2>/dev/null || pnpm install
pnpm run build
VITE_ECOSYSTEM=omnl pnpm run build:omnl
else
npm install
npm run build
VITE_ECOSYSTEM=omnl npm run build:omnl
fi
start_svc() {
@@ -188,10 +187,7 @@ echo
curl -sf "http://127.0.0.1:3012/api/v1/exchange/health" | head -c 200 || true
echo
curl -sf -o /dev/null -w "frontend=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/central-bank"
curl -sf -o /dev/null -w "z-hub=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/z"
curl -sf -o /dev/null -w "z-wallet=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/z-wallet"
curl -sf "http://127.0.0.1:3000/api/v1/z-bot/health" | head -c 200 || true
echo
curl -sf -o /dev/null -w "hub=%{http_code}\n" "http://127.0.0.1:$FRONTEND_PORT/hub"
curl -sf "http://127.0.0.1:8788/health" 2>/dev/null | head -c 80 || log "WARN: SWIFT listener :8788 not reachable"
if [[ -n "${DATABASE_URL:-}" ]] && [[ "${SEED_SUPER_ADMIN_USERS:-1}" == "1" ]]; then

View File

@@ -16,6 +16,9 @@ fi
log "Installing Z Ecosystem nginx vhost..."
sudo cp "$VHOST_SRC" "$VHOST_DST"
SNIPPET_SRC="$REPO_DIR/deploy/nginx/z-ecosystem-common-locations.conf"
SNIPPET_DST="/etc/nginx/snippets/z-ecosystem-common-locations.conf"
sudo cp "$SNIPPET_SRC" "$SNIPPET_DST"
sudo ln -sf "$VHOST_DST" "$VHOST_LINK"
log "Testing nginx..."

View File

@@ -52,8 +52,8 @@ if [[ "${Z_CHAIN_DEPLOY_CONTRACTS:-0}" == "1" ]]; then
node "$ROOT/scripts/deployment/sync-z-chain-deployed-addresses.mjs"
fi
log "Build backend + frontend (Z routes in SPA)..."
bash "$ROOT/scripts/deployment/deploy-omnl-bank-production.sh"
log "Build Z-only backend + frontend..."
bash "$ROOT/scripts/deployment/build-z-ecosystem-stack.sh"
log "Install Z domain nginx vhost..."
bash "$ROOT/scripts/deployment/deploy-z-domains.sh"

View File

@@ -48,6 +48,8 @@ $env:CHAIN_900002_RPC_URL = if ($env:CHAIN_900002_RPC_URL) { $env:CHAIN_900002_R
$env:SETTLEMENT_MIDDLEWARE_URL = if ($env:SETTLEMENT_MIDDLEWARE_URL) { $env:SETTLEMENT_MIDDLEWARE_URL } else { "http://127.0.0.1:3011" }
$env:SETTLEMENT_URL = $env:SETTLEMENT_MIDDLEWARE_URL
$env:TOKEN_AGGREGATION_URL = "http://127.0.0.1:3000"
$env:VITE_ECOSYSTEM = "z"
$env:OMNL_SUPPORTED_CHAINS_CONFIG = Join-Path $Root "config\z-supported-chains.v1.json"
if (-not $env:SETTLEMENT_MIDDLEWARE_CONFIG) {
$env:SETTLEMENT_MIDDLEWARE_CONFIG = Join-Path $Root "config\settlement-middleware.production.v1.json"
@@ -84,10 +86,10 @@ if (-not (Test-Path node_modules)) { npm install --legacy-peer-deps 2>&1 | Out-N
npm run build
if ($LASTEXITCODE -ne 0) { throw "token-aggregation build failed" }
Write-Host "Building frontend-dapp (Z Wallet routes) ..."
Write-Host "Building frontend-dapp (Z Ecosystem only) ..."
Set-Location "$Root\frontend-dapp"
if (-not (Test-Path node_modules)) { npm install --legacy-peer-deps 2>&1 | Out-Null }
npm run build
npm run build:z
if ($LASTEXITCODE -ne 0) { throw "frontend build failed" }
Stop-Port 3011

View File

@@ -0,0 +1,12 @@
# Run as Administrator to map zblockchainsystem.com to this PC (local Z portal on :3002)
$marker = '# Z Ecosystem only'
$hostsPath = "$env:SystemRoot\System32\drivers\etc\hosts"
$line = '127.0.0.1 zblockchainsystem.com www.zblockchainsystem.com rpc.zblockchainsystem.com explorer.zblockchainsystem.com'
$content = Get-Content $hostsPath -Raw
if ($content -match [regex]::Escape($marker)) {
Write-Host 'Z hosts entries already present.'
exit 0
}
Add-Content -Path $hostsPath -Value "`n$marker`n$line"
Write-Host 'Added zblockchainsystem.com -> 127.0.0.1'
Write-Host 'Open: http://zblockchainsystem.com:3002/z'

View File

@@ -30,6 +30,7 @@ Import-DotEnvFile (Join-Path $Root ".env")
Import-DotEnvFile (Join-Path $Root "config\z-ecosystem.local.env")
# Production frontend env (same-origin on zblockchainsystem.com)
$env:VITE_ECOSYSTEM = "z"
$env:VITE_TOKEN_AGGREGATION_URL = "/api/v1"
$env:VITE_SETTLEMENT_MIDDLEWARE_URL = "/settlement"
$env:VITE_DBIS_EXCHANGE_URL = "/exchange"
@@ -43,9 +44,9 @@ Write-Host "=== 1/4 Local stack (Z Chain + APIs + portal) ==="
& "$PSScriptRoot\deploy-z-ecosystem.ps1"
Write-Host ""
Write-Host "=== 2/4 Production frontend build ==="
Write-Host "=== 2/4 Production frontend build (Z-only) ==="
Set-Location "$Root\frontend-dapp"
npm run build
npm run build:z
if ($LASTEXITCODE -ne 0) { throw "production frontend build failed" }
Write-Host ""