Регистрация Solana: промо-topup URL с wallet(base58) и порог 0.01 SOL
This commit is contained in:
parent
2c68dedea2
commit
50da3e868d
@ -1,2 +1,2 @@
|
||||
client.version=1.2.17
|
||||
server.version=1.2.17
|
||||
client.version=1.2.18
|
||||
server.version=1.2.18
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -50,10 +50,10 @@ export function render({ navigate }) {
|
||||
card.innerHTML = `
|
||||
<p class="auth-copy">Кнопка «Пополнить» в кошельке будет переводить на отдельный сайт. Пока доступно тестовое пополнение.</p>
|
||||
<div class="stack" style="gap:6px;">
|
||||
<p class="meta-muted">1. Вы можете открыть сайт для покупки SOL.</p>
|
||||
<p class="meta-muted">1. Вы можете открыть промо-сайт пополнения с подставленным кошельком.</p>
|
||||
<p class="meta-muted">2. Либо нажать «Тестовое пополнение» и получить 1 SOL через DevNet airdrop.</p>
|
||||
</div>
|
||||
<a class="link-card" href="${getTopupSiteUrl()}" target="_blank" rel="noreferrer">Открыть сайт пополнения</a>
|
||||
<a class="link-card" id="topup-site-link" href="${getTopupSiteUrl(state.registrationPayment.walletAddress || '')}" target="_blank" rel="noreferrer">Открыть сайт пополнения</a>
|
||||
<div class="card stack" style="padding:12px; max-width:320px;">
|
||||
<div class="field-label" style="margin-bottom:6px;">Кошелёк для пополнения (wallet.key)</div>
|
||||
</div>
|
||||
@ -107,6 +107,10 @@ export function render({ navigate }) {
|
||||
state.registrationPayment.walletAddress = wallet.address;
|
||||
walletValue.value = wallet.address;
|
||||
}
|
||||
const topupSiteLink = card.querySelector('#topup-site-link');
|
||||
if (topupSiteLink instanceof HTMLAnchorElement) {
|
||||
topupSiteLink.href = getTopupSiteUrl(walletValue.value);
|
||||
}
|
||||
const balance = await getBalanceSol({
|
||||
endpoint: state.entrySettings.solanaServer,
|
||||
address: walletValue.value,
|
||||
@ -130,4 +134,3 @@ export function render({ navigate }) {
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@ export function render({ navigate }) {
|
||||
'Кнопка будет переводить на отдельный сайт пополнения.\n\nНажмите OK, чтобы открыть сайт.\nНажмите Отмена, чтобы выполнить тестовое пополнение (airdrop 1 SOL на DevNet).',
|
||||
);
|
||||
if (openSite) {
|
||||
window.open(getTopupSiteUrl(), '_blank', 'noopener,noreferrer');
|
||||
window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer');
|
||||
setStatus('Открыт сайт пополнения. Пока также доступно тестовое пополнение.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ import { extractDeviceKey32FromStoredValue } from './device-key-utils.js';
|
||||
import { loadEncryptedUserSecrets } from './key-vault.js';
|
||||
|
||||
const DEFAULT_SOLANA_ENDPOINT = 'https://api.devnet.solana.com';
|
||||
const TOPUP_SITE_URL = 'https://www.moonpay.com/buy/sol';
|
||||
const TOPUP_SITE_URL = 'https://shine-promo-solana-devnet.shineup.me/';
|
||||
|
||||
let solanaLibPromise = null;
|
||||
|
||||
@ -115,6 +115,14 @@ export function formatSol(value, digits = 6) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getTopupSiteUrl() {
|
||||
return TOPUP_SITE_URL;
|
||||
export function getTopupSiteUrl(walletAddress = '') {
|
||||
const cleanWallet = String(walletAddress || '').trim();
|
||||
if (!cleanWallet) return TOPUP_SITE_URL;
|
||||
try {
|
||||
const url = new URL(TOPUP_SITE_URL);
|
||||
url.searchParams.set('wallet', cleanWallet);
|
||||
return url.toString();
|
||||
} catch {
|
||||
return `${TOPUP_SITE_URL}?wallet=${encodeURIComponent(cleanWallet)}`;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user