Implement session-based API endpoints for creating, managing, and interacting with pre-funded sessions, including deposit and top-up invoice generation, macaroon authentication, and per-request debiting of compute costs.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2dc3847e-7186-4a22-9c7e-16cd31bca8d9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9f85e954-647c-46a5-90a7-396e495a805a/418bf6f8-212b-4bb0-a7a5-8231a061da4e/sPDHkg8
Replit-Helium-Checkpoint-Created: true
## New files
- btc-oracle.ts: CoinGecko BTC/USD fetch (60s cache), usdToSats() helper (ceil, min 1 sat),
5s abort timeout, fallback to BTC_PRICE_USD_FALLBACK env var (default $100k)
- lib/db/migrations/0002_cost_based_pricing.sql: SQL migration artifact adding 6 new columns
to jobs table (estimated_cost_usd, margin_pct, btc_price_usd, actual_input_tokens,
actual_output_tokens, actual_cost_usd); idempotent via ADD COLUMN IF NOT EXISTS
## Modified files
- pricing.ts: Full rewrite — per-model token rates (Haiku/Sonnet, env-var overridable),
DO infra amortisation per request, originator margin %, estimateInputTokens/Output by tier,
calculateActualCostUsd() for post-work ledger, async calculateWorkFeeSats() → WorkFeeBreakdown
- agent.ts: WorkResult now includes inputTokens + outputTokens from Anthropic usage;
workModel/evalModel exposed as readonly public; EVAL_MODEL/WORK_MODEL env var support
- lib/db/src/schema/jobs.ts: 6 new real/integer columns; schema pushed to DB
- jobs.ts route: Work invoice creation calls pricingService.calculateWorkFeeSats() async;
stores estimatedCostUsd/marginPct/btcPriceUsd; post-work stores actualInputTokens/
actualOutputTokens/actualCostUsd; GET response includes pricingBreakdown and costLedger
with totalTokens (input + output computed field)
- openapi.yaml: PricingBreakdown + CostLedger schemas (with totalTokens) added
- lib/api-zod/src/generated/api.ts: Regenerated with new schemas
- lib/api-client-react/src/generated/api.schemas.ts: Regenerated (PricingBreakdown, CostLedger)
- replit.md: 17 new env vars documented in cost-based pricing section
- btc-oracle.ts: CoinGecko BTC/USD fetch (60s cache), usdToSats() helper,
fallback to BTC_PRICE_USD_FALLBACK env var (default $100k), 5s abort timeout
- pricing.ts: Full rewrite — per-model token rates (Haiku/Sonnet, env-var
overridable), DO infra amortisation, originator margin %, estimateInputTokens(),
estimateOutputTokens() by request tier, calculateActualCostUsd() for post-work ledger,
async calculateWorkFeeSats() → WorkFeeBreakdown
- agent.ts: WorkResult now includes inputTokens + outputTokens from Anthropic usage;
workModel/evalModel exposed as readonly public; EVAL_MODEL/WORK_MODEL env var support
- jobs.ts: Work invoice creation calls pricingService.calculateWorkFeeSats() async;
stores estimatedCostUsd/marginPct/btcPriceUsd on job; after executeWork stores
actualInputTokens/actualOutputTokens/actualCostUsd; GET response includes
pricingBreakdown (awaiting_work_payment) and costLedger (complete)
- lib/db/src/schema/jobs.ts: 6 new real/integer columns for cost tracking; schema pushed
- openapi.yaml: PricingBreakdown + CostLedger schemas added to JobStatusResponse
- replit.md: 17 new env vars documented in Cost-based work fee pricing section
Pay a Lightning invoice → Timmy auto-provisions a Bitcoin full node on DO.
New: lib/db/src/schema/bootstrap-jobs.ts
- bootstrap_jobs table: id, state, amountSats, paymentHash, paymentRequest,
dropletId, nodeIp, tailscaleHostname, lnbitsUrl, sshPrivateKey,
sshKeyDelivered (bool), errorMessage, createdAt, updatedAt
- States: awaiting_payment | provisioning | ready | failed
- Payment data stored inline (no FK to jobs/invoices tables — separate entity)
- db:push applied to create table in Postgres
New: artifacts/api-server/src/lib/provisioner.ts
- ProvisionerService: stubs when DO_API_TOKEN absent, real otherwise
- Stub mode: generates a real RSA 4096-bit SSH keypair via ssh-keygen,
returns RFC 5737 test IP + fake Tailscale hostname after 2s delay
- Real mode: upload SSH public key to DO → generate Tailscale auth key →
create DO droplet with cloud-init user_data → poll for public IP (2 min)
- buildCloudInitScript(): non-interactive bash that installs Docker + Tailscale
+ UFW + Bitcoin Knots via docker-compose; joins Tailscale if authkey provided
- provision() designed as fire-and-forget (void); updates DB to ready/failed
New: artifacts/api-server/src/routes/bootstrap.ts
- POST /api/bootstrap: create job + LNbits invoice, return paymentRequest
- GET /api/bootstrap/🆔 poll-driven state machine
* awaiting_payment: checks payment, fires provisioner on confirm
* provisioning: returns progress message
* ready: delivers credentials; SSH private key delivered once then cleared
* failed: returns error message
- Stub mode message includes the exact /dev/stub/pay URL for easy testing
- nextSteps array guides user through post-provision setup
Updated: artifacts/api-server/src/lib/pricing.ts
- Added bootstrapFee field reading BOOTSTRAP_FEE_SATS env var (default 10000)
- calculateBootstrapFeeSats() method
Updated: artifacts/api-server/src/routes/index.ts
- Mounts bootstrapRouter
Updated: replit.md
- Documents all 7 new env vars (DO_API_TOKEN, DO_REGION, DO_SIZE, etc.)
- Full curl-based flow example with annotated response shape
End-to-end verified in stub mode: POST → pay → provisioning → ready (SSH key)
→ second GET clears key and shows sshKeyNote
Adds a foreign key constraint to the `invoices` table, referencing the `id` column in the `jobs` table, ensuring data integrity.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: d9dd1cc2-bc61-41c5-90bb-94504f4308a9
Replit-Helium-Checkpoint-Created: true
Integrate Anthropic AI for agent capabilities, introduce database schemas for jobs and invoices, and set up LNbits for payment processing.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 418bf6f8-212b-4bb0-a7a5-8231a061da4e
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: cce28acc-aeac-46ff-80ec-af4ade39e30f
Replit-Helium-Checkpoint-Created: true