feat(ui): кошелек на device.key и проверки серверов (тоже пока не проверено)

This commit is contained in:
AidarKC
2026-04-21 03:12:22 +03:00
parent 8be56192cb
commit e63c53a855
9 changed files with 588 additions and 79 deletions
+47 -15
View File
@@ -1,4 +1,3 @@
import { wallet } from './mock-data.js';
import { AuthService } from './services/auth-service.js';
import { clearClientAuthData } from './services/key-vault.js';
import { clearStoredMessages, listStoredMessages, putStoredMessage } from './services/message-store.js';
@@ -7,6 +6,7 @@ const clone = (value) => JSON.parse(JSON.stringify(value));
const SESSION_STORAGE_KEY = 'shine-ui-current-session-v1';
const REACTIONS_STORAGE_KEY = 'shine-ui-message-reactions-v2';
const WEB_PUSH_SUBSCRIPTION_KEY = 'shine-ui-webpush-subscription-v1';
const ENTRY_SETTINGS_STORAGE_KEY = 'shine-ui-entry-settings-v1';
const CHANNEL_NOTIFY_KEY = 'shine-channels-notify-v1';
const CHANNELS_DEMO_KEY = 'shine-channels-demo';
const CREATE_CHANNEL_FLASH_KEY = 'shine-channels-create-success';
@@ -77,7 +77,9 @@ function inferTunnelWsUrl() {
}
const LOCAL_WS_OVERRIDE_URL = readLocalWsOverrideUrl() || inferTunnelWsUrl();
const DEFAULT_SOLANA_SERVER = 'https://api.devnet.solana.com';
const DEFAULT_SHINE_SERVER = 'wss://shineup.me/ws';
const DEFAULT_ARWEAVE_SERVER = 'https://arweave.net';
function loadStoredSession() {
try {
@@ -125,6 +127,37 @@ function clearStoredSession() {
}
}
function loadStoredEntrySettings() {
try {
const raw = localStorage.getItem(ENTRY_SETTINGS_STORAGE_KEY);
if (!raw) return null;
const parsed = JSON.parse(raw);
if (!parsed || typeof parsed !== 'object') return null;
return parsed;
} catch {
return null;
}
}
function persistEntrySettings(settings) {
try {
const payload = {
language: String(settings?.language || 'ru'),
solanaServer: String(settings?.solanaServer || DEFAULT_SOLANA_SERVER),
shineServer: String(settings?.shineServer || DEFAULT_SHINE_SERVER),
arweaveServer: String(settings?.arweaveServer || DEFAULT_ARWEAVE_SERVER),
statuses: {
solanaServer: String(settings?.statuses?.solanaServer || 'idle'),
shineServer: String(settings?.statuses?.shineServer || 'idle'),
arweaveServer: String(settings?.statuses?.arweaveServer || 'idle'),
},
};
localStorage.setItem(ENTRY_SETTINGS_STORAGE_KEY, JSON.stringify(payload));
} catch {
// ignore storage errors
}
}
function clearBrowserClientData() {
const localKeys = [
SESSION_STORAGE_KEY,
@@ -151,6 +184,7 @@ function clearBrowserClientData() {
function createInitialState({ withStoredSession = true } = {}) {
const storedSession = withStoredSession ? loadStoredSession() : null;
const storedReactions = loadStoredReactions();
const storedEntrySettings = loadStoredEntrySettings();
const initialShineServer = LOCAL_WS_OVERRIDE_URL || DEFAULT_SHINE_SERVER;
return {
@@ -170,14 +204,14 @@ function createInitialState({ withStoredSession = true } = {}) {
},
startHint: '',
entrySettings: {
language: 'ru',
solanaServer: 'https://api.mainnet-beta.solana.com',
shineServer: initialShineServer,
arweaveServer: 'https://arweave.net',
language: String(storedEntrySettings?.language || 'ru'),
solanaServer: String(storedEntrySettings?.solanaServer || DEFAULT_SOLANA_SERVER),
shineServer: String(LOCAL_WS_OVERRIDE_URL || storedEntrySettings?.shineServer || initialShineServer),
arweaveServer: String(storedEntrySettings?.arweaveServer || DEFAULT_ARWEAVE_SERVER),
statuses: {
solanaServer: 'idle',
shineServer: 'idle',
arweaveServer: 'idle',
solanaServer: String(storedEntrySettings?.statuses?.solanaServer || 'idle'),
shineServer: String(storedEntrySettings?.statuses?.shineServer || 'idle'),
arweaveServer: String(storedEntrySettings?.statuses?.arweaveServer || 'idle'),
},
},
registrationDraft: {
@@ -194,8 +228,8 @@ function createInitialState({ withStoredSession = true } = {}) {
password: '',
},
registrationPayment: {
walletAddress: wallet.publicAddress,
balanceSOL: '0.0068',
walletAddress: '',
balanceSOL: '0.0000',
},
keyStorage: {
rootKey: 'Ключ root хранится в зашифрованном виде',
@@ -478,12 +512,9 @@ export function ensureChat(chatId) {
}
export function checkServerAvailability(address) {
const normalized = address.trim().toLowerCase();
const normalized = String(address || '').trim().toLowerCase();
if (!normalized) return 'unavailable';
const looksLikeUrl = /^(https?:\/\/|wss?:\/\/)[a-z0-9.-]+/i.test(normalized);
const blockedWord = /(offline|down|fail|bad|broken|invalid)/i.test(normalized);
return looksLikeUrl && !blockedWord ? 'available' : 'unavailable';
return /^(https?:\/\/|wss?:\/\/)/i.test(normalized) ? 'available' : 'unavailable';
}
export async function saveEntrySettings(nextSettings) {
@@ -497,6 +528,7 @@ export async function saveEntrySettings(nextSettings) {
...(nextSettings.statuses || {}),
},
};
persistEntrySettings(state.entrySettings);
await authService.reconnect(state.entrySettings.shineServer);
state.startHint = 'Настройки входа сохранены, адреса серверов обновлены.';
}