diff --git a/.env.example b/.env.example index 1f2b5ba..39ee34e 100644 --- a/.env.example +++ b/.env.example @@ -22,6 +22,8 @@ EXPO_PUBLIC_APP_ENV=development # ─── WalletConnect (optional) ────────────────────────────────────────────── # Get a project ID at https://cloud.walletconnect.com +# Required for Native Wallet Integration (MetaMask, Trust Wallet, etc.) +# Connected wallets can be cryptographically verified via signature. # EXPO_PUBLIC_WALLET_CONNECT_PROJECT_ID= # ─── Embedded Wallets — Privy (optional) ────────────────────────────── diff --git a/.maestro/07-walletconnect-flow.yaml b/.maestro/07-walletconnect-flow.yaml index 7df0d6c..8203b54 100644 --- a/.maestro/07-walletconnect-flow.yaml +++ b/.maestro/07-walletconnect-flow.yaml @@ -56,6 +56,8 @@ appId: xyz.guildpass.mobile id: "connected-wallet-address" - assertVisible: text: "Manual Entry" +- assertVisible: + text: "Unverified" # ── Step 7: Navigate to guilds and back ──────────────────────────────── - tapOn: diff --git a/app/profile.tsx b/app/profile.tsx index 5b8559b..98dd547 100644 --- a/app/profile.tsx +++ b/app/profile.tsx @@ -25,13 +25,25 @@ const CONNECTION_LABELS: Record = { export default function Profile() { const router = useRouter(); - const { walletAddress, isConnected, connectionKind, connectManually, disconnect } = useWallet(); + const { walletAddress, isConnected, connectionKind, isVerified, verifyOwnership, connectManually, disconnect } = useWallet(); const { open } = useWalletConnectModal(); const { isOffline } = useNetworkStatus(); const [inputValue, setInputValue] = useState(walletAddress || ""); const [error, setError] = useState(null); const [showManualEntry, setShowManualEntry] = useState(false); const [wcConnecting, setWcConnecting] = useState(false); + const [isVerifying, setIsVerifying] = useState(false); + const [verifyError, setVerifyError] = useState(null); + + const handleVerifyOwnership = async () => { + setIsVerifying(true); + setVerifyError(null); + const { success, error } = await verifyOwnership(); + if (!success) { + setVerifyError(error || "Verification failed"); + } + setIsVerifying(false); + }; // ── Field-level validation state ──────────────────────────────────── const [fieldError, setFieldError] = useState(null); @@ -235,9 +247,41 @@ export default function Profile() { {walletAddress ? ( - + + + {isVerified ? ( + + ✓ Verified + + ) : connectionKind === "manual" ? ( + + Unverified + + ) : null} + ) : null} + + {!isVerified && connectionKind !== "manual" ? ( + + + Verify Ownership + + + Sign a message to verify you control this wallet and unlock full access. + + {verifyError ? ( + {verifyError} + ) : null} +