import React, { useState, useEffect } from 'react'; import { getStoredCredentials, storeCredentials, clearStoredCredentials, } from '@/services/tradingService.browser'; interface APIKeyManagerProps { isApiActive: boolean; onToggleApiStatus: () => void; } const APIKeyManager: React.FC = ({ isApiActive, onToggleApiStatus }) => { const [apiKeyInput, setApiKeyInput] = useState(''); const [apiSecretInput, setApiSecretInput] = useState(''); const [mode, setMode] = useState<'live' | 'testnet'>('testnet'); const [keysSaved, setKeysSaved] = useState(false); const [isEditing, setIsEditing] = useState(false); const [hasStoredSecret, setHasStoredSecret] = useState(false); useEffect(() => { async function loadStored() { const stored = await getStoredCredentials(); if (stored) { setApiKeyInput(stored.apiKey); setMode(stored.mode); setKeysSaved(true); setHasStoredSecret(Boolean(stored.apiSecret)); } } loadStored(); }, []); const handleSave = async () => { const trimmedKey = apiKeyInput.trim(); const trimmedSecret = apiSecretInput.trim(); if (!trimmedKey) { alert('API Key cannot be empty.'); return; } // If the secret input is empty but a secret already exists for this key, // keep the existing secret. Otherwise require a secret. let secretToPersist = trimmedSecret; if (!secretToPersist) { const existing = await getStoredCredentials(trimmedKey); const existingSecret = existing?.apiSecret ?? ''; if (!existingSecret) { alert('Secret Key cannot be empty.'); return; } secretToPersist = existingSecret; } await storeCredentials({ apiKey: trimmedKey, apiSecret: secretToPersist, mode }); setKeysSaved(true); setIsEditing(false); setApiSecretInput(''); setHasStoredSecret(true); alert('API keys saved successfully.'); }; const handleEdit = async () => { const stored = await getStoredCredentials(apiKeyInput.trim()); if (stored) { setApiKeyInput(stored.apiKey); setMode(stored.mode); setHasStoredSecret(Boolean(stored.apiSecret)); } else { setApiKeyInput(''); setMode('testnet'); setHasStoredSecret(false); } setApiSecretInput(''); setIsEditing(true); }; const handleDelete = () => { if (window.confirm('Are you sure you want to delete the API keys? This action cannot be undone.')) { clearStoredCredentials(); setApiKeyInput(''); setApiSecretInput(''); setMode('testnet'); setKeysSaved(false); setIsEditing(false); setHasStoredSecret(false); if (isApiActive) { onToggleApiStatus(); } } }; const handleCancelEdit = async () => { setIsEditing(false); const stored = await getStoredCredentials(); if (stored) { setApiKeyInput(stored.apiKey); setMode(stored.mode); setHasStoredSecret(Boolean(stored.apiSecret)); } else { setApiKeyInput(''); setMode('testnet'); setHasStoredSecret(false); } setApiSecretInput(''); }; const maskApiKey = (key: string) => { if (key.length <= 8) return '****'; return `${key.substring(0, 4)}...${key.substring(key.length - 4)}`; }; const effectiveApiStatus = isApiActive && keysSaved; const modeLabel = mode === 'testnet' ? 'TESTNET' : 'LIVE'; return (

Layer 5: API Management

Manage API keys for trade execution.

{keysSaved ? (effectiveApiStatus ? 'API ACTIVE' : 'API INACTIVE') : 'NO KEY SET'} {keysSaved && ( {modeLabel} MODE )}
{keysSaved && !isEditing ? (
HMAC

Primary Trading Key

{modeLabel} MODE

API Key

{maskApiKey(apiKeyInput)}

Secret Key

**************************************************

Trading Mode

{mode === 'testnet' ? 'Binance Testnet (Paper Trading)' : 'Binance Live Trading'}

Permissions:

✓ Read Info ✓ Enable Trading ✗ Enable Withdrawals
) : (

{isEditing ? 'Edit API Keys' : 'Add New API Key'}

setApiKeyInput(e.target.value)} placeholder="Enter your API key" className="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-primary text-gray-200" />
setApiSecretInput(e.target.value)} placeholder="Enter your secret key" className="w-full bg-gray-700 border border-gray-600 rounded-md py-2 px-3 focus:outline-none focus:ring-2 focus:ring-primary text-gray-200" />
{isEditing && ( )}
)}
); }; export default APIKeyManager;