Superbridge
Start typing to search...
You need a Rollie to use the Superbridge Widget.

Guides

Wallets

Let the widget handle wallet connections, or bring your own

The widget supports EVM, Solana and Starknet. Which of them are in play comes from your Rollie's chains — if it has no Starknet chains there is no Starknet wallet UI, and if it has them your users need to be able to connect one. That isn't something you configure.

What you configure is, per ecosystem, whether your app handles wallets or the widget does.

Three ways this goes

Your appYour RollieWhat you pass
No wallet librariesEVMwalletConfig — your WalletConnect project and app identity.
No wallet librariesSolana or Starknet onlyNothing.
Already uses wagmiEVM + SolanawalletControl.evm. The widget still handles Solana completely, and with no config.

The widget handles it

The widget sets up wallet providers and renders its own wallet picker for every ecosystem your Rollie supports.

  • EVM — a minimal wagmi config. Discovers installed wallets via EIP-6963, and adds WalletConnect if you give it a project id.
  • Solana — its own ConnectionProvider and WalletProvider.
  • Starknet — a StarknetConfig with Braavos and Argent connectors.

For EVM there are two things the widget can't know, so you pass them in walletConfig:

<Widget
  walletConfig={{
    walletConnectProjectId: "your-project-id",
    app: {
      name: "My App",
      description: "Bridge assets to My Chain",
      iconUrl: "https://myapp.xyz/icon.png",
    },
  }}
/>

walletConnectProjectId — a WalletConnect project belongs to the app that uses it, not to your Rollie, so this has to be yours. Leave it out and the widget builds no WalletConnect connector at all: users can connect an injected wallet (and Base Account, on chains that support it) but have no QR or mobile pairing option. The widget logs a warning to that effect in development.

app — the identity users see in their wallet when they approve a connection. Leave it out and that prompt has no name, description or icon.

Neither is inherited from your Rollie. The widget's own request fetches chains, and nothing else — so a plain <Widget /> connects injected wallets and shows a nameless approval prompt. Whether that's acceptable is your call; passing walletConfig is what makes it not.

There is deliberately no app.url. WalletConnect verifies the domain a session comes from, so the connector always reports the live origin rather than a value you could get wrong.

Your app handles it

If your app already has a wallet stack — Privy, Dynamic, RainbowKit, AppKit, or plain wagmi — mount it anywhere above the widget and list the ecosystems it covers.

import { useDynamicContext } from "@dynamic-labs/sdk-react-core";
import { Widget } from "@superbridge/widget";

function Bridge() {
  const { setShowAuthFlow } = useDynamicContext();

  return (
    <Widget
      walletControl={{
        evm: {
          connect: () => setShowAuthFlow(true),
          disconnect: () => myWallet.disconnect(),
        },
      }}
    />
  );
}

function App() {
  return (
    <DynamicContextProvider settings={dynamicSettings}>
      <WagmiProvider config={wagmiConfig}>
        <DynamicWagmiConnector>
          <Bridge />
        </DynamicWagmiConnector>
      </WagmiProvider>
    </DynamicContextProvider>
  );
}
interface HostWallet {
  connect: () => void | Promise<void>;
  disconnect?: () => void | Promise<void>;
}

type WalletControl = Partial<Record<"evm" | "svm" | "stark", HostWallet>>;

Listing an ecosystem means two things:

  • The widget shows no account chip for it — yours already displays the account.
  • The widget calls your connect whenever it needs a wallet.

connect is required. Either your app drives the flow or the widget does; there's no in-between.

Whose provider gets used is a separate question, and it's automatic — see below.

Ecosystems you don't list

You only list what your wallet stack covers. In the example above, a Rollie with Solana chains gets the widget's own Solana provider, picker and account chip — untouched by the fact that you handle EVM.

walletConfig configures connectors, so what matters for it is whether the widget is the one installing them — not what you listed in walletControl. Only EVM reads it. Mount your own WagmiProvider and the widget builds no EVM connectors, so nothing in walletConfig is used; leave EVM to the widget and it applies even if you took the account chip with walletControl.evm. Solana and Starknet need no configuration either way.

Wallet providers

You never configure this. If a provider for an ecosystem is mounted above <Widget />, the widget uses it. If not, it installs its own. Two wagmi instances in one tree would mean two independent connections, so the widget never adds a second.

This is independent of walletControl. Listing an ecosystem says your app owns the UI; it says nothing about who set up the provider. The combinations all work:

Your appWhat the widget does
No providers, no walletControlInstalls providers, renders account chips, opens its own picker
WagmiProvider + walletControl.evmUses your wagmi, no EVM account chip, calls your connect
WagmiProvider, no walletControlUses your wagmi, renders its own account chip and picker

Listing an ecosystem in walletControl means your app shows the account and drives the connect flow, so in practice you list what your own wallet stack covers.

The widget's own wallet UI is two things: a "Connect wallet" button under the amount input while a wallet is needed and none is connected, and an account chip in the widget header once one is — showing which wallet, and opening the picker to switch or disconnect. The chip never asks you to connect; the form button is the only connect CTA.

If a provider is mounted but the widget behaves as though it isn't, your app and the widget are resolving two different copies of the library. Deduplicate to a single version with npm overrides or pnpm's pnpm.overrides; on Vite, resolve.dedupe fixes the resolution side of it. See Integration.