135 lines
No EOL
3.8 KiB
TypeScript
135 lines
No EOL
3.8 KiB
TypeScript
import {
|
|
ApiResponse,
|
|
Exchange,
|
|
ExchangeDetails,
|
|
ExchangeStats,
|
|
ProviderMapping,
|
|
ProviderExchange,
|
|
CreateExchangeRequest,
|
|
UpdateExchangeRequest,
|
|
CreateProviderMappingRequest,
|
|
UpdateProviderMappingRequest,
|
|
} from '../types';
|
|
|
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:4000/api';
|
|
|
|
class ExchangeApiService {
|
|
private async request<T>(
|
|
endpoint: string,
|
|
options?: RequestInit
|
|
): Promise<ApiResponse<T>> {
|
|
const url = `${API_BASE_URL}${endpoint}`;
|
|
|
|
const response = await fetch(url, {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options?.headers,
|
|
},
|
|
...options,
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!data.success) {
|
|
throw new Error(data.error || 'API request failed');
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
// Exchanges
|
|
async getExchanges(): Promise<Exchange[]> {
|
|
const response = await this.request<Exchange[]>('/exchanges');
|
|
return response.data || [];
|
|
}
|
|
|
|
async getExchangeById(id: string): Promise<ExchangeDetails | null> {
|
|
const response = await this.request<ExchangeDetails>(`/exchanges/${id}`);
|
|
return response.data || null;
|
|
}
|
|
|
|
async createExchange(data: CreateExchangeRequest): Promise<Exchange> {
|
|
const response = await this.request<Exchange>('/exchanges', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.data) {
|
|
throw new Error('No exchange data returned');
|
|
}
|
|
return response.data;
|
|
}
|
|
|
|
async updateExchange(id: string, data: UpdateExchangeRequest): Promise<Exchange> {
|
|
const response = await this.request<Exchange>(`/exchanges/${id}`, {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.data) {
|
|
throw new Error('No exchange data returned');
|
|
}
|
|
return response.data;
|
|
}
|
|
|
|
// Provider Mappings
|
|
async getProviderMappings(provider?: string): Promise<ProviderMapping[]> {
|
|
const endpoint = provider
|
|
? `/exchanges/provider-mappings/${provider}`
|
|
: '/exchanges/provider-mappings/all';
|
|
|
|
const response = await this.request<ProviderMapping[]>(endpoint);
|
|
return response.data || [];
|
|
}
|
|
|
|
async createProviderMapping(data: CreateProviderMappingRequest): Promise<ProviderMapping> {
|
|
const response = await this.request<ProviderMapping>('/exchanges/provider-mappings', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.data) {
|
|
throw new Error('No provider mapping data returned');
|
|
}
|
|
return response.data;
|
|
}
|
|
|
|
async updateProviderMapping(
|
|
id: string,
|
|
data: UpdateProviderMappingRequest
|
|
): Promise<ProviderMapping> {
|
|
const response = await this.request<ProviderMapping>(`/exchanges/provider-mappings/${id}`, {
|
|
method: 'PATCH',
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.data) {
|
|
throw new Error('No provider mapping data returned');
|
|
}
|
|
return response.data;
|
|
}
|
|
|
|
// Providers and Utilities
|
|
async getProviders(): Promise<string[]> {
|
|
const response = await this.request<string[]>('/exchanges/providers/list');
|
|
return response.data || [];
|
|
}
|
|
|
|
async getUnmappedProviderExchanges(provider: string): Promise<ProviderExchange[]> {
|
|
const response = await this.request<ProviderExchange[]>(
|
|
`/exchanges/provider-exchanges/unmapped/${provider}`
|
|
);
|
|
return response.data || [];
|
|
}
|
|
|
|
async getExchangeStats(): Promise<ExchangeStats> {
|
|
const response = await this.request<ExchangeStats>('/exchanges/stats/summary');
|
|
if (!response.data) {
|
|
throw new Error('No exchange stats data returned');
|
|
}
|
|
return response.data;
|
|
}
|
|
}
|
|
|
|
// Export singleton instance
|
|
export const exchangeApi = new ExchangeApiService(); |