SHA256
Перенести server UI в shine-UI и объединить PDA-модуль
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { readShineUserPda, updateServerOnSolana } from '../../js/services/shine-user-pda-service.js';
|
||||
import {
|
||||
$,
|
||||
buildKeyBundleFromForm,
|
||||
clearGenMessage,
|
||||
clearStatus,
|
||||
deriveKeyBundleFromPassword,
|
||||
fillKeyFields,
|
||||
formatBigInt,
|
||||
formatTimestamp,
|
||||
parseLoginList,
|
||||
setGenMessage,
|
||||
setStatus,
|
||||
setupPasswordEye,
|
||||
updateSolAddress,
|
||||
validateLoginOrThrow,
|
||||
wireDeviceAddressPreview,
|
||||
} from './server-ui-shared.js';
|
||||
|
||||
const fieldMap = {
|
||||
masterSecret: 'masterSecret',
|
||||
rootPub: 'rootPub',
|
||||
rootPriv: 'rootPriv',
|
||||
bchPub: 'bchPub',
|
||||
bchPriv: 'bchPriv',
|
||||
devPub: 'devPub',
|
||||
devPriv: 'devPriv',
|
||||
solBox: 'solBox',
|
||||
solAdr: 'solAdr',
|
||||
};
|
||||
|
||||
let currentPda = null;
|
||||
|
||||
setupPasswordEye($('btnEye'), $('password'));
|
||||
wireDeviceAddressPreview(fieldMap);
|
||||
|
||||
$('btnGen').addEventListener('click', async () => {
|
||||
clearGenMessage($('genMsg'));
|
||||
clearStatus($('status'));
|
||||
$('btnGen').disabled = true;
|
||||
try {
|
||||
const login = validateLoginOrThrow($('login').value);
|
||||
const password = $('password').value;
|
||||
const { masterSecret32, keyBundle } = await deriveKeyBundleFromPassword({ login, password });
|
||||
fillKeyFields(fieldMap, keyBundle, masterSecret32);
|
||||
updateSolAddress(fieldMap);
|
||||
setGenMessage($('genMsg'), 'Ключи и master secret сгенерированы из логина и пароля.', 'ok');
|
||||
} catch (error) {
|
||||
setGenMessage($('genMsg'), error?.message || String(error), 'err');
|
||||
} finally {
|
||||
$('btnGen').disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
$('btnLoad').addEventListener('click', async () => {
|
||||
clearStatus($('status'));
|
||||
clearGenMessage($('genMsg'));
|
||||
$('btnLoad').disabled = true;
|
||||
currentPda = null;
|
||||
$('pdaInfo').style.display = 'none';
|
||||
$('updateForm').style.display = 'none';
|
||||
try {
|
||||
const login = validateLoginOrThrow($('login').value);
|
||||
const endpoint = String($('endpoint').value || '').trim();
|
||||
if (!endpoint) throw new Error('Укажите Solana endpoint');
|
||||
|
||||
setStatus($('status'), 'Загрузка PDA из Solana...', 'info');
|
||||
const parsed = await readShineUserPda({ login, solanaEndpoint: endpoint });
|
||||
if (!parsed.isServer) throw new Error('Эта PDA не является серверной');
|
||||
currentPda = parsed;
|
||||
|
||||
$('iAddr').textContent = parsed.pdaAddress;
|
||||
$('iVer').textContent = `#${parsed.recordNumber}`;
|
||||
$('iCreated').textContent = formatTimestamp(parsed.createdAtMs);
|
||||
$('iUpdated').textContent = formatTimestamp(parsed.updatedAtMs);
|
||||
$('iSrvAddr').textContent = parsed.serverAddress || '—';
|
||||
$('iSync').textContent = parsed.syncServers.length ? parsed.syncServers.join(', ') : '—';
|
||||
$('iBch').textContent = parsed.blockchain.blockchainName;
|
||||
$('iLimit').textContent = formatBigInt(parsed.blockchain.paidLimitBytes);
|
||||
|
||||
$('serverAddress').value = parsed.serverAddress || '';
|
||||
$('syncServers').value = parsed.syncServers.join('\n');
|
||||
$('pdaInfo').style.display = 'block';
|
||||
$('updateForm').style.display = 'block';
|
||||
setStatus($('status'), 'PDA загружена. Можно менять адрес или sync_servers.', 'success');
|
||||
} catch (error) {
|
||||
setStatus($('status'), error?.message || String(error), 'error');
|
||||
} finally {
|
||||
$('btnLoad').disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
$('btnUpdate').addEventListener('click', async () => {
|
||||
clearStatus($('status'));
|
||||
clearGenMessage($('genMsg'));
|
||||
$('btnUpdate').disabled = true;
|
||||
try {
|
||||
if (!currentPda) throw new Error('Сначала загрузите PDA');
|
||||
const endpoint = String($('endpoint').value || '').trim();
|
||||
if (!endpoint) throw new Error('Укажите Solana endpoint');
|
||||
const serverAddress = String($('serverAddress').value || '').trim();
|
||||
if (!serverAddress) throw new Error('Укажите адрес сервера');
|
||||
|
||||
setStatus($('status'), 'Проверка и сборка keyBundle...', 'info');
|
||||
const { keyBundle, normalized } = await buildKeyBundleFromForm(fieldMap, { requireBlockchain: false });
|
||||
$('rootPub').value = normalized.rootPubB58;
|
||||
$('rootPriv').value = normalized.rootPrivB58;
|
||||
$('bchPub').value = normalized.bchPubB58;
|
||||
$('bchPriv').value = normalized.bchPrivB58;
|
||||
$('devPub').value = normalized.devPubB58;
|
||||
$('devPriv').value = normalized.devPrivB58;
|
||||
updateSolAddress(fieldMap);
|
||||
|
||||
setStatus($('status'), 'Отправка update_user_pda в Solana...', 'info');
|
||||
const result = await updateServerOnSolana({
|
||||
login: currentPda.login,
|
||||
keyBundle,
|
||||
serverAddress,
|
||||
addressFormatType: currentPda.addressFormatType ?? 1,
|
||||
addressFormatVersion: currentPda.addressFormatVersion ?? 0,
|
||||
syncServers: parseLoginList($('syncServers').value),
|
||||
solanaEndpoint: endpoint,
|
||||
});
|
||||
|
||||
setStatus(
|
||||
$('status'),
|
||||
`✓ PDA обновлена!\n\nЛогин: ${currentPda.login}\nPDA: ${result.pdaAddress}\nТранзакция: ${result.signature}`,
|
||||
'success',
|
||||
);
|
||||
currentPda = null;
|
||||
$('pdaInfo').style.display = 'none';
|
||||
$('updateForm').style.display = 'none';
|
||||
} catch (error) {
|
||||
setStatus($('status'), error?.message || String(error), 'error');
|
||||
} finally {
|
||||
$('btnUpdate').disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
document.body.dataset.ready = '1';
|
||||
Reference in New Issue
Block a user