The Recovery API Integration provides a complete solution for fetching and managing wallet recovery status from a backend API. It includes error handling, retry logic, polling capabilities, and comprehensive state management.
Handles all HTTP communication with the recovery API.
Key Functions:
Fetches the current recovery status for a wallet.
Parameters:
walletId(string) - The wallet ID to fetch status forconfig(optional) - API configuration:baseUrl- API base URL (default:process.env.NEXT_PUBLIC_API_URL)timeout- Request timeout in ms (default: 10000)retryAttempts- Number of retry attempts (default: 3)retryDelay- Delay between retries in ms (default: 1000)
Returns:
{
success: boolean
data?: RecoveryTimeline
error?: string
timestamp: number
}Features:
- Automatic retry with exponential backoff
- Request timeout handling
- Response validation
- Date parsing
- Error classification
Example:
const result = await fetchRecoveryStatus("wallet-123");
if (result.success) {
console.log("Recovery status:", result.data);
} else {
console.error("Error:", result.error);
}Fetches timeline events for a specific recovery.
Parameters:
recoveryId(string) - The recovery timeline IDconfig(optional) - API configuration
Returns:
{
success: boolean
data?: RecoveryTimelineEvent[]
error?: string
timestamp: number
}Example:
const result = await fetchRecoveryEvents("recovery-123");
if (result.success) {
result.data?.forEach(event => {
console.log(event.title, event.status);
});
}Polls recovery status at regular intervals.
Parameters:
walletId(string) - The wallet ID to pollinterval(number) - Polling interval in ms (default: 5000)maxDuration(number) - Max polling duration in ms (default: 300000)onUpdate(function) - Callback for status updatesconfig(optional) - API configuration
Returns:
- Function to stop polling
Features:
- Automatic polling at intervals
- Stops when recovery completes or fails
- Respects max duration
- Error handling
Example:
const stop = pollRecoveryStatus(
"wallet-123",
5000,
300000,
(response) => {
if (response.success) {
console.log("Status:", response.data?.status);
}
}
);
// Stop polling later
stop();Manages recovery status state and API integration.
Hook Signature:
useRecoveryStatus(walletId, options?)Parameters:
walletId(string | null) - The wallet IDoptions(optional):autoFetch(boolean) - Auto-fetch on mount (default: true)pollInterval(number) - Polling interval in ms (default: 5000)maxPollDuration(number) - Max polling duration in ms (default: 300000)onStatusChange(function) - Callback when status changesonError(function) - Callback when error occurs
Returns:
{
// State
timeline: RecoveryTimeline | null
loading: "idle" | "loading" | "success" | "error"
error: string | null
isStale: boolean
lastFetchTime: number | null
// Methods
refetch: () => Promise<void>
startPolling: () => void
stopPolling: () => void
markAsStale: () => void
clearError: () => void
// Computed
isLoading: boolean
isError: boolean
isSuccess: boolean
isIdle: boolean
}Features:
- Automatic fetching on mount
- Polling for in-progress recoveries
- Stale state detection
- Error handling
- Cleanup on unmount
Example:
const {
timeline,
loading,
error,
refetch,
isStale,
} = useRecoveryStatus("wallet-123", {
autoFetch: true,
pollInterval: 5000,
onStatusChange: (timeline) => {
console.log("Status updated:", timeline.status);
},
onError: (error) => {
console.error("Error:", error);
},
});
if (loading === "loading") return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (timeline) return <RecoveryTimelineList events={timeline.events} />;Fetches the current recovery status for a wallet.
Response:
{
"id": "recovery-123",
"walletId": "wallet-123",
"startedAt": "2025-01-20T10:00:00Z",
"completedAt": "2025-01-20T10:35:00Z",
"status": "completed",
"totalDuration": 2100000,
"events": [
{
"id": "event-001",
"type": "initiated",
"status": "completed",
"title": "Recovery Initiated",
"description": "Wallet recovery process started",
"timestamp": "2025-01-20T10:00:00Z",
"details": "User initiated recovery"
}
]
}Fetches timeline events for a specific recovery.
Response:
[
{
"id": "event-001",
"type": "initiated",
"status": "completed",
"title": "Recovery Initiated",
"description": "Wallet recovery process started",
"timestamp": "2025-01-20T10:00:00Z"
}
]Network Errors
- Retryable: true
- Message: "Network error occurred. Please check your connection."
Timeout Errors
- Retryable: true
- Message: "Request timed out. Please try again."
HTTP 4xx Errors
- Retryable: false (except 408)
- Message: HTTP status message
HTTP 5xx Errors
- Retryable: true
- Message: HTTP status message
Validation Errors
- Retryable: false
- Message: "Invalid recovery timeline data received from API"
- Automatic retry with exponential backoff
- Configurable retry attempts (default: 3)
- Configurable retry delay (default: 1000ms)
- Exponential backoff: delay * (attempt + 1)
Example:
Attempt 1: Immediate
Attempt 2: After 1000ms
Attempt 3: After 2000ms
idle- Initial state, no fetch in progressloading- Fetch in progresssuccess- Fetch completed successfullyerror- Fetch failed
- Data marked as stale after 60 seconds
- Checked every 30 seconds
- Can be manually marked as stale
- Indicates data needs refresh
- Automatically starts when recovery status is "in_progress"
- Stops when recovery status is "completed" or "failed"
- Respects max polling duration
const { startPolling, stopPolling } = useRecoveryStatus("wallet-123");
// Start polling
startPolling();
// Stop polling
stopPolling();# API base URL
NEXT_PUBLIC_API_URL=https://api.example.com
# Optional: API timeout (milliseconds)
NEXT_PUBLIC_API_TIMEOUT=10000
# Optional: Retry attempts
NEXT_PUBLIC_API_RETRY_ATTEMPTS=3
# Optional: Retry delay (milliseconds)
NEXT_PUBLIC_API_RETRY_DELAY=1000const result = await fetchRecoveryStatus("wallet-123", {
baseUrl: "https://custom-api.com",
timeout: 15000,
retryAttempts: 5,
retryDelay: 2000,
});- Successful status fetching
- Error handling (network, timeout, HTTP)
- Retry logic with exponential backoff
- Response validation
- Date parsing
- Polling behavior
- Configuration options
Test Count: 40+ tests
- Initial state
- Auto-fetching
- Manual refetching
- Polling behavior
- Callbacks (onStatusChange, onError)
- Stale state detection
- Error handling
- Loading states
- Cleanup on unmount
- Edge cases
Test Count: 50+ tests
Total Test Coverage: 90+ tests
import { useRecoveryStatus } from "@/hooks/useRecoveryStatus";
import { RecoveryTimelineList } from "@/components/recovery/RecoveryTimelineList";
export function RecoveryPage() {
const { timeline, loading, error } = useRecoveryStatus("wallet-123");
if (loading === "loading") return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!timeline) return <div>No recovery data</div>;
return <RecoveryTimelineList events={timeline.events} />;
}const { timeline, loading, error } = useRecoveryStatus("wallet-123", {
onStatusChange: (timeline) => {
console.log("Recovery status:", timeline.status);
if (timeline.status === "completed") {
showSuccessNotification("Recovery completed!");
}
},
onError: (error) => {
console.error("Recovery error:", error);
showErrorNotification(error);
},
});const { timeline, startPolling, stopPolling } = useRecoveryStatus(
"wallet-123",
{ autoFetch: false }
);
// Start polling manually
const handleStartPolling = () => {
startPolling();
};
// Stop polling manually
const handleStopPolling = () => {
stopPolling();
};const { timeline, isStale, markAsStale, refetch } = useRecoveryStatus(
"wallet-123"
);
// Check if data is stale
if (isStale) {
return (
<div>
<p>Data is stale. Please refresh.</p>
<button onClick={refetch}>Refresh</button>
</div>
);
}Evidence:
- 90+ comprehensive test cases
- Complete API service documentation
- Hook documentation with usage examples
- API endpoint documentation
- Error handling documentation
- Configuration documentation
Evidence:
- Tests verify API integration
- Mock data covers all scenarios
- Error state handling tested
- Polling behavior tested
- State transitions validated
- No breaking changes to existing APIs
Evidence:
- Stale state detection implemented
- Network error handling with retry
- Timeout handling with retry
- Invalid response validation
- Missing data handling
- Disconnected state management
Evidence:
- Uses existing hook patterns
- Follows TypeScript strict mode
- Integrates with existing components
- Uses existing utility functions
- Matches project file organization
- Follows existing test patterns
Evidence:
- API service in src/services/recoveryApi.ts
- Hook in src/hooks/useRecoveryStatus.ts
- Tests in tests directories
- All changes follow existing patterns
- No modifications to existing components
Evidence:
- useRecoveryStatus hook manages state
- Auto-fetching on mount
- Polling for in-progress recoveries
- Stale state detection
- Error state management
- Cleanup on unmount
- Efficient polling with configurable intervals
- Automatic polling stops when recovery completes
- Exponential backoff prevents server overload
- Request timeout prevents hanging requests
- Stale state detection prevents unnecessary refetches
- Validates all API responses
- Handles errors gracefully
- No sensitive data in logs
- Respects API rate limits
- Timeout protection
- WebSocket support for real-time updates
- Caching layer for repeated requests
- Offline support with local storage
- Request deduplication
- Advanced error recovery strategies
- Analytics and monitoring
- Check
NEXT_PUBLIC_API_URLenvironment variable - Verify API server is running
- Check network connectivity
- Review browser console for errors
- Verify recovery status is "in_progress"
- Check
pollIntervalconfiguration - Verify
maxPollDurationis sufficient - Check for errors in console
- Call
refetch()to refresh data - Check
lastFetchTimeto see when data was fetched - Verify
isStaleflag - Check network connectivity
- Increase
timeoutconfiguration - Check API server performance
- Verify network latency
- Check for server-side issues