# Connect external wallets

> How to connect external wallets on EVM and Solana

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

# Overview

Connectors let users authenticate with existing **external wallets**. Both **EVM** (e.g., MetaMask, Coinbase, WalletConnect) and **Solana** (e.g., Phantom) wallets are supported via UI components or custom UI, and can be surfaced together in your auth modal.

* EVM EOAs behave as regular wallets (no smart wallet features like sponsorship).
* You can optionally use an EVM EOA as a smart wallet owner to unlock smart wallet features like sponsorship and batching.
* Solana wallets are external wallets; you can enable sponsored gas with a policy.

## Pre-built UI connectors

* Auto-detect browser installed wallet extensions.
* Optionally add WalletConnect for other EVM wallets.
* Configure once with `configForExternalWallets()` and pass into the UI components using `createConfig()`.

You can fully customize wallet connector UI to define features wallets, ordering, and more. See how [here](/docs/wallets/react/connectors/customization).

### Detect and display EVM + Solana wallets

Use the helper to generate EVM connectors, Solana adapters, and UI customization in one place. Add to UI components by updating your `createConfig`.

```ts twoslash [src/config.ts]
// @noErrors
import {
  createConfig,
  cookieStorage,
  configForExternalWallets,
} from "@account-kit/react";
import { alchemy, sepolia } from "@account-kit/infra";
import { Connection } from "@solana/web3.js";

// Keep external wallets settings in one place
export const externalWalletsConfig = configForExternalWallets({
  // Preferred order (case-insensitive). Use "wallet_connect" for WalletConnect.
  wallets: ["wallet_connect", "phantom", "metamask", "coinbase wallet"],
  // Surface both EVM and Solana wallets (filter to ["evm"] or ["svm"] if desired)
  chainType: ["svm", "evm"],
  // EVM-only WalletConnect support (omit to disable)
  walletConnectProjectId: "your-project-id",
  // Controls the built-in Featured section
  hideMoreButton: false,
  numFeaturedWallets: 4,
});

export const config = createConfig(
  {
    transport: alchemy({ apiKey: "your_api_key" }),
    chain: sepolia,
    ssr: true,
    storage: cookieStorage,
    enablePopupOauth: true,
    sessionConfig: {
      expirationTimeMs: 1000 * 60 * 60, // 60 minutes (default is 15 min)
    },
    /**
     * External wallets (EVM + Solana)
     */
    connectors: externalWalletsConfig.connectors,
    solana: {
      connection: new Connection(
        `https://solana-devnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_API_KEY}`,
      ),
      adapters: externalWalletsConfig.adapters,
      // optional gas sponsor for Solana
      policyId: process.env.NEXT_PUBLIC_SOLANA_POLICY_ID,
    },
  },
  {
    // Authentication ui config - your customizations here
    auth: {
      sections: [
        [{ type: "email" }],
        [
          { type: "passkey" },
          { type: "social", authProviderId: "google", mode: "popup" },
          { type: "social", authProviderId: "facebook", mode: "popup" },
        ],
        [{ type: "external_wallets", ...externalWalletsConfig.uiConfig }],
      ],
      addPasskeyOnSignup: true,
      showSignInText: true,
    },
  },
);
```

If you don't need customization, you can manually pass EVM `connectors` and Solana `adapters` directly into `createConfig()` without using the helper.

### Wallet connect

If you want to access other EVM providers via `WalletConnect`, provide a WalletConnect Project ID in your external wallets config. You can create a WalletConnect project ID [here](https://cloud.reown.com/sign-in).

```ts twoslash
// @noErrors
export const externalWalletsConfig = configForExternalWallets({
  wallets: ["wallet_connect", "metamask", "phantom"],
  chainType: ["evm", "svm"],
  walletConnectProjectId: "your-project-id",
});
```

## Custom connectors

If you don't want to use pre-built UI components, you can use React hooks to customize your EOA connection.

### EVM connectors

Use the [useConnect](https://www.alchemy.com/docs/wallets/reference/account-kit/react/hooks/useConnect) hook to allow users to connect their EOA via available connectors:

```tsx twoslash
// @noErrors
import { useConnect } from "@account-kit/react";

const { connectors, connect } = useConnect({
  onSuccess: (data) => {
    console.log("Connected!", data);
  },
  onError: (err) => {
    console.error("Connection failed", err);
  },
});

return (
  <div>
    {connectors.map((connector) => (
      <button key={connector.id} onClick={() => connect({ connector })}>
        Connect with {connector.name}
      </button>
    ))}
  </div>
);
```

### Programmatic login with a Solana adapter

Use the Solana wallet hook to select a specific adapter without showing the modal:

```ts twoslash
// @noErrors
import { useSolanaWallet } from "@account-kit/react";

const { select, wallets } = useSolanaWallet();
const phantom = wallets.find((w) => w.name.toLowerCase() === "phantom");

if (phantom) {
  await select(phantom.adapter.name);
}
```

## Bring in an EOA as a smart wallet owner

For local wallets or JSON-RPC wallets that support the [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) standard (like MetaMask, Coinbase Wallet, etc.), you can use `WalletClientSigner` from `@aa-sdk/core` to bring in these EOAs as your smart wallet owner. More info [here](https://www.alchemy.com/docs/wallets/third-party/signers/privy).
By making your EOA an owner of a smart wallet, you gain access to smart wallet features.

```ts twoslash
// @noErrors
import { WalletClientSigner, type SmartAccountSigner } from "@aa-sdk/core";
import { createWalletClient, custom } from "viem";
import { sepolia } from "viem/chains";
import { createModularAccountV2 } from "@account-kit/smart-contracts";

const externalProvider = window.ethereum; // or another EIP-1193 provider

const walletClient = createWalletClient({
  chain: sepolia,
  transport: custom(externalProvider),
});

export const signer: SmartAccountSigner = new WalletClientSigner(
  walletClient,
  "json-rpc",
);

// Connect your signer to your smart account

const account = await createModularAccountV2({
  chain: sepolia,
  transport: alchemyTransport,
  signer: signer, // your EOA that you've brought in as an owner
});
```