document.addEventListener('DOMContentLoaded', () => { // DOM Elements const loginButton = document.getElementById('loginButton'); const logoutButton = document.getElementById('logoutButton'); const userInfo = document.getElementById('userInfo'); const userPubkey = document.getElementById('userPubkey'); const authSection = document.getElementById('auth-section'); const mainContent = document.getElementById('main-content'); const botsList = document.getElementById('bots-list'); const createBotBtn = document.getElementById('create-bot-btn'); const saveBotBtn = document.getElementById('save-bot-btn'); const generateKeypair = document.getElementById('generateKeypair'); const keypairInput = document.getElementById('keypair-input'); // Bootstrap Modal let createBotModal; if (typeof bootstrap !== 'undefined') { createBotModal = new bootstrap.Modal(document.getElementById('createBotModal')); } // State let currentUser = null; const API_ENDPOINT = ''; // Check if already logged in checkAuth(); // Event Listeners loginButton.addEventListener('click', login); logoutButton.addEventListener('click', logout); createBotBtn.addEventListener('click', showCreateBotModal); saveBotBtn.addEventListener('click', createBot); generateKeypair.addEventListener('change', toggleKeypairInput); // Functions async function checkAuth() { const token = localStorage.getItem('authToken'); if (!token) { showAuthSection(); return; } try { const response = await fetch(`${API_ENDPOINT}/api/auth/verify`, { headers: { 'Authorization': token } }); if (response.ok) { const data = await response.json(); currentUser = data.pubkey; showMainContent(); fetchBots(); } else { // Token invalid localStorage.removeItem('authToken'); showAuthSection(); } } catch (error) { console.error('Auth check failed:', error); showAuthSection(); } } async function login() { if (!window.nostr) { alert('Nostr extension not found. Please install a NIP-07 compatible extension like nos2x or Alby.'); return; } try { // Get user's public key const pubkey = await window.nostr.getPublicKey(); // Create challenge event for signing const event = { kind: 22242, created_at: Math.floor(Date.now() / 1000), tags: [['challenge', 'nostr-poster-auth']], content: 'Authenticate with Nostr Poster' }; // Sign the event const signedEvent = await window.nostr.signEvent(event); // Send to server for verification const response = await fetch(`${API_ENDPOINT}/api/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pubkey: pubkey, signature: signedEvent.sig, event: JSON.stringify(signedEvent) }) }); if (response.ok) { const data = await response.json(); localStorage.setItem('authToken', data.token); currentUser = pubkey; showMainContent(); fetchBots(); } else { alert('Authentication failed'); } } catch (error) { console.error('Login failed:', error); alert('Login failed: ' + error.message); } } function logout() { localStorage.removeItem('authToken'); currentUser = null; showAuthSection(); } function showAuthSection() { authSection.classList.remove('d-none'); mainContent.classList.add('d-none'); loginButton.classList.remove('d-none'); userInfo.classList.add('d-none'); logoutButton.classList.add('d-none'); } function showMainContent() { authSection.classList.add('d-none'); mainContent.classList.remove('d-none'); loginButton.classList.add('d-none'); userInfo.classList.remove('d-none'); logoutButton.classList.remove('d-none'); // Truncate pubkey for display const shortPubkey = currentUser.substring(0, 8) + '...' + currentUser.substring(currentUser.length - 4); userPubkey.textContent = shortPubkey; } async function fetchBots() { try { const token = localStorage.getItem('authToken'); const response = await fetch(`${API_ENDPOINT}/api/bots`, { headers: { 'Authorization': token } }); if (response.ok) { const bots = await response.json(); renderBots(bots); } else { console.error('Failed to fetch bots'); } } catch (error) { console.error('Error fetching bots:', error); } } function renderBots(bots) { botsList.innerHTML = ''; if (bots.length === 0) { botsList.innerHTML = `
You don't have any bots yet.
${bot.bio || 'No bio'}
npub...${bot.pubkey.substring(bot.pubkey.length - 8)}