[Infra] Lightning-Gated Node Bootstrap — pay once, get a Bitcoin full node #50

Closed
opened 2026-03-21 00:41:54 +00:00 by replit · 1 comment
Owner

What & Why

A user pays a single Lightning invoice (the "startup fee") and Timmy automatically provisions a Bitcoin full node for them on Digital Ocean — Ubuntu droplet + block volume + Bitcoin Knots + LND + LNbits via cloud-init — then returns the credentials. This is a proof-of-concept for "node-as-a-service bootstrapped by Lightning."

Done looks like

  • POST /api/bootstrap returns a Lightning invoice (BOOTSTRAP_FEE_SATS env var, default 10 000 sats)
  • GET /api/bootstrap/:id polls state: awaiting_paymentprovisioningready | failed
  • In stub mode (no DO_API_TOKEN), provisioning simulated in ~2 s with fake credentials
  • With real keys, a DO droplet + optional block volume is created, cloud-init runs node bootstrap, credentials returned
  • Delivered credentials: Tailscale hostname, SSH private key (delivered once, cleared from DB), node public IP, LNbits URL
  • Result includes note about Bitcoin sync taking 1–2 weeks

Out of scope

  • Waiting for full Bitcoin sync before marking ready (too slow)
  • UI for this flow (API only)
  • Refunding fee on provisioning failure (manual operator action for now)
  • Monitoring spawned node's uptime

Tasks

  1. DB schema — Add bootstrap_jobs table: state, invoice details, provisioning results (droplet ID, node IP, Tailscale hostname, SSH private key, error message), timestamps.
  2. Provisioner serviceprovisioner.ts in api-server/src/lib/: SSH keypair generation, Tailscale auth-key creation, DO droplet creation with cloud-init. Stub mode when DO_API_TOKEN absent.
  3. Bootstrap routesbootstrap.ts in api-server/src/routes/: POST /api/bootstrap (creates job + invoice) and GET /api/bootstrap/:id (poll state machine). Mount in app.ts.
  4. Pricing + env varscalculateBootstrapFeeSats() in PricingService. Document env vars in replit.md: DO_API_TOKEN, DO_REGION, DO_SIZE, DO_VOLUME_SIZE_GB, TAILSCALE_API_KEY, TAILSCALE_TAILNET, BOOTSTRAP_FEE_SATS.

Relevant files

  • lib/db/src/schema/index.ts
  • artifacts/api-server/src/routes/jobs.ts
  • artifacts/api-server/src/lib/lnbits.ts
  • artifacts/api-server/src/lib/pricing.ts
  • infrastructure/setup.sh
## What & Why A user pays a single Lightning invoice (the "startup fee") and Timmy automatically provisions a Bitcoin full node for them on Digital Ocean — Ubuntu droplet + block volume + Bitcoin Knots + LND + LNbits via cloud-init — then returns the credentials. This is a proof-of-concept for "node-as-a-service bootstrapped by Lightning." ## Done looks like - `POST /api/bootstrap` returns a Lightning invoice (`BOOTSTRAP_FEE_SATS` env var, default 10 000 sats) - `GET /api/bootstrap/:id` polls state: `awaiting_payment` → `provisioning` → `ready` | `failed` - In stub mode (no `DO_API_TOKEN`), provisioning simulated in ~2 s with fake credentials - With real keys, a DO droplet + optional block volume is created, cloud-init runs node bootstrap, credentials returned - Delivered credentials: Tailscale hostname, SSH private key (delivered once, cleared from DB), node public IP, LNbits URL - Result includes note about Bitcoin sync taking 1–2 weeks ## Out of scope - Waiting for full Bitcoin sync before marking ready (too slow) - UI for this flow (API only) - Refunding fee on provisioning failure (manual operator action for now) - Monitoring spawned node's uptime ## Tasks 1. **DB schema** — Add `bootstrap_jobs` table: state, invoice details, provisioning results (droplet ID, node IP, Tailscale hostname, SSH private key, error message), timestamps. 2. **Provisioner service** — `provisioner.ts` in `api-server/src/lib/`: SSH keypair generation, Tailscale auth-key creation, DO droplet creation with cloud-init. Stub mode when `DO_API_TOKEN` absent. 3. **Bootstrap routes** — `bootstrap.ts` in `api-server/src/routes/`: `POST /api/bootstrap` (creates job + invoice) and `GET /api/bootstrap/:id` (poll state machine). Mount in `app.ts`. 4. **Pricing + env vars** — `calculateBootstrapFeeSats()` in `PricingService`. Document env vars in `replit.md`: `DO_API_TOKEN`, `DO_REGION`, `DO_SIZE`, `DO_VOLUME_SIZE_GB`, `TAILSCALE_API_KEY`, `TAILSCALE_TAILNET`, `BOOTSTRAP_FEE_SATS`. ## Relevant files - `lib/db/src/schema/index.ts` - `artifacts/api-server/src/routes/jobs.ts` - `artifacts/api-server/src/lib/lnbits.ts` - `artifacts/api-server/src/lib/pricing.ts` - `infrastructure/setup.sh`
replit added the lightningbackend labels 2026-03-21 00:41:54 +00:00
gemini was assigned by Rockachopa 2026-03-22 23:37:26 +00:00
Collaborator

PR #98 created. This PR implements the Lightning-Gated Node Bootstrap feature, including DB schema, provisioner service, API routes, and documentation updates.

PR #98 created. This PR implements the Lightning-Gated Node Bootstrap feature, including DB schema, provisioner service, API routes, and documentation updates.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: replit/timmy-tower#50