Manage user accounts
Connect and manage user wallet sessions in your Wagmi or Vanilla JavaScript dapp. With the SDK, you can:
- Connect users' wallets to your dapp.
- Access user accounts (addresses).
- Connect and sign in a single user interaction.
- Handle connection states (connected/disconnected).
- Listen for account changes in real time.
- Manage wallet sessions (connect/disconnect).
- Support multiple wallet types (extension, mobile app).
Use Wagmi
Wagmi provides a simple, hook-based approach for handling wallet connections. For example:
Handle wallet connections
import { useAccount, useConnect, useDisconnect } from "wagmi"
function ConnectWallet() {
const { address, isConnected } = useAccount()
const { connectors, connect, isPending } = useConnect()
const { disconnect } = useDisconnect()
if (isConnected) {
return (
<div>
<div>Connected to {address}</div>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
)
}
return (
<div>
{connectors.map((connector) => (
<button
key={connector.uid}
onClick={() => connect({ connector })}
disabled={isPending}
>
{isPending ? "Connecting..." : `Connect ${connector.name}`}
</button>
))}
</div>
)
}
Wagmi provides a dedicated hook for handling account lifecycle events:
import { useAccountEffect } from "wagmi"
function WatchAccount() {
useAccountEffect({
onConnect(data) {
console.log("Connected!", {
address: data.address,
chainId: data.chainId,
isReconnected: data.isReconnected
})
},
onDisconnect() {
console.log("Disconnected!")
}
})
return <div>Watching for account changes...</div>
}
Use Vanilla JavaScript
You can implement user authentication directly in Vanilla JavaScript, using the
eth_requestAccounts
RPC method
and accountsChanged
provider event.
For example:
import { MetaMaskSDK } from "@metamask/sdk";
// Initialize SDK
const MMSDK = new MetaMaskSDK();
const provider = MMSDK.getProvider();
// Connect wallet
async function connectWallet() {
try {
// Disable button while request is pending
document.getElementById("connectBtn").disabled = true;
const accounts = await provider.request({
method: "eth_requestAccounts"
});
const account = accounts[0];
console.log("Connected:", account);
// Update UI
document.getElementById("status").textContent = `Connected: ${account}`;
document.getElementById("connectBtn").style.display = "none";
document.getElementById("disconnectBtn").style.display = "block";
} catch (err) {
if (err.code === 4001) {
console.log("User rejected connection");
} else {
console.error(err);
}
} finally {
document.getElementById("connectBtn").disabled = false;
}
}
// Disconnect wallet
async function disconnectWallet() {
try {
await MMSDK.terminate()
} catch (err) {
console.error("Error with disconnecting:", err)
}
}
// Handle account changes
provider.on("accountsChanged", (accounts) => {
if (accounts.length === 0) {
// User disconnected
document.getElementById("status").textContent = "Not connected";
document.getElementById("connectBtn").style.display = "block";
document.getElementById("disconnectBtn").style.display = "none";
} else {
// Account changed
document.getElementById("status").textContent = `Connected: ${accounts[0]}`;
}
});
Display connect and disconnect buttons in HTML:
<div>
<div id="status">Not connected</div>
<button id="connectBtn" onclick="connectWallet()">Connect MetaMask</button>
<button id="disconnectBtn" style="display: none" onclick="disconnectWallet()">
Disconnect
</button>
</div>