Why wallet signatures instead of passwords?

  1. No new passwords – authentication happens with the key the user already controls.
  2. Nothing to steal or reuse – each login is a one-off, domain-bound signature that never leaves the user’s device.
  3. Wallet-agnostic – works in any EIP-1193 wallet (browser extension, mobile deep-link, embedded provider) and follows the open “Sign in with Ethereum” (SIWE) EIP-4361 standard.
Base Accounts build on those standards so you can reuse any SIWE tooling – while still benefiting from passkeys, session keys, and smart-wallet security.
Please Follow the Brand GuidelinesIf you intend on using the SignInWithBaseButton, please follow the Brand Guidelines to ensure consistency across your application.

High-level flow

Undeployed Smart Wallets?
Base Account signatures include the ERC-6492 wrapper so they can be verified even before the wallet contract is deployed. Viem’s verifyMessage and verifyTypedData handle this automatically.

Implementation

Code Snippets

import { createBaseAccountSDK } from "@base-org/account";
import crypto from 'crypto';

// Initialize the SDK (no config needed for defaults)
const provider = createBaseAccountSDK().getProvider();

// 1 — get a fresh nonce (generate locally or prefetch from backend)
const nonce = window.crypto.randomUUID().replace(/-/g, '');
// OR prefetch from server
// const nonce = await fetch('/auth/nonce').then(r => r.text()); 

// 2 — connect and authenticate
try {
  const { accounts } = await provider.request({
    method: 'wallet_connect',
    params: [{
      version: '1',
      capabilities: {
        signInWithEthereum: { 
          nonce, 
          chainId: '0x2105' // Base Mainnet - 8453
        }
      }
    }]
  });
  const { address } = accounts[0];
  const { message, signature } = accounts[0].capabilities.signInWithEthereum;
  await fetch('/auth/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ address, message, signature })
  });
} catch (err) {
  console.error(`err ${err}`);
}
If using the above code beyond Base Account, note that not every wallet supports the new wallet_connect method yet. If the call throws [method_not_supported], fall back to using eth_requestAccounts and personal_sign.
To avoid popup blockers, fetch or generate the nonce before the user presses “Sign in with Base” (for example on page load). For security, the only requirement is that your backend keeps track of every nonce and refuses any that are reused – regardless of where it originated.

Example Express Server

server/auth.ts
import crypto from 'crypto';
import express from 'express';
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';

const app = express();
app.use(express.json());

// Simple in-memory nonce store (swap for Redis or DB in production)
const nonces = new Set<string>();

app.get('/auth/nonce', (_, res) => {
  const nonce = crypto.randomBytes(16).toString('hex');
  nonces.add(nonce);
  res.send(nonce);
});

const client = createPublicClient({ chain: base, transport: http() });

app.post('/auth/verify', async (req, res) => {
  const { address, message, signature } = req.body;

  // 1. Check nonce hasn\'t been reused
  const nonce = message.match(/at (\w{32})$/)?.[1];
  if (!nonce || !nonces.delete(nonce)) {
    return res.status(400).json({ error: 'Invalid or reused nonce' });
  }

  // 2. Verify signature
  const valid = await client.verifyMessage({ address, message, signature });
  if (!valid) return res.status(401).json({ error: 'Invalid signature' });

  // 3. Create session / JWT here
  res.json({ ok: true });
});

app.listen(3001, () => console.log('Auth server listening on :3001'));

Add the Base Sign In With Base Button

Use the pre-built component for a native look-and-feel:
App.tsx
import { SignInWithBaseButton } from '@base-org/account-ui/react';

export function App() {
  return (
    <SignInWithBaseButton
      colorScheme="light"
      onClick={() => signInWithBase()}
    />
  );
}
See full props and theming options in the Button Reference and Brand Guidelines.
Please Follow the Brand GuidelinesIf you intend on using the SignInWithBaseButton, please follow the Brand Guidelines to ensure consistency across your application.