From 5a589469f5e716e415542779bbdd817d79a61cad Mon Sep 17 00:00:00 2001 From: zramsay Date: Fri, 21 Mar 2025 17:17:30 -0400 Subject: [PATCH] try --- README.md | 56 +++++++++++++++++++ src/services/blockchain/seiService.ts | 50 +---------------- src/services/blockchain/tokenRewardService.ts | 37 ++++++++++-- 3 files changed, 88 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index b7c3536..c661d18 100644 --- a/README.md +++ b/README.md @@ -114,3 +114,59 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key - Details about each uploaded image - The system prevents duplicate image uploads and point awards - Only authenticated users can earn and view points + +## WILD Token Integration with Sei Blockchain + +This application rewards users with WILD tokens on the Sei blockchain when they identify wildlife images. The token distribution is handled by a secure backend service. + +### User Flow + +1. Users upload wildlife images and earn points in Supabase +2. Users who connect a wallet (Keplr or Leap) also receive WILD tokens automatically +3. Tokens are awarded based on the species identified (rare species earn more tokens) + +### Backend Service Setup + +The token distribution backend is located in the `sei-backend-src` directory. + +#### Setup Steps + +1. Navigate to the backend directory: + ```bash + cd sei-backend-src + ``` + +2. Install dependencies: + ```bash + npm install + ``` + +3. Build the service: + ```bash + npm run build + ``` + +4. Configure the service by creating a `.env` file (copy from `.env.example`): + ```bash + cp .env.example .env + ``` + +5. Edit the `.env` file with your actual configuration: + - `SEI_TOKEN_CONTRACT_ADDRESS`: Your WILD token contract address + - `DISTRIBUTOR_MNEMONIC`: The mnemonic phrase for your distributor wallet + - `API_KEY`: A secure API key for authentication + +6. Start the service: + ```bash + ./start.sh + ``` + +### Frontend Configuration + +Configure the following environment variables in your frontend's `.env.local`: + +``` +# Token Backend Service +NEXT_PUBLIC_TOKEN_BACKEND_URL=http://localhost:3001 +NEXT_PUBLIC_TOKEN_API_KEY=your-api-key-here +``` diff --git a/src/services/blockchain/seiService.ts b/src/services/blockchain/seiService.ts index 4dc124e..d504fb5 100644 --- a/src/services/blockchain/seiService.ts +++ b/src/services/blockchain/seiService.ts @@ -175,55 +175,7 @@ export const getWalletAddress = (): string | null => { return currentAddress; }; -/** - * Award WILD tokens to a user for wildlife sighting - * This interacts with the Wildlife Token smart contract on Sei - */ -export const awardTokensForWildlife = async ( - species: string, - amount: number = 10 -): Promise<{ success: boolean; txHash?: string; error?: string }> => { - try { - if (!isWalletConnected() || !currentAddress || !cosmWasmClient) { - return { - success: false, - error: 'Wallet not connected' - }; - } - - // WILD token contract address from environment or config - const tokenAddress = NETWORKS.testnet.tokenFactoryAddress; - if (!tokenAddress) { - return { - success: false, - error: 'WILD token contract address not configured' - }; - } - - // Execute CosmWasm contract message to award WILD tokens based on species - // The contract determines the actual amount based on species rarity - const result = await cosmWasmClient.execute( - currentAddress, - tokenAddress, - { award_tokens: { recipient: currentAddress, species: species.toLowerCase() } }, - 'auto', - undefined, // memo - [] // funds - no funds sent with this execution - ); - - console.log('WILD tokens awarded successfully:', result); - return { - success: true, - txHash: result.transactionHash - }; - } catch (error) { - console.error('Error awarding WILD tokens:', error); - return { - success: false, - error: error instanceof Error ? error.message : 'Unknown error during token award' - }; - } -}; +// Award tokens function removed - now handled by the backend service /** * Get WILD token balance for connected wallet diff --git a/src/services/blockchain/tokenRewardService.ts b/src/services/blockchain/tokenRewardService.ts index 5279c98..567764e 100644 --- a/src/services/blockchain/tokenRewardService.ts +++ b/src/services/blockchain/tokenRewardService.ts @@ -1,5 +1,4 @@ // src/services/blockchain/tokenRewardService.ts -import { awardTokensForWildlife } from './seiService'; import { isWalletConnected, getWalletAddress } from './seiService'; // Note: These reward amounts are for display purposes only @@ -75,14 +74,40 @@ export const awardTokensForSighting = async (species: string, points?: number): totalReward = baseReward + rareBonus; } - // Award WILD tokens through Sei contract based on species and amount - const result = await awardTokensForWildlife(species, totalReward); - + // Call the backend service to award tokens through the distributor + const apiUrl = process.env.NEXT_PUBLIC_TOKEN_BACKEND_URL || 'http://localhost:3001'; + const apiKey = process.env.NEXT_PUBLIC_TOKEN_API_KEY || ''; + const walletAddress = getWalletAddress(); + + if (!walletAddress) { + throw new Error('No wallet address available'); + } + + // Request tokens from the backend service + const response = await fetch(`${apiUrl}/api/award-tokens`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'x-api-key': apiKey + }, + body: JSON.stringify({ + recipientAddress: walletAddress, + species: species.toLowerCase() + }) + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.error || 'Error from token service'); + } + + const result = await response.json(); + if (result.success) { - console.log(`Awarded ${totalReward} tokens for ${species} sighting to wallet ${getWalletAddress()}`); + console.log(`Awarded tokens for ${species} sighting to wallet ${walletAddress}`); return { success: true, - tokenAmount: totalReward, + tokenAmount: result.amount, txHash: result.txHash, walletConnected: true };