Skip to content
Starknet Start

Wallets

Starknet Start does not need connector instances for browser wallets. StarknetConfig wraps GetStarknetProvider from @starknet-io/get-starknet-modal, which discovers the wallets injected in the page and exposes them to useConnect and to the premade connect UI.

Three StarknetConfig props control which wallets your users see:

  • recommendedWallets: wallets to suggest, including ones the user has not installed yet.
  • extraWallets: wallets that can't be discovered from the page, such as a wallet injected under a custom key.
  • store: a custom discovery store, to change how wallets are discovered.

Wallet discovery

Injected wallets are discovered automatically. You don't need to configure anything for wallets that use one of these mechanisms:

MechanismHow the wallet announces itself
Wallet StandardThe wallet registers through the wallet-standard:register-wallet event and implements the Starknet wallet features.
Legacy window objectsThe wallet injects a StarknetWindowObject (id, name, version, icon, request, on, off) on a window.starknet* key.
EIP-6963 (MetaMask Snap)MetaMask announces itself through EIP-6963 and is adapted to Starknet with the Starknet Snap.

Legacy injected wallets are wrapped in StarknetInjectedWallet so every wallet exposes the same Wallet Standard interface (WalletWithStarknetFeatures). If a wallet is found both ways, the Wallet Standard registration replaces the legacy one.

recommendedWallets takes wallet metadata (WalletInformation: id, name, icon and downloads links), not wallet instances. Recommended wallets that are not installed are listed as "unavailable" with their download links. Installed wallets are matched to their metadata by their Starknet wallet API id, wallet.features[StarknetWalletApi].id.

When the prop is omitted, every wallet known to get-starknet is recommended: Ready Wallet (formerly Argent X), Braavos, MetaMask, OKX Wallet and Keplr. Pass your own list to change the suggestions, or an empty array to show only installed wallets.

"use client";
import React from "react";
 
import { ,  } from "@starknet-io/get-starknet-core/wallets";
import {  } from "@starknetfoundation/starknet-start-chains";
import {  } from "@starknetfoundation/starknet-start-providers";
import {  } from "@starknetfoundation/starknet-start-react";
 
function ({  }: { : React. }) {
  return (
    < ={[]} ={()} ={[, ]}>
      {}
    </>
  );
}

@starknet-io/get-starknet-core/wallets exports readyWallet, braavos, metaMask, okxWallet, keplr and the full wallets list. To recommend another wallet, pass a WalletInformation object whose id equals the wallet's features[StarknetWalletApi].id. For a legacy injected wallet, that is the id of its window object. If the ids don't match, the modal lists the installed wallet and an unavailable recommendation as two separate entries.

Extra wallets

extraWallets takes Wallet Standard objects (WalletWithStarknetFeatures[]) and lists them alongside the discovered wallets. They are always shown as available and are returned by useConnect().connectors.

Keep extra wallets stable between renders (at module scope, in state or in a useMemo). Don't pass a wallet that discovery already finds, or it is listed twice.

Custom injected wallets

If a wallet injects a StarknetWindowObject that discovery doesn't pick up, wrap it with StarknetInjectedWallet and pass it to extraWallets. Read the window object after your app mounts: window is not defined during server-side rendering, and the wallet may inject itself after your bundle is evaluated.

"use client";
import React, { , ,  } from "react";
 
import {  } from "@starknet-io/get-starknet-core";
import {  } from "@starknetfoundation/starknet-start-chains";
import {  } from "@starknetfoundation/starknet-start-providers";
import {  } from "@starknetfoundation/starknet-start-react";
 
type  = <typeof >[0];
 
declare global {
  interface Window {
    ?: ;
  }
}
 
function () {
  const [, ] = <>();
 
  (() => {
    if (.) {
      (new (.));
    }
  }, []);
 
  return ;
}
 
export function ({  }: { : React. }) {
  const  = ();
  const  = (() => ( ? [] : []), []);
 
  return (
    < ={[]} ={()} ={}>
      {}
    </>
  );
}

Replace window.myWallet with the key your wallet injects. If the wallet injects itself after your app has mounted, run the check again when the wallet signals that it is ready.

If you are building a wallet, register it through the Wallet Standard. Dapps then discover it without extra configuration, whenever it loads.

Cartridge Controller

Install both the @cartridge/connector and @cartridge/controller packages.

pnpm i @cartridge/connector @cartridge/controller

Creating a ControllerConnector registers Controller through the Wallet Standard, so wallet discovery finds it like any other wallet. Create the connector once, at module scope, and don't pass controller.asWalletStandard() to extraWallets: Controller would be listed twice.

"use client";
import type React from "react";
 
import { ControllerConnector } from "@cartridge/connector";
import { mainnet, sepolia } from "@starknetfoundation/starknet-start-chains";
import { cartridgeProvider } from "@starknetfoundation/starknet-start-providers";
import { StarknetConfig } from "@starknetfoundation/starknet-start-react";
import { constants } from "starknet";
 
// Registers Controller with the Wallet Standard when created in the browser.
const controller = new ControllerConnector({
  chains: [
    {
      rpcUrl: "https://api.cartridge.gg/x/starknet/sepolia",
    },
    {
      rpcUrl: "https://api.cartridge.gg/x/starknet/mainnet",
    },
  ],
  defaultChainId: constants.StarknetChainId.SN_SEPOLIA,
});
 
export function AppProviders({ children }: { children: React.ReactNode }) {
  return (
    <StarknetConfig chains={[sepolia, mainnet]} provider={cartridgeProvider()} defaultChainId={sepolia.id}>
      {children}
    </StarknetConfig>
  );
}

The Controller enables seamless use of Session Keys. Pass session policies to the connector to enable them:

import { ControllerConnector } from "@cartridge/connector";
import { SessionPolicies } from "@cartridge/controller";
import { constants } from "starknet";
 
const policies: SessionPolicies = {
  contracts: {
    "0x3f96056436be253753351fe689110ced7d53f5db3fd98f13df3f19058311b95": {
      name: "Example Contract",
      description: "Example contract interaction",
      methods: [
        {
          name: "Create",
          description: "Create a new instance",
          entrypoint: "create",
        },
      ],
    },
  },
};
 
const controller = new ControllerConnector({
  chains: [
    {
      rpcUrl: "https://api.cartridge.gg/x/starknet/sepolia",
    },
    {
      rpcUrl: "https://api.cartridge.gg/x/starknet/mainnet",
    },
  ],
  defaultChainId: constants.StarknetChainId.SN_SEPOLIA,
  policies,
});

To change where Controller appears in the premade UI, use the sortAlgorithm prop of WalletConnectModal.

Custom discovery store

By default, all StarknetConfig instances share one discovery store. Pass your own store to change how wallets are discovered. For example, to stop offering MetaMask through the Starknet Snap, create a store without EIP-1193 adapters:

"use client";
import React from "react";
 
import {  } from "@starknet-io/get-starknet-core";
import {  } from "@starknetfoundation/starknet-start-chains";
import {  } from "@starknetfoundation/starknet-start-providers";
import {  } from "@starknetfoundation/starknet-start-react";
 
// Create the store once: it registers discovery listeners on `window`.
const  = ({ : [] });
 
function ({  }: { : React. }) {
  return (
    < ={[]} ={()} ={}>
      {}
    </>
  );
}

You may also want to drop metaMask from recommendedWallets so it is no longer suggested.

Connecting from your UI

Use WalletConnectModal from @starknet-io/get-starknet-ui for a ready-made connect button and wallet list; see the Connect Wallet UI demo.

To build your own list, useConnect returns the discovered and extra wallets as connectors:

"use client";
import React from "react";
 
import {  } from "@starknet-io/get-starknet-core";
import {  } from "@starknetfoundation/starknet-start-react";
 
function () {
  const { ,  } = ();
 
  return (
    <>
      {.(() => (
        < ={.[].} ={() => ({  })}>
          < ={.} ="" ={20} ={20} />
          Connect {.}
        </>
      ))}
    </>
  );
}

connectors only contains installed and extra wallets. Recommended wallets that are not installed are only listed by the premade UI.