import { readShineUserPda, updateServerOnSolana } from '../../js/services/shine-user-pda-service.js'; import { $, buildKeyBundleFromForm, clearGenMessage, clearStatus, deriveKeyBundleFromPassword, fillKeyFields, formatBigInt, formatTimestamp, openDevnetTopup, 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); $('password').value = ''; $('btnTopupDevnet').addEventListener('click', () => { try { openDevnetTopup($('devPub').value); } catch (error) { setStatus($('status'), error?.message || String(error), 'error'); } }); $('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); $('password').value = ''; $('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';