### Full Example: Authentication and Deposit in React TypeScript Source: https://context7_llms This comprehensive example integrates authentication and deposit functionalities within a React Mini App. It uses `authenticate` to get the user's wallet, `isWebView` to ensure correct environment, and `deposit` for transactions. The UI dynamically updates based on authentication status. Dependencies include `react` and `@lemoncash/mini-app-sdk`. ```typescript import React, { useEffect, useState } from 'react'; import { authenticate, deposit, isWebView, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); const handleDeposit = async () => { try { const result = await deposit({ amount: '100', tokenName: 'USDC', }); console.log('Deposit successful:', result.txHash); } catch (error) { console.error('Deposit failed:', error); throw error; } }; if (!isWebView()) { return
Please open this app in Lemon Cash
; } return (
{wallet ? `${wallet.slice(0, 8)}...${wallet.slice(-8)}` : 'Authenticating...' }
); }; ``` -------------------------------- ### SIWE Message Examples Source: https://eips.ethereum.org/EIPS/eip-4361 Provides concrete examples of SIWE messages, demonstrating variations with implicit/explicit schemes and ports. ```APIDOC ## Examples ### Example with Implicit Scheme ``` example.com wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` ### Example with Implicit Scheme and Explicit Port ``` example.com:3388 wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` ### Example with Explicit Scheme ``` https://example.com wants you to sign in with your Ethereum account: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 I accept the ExampleOrg Terms of Service: https://example.com/tos URI: https://example.com/login Version: 1 Chain ID: 1 Nonce: 32891756 Issued At: 2021-09-30T16:25:24Z Resources: - ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/ - https://example.com/my-web2-claim.json ``` ``` -------------------------------- ### Install Mini App SDK Bash Source: https://context7_llms Commands to install the Lemon Cash Mini App SDK using either npm or yarn package managers. This is the first step in integrating the SDK into your project. ```bash npm install @lemoncash/mini-app-sdk ``` ```bash yarn add @lemoncash/mini-app-sdk ``` -------------------------------- ### Authenticate User Typescript Source: https://context7_llms Example TypeScript code demonstrating how to use the `authenticate` function from the Mini App SDK to get the user's wallet address. It includes state management for the wallet and a useEffect hook to trigger authentication on component mount. ```typescript import { useState, useEffect } from 'react'; import { authenticate, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); }; ``` -------------------------------- ### Successful Authentication Response Example Source: https://context7_llms An example of a successful authentication response. It includes the user's wallet address, a cryptographic signature, and the message that was signed, confirming the user's identity. ```typescript { result: 'SUCCESS', data: { wallet: '0x1Ed17b06961B9B8DE78Ee924BcDaBC003aaE1867', signature: '0xba099e3ab31b8bf1201d2de2d0e4d81f7162f5de6993a960988959ff97be45b27d284a6e29d065cd175122953cf861725906639dc1f3229e66ff8b9d5820634a1b', message: 'web3-miniapps-svc.svc.staging.lemon wants you to sign in with your Ethereum account:\n0x1Ed17b06961B9B8DE78Ee924BcDaBC003aaE1867\n\nSign in with Ethereum to the app cbbe623b-be3d-4796-aa61-c93253a0a3af.\n\nURI: http://web3-miniapps-svc.svc.staging.lemon/auth/cbbe623b-be3d-4796-aa61-c93253a0a3af\nVersion: 1\nChain ID: 80002\nNonce: l3m0nc45h\nIssued At: 2025-09-03T19:02:52.697Z' } } ``` -------------------------------- ### Withdrawal Response Examples Typescript Source: https://context7_llms Provides example JSON objects for successful, failed, and cancelled withdrawal responses. These examples illustrate the structure of the data returned by the withdrawal function for each possible outcome. ```typescript { result: 'SUCCESS', data: { txHash: '0x1234567890123456789012345678901234567890' } } ``` ```typescript { result: 'FAILED', error: { message: 'Insufficient balance', code: 'INSUFFICIENT_BALANCE' } } ``` ```typescript { result: 'CANCELLED', } ``` -------------------------------- ### Authenticate with Nonce Source: https://context7_llms Example of initiating authentication by providing a unique nonce. This nonce should be generated on the backend and be distinct for each authentication attempt to ensure security. ```typescript await authenticate({ nonce: 'l3m0nc45h', }); ``` -------------------------------- ### Authenticate User Typescript Source: https://lemoncash.mintlify.app/llms-full.txt Example of how to use the `authenticate` function from the SDK to get the user's wallet address. It uses React hooks `useState` and `useEffect` to manage the wallet state and trigger authentication on component mount. ```typescript import { useState, useEffect } from 'react'; import { authenticate, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); }; ``` -------------------------------- ### Cancelled Authentication Response Example Source: https://context7_llms An example of a cancelled authentication response. This indicates that the user chose not to proceed with the authentication request. ```typescript { result: 'CANCELLED', } ``` -------------------------------- ### Receive Response from Native App via WebView - TypeScript Source: https://context7_llms TypeScript example showing how the Lemon Cash native app sends responses back to the mini app through WebView. The example demonstrates an authentication response containing wallet address, signature, and message data. ```typescript // Example: Authentication response webViewRef.current.postMessage(JSON.stringify({ action: 'AUTHENTICATE_RESPONSE', data: { wallet: '0x...', signature: '0x...', message: '...' } })); ``` -------------------------------- ### Open Mini App from Native and Web - JavaScript/TypeScript Source: https://context7_llms Cross-platform examples for opening Mini App deeplinks programmatically. Includes React Native implementation using Linking API and web implementation using window.location.href for handling deeplink navigation. ```javascript // React Native Linking.openURL('lemoncash://app/mini-apps/webview/my-mini-app-id'); // Web window.location.href = 'lemoncash://app/mini-apps/detail/my-mini-app-id'; ``` -------------------------------- ### Failed Authentication Response Example Source: https://context7_llms An example of a failed authentication response. It provides an error message and a machine-readable error code, which can be used for debugging and handling authentication failures. ```typescript { result: 'FAILED', error: { message: 'Invalid signature', code: 'INVALID_SIGNATURE' } } ``` -------------------------------- ### Open Mini App from Website - HTML Source: https://context7_llms HTML anchor tag example for opening a Mini App deeplink from a website. Users click the link to launch the Mini App detail page within the Lemon Cash application. ```html Open My Mini App ``` -------------------------------- ### Example Cancelled Response for Smart Contract Call (TypeScript) Source: https://lemoncash.mintlify.app/llms-full.txt An example of a cancelled response from a smart contract call, showing the 'CANCELLED' result, indicating the user terminated the transaction. ```typescript { result: 'CANCELLED', } ``` -------------------------------- ### Full Example: Authentication, Deposit, and WebView Check in TypeScript Source: https://lemoncash.mintlify.app/llms-full.txt This comprehensive React component integrates authentication, deposit functionality, and an environment check using the '@lemoncash/mini-app-sdk'. It fetches the user's wallet address upon mounting, displays it, and enables a deposit button once authenticated. The component also ensures the app is running within the Lemon Cash WebView. ```typescript import React, { useEffect, useState } from 'react'; import { authenticate, deposit, isWebView, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); const handleDeposit = async () => { try { const result = await deposit({ amount: '100', tokenName: 'USDC', }); console.log('Deposit successful:', result.txHash); } catch (error) { console.error('Deposit failed:', error); throw error; } }; if (!isWebView()) { return
Please open this app in Lemon Cash
; } return (
{wallet ? `${wallet.slice(0, 8)}...${wallet.slice(-8)}` : 'Authenticating...' }
); }; ``` -------------------------------- ### Handle Successful Deposit Response Source: https://context7_llms Example response object when a deposit transaction completes successfully. Contains the transaction hash that can be used to track the deposit on the blockchain. ```typescript { result: 'SUCCESS', data: { txHash: '0x1234567890123456789012345678901234567890' } } ``` -------------------------------- ### Authenticate User with SIWE - TypeScript Source: https://context7_llms TypeScript example implementing Sign In With Ethereum (SIWE) authentication using the authenticate function from the Lemon Cash Mini App SDK. Returns the user's wallet address and signed message for wallet ownership verification. ```typescript import { authenticate, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); }; ``` -------------------------------- ### Call Smart Contract with Title and Description Values Source: https://context7_llms This example demonstrates how to customize the transaction's title and description using dynamic values. The `titleValues` and `descriptionValues` objects allow for injecting specific data, such as amount, token, recipient, and network, to provide more context to the transaction. ```typescript await callSmartContract({ contracts: [ { contractAddress: "0x1234567890123456789012345678901234567890", functionName: "transfer", functionParams: ["0x0987654321098765432109876543210987654321", "1000000"], value: "0", }, ], titleValues: { amount: "100", token: "USDC", }, descriptionValues: { recipient: "0x0987654321098765432109876543210987654321", network: "Polygon", }, }); ``` -------------------------------- ### React Component with WebView Detection Source: https://lemoncash.mintlify.app/functions/is-webview Shows a complete React component example that checks the WebView environment on component mount using the isWebView() function. The component displays the WebView status and provides a message when features are not available in non-WebView environments. ```TypeScript/JSX import { isWebView } from '@lemoncash/mini-app-sdk'; import { useState, useEffect } from 'react'; export const MiniApp = () => { const [isInWebView, setIsInWebView] = useState(false); useEffect(() => { // Check WebView environment on component mount const webViewStatus = isWebView(); setIsInWebView(webViewStatus); }, []); return (

Mini App Status

WebView Environment: {isInWebView ? '✅ Available' : '❌ Not Available'}

{!isInWebView && (

Open this app in the Lemon Cash app to use all features.

)}
); }; ``` -------------------------------- ### Implement Deposit Functionality in TypeScript Source: https://context7_llms This snippet demonstrates how to integrate deposit functionality into a React Mini App using the `@lemoncash/mini-app-sdk`. It calls the `deposit` function with specified amount and token, logging the transaction hash on success or the error on failure. Ensure the SDK is installed as a dependency. ```typescript import React from 'react'; import { deposit } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const handleDeposit = async () => { try { const result = await deposit({ amount: '100', tokenName: 'USDC', }); console.log('Deposit successful:', result.txHash); } catch (error) { console.error('Deposit failed:', error); throw error; } }; return ( ); }; ``` -------------------------------- ### Send Message to Native App via WebView - TypeScript Source: https://context7_llms TypeScript example demonstrating how to send messages from a mini app to the Lemon Cash native application using React Native WebView. The example shows sending an authentication request with a nonce parameter. ```typescript // Example: Sending authentication request window.ReactNativeWebView.postMessage(JSON.stringify({ action: 'AUTHENTICATE', nonce: 'l3m0nc45h' })); ``` -------------------------------- ### Detect WebView Environment - TypeScript Source: https://context7_llms TypeScript example using the isWebView hook to detect if the application is running inside the Lemon Cash WebView. This is useful for conditional rendering and ensuring the app only operates within the supported environment. ```typescript import { isWebView } from '@lemoncash/mini-app-sdk'; function MyMiniApp() { if (!isWebView()) { return
This app only works inside Lemon Cash
; } return
Welcome to your mini app!
; } ``` -------------------------------- ### Handle Failed Deposit Response Source: https://context7_llms Example response object when a deposit transaction fails. Includes error message and error code for identifying the failure reason, such as insufficient balance or network issues. ```typescript { result: 'FAILED', error: { message: 'Insufficient balance', code: 'INSUFFICIENT_BALANCE' } } ``` -------------------------------- ### Handle Cancelled Deposit Response Source: https://context7_llms Example response object when a user cancels a deposit transaction. Indicates the operation was terminated by user action rather than completing or encountering an error. ```typescript { result: 'CANCELLED' } ``` -------------------------------- ### Example CANCELLED Response for Smart Contract Call Source: https://context7_llms Demonstrates a cancelled response from a smart contract call. This JSON object signifies a 'CANCELLED' result, indicating that the user chose not to proceed with the transaction. This is important for handling user-initiated cancellations gracefully. ```json { "result": "CANCELLED" } ``` -------------------------------- ### Example FAILED Response for Smart Contract Call Source: https://context7_llms Shows a failed response from a smart contract call. This JSON object represents a 'FAILED' result and contains an 'error' object with a 'message' (e.g., 'Insufficient balance') and an error 'code' (e.g., 'INSUFFICIENT_BALANCE'). This helps in diagnosing and handling errors during contract interactions. ```json { "result": "FAILED", "error": { "message": "Insufficient balance", "code": "INSUFFICIENT_BALANCE" } } ``` -------------------------------- ### Call Smart Contract - Simple Transaction Source: https://context7_llms Example of how to perform a simple transaction by calling a smart contract function. This involves specifying the contract address, function name, and parameters. The 'value' field is set to '0' indicating no native currency transfer. ```typescript await callSmartContract({ contracts: [ { contractAddress: "0x1234567890123456789012345678901234567890", functionName: "transfer", functionParams: ["0x0987654321098765432109876543210987654321", "1000000"], value: "0", }, ], }); ``` -------------------------------- ### Example SUCCESS Response for Smart Contract Call Source: https://context7_llms Illustrates a successful response from a smart contract call. This JSON object indicates a 'SUCCESS' result and includes the transaction hash ('txHash') within the 'data' object. This format is crucial for confirming successful operations and obtaining transaction identifiers. ```json { "result": "SUCCESS", "data": { "txHash": "0x1234567890123456789012345678901234567890" } } ``` -------------------------------- ### Backend: Verify SIWE Signature (TypeScript) Source: https://context7_llms This backend endpoint verifies a SIWE (Sign-In with Ethereum) signature using the viem library. It requires the wallet address, signature, and message as input. Before verification, it's crucial to check the nonce's validity (existence, expiration, and usage status) in your database. ```typescript import { createPublicClient, http } from 'viem'; import { mainnet } from 'viem/chains'; // Create a public client for signature verification const publicClient = createPublicClient({ chain: mainnet, // or your target chain transport: http() }); async function verifySiweSignature( wallet: string, signature: string, message: string ): Promise { try { // Before verification, check: // 1. Nonce exists in database and hasn't expired // 2. Nonce hasn't been used before // 3. Nonce matches the one in the signed message // Verify the SIWE signature (supports ERC-6492 for contract wallets) const isValid = await publicClient.verifySiweMessage({ message: message, signature: signature as `0x${string}`, address: wallet as `0x${string}`, }); if (isValid) { // After verification mark nonce as used in database return true; } else { return false; } } catch (error) { console.error('SIWE signature verification error:', error); return false; } } app.post('/api/auth/verify', async (req, res) => { try { const { wallet, signature, message, nonce } = req.body; const isValidSignature = await verifySiweSignature(wallet, signature, message); if (isValidSignature) { res.json({ verified: true, wallet }); } else { res.json({ verified: false, error: 'Invalid signature' }); } } catch (error) { res.status(400).json({ error: error instanceof Error ? error.message : 'Verification failed' }); } }); ``` -------------------------------- ### Informal Message Template Source: https://eips.ethereum.org/EIPS/eip-4361 A human-readable, bash-like template illustrating the structure of a full SIWE message. ```APIDOC ## Informal Message Template A bash-like informal template of the full SIWE Message is presented below for readability and ease of understanding. Field descriptions are provided in the following section. A full ABNF description is provided in ABNF Message Format. ``` ${scheme}://${domain} wants you to sign in with your Ethereum account: ${address} ${statement} URI: ${uri} Version: ${version} Chain ID: ${chain-id} Nonce: ${nonce} Issued At: ${issued-at} Expiration Time: ${expiration-time} Not Before: ${not-before} Request ID: ${request-id} Resources: - ${resources[0]} - ${resources[1]} ... - ${resources[n]} ``` ``` -------------------------------- ### Frontend: MiniApp Authentication Flow (React/TypeScript) Source: https://context7_llms This React component handles the frontend authentication flow using the LemonCash mini-app SDK. It first fetches a nonce from the backend, then prompts the user to sign a message with their wallet, and finally sends the signature to the backend for verification. It updates the UI to show the connection status and wallet address upon successful authentication. ```typescript import React, { useState, useEffect } from 'react'; import { authenticate, ChainId, TransactionResult } from '@lemoncash/mini-app-sdk'; import { getNonceFromBackend, verifySignatureOnBackend } from './api'; export const MiniApp: React.FC = () => { const [wallet, setWallet] = useState(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.FAILED) { throw new Error(`Authentication failed: ${result.error.message} (${result.error.code})`); } if (result.result === TransactionResult.CANCELLED) { throw new Error('Authentication was cancelled by the user'); } const { wallet, signature, message } = result.data; // 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 (

Wallet

Connected: {wallet ? '✅ Connected' : '❌ Not connected'}

{wallet && (

{wallet}

)}
); }; ``` -------------------------------- ### Frontend: API - Get Nonce from Backend (TypeScript) Source: https://context7_llms This is an API helper function for the frontend to retrieve a nonce from the backend. It makes a POST request to the '/api/auth/nonce' endpoint and returns the nonce value from the JSON response. An error is thrown if the request fails. ```typescript // API function to get nonce from backend export async function getNonceFromBackend(): Promise { const response = await fetch('/api/auth/nonce', { method: 'POST' }); if (!response.ok) { throw new Error('Failed to get nonce from backend'); } const { nonce } = await response.json(); return nonce; } ``` -------------------------------- ### POST /authenticate Source: https://context7_llms Authenticates a user by generating a signature proof from their wallet. This endpoint supports optional nonce validation for security and multi-chain authentication through chainId specification. ```APIDOC ## POST /authenticate ### Description Authenticates a user and returns their wallet address, cryptographic signature, and signed message. The authentication can be customized with a unique nonce and chain ID for multi-chain support. ### Method POST ### Endpoint /authenticate ### Parameters #### Request Body - **nonce** (string) - Optional - A unique nonce for the authentication request. Must be at least 8 alphanumeric characters in length if provided. Should be generated in your backend and be different for each authentication attempt. - **chainId** (ChainId) - Optional - The blockchain chain ID to use for the authentication request. If your Mini App supports multiple chains, provide the chain ID here (e.g., ChainId.POLYGON_AMOY). ### Request Example ```typescript await authenticate({ nonce: 'l3m0nc45h', chainId: ChainId.POLYGON_AMOY }); ``` ### Response #### Success Response (200) When authentication succeeds, returns a result of 'SUCCESS' with wallet details: - **result** (string) - Always 'SUCCESS' for successful authentication - **data** (object) - Contains authentication proof - **wallet** (string) - The authenticated user's wallet address - **signature** (string) - Cryptographic signature proving authentication - **message** (string) - The signed message containing authentication details #### Failed Response (400) When authentication fails: - **result** (string) - Always 'FAILED' - **error** (object) - Error details - **message** (string) - Human-readable error description - **code** (string) - Machine-readable error code for programmatic handling #### Cancelled Response When user cancels authentication: - **result** (string) - Always 'CANCELLED' ### Response Example - Success ```json { "result": "SUCCESS", "data": { "wallet": "0x1Ed17b06961B9B8DE78Ee924BcDaBC003aaE1867", "signature": "0xba099e3ab31b8bf1201d2de2d0e4d81f7162f5de6993a960988959ff97be45b27d284a6e29d065cd175122953cf861725906639dc1f3229e66ff8b9d5820634a1b", "message": "web3-miniapps-svc.svc.staging.lemon wants you to sign in with your Ethereum account:\n0x1Ed17b06961B9B8DE78Ee924BcDaBC003aaE1867\n\nSign in with Ethereum to the app cbbe623b-be3d-4796-aa61-c93253a0a3af.\n\nURI: http://web3-miniapps-svc.svc.staging.lemon/auth/cbbe623b-be3d-4796-aa61-c93253a0a3af\nVersion: 1\nChain ID: 80002\nNonce: l3m0nc45h\nIssued At: 2025-09-03T19:02:52.697Z" } } ``` ### Response Example - Failed ```json { "result": "FAILED", "error": { "message": "Invalid signature", "code": "INVALID_SIGNATURE" } } ``` ### Response Example - Cancelled ```json { "result": "CANCELLED" } ``` ``` -------------------------------- ### Basic React Component for Lemon Cash Authentication Source: https://lemoncash.mintlify.app/functions/authenticate A simple React component demonstrating the usage of the `authenticate` function from the Lemon Cash Mini App SDK. It initializes the wallet state and calls the authentication handler on component mount. ```javascript import { authenticate, TransactionResult } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const [wallet, setWallet] = useState(undefined); const handleAuthentication = async () => { const result = await authenticate(); if (result.result === TransactionResult.SUCCESS) { setWallet(result.data.wallet); } }; useEffect(() => { handleAuthentication(); }, []); }; ``` -------------------------------- ### Implement Deposit Functionality in TypeScript Source: https://lemoncash.mintlify.app/llms-full.txt This code snippet demonstrates how to integrate deposit functionality into a React Mini App using the '@lemoncash/mini-app-sdk'. It includes error handling for the deposit operation and displays a button to initiate the transaction. The function requires amount and tokenName as input and logs the transaction hash upon success. ```typescript import React from 'react'; import { deposit } from '@lemoncash/mini-app-sdk'; export const MiniApp = () => { const handleDeposit = async () => { try { const result = await deposit({ amount: '100', tokenName: 'USDC', }); console.log('Deposit successful:', result.txHash); } catch (error) { console.error('Deposit failed:', error); throw error; } }; return ( ); }; ``` -------------------------------- ### Authentication Flow - Frontend Integration Source: https://lemoncash.mintlify.app/llms-full.txt React component that orchestrates the complete authentication flow. Calls the nonce endpoint, requests user signature via the mini-app SDK, and verifies the signature on the backend. Handles success and cancellation states. ```APIDOC ## Authentication Flow ### Description Complete frontend authentication workflow using the LemonCash mini-app SDK. The flow includes: (1) fetching a nonce from the backend, (2) requesting user signature with the nonce, (3) verifying the signature on the backend, and (4) establishing the authenticated session. ### Flow Steps #### Step 1: Get Nonce from Backend ``` GET /api/auth/nonce Request: No body Response: { nonce: string } ``` #### Step 2: Request Signature from User ``` authenticate({ nonce, chainId: ChainId.POLYGON_AMOY }) Response: { wallet, signature, message } ``` #### Step 3: Verify Signature on Backend ``` POST /api/auth/verify Request: { wallet, signature, message, nonce } Response: { verified: boolean, wallet: string } ``` ### Error Handling - **TransactionResult.FAILED** - Authentication request failed with error code and message - **TransactionResult.CANCELLED** - User cancelled the authentication request - **Failed verification** - Backend signature verification returned false ### Frontend Implementation Details - Use getNonceFromBackend() to fetch fresh nonce before each auth attempt - Chain ID set to POLYGON_AMOY for Polygon Amoy testnet - Verify result status before processing response data - Set wallet state on successful verification - Trigger authentication on component mount with useEffect ``` -------------------------------- ### Verify Signature with Fetch API Source: https://lemoncash.mintlify.app/llms-full.txt This code snippet demonstrates how to verify a user's signature using the Fetch API. It sends a POST request to the '/api/auth/verify' endpoint with wallet, signature, message, and nonce. It handles potential network errors and returns the JSON response. ```typescript async function verifySignature(wallet: string, signature: string, message: string, nonce: string) { const response = await fetch('/api/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ wallet, signature, message, nonce, }), }); if (!response.ok) { throw new Error('Failed to verify signature'); } return response.json(); } ``` -------------------------------- ### Frontend: API - Verify Signature on Backend (TypeScript) Source: https://context7_llms This API helper function is used on the frontend to send the wallet address, signature, message, and nonce to the backend for signature verification. It's a crucial part of the authentication process, ensuring the user's identity. ```typescript // API function to verify signature on backend export async function verifySignatureOnBackend({ wallet, signature, message, nonce, }: { wallet: string; signature: string; message: string; nonce: string; }) { ``` -------------------------------- ### Call Smart Contract API Source: https://lemoncash.mintlify.app/llms-full.txt This API allows you to interact with smart contracts on the blockchain. You can specify the contract address, function name, parameters, and value to be sent. Optional fields include contract standard, chain ID, permits, and values for interpolating into the title and description. ```APIDOC ## POST /call-smart-contract ### Description Allows interaction with smart contracts by specifying contract details, function, parameters, and value. Supports optional fields for contract standards, chain IDs, permits, and dynamic text interpolation for titles and descriptions. ### Method POST ### Endpoint /call-smart-contract #### Request Body - **contractAddress** (0x${string}) - Required - The address of the smart contract to interact with. - **functionName** (string) - Required - The name of the smart contract function to call. - **functionParams** (string | number[]) - Required - The parameters to pass to the smart contract function. Use an empty array if no parameters are needed. - **value** (string) - Required - The amount of native currency (ETH, POL, etc.) to send with the transaction. Specify '0' if no native token is transferred. - **contractStandard** (ContractStandard) - Optional - The contract standard if any (e.g., 'ERC20'). - **chainId** (ChainId) - Optional - The chain ID to use if the Mini App supports multiple chains. - **permits** (Permit[]) - Optional - An array of Permit2 permits for token approvals. Each permit includes owner, token, spender, amount, deadline, and nonce. - **titleValues** (Record) - Optional - Values to interpolate into the method title using `{{key}}` placeholders. - **descriptionValues** (Record) - Optional - Values to interpolate into the method description using `{{key}}` placeholders. ### Request Example ```json { "contractAddress": "0x1234567890abcdef1234567890abcdef12345678", "functionName": "transfer", "functionParams": ["0xRecipientAddress", 1000000], "value": "0", "contractStandard": "ERC20", "titleValues": { "amount": "1", "token": "USDC" }, "descriptionValues": { "from": "0xSenderAddress", "to": "0xRecipientAddress" } } ``` ### Response #### Success Response (200) - **result** (TransactionResult) - The result of the smart contract call. Can be 'SUCCESS', 'FAILED', or 'CANCELLED'. - **data** (object) - Contains the transaction hash if the result is 'SUCCESS'. - **txHash** (string) - The transaction hash. - **error** (MiniAppError) - Contains error information if the result is 'FAILED'. - **message** (string) - The error message. - **code** (string) - The error code. #### Response Example ```json { "result": "SUCCESS", "data": { "txHash": "0x1234567890123456789012345678901234567890" } } ``` #### Error Response Example (FAILED) ```json { "result": "FAILED", "error": { "message": "Insufficient balance", "code": "INSUFFICIENT_BALANCE" } } ``` #### Response Example (CANCELLED) ```json { "result": "CANCELLED" } ``` ``` -------------------------------- ### Authenticate with Chain ID Source: https://context7_llms Demonstrates how to specify a particular chain ID for the authentication request if the Mini App supports multiple blockchains. This ensures the authentication occurs on the intended network. ```typescript import { ChainId } from '@lemoncash/mini-app-sdk'; await authenticate({ chainId: ChainId.POLYGON_AMOY, }); ``` -------------------------------- ### Message Signing and Verification Source: https://eips.ethereum.org/EIPS/eip-4361 Outlines the methods for signing and verifying SIWE messages using Ethereum accounts. ```APIDOC ## Signing and Verifying Messages with Ethereum Accounts * For Externally Owned Accounts (EOAs), the verification method specified in ERC-191 MUST be used. * For Contract Accounts, the verification method specified in ERC-1271 MUST be used. ``` -------------------------------- ### Frontend Authentication Flow (React/TypeScript) Source: https://lemoncash.mintlify.app/llms-full.txt React component that orchestrates the authentication process. It fetches a nonce from the backend, requests a signature from the user via the Lemon Cash Mini App SDK, and then sends the signature and message back to the backend for verification. Requires an API module for backend communication. ```typescript import React, { useState, useEffect } from 'react'; import { authenticate, ChainId, TransactionResult } from '@lemoncash/mini-app-sdk'; import { getNonceFromBackend, verifySignatureOnBackend } from './api'; export const MiniApp: React.FC = () => { const [wallet, setWallet] = useState(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.FAILED) { throw new Error(`Authentication failed: ${result.error.message} (${result.error.code})`); } if (result.result === TransactionResult.CANCELLED) { throw new Error('Authentication was cancelled by the user'); } const { wallet, signature, message } = result.data; // 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 (

Wallet

Connected: {wallet ? '✅ Connected' : '❌ Not connected'}

{wallet && (

{wallet}

)}
); }; ``` -------------------------------- ### Call Smart Contract - Batch Transaction Source: https://context7_llms This snippet shows how to execute multiple smart contract calls in a single batch transaction. It allows for sequential execution of different contract functions, such as 'transfer' and 'deposit', by providing an array of contract interaction objects. ```typescript await callSmartContract({ contracts: [ { contractAddress: "0x1234567890123456789012345678901234567890", functionName: "transfer", functionParams: ["0x0987654321098765432109876543210987654321", "1000000"], value: "0", }, { contractAddress: "0x1234567890123456789012345678901234567890", functionName: "deposit", functionParams: ["0x0987654321098765432109876543210987654321", "1000000"], value: "0", }, ], }); ``` -------------------------------- ### TypeScript Type Definitions for Mini App SDK Source: https://lemoncash.mintlify.app/llms-full.txt This code snippet defines various TypeScript types and enums used within the Lemon Cash Mini App SDK. It includes definitions for `MiniAppError`, `Address`, `Hex`, `TransactionResult`, `ChainId`, `TokenName`, and `ContractStandard`, providing a structured way to interact with SDK functionalities. ```typescript type MiniAppError = { message: string; code: string; }; type Address = `0x${string}`; type Hex = `0x${string}`; enum TransactionResult { SUCCESS = 'SUCCESS', FAILED = 'FAILED', CANCELLED = 'CANCELLED', } enum ChainId { // Mainnet ARBITRUM_ONE = 42161, BASE = 8453, ETH = 1, OP_MAINNET = 10, POLYGON = 137, // Testnet ARBITRUM_SEPOLIA = 421614, ETH_HOODI = 560048, ETH_SEPOLIA = 11155111, POLYGON_AMOY = 80002, } enum TokenName { ETH = 'ETH', POL = 'POL', USDC = 'USDC', USDT = 'USDT', } enum ContractStandard { ERC20 = 'ERC20', } ``` -------------------------------- ### Verify Signature API POST Request Source: https://context7_llms This snippet demonstrates how to send a POST request to the /api/auth/verify endpoint to verify a user's signature. It includes setting the 'Content-Type' header to 'application/json' and passing wallet, signature, message, and nonce in the request body. The function throws an error if the response is not ok and returns the JSON response upon success. ```typescript const response = await fetch('/api/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ wallet, signature, message, nonce, }), }); if (!response.ok) { throw new Error('Failed to verify signature'); } return response.json(); ``` -------------------------------- ### Authenticate User with SIWE using Lemon Cash SDK (JavaScript) Source: https://lemoncash.mintlify.app/functions/authenticate Demonstrates how to authenticate a user using the `authenticate` function from the Lemon Cash Mini App SDK. It fetches a nonce, requests the signature, and updates the UI based on the transaction result. This snippet is intended for frontend React components. ```javascript import React, { useState, useEffect } from 'react'; import { authenticate, ChainId, TransactionResult } from '@lemoncash/mini-app-sdk'; import { getNonceFromBackend, verifySignatureOnBackend } from './api'; export const MiniApp: React.FC = () => { const [wallet, setWallet] = useState(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.FAILED) { throw new Error(`Authentication failed: ${result.error.message} (${result.error.code})`); } if (result ``` -------------------------------- ### TypeScript Type Definitions for Mini App SDK Source: https://context7_llms This snippet defines various type aliases and enums used within the Lemon Cash Mini App SDK. It includes `MiniAppError` for error handling, `Address` and `Hex` for blockchain data, `TransactionResult` for operation outcomes, `ChainId` for network identification, `TokenName` for supported tokens, and `ContractStandard` for smart contract types. These types ensure type safety and clarity in SDK usage. ```typescript type MiniAppError = { message: string; code: string; }; type Address = `0x${string}`; type Hex = `0x${string}`; enum TransactionResult { SUCCESS = 'SUCCESS', FAILED = 'FAILED', CANCELLED = 'CANCELLED', } enum ChainId { // Mainnet ARBITRUM_ONE = 42161, BASE = 8453, ETH = 1, OP_MAINNET = 10, POLYGON = 137, // Testnet ARBITRUM_SEPOLIA = 421614, ETH_HOODI = 560048, ETH_SEPOLIA = 11155111, POLYGON_AMOY = 80002, } enum TokenName { ETH = 'ETH', POL = 'POL', USDC = 'USDC', USDT = 'USDT', } enum ContractStandard { ERC20 = 'ERC20', } ``` -------------------------------- ### Mini App Deeplink URLs - Lemon Cash Source: https://context7_llms Deeplink URL schemes for directing users to Mini Apps. Includes two main endpoints: one for displaying the Mini App detail page and another for launching the Mini App in a webview. The mini-app-id parameter must be obtained from the Lemon Cash team. ```url lemoncash://app/mini-apps/detail/:mini-app-id ``` ```url lemoncash://app/mini-apps/webview/:mini-app-id ```