88 lines
3.1 KiB
JavaScript
88 lines
3.1 KiB
JavaScript
import { readShineUserPda } from './shine-user-pda-service.js';
|
||
import {
|
||
defaultServerAddress,
|
||
defaultServerHttp,
|
||
defaultServerLogin,
|
||
defaultServerWs,
|
||
} from '../deploy-config.js';
|
||
|
||
export const DEFAULT_SHINE_SERVER_LOGIN = defaultServerLogin;
|
||
export const DEFAULT_SHINE_SERVER_ADDRESS = defaultServerAddress;
|
||
export const DEFAULT_SHINE_SERVER_HTTP = defaultServerHttp;
|
||
export const DEFAULT_SHINE_SERVER_WS = defaultServerWs;
|
||
|
||
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,
|
||
};
|
||
}
|