Authenticate a user using Sign In With Ethereum (SIWE).
The authenticate function will return the user’s wallet address and a signed message that verifies wallet ownership. This should be the primary authentication method for your Mini App.Uses Sign In With Ethereum (SIWE) to sign a message that contains a nonce that should be generated in your backend.
If present, it must be at least 8 alphanumeric characters in length.
A unique nonce for the authentication request. This should be generated in your backend and be different for each authentication attempt.
Backend endpointsThe backend is responsible for generating a nonce and verifying the signature.
Copy
import crypto from 'crypto';// Generate a cryptographically secure nonceasync function generateNonce(): Promise<string> { // Generate 32 random bytes and convert to hex const nonce = crypto.randomBytes(32).toString('hex'); // TODO: Store the nonce in your database with: // - timestamp for expiration // - used flag to prevent replay attacks // - user identifier return nonce;}app.post('/api/auth/nonce', async (req, res) => { const nonce = await generateNonce(); res.json({ nonce });});
Frontend React component:
Copy
import React, { useState, useEffect } from 'react';import { authenticate, ChainId, TransactionResult } from '@lemonatio/mini-app-sdk';import { getNonceFromBackend, verifySignatureOnBackend } from './api';export const MiniApp: React.FC = () => { const [wallet, setWallet] = useState<string | undefined>(undefined); const handleAuthenticate = async () => { // 1. Get a unique nonce from your backend const nonce = await getNonceFromBackend(); // 2. Request the signature using the nonce const result = await authenticate({ nonce, chainId: ChainId.POLYGON_AMOY }); if (result.result !== TransactionResult.SUCCESS) { throw new Error(`Authentication failed: ${result.result}`); } const { wallet, signature, message } = result; // 3. Verify the signature on your backend const verificationResult = await verifySignatureOnBackend({ wallet, signature, message, nonce, }); if (verificationResult.verified) { setWallet(wallet); } }; // Trigger authentication on component mount useEffect(() => { handleAuthenticate(); }, []); return ( <div> <h2>Wallet</h2> <p> Connected: {wallet ? '✅ Connected' : '❌ Not connected'} </p> {wallet && ( <p> {wallet} </p> )} </div> );};
The smart contract wallet is deployed on the first user’s transaction.The authenticate method supports ERC-6492 for contract wallets that are not yet deployed. This means users can authenticate even before their wallet contract is deployed.