0.3.0 • Published 6 months ago

@evmauth/eip712-authn v0.3.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

EVMAuth TypeScript EIP-712 Authentication

GitHub Actions Workflow Status GitHub Repo stars

A TypeScript library for secure authentication via EIP-712 message signing to verify ownership of a wallet address.

Features

  • Sign In With Wallet: Authenticate users via their Ethereum wallets using EIP-712 typed data signatures
  • Multi Wallet Support: First-class support for EIP-1193 and EIP-6963 wallet provider interface standard
  • Client Integration: Simple client library for browser-based applications
  • Server Verification: Robust server-side verification of signed messages
  • Full TypeScript Support: Complete type safety with TypeScript interfaces for all components
  • Framework Agnostic: Works with any JavaScript framework or vanilla JS
  • Minimal Dependencies: Small footprint with few external dependencies
  • Comprehensive Tests: Well-tested codebase with high test coverage
  • Secure Design: Built with security best practices from the ground up

Installation

npm install @evmauth/eip712-authn

Quick Start

Client-Side Implementation

import { AuthClient, walletConnector } from '@evmauth/eip712-authn/client';

// Initialize the auth client with your API endpoints
const authClient = new AuthClient({
  challengeUrl: 'https://your-api.com/challenge',
  authUrl: 'https://your-api.com/auth',
});

// Connect to a wallet
async function connectWallet() {
  // Get available wallet providers (supports EIP-6963)
  const providers = walletConnector.getProviders();
  
  if (providers.length > 0) {
    // Connect to the first available provider
    const address = await walletConnector.connect(providers[0]);
    console.log(`Connected to wallet: ${address}`);
    return address;
  } else {
    console.error('No wallet providers found');
    return null;
  }
}

// Authenticate with the connected wallet
async function authenticate() {
  try {
    // One-step authentication
    const success = await authClient.authenticateWithWallet();
    
    if (success) {
      console.log('Authentication successful!');
      // User is now authenticated
    }
    
    return success;
  } catch (error) {
    console.error('Authentication failed:', error);
    return false;
  }
}

// Usage in an application
document.getElementById('connect-btn').addEventListener('click', async () => {
  await connectWallet();
});

document.getElementById('login-btn').addEventListener('click', async () => {
  await authenticate();
});

Server-Side Implementation

import { AuthServer } from '@evmauth/eip712-authn/server';
import express from 'express';

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

// Initialize the auth server with a JWT secret and your domain details
const authServer = new AuthServer({
  jwtSecret: 'your_jwt_secret',
  appName: 'Your App Name',
  appVersion: '1',
});

// Challenge endpoint
app.get('/challenge', (req, res) => {
  const address = req.query.address as string;
  const networkId = Number.parseInt(req.query.networkId as string, 1); // default to Ethereum mainnet
  const expiresIn = 30; // seconds
  
  if (!address) {
    return res.status(400).json({ error: 'Wallet address is required' });
  }
  
  // Create a challenge for the wallet address
  const challenge = authServer.createChallenge(address, networkId, expiresIn);
  
  res.json(challenge);
});

// Authentication endpoint
app.post('/auth', (req, res) => {
  const signedMessage = req.headers.authorization?.replace('EIP712 ', '');
  const message = req.body;
  
  if (!signedMessage || !message) {
    return res.status(400).json({ error: 'Missing signature or message' });
  }
  
  // Verify the signed challenge and extract the wallet address
  const address = authServer.verifyChallenge(message, signedMessage);
  
  if (!address) {
    res.status(401).json({ error: 'Invalid signature' });
  }

  // Create a session or JWT token for the authenticated user
  // ...

  res.json({ success: true });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Auth Server Errors

All error classes below extend the AuthError class, which extends Error.

Error ClassDescription
InvalidJWTErrorThe EIP-712 message challenge JWT is invalid or expired.
InvalidMessageErrorThe unsigned EIP-712 message is invalid or does not match the expected format.
InvalidSignatureErrorThe signed EIP-712 message is invalid or does not match the expected format.
SignatureMismatchErrorThe EIP-712 message signer address does not match the challenge JWT address.

License

The EVMAuth TypeScript EIP-712 Authentication is released under the MIT License. See the LICENSE file for details.

0.3.0

6 months ago

0.2.3

6 months ago

0.2.2

6 months ago

0.2.1

6 months ago

0.2.0

6 months ago

0.1.1

6 months ago

0.1.0

6 months ago