& { # Ryvion DePIN Node Windows Installer $ErrorActionPreference = "Stop" $HubURL = "https://ryvion-hub.fly.dev" $BindToken = "" $InstallPath = "$env:ProgramFiles\Ryvion" $UIPort = "45890" Write-Host "" Write-Host " Ryvion DePIN Node Installer" -ForegroundColor Cyan Write-Host " ===========================" -ForegroundColor Cyan Write-Host "" # Check administrator privileges $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) if (-not $isAdmin) { Write-Host " [ERROR] This script requires administrator privileges." -ForegroundColor Red Write-Host " Please right-click PowerShell and select 'Run as Administrator'." -ForegroundColor Yellow return } try { # Stop existing service before updating (Windows locks running .exe files) $existingSvc = Get-Service -Name "RyvionNode" -ErrorAction SilentlyContinue if ($existingSvc) { Write-Host " [0/5] Stopping existing service..." -ForegroundColor Yellow # Disable failure recovery before stopping to prevent SCM auto-restart sc.exe failureflag RyvionNode 0 2>$null | Out-Null sc.exe failure RyvionNode reset= 0 actions= "" 2>$null | Out-Null Stop-Service -Name "RyvionNode" -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 2 # Kill any leftover process Get-Process -Name "ryvion-node" -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue Start-Sleep -Seconds 1 Write-Host " [OK] Existing service stopped" -ForegroundColor Green } Write-Host " [1/5] Downloading binary..." -ForegroundColor Yellow $releaseUrl = "$HubURL/download/windows/binary" $tempZip = Join-Path $env:TEMP "ryvion-node.zip" [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-WebRequest -Uri $releaseUrl -OutFile $tempZip -UseBasicParsing if (-not (Test-Path $tempZip)) { throw "Download failed" } $zipSize = (Get-Item $tempZip).Length Write-Host " [OK] Download completed ($([math]::Round($zipSize/1MB, 1)) MB)" -ForegroundColor Green Write-Host " [2/5] Installing..." -ForegroundColor Yellow New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null Expand-Archive -Path $tempZip -DestinationPath $InstallPath -Force $binPath = Join-Path $InstallPath "ryvion-node.exe" if (-not (Test-Path $binPath)) { throw "Binary not found after extraction at $binPath" } Write-Host " [OK] Extracted to $InstallPath" -ForegroundColor Green Write-Host " [3/5] Configuring PATH..." -ForegroundColor Yellow $machinePath = [Environment]::GetEnvironmentVariable("Path", "Machine") if ($machinePath -notlike "*$InstallPath*") { [Environment]::SetEnvironmentVariable("Path", "$machinePath;$InstallPath", "Machine") } Write-Host " [OK] PATH updated" -ForegroundColor Green Write-Host " [4/5] Writing config..." -ForegroundColor Yellow $cfgDir = Join-Path $env:USERPROFILE ".ryvion" if (-not (Test-Path $cfgDir)) { New-Item -ItemType Directory -Path $cfgDir -Force | Out-Null } $cfgPath = Join-Path $cfgDir "config.json" $cfgObj = @{ hub_url = $HubURL; device_type = "auto"; log_level = "info" } if ($BindToken -and $BindToken.Length -gt 0) { $cfgObj["bind_token"] = $BindToken } $cfgObj | ConvertTo-Json | Out-File -FilePath $cfgPath -Encoding ASCII -Force [Environment]::SetEnvironmentVariable("RYV_HUB_URL", $HubURL, "Machine") [Environment]::SetEnvironmentVariable("RYV_UI_PORT", $UIPort, "Machine") if ($BindToken -and $BindToken.Length -gt 0) { [Environment]::SetEnvironmentVariable("RYV_BIND_TOKEN", $BindToken, "Machine") } Write-Host " [OK] Config saved to $cfgPath" -ForegroundColor Green Write-Host " [5/5] Installing service..." -ForegroundColor Yellow $svcArgs = """$binPath"" -hub $HubURL -ui-port $UIPort" if (-not $existingSvc) { New-Service -Name "RyvionNode" -BinaryPathName $svcArgs -DisplayName "Ryvion DePIN Node" -StartupType Automatic -Description "Ryvion distributed compute node" -ErrorAction Stop | Out-Null } else { sc.exe config RyvionNode binPath= $svcArgs | Out-Null } # Configure automatic restart on failure (restart after 5s, 10s, 30s) sc.exe failure RyvionNode reset= 86400 actions= restart/5000/restart/10000/restart/30000 | Out-Null sc.exe failureflag RyvionNode 1 | Out-Null $svc = Get-Service -Name "RyvionNode" if ($svc.Status -ne "Running") { Start-Service -Name "RyvionNode" -ErrorAction Stop Start-Sleep -Seconds 3 $svc = Get-Service -Name "RyvionNode" } if ($svc.Status -eq "Running") { Write-Host " [OK] Service installed and running (auto-restart on failure)" -ForegroundColor Green } else { Write-Host " [WARN] Service status: $($svc.Status)" -ForegroundColor Yellow } try { for ($i = 0; $i -lt 5; $i++) { try { Invoke-WebRequest -Uri "http://127.0.0.1:$UIPort/healthz" -UseBasicParsing -TimeoutSec 2 | Out-Null Write-Host " [OK] Local operator API is reachable on http://127.0.0.1:$UIPort" -ForegroundColor Green break } catch { Start-Sleep -Seconds 1 } } } catch { Write-Host " [WARN] Could not confirm local operator API on port $UIPort yet" -ForegroundColor Yellow } Remove-Item $tempZip -Force -ErrorAction SilentlyContinue Write-Host "" Write-Host " Ryvion Node installed successfully!" -ForegroundColor Green Write-Host "" Write-Host " Next steps:" -ForegroundColor White Write-Host " - Check status: Get-Service RyvionNode" -ForegroundColor Gray Write-Host " - Dashboard: https://ryvion.com/dashboard" -ForegroundColor Gray Write-Host "" } catch { Write-Host "" Write-Host " [ERROR] Installation failed: $($_.Exception.Message)" -ForegroundColor Red Write-Host "" Write-Host " Troubleshooting:" -ForegroundColor Yellow Write-Host " 1. Make sure you run PowerShell as Administrator" -ForegroundColor Gray Write-Host " 2. Check if antivirus blocked the binary" -ForegroundColor Gray Write-Host " 3. Try: Stop-Service RyvionNode; then reinstall" -ForegroundColor Gray Write-Host "" } }