diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx
index 50ce820f..e05e2e4c 100644
--- a/src/AppRouter.tsx
+++ b/src/AppRouter.tsx
@@ -10,6 +10,7 @@ import { SettingsPage } from "./pages/SettingsPage";
import { HashtagPage } from "./pages/HashtagPage";
import { BookmarksPage } from "./pages/BookmarksPage";
import { PlaceholderPage } from "./pages/PlaceholderPage";
+import { WalletPage } from "./pages/WalletPage";
import { KindFeedPage } from "./pages/KindFeedPage";
import NotFound from "./pages/NotFound";
@@ -30,10 +31,10 @@ export function AppRouter() {
} />
} />
} />
- } />
+ } />
} />
} />
- } />
+
{/* NIP-19 route for npub1, note1, naddr1, nevent1, nprofile1 */}
} />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
diff --git a/src/components/MobileDrawer.tsx b/src/components/MobileDrawer.tsx
index b1384473..73c706be 100644
--- a/src/components/MobileDrawer.tsx
+++ b/src/components/MobileDrawer.tsx
@@ -1,5 +1,5 @@
import { Link, useNavigate } from 'react-router-dom';
-import { User, Wallet, Bookmark, EyeOff, Settings, ShieldBan, LogOut, ChevronDown, ChevronUp } from 'lucide-react';
+import { User, Wallet, Bookmark, EyeOff, Settings, LogOut, ChevronDown, ChevronUp } from 'lucide-react';
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
import { Sheet, SheetContent, SheetTitle } from '@/components/ui/sheet';
import { Separator } from '@/components/ui/separator';
@@ -109,12 +109,6 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) {
label="Preferences"
onClick={handleClose}
/>
- }
- label="Domain blocks"
- onClick={handleClose}
- />
-
+ {otherUsers.length > 0 && (
+ <>
+
- {/* Switch accounts section */}
-
-
+ {/* Switch accounts section */}
+
+
- {showAccountSwitcher && otherUsers.length > 0 && (
-
- {otherUsers.map((account) => (
-
- ))}
+ {showAccountSwitcher && (
+
+ {otherUsers.map((account) => (
+
+ ))}
+
+ )}
- )}
-
+ >
+ )}
) : (
diff --git a/src/pages/WalletPage.tsx b/src/pages/WalletPage.tsx
new file mode 100644
index 00000000..204ca7f4
--- /dev/null
+++ b/src/pages/WalletPage.tsx
@@ -0,0 +1,289 @@
+import { useState } from 'react';
+import { useSeoMeta } from '@unhead/react';
+import { ArrowLeft, Wallet, Plus, Trash2, Zap, Globe, WalletMinimal, CheckCircle } from 'lucide-react';
+import { Link } from 'react-router-dom';
+import { MainLayout } from '@/components/MainLayout';
+import { Button } from '@/components/ui/button';
+import { Input } from '@/components/ui/input';
+import { Label } from '@/components/ui/label';
+import { Textarea } from '@/components/ui/textarea';
+import { Badge } from '@/components/ui/badge';
+import { Separator } from '@/components/ui/separator';
+import { Card, CardContent } from '@/components/ui/card';
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from '@/components/ui/dialog';
+import { useNWC } from '@/hooks/useNWCContext';
+import { useWallet } from '@/hooks/useWallet';
+import { useToast } from '@/hooks/useToast';
+import { useCurrentUser } from '@/hooks/useCurrentUser';
+
+export function WalletPage() {
+ const [addDialogOpen, setAddDialogOpen] = useState(false);
+ const [connectionUri, setConnectionUri] = useState('');
+ const [alias, setAlias] = useState('');
+ const [isConnecting, setIsConnecting] = useState(false);
+
+ const { user } = useCurrentUser();
+ const {
+ connections,
+ activeConnection,
+ connectionInfo,
+ addConnection,
+ removeConnection,
+ setActiveConnection,
+ } = useNWC();
+ const { webln } = useWallet();
+ const hasNWC = connections.length > 0 && connections.some(c => c.isConnected);
+ const { toast } = useToast();
+
+ useSeoMeta({
+ title: 'Wallet | Mew',
+ description: 'Manage your Lightning wallet connections',
+ });
+
+ const handleAddConnection = async () => {
+ if (!connectionUri.trim()) {
+ toast({
+ title: 'Connection URI required',
+ description: 'Please enter a valid NWC connection URI.',
+ variant: 'destructive',
+ });
+ return;
+ }
+
+ setIsConnecting(true);
+ try {
+ const success = await addConnection(connectionUri.trim(), alias.trim() || undefined);
+ if (success) {
+ setConnectionUri('');
+ setAlias('');
+ setAddDialogOpen(false);
+ }
+ } finally {
+ setIsConnecting(false);
+ }
+ };
+
+ const handleRemoveConnection = (connectionString: string) => {
+ removeConnection(connectionString);
+ };
+
+ const handleSetActive = (connectionString: string) => {
+ setActiveConnection(connectionString);
+ toast({
+ title: 'Active wallet changed',
+ description: 'The selected wallet is now active for zaps.',
+ });
+ };
+
+ return (
+
+
+ {/* Sticky header */}
+
+
+ {!user ? (
+
+
+
Log in to manage your wallet
+
Connect a Lightning wallet to send zaps on Nostr.
+
+ ) : (
+
+ {/* Connection status cards */}
+
+
Status
+
+ {/* WebLN */}
+
+
+
+
+
+
+
+
WebLN
+
Browser extension
+
+
+
+ {webln && }
+
+ {webln ? 'Ready' : 'Not Found'}
+
+
+
+
+
+ {/* NWC */}
+
+
+
+
+
+
+
+
Nostr Wallet Connect
+
+ {connections.length > 0
+ ? `${connections.length} wallet${connections.length !== 1 ? 's' : ''} connected`
+ : 'Remote wallet connection'}
+
+
+
+
+ {hasNWC && }
+
+ {hasNWC ? 'Ready' : 'None'}
+
+
+
+
+
+
+
+
+
+ {/* NWC Wallets */}
+
+
+
Nostr Wallet Connect
+
+
+
+ {connections.length === 0 ? (
+
+
+
+ No wallets connected
+ Add an NWC connection to enable instant zaps.
+
+
+ ) : (
+
+ {connections.map((connection) => {
+ const info = connectionInfo[connection.connectionString];
+ const isActive = activeConnection === connection.connectionString;
+ return (
+
+
+
+
+
+
+
+
+ {connection.alias || info?.alias || 'Lightning Wallet'}
+
+
+ {isActive ? 'Active' : 'NWC Connection'}
+
+
+
+
+ {isActive && }
+ {!isActive && (
+
+ )}
+
+
+
+
+ );
+ })}
+
+ )}
+
+
+ {/* Help text */}
+ {!webln && connections.length === 0 && (
+ <>
+
+
+
+ Install a WebLN browser extension or connect a NWC wallet to send zaps.
+
+
+ >
+ )}
+
+ )}
+
+
+ {/* Add wallet dialog */}
+
+
+ );
+}