- 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>
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>
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>
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>
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>
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>
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>
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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>
- 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>