2.6.3.1 Wallet Verification Flow

1. Frontend: User clicks “Connect Wallet” (MetaMask, WalletConnect, etc.).

2. Nonce Generation: The backend creates a one-time nonce (e.g., random string) stored in the user’s DB row or Redis.

3. Signature: The frontend requests the user to sign the nonce with their wallet’s private key.

4. Verification: The backend verifies the signature using ethers.js or web3.js. If valid, it associates the wallet address with the user’s account.

Example Controller:

// backend/src/controllers/walletController.js
const { ethers } = require('ethers');
const User = require('../models/User');
const crypto = require('crypto');

exports.generateNonce = async (req, res) => {
  try {
    const nonce = crypto.randomBytes(16).toString('hex');
    // Store in DB or Redis for user
    // ...
    return res.json({ nonce });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Server error' });
  }
};

exports.verifySignature = async (req, res) => {
  try {
    const { address, signature, nonce } = req.body;
    // Retrieve the expected nonce from DB
    // ...
    // Recreate the message and verify
    const message = `Welcome to SUM+1. Nonce: ${nonce}`;
    const signingAddress = ethers.utils.verifyMessage(message, signature);
    if (signingAddress.toLowerCase() === address.toLowerCase()) {
      // Link wallet to user account
      // ...
      return res.json({ success: true });
    }
    return res.status(400).json({ error: 'Invalid signature' });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Server error' });
  }
};

Last updated