Sign In With Ethereum
Add ERC-4361 wallet sign-in and connected wallet settings to your Solid/Zaidan app.
The SIWE plugin adds wallet sign-in backed by Better Auth's siwe() plugin, with optional email collection and a security settings card for connected wallets.
It contributes:
- A "Continue with Ethereum" button on sign-in views
- An optional email dialog when the plugin's
emailmode is"optional"or"required" - A
<WalletAccounts />security card for connecting, promoting, and removing wallets
Setup
Configure the Better Auth server
Add siwe() with a secure nonce generator and an ERC-4361 verifier, then apply the plugin schema.
import { betterAuth } from "better-auth"
import { siwe } from "better-auth/plugins"
import { verifyMessage } from "viem"
import { generateSiweNonce } from "viem/siwe"
export const auth = betterAuth({
// ...
plugins: [
siwe({
domain: "app.example.com",
getNonce: async () => generateSiweNonce(),
verifyMessage: async ({ message, signature, address }) =>
verifyMessage({
address: address as `0x${string}`,
message,
signature: signature as `0x${string}`
})
})
]
})Add the matching client plugin
import { createAuthClient } from "better-auth/solid"
import { siweClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [siweClient()]
})Install the UI plugin
npx shadcn@latest add https://better-auth-ui.com/r/solid/siwe.jsonRegister the plugin
connector is yours to supply. It bridges the plugin to whichever wallet library you use, so BAUI never depends on one.
import { AuthProvider } from "@/components/auth/auth-provider"
import { siwePlugin } from "@/lib/auth/siwe-plugin"
import { authClient } from "@/lib/auth-client"
export function Providers(props: { children?: JSX.Element }) {
return (
<AuthProvider
authClient={authClient}
navigate={navigate}
plugins={[
siwePlugin({
connector,
domain: "app.example.com",
uri: "https://app.example.com"
})
]}
>
{props.children}
</AuthProvider>
)
}Pass walletManager as well to render the <WalletAccounts /> security card. Without it the plugin only contributes the sign-in button.
domain and uri must match what the server verifies. A mismatch makes every signature fail verification.
Runtime prerequisites
- Server:
siwe()frombetter-auth/plugins, withgetNonceandverifyMessage. - Client:
siweClient()frombetter-auth/client/plugins. - App: a wallet connector, and a wallet manager if you want the settings card.
- Runtime API: SIWE query and mutation options from Solid runtime APIs.
Copied files
src/lib/auth/siwe-plugin.tssrc/components/auth/siwe/sign-in-ethereum-button.tsxsrc/components/auth/siwe/wallet-accounts.tsx
After install these files are yours. Restyle the wallet rows, change how addresses are shortened, or swap the dialog for your wallet library's own modal.
Options
Prop
Type
Localization
Prop
Type
Last updated on