Appearance
Wallet Connection
This guide covers wallet connection patterns for MiniPay Mini Apps: auto-connect, connection state, and error handling. Mini Apps are designed to run inside MiniPay; the wallet connection must happen automatically on page load — never show a "Connect wallet" button. Do not prompt users to sign a message to access your site or authenticate; connection is automatic.
Run inside MiniPay
MiniPay injects window.ethereum when it loads your app. If the provider is missing, your app is not running in MiniPay. Check before connecting:
tsx
function getEthereumProvider() {
if (typeof window === "undefined" || !window.ethereum) {
throw new Error(
"window.ethereum is required. Please run this app inside MiniPay."
);
}
return window.ethereum;
}
// Optional: detect MiniPay specifically
if (window.ethereum?.isMiniPay) {
console.log("Running in MiniPay");
}Use this in a custom Wagmi transport or when creating a public client. See Project setup for a full config.
Auto-connect
MiniPay requires that Mini Apps automatically connect to the wallet when the page loads. Never show a connect button. Use a single hook that connects on mount and tracks loading/error:
tsx
import { useEffect, useState } from "react";
import { useConnect, useConnectors } from "wagmi";
export function useAutoConnect() {
const connectors = useConnectors();
const { connect, error, isPending } = useConnect();
const [hasAttempted, setHasAttempted] = useState(false);
useEffect(() => {
if (hasAttempted || connectors.length === 0) return;
const attemptConnect = async () => {
try {
await connect({ connector: connectors[0] });
} catch (err) {
console.error("Failed to connect:", err);
}
setHasAttempted(true);
};
attemptConnect();
}, [connectors, connect, hasAttempted]);
return { error, isPending };
}Detecting MiniPay
Check window.ethereum?.isMiniPay === true to detect MiniPay. Use this only if you need to branch behavior; most apps just require window.ethereum and auto-connect.
Connection state
Use Wagmi v3's useConnection() to track address, chainId, isConnected, isConnecting, and error:
tsx
import { useConnection } from "wagmi";
function WalletStatus() {
const { address, isConnected, isConnecting, chainId, error } = useConnection();
if (isConnecting) return <div>Connecting to MiniPay...</div>;
if (!isConnected || !address) {
return (
<div>
<p>Not connected. Run this app inside MiniPay.</p>
{error && <p>Error: {error.message}</p>}
</div>
);
}
return (
<div>
<p>Connected: {address}</p>
<p>Chain ID: {chainId}</p>
</div>
);
}Error handling
Show "Not connected" when there is no address; show a user-friendly message when useConnection().error or useConnect().error is set (e.g. "Open this app from MiniPay" or "Connection failed. Unlock MiniPay and try again."). Prefer error codes or standard error names over message text. For patterns and examples, see Best practices — Error handling.
Best practices
- Run inside MiniPay: Your app expects
window.ethereum; show a clear message or usegetEthereumProvider()to throw if it's missing. - Always auto-connect: Never show a connect button; connect on page load.
- Handle errors gracefully: Show user-friendly messages for connection failures.
- Check provider availability: Verify
window.ethereumexists (and optionallyisMiniPay) before connecting. - Provide loading states: Show "Connecting to MiniPay..." while connecting.
Common issues
- Provider not found: If
window.ethereumis undefined, the app is not in MiniPay. Show a message or redirect; seegetEthereumProvider()above. - Connection rejected: With auto-connect this is rare. If you see an error, check
error.code === -32604orerror.name === "UserRejectedRequestError"and show "Transaction cancelled" or similar. - Multiple connection attempts: Use a
hasAttempted(or similar) flag so the auto-connect effect runs only once.
Next Steps
- Learn about retrieving balances
- See how to send transactions
- Check out best practices for wallet interactions