UNPKG

defarm-sdk

Version:

DeFarm SDK - On-premise blockchain data processing and tokenization engine for agriculture supply chain

449 lines (391 loc) 12.4 kB
import type { Asset } from '../types'; import { EventEmitter } from 'events'; import { DeFarmSDKError, ErrorCode } from '../utils'; export interface PremiumAPIConfig { baseUrl: string; apiKey: string; timeout?: number; retries?: number; version?: string; } export interface QualityScore { overall: number; factors: { completeness: number; accuracy: number; consistency: number; freshness: number; }; recommendations: string[]; } export interface FraudDetection { riskScore: number; alerts: Array<{ type: 'data_inconsistency' | 'unusual_pattern' | 'duplicate_detected' | 'temporal_anomaly'; severity: 'low' | 'medium' | 'high' | 'critical'; message: string; evidence: any; }>; confidence: number; } export interface ComplianceCheck { passed: boolean; checks: Array<{ rule: string; status: 'pass' | 'fail' | 'warning'; message: string; regulation: string; }>; certifications: string[]; } export interface MarketIntelligence { pricing: { current: number; currency: string; trend: 'up' | 'down' | 'stable'; confidence: number; }; demand: { level: 'low' | 'medium' | 'high' | 'very_high'; forecast: number[]; factors: string[]; }; competition: { suppliers: number; marketShare: number; competitive_advantage: string[]; }; } export interface RiskAssessment { overall: number; categories: { operational: number; financial: number; regulatory: number; environmental: number; market: number; }; recommendations: Array<{ category: string; priority: 'low' | 'medium' | 'high' | 'critical'; action: string; impact: string; }>; } export class PremiumAPIClient extends EventEmitter { private config: PremiumAPIConfig; private rateLimitRemaining: number = 1000; private rateLimitReset: Date = new Date(); constructor(config: PremiumAPIConfig) { super(); this.config = { timeout: 30000, retries: 3, version: 'v1', ...config }; } async calculateQualityScore(asset: Asset): Promise<QualityScore> { return this.makeRequest('/analytics/quality-score', { method: 'POST', body: JSON.stringify({ asset }), headers: { 'Content-Type': 'application/json' } }); } async detectFraud(asset: Asset): Promise<FraudDetection> { return this.makeRequest('/analytics/fraud-detection', { method: 'POST', body: JSON.stringify({ asset }), headers: { 'Content-Type': 'application/json' } }); } async checkCompliance(asset: Asset, regulations: string[] = []): Promise<ComplianceCheck> { return this.makeRequest('/compliance/check', { method: 'POST', body: JSON.stringify({ asset, regulations }), headers: { 'Content-Type': 'application/json' } }); } async getMarketIntelligence( category: string, subcategory: string, location?: { country: string; state?: string } ): Promise<MarketIntelligence> { const params = new URLSearchParams({ category, subcategory, ...(location?.country && { country: location.country }), ...(location?.state && { state: location.state }) }); return this.makeRequest(`/market/intelligence?${params.toString()}`); } async assessRisk(asset: Asset): Promise<RiskAssessment> { return this.makeRequest('/analytics/risk-assessment', { method: 'POST', body: JSON.stringify({ asset }), headers: { 'Content-Type': 'application/json' } }); } async batchAnalyze(assets: Asset[]): Promise<{ qualityScores: QualityScore[]; fraudDetections: FraudDetection[]; complianceChecks: ComplianceCheck[]; riskAssessments: RiskAssessment[]; }> { return this.makeRequest('/analytics/batch', { method: 'POST', body: JSON.stringify({ assets }), headers: { 'Content-Type': 'application/json' } }); } async getUsageStats(): Promise<{ period: string; totalCalls: number; callsByEndpoint: Record<string, number>; costBreakdown: Record<string, number>; remainingCredits: number; }> { return this.makeRequest('/account/usage'); } getRateLimitInfo(): { remaining: number; resetAt: Date } { return { remaining: this.rateLimitRemaining, resetAt: this.rateLimitReset }; } private async makeRequest(endpoint: string, options: RequestInit = {}): Promise<any> { // Emit request event this.emit('request', { endpoint, options }); // Check rate limits before making request if (this.rateLimitRemaining <= 0 && this.rateLimitReset > new Date()) { const waitTime = this.rateLimitReset.getTime() - Date.now(); throw new DeFarmSDKError( ErrorCode.RATE_LIMIT_EXCEEDED, `Rate limit exceeded. Retry after ${Math.ceil(waitTime / 1000)} seconds`, { retryAfter: this.rateLimitReset } ); } const url = `${this.config.baseUrl}/${this.config.version}${endpoint}`; const requestOptions: RequestInit = { ...options, headers: { 'Authorization': `Bearer ${this.config.apiKey}`, 'User-Agent': 'DeFarm-SDK/0.1.0', ...options.headers } }; let lastError: Error | null = null; for (let attempt = 0; attempt <= (this.config.retries || 3); attempt++) { try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), this.config.timeout); const response = await fetch(url, { ...requestOptions, signal: controller.signal }); clearTimeout(timeoutId); this.updateRateLimitInfo(response); if (!response.ok) { if (response.status === 429) { const retryAfter = response.headers.get('Retry-After'); const waitTime = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, attempt) * 1000; if (attempt < (this.config.retries || 3)) { await this.delay(waitTime); continue; } } const errorData = await response.json().catch(() => ({})); const errorCode = response.status === 401 ? ErrorCode.AUTHENTICATION_ERROR : response.status === 403 ? ErrorCode.AUTHORIZATION_ERROR : response.status === 429 ? ErrorCode.RATE_LIMIT_EXCEEDED : response.status >= 500 ? ErrorCode.API_ERROR : ErrorCode.PREMIUM_API_ERROR; throw new DeFarmSDKError( errorCode, `API request failed: ${response.status} ${response.statusText}. ${ errorData.message || errorData.error || '' }`, { status: response.status, endpoint, errorData } ); } const data = await response.json(); // Emit success event this.emit('response', { endpoint, status: response.status, data }); return data; } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); if (error instanceof Error && error.name === 'AbortError') { lastError = new DeFarmSDKError( ErrorCode.TIMEOUT_ERROR, `Request timeout after ${this.config.timeout}ms`, { endpoint, timeout: this.config.timeout } ); } // Emit error event this.emit('error', { endpoint, error: lastError, attempt }); if (attempt < (this.config.retries || 3)) { const backoffTime = Math.pow(2, attempt) * 1000; await this.delay(backoffTime); continue; } } } throw lastError || new Error('Unknown API error'); } private updateRateLimitInfo(response: Response): void { const remaining = response.headers.get('X-RateLimit-Remaining'); const reset = response.headers.get('X-RateLimit-Reset'); if (remaining) { this.rateLimitRemaining = parseInt(remaining); } if (reset) { this.rateLimitReset = new Date(parseInt(reset) * 1000); } } private delay(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } // Monitoring and debugging methods async healthCheck(): Promise<{ status: 'healthy' | 'degraded' | 'unhealthy'; latency: number; rateLimits: { remaining: number; resetAt: Date }; version: string; }> { const start = Date.now(); try { const response = await this.makeRequest('/health'); const latency = Date.now() - start; return { status: 'healthy', latency, rateLimits: this.getRateLimitInfo(), version: response.version || this.config.version || 'unknown' }; } catch (error) { return { status: 'unhealthy', latency: Date.now() - start, rateLimits: this.getRateLimitInfo(), version: this.config.version || 'unknown' }; } } // Enhanced analytics methods async getAnalyticsReport( assets: Asset[], options: { includeQuality?: boolean; includeFraud?: boolean; includeCompliance?: boolean; includeRisk?: boolean; includeMarket?: boolean; } = {} ): Promise<{ summary: { totalAssets: number; averageQualityScore?: number; highRiskCount?: number; complianceRate?: number; }; details: { byCategory: Record<string, any>; byLocation: Record<string, any>; trends: any[]; }; recommendations: string[]; }> { const payload = { assets, options }; return this.makeRequest('/analytics/report', { method: 'POST', body: JSON.stringify(payload), headers: { 'Content-Type': 'application/json' } }); } // Data enrichment methods async enrichAsset(asset: Asset): Promise<{ enriched: Asset; sources: string[]; confidence: number; additions: Record<string, any>; }> { return this.makeRequest('/enrich/asset', { method: 'POST', body: JSON.stringify({ asset }), headers: { 'Content-Type': 'application/json' } }); } // Predictive analytics async predictPrice( asset: Asset, timeframe: '1d' | '1w' | '1m' | '3m' | '6m' | '1y' ): Promise<{ current: number; predicted: number; confidence: number; factors: Array<{ name: string; impact: number }>; range: { low: number; high: number }; }> { return this.makeRequest('/predict/price', { method: 'POST', body: JSON.stringify({ asset, timeframe }), headers: { 'Content-Type': 'application/json' } }); } // Blockchain verification async verifyOnChain( dfid: string, blockchain: 'stellar' | 'polygon' | 'ethereum' = 'stellar' ): Promise<{ verified: boolean; transactionHash?: string; blockNumber?: number; timestamp?: Date; data?: any; }> { return this.makeRequest(`/verify/blockchain/${blockchain}/${dfid}`); } // Compliance automation async generateComplianceReport( assets: Asset[], regulations: string[], format: 'pdf' | 'json' | 'csv' = 'json' ): Promise<{ reportId: string; status: 'completed' | 'processing' | 'failed'; downloadUrl?: string; expiresAt?: Date; }> { return this.makeRequest('/compliance/report/generate', { method: 'POST', body: JSON.stringify({ assets, regulations, format }), headers: { 'Content-Type': 'application/json' } }); } // Real-time monitoring async subscribeToAlerts( criteria: { categories?: string[]; riskThreshold?: number; complianceRules?: string[]; priceChanges?: { threshold: number; direction: 'up' | 'down' | 'both' }; }, webhook?: string ): Promise<{ subscriptionId: string; active: boolean; criteria: any; webhookUrl?: string; }> { return this.makeRequest('/alerts/subscribe', { method: 'POST', body: JSON.stringify({ criteria, webhook }), headers: { 'Content-Type': 'application/json' } }); } async unsubscribe(subscriptionId: string): Promise<{ success: boolean }> { return this.makeRequest(`/alerts/unsubscribe/${subscriptionId}`, { method: 'DELETE' }); } }