Connect external wallets

Overview

Connectors let users authenticate with existing external wallets. We support both EVM (e.g., MetaMask, Coinbase, WalletConnect) and Solana (e.g., Phantom) wallets via UI components or custom UI. and can surface them 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.

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.

[src/config.ts]
1// @noErrors
2import {
3 createConfig,
4 cookieStorage,
5 configForExternalWallets,
6} from "@account-kit/react";
7import { alchemy, sepolia } from "@account-kit/infra";
8import { Connection } from "@solana/web3.js";
9
10// Keep external wallets settings in one place
11export const externalWalletsConfig = configForExternalWallets({
12 // Preferred order (case-insensitive). Use "wallet_connect" for WalletConnect.
13 wallets: ["wallet_connect", "phantom", "metamask", "coinbase wallet"],
14 // Surface both EVM and Solana wallets (filter to ["evm"] or ["svm"] if desired)
15 chainType: ["svm", "evm"],
16 // EVM-only WalletConnect support (omit to disable)
17 walletConnectProjectId: "your-project-id",
18 // Controls the built-in Featured section
19 hideMoreButton: false,
20 numFeaturedWallets: 4,
21});
22
23export const config = createConfig(
24 {
25 transport: alchemy({ apiKey: "your_api_key" }),
26 chain: sepolia,
27 ssr: true,
28 storage: cookieStorage,
29 enablePopupOauth: true,
30 sessionConfig: {
31 expirationTimeMs: 1000 * 60 * 60, // 60 minutes (default is 15 min)
32 },
33 /**
34 * External wallets (EVM + Solana)
35 */
36 connectors: externalWalletsConfig.connectors,
37 solana: {
38 connection: new Connection(
39 `https://solana-devnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_API_KEY}`,
40 ),
41 adapters: externalWalletsConfig.adapters,
42 // optional gas sponsor for Solana
43 policyId: process.env.NEXT_PUBLIC_SOLANA_POLICY_ID,
44 },
45 },
46 {
47 // Authentication ui config - your customizations here
48 auth: {
49 sections: [
50 [{ type: "email" }],
51 [
52 { type: "passkey" },
53 { type: "social", authProviderId: "google", mode: "popup" },
54 { type: "social", authProviderId: "facebook", mode: "popup" },
55 ],
56 [{ type: "external_wallets", ...externalWalletsConfig.uiConfig }],
57 ],
58 addPasskeyOnSignup: true,
59 showSignInText: true,
60 },
61 },
62);

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.

1// @noErrors
2export const externalWalletsConfig = configForExternalWallets({
3 wallets: ["wallet_connect", "metamask", "phantom"],
4 chainType: ["evm", "svm"],
5 walletConnectProjectId: "your-project-id",
6});

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 hook to allow users to connect their EOA via available connectors:

1// @noErrors
2import { useConnect } from "@account-kit/react";
3
4const { connectors, connect } = useConnect({
5 onSuccess: (data) => {
6 console.log("Connected!", data);
7 },
8 onError: (err) => {
9 console.error("Connection failed", err);
10 },
11});
12
13return (
14 <div>
15 {connectors.map((connector) => (
16 <button key={connector.id} onClick={() => connect({ connector })}>
17 Connect with {connector.name}
18 </button>
19 ))}
20 </div>
21);

Programmatic login with a Solana adapter

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

1// @noErrors
2import { useSolanaWallet } from "@account-kit/react";
3
4const { select, wallets } = useSolanaWallet();
5const phantom = wallets.find((w) => w.name.toLowerCase() === "phantom");
6
7if (phantom) {
8 await select(phantom.adapter.name);
9}

Bring in an EOA as a Smart Wallet Owner

For local wallets or JSON-RPC wallets that support the 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. By making your EOA an owner of a smart account, you will have access to AA feature through your new smart wallet.

1// @noErrors
2import { WalletClientSigner, type SmartAccountSigner } from "@aa-sdk/core";
3import { createWalletClient, custom } from "viem";
4import { sepolia } from "viem/chains";
5import { createModularAccountV2 } from "@account-kit/smart-contracts";
6
7const externalProvider = window.ethereum; // or another EIP-1193 provider
8
9const walletClient = createWalletClient({
10 chain: sepolia,
11 transport: custom(externalProvider),
12});
13
14export const signer: SmartAccountSigner = new WalletClientSigner(
15 walletClient,
16 "json-rpc",
17);
18
19// Connect your signer to your smart account
20
21const account = await createModularAccountV2({
22 chain: sepolia,
23 transport: alchemyTransport,
24 signer: signer, // your EOA that you've brought in as an owner
25});