From da8928c9939c965fc131afadd146f1eaa339acf3 Mon Sep 17 00:00:00 2001 From: Unheard0840 Date: Sat, 29 Aug 2026 10:22:31 +0000 Subject: [PATCH] Update server/status.js Add persistent Bitcoin address watchlist --- server/status.js | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/server/status.js b/server/status.js index f8bf4de..f15d516 100644 --- a/server/status.js +++ b/server/status.js @@ -5,6 +5,11 @@ const { createSession, isValidSession, } = require('./auth'); +const { + listAddresses, + addAddress, + removeAddress, +} = require('./addresses'); const port = 8080; const fulcrumTimeoutMs = 3000; @@ -265,6 +270,125 @@ const server = http.createServer(async (req, res) => { return } + if (req.method === 'GET' && req.url === '/api/addresses') { + if (!isValidSession(req)) { + res.writeHead(401, { + 'Content-Type': 'application/json', + }) + res.end(JSON.stringify({ error: 'Authentication required' })) + return + } + + try { + const addresses = await listAddresses() + + res.writeHead(200, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify({ addresses })) + } catch (error) { + console.error('Failed to list addresses:', error) + + res.writeHead(500, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify({ + error: 'Failed to read address watchlist', + })) + } + + return + } + + if (req.method === 'POST' && req.url === '/api/addresses') { + if (!isValidSession(req)) { + res.writeHead(401, { + 'Content-Type': 'application/json', + }) + res.end(JSON.stringify({ error: 'Authentication required' })) + return + } + + let body = '' + + req.on('data', (chunk) => { + body += chunk + }) + + req.on('end', async () => { + try { + const input = JSON.parse(body) + + const entry = await addAddress( + input.address, + input.label, + ) + + res.writeHead(201, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify(entry)) + } catch (error) { + const message = error instanceof Error + ? error.message + : 'Failed to add address' + + res.writeHead(400, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify({ error: message })) + } + }) + + return + } + + if (req.method === 'DELETE' && req.url === '/api/addresses') { + if (!isValidSession(req)) { + res.writeHead(401, { + 'Content-Type': 'application/json', + }) + res.end(JSON.stringify({ error: 'Authentication required' })) + return + } + + let body = '' + + req.on('data', (chunk) => { + body += chunk + }) + + req.on('end', async () => { + try { + const input = JSON.parse(body) + + await removeAddress(input.address) + + res.writeHead(200, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify({ ok: true })) + } catch (error) { + const message = error instanceof Error + ? error.message + : 'Failed to remove address' + + res.writeHead(400, { + 'Content-Type': 'application/json', + }) + + res.end(JSON.stringify({ error: message })) + } + }) + + return + } + if (req.url === '/api/status') { if (!isValidSession(req)) { res.writeHead(401, {