Stupid skylights... Spent my morning crawling around the attic looking for a leak, and then diverting the leak out the soffit so it stopped soaking the insulation. Found out it is leaking because of a big ice dam under the skylight which is loosing too much heat I guess. Gotta melt all that ice now.
rustinmyeye2d
Flashing #2 now
#2
rustinmyeye2d
Setting up a couple #reticulum #rnode s to play with...
#reticulum
#rnode
rustinmyeye3d
Thank you for that tip! Just set that up. I had no idea.
rustinmyeye3d
I just realized that Mr. Vain has been in my head because this song plays on the radio so often! Double earworm...
https://www.youtube.com/watch?v=TqFE9h-hXlY
rustinmyeye3d
https://youtu.be/BC4bTHmWz-A
rustinmyeye3d
Seems plausible that this was mine, but others seem too recent.
rustinmyeye3d
#asknostr I wanted to build a thing to check an first note, kinda like to see how long I've been using nostr, but it doesn't work for everyone I try. What's the right way to do this?
Running it here: https://notecheck.bspr.UK
Code made by a robot:
❯ cat server.js 10:16:39const express = require("express");
const { nip19 } = require("nostr-tools");
const { SimplePool, useWebSocketImplementation } = require("nostr-tools/pool");
const WebSocket = require("ws");
useWebSocketImplementation(WebSocket);
const app = express();
const PORT = 4747;
app.use(express.urlencoded({ extended: true }));
// Convert npub to hex
function (npub) {
const { type, data } = nip19.decode(npub);
if (type !== "npub") throw new Error("Invalid npub");
return data;
}
// Expanded default relay list
const defaultRelays = [
"wss://relay.damus.io",
"wss://nos.lol",
"wss://nostr.wine",
"wss://relay.nostr.band",
"wss://nostr.bitcoiner.social",
"wss://nostr.oxtr.dev",
"wss://soloco.nl",
"wss://nostr.einundzwanzig.space",
"wss://relay.nostr.net",
"wss://offchain.pub",
"wss://relay.snort.social",
"wss://eden.nostr.land",
"wss://nostr.mom",
"wss://relay.nostrview.com",
"wss://nostr.plebchain.org",
"wss://nostr.21sats.net"
];
// Get oldest kind 1 (note) timestamp from multiple relays
async function getFirstNoteTimestamp(pubkeyHex, extraRelays = []) {
const relays = [...defaultRelays, ...extraRelays];
const pool = new SimplePool();
let oldestTimestamp = Infinity;
const promises = relays.map(url => {
return new Promise((resolve) => {
const sub = pool.subscribe(
[url],
{ kinds: [1], authors: [pubkeyHex] },
{
onevent(event) {
if (event.created_at < oldestTimestamp) {
oldestTimestamp = event.created_at;
}
},
oneose() {
resolve();
}
}
);
// Safety timeout per relay
setTimeout(() => {
sub?.close();
resolve();
}, 12000);
});
});
await Promise.all(promises);
pool.close(relays);
return oldestTimestamp === Infinity ? null : oldestTimestamp;
}
// Home page
app.get("/", (req, res) => {
res.send(renderPage());
});
// Handle form submission
app.post("/", async (req, res) => {
const npub = req.body.npub;
const extraRelays = req.body.extraRelays
? req.body.extraRelays.split(/\s+/).filter(Boolean)
: [];
let message;
try {
const pubkeyHex = (npub);
const ts = await getFirstNoteTimestamp(pubkeyHex, extraRelays);
if (ts) {
const timestampStr = new Date(ts * 1000).toUTCString();
message = `First Note: ${timestampStr}`;
} else {
message = "No notes found for this npub.";
}
} catch (err) {
message = `Error: ${err.message}`;
}
res.send(renderPage(npub, message, extraRelays));
});
// Render HTML page
function renderPage(npub = "", message = "", extraRelays = []) {
return `
Nostr First Note Finder