SHA256
Регистрация: пополнение в том же окне и тестовый top-up
This commit is contained in:
@@ -257,8 +257,8 @@ export function render({ navigate }) {
|
||||
topupButton.textContent = 'Пополнить кошелёк';
|
||||
topupButton.addEventListener('click', async () => {
|
||||
try {
|
||||
const walletAddress = await deriveUserWalletAddress();
|
||||
window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer');
|
||||
await deriveUserWalletAddress();
|
||||
navigate('topup-view');
|
||||
} catch (error) {
|
||||
status.className = 'status-line is-unavailable';
|
||||
status.textContent = `Не удалось подготовить кошелёк: ${error?.message || 'unknown'}`;
|
||||
@@ -301,10 +301,8 @@ export function render({ navigate }) {
|
||||
: `Для регистрации пополните этот кошелёк соланами примерно на ${RECOMMENDED_TOPUP_SOL} SOL. Сейчас на кошельке ${formatSol(currentBalance, 6)} SOL. Минимум для продолжения: ${MIN_REQUIRED_SOL} SOL.`;
|
||||
status.style.display = '';
|
||||
if (isTestContour) {
|
||||
const openTopup = window.confirm('Открыть страницу пополнения с вашим кошельком?');
|
||||
if (openTopup) {
|
||||
window.open(getTopupSiteUrl(walletAddress), '_blank', 'noopener,noreferrer');
|
||||
}
|
||||
const openTopup = window.confirm('Перейти на экран пополнения и затем продолжить регистрацию?');
|
||||
if (openTopup) navigate('topup-view');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { renderHeader } from '../components/header.js';
|
||||
import { state } from '../state.js';
|
||||
import {
|
||||
createSolanaWalletFromPrivateBase58,
|
||||
formatSol,
|
||||
getBalanceSol,
|
||||
getTopupSiteUrl,
|
||||
requestAirdropSol,
|
||||
transferSol,
|
||||
} from '../services/solana-wallet-service.js';
|
||||
import { loadSolanaWeb3 } from '../vendor/solana-web3-loader.js';
|
||||
|
||||
export const pageMeta = { id: 'topup-view', title: 'Пополнение счета', showAppChrome: false };
|
||||
export const pageMeta = { id: 'topup-view', title: 'Пополнение solana счета', showAppChrome: false };
|
||||
const DEVNET_ENDPOINT = 'https://api.devnet.solana.com';
|
||||
const SENDER_PRIVATE_32_BASE58 = '6xqAuKYvA8qrCdAkcw7Y8aMgvBnYk8JLxWLma5BzbAvu';
|
||||
const REGISTRATION_TOPUP_AMOUNT_SOL = 0.02;
|
||||
|
||||
// Канонический Solana-адрес пополнения = публичный device-ключ из сгенерированного набора ключей.
|
||||
// Тот же путь, что в registration-payment-view (deriveUserWalletAddress); не выводим адрес
|
||||
@@ -39,6 +43,10 @@ export function render({ navigate }) {
|
||||
const status = document.createElement('p');
|
||||
status.className = 'meta-muted';
|
||||
status.textContent = 'Проверяем кошелек...';
|
||||
status.style.whiteSpace = 'pre-wrap';
|
||||
status.style.overflowWrap = 'anywhere';
|
||||
status.style.wordBreak = 'break-word';
|
||||
status.style.fontSize = '13px';
|
||||
|
||||
const copyButton = document.createElement('button');
|
||||
copyButton.className = 'ghost-btn';
|
||||
@@ -63,42 +71,54 @@ export function render({ navigate }) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'card stack';
|
||||
card.innerHTML = `
|
||||
<p class="auth-copy">Кнопка «Пополнить» в кошельке будет переводить на отдельный сайт. Пока доступно тестовое пополнение.</p>
|
||||
<div class="stack" style="gap:6px;">
|
||||
<p class="meta-muted">1. Вы можете открыть промо-сайт пополнения с подставленным кошельком.</p>
|
||||
<p class="meta-muted">2. Либо нажать «Тестовое пополнение» и получить 1 SOL через DevNet airdrop.</p>
|
||||
</div>
|
||||
<a class="link-card" id="topup-site-link" href="${getTopupSiteUrl(state.registrationPayment.walletAddress || '')}" target="_blank" rel="noreferrer">Открыть сайт пополнения</a>
|
||||
<p class="auth-copy">Можете или пополнить счёт тестовыми соланами и продолжить регистрацию.</p>
|
||||
<div class="card stack" style="padding:12px; max-width:320px;">
|
||||
<div class="field-label" style="margin-bottom:6px;">Кошелёк для пополнения (client key = Solana wallet)</div>
|
||||
</div>
|
||||
<div class="stack" style="gap:6px;">
|
||||
<p class="meta-muted">Или можете отдельно открыть страницу тестового пополнения.</p>
|
||||
<a class="link-card" id="topup-site-link" href="${getTopupSiteUrl(state.registrationPayment.walletAddress || '')}" target="_blank" rel="noreferrer">Открыть страницу тестового пополнения</a>
|
||||
</div>
|
||||
`;
|
||||
card.children[3].append(walletRow);
|
||||
card.children[1].append(walletRow);
|
||||
|
||||
const testButton = document.createElement('button');
|
||||
testButton.className = 'ghost-btn';
|
||||
testButton.type = 'button';
|
||||
testButton.textContent = 'Тестовое пополнение (1 SOL)';
|
||||
testButton.textContent = 'Тестовое пополнение для регистрации';
|
||||
testButton.addEventListener('click', async () => {
|
||||
const address = String(walletValue.value || '').trim();
|
||||
if (!address) {
|
||||
window.alert('Адрес кошелька не найден.');
|
||||
return;
|
||||
}
|
||||
if (!senderKeypair) {
|
||||
status.textContent = 'Ошибка: тестовый кошелёк отправителя ещё не инициализирован.';
|
||||
return;
|
||||
}
|
||||
testButton.disabled = true;
|
||||
try {
|
||||
const drop = await requestAirdropSol({
|
||||
endpoint: state.entrySettings.solanaServer,
|
||||
address,
|
||||
amountSol: 1,
|
||||
status.textContent = 'Отправляем тестовое пополнение для регистрации...';
|
||||
const tx = await transferSol({
|
||||
endpoint: DEVNET_ENDPOINT,
|
||||
fromKeypair: senderKeypair,
|
||||
toAddress: address,
|
||||
amountSol: REGISTRATION_TOPUP_AMOUNT_SOL,
|
||||
});
|
||||
const bal = await getBalanceSol({
|
||||
endpoint: state.entrySettings.solanaServer,
|
||||
endpoint: DEVNET_ENDPOINT,
|
||||
address,
|
||||
});
|
||||
state.registrationPayment.balanceSOL = String(bal.sol);
|
||||
status.textContent = `Тестовое пополнение выполнено. Новый баланс: ${formatSol(bal.sol, 6)} SOL. Signature: ${drop.signature}`;
|
||||
status.style.fontSize = '12px';
|
||||
status.textContent = [
|
||||
'Тестовое пополнение для регистрации выполнено.',
|
||||
`Кошелёк пополнен на ${REGISTRATION_TOPUP_AMOUNT_SOL} SOL.`,
|
||||
`Новый баланс: ${formatSol(bal.sol, 6)} SOL.`,
|
||||
`Signature: ${tx.signature}`,
|
||||
].join('\n');
|
||||
} catch (error) {
|
||||
status.style.fontSize = '13px';
|
||||
status.textContent = `Ошибка тестового пополнения: ${error?.message || 'unknown'}`;
|
||||
} finally {
|
||||
testButton.disabled = false;
|
||||
@@ -108,12 +128,13 @@ export function render({ navigate }) {
|
||||
const backButton = document.createElement('button');
|
||||
backButton.className = 'primary-btn';
|
||||
backButton.type = 'button';
|
||||
backButton.textContent = 'Назад';
|
||||
backButton.textContent = 'Продолжить регистрацию';
|
||||
backButton.addEventListener('click', () => navigate('registration-payment-view'));
|
||||
|
||||
const actions = document.createElement('div');
|
||||
actions.className = 'auth-footer-actions';
|
||||
actions.append(testButton, backButton);
|
||||
let senderKeypair = null;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
@@ -132,6 +153,8 @@ export function render({ navigate }) {
|
||||
});
|
||||
state.registrationPayment.balanceSOL = String(balance.sol);
|
||||
status.textContent = `Текущий баланс: ${formatSol(balance.sol, 6)} SOL`;
|
||||
const sender = await createSolanaWalletFromPrivateBase58(SENDER_PRIVATE_32_BASE58);
|
||||
senderKeypair = sender.keypair;
|
||||
} catch (error) {
|
||||
status.textContent = `Не удалось получить баланс: ${error?.message || 'unknown'}`;
|
||||
}
|
||||
@@ -139,7 +162,7 @@ export function render({ navigate }) {
|
||||
|
||||
screen.append(
|
||||
renderHeader({
|
||||
title: 'Пополнение счета',
|
||||
title: 'Пополнение solana счета',
|
||||
leftAction: { label: '←', onClick: () => navigate('registration-payment-view') },
|
||||
}),
|
||||
card,
|
||||
|
||||
Reference in New Issue
Block a user