import { formatInboundLabel } from '@/lib/inbounds/label'; import { preferPublicHost, resolveShareHost } from '@/lib/xray/inbound-link'; import type { ClientRecord, InboundOption } from '@/hooks/useClients'; export function isWireguardClient(client: ClientRecord | null | undefined): boolean { if (!client) return false; return !!(client.privateKey || client.publicKey || client.allowedIPs || client.preSharedKey || client.keepAlive); } export function findWireguardInbound( client: ClientRecord | null | undefined, inboundsById: Record, ): InboundOption | undefined { return (client?.inboundIds || []) .map((id) => inboundsById[id]) .find((ib) => ib?.protocol === 'wireguard'); } export function buildWireguardClientConfig( client: ClientRecord, inbound: InboundOption | undefined, host = window.location.hostname, publicHost = '', ): string { const endpointHost = resolveShareHost(inbound ?? {}, inbound?.nodeAddress ?? '', preferPublicHost(host, publicHost)); const address = client.allowedIPs || '10.0.0.2/32'; const endpoint = `${endpointHost}:${inbound?.port || ''}`; const inboundName = inbound ? formatInboundLabel(inbound.tag, inbound.remark) : ''; const remark = [inboundName, client.email, client.comment].filter(Boolean).join(' - '); const lines = [ '[Interface]', `PrivateKey = ${client.privateKey || client.password || ''}`, `Address = ${address}`, `DNS = ${inbound?.wgDns || '1.1.1.1, 1.0.0.1'}`, ]; if (inbound?.wgMtu && inbound.wgMtu > 0) lines.push(`MTU = ${inbound.wgMtu}`); lines.push(''); if (remark) lines.push(`# ${remark}`); lines.push('[Peer]', `PublicKey = ${inbound?.wgPublicKey || ''}`); if (client.preSharedKey) lines.push(`PresharedKey = ${client.preSharedKey}`); lines.push('AllowedIPs = 0.0.0.0/0, ::/0', `Endpoint = ${endpoint}`); if (client.keepAlive && client.keepAlive > 0) lines.push(`PersistentKeepalive = ${client.keepAlive}`); return lines.join('\n'); }