diff options
| author | Adam Soltys <[email protected]> | 2026-08-02 09:14:37 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-02 09:14:37 -0700 |
| commit | e9ef91e007a945ca01d4de45392b15bd257e06a3 (patch) | |
| tree | 1bd40ba3d8578885ce9ceab33f1b8e813657e4af /names/server.js | |
| parent | 165c03875369a9c21e69ae1429d51b8e6a3a497c (diff) | |
| download | coinosv3-e9ef91e007a945ca01d4de45392b15bd257e06a3.tar.gz coinosv3-e9ef91e007a945ca01d4de45392b15bd257e06a3.zip | |
Registrar: an operator endpoint to top the float up over Lightning
The float pays out in Ark while incoming Lightning accumulates on the
node, so it needs periodic refilling. It can now mint an invoice
against its own balance (token-guarded, since the endpoint is public).
Co-Authored-By: Claude Fable 5 <[email protected]>
Diffstat (limited to 'names/server.js')
| -rw-r--r-- | names/server.js | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/names/server.js b/names/server.js index bd62f81..57a6e8c 100644 --- a/names/server.js +++ b/names/server.js @@ -463,6 +463,37 @@ Bun.serve({ } } + // Top up the float over Lightning: it mints an invoice against its own + // ark balance, which anyone (in practice, the operator's node) can pay. + // Guarded by a token from the config file — this endpoint is public. + if (url.pathname === '/admin/topup' && req.method === 'POST') { + if (!CFG.adminToken || req.headers.get('x-admin-token') !== CFG.adminToken) { + return json({ error: 'unauthorized' }, 401); + } + if (!fwd) return json({ error: 'no forwarder wallet' }, 503); + const body = await req.json().catch(() => ({})); + const sat = Math.floor(body.sat || 0); + if (!sat || sat < 1000) return json({ error: 'amount too small' }, 400); + try { + const a = await fwd.createLnInvoice(sat, 'names float top-up'); + log(`float top-up invoice for ${sat} sat`); + return json({ invoice: a.invoice, paymentHash: a.paymentHash }); + } catch (e) { + return json({ error: e.message }, 500); + } + } + + // Drive an in-flight lightning receive forward (top-ups settle async). + if (url.pathname === '/admin/drive' && req.method === 'POST') { + if (!CFG.adminToken || req.headers.get('x-admin-token') !== CFG.adminToken) { + return json({ error: 'unauthorized' }, 401); + } + if (!fwd) return json({ error: 'no forwarder wallet' }, 503); + for (const a of fwd.pendingActions()) { await fwd.driveLn(a.id).catch(() => {}); } + await fwd.sync().catch(() => {}); + return json({ ok: true, floatSat: fwd.balance().spendableSat }); + } + if (url.pathname === '/register' && req.method === 'POST') { if (!rateOk(ip)) return json({ error: 'rate limited' }, 429); const bodyText = await req.text(); |
