Files
bitvid/js/payments/platformAddress.js
T

159 lines
3.7 KiB
JavaScript

// js/payments/platformAddress.js
import { PLATFORM_LUD16_OVERRIDE, ADMIN_SUPER_NPUB } from "../config.js";
import { nostrClient } from "../nostr.js";
import { setProfileCacheEntry } from "../state/cache.js";
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
const CACHE_TTL_MS = 10 * 60 * 1000;
let cachedAddress = null;
function getGlobalWindow() {
if (typeof window !== "undefined") {
return window;
}
if (typeof globalThis !== "undefined") {
return globalThis;
}
return {};
}
function getNostrTools() {
const win = getGlobalWindow();
return win?.NostrTools || null;
}
function decodeAdminPubkey() {
const trimmed = typeof ADMIN_SUPER_NPUB === "string" ? ADMIN_SUPER_NPUB.trim() : "";
if (!trimmed) {
return null;
}
if (HEX64_REGEX.test(trimmed)) {
return trimmed.toLowerCase();
}
const tools = getNostrTools();
const decoder = tools?.nip19?.decode;
if (typeof decoder === "function") {
try {
const decoded = decoder(trimmed);
if (decoded?.type === "npub" && typeof decoded.data === "string") {
const hex = decoded.data.trim();
if (HEX64_REGEX.test(hex)) {
return hex.toLowerCase();
}
}
} catch (error) {
console.warn("[platformAddress] Failed to decode ADMIN_SUPER_NPUB", error);
}
}
return null;
}
function shouldUseOverride() {
return typeof PLATFORM_LUD16_OVERRIDE === "string" && PLATFORM_LUD16_OVERRIDE.trim();
}
function getOverrideAddress() {
const trimmed = PLATFORM_LUD16_OVERRIDE.trim();
return trimmed || null;
}
function isCacheFresh(entry) {
if (!entry) {
return false;
}
if (typeof entry.expiresAt !== "number") {
return false;
}
return entry.expiresAt > Date.now();
}
async function fetchAdminMetadata(adminPubkey) {
if (!adminPubkey) {
return null;
}
if (!nostrClient?.pool || !Array.isArray(nostrClient?.relays)) {
console.warn("[platformAddress] Nostr client is not ready.");
return null;
}
try {
const events = await nostrClient.pool.list(nostrClient.relays, [
{ kinds: [0], authors: [adminPubkey], limit: 1 },
]);
if (!Array.isArray(events) || events.length === 0) {
return null;
}
let newest = null;
for (const event of events) {
if (!event || event.pubkey !== adminPubkey || !event.content) {
continue;
}
if (!newest || event.created_at > newest.created_at) {
newest = event;
}
}
if (!newest?.content) {
return null;
}
const data = JSON.parse(newest.content);
const lightningAddress =
typeof data.lud16 === "string" && data.lud16.trim()
? data.lud16.trim()
: typeof data.lud06 === "string" && data.lud06.trim()
? data.lud06.trim()
: "";
if (lightningAddress) {
setProfileCacheEntry(adminPubkey, data, { persist: false });
}
return lightningAddress || null;
} catch (error) {
console.warn("[platformAddress] Failed to fetch admin metadata", error);
return null;
}
}
export async function getPlatformLightningAddress({ forceRefresh = false } = {}) {
if (shouldUseOverride()) {
return getOverrideAddress();
}
if (!forceRefresh && isCacheFresh(cachedAddress)) {
return cachedAddress.value;
}
const adminPubkey = decodeAdminPubkey();
if (!adminPubkey) {
return null;
}
if (forceRefresh !== true && cachedAddress?.value) {
return cachedAddress.value;
}
const lightningAddress = await fetchAdminMetadata(adminPubkey);
if (lightningAddress) {
cachedAddress = {
value: lightningAddress,
expiresAt: Date.now() + CACHE_TTL_MS,
};
}
return lightningAddress || cachedAddress?.value || null;
}
export function __resetPlatformAddressCache() {
cachedAddress = null;
}