Commit graph

22 commits

Author SHA1 Message Date
Claude
3f294340b2
feat: UpdateDnsRecords Action, Prometheus metrics, JSON validation
- UpdateDnsRecords Action: controller method now one-liner, all DNS
  logic in Action with activity logging and edit lock.
- Prometheus metrics at /v1/metrics: chain_height, alias_count,
  claims_pending, dns_tickets, gateways_live. Grafana-ready.
- ValidateJsonRequest middleware: enforces application/json on POST,
  64KB body size limit. Applied to all /v1/* API routes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:12:07 +01:00
Claude
ad29a45507
feat: chain:stop command + DNS update activity logging
chain:stop sends SIGTERM and waits for graceful shutdown.
DNS updateRecords now logs 'dns_updated' activity with ticket_id
and records. Claim approve/reject also logged in previous commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:09:19 +01:00
Claude
3f82c497fd
feat: claim approval/rejection API endpoints
POST /v1/names/claims/{id}/approve — changes status, logs activity.
POST /v1/names/claims/{id}/reject — changes status, logs activity.
Both require auth.api middleware. Validates claim exists and is pending.
Completes the claim lifecycle: submit → review → approve/reject.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:07:38 +01:00
Claude
1ef6ed1c7b
refactor: move DNS tickets from Cache to DnsTicket database model
DNS change tickets now persisted in MariaDB via DnsTicket model.
Survives cache clears and container rebuilds. Model has open(),
confirm(), fail() methods and pending/queued scopes. Controller
updateRecords and ticket endpoints refactored. RetryDnsTickets
command queries model instead of cache.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:06:00 +01:00
Claude
6af0d7ea73
feat: API Resources for consistent JSON formatting
NameResource transforms alias data with parsed type, capabilities,
and owner_type (registry/community). ClaimResource formats claim
responses. Lookup endpoint uses NameResource, claim uses ClaimResource
with additional message. Follows CorePHP patterns/building-rest-apis.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:49:19 +01:00
Claude
ca11c4ccee
refactor: extract Actions for CheckAvailability, SubmitClaim, RegisterName
CorePHP Actions pattern — single-purpose classes with static ::run().
Controller methods now delegate to Actions. Each Action validates,
executes, and returns typed results. Enables reuse from commands,
jobs, and tests without going through HTTP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:24:27 +01:00
Claude
2b91476cf7
refactor: move pre-registration claims from Cache to database model
Claims stored in Cache were lost on cache clear. Now persisted in
name_claims SQLite table via NameClaim Eloquent model. Auto-generates
claim_id via random_bytes. Scopes: pending(), approved(). Methods:
approve(), reject(). Status page updated to query model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 11:21:58 +01:00
Claude
1f31444171
feat(names): pre-registration claim system for soft launch
Adds claim/listClaims endpoints so visitors can reserve .lthn names
before chain registration is fully automated. Claims are stored with
email for notification when approved. Admin endpoint lists all claims.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 08:30:23 +01:00
Claude
a5f28d5f6f
security: fix critical + high code review findings
CRITICAL:
- DaemonRpc: only cache successful responses as stale fallback (not errors)
- Records endpoint: replaced file_get_contents with Http::timeout(3)

HIGH:
- WalletRpc: removed exception message from API response (IP leak)
- Ticket/session IDs: replaced MD5(predictable) with random_bytes (CSPRNG)
- Race condition lock: Cache::add() atomic instead of has()+put()

MEDIUM:
- Block caching: getBlockByHeight cached 1hr (blocks are immutable)
- Sunrise meta description: fixed Blade variable syntax

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 08:08:18 +01:00
Claude
ed300e200e
feat(sunrise): verify then pay claim flow + ownership tiers
- Verify response includes claim_process (4 steps: verify → check → pay → transfer)
- Ownership tiers: free (registry key, limited DNS) vs paid (your key, full control)
- Check response includes purchase_url when verified
- Payment via Blesta/BTCPay completes the claim

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 06:34:26 +01:00
Claude
054b2e6161
feat(sunrise): DNS TXT verification for brand claims (HNS-style)
- GET /v1/names/sunrise/verify/{name} — generate verification token
- GET /v1/names/sunrise/check/{name} — check TXT record across .com/.org/.net/.io/.co.uk
- Token: _lthn-verify.brand.com TXT "lthn-verify={hash}"
- Same process as Handshake TLD claims
- Sunrise page shows both auto (DNS) and manual (email) verification paths
- Automatic claim when DNS record matches

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 06:28:58 +01:00
Claude
994fa0733f
feat(names): API auth + rate limiting on write endpoints
- Bearer token auth middleware on POST /register and /records
- Throttle: 10 registrations/min, 20 DNS updates/min
- Token configurable via API_TOKEN env var (disabled when empty)
- Daemon alias validation: a-z 0-9 . - up to 255 chars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:44:53 +01:00
Claude
c166471d19
feat(names): per-name edit lock prevents concurrent DNS overwrites
- DNS update locks name for 5 min (until block confirms)
- Second edit gets clear "update pending" error (409)
- Lock released when ticket confirmed against chain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:19:01 +01:00
Claude
fc97af878f
fix(names): use pipe separator in dns= format, prevent comma-in-value bug
- dns= entries now separated by | instead of ,
- Commas in TXT values (e.g. SPF records) no longer break parsing
- IPv6 addresses verified safe with splitColon(entry, 3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:17:09 +01:00
Claude
1f29000c11
feat(chain): circuit breaker with stale cache fallback
- DaemonRpc: try/catch with stale cache (1h TTL) when daemon is down
- WalletRpc: try/catch with clear error message
- Health endpoint: status=offline/degraded/critical/low_funds/healthy
- Reports wallet_online, daemon_online, stale flags
- Reduced daemon timeout from 10s to 5s, wallet from 30s to 15s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 03:06:23 +01:00
Claude
0c5f35c47f
feat(names): reservation lock prevents race conditions
- Cache-based lock on name during registration (10 min TTL)
- Availability check shows reserved: true when locked
- Second registration attempt gets clear error message
- Lock released on permanent failure, auto-expires after 10 min

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:55:57 +01:00
Claude
afc955c7b9
feat(names): wallet health endpoint + pre-flight balance check
- GET /v1/names/health — registrar balance, registrations remaining, chain status
- Returns 503 when critically low (< 2 registrations)
- Pre-flight balance check in register endpoint rejects early if wallet empty
- Thresholds: low_funds < 10, critical < 2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:52:34 +01:00
Claude
e351b9deaa
feat(names): background retry for queued DNS tickets
- artisan names:retry-dns command retries queued tickets
- Checks pending tx confirmation against chain
- Tracks ticket IDs in cache for iteration
- Registered via ConsoleBooting event

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:41:29 +01:00
Claude
03a45a51d4
feat(names): DNS change queue with ticket tracking
- POST /v1/names/records/{name} returns ticket ID for tracking
- GET /v1/names/ticket/{id} checks status (queued/pending/confirmed)
- Queue gracefully handles busy chain (202 Accepted)
- Ticket auto-checks confirmation against chain alias

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 02:06:38 +01:00
Claude
c46a163bbb
feat(names): DNS records backed by LNS sidechain
- GET /v1/names/records/{name} reads from LNS sidechain (/resolve)
- POST /v1/names/records/{name} writes via update_alias on chain
- Records encoded in alias comment: dns=TYPE:HOST:VALUE,...
- LNS_URL config for sidechain endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 00:53:49 +01:00
Claude
0899881138
feat(lthn.io): name registration API, Blade views, wallet RPC
- POST /v1/names/register endpoint with wallet RPC integration
- WalletRpc service for alias registration via daemon wallet
- Blade views for homepage, explorer, names directory, network status
- Explorer and Names modules with view namespaces and web controllers
- Pool endpoint graceful offline handling
- Explorer block detail, aliases, search views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 23:04:27 +01:00
Claude
77cc45dd83
feat: lthn.io CorePHP app — TLD website + blockchain services
Modules:
- Chain: daemon RPC client (DaemonRpc singleton, cached queries)
- Explorer: block browser, tx viewer, alias directory, search, stats API
- Names: .lthn TLD registrar portal (availability check, lookup, directory)
- Trade: scaffold (DEX frontend + API)
- Pool: scaffold (mining pool dashboard)

Replaces 5 Node.js containers (5.9GB) with one FrankenPHP app.
Built on CorePHP framework pattern from host.uk.com.

Co-Authored-By: Charon <charon@lethean.io>
2026-04-03 16:13:55 +01:00