Styling Connectors
External wallets (EVM + Solana)
Use configForExternalWallets() to specify external wallets you want to support, then add to your UI configuration. This allows you to feature wallets, merge EVM/Solana variants by name, and enable WalletConnect.
import {
const createConfig: (props: CreateConfigProps, ui?: AlchemyAccountsUIConfig) => AlchemyAccountsConfigWithUIWraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).
createConfig,
const cookieStorage: (config?: {
sessionLength?: number;
domain?: string;
}) => StorageFunction to create cookie based Storage
cookieStorage,
import configForExternalWalletsconfigForExternalWallets,
} from "@account-kit/react";
import { function alchemy(config: AlchemyTransportConfig): AlchemyTransportCreates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.
alchemy, const sepolia: Chainsepolia } from "@account-kit/infra";
import { import ConnectionConnection } from "@solana/web3.js";
export const const externalWalletsConfig: anyexternalWalletsConfig = import configForExternalWalletsconfigForExternalWallets({
// Preferred order (case-insensitive). Use "wallet_connect" for WalletConnect.
wallets: string[]wallets: ["wallet_connect", "phantom", "metamask", "coinbase wallet"],
// Which chains to surface (filter to ["evm"] or ["svm"] if needed)
chainType: string[]chainType: ["svm", "evm"],
// EVM-only
walletConnectProjectId: stringwalletConnectProjectId: "your-project-id",
// Built-in Featured section controls
hideMoreButton: booleanhideMoreButton: false,
numFeaturedWallets: numbernumFeaturedWallets: 4,
});
export const const config: AlchemyAccountsConfigWithUIconfig = function createConfig(props: CreateConfigProps, ui?: AlchemyAccountsUIConfig): AlchemyAccountsConfigWithUIWraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).
createConfig(
{
transport: AlchemyTransporttransport: function alchemy(config: AlchemyTransportConfig): AlchemyTransportCreates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.
alchemy({ apiKey: stringapiKey: "YOUR_API_KEY" }),
chain: Chainchain: const sepolia: Chainsepolia,
storage?: CreateStorageFn | undefinedstorage: const cookieStorage: (config?: {
sessionLength?: number;
domain?: string;
}) => StorageFunction to create cookie based Storage
cookieStorage,
solana: {
connection: any;
adapters: any;
policyId: string | undefined;
}solana: {
connection: Connectionconnection: new import ConnectionConnection(
`https://solana-devnet.g.alchemy.com/v2/${var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvThe process.env property returns an object containing the user environment. See environ(7).
An example of this object looks like:
jsTERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', USER: 'maciej', PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', PWD: '/Users/maciej', EDITOR: 'vim', SHLVL: '1', HOME: '/Users/maciej', LOGNAME: 'maciej', _: '/usr/local/bin/node'
It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:
bash node -e 'process.env.foo = "bar"' && echo $foo
While the following will:
env.foo = 'bar'; console.log(env.foo); ```
Assigning a property on `process.env` will implicitly convert the value to a string. **This behavior is deprecated.** Future versions of Node.js may throw an error when the value is not a string, number, or boolean.
```js import env from 'node:process';
env.test = null; console.log(env.test); // => 'null' env.test = undefined; console.log(env.test); // => 'undefined' ```
Use `delete` to delete a property from `process.env`.
```js import env from 'node:process';
env.TEST = 1; delete env.TEST; console.log(env.TEST); // => undefined ```
On Windows operating systems, environment variables are case-insensitive.
```js import env from 'node:process';
env.TEST = 1; console.log(env.test); // => 1 ```
Unless explicitly specified when creating a `Worker` instance, each `Worker` thread has its own copy of `process.env`, based on its parent thread's `process.env`, or whatever was specified as the `env` option to the `Worker` constructor. Changes to `process.env` will not be visible across `Worker` threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of `process.env` on a `Worker` instance operates in a case-sensitive manner unlike the main thread.
env.string | undefinedNEXT_PUBLIC_ALCHEMY_API_KEY}`,
),
adapters: anyadapters: const externalWalletsConfig: anyexternalWalletsConfig.anyadapters,
// optional
policyId?: string | undefinedpolicyId: var process: NodeJS.Processprocess.NodeJS.Process.env: NodeJS.ProcessEnvThe process.env property returns an object containing the user environment. See environ(7).
An example of this object looks like:
jsTERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', USER: 'maciej', PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', PWD: '/Users/maciej', EDITOR: 'vim', SHLVL: '1', HOME: '/Users/maciej', LOGNAME: 'maciej', _: '/usr/local/bin/node'
It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:
bash node -e 'process.env.foo = "bar"' && echo $foo
While the following will:
env.foo = 'bar'; console.log(env.foo); ```
Assigning a property on `process.env` will implicitly convert the value to a string. **This behavior is deprecated.** Future versions of Node.js may throw an error when the value is not a string, number, or boolean.
```js import env from 'node:process';
env.test = null; console.log(env.test); // => 'null' env.test = undefined; console.log(env.test); // => 'undefined' ```
Use `delete` to delete a property from `process.env`.
```js import env from 'node:process';
env.TEST = 1; delete env.TEST; console.log(env.TEST); // => undefined ```
On Windows operating systems, environment variables are case-insensitive.
```js import env from 'node:process';
env.TEST = 1; console.log(env.test); // => 1 ```
Unless explicitly specified when creating a `Worker` instance, each `Worker` thread has its own copy of `process.env`, based on its parent thread's `process.env`, or whatever was specified as the `env` option to the `Worker` constructor. Changes to `process.env` will not be visible across `Worker` threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of `process.env` on a `Worker` instance operates in a case-sensitive manner unlike the main thread.
env.string | undefinedNEXT_PUBLIC_SOLANA_POLICY_ID,
},
connectors?: CreateConnectorFn[] | undefinedconnectors: const externalWalletsConfig: anyexternalWalletsConfig.anyconnectors,
},
{
auth?: {
addPasskeyOnSignup?: boolean;
header?: React.ReactNode;
hideError?: boolean;
onAuthSuccess?: () => void;
sections: AuthType[][];
hideSignInText?: boolean;
} | undefinedauth: {
sections: AuthType[][]Each section can contain multiple auth types which will be grouped together and separated by an OR divider
sections: [
[{ type: "email"type: "email" }],
[
{ type: "passkey"type: "passkey" },
{ type: "social"type: "social", authProviderId: KnownAuthProviderauthProviderId: "google", mode: "popup"mode: "popup" },
],
[
// Spread the pre-configured UI for external wallets
{ type: "external_wallets"type: "external_wallets", ...const externalWalletsConfig: anyexternalWalletsConfig.anyuiConfig },
],
],
},
},
);You can still pass EVM connectors and Solana adapters directly into createConfig() without the helper.
How it behaves
How the external wallets UI behaves:
- Featured: uses your
walletsorder; EVM then Solana for the same name (counts once); capped bynumFeaturedWallets - All Wallets: same ordering; detected wallets not in
walletsare appended - Filtering: respects
chainType(e.g.,["svm"]hides EVM + WalletConnect) - WalletConnect: EVM‑only; shown when
walletConnectProjectIdis set andchainTypeincludes"evm"
Programmatic usage
Programmatic flows when you want to bypass the modal:
import { const useConnect: (params?: UseConnectParameters<Config>["mutation"]) => UseConnectReturnType<Config>Re-exported wagmi hook for connecting an EOA. This hook uses the internal wagmi config though so that the state is in sync with the rest of the Alchemy Account hook state. Useful if you wnat to connect to an EOA.
useConnect } from "@account-kit/react";
const { const connect: ConnectMutate<Config, unknown>connect, const connectors: readonly Connector<CreateConnectorFn>[]connectors } = function useConnect(params?: UseConnectParameters<Config>["mutation"]): UseConnectReturnType<Config>Re-exported wagmi hook for connecting an EOA. This hook uses the internal wagmi config though so that the state is in sync with the rest of the Alchemy Account hook state. Useful if you wnat to connect to an EOA.
useConnect();
const const metaMask: Connector<CreateConnectorFn> | undefinedmetaMask = const connectors: readonly Connector<CreateConnectorFn>[]connectors.ReadonlyArray<Connector<CreateConnectorFn>>.find(predicate: (value: Connector<CreateConnectorFn>, index: number, obj: readonly Connector<CreateConnectorFn>[]) => unknown, thisArg?: any): Connector<...> | undefined (+1 overload)Returns the value of the first element in the array where predicate is true, and undefined otherwise.
find((c: Connector<CreateConnectorFn>c) => c: Connector<CreateConnectorFn>c.id: stringid === "metaMask");
await const connect: <Connector<CreateConnectorFn>>(variables: ConnectVariables<Config, Connector<CreateConnectorFn>>, options?: {
...;
} | undefined) => voidconnect({ connector: CreateConnectorFn | Connector<CreateConnectorFn>connector: const metaMask: Connector<CreateConnectorFn> | undefinedmetaMask! });import { import useSolanaWalletuseSolanaWallet } from "@account-kit/react";
const { const select: anyselect, const wallets: anywallets } = import useSolanaWalletuseSolanaWallet();
const const phantom: anyphantom = const wallets: anywallets.anyfind((w: anyw) => w: anyw.anyname.anytoLowerCase() === "phantom");
if (const phantom: anyphantom) await const select: anyselect(const phantom: anyphantom.anyadapter.anyname);