2024-04-29 20:43:18 +03:00
|
|
|
const APP_PATH = '/settings:settings:sys/ask';
|
|
|
|
|
|
|
|
// Fetch initial data and populate the UI
|
|
|
|
function init() {
|
2024-05-09 00:35:38 +03:00
|
|
|
fetch(APP_PATH)
|
|
|
|
.then(response => response.json())
|
2024-04-29 20:43:18 +03:00
|
|
|
.then(data => {
|
2024-05-09 00:35:38 +03:00
|
|
|
console.log(data);
|
|
|
|
populate(data);
|
2024-04-29 20:43:18 +03:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-04-30 21:20:26 +03:00
|
|
|
function api_call(body) {
|
|
|
|
fetch(APP_PATH, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function shutdown() {
|
|
|
|
api_call("Shutdown");
|
2024-06-03 07:33:25 +03:00
|
|
|
setTimeout(() => {
|
|
|
|
window.location.reload();
|
|
|
|
}, 1000);
|
2024-04-30 21:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function populate(data) {
|
|
|
|
populate_node_info(data.identity);
|
|
|
|
populate_net_diagnostics(data.diagnostics);
|
|
|
|
populate_eth_rpc_providers(data.eth_rpc_providers);
|
|
|
|
populate_eth_rpc_settings(data.eth_rpc_access_settings);
|
2024-07-26 19:50:31 +03:00
|
|
|
populate_process_map(data.process_map);
|
2024-04-30 21:20:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function populate_node_info(identity) {
|
|
|
|
document.getElementById('node-name').innerText = identity.name;
|
|
|
|
document.getElementById('net-key').innerText = identity.networking_key;
|
|
|
|
if (identity.ws_routing) {
|
|
|
|
document.getElementById('ip-ports').innerText = identity.ws_routing;
|
|
|
|
} else {
|
|
|
|
document.getElementById('ip-ports').style.display = 'none';
|
|
|
|
}
|
|
|
|
if (identity.routers) {
|
|
|
|
document.getElementById('routers').innerText = identity.routers;
|
|
|
|
} else {
|
|
|
|
document.getElementById('routers').style.display = 'none';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function populate_net_diagnostics(diagnostics) {
|
|
|
|
document.getElementById('diagnostics').innerText = diagnostics;
|
|
|
|
}
|
|
|
|
|
|
|
|
function populate_eth_rpc_providers(providers) {
|
|
|
|
const ul = document.getElementById('providers');
|
|
|
|
ul.innerHTML = '';
|
|
|
|
providers.forEach(provider => {
|
|
|
|
const li = document.createElement('li');
|
2024-05-14 01:20:23 +03:00
|
|
|
li.innerHTML = `${JSON.stringify(provider, undefined, 2)}`;
|
2024-04-30 21:20:26 +03:00
|
|
|
ul.appendChild(li);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function populate_eth_rpc_settings(settings) {
|
|
|
|
if (settings.public) {
|
2024-05-14 01:20:23 +03:00
|
|
|
document.getElementById('public').innerText = 'status: public';
|
2024-04-30 21:20:26 +03:00
|
|
|
document.getElementById('allowed-nodes').style.display = 'none';
|
|
|
|
} else {
|
2024-05-14 01:20:23 +03:00
|
|
|
document.getElementById('public').innerText = 'status: private';
|
2024-04-30 21:20:26 +03:00
|
|
|
const ul = document.getElementById('allowed-nodes');
|
|
|
|
ul.innerHTML = '';
|
|
|
|
if (settings.allow.length === 0) {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
li.innerHTML = `<li>(none)</li>`;
|
|
|
|
ul.appendChild(li);
|
|
|
|
} else {
|
|
|
|
settings.allow.forEach(allowed_node => {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
li.innerHTML = `<li>${allowed_node}</li>`;
|
|
|
|
ul.appendChild(li);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const ul = document.getElementById('denied-nodes');
|
|
|
|
ul.innerHTML = '';
|
|
|
|
if (settings.deny.length === 0) {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
li.innerHTML = `<li>(none)</li>`;
|
|
|
|
ul.appendChild(li);
|
|
|
|
} else {
|
|
|
|
settings.deny.forEach(denied_node => {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
li.innerHTML = `<li>${denied_node}</li>`;
|
|
|
|
ul.appendChild(li);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-26 19:50:31 +03:00
|
|
|
function populate_process_map(process_map) {
|
|
|
|
const ul = document.getElementById('process-map');
|
|
|
|
ul.innerHTML = '';
|
|
|
|
Object.entries(process_map).forEach(([id, process]) => {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
|
|
|
|
const name = document.createElement('p');
|
|
|
|
name.innerHTML = `${id}`;
|
|
|
|
name.innerHTML += `<button class="kill-process" data-id="${id}">kill</button>`;
|
|
|
|
li.appendChild(name);
|
|
|
|
|
|
|
|
const public = document.createElement('p');
|
|
|
|
public.innerHTML = `public: ${process.public}`;
|
|
|
|
li.appendChild(public);
|
|
|
|
|
|
|
|
const on_exit = document.createElement('p');
|
|
|
|
on_exit.innerHTML = `on_exit: ${process.on_exit}`;
|
|
|
|
li.appendChild(on_exit);
|
|
|
|
|
|
|
|
const wit_version = document.createElement('p');
|
|
|
|
if (process.wit_version) {
|
|
|
|
wit_version.innerHTML = `wit_version: ${process.wit_version}`;
|
|
|
|
li.appendChild(wit_version);
|
|
|
|
}
|
|
|
|
|
|
|
|
const wasm_bytes_handle = document.createElement('p');
|
|
|
|
if (process.wasm_bytes_handle) {
|
|
|
|
wasm_bytes_handle.innerHTML = `wasm_bytes_handle: ${process.wasm_bytes_handle}`;
|
|
|
|
li.appendChild(wasm_bytes_handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
const caps = document.createElement('ul');
|
|
|
|
process.capabilities.forEach(cap => {
|
|
|
|
const li = document.createElement('li');
|
|
|
|
li.innerHTML = `${cap.issuer}(${JSON.stringify(JSON.parse(cap.params), null, 2)})`;
|
|
|
|
caps.appendChild(li);
|
|
|
|
});
|
|
|
|
li.appendChild(caps);
|
|
|
|
|
|
|
|
ul.appendChild(li);
|
|
|
|
});
|
|
|
|
document.querySelectorAll('.kill-process').forEach(button => {
|
|
|
|
let id = button.getAttribute('data-id');
|
2024-07-26 19:57:20 +03:00
|
|
|
// apps we don't want user to kill, also runtime modules that cannot be killed
|
|
|
|
const do_not_kill = [
|
|
|
|
'settings:setting:sys',
|
|
|
|
'main:app_store:sys',
|
|
|
|
'net:distro:sys',
|
|
|
|
'kernel:distro:sys',
|
|
|
|
'kv:distro:sys',
|
|
|
|
'sqlite:distro:sys',
|
|
|
|
'eth:distro:sys',
|
|
|
|
'vfs:distro:sys',
|
|
|
|
'state:distro:sys',
|
|
|
|
'kns_indexer:kns_indexer:sys',
|
|
|
|
'http_client:distro:sys',
|
|
|
|
'http_server:distro:sys',
|
|
|
|
'terminal:terminal:sys',
|
|
|
|
'timer:distro:sys',
|
|
|
|
];
|
2024-07-26 19:50:31 +03:00
|
|
|
if (!do_not_kill.includes(id)) {
|
|
|
|
button.addEventListener('click', () => {
|
|
|
|
api_call({ "KillProcess": id });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-04-29 20:43:18 +03:00
|
|
|
// Call init to start the application
|
|
|
|
init();
|
|
|
|
|
2024-04-30 21:20:26 +03:00
|
|
|
// Setup event listeners
|
|
|
|
document.getElementById('shutdown').addEventListener('click', shutdown);
|
|
|
|
|
|
|
|
document.getElementById('get-peer-pki').addEventListener('submit', (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
const data = new FormData(e.target);
|
|
|
|
const body = {
|
|
|
|
"PeerId": data.get('peer'),
|
|
|
|
};
|
|
|
|
fetch(APP_PATH, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
}).then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
if (data === null) {
|
|
|
|
document.getElementById('peer-pki-response').innerText = "no pki data for peer";
|
|
|
|
} else {
|
2024-05-14 02:15:07 +03:00
|
|
|
e.target.reset();
|
2024-05-14 01:20:23 +03:00
|
|
|
document.getElementById('peer-pki-response').innerText = JSON.stringify(data, undefined, 2);
|
2024-04-30 21:20:26 +03:00
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
document.getElementById('ping-peer').addEventListener('submit', (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
const data = new FormData(e.target);
|
|
|
|
const body = {
|
|
|
|
"Hi": {
|
|
|
|
node: data.get('peer'),
|
|
|
|
content: data.get('content'),
|
|
|
|
timeout: Number(data.get('timeout')),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
fetch(APP_PATH, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
}).then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
if (data === null) {
|
2024-05-14 02:15:07 +03:00
|
|
|
e.target.reset();
|
2024-04-30 21:20:26 +03:00
|
|
|
document.getElementById('peer-ping-response').innerText = "ping successful!";
|
|
|
|
} else if (data === "HiTimeout") {
|
|
|
|
document.getElementById('peer-ping-response').innerText = "node timed out";
|
|
|
|
} else if (data === "HiOffline") {
|
|
|
|
document.getElementById('peer-ping-response').innerText = "node is offline";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
2024-05-14 02:15:07 +03:00
|
|
|
document.getElementById('add-eth-provider').addEventListener('submit', (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
const data = new FormData(e.target);
|
|
|
|
const rpc_url = data.get('rpc-url');
|
|
|
|
// validate rpc url
|
|
|
|
if (!rpc_url.startsWith('wss://') && !rpc_url.startsWith('ws://')) {
|
|
|
|
alert('Invalid RPC URL');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const body = {
|
|
|
|
"EthConfig": {
|
|
|
|
"AddProvider": {
|
|
|
|
chain_id: Number(data.get('chain-id')),
|
|
|
|
trusted: false,
|
|
|
|
provider: { "RpcUrl": rpc_url },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
fetch(APP_PATH, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
}).then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
if (data === null) {
|
|
|
|
e.target.reset();
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
alert(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
|
|
|
document.getElementById('remove-eth-provider').addEventListener('submit', (e) => {
|
|
|
|
e.preventDefault();
|
|
|
|
const data = new FormData(e.target);
|
|
|
|
const body = {
|
|
|
|
"EthConfig": {
|
|
|
|
"RemoveProvider": [Number(data.get('chain-id')), data.get('rpc-url')]
|
|
|
|
}
|
|
|
|
};
|
|
|
|
fetch(APP_PATH, {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
}).then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
if (data === null) {
|
|
|
|
e.target.reset();
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
alert(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})
|
|
|
|
|
2024-04-29 20:43:18 +03:00
|
|
|
// Setup WebSocket connection
|
2024-05-09 00:35:38 +03:00
|
|
|
const wsProtocol = location.protocol === 'https:' ? 'wss://' : 'ws://';
|
|
|
|
const ws = new WebSocket(wsProtocol + location.host + "/settings:settings:sys/");
|
2024-04-29 20:43:18 +03:00
|
|
|
ws.onmessage = event => {
|
|
|
|
const data = JSON.parse(event.data);
|
|
|
|
console.log(data);
|
2024-04-30 21:20:26 +03:00
|
|
|
populate(data);
|
2024-04-29 20:43:18 +03:00
|
|
|
};
|
|
|
|
|