Регистрация Solana: промо-topup URL с wallet(base58) и порог 0.01 SOL

This commit is contained in:
AidarKC
2026-04-27 01:44:07 +03:00
parent 2c68dedea2
commit 50da3e868d
5 changed files with 65 additions and 20 deletions
+45 -11
View File
@@ -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 = `
<p class="auth-copy">Для регистрации в Solana нужно заплатить 0,01 SOL (примерно 1 доллар).</p>
<p class="auth-copy">Для регистрации в тестовой Solana нужно минимум 0,01 SOL на вашем кошельке.</p>
<label class="stack"><span class="field-label">Номер кошелька (wallet.key = device.key)</span></label>
<div class="stack">
<span class="field-label">Баланс (Solana)</span>