# Deploy Z Ecosystem portal locally (chain + settlement + API + portal) $ErrorActionPreference = "Stop" $Root = (Resolve-Path (Join-Path $PSScriptRoot "..\..")).Path $LogDir = Join-Path $Root "logs" New-Item -ItemType Directory -Force -Path $LogDir | Out-Null function Import-DotEnvFile([string]$Path) { if (-not (Test-Path $Path)) { return } Get-Content $Path | ForEach-Object { $line = $_.Trim() if ($line -eq "" -or $line.StartsWith("#")) { return } if ($line -match '^\s*([^=]+)=(.*)$') { $name = $matches[1].Trim() $value = $matches[2].Trim().Trim('"').Trim("'") Set-Item -Path "env:$name" -Value $value } } } function Test-ZChainRpc { try { $body = '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' $r = Invoke-RestMethod -Uri "http://127.0.0.1:8546" -Method Post -Body $body -ContentType "application/json" -TimeoutSec 2 return ($r.result -eq "0xdbba2") } catch { return $false } } function Stop-Port($port) { $conn = Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue | Select-Object -First 1 if ($conn -and $conn.OwningProcess) { Stop-Process -Id $conn.OwningProcess -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 1 } } function Start-BackgroundService([string]$Name, [string]$WorkDir, [string]$Command, [string]$LogFile) { Write-Host "Starting $Name ..." Start-Process -FilePath "cmd.exe" -ArgumentList @("/c", "$Command > `"$LogFile`" 2>&1") ` -WorkingDirectory $WorkDir -WindowStyle Hidden } Set-Location $Root Import-DotEnvFile (Join-Path $Root ".env") Import-DotEnvFile (Join-Path $Root "config\z-ecosystem.local.env") $env:CHAIN_900002_RPC_URL = if ($env:CHAIN_900002_RPC_URL) { $env:CHAIN_900002_RPC_URL } else { "http://127.0.0.1:8546" } $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" } if (-not $env:OMNL_SUPPORTED_CHAINS_CONFIG) { $env:OMNL_SUPPORTED_CHAINS_CONFIG = Join-Path $Root "config\omnl-supported-chains.v1.json" } if (-not (Test-ZChainRpc)) { Write-Host "Z Chain RPC not running - starting complete-z-chain ..." & "$PSScriptRoot\complete-z-chain.ps1" } Write-Host "Building packages (settlement-core) ..." foreach ($pkg in @("packages\integration-foundation", "packages\settlement-core")) { $pkgDir = Join-Path $Root $pkg if (Test-Path $pkgDir) { Set-Location $pkgDir if (-not (Test-Path node_modules)) { npm install --legacy-peer-deps 2>&1 | Out-Null } npm run build if ($LASTEXITCODE -ne 0) { throw "$pkg build failed" } } } Write-Host "Building settlement-middleware ..." Set-Location "$Root\services\settlement-middleware" if (-not (Test-Path node_modules)) { npm install --legacy-peer-deps 2>&1 | Out-Null } npm run build if ($LASTEXITCODE -ne 0) { throw "settlement-middleware build failed" } Write-Host "Building token-aggregation ..." Set-Location "$Root\services\token-aggregation" if (-not (Test-Path node_modules)) { npm install --legacy-peer-deps 2>&1 | Out-Null } npm run build if ($LASTEXITCODE -ne 0) { throw "token-aggregation build failed" } 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:z if ($LASTEXITCODE -ne 0) { throw "frontend build failed" } Stop-Port 3011 Stop-Port 3000 Stop-Port 3002 $settlementLog = Join-Path $LogDir "settlement-middleware.log" $tokenLog = Join-Path $LogDir "token-aggregation.log" $portalLog = Join-Path $LogDir "portal-serve.log" Start-BackgroundService "settlement-middleware on :3011" "$Root\services\settlement-middleware" "npm start" $settlementLog Start-Sleep -Seconds 3 Start-BackgroundService "token-aggregation on :3000" "$Root\services\token-aggregation" "npm start" $tokenLog Start-Sleep -Seconds 4 $env:SETTLEMENT_URL = "http://127.0.0.1:3011" Start-BackgroundService "portal on :3002" "$Root\frontend-dapp" "npm run serve:portal" $portalLog Start-Sleep -Seconds 5 $llmStatus = "rule-based" try { $health = Invoke-RestMethod -Uri "http://localhost:3000/api/v1/z-bot/health" -TimeoutSec 5 $llmStatus = $health.llm.provider } catch { } $settlementStatus = "unknown" try { $settlementStatus = (Invoke-RestMethod -Uri "http://localhost:3011/api/v1/settlement/health" -TimeoutSec 5).status } catch { $settlementStatus = "unreachable" } Write-Host "" Write-Host "Z Ecosystem deployed locally:" Write-Host " Hub: http://localhost:3002/z" Write-Host " Wallet: http://localhost:3002/z-wallet" Write-Host " Z Bot API: http://localhost:3000/api/v1/z-bot/health ($llmStatus)" Write-Host " Settlement: http://localhost:3011/api/v1/settlement/health ($settlementStatus)" Write-Host " Z Chain RPC: $($env:CHAIN_900002_RPC_URL)" Write-Host " Logs: $LogDir" if ($llmStatus -eq "rule-based") { Write-Host "" Write-Host "Azure OpenAI: copy config/z-ecosystem.local.env.example to config/z-ecosystem.local.env and set AZURE_OPENAI_* then redeploy." }