Skip to main content
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.

Usage

import { authenticate } from '@lemonatio/mini-app-sdk';

export const MiniApp = () => {
  const [wallet, setWallet] = useState<string | undefined>(undefined);

  const handleAuthentication = async () => {
    const authentication = await authenticate();
    
    setWallet(authentication.wallet);
  };

  useEffect(() => {
    handleAuthentication();
  }, []);
};

Parameters

type AuthenticateInput = {
  nonce?: string;
  chainId?: ChainId;
}
nonce
string
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.
await authenticate({
  nonce: 'l3m0nc45h',
});
chainId
ChainId
If your Mini App supports multiple chains, you can provide the chain id to use for the authentication request.
import { ChainId } from '@lemonatio/mini-app-sdk';

await authenticate({
  chainId: ChainId.POLYGON_AMOY,
});

Returns

type AuthenticateResponse = {
  result: TransactionResult.SUCCESS;
  data: {
    wallet: string;
    signature: string;
    message: string;
  };
} | {
  result: TransactionResult.FAILED;
  error: string;
} | {
  result: TransactionResult.CANCELLED;
};
result
TransactionResult
The result of the authentication attempt.
  • SUCCESS: The authentication was successful.
  • FAILED: The authentication failed.
  • CANCELLED: The authentication was cancelled by the user.
data
object
Contains the wallet address, signature and message. Only present when the result is SUCCESS.
  • wallet: The wallet address of the authenticated user.
  • signature: The cryptographic signature proving the user’s authentication.
  • message: The message that was signed by the user’s wallet.
error
string
Contains the error message when the authentication fails. Only present when the result is FAILED.

Complete Authentication Flow

Backend endpoints The backend is responsible for generating a nonce and verifying the signature.
import crypto from 'crypto';

// Generate a cryptographically secure nonce
async 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:
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>
  );
};

ERC-6492 Support

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.