Add simplified NIP-46 bunker page with click-to-copy QR codes (v0.41.0)
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
- Add BunkerView with two QR codes: client (bunker://) and signer (nostr+connect://) - Add click-to-copy functionality on QR codes with visual "Copied!" feedback - Add CAT requirement warning (only shows when ACL mode is active) - Remove WireGuard dependencies from bunker page - Add /api/bunker/info public endpoint for relay URL, ACL mode, CAT status - Add Cashu token verification for WebSocket connections - Add kind permission checking for Cashu token scopes - Add cashuToken field to Listener for connection-level token tracking Files modified: - app/handle-bunker.go: New bunker info endpoint (without WireGuard) - app/handle-event.go: Add Cashu token kind permission check - app/handle-websocket.go: Extract and verify Cashu token on WS upgrade - app/listener.go: Add cashuToken field - app/server.go: Register bunker info endpoint - app/web/src/BunkerView.svelte: Complete rewrite with QR codes - app/web/src/api.js: Add getBunkerInfo() function - pkg/version/version: Bump to v0.41.0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
83
app/handle-bunker.go
Normal file
83
app/handle-bunker.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"git.mleku.dev/mleku/nostr/encoders/bech32encoding"
|
||||
"git.mleku.dev/mleku/nostr/encoders/hex"
|
||||
"git.mleku.dev/mleku/nostr/interfaces/signer/p8k"
|
||||
"lol.mleku.dev/chk"
|
||||
"lol.mleku.dev/log"
|
||||
)
|
||||
|
||||
// BunkerInfoResponse is returned by the /api/bunker/info endpoint.
|
||||
type BunkerInfoResponse struct {
|
||||
RelayURL string `json:"relay_url"` // WebSocket URL for NIP-46 connections
|
||||
RelayNpub string `json:"relay_npub"` // Relay's npub
|
||||
RelayPubkey string `json:"relay_pubkey"` // Relay's hex pubkey
|
||||
ACLMode string `json:"acl_mode"` // Current ACL mode
|
||||
CashuEnabled bool `json:"cashu_enabled"` // Whether CAT is required
|
||||
Available bool `json:"available"` // Whether bunker is available
|
||||
}
|
||||
|
||||
// handleBunkerInfo returns bunker connection information.
|
||||
// This is a public endpoint that doesn't require authentication.
|
||||
func (s *Server) handleBunkerInfo(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Get relay identity
|
||||
relaySecret, err := s.DB.GetOrCreateRelayIdentitySecret()
|
||||
if chk.E(err) {
|
||||
log.E.F("failed to get relay identity: %v", err)
|
||||
http.Error(w, "Failed to get relay identity", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Derive public key
|
||||
sign, err := p8k.New()
|
||||
if chk.E(err) {
|
||||
http.Error(w, "Failed to create signer", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := sign.InitSec(relaySecret); chk.E(err) {
|
||||
http.Error(w, "Failed to initialize signer", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
relayPubkey := sign.Pub()
|
||||
relayPubkeyHex := hex.Enc(relayPubkey)
|
||||
|
||||
// Encode as npub
|
||||
relayNpubBytes, err := bech32encoding.BinToNpub(relayPubkey)
|
||||
relayNpub := string(relayNpubBytes)
|
||||
if chk.E(err) {
|
||||
relayNpub = relayPubkeyHex // Fallback to hex
|
||||
}
|
||||
|
||||
// Build WebSocket URL from service URL
|
||||
serviceURL := s.ServiceURL(r)
|
||||
wsURL := strings.Replace(serviceURL, "https://", "wss://", 1)
|
||||
wsURL = strings.Replace(wsURL, "http://", "ws://", 1)
|
||||
|
||||
// Check if Cashu is enabled
|
||||
cashuEnabled := s.CashuIssuer != nil
|
||||
|
||||
// Bunker is available when ACL mode is not "none"
|
||||
available := s.Config.ACLMode != "none"
|
||||
|
||||
resp := BunkerInfoResponse{
|
||||
RelayURL: wsURL,
|
||||
RelayNpub: relayNpub,
|
||||
RelayPubkey: relayPubkeyHex,
|
||||
ACLMode: s.Config.ACLMode,
|
||||
CashuEnabled: cashuEnabled,
|
||||
Available: available,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
Reference in New Issue
Block a user