@clawlabz/clawnetwork 0.1.1 → 0.1.2
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/index.ts +219 -97
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -807,24 +807,28 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
807
807
|
<meta charset="UTF-8">
|
|
808
808
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
809
809
|
<title>ClawNetwork Node Dashboard</title>
|
|
810
|
-
<link rel="icon" href="https://
|
|
810
|
+
<link rel="icon" href="https://explorer.clawlabz.xyz/favicon.png">
|
|
811
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
812
|
+
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
811
813
|
<style>
|
|
812
814
|
:root {
|
|
813
|
-
--bg: #
|
|
814
|
-
--bg-panel: #
|
|
815
|
-
--border: #
|
|
816
|
-
--accent: #
|
|
817
|
-
--accent-dim: rgba(
|
|
818
|
-
--
|
|
819
|
-
--
|
|
820
|
-
--purple:
|
|
821
|
-
--
|
|
822
|
-
--
|
|
823
|
-
--
|
|
824
|
-
--
|
|
825
|
-
--
|
|
815
|
+
--bg: #0a0705;
|
|
816
|
+
--bg-panel: #140e0a;
|
|
817
|
+
--border: #2a1c14;
|
|
818
|
+
--accent: #F96706;
|
|
819
|
+
--accent-dim: rgba(249, 103, 6, 0.15);
|
|
820
|
+
--accent-light: #FF8C3A;
|
|
821
|
+
--purple: #a855f7;
|
|
822
|
+
--purple-dim: rgba(168, 85, 247, 0.15);
|
|
823
|
+
--green: #22c55e;
|
|
824
|
+
--green-dim: rgba(34, 197, 94, 0.15);
|
|
825
|
+
--text: #fffaf5;
|
|
826
|
+
--text-dim: #8892a0;
|
|
827
|
+
--danger: #ef4444;
|
|
828
|
+
--font: 'Space Grotesk', system-ui, -apple-system, sans-serif;
|
|
829
|
+
--font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
|
|
826
830
|
--radius: 10px;
|
|
827
|
-
--shadow: 0 4px 24px rgba(0, 0, 0, 0.
|
|
831
|
+
--shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
|
|
828
832
|
}
|
|
829
833
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
830
834
|
body { background: var(--bg); color: var(--text); font-family: var(--font); line-height: 1.6; min-height: 100vh; }
|
|
@@ -834,16 +838,17 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
834
838
|
.header { background: var(--bg-panel); border-bottom: 1px solid var(--border); padding: 16px 0; position: sticky; top: 0; z-index: 100; }
|
|
835
839
|
.header .container { display: flex; align-items: center; justify-content: space-between; }
|
|
836
840
|
.logo { font-size: 22px; font-weight: 800; letter-spacing: -0.5px; }
|
|
837
|
-
.logo-claw { color:
|
|
838
|
-
.logo-net { color: var(--
|
|
841
|
+
.logo-claw { color: #ffffff; }
|
|
842
|
+
.logo-net { color: var(--accent); }
|
|
839
843
|
.header-badge { font-size: 11px; background: var(--accent-dim); color: var(--accent); padding: 2px 8px; border-radius: 4px; }
|
|
840
844
|
|
|
841
|
-
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
845
|
+
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
|
|
842
846
|
.stat-card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
|
|
843
847
|
.stat-label { font-size: 12px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; }
|
|
844
848
|
.stat-value { font-size: 28px; font-weight: 700; font-family: var(--font-mono); margin-top: 4px; }
|
|
845
849
|
.stat-value.green { color: var(--green); }
|
|
846
850
|
.stat-value.accent { color: var(--accent); }
|
|
851
|
+
.stat-value.purple { color: var(--purple); }
|
|
847
852
|
.stat-value.danger { color: var(--danger); }
|
|
848
853
|
|
|
849
854
|
.panel { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; margin: 16px 0; }
|
|
@@ -858,13 +863,23 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
858
863
|
.status-dot.offline { background: var(--danger); }
|
|
859
864
|
.status-dot.syncing { background: #ffaa00; animation: pulse 1.5s infinite; }
|
|
860
865
|
|
|
861
|
-
.btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg-panel); color: var(--text); font-size: 13px; cursor: pointer; transition: 0.2s; }
|
|
866
|
+
.btn { display: inline-flex; align-items: center; gap: 6px; padding: 8px 16px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg-panel); color: var(--text); font-size: 13px; cursor: pointer; transition: 0.2s; font-family: var(--font); }
|
|
862
867
|
.btn:hover { border-color: var(--accent); color: var(--accent); }
|
|
863
868
|
.btn.danger:hover { border-color: var(--danger); color: var(--danger); }
|
|
864
869
|
.btn.primary { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
|
|
865
|
-
.
|
|
870
|
+
.node-controls { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding-top: 16px; margin-top: 16px; border-top: 1px solid var(--border); }
|
|
871
|
+
.node-controls .spacer { flex: 1; }
|
|
866
872
|
|
|
867
|
-
.
|
|
873
|
+
.wallet-hero { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; flex-wrap: wrap; }
|
|
874
|
+
.wallet-balance { font-size: 36px; font-weight: 800; font-family: var(--font-mono); color: var(--accent); letter-spacing: -1px; line-height: 1; }
|
|
875
|
+
.wallet-balance-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; }
|
|
876
|
+
.wallet-addr-wrap { flex: 1; min-width: 0; }
|
|
877
|
+
.wallet-addr-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; }
|
|
878
|
+
.wallet-addr { font-family: var(--font-mono); font-size: 12px; background: var(--bg); padding: 8px 12px; border-radius: 6px; border: 1px solid var(--border); word-break: break-all; display: flex; align-items: center; gap: 8px; }
|
|
879
|
+
.copy-btn { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 12px; padding: 2px 8px; border-radius: 4px; border: 1px solid var(--accent); white-space: nowrap; font-family: var(--font); transition: 0.2s; }
|
|
880
|
+
.copy-btn:hover { background: var(--accent-dim); }
|
|
881
|
+
|
|
882
|
+
.logs-box { background: #060402; border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; font-family: var(--font-mono); font-size: 12px; max-height: 300px; overflow-y: auto; white-space: pre-wrap; color: var(--text-dim); line-height: 1.8; }
|
|
868
883
|
|
|
869
884
|
.wallet-addr { font-family: var(--font-mono); font-size: 13px; background: var(--bg); padding: 8px 12px; border-radius: 6px; border: 1px solid var(--border); word-break: break-all; display: flex; align-items: center; gap: 8px; }
|
|
870
885
|
.copy-btn { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 14px; padding: 2px 6px; }
|
|
@@ -873,7 +888,7 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
873
888
|
.toast { position: fixed; bottom: 24px; right: 24px; background: var(--bg-panel); border: 1px solid var(--accent); color: var(--accent); padding: 12px 20px; border-radius: 8px; font-size: 13px; opacity: 0; transition: 0.3s; z-index: 1000; }
|
|
874
889
|
.toast.show { opacity: 1; }
|
|
875
890
|
|
|
876
|
-
.quick-actions { display: grid; grid-template-columns: repeat(
|
|
891
|
+
.quick-actions { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 16px 0 0; }
|
|
877
892
|
.quick-action { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; cursor: pointer; transition: 0.2s; display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); }
|
|
878
893
|
.quick-action:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-1px); }
|
|
879
894
|
.quick-action .qa-icon { font-size: 18px; width: 28px; text-align: center; }
|
|
@@ -890,77 +905,81 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
890
905
|
.modal-actions { display: flex; gap: 8px; margin-top: 16px; justify-content: flex-end; }
|
|
891
906
|
.modal-close { background: none; border: 1px solid var(--border); color: var(--text-dim); padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 13px; }
|
|
892
907
|
.modal-close:hover { border-color: var(--text); color: var(--text); }
|
|
908
|
+
.modal-input { width: 100%; box-sizing: border-box; background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 10px 12px; font-size: 14px; color: var(--text); font-family: var(--font-mono); outline: none; margin-top: 4px; }
|
|
909
|
+
.modal-input:focus { border-color: var(--accent); }
|
|
910
|
+
.modal-hint { font-size: 12px; color: var(--text-dim); margin-top: 6px; line-height: 1.5; }
|
|
893
911
|
</style>
|
|
894
912
|
</head>
|
|
895
913
|
<body>
|
|
896
914
|
<header class="header">
|
|
897
915
|
<div class="container">
|
|
898
916
|
<div style="display:flex;align-items:center;gap:14px">
|
|
899
|
-
<div class="logo"><span class="logo-claw">Claw</span><span class="logo-net">Network</span></div>
|
|
917
|
+
<div class="logo"><img src="https://explorer.clawlabz.xyz/favicon.png" style="width:28px;height:28px;border-radius:6px;vertical-align:middle;margin-right:8px"><span class="logo-claw">Claw</span><span class="logo-net">Network</span></div>
|
|
900
918
|
<span class="header-badge">Node Dashboard</span>
|
|
901
919
|
</div>
|
|
902
920
|
<span id="lastUpdate" style="font-size:12px;color:var(--text-dim)"></span>
|
|
903
921
|
</div>
|
|
904
922
|
</header>
|
|
905
923
|
|
|
906
|
-
<main class="container" style="padding-top:
|
|
907
|
-
<div class="stats-grid">
|
|
908
|
-
<div class="stat-card">
|
|
909
|
-
<div class="stat-label">Status</div>
|
|
910
|
-
<div class="stat-value" id="statusValue"><span class="status-dot offline"></span>Offline</div>
|
|
911
|
-
</div>
|
|
912
|
-
<div class="stat-card">
|
|
913
|
-
<div class="stat-label">Block Height</div>
|
|
914
|
-
<div class="stat-value accent" id="heightValue">—</div>
|
|
915
|
-
</div>
|
|
916
|
-
<div class="stat-card">
|
|
917
|
-
<div class="stat-label">Peers</div>
|
|
918
|
-
<div class="stat-value" id="peersValue">—</div>
|
|
919
|
-
</div>
|
|
920
|
-
<div class="stat-card">
|
|
921
|
-
<div class="stat-label">Uptime</div>
|
|
922
|
-
<div class="stat-value" id="uptimeValue">—</div>
|
|
923
|
-
</div>
|
|
924
|
-
</div>
|
|
925
|
-
|
|
926
|
-
<div class="btn-group">
|
|
927
|
-
<button class="btn primary" onclick="doAction('start')">Start Node</button>
|
|
928
|
-
<button class="btn danger" onclick="doAction('stop')">Stop Node</button>
|
|
929
|
-
<button class="btn" onclick="doAction('faucet')">Faucet (testnet)</button>
|
|
930
|
-
<button class="btn" onclick="refreshLogs()">Refresh Logs</button>
|
|
931
|
-
</div>
|
|
924
|
+
<main class="container" style="padding-top:16px;padding-bottom:40px">
|
|
932
925
|
|
|
933
926
|
<div class="panel">
|
|
934
|
-
<div class="panel-title">
|
|
935
|
-
<div
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
<span class="
|
|
939
|
-
<div><div class="qa-label">Copy Address</div><div class="qa-hint">Share to receive CLAW</div></div>
|
|
940
|
-
</div>
|
|
941
|
-
<div class="quick-action" onclick="importToExtension()" id="qaImportExt" style="display:none">
|
|
942
|
-
<span class="qa-icon">🔗</span>
|
|
943
|
-
<div><div class="qa-label">Import to Extension</div><div class="qa-hint">One-click import to browser wallet</div></div>
|
|
927
|
+
<div class="panel-title">Node</div>
|
|
928
|
+
<div class="stats-grid" style="margin:0 0 4px">
|
|
929
|
+
<div class="stat-card">
|
|
930
|
+
<div class="stat-label">Status</div>
|
|
931
|
+
<div class="stat-value" id="statusValue"><span class="status-dot offline"></span>Offline</div>
|
|
944
932
|
</div>
|
|
945
|
-
<div class="
|
|
946
|
-
<
|
|
947
|
-
<div
|
|
933
|
+
<div class="stat-card">
|
|
934
|
+
<div class="stat-label">Block Height</div>
|
|
935
|
+
<div class="stat-value accent" id="heightValue">—</div>
|
|
948
936
|
</div>
|
|
949
|
-
<div class="
|
|
950
|
-
<
|
|
951
|
-
<div
|
|
937
|
+
<div class="stat-card">
|
|
938
|
+
<div class="stat-label">Peers</div>
|
|
939
|
+
<div class="stat-value" id="peersValue">—</div>
|
|
952
940
|
</div>
|
|
953
|
-
<div class="
|
|
954
|
-
<
|
|
955
|
-
<div
|
|
941
|
+
<div class="stat-card">
|
|
942
|
+
<div class="stat-label">Uptime</div>
|
|
943
|
+
<div class="stat-value" id="uptimeValue">—</div>
|
|
956
944
|
</div>
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
945
|
+
</div>
|
|
946
|
+
<div class="node-controls">
|
|
947
|
+
<button class="btn primary" onclick="doAction('start')">▶ Start Node</button>
|
|
948
|
+
<button class="btn danger" onclick="doAction('stop')">■ Stop Node</button>
|
|
949
|
+
</div>
|
|
950
|
+
</div>
|
|
951
|
+
|
|
952
|
+
<div class="panel" id="walletPanel">
|
|
953
|
+
<div class="panel-title">Wallet</div>
|
|
954
|
+
<div id="walletEmpty" style="color:var(--text-dim);font-size:13px">No wallet yet — start the node to generate one</div>
|
|
955
|
+
<div id="walletLoaded" style="display:none">
|
|
956
|
+
<div class="wallet-hero">
|
|
957
|
+
<div>
|
|
958
|
+
<div class="wallet-balance-label">Balance</div>
|
|
959
|
+
<div class="wallet-balance" id="walletBalance">—</div>
|
|
960
|
+
</div>
|
|
961
|
+
<div class="wallet-addr-wrap">
|
|
962
|
+
<div class="wallet-addr-label">Address</div>
|
|
963
|
+
<div class="wallet-addr"><span id="walletAddrText" style="flex:1;min-width:0;word-break:break-all"></span><button class="copy-btn" onclick="copyText(cachedAddress)">Copy</button></div>
|
|
964
|
+
</div>
|
|
960
965
|
</div>
|
|
961
|
-
<div class="quick-
|
|
962
|
-
<
|
|
963
|
-
|
|
966
|
+
<div class="quick-actions" id="walletActions">
|
|
967
|
+
<div class="quick-action" onclick="importToExtension()" id="qaImportExt">
|
|
968
|
+
<span class="qa-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg></span>
|
|
969
|
+
<div><div class="qa-label">Import to Extension</div><div class="qa-hint" id="qaImportHint">One-click import to browser wallet</div></div>
|
|
970
|
+
</div>
|
|
971
|
+
<div class="quick-action warn" onclick="showExportKey()">
|
|
972
|
+
<span class="qa-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/></svg></span>
|
|
973
|
+
<div><div class="qa-label">Export Private Key</div><div class="qa-hint">Manual copy for backup</div></div>
|
|
974
|
+
</div>
|
|
975
|
+
<div class="quick-action" onclick="openExplorer()">
|
|
976
|
+
<span class="qa-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></span>
|
|
977
|
+
<div><div class="qa-label">View on Explorer</div><div class="qa-hint">Transaction history</div></div>
|
|
978
|
+
</div>
|
|
979
|
+
<div class="quick-action" id="qaRegister" onclick="handleRegisterAgent()">
|
|
980
|
+
<span class="qa-icon"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><path d="M15 2v2M9 2v2M15 20v2M9 20v2M2 15h2M2 9h2M20 15h2M20 9h2"/></svg></span>
|
|
981
|
+
<div><div class="qa-label" id="qaRegisterLabel">Register Agent</div><div class="qa-hint" id="qaRegisterHint">On-chain identity</div></div>
|
|
982
|
+
</div>
|
|
964
983
|
</div>
|
|
965
984
|
</div>
|
|
966
985
|
</div>
|
|
@@ -971,13 +990,57 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
971
990
|
</div>
|
|
972
991
|
|
|
973
992
|
<div class="panel">
|
|
974
|
-
<div
|
|
993
|
+
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
|
|
994
|
+
<div class="panel-title" style="margin-bottom:0">Recent Logs</div>
|
|
995
|
+
<button class="btn" style="font-size:12px;padding:5px 12px" onclick="refreshLogs()">↻ Refresh</button>
|
|
996
|
+
</div>
|
|
975
997
|
<div class="logs-box" id="logsBox">Loading...</div>
|
|
976
998
|
</div>
|
|
977
999
|
</main>
|
|
978
1000
|
|
|
1001
|
+
<footer style="border-top:1px solid var(--border);padding:24px 0;margin-top:16px">
|
|
1002
|
+
<div class="container" style="display:flex;flex-wrap:wrap;gap:20px;align-items:center;justify-content:space-between">
|
|
1003
|
+
<div style="display:flex;align-items:center;gap:8px">
|
|
1004
|
+
<img src="https://explorer.clawlabz.xyz/favicon.png" style="width:18px;height:18px;border-radius:4px;opacity:0.7">
|
|
1005
|
+
<span style="font-size:12px;color:var(--text-dim)">© 2026 ClawLabz</span>
|
|
1006
|
+
</div>
|
|
1007
|
+
<div style="display:flex;gap:20px;flex-wrap:wrap">
|
|
1008
|
+
<a href="https://chain.clawlabz.xyz" target="_blank" style="font-size:12px;color:var(--text-dim);text-decoration:none;transition:0.2s" onmouseover="this.style.color='var(--accent)'" onmouseout="this.style.color='var(--text-dim)'">Chain</a>
|
|
1009
|
+
<a href="https://explorer.clawlabz.xyz" target="_blank" style="font-size:12px;color:var(--text-dim);text-decoration:none;transition:0.2s" onmouseover="this.style.color='var(--accent)'" onmouseout="this.style.color='var(--text-dim)'">Explorer</a>
|
|
1010
|
+
<a href="https://chrome.google.com/webstore/search/ClawNetwork" target="_blank" style="font-size:12px;color:var(--text-dim);text-decoration:none;transition:0.2s" onmouseover="this.style.color='var(--accent)'" onmouseout="this.style.color='var(--text-dim)'">Wallet Extension</a>
|
|
1011
|
+
</div>
|
|
1012
|
+
</div>
|
|
1013
|
+
</footer>
|
|
1014
|
+
|
|
979
1015
|
<div class="toast" id="toast"></div>
|
|
980
1016
|
|
|
1017
|
+
<div class="modal-overlay" id="registerModal" onclick="if(event.target===this)closeRegisterModal()">
|
|
1018
|
+
<div class="modal">
|
|
1019
|
+
<div class="modal-title">Register Agent</div>
|
|
1020
|
+
<p style="font-size:13px;color:var(--text-dim);margin:0 0 12px">Register your wallet as an AI Agent on ClawNetwork. The name is your on-chain identity — it does not need to be unique globally (the wallet address is what's unique). Registration is gas-free on mainnet.</p>
|
|
1021
|
+
<input id="registerNameInput" class="modal-input" type="text" placeholder="my-agent-name" maxlength="32" onkeydown="if(event.key==='Enter')submitRegisterAgent()" />
|
|
1022
|
+
<div class="modal-hint">Allowed: letters, numbers, hyphens, underscores. Max 32 chars.</div>
|
|
1023
|
+
<div class="modal-actions">
|
|
1024
|
+
<button class="modal-close" onclick="closeRegisterModal()">Cancel</button>
|
|
1025
|
+
<button class="btn primary" onclick="submitRegisterAgent()">Register</button>
|
|
1026
|
+
</div>
|
|
1027
|
+
</div>
|
|
1028
|
+
</div>
|
|
1029
|
+
|
|
1030
|
+
<div class="modal-overlay" id="installModal" onclick="if(event.target===this)closeInstallModal()">
|
|
1031
|
+
<div class="modal">
|
|
1032
|
+
<div class="modal-title">Install ClawNetwork Wallet</div>
|
|
1033
|
+
<p style="font-size:13px;color:var(--text-dim);margin:0 0 16px;line-height:1.6">The ClawNetwork browser extension is not detected. Install it first, then click Import to Extension to import your node wallet.</p>
|
|
1034
|
+
<div style="display:flex;gap:10px;flex-direction:column">
|
|
1035
|
+
<a href="https://chrome.google.com/webstore/search/ClawNetwork" target="_blank" class="btn primary" style="text-decoration:none;justify-content:center;padding:10px 16px">Open Chrome Web Store</a>
|
|
1036
|
+
<a href="https://chain.clawlabz.xyz" target="_blank" style="font-size:12px;color:var(--text-dim);text-decoration:none;text-align:center" onmouseover="this.style.color='var(--accent)'" onmouseout="this.style.color='var(--text-dim)'">Learn more at chain.clawlabz.xyz →</a>
|
|
1037
|
+
</div>
|
|
1038
|
+
<div class="modal-actions" style="margin-top:16px">
|
|
1039
|
+
<button class="modal-close" onclick="closeInstallModal()">Close</button>
|
|
1040
|
+
</div>
|
|
1041
|
+
</div>
|
|
1042
|
+
</div>
|
|
1043
|
+
|
|
981
1044
|
<div class="modal-overlay" id="exportModal" onclick="if(event.target===this)closeExportModal()">
|
|
982
1045
|
<div class="modal">
|
|
983
1046
|
<div class="modal-title">Export Private Key</div>
|
|
@@ -1006,6 +1069,7 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1006
1069
|
let cachedAddress = '';
|
|
1007
1070
|
let cachedNetwork = '';
|
|
1008
1071
|
let cachedKey = '';
|
|
1072
|
+
let cachedAgentName = ''; // '' = not registered, string = registered name
|
|
1009
1073
|
|
|
1010
1074
|
function copyText(text) {
|
|
1011
1075
|
navigator.clipboard.writeText(text).then(() => toast('Copied!')).catch(() => {});
|
|
@@ -1050,16 +1114,13 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1050
1114
|
window.open('https://chain.clawlabz.xyz/faucet', '_blank');
|
|
1051
1115
|
}
|
|
1052
1116
|
|
|
1053
|
-
// Detect ClawNetwork extension provider
|
|
1117
|
+
// Detect ClawNetwork extension provider (for enhanced flow when available)
|
|
1054
1118
|
let hasExtension = false;
|
|
1055
1119
|
function checkExtension() {
|
|
1056
1120
|
if (window.clawNetwork && window.clawNetwork.isClawNetwork) {
|
|
1057
1121
|
hasExtension = true;
|
|
1058
|
-
const el = document.getElementById('qaImportExt');
|
|
1059
|
-
if (el) el.style.display = '';
|
|
1060
1122
|
}
|
|
1061
1123
|
}
|
|
1062
|
-
// Check immediately and after a short delay (extension injects at document_start)
|
|
1063
1124
|
checkExtension();
|
|
1064
1125
|
setTimeout(checkExtension, 1000);
|
|
1065
1126
|
setTimeout(checkExtension, 3000);
|
|
@@ -1083,7 +1144,10 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1083
1144
|
} catch (e) { /* fall through to provider method */ }
|
|
1084
1145
|
}
|
|
1085
1146
|
// Fallback: use window.clawNetwork provider
|
|
1086
|
-
if (!window.clawNetwork) {
|
|
1147
|
+
if (!window.clawNetwork) {
|
|
1148
|
+
document.getElementById('installModal').classList.add('open');
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1087
1151
|
toast('Connecting to extension...');
|
|
1088
1152
|
try {
|
|
1089
1153
|
await window.clawNetwork.request({ method: 'claw_requestAccounts' });
|
|
@@ -1145,21 +1209,45 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1145
1209
|
setTimeout(fetchStatus, 3000);
|
|
1146
1210
|
}
|
|
1147
1211
|
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1212
|
+
function closeInstallModal() {
|
|
1213
|
+
document.getElementById('installModal').classList.remove('open');
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
function handleRegisterAgent() {
|
|
1217
|
+
if (cachedAgentName) {
|
|
1218
|
+
toast('Already registered as "' + cachedAgentName + '"');
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
openRegisterModal();
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
function openRegisterModal() {
|
|
1225
|
+
document.getElementById('registerNameInput').value = '';
|
|
1226
|
+
document.getElementById('registerModal').classList.add('open');
|
|
1227
|
+
setTimeout(() => document.getElementById('registerNameInput').focus(), 50);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
function closeRegisterModal() {
|
|
1231
|
+
document.getElementById('registerModal').classList.remove('open');
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
async function submitRegisterAgent() {
|
|
1235
|
+
const raw = document.getElementById('registerNameInput').value.trim();
|
|
1236
|
+
const name = raw.replace(/[^a-zA-Z0-9_-]/g, '').slice(0, 32);
|
|
1237
|
+
if (!name) { toast('Please enter an agent name'); return; }
|
|
1238
|
+
closeRegisterModal();
|
|
1151
1239
|
if (window.clawNetwork) {
|
|
1152
1240
|
try {
|
|
1153
1241
|
toast('Approve registration in extension...');
|
|
1154
1242
|
await window.clawNetwork.request({ method: 'claw_requestAccounts' });
|
|
1155
1243
|
await window.clawNetwork.request({ method: 'claw_registerAgent', params: [name] });
|
|
1156
|
-
toast('Agent registered!');
|
|
1244
|
+
toast('Agent "' + name + '" registered!');
|
|
1157
1245
|
} catch (e) { toast('Registration failed: ' + (e.message || e)); }
|
|
1158
1246
|
} else {
|
|
1159
1247
|
try {
|
|
1160
1248
|
const res = await fetch(API + '/api/agent/register', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({name}) });
|
|
1161
1249
|
const data = await res.json();
|
|
1162
|
-
toast(data.ok ? 'Agent registered!' : 'Error: ' + data.error);
|
|
1250
|
+
toast(data.ok ? 'Agent "' + name + '" registered!' : 'Error: ' + data.error);
|
|
1163
1251
|
} catch (e) { toast('Registration failed: ' + e.message); }
|
|
1164
1252
|
}
|
|
1165
1253
|
}
|
|
@@ -1170,7 +1258,10 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1170
1258
|
const data = await res.json();
|
|
1171
1259
|
renderStatus(data);
|
|
1172
1260
|
document.getElementById('lastUpdate').textContent = 'Updated: ' + new Date().toLocaleTimeString();
|
|
1173
|
-
} catch (e) {
|
|
1261
|
+
} catch (e) {
|
|
1262
|
+
console.error(e);
|
|
1263
|
+
renderStatus({ running: false, blockHeight: null, peerCount: null, walletAddress: '', network: 'mainnet', syncMode: 'light', rpcUrl: 'http://localhost:19877', pluginVersion: '0.1.1', restartCount: 0, dataDir: '', balance: '', syncing: false, uptimeFormatted: '—', pid: null });
|
|
1264
|
+
}
|
|
1174
1265
|
}
|
|
1175
1266
|
|
|
1176
1267
|
function renderStatus(s) {
|
|
@@ -1192,12 +1283,34 @@ function buildUiHtml(cfg: PluginConfig): string {
|
|
|
1192
1283
|
// Wallet
|
|
1193
1284
|
cachedAddress = s.walletAddress || '';
|
|
1194
1285
|
cachedNetwork = s.network || '';
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1286
|
+
if (s.walletAddress) {
|
|
1287
|
+
document.getElementById('walletEmpty').style.display = 'none';
|
|
1288
|
+
document.getElementById('walletLoaded').style.display = '';
|
|
1289
|
+
document.getElementById('walletAddrText').textContent = s.walletAddress;
|
|
1290
|
+
document.getElementById('walletBalance').textContent = s.balance || '—';
|
|
1291
|
+
// Agent status
|
|
1292
|
+
cachedAgentName = s.agentName || '';
|
|
1293
|
+
const regCard = document.getElementById('qaRegister');
|
|
1294
|
+
const regLabel = document.getElementById('qaRegisterLabel');
|
|
1295
|
+
const regHint = document.getElementById('qaRegisterHint');
|
|
1296
|
+
if (cachedAgentName) {
|
|
1297
|
+
regLabel.textContent = 'Agent Registered';
|
|
1298
|
+
regHint.innerHTML = '<span style="color:var(--green)">✓ ' + cachedAgentName + '</span>';
|
|
1299
|
+
regCard.style.borderColor = 'var(--green)';
|
|
1300
|
+
regCard.style.opacity = '0.85';
|
|
1301
|
+
} else {
|
|
1302
|
+
regLabel.textContent = 'Register Agent';
|
|
1303
|
+
regHint.textContent = 'On-chain identity';
|
|
1304
|
+
regCard.style.borderColor = '';
|
|
1305
|
+
regCard.style.opacity = '';
|
|
1306
|
+
}
|
|
1307
|
+
// Extension detection hint
|
|
1308
|
+
const hasExt = !!(window.clawNetwork && window.clawNetwork.isClawNetwork);
|
|
1309
|
+
document.getElementById('qaImportHint').textContent = hasExt ? 'Extension detected — click to import' : 'Install wallet extension first';
|
|
1310
|
+
} else {
|
|
1311
|
+
document.getElementById('walletEmpty').style.display = '';
|
|
1312
|
+
document.getElementById('walletLoaded').style.display = 'none';
|
|
1313
|
+
}
|
|
1201
1314
|
|
|
1202
1315
|
// Node info
|
|
1203
1316
|
const rows = [
|
|
@@ -1321,10 +1434,16 @@ async function handle(req, res) {
|
|
|
1321
1434
|
try {
|
|
1322
1435
|
const h = await fetchJson('http://localhost:' + RPC_PORT + '/health');
|
|
1323
1436
|
let balance = '';
|
|
1437
|
+
let walletAddress = '';
|
|
1438
|
+
let agentName = '';
|
|
1324
1439
|
try {
|
|
1325
1440
|
const walletPath = path.join(os.homedir(), '.openclaw/workspace/clawnetwork/wallet.json');
|
|
1326
1441
|
const w = JSON.parse(fs.readFileSync(walletPath, 'utf8'));
|
|
1327
|
-
|
|
1442
|
+
walletAddress = w.address || '';
|
|
1443
|
+
if (w.address) {
|
|
1444
|
+
const b = await rpcCall('claw_getBalance', [w.address]); balance = formatClaw(b);
|
|
1445
|
+
try { const ag = await rpcCall('claw_getAgent', [w.address]); agentName = (ag && ag.name) ? ag.name : ''; } catch {}
|
|
1446
|
+
}
|
|
1328
1447
|
} catch {}
|
|
1329
1448
|
json(200, {
|
|
1330
1449
|
running: h.status === 'ok',
|
|
@@ -1333,14 +1452,17 @@ async function handle(req, res) {
|
|
|
1333
1452
|
network: h.chain_id,
|
|
1334
1453
|
syncMode: 'light',
|
|
1335
1454
|
rpcUrl: 'http://localhost:' + RPC_PORT,
|
|
1336
|
-
walletAddress
|
|
1455
|
+
walletAddress,
|
|
1337
1456
|
binaryVersion: h.version,
|
|
1338
|
-
pluginVersion: '0.1.
|
|
1457
|
+
pluginVersion: '0.1.1',
|
|
1339
1458
|
uptime: h.uptime_secs,
|
|
1340
1459
|
uptimeFormatted: h.uptime_secs < 60 ? h.uptime_secs + 's' : h.uptime_secs < 3600 ? Math.floor(h.uptime_secs/60) + 'm' : Math.floor(h.uptime_secs/3600) + 'h ' + Math.floor((h.uptime_secs%3600)/60) + 'm',
|
|
1341
|
-
restartCount: 0, dataDir: path.join(os.homedir(), '.clawnetwork'), balance, syncing: h.status === 'degraded',
|
|
1460
|
+
restartCount: 0, dataDir: path.join(os.homedir(), '.clawnetwork'), balance, agentName, syncing: h.status === 'degraded',
|
|
1342
1461
|
});
|
|
1343
|
-
} catch {
|
|
1462
|
+
} catch {
|
|
1463
|
+
const walletAddr = (() => { try { return JSON.parse(fs.readFileSync(path.join(os.homedir(), '.openclaw/workspace/clawnetwork/wallet.json'), 'utf8')).address; } catch { return ''; } })();
|
|
1464
|
+
json(200, { running: false, blockHeight: null, peerCount: null, walletAddress: walletAddr, network: 'mainnet', syncMode: 'light', rpcUrl: 'http://localhost:' + RPC_PORT, pluginVersion: '0.1.1', restartCount: 0, dataDir: path.join(os.homedir(), '.clawnetwork'), balance: '', agentName: '', syncing: false, uptimeFormatted: '—', pid: null });
|
|
1465
|
+
}
|
|
1344
1466
|
return;
|
|
1345
1467
|
}
|
|
1346
1468
|
if (p === '/api/logs') {
|