/** * pnpm seed: ingest the initial mint list, run one probe cycle, run one discovery * backfill, print a summary table. * * The list below is every mint URL carried in a kind 38172 announcement on the old * site's relay pool at the time of the rebuild (see NOTES.md: the old project has no * hardcoded list of its own, its directory is built live from Nostr). Seeding is only * a warm start, discovery finds everything here on its own and keeps finding more. */ import { closeDb, getDb } from './db.ts'; import { closePool, runDiscovery } from './discovery.ts'; import { log } from './log.ts'; import { insertMintIfNew } from './mints.ts'; import { probeAll } from './probe.ts'; import { listMints } from './queries.ts'; const SEED_MINTS = [ 'https://21mint.me', 'https://bitcointxoko.com/cashu/api/v1/dMk78c5aR7uhHzcqH3Bwqp', 'https://cashu.boats', 'https://cashu.mineracks.com', 'https://forge.flashapp.me', 'https://lnb.bolverker.com/cashu/api/v1/GZjPXyQXsgnZEgKZsLRQyy', 'https://lnwallet.app/cashu/api/v1/9tZLEVyknrtaGxeBjEecc4', 'https://bb.mountainlake.io/cashu/api/v1/WpczZwvNES7wMa8ForKGmh', 'https://mint.0xchat.com', 'https://mint.28waves.com', 'https://mint.belgianbitcoinembassy.org', 'https://mint.btcforplebs.com', 'https://mint.cashu.chat', 'https://mint.coinos.io', 'https://mint.endfiat.money', 'https://mint.fredix.xyz', 'https://mint.gitvid.net', 'https://mint.gwoq.com', 'https://mint.kashir.xyz', 'https://mint.lnfast.com', 'https://mint.lnserver.com', 'https://mint.lnvoltz.com', 'https://mint.lnw.cash', 'https://mint.lnwallet.app', 'https://mint.mikelcalvo.net', 'https://mint.minibits.cash/Bitcoin', 'https://mint.mineracks.com', 'https://mint.mountainlake.io', 'https://mint.nostrich.cc', 'https://mint.quixote.cash/cashu/api/v1/TX6nZECe8r6hjDxtdA6N5b', 'https://mint.sharegap.net', 'https://mint.westernbtc.com', 'https://mint2.nutmix.cash', 'https://obsessedjerky7.lnbits.com/cashu/api/v1/L4bNfiBtTyhEpZWdt6QTb4', 'https://smilemoji.cash:3338', 'https://stpaulinternet.net/cashu/api/v1/TTcmiEDSWmkefef3XqERKv', 'https://kashu.me', ]; function pad(s: string, width: number): string { return s.length > width ? `${s.slice(0, width - 1)}…` : s.padEnd(width); } async function main(): Promise { getDb(); let added = 0; for (const url of SEED_MINTS) if (insertMintIfNew(url)) added++; log.info('seed list ingested', { listed: SEED_MINTS.length, added }); await probeAll(); const discovery = await runDiscovery(true); // Discovery almost always turns up mints the seed list did not have. Probe those too, // otherwise they sit at status 'unknown' with no metadata. if (discovery.newMints.length > 0) { log.info('probing newly discovered mints', { count: discovery.newMints.length }); await probeAll(); } const mints = listMints(); const width = { host: 44, status: 9, score: 7, reviews: 8, rating: 7 }; console.log(''); console.log( [ pad('MINT', width.host), pad('STATUS', width.status), pad('SCORE', width.score), pad('REVIEWS', width.reviews), pad('RATING', width.rating), 'VERSION', ].join(' '), ); console.log('-'.repeat(110)); for (const m of mints) { console.log( [ pad(m.host, width.host), pad(m.status, width.status), pad(m.score.toFixed(3), width.score), pad(String(m.review_count), width.reviews), pad(m.rating_avg === null ? '-' : m.rating_avg.toFixed(1), width.rating), m.version ?? '-', ].join(' '), ); } const online = mints.filter((m) => m.status === 'online').length; const offline = mints.filter((m) => m.status === 'offline').length; const reviews = mints.reduce((sum, m) => sum + m.review_count, 0); console.log('-'.repeat(110)); console.log( `${mints.length} mints (${online} online, ${offline} offline), ${reviews} reviews indexed`, ); closePool(); closeDb(); process.exit(0); } void main();