Skip to content

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

  1. Run inside MiniPay: Your app expects window.ethereum; show a clear message or use getEthereumProvider() to throw if it's missing.
  2. Always auto-connect: Never show a connect button; connect on page load.
  3. Handle errors gracefully: Show user-friendly messages for connection failures.
  4. Check provider availability: Verify window.ethereum exists (and optionally isMiniPay) before connecting.
  5. Provide loading states: Show "Connecting to MiniPay..." while connecting.

Common issues

  • Provider not found: If window.ethereum is undefined, the app is not in MiniPay. Show a message or redirect; see getEthereumProvider() above.
  • Connection rejected: With auto-connect this is rare. If you see an error, check error.code === -32604 or error.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