import { readShineUserPda } from './shine-user-pda-service.js'; export const DEFAULT_SHINE_SERVER_LOGIN = 'shineupme'; export const DEFAULT_SHINE_SERVER_ADDRESS = 'shineup.me'; export const DEFAULT_SHINE_SERVER_HTTP = `https://${DEFAULT_SHINE_SERVER_ADDRESS}`; export const DEFAULT_SHINE_SERVER_WS = `wss://${DEFAULT_SHINE_SERVER_ADDRESS}/ws`; function normalizeHostLike(value) { const raw = String(value || '').trim(); if (!raw) return ''; try { const withScheme = /^[a-z]+:\/\//i.test(raw) ? raw : `https://${raw}`; const parsed = new URL(withScheme); return String(parsed.host || '').trim().toLowerCase(); } catch { return raw.replace(/^https?:\/\//i, '').replace(/^wss?:\/\//i, '').replace(/\/.*$/, '').trim().toLowerCase(); } } export function normalizeShineServerLogin(value) { return String(value || '').trim().toLowerCase(); } export function buildShineHttpUrlFromAddress(address) { const host = normalizeHostLike(address); if (!host) return DEFAULT_SHINE_SERVER_HTTP; return `https://${host}`; } export function buildShineWsUrlFromAddress(address) { const host = normalizeHostLike(address); if (!host) return DEFAULT_SHINE_SERVER_WS; return `wss://${host}/ws`; } export async function resolveShineServerByServerLogin({ serverLogin, solanaEndpoint }) { const cleanServerLogin = normalizeShineServerLogin(serverLogin) || DEFAULT_SHINE_SERVER_LOGIN; const parsed = await readShineUserPda({ login: cleanServerLogin, solanaEndpoint, }); if (!parsed?.isServer) { throw new Error(`Логин @${cleanServerLogin} не опубликован как сервер SHiNE.`); } const serverAddress = normalizeHostLike(parsed?.serverAddress || ''); if (!serverAddress) { throw new Error(`У server PDA пользователя @${cleanServerLogin} не задан server_address.`); } return { serverLogin: cleanServerLogin, serverAddress, httpBase: buildShineHttpUrlFromAddress(serverAddress), wsUrl: buildShineWsUrlFromAddress(serverAddress), userPda: parsed, }; } export async function resolveShineServerForUserLogin({ login, solanaEndpoint, fallbackServerLogin = '' }) { const cleanLogin = normalizeShineServerLogin(login); if (!cleanLogin) throw new Error('Не указан логин пользователя для поиска сервера доступа.'); const parsedUser = await readShineUserPda({ login: cleanLogin, solanaEndpoint, }); const accessServers = Array.isArray(parsedUser?.accessServers) ? parsedUser.accessServers.map((value) => normalizeShineServerLogin(value)).filter(Boolean) : []; const pickedServerLogin = accessServers[0] || normalizeShineServerLogin(fallbackServerLogin); if (!pickedServerLogin) { throw new Error(`У пользователя @${cleanLogin} в PDA не указан access server.`); } const resolved = await resolveShineServerByServerLogin({ serverLogin: pickedServerLogin, solanaEndpoint, }); return { ...resolved, accessServerLogin: pickedServerLogin, userPda: parsedUser, }; }