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
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:
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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' },
|
||||
|
||||
81
frontend-dapp/src/components/layout/ZProductLayout.tsx
Normal file
81
frontend-dapp/src/components/layout/ZProductLayout.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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' },
|
||||
|
||||
9
frontend-dapp/src/config/ecosystemMode.ts
Normal file
9
frontend-dapp/src/config/ecosystemMode.ts
Normal 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';
|
||||
@@ -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' },
|
||||
|
||||
Reference in New Issue
Block a user