Exemplos de Uso da API
Esta página demonstra como usar a API da Ekonavi para casos de uso comuns, incluindo integração blockchain e transações on-chain.
Configuração Inicial
Instalação
npm install axios ethers
Configuração Base
import axios from 'axios';
import { ethers } from 'ethers';
const API_BASE = 'https://api.ekonavi.com';
const api = axios.create({
baseURL: API_BASE,
headers: {
'Content-Type': 'application/json'
}
});
// Interceptor para adicionar token automaticamente
api.interceptors.request.use((config) => {
const token = localStorage.getItem('ekonavi_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
1. Autenticação e Login
Login com Email e Senha
async function loginWithEmail(email, password) {
try {
const response = await api.post('/auth/login-email-password', {
email,
password,
redirect: 'https://ekonavi.com/cert/dashboard' // opcional
});
const { token, user } = response.data;
localStorage.setItem('ekonavi_token', token);
localStorage.setItem('ekonavi_user', JSON.stringify(user));
return { success: true, user };
} catch (error) {
console.error('Login failed:', error.response?.data);
return { success: false, error: error.response?.data };
}
}
Login com Carteira Ethereum
async function connectWallet() {
if (!window.ethereum) {
throw new Error('MetaMask não está instalado');
}
try {
// 1. Conectar carteira
await window.ethereum.request({ method: 'eth_requestAccounts' });
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
// 2. Criar mensagem para assinar
const message = `Login na Ekonavi\nAddress: ${address}\nTimestamp: ${Date.now()}`;
// 3. Assinar mensagem
const signature = await signer.signMessage(message);
// 4. Autenticar na API
const response = await api.post('/auth/wallet-connect', {
address,
signature,
message
});
const { token, user } = response.data;
localStorage.setItem('ekonavi_token', token);
localStorage.setItem('ekonavi_wallet', address);
return { success: true, user, address };
} catch (error) {
console.error('Wallet connection failed:', error);
return { success: false, error };
}
}
2. Registrar Prática Sustentável
async function registerSustainablePractice(practiceData) {
try {
const practice = await api.post('/practices', {
type: 'organic_farming', // ou outro tipo
description: practiceData.description,
area_hectares: practiceData.area,
implementation_date: practiceData.date,
evidence_photos: practiceData.photos, // URLs das fotos
location: {
latitude: practiceData.lat,
longitude: practiceData.lng
},
expected_impact: {
carbon_offset_tons: practiceData.carbonOffset,
water_saved_liters: practiceData.waterSaved
}
});
console.log('Prática registrada:', practice.data);
return practice.data;
} catch (error) {
console.error('Erro ao registrar prática:', error.response?.data);
throw error;
}
}
3. Processo de Verificação
Solicitar Verificação
async function requestVerification(practiceId) {
try {
const verification = await api.post('/verifications', {
practice_id: practiceId,
verification_type: 'field_inspection',
notes: 'Solicito verificação para esta prática sustentável'
});
return verification.data;
} catch (error) {
console.error('Erro ao solicitar verificação:', error);
throw error;
}
}
Aprovar Verificação (Verificador)
async function approveVerification(verificationId, verificationData) {
try {
const result = await api.post(`/verifications/${verificationId}/approve`, {
inspector_notes: verificationData.notes,
carbon_impact_verified: verificationData.carbonImpact,
photos_verification: verificationData.photos,
certification_level: 'gold', // bronze, silver, gold
token_reward_amount: verificationData.rewardTokens
});
return result.data;
} catch (error) {
console.error('Erro na aprovação:', error);
throw error;
}
}
4. Transações Blockchain e Tokens
Verificar Saldo de Tokens
async function getTokenBalance(walletAddress) {
try {
const balance = await api.get(`/tokens/balance/${walletAddress}`);
return balance.data;
} catch (error) {
console.error('Erro ao verificar saldo:', error);
throw error;
}
}
Transferir Tokens
async function transferTokens(toAddress, amount, reason) {
try {
// 1. Preparar transação na API
const transferPrep = await api.post('/tokens/prepare-transfer', {
to_address: toAddress,
amount: amount,
reason: reason
});
const { transaction_data, gas_estimate } = transferPrep.data;
// 2. Executar transação na blockchain
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const tx = await signer.sendTransaction({
to: transaction_data.to,
data: transaction_data.data,
gasLimit: gas_estimate,
gasPrice: await provider.getGasPrice()
});
// 3. Confirmar na API
const confirmation = await api.post('/tokens/confirm-transfer', {
transaction_hash: tx.hash,
transfer_id: transferPrep.data.transfer_id
});
// 4. Aguardar confirmação na blockchain
const receipt = await tx.wait();
return {
success: true,
transaction_hash: tx.hash,
block_number: receipt.blockNumber,
confirmation: confirmation.data
};
} catch (error) {
console.error('Erro na transferência:', error);
throw error;
}
}
Mintar Tokens de Recompensa (Admin)
async function mintRewardTokens(farmerAddress, amount, practiceId) {
try {
const mint = await api.post('/tokens/mint', {
to_address: farmerAddress,
amount: amount,
practice_id: practiceId,
reason: 'sustainable_practice_reward'
});
return mint.data;
} catch (error) {
console.error('Erro ao mintar tokens:', error);
throw error;
}
}
5. Dados On-Chain e Transparência
Registrar Dados na Blockchain
async function submitDataOnChain(verificationData) {
try {
// 1. Criar hash dos dados para blockchain
const dataHash = ethers.keccak256(
ethers.toUtf8Bytes(JSON.stringify(verificationData))
);
// 2. Registrar hash na blockchain
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
// Contrato inteligente da Ekonavi (exemplo)
const contractAddress = '0x...'; // endereço do contrato
const contractABI = [
"function recordVerification(bytes32 dataHash, uint256 practiceId) external",
"function getVerification(uint256 practiceId) external view returns (bytes32)"
];
const contract = new ethers.Contract(contractAddress, contractABI, signer);
// 3. Executar transação
const tx = await contract.recordVerification(dataHash, verificationData.practiceId);
const receipt = await tx.wait();
// 4. Confirmar na API
await api.post('/blockchain/confirm-record', {
transaction_hash: tx.hash,
block_number: receipt.blockNumber,
data_hash: dataHash,
practice_id: verificationData.practiceId
});
return {
success: true,
transaction_hash: tx.hash,
data_hash: dataHash,
block_number: receipt.blockNumber
};
} catch (error) {
console.error('Erro ao registrar na blockchain:', error);
throw error;
}
}
6. Monitoramento e Analytics
Obter Estatísticas do Agricultor
async function getFarmerStats(farmerId) {
try {
const [
farmer,
practices,
verifications,
tokens
] = await Promise.all([
api.get(`/farmers/${farmerId}`),
api.get(`/farmers/${farmerId}/practices`),
api.get(`/verifications?farmer_id=${farmerId}`),
api.get(`/tokens/balance/${farmerId}`)
]);
return {
farmer: farmer.data,
total_practices: practices.data.length,
verified_practices: verifications.data.filter(v => v.status === 'approved').length,
token_balance: tokens.data.balance,
carbon_offset: practices.data.reduce((sum, p) => sum + (p.carbon_impact || 0), 0)
};
} catch (error) {
console.error('Erro ao obter estatísticas:', error);
throw error;
}
}
Dashboard de Impacto Global
async function getGlobalImpactData() {
try {
const stats = await api.get('/public/stats');
return {
total_farmers: stats.data.farmers_count,
total_practices: stats.data.practices_count,
total_carbon_offset: stats.data.carbon_offset_tons,
total_tokens_distributed: stats.data.tokens_distributed,
verified_practices: stats.data.verified_practices_count
};
} catch (error) {
console.error('Erro ao obter dados globais:', error);
throw error;
}
}
7. Integração Completa - Fluxo Agricultor
class EkonaviFarmerSDK {
constructor(apiKey) {
this.api = axios.create({
baseURL: API_BASE,
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
}
async registerAndVerifyPractice(practiceData) {
try {
// 1. Registrar prática
const practice = await this.api.post('/practices', practiceData);
// 2. Solicitar verificação
const verification = await this.api.post('/verifications', {
practice_id: practice.data.id,
verification_type: 'field_inspection'
});
// 3. Monitorar status da verificação
const verificationStatus = await this.waitForVerification(verification.data.id);
// 4. Se aprovada, verificar tokens recebidos
if (verificationStatus.status === 'approved') {
const tokenBalance = await this.api.get('/tokens/balance/me');
return {
practice: practice.data,
verification: verificationStatus,
tokens_earned: verificationStatus.token_reward_amount,
current_balance: tokenBalance.data.balance
};
}
return { practice: practice.data, verification: verificationStatus };
} catch (error) {
console.error('Erro no fluxo completo:', error);
throw error;
}
}
async waitForVerification(verificationId, maxAttempts = 30) {
for (let i = 0; i < maxAttempts; i++) {
const verification = await this.api.get(`/verifications/${verificationId}`);
if (verification.data.status !== 'pending') {
return verification.data;
}
// Aguardar 10 segundos antes de tentar novamente
await new Promise(resolve => setTimeout(resolve, 10000));
}
throw new Error('Timeout aguardando verificação');
}
}
Tratamento de Erros
// Interceptor global para tratamento de erros
api.interceptors.response.use(
(response) => response,
(error) => {
if (error.response?.status === 401) {
// Token expirado, redirecionar para login
localStorage.removeItem('ekonavi_token');
window.location.href = '/login';
} else if (error.response?.status === 429) {
// Rate limit excedido
console.warn('Rate limit excedido, aguarde antes de tentar novamente');
}
return Promise.reject(error);
}
);