2026-02-10 11:32:49 -08:00
package wallet
import (
"context"
"fmt"
2026-05-22 21:55:42 -07:00
"os"
"strings"
"time"
2026-02-10 11:32:49 -08:00
)
2026-05-22 21:55:42 -07:00
const (
WalletConnectStatusStub = "stub"
WalletConnectStatusDisabled = "disabled"
)
// Config describes the public WalletConnect v2 posture exposed to clients.
type Config struct {
Status string ` json:"status" `
Enabled bool ` json:"enabled" `
ProjectID string ` json:"projectId" `
RelayURL string ` json:"relayUrl" `
MetadataURL string ` json:"metadataUrl" `
RequiredNamespaces [ ] string ` json:"requiredNamespaces" `
SupportedChains [ ] int ` json:"supportedChains" `
FallbackAuth string ` json:"fallbackAuth" `
Message string ` json:"message" `
UpdatedAt string ` json:"updatedAt" `
}
// ConnectResponse is returned while WalletConnect session bridging remains a stub.
type ConnectResponse struct {
Status string ` json:"status" `
Enabled bool ` json:"enabled" `
URI string ` json:"uri,omitempty" `
SessionID string ` json:"sessionId,omitempty" `
ExpiresAt string ` json:"expiresAt,omitempty" `
FallbackAuth string ` json:"fallbackAuth" `
Message string ` json:"message" `
}
// Session represents a wallet session snapshot for future WalletConnect integration.
type Session struct {
SessionID string ` json:"sessionId" `
Address string ` json:"address,omitempty" `
ChainID int ` json:"chainId,omitempty" `
Connected bool ` json:"connected" `
Status string ` json:"status" `
Message string ` json:"message" `
}
// WalletConnect handles WalletConnect v2 integration posture for the explorer API.
2026-02-10 11:32:49 -08:00
type WalletConnect struct {
projectID string
2026-05-22 21:55:42 -07:00
relayURL string
chainID int
2026-02-10 11:32:49 -08:00
}
2026-05-22 21:55:42 -07:00
// NewWalletConnect creates a WalletConnect handler using deployment env vars.
func NewWalletConnect ( chainID int ) * WalletConnect {
projectID := strings . TrimSpace ( os . Getenv ( "WALLETCONNECT_PROJECT_ID" ) )
relayURL := strings . TrimSpace ( os . Getenv ( "WALLETCONNECT_RELAY_URL" ) )
if relayURL == "" {
relayURL = "wss://relay.walletconnect.org"
}
return & WalletConnect {
projectID : projectID ,
relayURL : relayURL ,
chainID : chainID ,
}
2026-02-10 11:32:49 -08:00
}
2026-05-22 21:55:42 -07:00
func ( wc * WalletConnect ) enabled ( ) bool {
return wc . projectID != ""
2026-02-10 11:32:49 -08:00
}
2026-05-22 21:55:42 -07:00
// PublicConfig returns the read-only WalletConnect config surface for clients.
func ( wc * WalletConnect ) PublicConfig ( ) Config {
status := WalletConnectStatusStub
if ! wc . enabled ( ) {
status = WalletConnectStatusDisabled
}
return Config {
Status : status ,
Enabled : wc . enabled ( ) ,
ProjectID : wc . projectID ,
RelayURL : wc . relayURL ,
MetadataURL : "/api/v1/walletconnect/metadata" ,
RequiredNamespaces : [ ] string { "eip155" } ,
SupportedChains : [ ] int { wc . chainID , 1 } ,
FallbackAuth : "/api/v1/auth/wallet" ,
Message : wc . publicMessage ( ) ,
UpdatedAt : time . Now ( ) . UTC ( ) . Format ( time . RFC3339 ) ,
}
2026-02-10 11:32:49 -08:00
}
2026-05-22 21:55:42 -07:00
func ( wc * WalletConnect ) publicMessage ( ) string {
if wc . enabled ( ) {
return "WalletConnect v2 config is published, but session bridging is still stubbed. Use browser wallet auth at /api/v1/auth/wallet until mobile QR sessions ship."
}
return "WalletConnect v2 is not configured. Set WALLETCONNECT_PROJECT_ID to publish relay config; browser wallet auth remains available at /api/v1/auth/wallet."
2026-02-10 11:32:49 -08:00
}
2026-05-22 21:55:42 -07:00
// Connect initiates a wallet connection. Live QR sessions are not implemented yet.
func ( wc * WalletConnect ) Connect ( _ context . Context ) ( * ConnectResponse , error ) {
return & ConnectResponse {
Status : WalletConnectStatusStub ,
Enabled : wc . enabled ( ) ,
FallbackAuth : "/api/v1/auth/wallet" ,
Message : "WalletConnect session creation is stubbed. Use browser extension wallet auth until the relay bridge is enabled." ,
} , fmt . Errorf ( "walletconnect session bridge not implemented" )
}
// GetSession gets a wallet session snapshot. Storage is not implemented yet.
func ( wc * WalletConnect ) GetSession ( _ context . Context , sessionID string ) ( * Session , error ) {
if strings . TrimSpace ( sessionID ) == "" {
return nil , fmt . Errorf ( "session id is required" )
}
return & Session {
SessionID : sessionID ,
Connected : false ,
Status : WalletConnectStatusStub ,
Message : "WalletConnect session lookup is stubbed." ,
} , fmt . Errorf ( "walletconnect session storage not implemented" )
}