Skip to content

Instantly share code, notes, and snippets.

@nelson-david
Created September 4, 2024 04:19
Show Gist options
  • Save nelson-david/8ad84561828ac4735b1551f05b7983e3 to your computer and use it in GitHub Desktop.
Save nelson-david/8ad84561828ac4735b1551f05b7983e3 to your computer and use it in GitHub Desktop.
# Sign in with Ethereum Implementation in Next.js

## Overview
This implementation showcases how to integrate "Sign in with Ethereum" functionality in a Next.js application using the [login.xyz](https://docs.login.xyz/) documentation.

## Installation
First, initialize a Next.js project and install the necessary dependencies:

```bash
npx create-next-app eth-login-nextjs
cd eth-login-nextjs
npm install ethers @walletconnect/web3-provider siwe

Frontend Implementation

pages/index.js

import { useState } from 'react';
import { ethers } from 'ethers';
import { SiweMessage } from 'siwe';

export default function Home() {
    const [address, setAddress] = useState(null);
    const [error, setError] = useState(null);

    const handleSignIn = async () => {
        try {
            const provider = new ethers.providers.Web3Provider(window.ethereum);
            await provider.send("eth_requestAccounts", []);
            const signer = provider.getSigner();
            const userAddress = await signer.getAddress();
            
            const message = new SiweMessage({
                domain: window.location.host,
                address: userAddress,
                statement: 'Sign in with Ethereum to the app.',
                uri: window.location.origin,
                version: '1',
                chainId: 1,
            });

            const signature = await signer.signMessage(message.prepareMessage());

            // Send this data to your backend for verification
            const verifyResponse = await fetch('/api/verify', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ message, signature }),
            });

            if (verifyResponse.ok) {
                setAddress(userAddress);
            } else {
                throw new Error('Verification failed');
            }
        } catch (err) {
            setError(err.message);
        }
    };

    return (
        <div>
            <h1>Sign in with Ethereum</h1>
            <button onClick={handleSignIn}>Sign In</button>
            {address && <p>Signed in as: {address}</p>}
            {error && <p style={{ color: 'red' }}>{error}</p>}
        </div>
    );
}

Backend Verification

In Next.js, you can use API routes for backend verification. Create a new file pages/api/verify.js:

import { SiweMessage } from 'siwe';

export default async function handler(req, res) {
    try {
        const { message, signature } = req.body;
        const siweMessage = new SiweMessage(message);
        const fields = await siweMessage.validate(signature);

        // Here you would check fields for validity and session management
        if (fields.address) {
            // Example: Add session management here
            return res.status(200).json({ success: true });
        } else {
            return res.status(400).json({ success: false });
        }
    } catch (error) {
        return res.status(400).json({ success: false, error: error.message });
    }
}

Explanation

  • Frontend: We request the user's Ethereum address using ethers.js. A SiweMessage is generated using the siwe package, which is then signed by the user. This signature and message are sent to the backend for verification.

  • Backend: The API route verifies the signature using SiweMessage. You can then manage sessions or perform additional checks based on the verified address.

Conclusion

This is a basic implementation of "Sign in with Ethereum" using Next.js. You can extend this implementation with more features like session management, user authentication, and additional checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment