The widget supports two wallet ownership models, controlled by the widgetMode config field.
| Mode | Who owns the wallet | When to use |
|---|
"standalone" (default) | The widget. Uses built-in wagmi connectors (injected wallets, WalletConnect, EIP-6963 discovery). | Standalone trading pages; landing pages; embeds where the host app has no wallet flow. |
"dapp" | The host app. Pass an EIP-1193 provider and handle Connect Wallet clicks yourself. | dApps that already have a wallet connection (wagmi, RainbowKit, Web3Modal, etc.). |
Standalone mode
In standalone mode the widget renders its own Connect Wallet button and handles the full connector flow using built-in wagmi connectors. No extra configuration needed.
<Widget config={{ widgetMode: "standalone" }} /> // default; can be omitted
Optional: add Privy as a connector
If you want Privy in the connector list (alongside the built-in connectors), pass privyAppId. Privy is not required; the widget works without it.
<Widget
config={{
privyAppId: "clxxx...xxx",
privyClientId: "client_xxx...xxx", // optional, only takes effect with privyAppId
}}
/>
dApp mode: bring your own provider
Set widgetMode: "dapp" and pass an EIP-1193 provider. Your host app is responsible for connecting the wallet.
<Widget
config={{ widgetMode: "dapp" }}
provider={window.ethereum}
events={{
onConnectWalletClick: () => {
// open your host app's wallet modal
openConnectModal();
},
}}
/>
The provider prop
Must satisfy EIP1193ProviderLax. This is a looser version of viem’s EIP1193Provider, since many third-party wallets don’t satisfy viem’s strict signature:
type EIP1193ProviderLax = {
request: (args: { method: any; params?: any }) => Promise<any>;
on: (event: any, callback: (arg: unknown) => void) => void;
removeListener: (event: any, callback: (arg: unknown) => void) => void;
};
Most wallet connectors (wagmi connectors, RainbowKit, raw window.ethereum) satisfy this shape.
In dapp mode the widget’s internal Connect Wallet drawer is not rendered. Without an onConnectWalletClick event handler, the button is disabled. With one, the button is enabled but still won’t open the widget’s own drawer: you must run your host app’s wallet connection flow inside the handler.
<Widget
config={{ widgetMode: "dapp" }}
provider={provider}
events={{
onConnectWalletClick: () => {
// host-app responsibility, e.g. open RainbowKit modal
openConnectModal();
},
}}
/>
Hide the wallet UI entirely
If your host app shows the connected account elsewhere, hide the widget’s wallet header:
<Widget
config={{
widgetMode: "dapp",
excludeUI: ["wallet-management"],
}}
provider={provider}
/>
Decision tree
Does your host app already manage the user wallet?
├── No → widgetMode: "standalone" (optionally add privyAppId for Privy)
└── Yes → widgetMode: "dapp" + provider + onConnectWalletClick
└── Already show the connected account in the host UI?
└── Yes → excludeUI: ["wallet-management"]
Connection events
Both modes emit onConnectWallet events you can use for analytics. See Events & callbacks for payload details.
<Widget
events={{
onConnectWallet: ({ event }) => {
if (event.name === "ConnectWallet:connect") {
analytics.track("wallet_connected", {
connector: event.params.connectorType,
action: event.params.connectorAction,
});
}
},
}}
/>
Related pages