web3 钱包签名登录


RainbowKit 提供 RainbowKitAuthenticationProvider 封装了钱包授权流程,并提供配置项允许用户自定义各流程逻辑

pnpm add @rainbow-me/rainbowkit viem wagmi @tanstack/react-query

  1. 用户打开弹窗连接钱包获取 address
  1. 从后端获取 nonce 随机数
getNonce: async () => {
  const response = await fetch("/api/nonce");
  return await response.text();
},
  1. 使用 createSiweMessage 创建 siwe 消息 -> 需要 address nonce
const siweMessage = createSiweMessage({
  domain: window.location.host,
  address,
  statement: "Sign in with Ethereum to the app.",
  uri: window.location.origin,
  version: "1",
  chainId,
  nonce,
});
  1. 让后端验证签名
const response = await fetch("/api/verify", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ message, signature }),
});

/api/verify 简要逻辑如下

const publicClient = createPublicClient({
  chain: mainnet, // 使用的链
  transport: http(),
});

// 从 message 中解析 address 并使用 verifyHash 验证签名是否由该 address 签署
const isValid = await verifySiweMessage(publicClient, {
  message,
  signature,
  // 可选:验证其他字段
  // nonce: 'expected-nonce',
});