ovtools 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +121 -2
- package/assets/common/bond-inspect.sh +368 -0
- package/assets/common/config.sh +263 -0
- package/assets/common/extract-data.sh +197 -0
- package/assets/common/harden-host.sh +37 -0
- package/assets/common/install-deps.sh +93 -0
- package/assets/common/node-enroll.sh +65 -0
- package/assets/common/node-setup.sh +150 -0
- package/assets/common/node-start.sh +90 -0
- package/assets/common/node-stop.sh +18 -0
- package/assets/common/node-upgrade.sh +45 -0
- package/assets/common/pre-run.sh +497 -0
- package/assets/common/promote-validator.sh +104 -0
- package/assets/deploy/10-prepare-host.sh +98 -0
- package/assets/deploy/20-install-toolchain.sh +93 -0
- package/assets/deploy/30-setup-node.sh +82 -0
- package/assets/deploy/40-start-node.sh +75 -0
- package/assets/deploy/50-verify.sh +259 -0
- package/assets/deploy/60-enroll.sh +304 -0
- package/assets/deploy/70-promote.sh +152 -0
- package/assets/deploy/lib.sh +398 -0
- package/assets/manage/10-bond-increase.sh +149 -0
- package/assets/manage/10-diagnose-node.sh +169 -0
- package/assets/manage/20-exit-validator.sh +259 -0
- package/assets/manage/25-recover-node.sh +291 -0
- package/assets/manage/30-status.sh +64 -0
- package/assets/manage/40-exit-withdraw.sh +133 -0
- package/assets/manage/bond_inc.sh +318 -0
- package/assets/manage/dashboard_monitor/app.js +1544 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/base.css +113 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/content.css +133 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/controls.css +229 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/data.css +374 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/icons.css +35 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/motion.css +57 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/shell.css +51 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/sidebar.css +242 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/components/topbar.css +138 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/fonts.css +30 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/synteq-ui-v2.css +25 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-dark.css +38 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-light.css +36 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/css/tokens.css +61 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
- package/assets/manage/dashboard_monitor/assets/v2.2/js/synteq-ui-v2.js +869 -0
- package/assets/manage/dashboard_monitor/deploy-dashboard.sh +230 -0
- package/assets/manage/dashboard_monitor/favicon.svg +13 -0
- package/assets/manage/dashboard_monitor/index.html +1197 -0
- package/assets/manage/dashboard_monitor/nginx-octra.conf +76 -0
- package/assets/manage/dashboard_monitor/octra-dashboard.service +29 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.cron +12 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.service +16 -0
- package/assets/manage/dashboard_monitor/octra-node-prune.timer +12 -0
- package/assets/manage/dashboard_monitor/prune-node-junk.sh +329 -0
- package/assets/manage/dashboard_monitor/server.py +1887 -0
- package/assets/manage/dashboard_monitor/ssl-certbot.sh +90 -0
- package/assets/manage/dashboard_monitor/styles.css +327 -0
- package/assets/manage/lib.sh +347 -0
- package/assets/manifest.json +143 -0
- package/assets/migrate/00-backup-identity.sh +67 -0
- package/assets/migrate/01-prepare-target.sh +145 -0
- package/assets/migrate/02-authorize-pull.sh +43 -0
- package/assets/migrate/03-pull-state.sh +102 -0
- package/assets/migrate/04-stop-source.sh +85 -0
- package/assets/migrate/05-finalize-target.sh +140 -0
- package/assets/migrate/06-start-target.sh +57 -0
- package/assets/migrate/07-verify.sh +237 -0
- package/assets/migrate/08-rollback.sh +54 -0
- package/assets/migrate/lib.sh +149 -0
- package/assets/upgrade/10-preflight.sh +120 -0
- package/assets/upgrade/20-upgrade.sh +142 -0
- package/assets/upgrade/30-manual-upgrade.sh +129 -0
- package/assets/upgrade/40-storage-prune.sh +65 -0
- package/assets/upgrade/50-status.sh +58 -0
- package/assets/upgrade/lib.sh +232 -0
- package/bin/ovtools.js +32 -0
- package/dist/api/checks.d.ts +6 -0
- package/dist/api/checks.d.ts.map +1 -0
- package/dist/api/checks.js +173 -0
- package/dist/api/checks.js.map +1 -0
- package/dist/api/hostkeys.d.ts +10 -0
- package/dist/api/hostkeys.d.ts.map +1 -0
- package/dist/api/hostkeys.js +58 -0
- package/dist/api/hostkeys.js.map +1 -0
- package/dist/api/jobs.d.ts +33 -0
- package/dist/api/jobs.d.ts.map +1 -0
- package/dist/api/jobs.js +483 -0
- package/dist/api/jobs.js.map +1 -0
- package/dist/api/nodes.d.ts +16 -0
- package/dist/api/nodes.d.ts.map +1 -0
- package/dist/api/nodes.js +126 -0
- package/dist/api/nodes.js.map +1 -0
- package/dist/api/server.d.ts +3 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +443 -0
- package/dist/api/server.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +301 -0
- package/dist/cli.js.map +1 -0
- package/dist/constants.d.ts +76 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +150 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/base.d.ts +52 -0
- package/dist/orchestrator/base.d.ts.map +1 -0
- package/dist/orchestrator/base.js +219 -0
- package/dist/orchestrator/base.js.map +1 -0
- package/dist/orchestrator/deploy.d.ts +33 -0
- package/dist/orchestrator/deploy.d.ts.map +1 -0
- package/dist/orchestrator/deploy.js +313 -0
- package/dist/orchestrator/deploy.js.map +1 -0
- package/dist/orchestrator/manage.d.ts +28 -0
- package/dist/orchestrator/manage.d.ts.map +1 -0
- package/dist/orchestrator/manage.js +267 -0
- package/dist/orchestrator/manage.js.map +1 -0
- package/dist/orchestrator/migrate.d.ts +31 -0
- package/dist/orchestrator/migrate.d.ts.map +1 -0
- package/dist/orchestrator/migrate.js +442 -0
- package/dist/orchestrator/migrate.js.map +1 -0
- package/dist/ssh/client.d.ts +39 -0
- package/dist/ssh/client.d.ts.map +1 -0
- package/dist/ssh/client.js +418 -0
- package/dist/ssh/client.js.map +1 -0
- package/dist/test/core.test.d.ts +2 -0
- package/dist/test/core.test.d.ts.map +1 -0
- package/dist/test/core.test.js +188 -0
- package/dist/test/core.test.js.map +1 -0
- package/dist/types.d.ts +267 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/assets.d.ts +28 -0
- package/dist/utils/assets.d.ts.map +1 -0
- package/dist/utils/assets.js +583 -0
- package/dist/utils/assets.js.map +1 -0
- package/dist/utils/browser.d.ts +2 -0
- package/dist/utils/browser.d.ts.map +1 -0
- package/dist/utils/browser.js +23 -0
- package/dist/utils/browser.js.map +1 -0
- package/dist/utils/dashboard.d.ts +16 -0
- package/dist/utils/dashboard.d.ts.map +1 -0
- package/dist/utils/dashboard.js +177 -0
- package/dist/utils/dashboard.js.map +1 -0
- package/dist/utils/helpers.d.ts +29 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +204 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/scripts.d.ts +60 -0
- package/dist/utils/scripts.d.ts.map +1 -0
- package/dist/utils/scripts.js +174 -0
- package/dist/utils/scripts.js.map +1 -0
- package/dist/utils/state.d.ts +12 -0
- package/dist/utils/state.d.ts.map +1 -0
- package/dist/utils/state.js +44 -0
- package/dist/utils/state.js.map +1 -0
- package/dist/utils/tar.d.ts +11 -0
- package/dist/utils/tar.d.ts.map +1 -0
- package/dist/utils/tar.js +93 -0
- package/dist/utils/tar.js.map +1 -0
- package/dist/utils/update.d.ts +9 -0
- package/dist/utils/update.d.ts.map +1 -0
- package/dist/utils/update.js +134 -0
- package/dist/utils/update.js.map +1 -0
- package/dist/utils/websocket.d.ts +10 -0
- package/dist/utils/websocket.d.ts.map +1 -0
- package/dist/utils/websocket.js +203 -0
- package/dist/utils/websocket.js.map +1 -0
- package/package.json +55 -4
- package/public/app.js +2712 -0
- package/public/assets/v2.2/css/base.css +113 -0
- package/public/assets/v2.2/css/components/content.css +133 -0
- package/public/assets/v2.2/css/components/controls.css +229 -0
- package/public/assets/v2.2/css/components/data.css +373 -0
- package/public/assets/v2.2/css/components/icons.css +35 -0
- package/public/assets/v2.2/css/components/motion.css +57 -0
- package/public/assets/v2.2/css/components/shell.css +51 -0
- package/public/assets/v2.2/css/components/sidebar.css +242 -0
- package/public/assets/v2.2/css/components/topbar.css +138 -0
- package/public/assets/v2.2/css/fonts.css +30 -0
- package/public/assets/v2.2/css/synteq-ui-v2.css +25 -0
- package/public/assets/v2.2/css/theme-dark.css +38 -0
- package/public/assets/v2.2/css/theme-light.css +36 -0
- package/public/assets/v2.2/css/tokens.css +61 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
- package/public/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
- package/public/assets/v2.2/js/synteq-ui-v2.js +869 -0
- package/public/favicon.svg +7 -0
- package/public/index.html +1080 -0
- package/public/styles.css +552 -0
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="dark" class="theme-dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
6
|
+
<meta name="color-scheme" content="dark light" />
|
|
7
|
+
<meta name="description" content="Validator Management System - deploy, migrate and manage Octra validators" />
|
|
8
|
+
<title>Validator Management System</title>
|
|
9
|
+
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
|
|
10
|
+
<link rel="stylesheet" href="assets/v2.2/css/synteq-ui-v2.css?v=2.2.1" />
|
|
11
|
+
<link rel="stylesheet" href="styles.css?v=2.1.3" />
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
|
|
15
|
+
<div class="v2-app" id="app">
|
|
16
|
+
|
|
17
|
+
<!-- --------------- NAVIGATION DOCK --------------- -->
|
|
18
|
+
<aside class="v2-aside" aria-label="Primary navigation" id="sidebar">
|
|
19
|
+
<a href="#console" class="v2-aside__brand" id="aside-brand"
|
|
20
|
+
aria-label="Validator Management System" title="Validator Management System">
|
|
21
|
+
<span class="v2-aside__brand-mark" aria-hidden="true">
|
|
22
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4">
|
|
23
|
+
<path d="M4 7h13l-3-3" /><path d="M20 17H7l3 3" />
|
|
24
|
+
</svg>
|
|
25
|
+
</span>
|
|
26
|
+
</a>
|
|
27
|
+
|
|
28
|
+
<nav class="v2-nav" aria-label="Console sections">
|
|
29
|
+
<a href="#console" class="v2-nav__item v2-nav__item--active" aria-current="page">
|
|
30
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><polygon points="6 3 20 12 6 21 6 3"/></svg>
|
|
31
|
+
Console
|
|
32
|
+
</a>
|
|
33
|
+
<a href="#nodes" class="v2-nav__item">
|
|
34
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="4" width="18" height="7" rx="1"/><rect x="3" y="13" width="18" height="7" rx="1"/><line x1="7" y1="7.5" x2="7.01" y2="7.5"/><line x1="7" y1="16.5" x2="7.01" y2="16.5"/></svg>
|
|
35
|
+
Nodes
|
|
36
|
+
</a>
|
|
37
|
+
<a href="#log" class="v2-nav__item">
|
|
38
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/></svg>
|
|
39
|
+
Live log
|
|
40
|
+
<span class="v2-nav__badge" id="nav-log-badge" hidden>0</span>
|
|
41
|
+
</a>
|
|
42
|
+
<a href="#guide" class="v2-nav__item">
|
|
43
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
|
|
44
|
+
Guide
|
|
45
|
+
</a>
|
|
46
|
+
</nav>
|
|
47
|
+
|
|
48
|
+
<div class="v2-aside__footer">
|
|
49
|
+
<!-- Bottom-right of the navigation: ONE word for the console state
|
|
50
|
+
(Idle / Running / Done / Failed / Offline). The phase detail stays in
|
|
51
|
+
the topbar badge, the same split the monitor uses. The dot stays
|
|
52
|
+
outside the badge: one indicator per row, never a dot inside a pill. -->
|
|
53
|
+
<span class="v2-dot" id="dock-dot" aria-hidden="true"></span>
|
|
54
|
+
<span class="v2-badge mc-dockstatus" id="dock-status" title="Console state">
|
|
55
|
+
<span id="dock-status-text">Idle</span>
|
|
56
|
+
</span>
|
|
57
|
+
</div>
|
|
58
|
+
</aside>
|
|
59
|
+
|
|
60
|
+
<!-- --------------- TOPBAR --------------- -->
|
|
61
|
+
<header class="v2-topbar" role="banner">
|
|
62
|
+
<button class="v2-sidebar-toggle" data-v2-sidebar-toggle aria-label="Toggle navigation" aria-expanded="true" aria-controls="sidebar">
|
|
63
|
+
<svg class="v2-icon v2-icon--18 icon-menu" viewBox="0 0 24 24" aria-hidden="true"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
|
64
|
+
<svg class="v2-icon v2-icon--18 icon-close" viewBox="0 0 24 24" aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
65
|
+
</button>
|
|
66
|
+
|
|
67
|
+
<div class="v2-topbar__left">
|
|
68
|
+
<span class="v2-topbar__crumb v2-mono">octra</span>
|
|
69
|
+
<span class="v2-topbar__sep" aria-hidden="true">/</span>
|
|
70
|
+
<span class="v2-topbar__title" id="topbar-title">Validator Management</span>
|
|
71
|
+
<span class="v2-badge" id="topbar-status" title="Phase state">
|
|
72
|
+
<span id="topbar-status-text">idle</span>
|
|
73
|
+
</span>
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<div class="v2-topbar__right">
|
|
77
|
+
<span class="live-age v2-t-xs v2-mono" id="live-age" title="Time since the last state poll">-</span>
|
|
78
|
+
<button class="v2-iconbtn" id="btn-refresh" aria-label="Refresh now" title="Refresh state">
|
|
79
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
|
|
80
|
+
</button>
|
|
81
|
+
<button class="v2-iconbtn" id="btn-stop" aria-label="Cancel running phase" title="Cancel running phase" disabled>
|
|
82
|
+
<svg class="v2-icon v2-icon--16" viewBox="0 0 24 24" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2"/></svg>
|
|
83
|
+
</button>
|
|
84
|
+
<button class="v2-iconbtn v2-theme-toggle" data-v2-toggle-theme aria-label="Toggle theme">
|
|
85
|
+
<svg class="v2-icon v2-icon--16 v2-icon--moon" viewBox="0 0 24 24" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
|
|
86
|
+
<svg class="v2-icon v2-icon--16 v2-icon--sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
|
|
87
|
+
</button>
|
|
88
|
+
</div>
|
|
89
|
+
</header>
|
|
90
|
+
|
|
91
|
+
<main class="v2-main" aria-label="Validator Management System">
|
|
92
|
+
<div class="v2-content v2-scroll" id="main-content">
|
|
93
|
+
|
|
94
|
+
<!-- ---------- 1. CONSOLE ---------- -->
|
|
95
|
+
<section class="v2-section v2-section--compact" id="console" aria-label="Validator Management System">
|
|
96
|
+
|
|
97
|
+
<div class="mc-hero">
|
|
98
|
+
<div class="mc-hero__main">
|
|
99
|
+
<div class="mc-hero__title-row">
|
|
100
|
+
<h1 class="mc-hero__title" id="hero-title">Validator Management</h1>
|
|
101
|
+
<span class="v2-badge" id="hero-state-badge">
|
|
102
|
+
<span id="hero-state-text">idle</span>
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="mc-hero__meta">
|
|
106
|
+
<span class="v2-t-xs v2-mute">
|
|
107
|
+
orchestrator <span class="v2-mono" id="hero-orchestrator">-</span>
|
|
108
|
+
</span>
|
|
109
|
+
<span class="mc-hero__sep" aria-hidden="true">-</span>
|
|
110
|
+
<span class="v2-t-xs v2-mute">route <span class="v2-mono" id="hero-route-text">-</span></span>
|
|
111
|
+
<span class="mc-hero__sep" aria-hidden="true">-</span>
|
|
112
|
+
<span class="v2-t-xs v2-mute">
|
|
113
|
+
project <span class="v2-mono" id="hero-project">-</span>
|
|
114
|
+
</span>
|
|
115
|
+
<span class="mc-hero__sep" aria-hidden="true">-</span>
|
|
116
|
+
<span class="v2-t-xs v2-mute">elapsed <span class="v2-mono" id="hero-elapsed">-</span></span>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<!-- safety banner: only shown when a rule is at risk -->
|
|
122
|
+
<div class="mc-alert" id="safety-alert" hidden></div>
|
|
123
|
+
|
|
124
|
+
<!-- three dashboards, one console: pick the program (the choice is remembered).
|
|
125
|
+
The fourth tool - updating the running node - lives INSIDE "Manage active
|
|
126
|
+
node" (its actions sit next to Increase bond / Exit validator in the Live
|
|
127
|
+
node state section), so there is no tab for it (2026-11-05). -->
|
|
128
|
+
<nav class="mc-tabs" id="seg-programs" role="tablist" aria-label="Automation program">
|
|
129
|
+
<button type="button" class="mc-tab" data-program="deploy" role="tab" aria-selected="false">
|
|
130
|
+
<span class="mc-tab__title">Deploy fresh node</span>
|
|
131
|
+
<span class="mc-tab__hint">One fresh VPS: toolchain, identity, sync, start, verify, enroll</span>
|
|
132
|
+
</button>
|
|
133
|
+
<button type="button" class="mc-tab mc-tab--active" data-program="migrate" role="tab" aria-selected="true">
|
|
134
|
+
<span class="mc-tab__title">Migrate node</span>
|
|
135
|
+
<span class="mc-tab__hint">Move the running validator: source keeps voting until the switch</span>
|
|
136
|
+
</button>
|
|
137
|
+
<button type="button" class="mc-tab" data-program="manage" role="tab" aria-selected="false">
|
|
138
|
+
<span class="mc-tab__title">Manage active node</span>
|
|
139
|
+
<span class="mc-tab__hint">Bond, exit, update the software, prune preserved states, monitor</span>
|
|
140
|
+
</button>
|
|
141
|
+
</nav>
|
|
142
|
+
|
|
143
|
+
<!-- ---------- 1. PROJECT SETTINGS (deploy + migrate) ---------- -->
|
|
144
|
+
<!-- What a deploy/migrate run really takes from here: the swap file size.
|
|
145
|
+
The data store is detected and formatted by the program itself, and the
|
|
146
|
+
monitoring dashboard is NOT part of a deploy or a migration any more -
|
|
147
|
+
it is the "Deploy monitor" action of the Manage active node tab
|
|
148
|
+
(2026-11-05), so the checkbox that used to sit here is gone. The Manage
|
|
149
|
+
tab hides this section entirely. -->
|
|
150
|
+
<section class="v2-section v2-section--compact" id="settings" aria-label="Project settings">
|
|
151
|
+
<div class="v2-section__head">
|
|
152
|
+
<span class="v2-section__title">Project settings</span>
|
|
153
|
+
<span class="v2-section__meta" id="settings-meta">swap - the data store is automatic</span>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<div class="mc-form mc-settings" role="group" aria-label="Project settings">
|
|
157
|
+
<label class="mc-field mc-field--sm" title="Swap file size on the host (0 = no swap)">
|
|
158
|
+
<span class="mc-field__label">Swap (GB)</span>
|
|
159
|
+
<input class="v2-input" id="set-swap" type="number" min="0" max="64" value="8" />
|
|
160
|
+
</label>
|
|
161
|
+
<button class="v2-btn v2-btn--brand mc-settings__save" id="btn-settings-save">
|
|
162
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
163
|
+
aria-hidden="true"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
|
|
164
|
+
Save settings
|
|
165
|
+
</button>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<!-- The data store is detected and formatted by the program: nothing to
|
|
169
|
+
type. When a node-building run of THIS page has finished, the
|
|
170
|
+
operator gets a pointer to where the rest lives (monitoring, bond,
|
|
171
|
+
exit) instead of having to hunt for it. A freshly opened page - whose
|
|
172
|
+
/api/state still carries the finished run of an earlier session - and a
|
|
173
|
+
run still in flight both stay quiet (2026-11-04). -->
|
|
174
|
+
<div class="mc-settings__off" id="settings-off" hidden>
|
|
175
|
+
<span class="v2-t-xs v2-mute">
|
|
176
|
+
<span class="v2-mono" id="dash-off-host">-</span> is set up. Monitoring, bond and
|
|
177
|
+
exit live in the Manage active node tab:
|
|
178
|
+
</span>
|
|
179
|
+
<button class="v2-btn v2-btn--ghost" id="btn-goto-manage">
|
|
180
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
181
|
+
aria-hidden="true"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>
|
|
182
|
+
Go to Manage active node
|
|
183
|
+
</button>
|
|
184
|
+
</div>
|
|
185
|
+
</section>
|
|
186
|
+
|
|
187
|
+
<!-- =============== DASHBOARD 1: DEPLOY FRESH NODE =============== -->
|
|
188
|
+
<div class="mc-panel" id="panel-deploy" role="tabpanel" aria-label="Deploy fresh node" hidden>
|
|
189
|
+
<div class="mc-program__head">
|
|
190
|
+
<span class="mc-program__title">Deploy fresh node</span>
|
|
191
|
+
<span class="v2-t-xs v2-mute">
|
|
192
|
+
One target VPS. Swap + data store, toolchain, node identity, chain sync, start, verify -
|
|
193
|
+
then the "Ready for enrollment" popup: confirm the top-up, type the bond amount and press
|
|
194
|
+
Enroll; the run only ends once the node is an ACTIVE validator and voting.
|
|
195
|
+
</span>
|
|
196
|
+
</div>
|
|
197
|
+
<div class="mc-pipeline" id="d-pipeline" role="list" aria-label="Deploy pipeline steps"></div>
|
|
198
|
+
|
|
199
|
+
<div class="mc-endpoints mc-endpoints--single">
|
|
200
|
+
<div class="mc-endpoint">
|
|
201
|
+
<span class="mc-endpoint__role">Target VPS (new node)</span>
|
|
202
|
+
<input class="v2-input v2-mono" id="d-inp-ip" type="text" placeholder="IP address or hostname"
|
|
203
|
+
autocomplete="off" spellcheck="false" aria-label="Target IP address" />
|
|
204
|
+
<div class="mc-auth">
|
|
205
|
+
<select class="v2-input mc-auth__method" id="d-inp-auth" aria-label="Target authentication method"
|
|
206
|
+
data-key="d-inp-key" data-keybox="d-key-box" data-keytext="d-inp-keytext" data-pick="d-btn-key-pick" data-passfield="d-inp-pass" data-eye="d-btn-pass-eye">
|
|
207
|
+
<option value="password">password</option>
|
|
208
|
+
<option value="key">ssh key</option>
|
|
209
|
+
</select>
|
|
210
|
+
<div class="mc-key" id="d-key-box" hidden>
|
|
211
|
+
<div class="mc-key__row">
|
|
212
|
+
<input class="v2-input v2-mono mc-auth__key" id="d-inp-key" type="text"
|
|
213
|
+
placeholder="/home/you/.ssh/id_ed25519" autocomplete="off" spellcheck="false"
|
|
214
|
+
aria-label="Target private key file (OpenSSH)" />
|
|
215
|
+
<button type="button" class="v2-btn v2-btn--ghost mc-key__pick" id="d-btn-key-pick"
|
|
216
|
+
data-key="d-inp-key" title="Pick the private key file on this machine">
|
|
217
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
218
|
+
aria-hidden="true"><circle cx="7.5" cy="15.5" r="3.5"/><path d="M10.3 12.7 20 3"/><path d="M15 8l3 3"/></svg>
|
|
219
|
+
Browse
|
|
220
|
+
</button>
|
|
221
|
+
</div>
|
|
222
|
+
<textarea class="v2-input v2-mono mc-key__text" id="d-inp-keytext" rows="2" spellcheck="false"
|
|
223
|
+
placeholder="or paste the private key text here (saved 0600 on this machine)"></textarea>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="mc-pass">
|
|
227
|
+
<input class="v2-input" id="d-inp-pass" type="password" placeholder="root password"
|
|
228
|
+
autocomplete="new-password" spellcheck="false" aria-label="Target root password" />
|
|
229
|
+
<button type="button" class="v2-iconbtn mc-pass__toggle" id="d-btn-pass-eye"
|
|
230
|
+
data-pass="d-inp-pass" data-pass-label="target password"
|
|
231
|
+
aria-label="Show target password" aria-pressed="false" title="Show password">
|
|
232
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-open" viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
233
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-off" viewBox="0 0 24 24" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
234
|
+
</button>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
<!-- The only option left here is the Check button: the bond is asked in
|
|
240
|
+
the "Ready for enrollment" popup (after the sync) and the verify
|
|
241
|
+
samples/interval are fixed by the program. -->
|
|
242
|
+
<div class="mc-form" role="group" aria-label="Deploy options">
|
|
243
|
+
<button class="v2-btn v2-btn--primary mc-check-btn" id="d-btn-check" title="Verify the target before anything is written">
|
|
244
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
245
|
+
Check
|
|
246
|
+
</button>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<div class="mc-check" id="d-check-result" hidden>
|
|
250
|
+
<div class="mc-check__head">
|
|
251
|
+
<span class="v2-badge" id="d-check-badge">
|
|
252
|
+
<span id="d-check-badge-text">not checked</span>
|
|
253
|
+
</span>
|
|
254
|
+
<span class="v2-t-xs v2-mute" id="d-check-summary">-</span>
|
|
255
|
+
<span class="v2-t-xs v2-mono v2-mute" id="d-check-age"></span>
|
|
256
|
+
</div>
|
|
257
|
+
<div class="mc-check__list" id="d-check-list" role="list"></div>
|
|
258
|
+
<div class="mc-check__actions" id="d-check-actions" hidden></div>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<div class="mc-progress" id="d-progress-wrap" hidden>
|
|
262
|
+
<div class="v2-gauge" id="d-gauge" role="progressbar" aria-label="Deploy progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
|
263
|
+
<div class="v2-gauge__head">
|
|
264
|
+
<span class="v2-gauge__label" id="d-phase-label">running</span>
|
|
265
|
+
<span class="v2-gauge__value"><span id="d-phase-pct">0</span><span class="v2-gauge__max"> %</span></span>
|
|
266
|
+
</div>
|
|
267
|
+
<div class="v2-gauge__track"><div class="v2-gauge__fill"></div></div>
|
|
268
|
+
</div>
|
|
269
|
+
<div class="mc-progress__meta">
|
|
270
|
+
<span class="v2-mono v2-t-xs" id="d-phase-rate">-</span>
|
|
271
|
+
<span class="v2-mono v2-t-xs v2-mute" id="d-phase-status">-</span>
|
|
272
|
+
<span class="v2-mono v2-t-xs v2-mute" id="d-phase-idle"></span>
|
|
273
|
+
<span class="v2-mono v2-t-xs v2-mute" id="d-phase-exit"></span>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
|
|
277
|
+
<div class="mc-actions mc-actions--deploy">
|
|
278
|
+
<label class="mc-field mc-field--sm mc-role-field" title="observer: a synced node without a bond. validator: the console pauses after verify so you can top up the wallet, then enrolls and promotes">
|
|
279
|
+
<span class="mc-field__label">Node role</span>
|
|
280
|
+
<select class="v2-input" id="d-role">
|
|
281
|
+
<option value="validator" selected>validator</option>
|
|
282
|
+
<option value="observer">observer</option>
|
|
283
|
+
</select>
|
|
284
|
+
</label>
|
|
285
|
+
<button class="v2-btn v2-btn--brand" id="d-btn-start">
|
|
286
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
287
|
+
aria-hidden="true"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
288
|
+
Start deploy
|
|
289
|
+
</button>
|
|
290
|
+
<button class="v2-btn v2-btn--ghost" id="d-btn-status">
|
|
291
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
292
|
+
aria-hidden="true"><circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><line x1="12" y1="8" x2="12" y2="8"/></svg>
|
|
293
|
+
Print status
|
|
294
|
+
</button>
|
|
295
|
+
<span class="v2-t-xs v2-mute mc-footnote" id="d-action-note">
|
|
296
|
+
One click: check - prep - toolchain - setup - start - verify, then (validator) the top-up popup,
|
|
297
|
+
enroll - promote - verify.
|
|
298
|
+
</span>
|
|
299
|
+
</div>
|
|
300
|
+
|
|
301
|
+
<div class="mc-result" id="d-dash-result" hidden></div>
|
|
302
|
+
</div>
|
|
303
|
+
|
|
304
|
+
<!-- =============== DASHBOARD 2: MIGRATE NODE =============== -->
|
|
305
|
+
<div class="mc-panel" id="panel-migrate" role="tabpanel" aria-label="Migrate node">
|
|
306
|
+
<div class="mc-program__head">
|
|
307
|
+
<span class="mc-program__title">Migrate node</span>
|
|
308
|
+
<span class="v2-t-xs v2-mute">
|
|
309
|
+
Source validator -> new VPS. The source keeps voting until the switch, so the downtime is the
|
|
310
|
+
final delta sync only.
|
|
311
|
+
</span>
|
|
312
|
+
</div>
|
|
313
|
+
<div class="mc-pipeline" id="pipeline-list" role="list" aria-label="Migration pipeline steps"></div>
|
|
314
|
+
|
|
315
|
+
<!-- endpoints: one row per field (host, auth method, credential) -->
|
|
316
|
+
<div class="mc-endpoints">
|
|
317
|
+
<div class="mc-endpoint" id="endpoint-src">
|
|
318
|
+
<span class="mc-endpoint__role" id="endpoint-src-role">Source</span>
|
|
319
|
+
<input class="v2-input v2-mono" id="inp-old" type="text" placeholder="IP address or hostname"
|
|
320
|
+
autocomplete="off" spellcheck="false" aria-label="Source IP address" />
|
|
321
|
+
<div class="mc-auth">
|
|
322
|
+
<select class="v2-input mc-auth__method" id="inp-old-auth" aria-label="Source authentication method"
|
|
323
|
+
data-key="inp-old-key" data-keybox="old-key-box" data-keytext="inp-old-keytext" data-pick="btn-old-key-pick" data-passfield="inp-old-pass" data-eye="btn-old-pass-eye">
|
|
324
|
+
<option value="password">password</option>
|
|
325
|
+
<option value="key">ssh key</option>
|
|
326
|
+
</select>
|
|
327
|
+
<div class="mc-key" id="old-key-box" hidden>
|
|
328
|
+
<div class="mc-key__row">
|
|
329
|
+
<input class="v2-input v2-mono mc-auth__key" id="inp-old-key" type="text"
|
|
330
|
+
placeholder="/home/you/.ssh/id_ed25519" autocomplete="off" spellcheck="false"
|
|
331
|
+
aria-label="Source private key file (OpenSSH)" />
|
|
332
|
+
<button type="button" class="v2-btn v2-btn--ghost mc-key__pick" id="btn-old-key-pick"
|
|
333
|
+
data-key="inp-old-key" title="Pick the private key file on this machine">
|
|
334
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
335
|
+
aria-hidden="true"><circle cx="7.5" cy="15.5" r="3.5"/><path d="M10.3 12.7 20 3"/><path d="M15 8l3 3"/></svg>
|
|
336
|
+
Browse
|
|
337
|
+
</button>
|
|
338
|
+
</div>
|
|
339
|
+
<textarea class="v2-input v2-mono mc-key__text" id="inp-old-keytext" rows="2" spellcheck="false"
|
|
340
|
+
placeholder="or paste the private key text here (saved 0600 on this machine)"></textarea>
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="mc-pass">
|
|
344
|
+
<input class="v2-input" id="inp-old-pass" type="password" placeholder="root password"
|
|
345
|
+
autocomplete="new-password" spellcheck="false" aria-label="Source root password" />
|
|
346
|
+
<button type="button" class="v2-iconbtn mc-pass__toggle" id="btn-old-pass-eye"
|
|
347
|
+
data-pass="inp-old-pass" data-pass-label="source password"
|
|
348
|
+
aria-label="Show source password" aria-pressed="false" title="Show password">
|
|
349
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-open" viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
350
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-off" viewBox="0 0 24 24" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
351
|
+
</button>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
|
|
355
|
+
<div class="mc-endpoint">
|
|
356
|
+
<span class="mc-endpoint__role" id="endpoint-dst-role">Target</span>
|
|
357
|
+
<input class="v2-input v2-mono" id="inp-new" type="text" placeholder="IP address or hostname"
|
|
358
|
+
autocomplete="off" spellcheck="false" aria-label="Target IP address" />
|
|
359
|
+
<div class="mc-auth">
|
|
360
|
+
<select class="v2-input mc-auth__method" id="inp-new-auth" aria-label="Target authentication method"
|
|
361
|
+
data-key="inp-new-key" data-keybox="new-key-box" data-keytext="inp-new-keytext" data-pick="btn-new-key-pick" data-passfield="inp-new-pass" data-eye="btn-new-pass-eye" data-mirror-source="inp-old-auth">
|
|
362
|
+
<option value="password">password</option>
|
|
363
|
+
<option value="key">ssh key</option>
|
|
364
|
+
</select>
|
|
365
|
+
<div class="mc-key" id="new-key-box" hidden>
|
|
366
|
+
<div class="mc-key__row">
|
|
367
|
+
<input class="v2-input v2-mono mc-auth__key" id="inp-new-key" type="text"
|
|
368
|
+
placeholder="/home/you/.ssh/id_ed25519" autocomplete="off" spellcheck="false"
|
|
369
|
+
aria-label="Target private key file (OpenSSH)" />
|
|
370
|
+
<button type="button" class="v2-btn v2-btn--ghost mc-key__pick" id="btn-new-key-pick"
|
|
371
|
+
data-key="inp-new-key" title="Pick the private key file on this machine">
|
|
372
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
373
|
+
aria-hidden="true"><circle cx="7.5" cy="15.5" r="3.5"/><path d="M10.3 12.7 20 3"/><path d="M15 8l3 3"/></svg>
|
|
374
|
+
Browse
|
|
375
|
+
</button>
|
|
376
|
+
</div>
|
|
377
|
+
<textarea class="v2-input v2-mono mc-key__text" id="inp-new-keytext" rows="2" spellcheck="false"
|
|
378
|
+
placeholder="or paste the private key text here (saved 0600 on this machine)"></textarea>
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
<div class="mc-pass">
|
|
382
|
+
<input class="v2-input" id="inp-new-pass" type="password" placeholder="root password"
|
|
383
|
+
autocomplete="new-password" spellcheck="false" aria-label="Target root password" />
|
|
384
|
+
<button type="button" class="v2-iconbtn mc-pass__toggle" id="btn-new-pass-eye"
|
|
385
|
+
data-pass="inp-new-pass" data-pass-label="target password"
|
|
386
|
+
aria-label="Show target password" aria-pressed="false" title="Show password">
|
|
387
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-open" viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
388
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-off" viewBox="0 0 24 24" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
389
|
+
</button>
|
|
390
|
+
</div>
|
|
391
|
+
<label class="mc-samepass" for="chk-same-pass">
|
|
392
|
+
<input type="checkbox" id="chk-same-pass" checked />
|
|
393
|
+
<span>same credential as source</span>
|
|
394
|
+
</label>
|
|
395
|
+
</div>
|
|
396
|
+
</div>
|
|
397
|
+
|
|
398
|
+
<!-- options: the verify samples/interval are fixed by the program -->
|
|
399
|
+
<div class="mc-form" role="group" aria-label="Migration options">
|
|
400
|
+
<button class="v2-btn v2-btn--primary mc-check-btn" id="btn-check" title="Verify every precondition">
|
|
401
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
402
|
+
Check
|
|
403
|
+
</button>
|
|
404
|
+
<button class="v2-btn v2-btn--ghost" id="btn-swap" title="Swap source and target">
|
|
405
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
406
|
+
aria-hidden="true"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
|
|
407
|
+
swap
|
|
408
|
+
</button>
|
|
409
|
+
<span class="v2-t-xs v2-mute mc-footnote">
|
|
410
|
+
Passwords stay in this browser tab and the local server process - never written to disk.
|
|
411
|
+
The target data volume is formatted and mounted automatically.
|
|
412
|
+
</span>
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
<!-- precondition check result -->
|
|
416
|
+
<div class="mc-check" id="check-result" hidden>
|
|
417
|
+
<div class="mc-check__head">
|
|
418
|
+
<span class="v2-badge" id="check-badge">
|
|
419
|
+
<span id="check-badge-text">not checked</span>
|
|
420
|
+
</span>
|
|
421
|
+
<span class="v2-t-xs v2-mute" id="check-summary">-</span>
|
|
422
|
+
<span class="v2-t-xs v2-mono v2-mute" id="check-age"></span>
|
|
423
|
+
</div>
|
|
424
|
+
<div class="mc-check__list" id="check-list" role="list"></div>
|
|
425
|
+
<div class="mc-check__actions" id="check-actions" hidden></div>
|
|
426
|
+
</div>
|
|
427
|
+
|
|
428
|
+
<!-- progress -->
|
|
429
|
+
<div class="mc-progress" id="progress-wrap" hidden>
|
|
430
|
+
<div class="v2-gauge" id="phase-gauge" role="progressbar" aria-label="Phase progress" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
|
431
|
+
<div class="v2-gauge__head">
|
|
432
|
+
<span class="v2-gauge__label" id="phase-label">running</span>
|
|
433
|
+
<span class="v2-gauge__value"><span id="phase-pct">0</span><span class="v2-gauge__max"> %</span></span>
|
|
434
|
+
</div>
|
|
435
|
+
<div class="v2-gauge__track"><div class="v2-gauge__fill"></div></div>
|
|
436
|
+
</div>
|
|
437
|
+
<div class="mc-progress__meta">
|
|
438
|
+
<span class="v2-mono v2-t-xs" id="phase-rate">-</span>
|
|
439
|
+
<span class="v2-mono v2-t-xs v2-mute" id="phase-status">-</span>
|
|
440
|
+
<span class="v2-mono v2-t-xs v2-mute" id="phase-idle"></span>
|
|
441
|
+
<span class="v2-mono v2-t-xs v2-mute" id="phase-exit"></span>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
|
|
445
|
+
<!-- no manual step list: the console runs the whole pipeline in order, then
|
|
446
|
+
watches the chain admit the migrated validator (the monitoring
|
|
447
|
+
dashboard is a Manage active node action, not part of a migration) -->
|
|
448
|
+
<div class="mc-actions">
|
|
449
|
+
<button class="v2-btn v2-btn--brand" id="btn-run-all">
|
|
450
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
451
|
+
aria-hidden="true"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
452
|
+
Start migration
|
|
453
|
+
</button>
|
|
454
|
+
<button class="v2-btn v2-btn--danger" id="btn-run-rollback">
|
|
455
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
456
|
+
aria-hidden="true"><polyline points="9 14 4 9 9 4"/><path d="M20 20v-7a4 4 0 0 0-4-4H4"/></svg>
|
|
457
|
+
Rollback
|
|
458
|
+
</button>
|
|
459
|
+
<button class="v2-btn v2-btn--ghost" id="btn-status">
|
|
460
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
461
|
+
aria-hidden="true"><circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><line x1="12" y1="8" x2="12" y2="8"/></svg>
|
|
462
|
+
Print status
|
|
463
|
+
</button>
|
|
464
|
+
<!-- the note is filled by app.js (the last identity backup, or a warning):
|
|
465
|
+
empty by default, and `:empty` hides it -->
|
|
466
|
+
<span class="v2-t-xs v2-mute mc-footnote" id="action-note"></span>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<div class="mc-result" id="dash-result" hidden></div>
|
|
470
|
+
</div>
|
|
471
|
+
|
|
472
|
+
<!-- =============== DASHBOARD 3: MANAGE ACTIVE NODE =============== -->
|
|
473
|
+
<div class="mc-panel" id="panel-manage" role="tabpanel" aria-label="Manage active node" hidden>
|
|
474
|
+
<div class="mc-program__head">
|
|
475
|
+
<span class="mc-program__title">Manage active node</span>
|
|
476
|
+
<span class="v2-t-xs v2-mute">
|
|
477
|
+
The validator that already runs on this host: increase its bond, exit the set and take the
|
|
478
|
+
stake back, or deploy the read-only monitoring dashboard (graphs, logs, wallet).
|
|
479
|
+
</span>
|
|
480
|
+
</div>
|
|
481
|
+
<div class="mc-pipeline" id="m-pipeline" role="list" aria-label="Manage actions"></div>
|
|
482
|
+
|
|
483
|
+
<div class="mc-endpoints">
|
|
484
|
+
<div class="mc-endpoint">
|
|
485
|
+
<span class="mc-endpoint__role">Node</span>
|
|
486
|
+
<input class="v2-input v2-mono" id="m-inp-ip" type="text" placeholder="IP address of the validator"
|
|
487
|
+
autocomplete="off" spellcheck="false" aria-label="Validator IP address" />
|
|
488
|
+
<div class="mc-auth">
|
|
489
|
+
<select class="v2-input mc-auth__method" id="m-inp-auth" aria-label="Node authentication method"
|
|
490
|
+
data-key="m-inp-key" data-keybox="m-key-box" data-keytext="m-inp-keytext" data-pick="m-btn-key-pick" data-passfield="m-inp-pass" data-eye="m-btn-pass-eye">
|
|
491
|
+
<option value="password">password</option>
|
|
492
|
+
<option value="key">ssh key</option>
|
|
493
|
+
</select>
|
|
494
|
+
<div class="mc-key" id="m-key-box" hidden>
|
|
495
|
+
<div class="mc-key__row">
|
|
496
|
+
<input class="v2-input v2-mono mc-auth__key" id="m-inp-key" type="text"
|
|
497
|
+
placeholder="/home/you/.ssh/id_ed25519" autocomplete="off" spellcheck="false"
|
|
498
|
+
aria-label="Node private key file (OpenSSH)" />
|
|
499
|
+
<button type="button" class="v2-btn v2-btn--ghost mc-key__pick" id="m-btn-key-pick"
|
|
500
|
+
data-key="m-inp-key" title="Pick the private key file on this machine">
|
|
501
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
502
|
+
aria-hidden="true"><circle cx="7.5" cy="15.5" r="3.5"/><path d="M10.3 12.7 20 3"/><path d="M15 8l3 3"/></svg>
|
|
503
|
+
Browse
|
|
504
|
+
</button>
|
|
505
|
+
</div>
|
|
506
|
+
<textarea class="v2-input v2-mono mc-key__text" id="m-inp-keytext" rows="2" spellcheck="false"
|
|
507
|
+
placeholder="or paste the private key text here (saved 0600 on this machine)"></textarea>
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
<div class="mc-pass">
|
|
511
|
+
<input class="v2-input" id="m-inp-pass" type="password" placeholder="root password"
|
|
512
|
+
autocomplete="new-password" aria-label="Root password" />
|
|
513
|
+
<button type="button" class="v2-iconbtn mc-pass__toggle" id="m-btn-pass-eye"
|
|
514
|
+
data-pass="m-inp-pass" data-pass-label="node password"
|
|
515
|
+
aria-label="Show node password" aria-pressed="false" title="Show password">
|
|
516
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-open" viewBox="0 0 24 24" aria-hidden="true"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
517
|
+
<svg class="v2-icon v2-icon--16 mc-pass__eye-off" viewBox="0 0 24 24" aria-hidden="true"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
518
|
+
</button>
|
|
519
|
+
</div>
|
|
520
|
+
</div>
|
|
521
|
+
</div>
|
|
522
|
+
|
|
523
|
+
<!-- Check stays with the form: it validates the address + credentials the
|
|
524
|
+
operator just typed. The node actions (bond / exit / monitor / status)
|
|
525
|
+
live in the "Live node state" section, right next to the state they
|
|
526
|
+
act on (2026-11-05). -->
|
|
527
|
+
<div class="mc-actions">
|
|
528
|
+
<button class="v2-btn v2-btn--primary" id="m-btn-check">
|
|
529
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
530
|
+
aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
531
|
+
Check
|
|
532
|
+
</button>
|
|
533
|
+
<label class="mc-enroll__check" for="m-test-only"
|
|
534
|
+
title="Update node only: run the official tool's test pass (it checks the mechanics and changes nothing)">
|
|
535
|
+
<input type="checkbox" id="m-test-only" />
|
|
536
|
+
<span>Update: test only (change nothing)</span>
|
|
537
|
+
</label>
|
|
538
|
+
</div>
|
|
539
|
+
|
|
540
|
+
<div class="mc-check" id="m-check-result" hidden>
|
|
541
|
+
<div class="mc-check__head">
|
|
542
|
+
<span class="v2-badge" id="m-check-badge">
|
|
543
|
+
<span id="m-check-badge-text">not checked</span>
|
|
544
|
+
</span>
|
|
545
|
+
<span class="v2-t-xs v2-mute" id="m-check-summary">-</span>
|
|
546
|
+
<span class="v2-t-xs v2-mono v2-mute" id="m-check-age"></span>
|
|
547
|
+
</div>
|
|
548
|
+
<div class="mc-check__list" id="m-check-list" role="list"></div>
|
|
549
|
+
<div class="mc-check__actions" id="m-check-actions" hidden></div>
|
|
550
|
+
</div>
|
|
551
|
+
|
|
552
|
+
<div class="mc-progress" id="m-progress-wrap" hidden>
|
|
553
|
+
<div class="v2-gauge" id="m-gauge" role="progressbar" aria-label="Manage progress"
|
|
554
|
+
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
|
555
|
+
<div class="v2-gauge__head">
|
|
556
|
+
<span class="v2-gauge__label" id="m-phase-label">running</span>
|
|
557
|
+
<span class="v2-gauge__value"><span id="m-phase-pct">0</span><span class="v2-gauge__max"> %</span></span>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="v2-gauge__track"><div class="v2-gauge__fill"></div></div>
|
|
560
|
+
</div>
|
|
561
|
+
<div class="mc-progress__meta">
|
|
562
|
+
<span class="v2-mono v2-t-xs" id="m-phase-rate">-</span>
|
|
563
|
+
<span class="v2-mono v2-t-xs v2-mute" id="m-phase-status">-</span>
|
|
564
|
+
<span class="v2-mono v2-t-xs v2-mute" id="m-phase-idle"></span>
|
|
565
|
+
<span class="v2-mono v2-t-xs v2-mute" id="m-phase-exit"></span>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
|
|
569
|
+
<div class="mc-result" id="m-dash-result" hidden></div>
|
|
570
|
+
</div>
|
|
571
|
+
|
|
572
|
+
</section>
|
|
573
|
+
|
|
574
|
+
<section class="v2-section v2-section--compact" id="nodes" aria-label="Node state">
|
|
575
|
+
<div class="v2-section__head">
|
|
576
|
+
<span class="v2-section__title">Live node state</span>
|
|
577
|
+
<span class="v2-section__meta" id="nodes-meta">every 10s - node REST API</span>
|
|
578
|
+
</div>
|
|
579
|
+
<div class="mc-nodes" id="nodes-grid">
|
|
580
|
+
<div class="mc-node" id="node-src-card">
|
|
581
|
+
<div class="mc-node__head">
|
|
582
|
+
<span class="v2-badge" id="src-role">source</span>
|
|
583
|
+
<span class="v2-mono mc-node__ip" id="src-ip">-</span>
|
|
584
|
+
<span class="v2-badge" id="src-state"><span id="src-state-text">-</span></span>
|
|
585
|
+
</div>
|
|
586
|
+
<div class="v2-stat-strip">
|
|
587
|
+
<div class="v2-stat"><span class="v2-stat__label">Epoch</span><div class="v2-stat__value v2-mono" id="src-epoch">-</div><span class="v2-t-xs v2-mute" id="src-head">-</span></div>
|
|
588
|
+
<div class="v2-stat"><span class="v2-stat__label">Membership</span><div class="v2-stat__value" id="src-membership">-</div><span class="v2-t-xs v2-mute" id="src-nextset">-</span></div>
|
|
589
|
+
<div class="v2-stat"><span class="v2-stat__label">Enrollment</span><div class="v2-stat__value" id="src-enroll">-</div><span class="v2-t-xs v2-mute" id="src-bond">-</span></div>
|
|
590
|
+
</div>
|
|
591
|
+
<div class="mc-node__foot v2-mono v2-t-xs v2-mute" id="src-foot">-</div>
|
|
592
|
+
</div>
|
|
593
|
+
|
|
594
|
+
<div class="mc-node">
|
|
595
|
+
<div class="mc-node__head">
|
|
596
|
+
<span class="v2-badge" id="dst-role">target</span>
|
|
597
|
+
<span class="v2-mono mc-node__ip" id="dst-ip">-</span>
|
|
598
|
+
<span class="v2-badge" id="dst-state"><span id="dst-state-text">-</span></span>
|
|
599
|
+
</div>
|
|
600
|
+
<div class="v2-stat-strip">
|
|
601
|
+
<div class="v2-stat"><span class="v2-stat__label">Epoch</span><div class="v2-stat__value v2-mono" id="dst-epoch">-</div><span class="v2-t-xs v2-mute" id="dst-head">-</span></div>
|
|
602
|
+
<div class="v2-stat"><span class="v2-stat__label">Membership</span><div class="v2-stat__value" id="dst-membership">-</div><span class="v2-t-xs v2-mute" id="dst-nextset">-</span></div>
|
|
603
|
+
<div class="v2-stat"><span class="v2-stat__label">Enrollment</span><div class="v2-stat__value" id="dst-enroll">-</div><span class="v2-t-xs v2-mute" id="dst-bond">-</span></div>
|
|
604
|
+
</div>
|
|
605
|
+
<div class="mc-node__foot v2-mono v2-t-xs v2-mute" id="dst-foot">-</div>
|
|
606
|
+
</div>
|
|
607
|
+
|
|
608
|
+
<!-- ---------- manage: the actions for the node on the left ----------
|
|
609
|
+
They are part of the state they act on, so they sit right next to the
|
|
610
|
+
stats (2 columns x 2 rows, centred), and the pointer/warning line
|
|
611
|
+
below them is the note app.js fills. Deploy and Migrate hide the
|
|
612
|
+
whole block (it is the Manage tool's action set, 2026-11-05). -->
|
|
613
|
+
<div class="mc-nodeactions" id="node-actions" hidden>
|
|
614
|
+
<div class="mc-nodeactions__grid" role="group" aria-label="Manage this validator">
|
|
615
|
+
<button class="v2-btn v2-btn--primary mc-nodeactions__wide" id="m-btn-dashboard"
|
|
616
|
+
title="Publish the read-only monitoring dashboard (asks for the host name and the certificate)">
|
|
617
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
618
|
+
aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
|
619
|
+
Deploy Dashboard Monitor
|
|
620
|
+
</button>
|
|
621
|
+
<button class="v2-btn" id="m-btn-bond"
|
|
622
|
+
title="Add OCT to the bond (bond_inc.sh runs as the octra user; later increases add --new automatically)">
|
|
623
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
624
|
+
aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
|
|
625
|
+
Increase bond
|
|
626
|
+
</button>
|
|
627
|
+
<button class="v2-btn" id="m-btn-status"
|
|
628
|
+
title="Read the identity, membership, bond and wallet balance from the host">
|
|
629
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
630
|
+
aria-hidden="true"><circle cx="12" cy="12" r="9"/><line x1="12" y1="11" x2="12" y2="16"/><line x1="12" y1="8" x2="12" y2="8"/></svg>
|
|
631
|
+
Print status
|
|
632
|
+
</button>
|
|
633
|
+
<button class="v2-btn" id="m-btn-upgrade"
|
|
634
|
+
title="Run the official controls/upgrade.sh: it checks the repo in test mode first, then applies (build, restart, wait until the node is operational)">
|
|
635
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
636
|
+
aria-hidden="true"><path d="M21 12a9 9 0 1 1-3-6.7"/><polyline points="21 3 21 9 15 9"/></svg>
|
|
637
|
+
Update node (auto)
|
|
638
|
+
</button>
|
|
639
|
+
<button class="v2-btn" id="m-btn-manual"
|
|
640
|
+
title="The README's manual path (used when the official tool cannot run): git pull, check.sh, make mcl, dune build, stop, run --rebind-runtime, stat">
|
|
641
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
642
|
+
aria-hidden="true"><path d="M14.7 6.3a4 4 0 0 1-5.4 5.4L4 17v3h3l5.3-5.3a4 4 0 0 1 5.4-5.4l-2.6 2.6 1.4 1.4 2.6-2.6a4 4 0 0 1-5.4 0z"/></svg>
|
|
643
|
+
Manual update
|
|
644
|
+
</button>
|
|
645
|
+
<button class="v2-btn" id="m-btn-diagnose"
|
|
646
|
+
title="Read-only: why is this node not voting? pm2 state, /rpc vs /status, head_epoch moving or frozen, how far behind it is, the last catch-up refusal and rejoin.sh --check">
|
|
647
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
648
|
+
aria-hidden="true"><circle cx="11" cy="11" r="7"/><line x1="16.5" y1="16.5" x2="21" y2="21"/></svg>
|
|
649
|
+
Diagnose node
|
|
650
|
+
</button>
|
|
651
|
+
<button class="v2-btn" id="m-btn-recover"
|
|
652
|
+
title="The solved path for a node stuck in 'ready / outside set': clean pm2 restart when it is frozen, pm2 session re-created when rejoin.sh says the data directory is used outside PM2, bounded catch-up, then rejoin/join - it signs nothing and never exits">
|
|
653
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
654
|
+
aria-hidden="true"><path d="M3 12a9 9 0 0 1 15.5-6.2"/><polyline points="21 3 21 9 15 9"/><path d="M21 12a9 9 0 0 1-15.5 6.2"/><polyline points="3 21 3 15 9 15"/></svg>
|
|
655
|
+
Fix stuck node
|
|
656
|
+
</button>
|
|
657
|
+
<button class="v2-btn mc-nodeactions__wide" id="m-btn-storage"
|
|
658
|
+
title="controls/storage.sh --prune-prior --yes: drop the states of the previous epochs to free disk (the daily prune job does this too)">
|
|
659
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
660
|
+
aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
|
|
661
|
+
Prune preserved states
|
|
662
|
+
</button>
|
|
663
|
+
<button class="v2-btn v2-btn--danger mc-nodeactions__wide" id="m-btn-exit"
|
|
664
|
+
title="Leave the validator set, wait for the unbonding and take the stake back (the node is not deleted)">
|
|
665
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
666
|
+
aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
|
667
|
+
Exit validator
|
|
668
|
+
</button>
|
|
669
|
+
<span class="v2-t-xs v2-mute mc-nodeactions__note" id="m-action-note">
|
|
670
|
+
Critical: bond and exit need the node to be the ACTIVE validator. Increase bond = bond_inc.sh as the
|
|
671
|
+
octra user (the first increase runs plain, later ones add --new automatically). Exit = the exit is
|
|
672
|
+
signed now, the stake unlocks at the epoch the console reports, and this host retries the withdrawal
|
|
673
|
+
by itself every 15 minutes (no follow-up needed). Update = controls/upgrade.sh (tested first, then applied);
|
|
674
|
+
the manual fallback pulls and rebuilds by hand. Neither ever syncs, changes config/network.env or
|
|
675
|
+
re-enrolls the node; prune only drops the preserved states. Diagnose = evidence only; Fix stuck node =
|
|
676
|
+
bounded repair (pm2 restart / session, catch-up, rejoin, readiness) and never a new bond or an exit.
|
|
677
|
+
</span>
|
|
678
|
+
</div>
|
|
679
|
+
</div>
|
|
680
|
+
|
|
681
|
+
</div>
|
|
682
|
+
</section>
|
|
683
|
+
|
|
684
|
+
<!-- ---------- 3. LIVE LOG ---------- -->
|
|
685
|
+
<section class="v2-section v2-section--compact" id="log" aria-label="Live log">
|
|
686
|
+
<div class="v2-section__head">
|
|
687
|
+
<span class="v2-section__title">Live log</span>
|
|
688
|
+
<span class="v2-section__meta" id="log-meta">streaming - 0 lines</span>
|
|
689
|
+
</div>
|
|
690
|
+
|
|
691
|
+
<div class="mc-logbar">
|
|
692
|
+
<div class="v2-seg" role="group" aria-label="Log level filter">
|
|
693
|
+
<button class="v2-seg__btn v2-seg__btn--active" data-level="all">All</button>
|
|
694
|
+
<button class="v2-seg__btn" data-level="info">Info</button>
|
|
695
|
+
<button class="v2-seg__btn" data-level="ok">OK</button>
|
|
696
|
+
<button class="v2-seg__btn" data-level="warn">Warn</button>
|
|
697
|
+
<button class="v2-seg__btn" data-level="error">Error</button>
|
|
698
|
+
</div>
|
|
699
|
+
<div class="v2-seg mc-logbar__hosts" id="seg-host" role="group" aria-label="Host filter" hidden></div>
|
|
700
|
+
<input class="v2-input mc-logbar__search" id="inp-log-filter" type="search" placeholder="filter text..." aria-label="Filter log text" />
|
|
701
|
+
<button class="v2-btn v2-btn--ghost mc-logbtn" id="btn-log-pause" aria-pressed="false" title="Pause the live log">
|
|
702
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
703
|
+
aria-hidden="true"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>
|
|
704
|
+
<span id="btn-log-pause-text">Pause</span>
|
|
705
|
+
</button>
|
|
706
|
+
<button class="v2-btn v2-btn--ghost mc-logbtn" id="btn-log-clear" title="Clear the log view">
|
|
707
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
708
|
+
aria-hidden="true"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><path d="M10 11v6M14 11v6"/><path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
|
|
709
|
+
<span>Clear</span>
|
|
710
|
+
</button>
|
|
711
|
+
<button class="v2-btn v2-btn--ghost mc-logbtn" id="btn-log-download" title="Download the log as text">
|
|
712
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
713
|
+
aria-hidden="true"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
|
714
|
+
<span>Download</span>
|
|
715
|
+
</button>
|
|
716
|
+
<span class="mc-legend" id="log-legend" hidden></span>
|
|
717
|
+
</div>
|
|
718
|
+
|
|
719
|
+
<div class="v2-log v2-log--scroll v2-log--bordered" id="log-view" role="log" aria-label="Run output">
|
|
720
|
+
<div class="v2-log__empty" id="log-empty">waiting for output...</div>
|
|
721
|
+
</div>
|
|
722
|
+
</section>
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
<!-- ---------- 4. GUIDE ---------- -->
|
|
726
|
+
<section class="v2-section v2-section--compact" id="guide" aria-label="Guide">
|
|
727
|
+
<div class="v2-section__head">
|
|
728
|
+
<span class="v2-section__title">Runbook & safety</span>
|
|
729
|
+
<span class="v2-section__meta">one column per program - what it does, what is safe, what takes time</span>
|
|
730
|
+
</div>
|
|
731
|
+
|
|
732
|
+
<div class="mc-guide mc-guide--three">
|
|
733
|
+
<div class="mc-guide__col">
|
|
734
|
+
<h3 class="mc-guide__h">Deploy fresh node</h3>
|
|
735
|
+
<ul class="mc-guide__list">
|
|
736
|
+
<li><strong>Use it for:</strong> a brand-new VPS that should become an Octra node.</li>
|
|
737
|
+
<li>It prepares the machine, builds the node, creates a new wallet and syncs the chain.</li>
|
|
738
|
+
<li>When the node is up it asks for the <strong>top-up</strong> and the <strong>bond amount</strong>; after you press <strong>Enroll</strong> the console tells you the epoch the chain scheduled and keeps watching - yellow, not red - until the node is an <strong>active validator and voting</strong>. A popup appears by itself the moment that happens, even if the run is already over.</li>
|
|
739
|
+
<li>Your only input is the host and its login. Swap size is the one setting you may change.</li>
|
|
740
|
+
<li>The monitoring dashboard is <strong>not</strong> part of a deploy: publish it later from <strong>Manage active node - Deploy monitor</strong>.</li>
|
|
741
|
+
<li><strong>Takes:</strong> roughly 45-100 minutes; the chain sync is the slow part.</li>
|
|
742
|
+
<li>The machine must be <strong>empty</strong> - if a node already runs there, use Migrate.</li>
|
|
743
|
+
</ul>
|
|
744
|
+
</div>
|
|
745
|
+
<div class="mc-guide__col">
|
|
746
|
+
<h3 class="mc-guide__h">Migrate node</h3>
|
|
747
|
+
<ul class="mc-guide__list">
|
|
748
|
+
<li><strong>Use it for:</strong> moving the validator that already runs to a new machine.</li>
|
|
749
|
+
<li>It copies the wallet and the chain first, and only then stops the old node - so the downtime is short.</li>
|
|
750
|
+
<li>The old machine stays powered off afterwards: keep it as the fallback.</li>
|
|
751
|
+
<li>The run ends by watching the chain admit the migrated validator: yellow while it waits, and a popup when it starts voting.</li>
|
|
752
|
+
<li><strong>Takes:</strong> about 30-60 minutes; the validator is offline only for the final catch-up.</li>
|
|
753
|
+
<li>Never start the old node again while the new one is running - two copies of one wallet is the one thing that must not happen.</li>
|
|
754
|
+
</ul>
|
|
755
|
+
</div>
|
|
756
|
+
<div class="mc-guide__col">
|
|
757
|
+
<h3 class="mc-guide__h">Manage active node</h3>
|
|
758
|
+
<ul class="mc-guide__list">
|
|
759
|
+
<li><strong>Use it for:</strong> the validator that is already running - increasing its bond, leaving the set, updating its software or putting the monitor online.</li>
|
|
760
|
+
<li><strong>Increase bond</strong> adds OCT to the stake; the console asks for the amount (whole OCT) in a popup. Ask for a <em>new</em> increase only after the previous one is confirmed (the console handles that for you).</li>
|
|
761
|
+
<li><strong>Exit validator</strong> leaves the validator set and waits until the stake comes back to the wallet. It can take a while - the network releases the stake on its own schedule. The node itself is not deleted.</li>
|
|
762
|
+
<li>Both need the node to be the <strong>active</strong> validator, so press <strong>Check</strong> first.</li>
|
|
763
|
+
<li><strong>Node stuck in "ready / outside set"?</strong> <strong>Diagnose node</strong> shows why (pm2, RPC,
|
|
764
|
+
head frozen, epochs behind, the rejoin verdict, memory), then <strong>Fix stuck node</strong> runs the
|
|
765
|
+
bounded repair - pm2 restart / session, catch-up wait, rejoin, readiness. It signs no bond and never
|
|
766
|
+
exits, and neither button needs a passing Check: a broken node cannot pass one.</li>
|
|
767
|
+
<li>Optional: <strong>Deploy monitor</strong> puts the read-only live dashboard online (graphs, logs, wallet, consensus) - the manage actions behind it live in this tab, not on the dashboard. The popup asks for the host name and how to get the certificate - your own Cloudflare origin files, or an automatic Let's Encrypt one (the host name must already point at the machine).</li>
|
|
768
|
+
<li><strong>Update node</strong> (same section) updates the software when the developer announces a release (upstream README: "How to update (if you are already a validator)"): <span class="v2-mono">controls/upgrade.sh</span> is run in test mode first - it changes nothing - and only then with <span class="v2-mono">--apply</span> (pull, build, restart, wait, verify). Its own verdict tells you it worked: <span class="v2-mono">validator_active</span> or <span class="v2-mono">observer_synced</span>.</li>
|
|
769
|
+
<li>If that tool cannot run, <strong>Manual update</strong> does what the README lists by hand: <span class="v2-mono">git pull</span>, check, build <span class="v2-mono">mcl</span>, dune build, stop, <span class="v2-mono">run.sh --rebind-runtime</span>, stat.</li>
|
|
770
|
+
<li><strong>Prune preserved states</strong> drops the states of the previous epochs (<span class="v2-mono">storage.sh --prune-prior --yes</span>) to free disk; the daily prune job does it too.</li>
|
|
771
|
+
<li>An update <strong>never</strong> runs a sync, never changes <span class="v2-mono">config/network.env</span> and never re-enrolls: the identity and the data stay. The node is offline only for the restart.</li>
|
|
772
|
+
</ul>
|
|
773
|
+
</div>
|
|
774
|
+
</div>
|
|
775
|
+
<p class="v2-t-xs v2-mute mc-guide__foot">
|
|
776
|
+
The console only talks to the hosts you type; nothing is stored in the browser. Green means
|
|
777
|
+
done, yellow is a normal wait, red needs your attention.
|
|
778
|
+
</p>
|
|
779
|
+
</section>
|
|
780
|
+
|
|
781
|
+
</div>
|
|
782
|
+
</main>
|
|
783
|
+
</div>
|
|
784
|
+
|
|
785
|
+
<!-- ---------- APPROVAL MODAL (one click, no typing) ---------- -->
|
|
786
|
+
<div class="mc-modal" id="confirm-modal" hidden role="dialog" aria-modal="true" aria-labelledby="confirm-title">
|
|
787
|
+
<div class="mc-modal__body">
|
|
788
|
+
<h2 class="mc-modal__title" id="confirm-title">Confirm phase</h2>
|
|
789
|
+
<p class="mc-modal__text" id="confirm-text">-</p>
|
|
790
|
+
<p class="mc-modal__text mc-enroll__note" id="confirm-risk">-</p>
|
|
791
|
+
<div class="mc-modal__actions">
|
|
792
|
+
<button class="v2-btn v2-btn--ghost" id="confirm-cancel">
|
|
793
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
794
|
+
aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
795
|
+
Cancel
|
|
796
|
+
</button>
|
|
797
|
+
<button class="v2-btn v2-btn--brand" id="confirm-ok">
|
|
798
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
799
|
+
aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
800
|
+
Approve & run
|
|
801
|
+
</button>
|
|
802
|
+
</div>
|
|
803
|
+
</div>
|
|
804
|
+
</div>
|
|
805
|
+
|
|
806
|
+
<!-- ---------- BROWSER-NATIVE PICKERS (hidden) ---------------------------
|
|
807
|
+
The two "Browse"/"Choose folder" buttons drive these inputs instead of a
|
|
808
|
+
dialog opened by the console process: Windows refuses to activate a window
|
|
809
|
+
created by a process that has no foreground window, so the native dialog was
|
|
810
|
+
built behind the browser and the operator saw nothing. A dialog opened by
|
|
811
|
+
the browser itself is always in front, and the picked file text is what the
|
|
812
|
+
server stores (tmp/keys/ and tmp/certs/). -->
|
|
813
|
+
<input type="file" id="inp-key-pick" accept=".pem,.key,.ppk,id_*,*" hidden />
|
|
814
|
+
<input type="file" id="inp-cert-dir" webkitdirectory directory multiple hidden />
|
|
815
|
+
|
|
816
|
+
<!-- ---------- BOND MODAL (manage: increase the bond) ---------- -->
|
|
817
|
+
<div class="mc-modal" id="bond-modal" hidden role="dialog" aria-modal="true" aria-labelledby="bond-title">
|
|
818
|
+
<div class="mc-modal__body">
|
|
819
|
+
<h2 class="mc-modal__title" id="bond-title">Increase bond</h2>
|
|
820
|
+
<p class="mc-modal__text">
|
|
821
|
+
Adds OCT to the stake of the validator running on
|
|
822
|
+
<span class="v2-mono" id="bond-node">-</span>. The node signs the transaction
|
|
823
|
+
itself (<span class="v2-mono">bond_inc.sh</span> as the octra user); the first
|
|
824
|
+
increase runs plain, every later one is a new increase (<span class="v2-mono">--new</span>)
|
|
825
|
+
and is only allowed once the previous one is confirmed.
|
|
826
|
+
</p>
|
|
827
|
+
<label class="mc-field">
|
|
828
|
+
<span class="mc-field__label">Amount to add (OCT)</span>
|
|
829
|
+
<input class="v2-input v2-mono" id="bond-amount" type="number" min="1" step="1" value="1"
|
|
830
|
+
autocomplete="off" spellcheck="false" />
|
|
831
|
+
</label>
|
|
832
|
+
<p class="mc-modal__text mc-enroll__note" id="bond-note"></p>
|
|
833
|
+
<div class="mc-modal__actions">
|
|
834
|
+
<button class="v2-btn v2-btn--ghost" id="bond-cancel">
|
|
835
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
836
|
+
aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
837
|
+
Cancel
|
|
838
|
+
</button>
|
|
839
|
+
<button class="v2-btn v2-btn--brand" id="bond-ok">
|
|
840
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
841
|
+
aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
|
|
842
|
+
Increase bond
|
|
843
|
+
</button>
|
|
844
|
+
</div>
|
|
845
|
+
</div>
|
|
846
|
+
</div>
|
|
847
|
+
|
|
848
|
+
<!-- ---------- EXIT MODAL (manage: leave the validator set) ---------- -->
|
|
849
|
+
<div class="mc-modal" id="exit-modal" hidden role="dialog" aria-modal="true" aria-labelledby="exit-title">
|
|
850
|
+
<div class="mc-modal__body">
|
|
851
|
+
<h2 class="mc-modal__title" id="exit-title">Exit validator</h2>
|
|
852
|
+
<p class="mc-modal__text">
|
|
853
|
+
This takes <span class="v2-mono" id="exit-node">-</span> out of the validator set and
|
|
854
|
+
starts the exit. The console:
|
|
855
|
+
</p>
|
|
856
|
+
<ul class="mc-guide__list">
|
|
857
|
+
<li>submits the exit transaction (the node stops voting),</li>
|
|
858
|
+
<li>reports the epoch the chain recorded the exit at and the epoch the stake unlocks at,</li>
|
|
859
|
+
<li>leaves the withdrawal to this host (a timer retries it every 15 minutes) and
|
|
860
|
+
reports again when the funds are back.</li>
|
|
861
|
+
</ul>
|
|
862
|
+
<p class="mc-modal__text">
|
|
863
|
+
The unbonding period decides how long that takes (often a day or more), so nothing has
|
|
864
|
+
to be watched or re-run: the node itself is <strong>not</strong> deleted and the wallet
|
|
865
|
+
stays valid.
|
|
866
|
+
</p>
|
|
867
|
+
<p class="mc-modal__text mc-enroll__note" id="exit-note"></p>
|
|
868
|
+
<div class="mc-modal__actions">
|
|
869
|
+
<button class="v2-btn v2-btn--ghost" id="exit-cancel">
|
|
870
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
871
|
+
aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
|
872
|
+
Keep validating
|
|
873
|
+
</button>
|
|
874
|
+
<button class="v2-btn v2-btn--danger" id="exit-ok">
|
|
875
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
876
|
+
aria-hidden="true"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
|
|
877
|
+
Exit validator
|
|
878
|
+
</button>
|
|
879
|
+
</div>
|
|
880
|
+
</div>
|
|
881
|
+
</div>
|
|
882
|
+
|
|
883
|
+
<!-- ---------- MONITOR MODAL (manage: deploy the monitoring dashboard) ---------- -->
|
|
884
|
+
<div class="mc-modal" id="monitor-modal" hidden role="dialog" aria-modal="true" aria-labelledby="monitor-title">
|
|
885
|
+
<div class="mc-modal__body">
|
|
886
|
+
<h2 class="mc-modal__title" id="monitor-title">Deploy monitor</h2>
|
|
887
|
+
<p class="mc-modal__text">
|
|
888
|
+
Publishes nginx + <span class="v2-mono">octra-dashboard</span> on
|
|
889
|
+
<span class="v2-mono" id="monitor-node">-</span> as a <strong>read-only</strong>
|
|
890
|
+
monitor: graphs, logs, wallet and consensus. The manage actions stay in this tab -
|
|
891
|
+
the public dashboard carries no button and no token.
|
|
892
|
+
</p>
|
|
893
|
+
<label class="mc-field">
|
|
894
|
+
<span class="mc-field__label">Domain name</span>
|
|
895
|
+
<input class="v2-input v2-mono" id="monitor-domain" type="text" placeholder="node-abcde.example.com"
|
|
896
|
+
autocomplete="off" spellcheck="false" />
|
|
897
|
+
</label>
|
|
898
|
+
|
|
899
|
+
<fieldset class="mc-ssl">
|
|
900
|
+
<legend class="mc-field__label">TLS certificate</legend>
|
|
901
|
+
<label class="mc-ssl__opt">
|
|
902
|
+
<input type="radio" name="monitor-ssl" id="monitor-ssl-cloudflare" value="cloudflare" checked />
|
|
903
|
+
<span>
|
|
904
|
+
<strong>Cloudflare origin certificate</strong>
|
|
905
|
+
<em>upload fullchain.pem + privkey.pem from a folder on this machine</em>
|
|
906
|
+
</span>
|
|
907
|
+
</label>
|
|
908
|
+
<div class="mc-ssl__body" id="monitor-cf-row">
|
|
909
|
+
<div class="mc-key__row">
|
|
910
|
+
<input class="v2-input v2-mono" id="monitor-certdir" type="text"
|
|
911
|
+
placeholder="C:\certs\onode" autocomplete="off" spellcheck="false"
|
|
912
|
+
aria-label="Folder with fullchain.pem and privkey.pem" />
|
|
913
|
+
<button type="button" class="v2-btn v2-btn--ghost mc-key__pick" id="monitor-certdir-pick"
|
|
914
|
+
title="Open the folder picker and choose the folder with the two PEM files">
|
|
915
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
916
|
+
aria-hidden="true"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>
|
|
917
|
+
Choose folder
|
|
918
|
+
</button>
|
|
919
|
+
</div>
|
|
920
|
+
<span class="v2-t-xs v2-mute" id="monitor-certdir-note">the folder must contain fullchain.pem and privkey.pem</span>
|
|
921
|
+
</div>
|
|
922
|
+
<label class="mc-ssl__opt">
|
|
923
|
+
<input type="radio" name="monitor-ssl" id="monitor-ssl-certbot" value="certbot" />
|
|
924
|
+
<span>
|
|
925
|
+
<strong>Let's Encrypt (certbot)</strong>
|
|
926
|
+
<em>issued on the server - DNS must already point at the node and port 80 must be open</em>
|
|
927
|
+
</span>
|
|
928
|
+
</label>
|
|
929
|
+
<div class="mc-ssl__body" id="monitor-le-row" hidden>
|
|
930
|
+
<label class="mc-field">
|
|
931
|
+
<span class="mc-field__label">Contact e-mail (optional)</span>
|
|
932
|
+
<input class="v2-input v2-mono" id="monitor-email" type="email" placeholder="you@example.com"
|
|
933
|
+
autocomplete="off" spellcheck="false" />
|
|
934
|
+
</label>
|
|
935
|
+
<span class="v2-t-xs v2-mute">certbot renews the certificate by itself (systemd timer)</span>
|
|
936
|
+
</div>
|
|
937
|
+
</fieldset>
|
|
938
|
+
|
|
939
|
+
<label class="mc-enroll__check" for="monitor-force">
|
|
940
|
+
<input type="checkbox" id="monitor-force" />
|
|
941
|
+
<span>Force redeploy (ignore the checkpoint of an identical earlier deploy)</span>
|
|
942
|
+
</label>
|
|
943
|
+
<p class="mc-modal__text mc-enroll__note" id="monitor-note"></p>
|
|
944
|
+
<div class="mc-modal__actions">
|
|
945
|
+
<button class="v2-btn v2-btn--ghost" id="monitor-cancel">
|
|
946
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
947
|
+
aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
948
|
+
Cancel
|
|
949
|
+
</button>
|
|
950
|
+
<button class="v2-btn v2-btn--brand" id="monitor-ok">
|
|
951
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
952
|
+
aria-hidden="true"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
|
|
953
|
+
Deploy monitor
|
|
954
|
+
</button>
|
|
955
|
+
</div>
|
|
956
|
+
</div>
|
|
957
|
+
</div>
|
|
958
|
+
|
|
959
|
+
<div class="mc-modal" id="enroll-modal" hidden role="dialog" aria-modal="true" aria-labelledby="enroll-title">
|
|
960
|
+
<div class="mc-modal__body">
|
|
961
|
+
<h2 class="mc-modal__title" id="enroll-title">Ready for enrollment</h2>
|
|
962
|
+
<p class="mc-modal__text">
|
|
963
|
+
The node is built, started and verified - its wallet exists and is online as an
|
|
964
|
+
<strong>observer</strong>. Enrolling spends the bond from that wallet, so:
|
|
965
|
+
</p>
|
|
966
|
+
<ol class="mc-guide__list">
|
|
967
|
+
<li>send OCTRA to the wallet address below (at least the amount you enter),</li>
|
|
968
|
+
<li>tick the confirmation when the transfer is done,</li>
|
|
969
|
+
<li>press <strong>Enroll</strong> - the console then runs
|
|
970
|
+
<span class="v2-mono">enroll - promote - verify</span> and keeps watching the chain:
|
|
971
|
+
the set fold admits the validator and it starts voting by itself. You get a popup the
|
|
972
|
+
moment that happens, even if the run has already ended.</li>
|
|
973
|
+
</ol>
|
|
974
|
+
<div class="mc-enroll__addr">
|
|
975
|
+
<span class="mc-field__label">Wallet address (top this up)</span>
|
|
976
|
+
<span class="v2-mono mc-enroll__value" id="enroll-address">reading...</span>
|
|
977
|
+
</div>
|
|
978
|
+
<label class="mc-field">
|
|
979
|
+
<span class="mc-field__label">Bond amount to enroll (OCT)</span>
|
|
980
|
+
<input class="v2-input" id="enroll-bond" type="number" min="1" step="1" value="1" />
|
|
981
|
+
</label>
|
|
982
|
+
<label class="mc-enroll__check" for="enroll-funded">
|
|
983
|
+
<input type="checkbox" id="enroll-funded" />
|
|
984
|
+
<span>I already topped up this wallet - enroll now</span>
|
|
985
|
+
</label>
|
|
986
|
+
<p class="mc-modal__text mc-enroll__note" id="enroll-note"></p>
|
|
987
|
+
<div class="mc-modal__actions">
|
|
988
|
+
<button class="v2-btn v2-btn--ghost" id="enroll-cancel">
|
|
989
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
990
|
+
aria-hidden="true"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
991
|
+
Later
|
|
992
|
+
</button>
|
|
993
|
+
<button class="v2-btn v2-btn--brand" id="enroll-ok" disabled>
|
|
994
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
995
|
+
aria-hidden="true"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><line x1="19" y1="8" x2="19" y2="14"/><line x1="22" y1="11" x2="16" y2="11"/></svg>
|
|
996
|
+
Enroll
|
|
997
|
+
</button>
|
|
998
|
+
</div>
|
|
999
|
+
</div>
|
|
1000
|
+
</div>
|
|
1001
|
+
|
|
1002
|
+
<!-- ---------- ACTIVATION MODAL (the chain admitted the validator) ---------- -->
|
|
1003
|
+
<!-- The console watches the node after enrollment: the set fold admits a new
|
|
1004
|
+
validator and its first duty epoch starts voting. The moment the node reports
|
|
1005
|
+
validator_active = true this opens by itself - even when the run is long over -
|
|
1006
|
+
so nobody has to poll controls/stat.sh by hand (2026-11-05). -->
|
|
1007
|
+
<div class="mc-modal" id="activation-modal" hidden role="dialog" aria-modal="true" aria-labelledby="activation-title">
|
|
1008
|
+
<div class="mc-modal__body">
|
|
1009
|
+
<h2 class="mc-modal__title" id="activation-title">Validator is active</h2>
|
|
1010
|
+
<p class="mc-modal__text">
|
|
1011
|
+
The chain admitted this validator and it is <strong>voting</strong> now.
|
|
1012
|
+
</p>
|
|
1013
|
+
<div class="mc-enroll__addr">
|
|
1014
|
+
<span class="mc-field__label">Node</span>
|
|
1015
|
+
<span class="v2-mono mc-enroll__value" id="activation-node">-</span>
|
|
1016
|
+
</div>
|
|
1017
|
+
<div class="mc-enroll__addr">
|
|
1018
|
+
<span class="mc-field__label">Activation epoch</span>
|
|
1019
|
+
<span class="v2-mono mc-enroll__value" id="activation-epoch">-</span>
|
|
1020
|
+
</div>
|
|
1021
|
+
<p class="mc-modal__text mc-enroll__note" id="activation-note"></p>
|
|
1022
|
+
<div class="mc-modal__actions">
|
|
1023
|
+
<button class="v2-btn v2-btn--brand" id="activation-ok">
|
|
1024
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
1025
|
+
aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
1026
|
+
Close
|
|
1027
|
+
</button>
|
|
1028
|
+
</div>
|
|
1029
|
+
</div>
|
|
1030
|
+
</div>
|
|
1031
|
+
|
|
1032
|
+
<!-- ---------- EXIT MODAL (the exit is on chain: this is when the money is back) ---------- -->
|
|
1033
|
+
<!-- An exit is a chain deadline, not a finished job: the set releases the validator
|
|
1034
|
+
at a fold and the bond unlocks at `withdraw_epoch` - weeks later on this
|
|
1035
|
+
network. The console reports both epochs and the distance to them, keeps
|
|
1036
|
+
following the unbonding in the background (the host retries the withdrawal by
|
|
1037
|
+
itself) and opens this popup again the moment validator_bond reaches 0. -->
|
|
1038
|
+
<div class="mc-modal" id="exit-state-modal" hidden role="dialog" aria-modal="true" aria-labelledby="exit-state-title">
|
|
1039
|
+
<div class="mc-modal__body">
|
|
1040
|
+
<h2 class="mc-modal__title" id="exit-state-title">Exit accepted</h2>
|
|
1041
|
+
<p class="mc-modal__text" id="exit-state-text">
|
|
1042
|
+
The validator left the set. The stake unlocks when the chain reaches the epoch below.
|
|
1043
|
+
</p>
|
|
1044
|
+
<div class="mc-enroll__addr">
|
|
1045
|
+
<span class="mc-field__label">Node</span>
|
|
1046
|
+
<span class="v2-mono mc-enroll__value" id="exit-state-node">-</span>
|
|
1047
|
+
</div>
|
|
1048
|
+
<div class="mc-enroll__addr">
|
|
1049
|
+
<span class="mc-field__label">Exit epoch</span>
|
|
1050
|
+
<span class="v2-mono mc-enroll__value" id="exit-state-epoch">-</span>
|
|
1051
|
+
</div>
|
|
1052
|
+
<div class="mc-enroll__addr">
|
|
1053
|
+
<span class="mc-field__label">Stake unlocks at epoch</span>
|
|
1054
|
+
<span class="v2-mono mc-enroll__value" id="exit-state-unlock">-</span>
|
|
1055
|
+
</div>
|
|
1056
|
+
<div class="mc-enroll__addr">
|
|
1057
|
+
<span class="mc-field__label">Epochs left</span>
|
|
1058
|
+
<span class="v2-mono mc-enroll__value" id="exit-state-remaining">-</span>
|
|
1059
|
+
</div>
|
|
1060
|
+
<div class="mc-enroll__addr">
|
|
1061
|
+
<span class="mc-field__label">Estimated wait</span>
|
|
1062
|
+
<span class="v2-mono mc-enroll__value" id="exit-state-eta">-</span>
|
|
1063
|
+
</div>
|
|
1064
|
+
<p class="mc-modal__text mc-enroll__note" id="exit-state-note"></p>
|
|
1065
|
+
<div class="mc-modal__actions">
|
|
1066
|
+
<button class="v2-btn v2-btn--brand" id="exit-state-ok">
|
|
1067
|
+
<svg class="v2-icon v2-icon--14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
1068
|
+
aria-hidden="true"><polyline points="20 6 9 17 4 12"/></svg>
|
|
1069
|
+
Close
|
|
1070
|
+
</button>
|
|
1071
|
+
</div>
|
|
1072
|
+
</div>
|
|
1073
|
+
</div>
|
|
1074
|
+
|
|
1075
|
+
<script src="assets/v2.2/js/synteq-ui-v2.js"></script>
|
|
1076
|
+
<script src="app.js?v=3.0.0"></script>
|
|
1077
|
+
</body>
|
|
1078
|
+
</html>
|
|
1079
|
+
|
|
1080
|
+
|