Overview

The Embedded Wallet Kit provides a straightforward way to authenticate and use external wallets in your React application. The EWK offers abstractions to easily discover available wallet providers, connect to them, sign messages and transactions, switch chains, and use external wallets alongside embedded ones. This creates a seamless developer experience when switching between embedded and external wallets, with minimal changes required to your application logic.

Different uses cases of external wallets

External wallets can be used in two primary ways within your application:
1

Authentication

Use an external wallet to authenticate into a sub-organization. Under the hood the wallet acts as a stamper signing requests sent to Turnkey.
2

Connecting

Use an external wallet to sign alongside or instead of embedded wallets.Key functionality:
  • Connect to supported wallet providers
  • Sign messages using a connected wallet
  • Sign transactions using a connected wallet
  • Switch between EVM chains when multiple networks are supported
  • Disconnect a connected wallet

What is a WalletProvider?

Both authentication and external wallet connecting flows rely on a WalletProvider. A WalletProvider refers to an external wallet interface, such as a browser extension (e.g., MetaMask, Phantom) or a bridge like WalletConnect (if enabled). These providers act as the bridge between your app and the user’s wallet for signing, authentication, and transaction purposes. You can retrieve available wallet providers by calling the getWalletProviders(), which returns an array of WalletProvider instances available in the current environment.
const providers = await getWalletProviders();
If a provider is already connected, it will still appear in the result of getWalletProviders(). To determine whether it’s connected, you can inspect the provider.connectedAddresses property. This will list the currently connected addresses for that provider.
Note:
  • Each WalletProvider can only maintain one active connection per namespace (e.g., one Ethereum address and one Solana address at a time).
    • Example: if you connect a second Ethereum address in MetaMask, it will replace the currently connected one. The same applies for Solana.
  • If a provider supports multiple namespaces (e.g., MetaMask supports both Ethereum and Solana), it will appear as two separate providers in the result of getWalletProviders().
    • They may share the same display name (e.g., "MetaMask"), but they’ll have different chainInfo values and are treated independently in authentication and connection logic.
  • The duration of a connection depends on the provider’s behavior.
    • Most providers maintain a session until it is explicitly disconnected, either from your app or manually via the wallet UI (e.g., disconnecting in MetaMask).

What does the WalletProvider object look like?

Here’s an example of how WalletProvider objects are returned when both Ethereum, Solana, and WalletConnect are enabled.

Native Ethereum provider

{
  interfaceType: "ethereum",
  chainInfo: {
    namespace: "ethereum",
    chainId: "0x2105", // Ethereum Sepolia
  },
  info: {
    uuid: "9d549e1b-b0ee-42a9-883b-a8455e199637",
    name: "MetaMask",
    icon: "data:image/svg+xml;base64,...", // base64-encoded wallet icon
    rdns: "io.metamask",
  },
  provider: { ... }, // RPC provider injected by MetaMask
  connectedAddresses: [], // populated once user connects
}

Native Solana provider

{
  interfaceType: "solana",
  chainInfo: {
    namespace: "solana",
  },
  info: {
    name: "MetaMask",
    icon: "data:image/svg+xml;base64,...", // base64-encoded wallet icon
  },
  provider: { ... }, // RPC provider for Solana via MetaMask
  connectedAddresses: [], // populated once user connects
}

WalletConnect provider (Ethereum example)

{
  interfaceType: "wallet-connect",
  chainInfo: {
    namespace: "ethereum",
    chainId: "0x1", // Ethereum Mainnet
  },
  info: {
    name: "Rainbow",
    icon: "data:image/svg+xml;base64,...", // base64-encoded wallet icon
  },
  provider: { ... }, // RPC provider via WalletConnect
  connectedAddresses: [], // populated once user connects
}

Shared attributes

All providers, regardless of chain, include:
  • interfaceType – identifies where the provider came from:
    • “ethereum” → native EIP-1193 Ethereum provider (e.g., MetaMask, Rabby).
    • “solana” → native Wallet Standard Solana provider (e.g., Phantom, Backpack).
    • “wallet-connect” → WalletConnect provider.
  • chainInfo – the blockchain namespace, and optionally a chain ID.
  • info – metadata about the provider, such as name, icon, and (sometimes) uuid or rdns.
  • provider – the underlying RPC provider injected by the wallet.
  • connectedAddresses – an array of currently connected addresses (populated after the user connects).

Namespace-specific differences

  • Ethereum (namespace: "ethereum") - always includes a chainId in chainInfo (e.g., “0x1” for Mainnet, “0xaa36a7” for Sepolia).
  • Solana (namespace: "solana") - never includes a chainId, since Solana is a single-chain ecosystem.

Provider-specific differences

  • WalletConnect (interfaceType: "wallet_connect") - includes a uri property used for the session handshake.
  • Metadata (info) - Native Ethereum providers may expose extra fields like uuid and rdns, while Native Solana providers usually only include a name and icon.