Добавить диагностику server PDA и баланс device (не проверено)

This commit is contained in:
AidarKC
2026-06-03 16:12:40 +04:00
parent ee3721dfa4
commit eeb115584d
10 changed files with 218 additions and 8 deletions
@@ -4,15 +4,20 @@ import {
buildKeyBundleFromForm,
clearGenMessage,
clearStatus,
compareExpectedPublicKeys,
deriveKeyBundleFromPassword,
fillKeyFields,
formatBigInt,
formatTimestamp,
openDevnetTopup,
parseLoginList,
publicKeyBytesToBase58,
refreshDeviceBalance,
setGenMessage,
setStatus,
setText,
setupPasswordEye,
summarizeKeyComparison,
updateSolAddress,
validateLoginOrThrow,
wireDeviceAddressPreview,
@@ -32,9 +37,62 @@ const fieldMap = {
let currentPda = null;
function resetExpectedKeysUi() {
$('expectedKeysBox').style.display = 'none';
setText('expectedRootPub', '');
setText('expectedBchPub', '');
setText('expectedDevPub', '');
clearGenMessage($('expectedKeysStatus'));
setText('deviceBalance', 'Баланс device ещё не запрашивался.');
}
function renderExpectedKeys(parsed) {
$('expectedKeysBox').style.display = 'block';
setText('expectedRootPub', publicKeyBytesToBase58(parsed.rootKey));
setText('expectedBchPub', publicKeyBytesToBase58(parsed.blockchain.blockchainPublicKey));
setText('expectedDevPub', publicKeyBytesToBase58(parsed.deviceKey));
setGenMessage($('expectedKeysStatus'), 'После генерации ключей этот блок покажет, совпадают ли они с уже записанной PDA.', 'warn');
}
function compareCurrentFormKeysWithPda() {
if (!currentPda) throw new Error('Сначала загрузите PDA');
const blockchainActual = String($('bchPub').value || '').trim();
return {
resultMap: {
root: compareExpectedPublicKeys(publicKeyBytesToBase58(currentPda.rootKey), $('rootPub').value),
blockchain: blockchainActual
? compareExpectedPublicKeys(publicKeyBytesToBase58(currentPda.blockchain.blockchainPublicKey), blockchainActual)
: { matches: true, expected: publicKeyBytesToBase58(currentPda.blockchain.blockchainPublicKey), actual: '' },
device: compareExpectedPublicKeys(publicKeyBytesToBase58(currentPda.deviceKey), $('devPub').value),
},
};
}
function renderComparisonStatus() {
if (!currentPda) return false;
try {
const { resultMap } = compareCurrentFormKeysWithPda();
const summary = summarizeKeyComparison(resultMap);
if (summary.allMatch) {
setGenMessage($('expectedKeysStatus'), 'Ключи совпадают с загруженной PDA. Похоже, пароль верный.', 'ok');
return true;
}
setGenMessage(
$('expectedKeysStatus'),
`Не совпали ключи: ${summary.mismatches.join(', ')}. Похоже, пароль неверный или введены не те ключи.`,
'err',
);
return false;
} catch (error) {
setGenMessage($('expectedKeysStatus'), error?.message || String(error), 'err');
return false;
}
}
setupPasswordEye($('btnEye'), $('password'));
wireDeviceAddressPreview(fieldMap);
$('password').value = '';
resetExpectedKeysUi();
$('btnTopupDevnet').addEventListener('click', () => {
try {
@@ -44,6 +102,21 @@ $('btnTopupDevnet').addEventListener('click', () => {
}
});
$('btnRefreshBalance').addEventListener('click', async () => {
try {
$('btnRefreshBalance').disabled = true;
await refreshDeviceBalance({
endpoint: $('endpoint').value,
deviceAddress: $('devPub').value,
targetNode: $('deviceBalance'),
});
} catch (error) {
setStatus($('status'), error?.message || String(error), 'error');
} finally {
$('btnRefreshBalance').disabled = false;
}
});
$('btnGen').addEventListener('click', async () => {
clearGenMessage($('genMsg'));
clearStatus($('status'));
@@ -54,7 +127,15 @@ $('btnGen').addEventListener('click', async () => {
const { masterSecret32, keyBundle } = await deriveKeyBundleFromPassword({ login, password });
fillKeyFields(fieldMap, keyBundle, masterSecret32);
updateSolAddress(fieldMap);
setGenMessage($('genMsg'), 'Ключи и master secret сгенерированы из логина и пароля.', 'ok');
$('deviceBalance').textContent = 'Теперь можно проверить баланс device-аккаунта.';
const keysOk = renderComparisonStatus();
setGenMessage(
$('genMsg'),
keysOk
? 'Ключи и master secret сгенерированы из логина и пароля. Device-ключ оплатит транзакцию.'
: 'Ключи сгенерированы, но не совпали с уже загруженной PDA. Скорее всего, пароль неверный.',
keysOk ? 'ok' : 'err',
);
} catch (error) {
setGenMessage($('genMsg'), error?.message || String(error), 'err');
} finally {
@@ -69,6 +150,7 @@ $('btnLoad').addEventListener('click', async () => {
currentPda = null;
$('pdaInfo').style.display = 'none';
$('updateForm').style.display = 'none';
resetExpectedKeysUi();
try {
const login = validateLoginOrThrow($('login').value);
const endpoint = String($('endpoint').value || '').trim();
@@ -93,6 +175,7 @@ $('btnLoad').addEventListener('click', async () => {
$('syncServers').value = parsed.syncServers.join('\n');
$('pdaInfo').style.display = 'block';
$('updateForm').style.display = 'block';
renderExpectedKeys(parsed);
setStatus($('status'), 'PDA загружена. Можно менять адрес или sync_servers.', 'success');
} catch (error) {
setStatus($('status'), error?.message || String(error), 'error');
@@ -121,6 +204,9 @@ $('btnUpdate').addEventListener('click', async () => {
$('devPub').value = normalized.devPubB58;
$('devPriv').value = normalized.devPrivB58;
updateSolAddress(fieldMap);
if (!renderComparisonStatus()) {
throw new Error('Ключи не совпадают с загруженной PDA. Проверьте пароль или введённые ключи.');
}
setStatus($('status'), 'Отправка update_user_pda в Solana...', 'info');
const result = await updateServerOnSolana({