diff --git a/VERSION.properties b/VERSION.properties index 4bf4549..c6a44b3 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.17 -server.version=1.2.17 +client.version=1.2.18 +server.version=1.2.18 diff --git a/shine-UI/js/pages/registration-payment-view.js b/shine-UI/js/pages/registration-payment-view.js index a6632a1..d3b5fbb 100644 --- a/shine-UI/js/pages/registration-payment-view.js +++ b/shine-UI/js/pages/registration-payment-view.js @@ -6,9 +6,15 @@ import { state, } from '../state.js'; import { toUserMessage } from '../services/ui-error-texts.js'; -import { deriveWalletFromPassword, formatSol, getBalanceSol } from '../services/solana-wallet-service.js'; +import { + deriveWalletFromPassword, + formatSol, + getBalanceSol, + getTopupSiteUrl, +} from '../services/solana-wallet-service.js'; export const pageMeta = { id: 'registration-payment-view', title: 'Оплата регистрации', showAppChrome: false }; +const MIN_REQUIRED_SOL = 0.01; function parseBalanceSol(value) { const parsed = Number.parseFloat(String(value || '').replace(',', '.')); @@ -77,9 +83,9 @@ export function render({ navigate }) { refreshButton.textContent = '↻'; refreshButton.title = 'Обновить'; - const refreshBalance = async () => { + const refreshBalance = async ({ showError = true } = {}) => { const address = String(walletValue.value || '').trim(); - if (!address) return; + if (!address) return null; refreshButton.disabled = true; try { const balance = await getBalanceSol({ @@ -88,10 +94,14 @@ export function render({ navigate }) { }); state.registrationPayment.balanceSOL = String(balance.sol); balanceValue.textContent = `${formatSol(balance.sol, 6)} SOL`; + return Number(balance.sol) || 0; } catch (error) { - status.className = 'status-line is-unavailable'; - status.textContent = `Не удалось обновить баланс: ${error?.message || 'unknown'}`; - status.style.display = ''; + if (showError) { + status.className = 'status-line is-unavailable'; + status.textContent = `Не удалось обновить баланс: ${error?.message || 'unknown'}`; + status.style.display = ''; + } + return null; } finally { refreshButton.disabled = false; } @@ -106,8 +116,11 @@ export function render({ navigate }) { const topupButton = document.createElement('button'); topupButton.className = 'ghost-btn'; topupButton.type = 'button'; - topupButton.textContent = 'Пополнить счет'; - topupButton.addEventListener('click', () => navigate('topup-view')); + topupButton.textContent = 'Пополнить кошелёк'; + topupButton.addEventListener('click', () => { + const walletAddress = String(walletValue.value || '').trim(); + window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer'); + }); const submitButton = document.createElement('button'); submitButton.className = 'primary-btn'; @@ -116,8 +129,8 @@ export function render({ navigate }) { submitButton.addEventListener('click', async () => { status.style.display = 'none'; - const cryptoState = getCryptoRuntimeState(); - if (!cryptoState.hasCrypto || !cryptoState.hasGetRandomValues || !cryptoState.hasSubtle) { + const cryptoState = getCryptoRuntimeState(); + if (!cryptoState.hasCrypto || !cryptoState.hasGetRandomValues || !cryptoState.hasSubtle) { status.className = 'status-line is-unavailable'; status.textContent = 'Криптография браузера недоступна. Откройте приложение через HTTPS tunnel или localhost и повторите регистрацию.'; status.style.display = ''; @@ -128,6 +141,27 @@ export function render({ navigate }) { submitButton.disabled = true; submitButton.textContent = 'Регистрация...'; + const walletAddress = String(walletValue.value || '').trim(); + if (!walletAddress) { + status.className = 'status-line is-unavailable'; + status.textContent = 'Кошелёк не подготовлен. Нажмите «Обновить» и попробуйте снова.'; + status.style.display = ''; + return; + } + + const currentBalance = await refreshBalance({ showError: true }); + if (currentBalance == null) return; + if (currentBalance < MIN_REQUIRED_SOL) { + status.className = 'status-line is-unavailable'; + status.textContent = `Для регистрации нужно минимум ${MIN_REQUIRED_SOL} SOL. Сейчас на кошельке ${formatSol(currentBalance, 6)} SOL. Пополните на промо-странице или попросите перевод у знакомого с тестовыми SOL.`; + status.style.display = ''; + const openTopup = window.confirm('Открыть страницу пополнения с вашим кошельком?'); + if (openTopup) { + window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer'); + } + return; + } + await authService.reconnect(state.entrySettings.shineServer); const result = await authService.registerUser(state.registrationDraft.login, state.registrationDraft.password); state.registrationDraft.flowType = 'registration'; @@ -151,7 +185,7 @@ export function render({ navigate }) { }); card.innerHTML = ` -
Для регистрации в Solana нужно заплатить 0,01 SOL (примерно 1 доллар).
+Для регистрации в тестовой Solana нужно минимум 0,01 SOL на вашем кошельке.
Кнопка «Пополнить» в кошельке будет переводить на отдельный сайт. Пока доступно тестовое пополнение.