Aeontropy's avatar
Aeontropy
aeontropy@snort.social
npub1kade...z2an
Lo que se ve no se juzga https://throne.com/aeontropy Lightning wallet: Aeontropy@primal.net https://x.com/Aeontropy https://www.youtube.com/@Aeontropy https://www.twitch.tv/garbage_killer
Aeontropy's avatar
Aeontropy 1 month ago
Hello Nostr once again to remind you can bulk delete notes with this, maybe is not perfect but certainly works in some way, relay operators may or not may delete your notes have fun, improvements are welcome. Also save it as html, paste nsec carefully using a temporary clipboard. PS: I was able to build it with Grok. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>Nostr Mass Delete v3 (NIP-62)</title> <script src="https://cdn.jsdelivr.net/npm/nostr-tools@2.10.0/lib/nostr.bundle.js"></script> <style> body { font-family: system-ui, sans-serif; margin:0; padding:16px; background:#111; color:#ddd; line-height:1.5; } input, button, select { width:100%; padding:14px; margin:10px 0; border-radius:8px; font-size:17px; } button { background:#c00; color:white; border:none; font-weight:bold; } button.secondary { background:#555; } button.danger { background:#900; } .event { margin:12px 0; padding:14px; background:#222; border-radius:8px; } .controls { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0; } .controls button { width:auto; flex:1; min-width:140px; } pre { font-size:13px; white-space:pre-wrap; word-break:break-all; } #status { margin:15px 0; padding:12px; background:#222; border-radius:8px; } </style> </head> <body> <h1>Nostr Mass Delete v3 + NIP-62</h1> <input type="password" id="nsec" placeholder="nsec1... your private key" autocomplete="off"> <button id="connect">Connect & Fetch</button> <div id="status"></div> <div id="controls" style="display:none;"> <select id="kind"> <option value="1">Kind 1 — Notes</option> <option value="3">Kind 3 — Contacts / Follows</option> <option value="7">Kind 7 — Reactions</option> <option value="30023">Kind 30023 — Long-form</option> <option value="0">Kind 0 — Profile (careful)</option> </select> <div class="controls"> <button class="secondary" id="selectAll">Select All</button> <button class="secondary" id="selectNone">Select None</button> <button id="deleteAllFetched">🗑️ Delete ALL Fetched</button> </div> <button id="fetchMore">Fetch More Events</button> <div class="controls"> <button class="danger" id="vanishCurrent">🌪️ Vanish on Current Relays (NIP-62)</button> <button class="danger" id="vanishGlobal">☢️ Global Vanish (ALL_RELAYS)</button> </div> </div> <div id="events"></div> <button id="deleteSelected" style="display:none;" class="danger">Delete Selected</button> <script> let pool, sk, pubkey; let RELAYS = [ "wss://relay.damus.io", "wss://nos.lol", "wss://relay.primal.net", "wss://nostr.wine", "wss://relay.nostr.band", "wss://nostr.orangepill.dev", "wss://relay.snort.social", "wss://eden.nostr.land", "wss://nostr-pub.wellorder.net", "wss://nostr.mom", "wss://relay.current.fyi", "wss://nostr.rocks", "wss://relay.nostr.bg", "wss://nostr.fmt.wiz.biz", "wss://nostr.oxtr.dev", "wss://nostr.bitcoiner.social", "wss://relay.nos.social", "wss://nostr21.com", "wss://premium.primal.net", "wss://relay.nostrplebs.com", "wss://relay.mostr.pub", "wss://relay.ditto.pub", "wss://temp.iris.to", "wss://vault.iris.to", // Add your private/paid relays here ]; async function connect() { /* same as before */ const nsec = document.getElementById('nsec').value.trim(); if (!nsec.startsWith('nsec1')) return alert('Enter valid nsec'); try { sk = NostrTools.nip19.decode(nsec).data; pubkey = NostrTools.getPublicKey(sk); document.getElementById('status').innerHTML = `✅ Connected as ${NostrTools.nip19.npubEncode(pubkey).slice(0,12)}...`; document.getElementById('controls').style.display = 'block'; fetchEvents(); } catch(e) { alert('Invalid nsec'); } } async function fetchEvents() { /* unchanged from v2, but supports kind 3 */ const kind = parseInt(document.getElementById('kind').value); const status = document.getElementById('status'); const eventsDiv = document.getElementById('events'); eventsDiv.innerHTML = ''; status.innerHTML += `<p>Fetching kind ${kind}...</p>`; pool = new NostrTools.SimplePool(); const sub = pool.subscribeMany(RELAYS, [{ kinds: [kind], authors: [pubkey], limit: 200 }], { onevent: (event) => { const div = document.createElement('div'); div.className = 'event'; div.innerHTML = ` <label><input type="checkbox" class="select-event" data-id="${event.id}" checked> ${new Date(event.created_at * 1000).toLocaleString()}</label><br> <pre>${(event.content || JSON.stringify(event.tags || [])).substring(0, 200)}...</pre> `; eventsDiv.appendChild(div); }, oneose: () => status.innerHTML += '<p>Fetch complete.</p>' }); setTimeout(() => sub.close(), 45000); } function toggleAll(checked) { document.querySelectorAll('.select-event').forEach(cb => cb.checked = checked); } async function deleteEvents(ids) { /* unchanged */ if (!ids.length || !confirm(`Delete ${ids.length} events?`)) return; const status = document.getElementById('status'); pool = new NostrTools.SimplePool(); for (let id of ids) { const delEvent = { kind: 5, created_at: Math.floor(Date.now()/1000), content: 'Mass delete', tags: [['e', id], ['k', '1']] }; const signed = NostrTools.finalizeEvent(delEvent, sk); await Promise.any(pool.publish(RELAYS, signed)).catch(()=>{}); status.innerHTML += `🗑️ ${id.slice(0,12)}...<br>`; } status.innerHTML += `<p>✅ Deletion requests sent.</p>`; } async function sendVanish(toAll = false) { if (!confirm(toAll ? 'GLOBAL VANISH — Request ALL relays to delete everything?' : 'Send Vanish request to current relays?')) return; const status = document.getElementById('status'); pool = new NostrTools.SimplePool(); const tags = toAll ? [['relay', 'ALL_RELAYS']] : RELAYS.map(r => ['relay', r]); const vanishEvent = { kind: 62, created_at: Math.floor(Date.now() / 1000), content: 'Mass cleanup via tool — please delete all my events', tags: tags }; const signed = NostrTools.finalizeEvent(vanishEvent, sk); const targets = toAll ? RELAYS : RELAYS; for (let relay of targets) { try { await pool.publish([relay], signed); status.innerHTML += `🌪️ Vanish sent to ${relay}<br>`; } catch(e) {} } status.innerHTML += `<p><strong>✅ NIP-62 Vanish requests sent!</strong></p>`; } // Listeners document.getElementById('connect').onclick = connect; document.getElementById('fetchMore').onclick = fetchEvents; document.getElementById('selectAll').onclick = () => toggleAll(true); document.getElementById('selectNone').onclick = () => toggleAll(false); document.getElementById('deleteAllFetched').onclick = () => { const ids = Array.from(document.querySelectorAll('.select-event')).map(cb => cb.dataset.id); deleteEvents(ids); }; document.getElementById('deleteSelected').onclick = () => { const ids = Array.from(document.querySelectorAll('.select-event:checked')).map(cb => cb.dataset.id); deleteEvents(ids); }; document.getElementById('vanishCurrent').onclick = () => sendVanish(false); document.getElementById('vanishGlobal').onclick = () => sendVanish(true); </script> </body> </html>
Aeontropy's avatar
Aeontropy 2 months ago
New gen z/alpha has a new name for losing virginity and seems way drastic (killing, murder)🤦‍♂️
Aeontropy's avatar
Aeontropy 2 months ago
Hehe I know when is going to continue, Valve knows.
Aeontropy's avatar
Aeontropy 2 months ago
Umeko J as Velvet. Love it... That's it!
Aeontropy's avatar
Aeontropy 2 months ago
A comparación de hace 2 décadas, lidiar con mi madre ahora es de no rompas su zen, o de lo contrario es como lo que se describe una mujer en modo supervivencia, si no sabes que es búscalo 😅
Aeontropy's avatar
Aeontropy 2 months ago
Let's see how many vtubers actually wish for happy father's day <3
Aeontropy's avatar
Aeontropy 2 months ago
In today internet, Bob Ross instructions literally will be considered as keep it for yourself, gatekeep!
Aeontropy's avatar
Aeontropy 2 months ago
Cuando se percibe hostilidad en la actitud y si eres de cuna de oro tienes que aprender lo mas rápido posible a ser mas de calle, se pierden los modales si, solo depende el momento y la ocasión que así lo disponga. Buenas noches.
Aeontropy's avatar
Aeontropy 2 months ago
Es muy bien sabido que estafadores ocupan la imagen de Michael Saylor pero a veces me preguntó yo, en el dinero convencional que aun ocupamos siguen estafando a gente eh incluso bancos o comercios. No hay dinero alguno que no sea producto de envidias.
Aeontropy's avatar
Aeontropy 2 months ago
Its annoying cleaning multimedia notes but whatever a price to pay for shitposting
Aeontropy's avatar
Aeontropy 2 months ago
Hello FBI/CIA we have a chinese menace around saying she loves raping men, messages are in chinese btw
Aeontropy's avatar
Aeontropy 2 months ago
Nostr already serves its purpose, the question is when. For now seems a glimpse web 2.0 going dystopia yet it doesn't. When the moment arrives is when Nostr shines.
Aeontropy's avatar
Aeontropy 2 months ago
What I learned while being on nostr is that better avoid reposting other's people spam content just to bring life to that place but anyways sorry! keep your stuff I don't need it anymore.
Aeontropy's avatar
Aeontropy 2 months ago
I'm not a clipper in fact I don't how to use adobe after and premier cluttered menus hate
Aeontropy's avatar
Aeontropy 2 months ago
Freedom of speech, Twitter filters external links with sussy titles -_-*