diff --git a/frontend/src/components/wallet/WalletModal.tsx b/frontend/src/components/wallet/WalletModal.tsx index 894e372b..60f727ac 100644 --- a/frontend/src/components/wallet/WalletModal.tsx +++ b/frontend/src/components/wallet/WalletModal.tsx @@ -3,12 +3,13 @@ /** * components/wallet/WalletModal.tsx * - * Wallet selection modal. Shows three wallet cards (Freighter, Albedo, xBull) - * and handles all connecting states and error display. + * Wallet selection modal. Shows the production-ready Freighter connector and + * handles all connecting states and error display. + * + * Albedo and xBull are intentionally hidden until real connectors are + * implemented; the production picker must never create mock sessions. * * - Freighter: shows "Install Freighter" link when extension is absent. - * - Albedo: note that a popup window will open. - * - xBull: note for mobile / extension users. * - Dismiss via Escape key or backdrop click. */ @@ -22,14 +23,15 @@ interface WalletModalProps { onClose: () => void; } -const WALLET_NOTES: Partial> = { - albedo: "A popup window will open for authentication.", - xbull: "Available as browser extension or mobile app.", -}; - export function WalletModal({ onClose }: WalletModalProps) { - const { wallets, status, selectedWalletId, errorMessage, connect, clearError } = - useWallet(); + const { + wallets, + status, + selectedWalletId, + errorMessage, + connect, + clearError, + } = useWallet(); const isConnecting = status === "connecting"; const [freighterInstalled, setFreighterInstalled] = React.useState(true); @@ -123,11 +125,7 @@ export function WalletModal({ onClose }: WalletModalProps) { {errorMessage && (
{errorMessage} -
@@ -140,8 +138,6 @@ export function WalletModal({ onClose }: WalletModalProps) { const isConnectingThis = isConnecting && isActiveWallet; const isFreighter = wallet.id === "freighter"; const notInstalled = isFreighter && !freighterInstalled; - const note = WALLET_NOTES[wallet.id]; - return (
{wallet.badge}

{wallet.description}

- {note && !notInstalled && ( -

{note}

- )} - {notInstalled ? ( {isConnecting ? "Waiting for wallet approval…" - : "Supported wallets: Freighter, Albedo, xBull"} + : `Supported wallets: ${wallets.map((wallet) => wallet.name).join(", ")}`}

diff --git a/frontend/src/context/wallet-context.tsx b/frontend/src/context/wallet-context.tsx index f6d921ec..3538a7c9 100644 --- a/frontend/src/context/wallet-context.tsx +++ b/frontend/src/context/wallet-context.tsx @@ -35,7 +35,7 @@ interface WalletContextValue { // so stale persisted sessions are discarded rather than causing type errors. const STORAGE_KEY = "flowfi.wallet.session.v1"; const WalletContext = createContext(undefined); -const VALID_WALLET_IDS: WalletId[] = ["freighter", "albedo", "xbull"]; +const VALID_WALLET_IDS = SUPPORTED_WALLETS.map((wallet) => wallet.id); interface WalletState { status: WalletStatus; @@ -133,7 +133,7 @@ function isWalletSession(value: unknown): value is WalletSession { typeof session.publicKey === "string" && typeof session.connectedAt === "string" && typeof session.network === "string" && - typeof session.mocked === "boolean" + session.mocked === false ); } diff --git a/frontend/src/lib/wallet.ts b/frontend/src/lib/wallet.ts index d251349e..48b1f88b 100644 --- a/frontend/src/lib/wallet.ts +++ b/frontend/src/lib/wallet.ts @@ -2,19 +2,17 @@ * lib/wallet.ts * * Production wallet adapter for FlowFi. - * Supports Freighter (browser extension), Albedo (web auth popup), - * and xBull (extension / mobile handoff) via @creit.tech/stellar-wallets-kit. + * Currently supports Freighter (browser extension). * - * No mock sessions are created in production paths. + * Albedo and xBull are intentionally not advertised until real connectors are + * implemented. No mock sessions are created in production paths. * Set NEXT_PUBLIC_STELLAR_NETWORK=TESTNET|MAINNET in .env to control network. */ // ── Network configuration ───────────────────────────────────────────────────── -export const STELLAR_NETWORK = - (process.env.NEXT_PUBLIC_STELLAR_NETWORK ?? "TESTNET") as - | "TESTNET" - | "MAINNET"; +export const STELLAR_NETWORK = (process.env.NEXT_PUBLIC_STELLAR_NETWORK ?? + "TESTNET") as "TESTNET" | "MAINNET"; export const STELLAR_NETWORK_ID = STELLAR_NETWORK === "MAINNET" @@ -28,7 +26,7 @@ import { getNetworkDetails, } from "@stellar/freighter-api"; -export type WalletId = "freighter" | "albedo" | "xbull"; +export type WalletId = "freighter"; export interface WalletDescriptor { id: WalletId; @@ -71,18 +69,6 @@ export const SUPPORTED_WALLETS: readonly WalletDescriptor[] = [ badge: "Extension", description: "Direct browser wallet for Stellar accounts and Soroban apps.", }, - { - id: "albedo", - name: "Albedo", - badge: "Web", - description: "Connect via web authentication popup. No extension required.", - }, - { - id: "xbull", - name: "xBull", - badge: "Extension", - description: "Browser extension and mobile wallet for Stellar ecosystem.", - }, ]; // ── Internal helpers ────────────────────────────────────────────────────────── @@ -91,7 +77,6 @@ function buildSession( walletId: WalletId, publicKey: string, network: string, - mocked: boolean = false, ): WalletSession { const descriptor = SUPPORTED_WALLETS.find((w) => w.id === walletId); @@ -105,7 +90,7 @@ function buildSession( publicKey, connectedAt: new Date().toISOString(), network, - mocked, + mocked: false, }; } @@ -122,10 +107,14 @@ async function connectFreighter(): Promise { const { address, error: addressError } = await getAddress(); if (!address || addressError) { - throw new Error(addressError || "Freighter did not return a valid public key."); + throw new Error( + addressError || "Freighter did not return a valid public key.", + ); } - let networkId =STELLAR_NETWORK_ID.toLowerCase().includes("public") ? "Mainnet" : "Testnet"; + let networkId = STELLAR_NETWORK_ID.toLowerCase().includes("public") + ? "Mainnet" + : "Testnet"; try { const details = await getNetworkDetails(); @@ -146,48 +135,6 @@ async function connectFreighter(): Promise { return buildSession("freighter", address, networkId); } -// ── Albedo (Mock) ────────────────────────────────────────────────────────────── - -/** - * Mock connection for Albedo wallet. - * Simulates a connection with a delay to show loading state. - * In production, this would integrate with Albedo's web auth popup. - */ -async function connectAlbedo(): Promise { - // Simulate connection delay - await new Promise((resolve) => setTimeout(resolve, 1500)); - - // Generate a mock public key for demonstration - // In production, this would come from Albedo's authentication flow - // Stellar public keys are base32 encoded and 56 characters long, starting with G - const mockPublicKey = "G" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".substring(0, 55); - - const networkId = STELLAR_NETWORK === "MAINNET" ? "Mainnet" : "Testnet"; - - return buildSession("albedo", mockPublicKey, networkId, true); -} - -// ── xBull (Mock) ──────────────────────────────────────────────────────────────── - -/** - * Mock connection for xBull wallet. - * Simulates a connection with a delay to show loading state. - * In production, this would integrate with xBull extension or mobile handoff. - */ -async function connectXBull(): Promise { - // Simulate connection delay - await new Promise((resolve) => setTimeout(resolve, 1500)); - - // Generate a mock public key for demonstration - // In production, this would come from xBull's connection flow - // Stellar public keys are base32 encoded and 56 characters long, starting with G - const mockPublicKey = "G" + "ZYXWVUTSRQPONMLKJIHGFEDCBA234567".substring(0, 55); - - const networkId = STELLAR_NETWORK === "MAINNET" ? "Mainnet" : "Testnet"; - - return buildSession("xbull", mockPublicKey, networkId, true); -} - // ── Public connect dispatch ─────────────────────────────────────────────────── export async function connectWallet( @@ -196,10 +143,6 @@ export async function connectWallet( switch (walletId) { case "freighter": return connectFreighter(); - case "albedo": - return connectAlbedo(); - case "xbull": - return connectXBull(); default: throw new Error("Unsupported wallet selected."); }