@one_deploy/sdk 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/{engine-CrlhH0nw.d.mts → engine-BeVuHpVx.d.mts} +163 -0
  2. package/dist/{engine-5ndtBaCr.d.ts → engine-DSc1Em4V.d.ts} +163 -0
  3. package/dist/hooks/index.d.mts +132 -3
  4. package/dist/hooks/index.d.ts +132 -3
  5. package/dist/hooks/index.js +351 -0
  6. package/dist/hooks/index.js.map +1 -1
  7. package/dist/hooks/index.mjs +345 -2
  8. package/dist/hooks/index.mjs.map +1 -1
  9. package/dist/index.d.mts +3 -3
  10. package/dist/index.d.ts +3 -3
  11. package/dist/index.js +352 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +345 -2
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/providers/index.d.mts +1 -1
  16. package/dist/providers/index.d.ts +1 -1
  17. package/dist/providers/index.js +98 -0
  18. package/dist/providers/index.js.map +1 -1
  19. package/dist/providers/index.mjs +98 -0
  20. package/dist/providers/index.mjs.map +1 -1
  21. package/dist/react-native.d.mts +140 -3
  22. package/dist/react-native.d.ts +140 -3
  23. package/dist/react-native.js +642 -0
  24. package/dist/react-native.js.map +1 -1
  25. package/dist/react-native.mjs +636 -1
  26. package/dist/react-native.mjs.map +1 -1
  27. package/dist/services/index.d.mts +99 -79
  28. package/dist/services/index.d.ts +99 -79
  29. package/dist/services/index.js +254 -0
  30. package/dist/services/index.js.map +1 -1
  31. package/dist/services/index.mjs +252 -1
  32. package/dist/services/index.mjs.map +1 -1
  33. package/dist/supabase-BT0c7q9e.d.mts +82 -0
  34. package/dist/supabase-BT0c7q9e.d.ts +82 -0
  35. package/package.json +5 -1
  36. package/src/components/OneSwapWidget.tsx +1 -1
  37. package/src/components/ai/OneChainSelector.tsx +183 -0
  38. package/src/components/ai/OneCycleSelector.tsx +187 -0
  39. package/src/components/ai/OnePairSelector.tsx +181 -0
  40. package/src/components/ai/OneTierSelector.tsx +187 -0
  41. package/src/components/ai/index.ts +17 -0
  42. package/src/components/index.ts +3 -0
  43. package/src/hooks/index.ts +20 -0
  44. package/src/hooks/useAITrading.ts +444 -0
  45. package/src/index.ts +20 -0
  46. package/src/react-native.ts +23 -0
  47. package/src/services/engine.ts +184 -0
  48. package/src/services/index.ts +16 -0
  49. package/src/services/usage.ts +249 -0
  50. package/.turbo/turbo-build.log +0 -0
  51. package/.turbo/turbo-type-check.log +0 -0
  52. package/tsconfig.json +0 -22
  53. package/tsup.config.ts +0 -25
@@ -0,0 +1,444 @@
1
+ /**
2
+ * AI Trading Hooks for ONE SDK
3
+ *
4
+ * React hooks for AI quantitative trading features.
5
+ * These hooks provide easy access to AI strategies, orders, and portfolio management.
6
+ */
7
+
8
+ import { useState, useEffect, useCallback, useMemo } from 'react';
9
+ import { createOneEngineClient, OneEngineClient } from '../services/engine';
10
+ import type {
11
+ AIStrategy,
12
+ AIOrder,
13
+ AIOrderStatus,
14
+ AIPortfolioSummary,
15
+ AITradeAllocation,
16
+ AINavSnapshot,
17
+ AIMarketData,
18
+ CreateAIOrderRequest,
19
+ StrategyCategory,
20
+ ApiResponse,
21
+ } from '../types';
22
+
23
+ // Singleton client instance
24
+ let clientInstance: OneEngineClient | null = null;
25
+
26
+ function getClient(): OneEngineClient {
27
+ if (!clientInstance) {
28
+ clientInstance = createOneEngineClient();
29
+ }
30
+ return clientInstance;
31
+ }
32
+
33
+ /**
34
+ * Set the access token for authenticated requests
35
+ */
36
+ export function setAITradingAccessToken(token: string) {
37
+ getClient().setAccessToken(token);
38
+ }
39
+
40
+ /**
41
+ * Clear the access token
42
+ */
43
+ export function clearAITradingAccessToken() {
44
+ getClient().clearAccessToken();
45
+ }
46
+
47
+ // ============================================
48
+ // AI Strategies Hooks
49
+ // ============================================
50
+
51
+ export interface UseAIStrategiesOptions {
52
+ category?: StrategyCategory;
53
+ riskLevel?: number;
54
+ minTvl?: number;
55
+ isActive?: boolean;
56
+ autoRefresh?: boolean;
57
+ refreshInterval?: number;
58
+ }
59
+
60
+ export interface UseAIStrategiesResult {
61
+ strategies: AIStrategy[];
62
+ isLoading: boolean;
63
+ error: string | null;
64
+ refresh: () => Promise<void>;
65
+ }
66
+
67
+ /**
68
+ * Hook to fetch and manage AI trading strategies
69
+ */
70
+ export function useAIStrategies(options: UseAIStrategiesOptions = {}): UseAIStrategiesResult {
71
+ const [strategies, setStrategies] = useState<AIStrategy[]>([]);
72
+ const [isLoading, setIsLoading] = useState(true);
73
+ const [error, setError] = useState<string | null>(null);
74
+
75
+ const { category, riskLevel, minTvl, isActive, autoRefresh = false, refreshInterval = 60000 } = options;
76
+
77
+ const fetchStrategies = useCallback(async () => {
78
+ setIsLoading(true);
79
+ setError(null);
80
+ try {
81
+ const result = await getClient().getAIStrategies({ category, riskLevel, minTvl, isActive });
82
+ if (result.success && result.data?.strategies) {
83
+ setStrategies(result.data.strategies);
84
+ } else {
85
+ setError(result.error?.message || 'Failed to fetch strategies');
86
+ }
87
+ } catch (err) {
88
+ setError(err instanceof Error ? err.message : 'Unknown error');
89
+ } finally {
90
+ setIsLoading(false);
91
+ }
92
+ }, [category, riskLevel, minTvl, isActive]);
93
+
94
+ useEffect(() => {
95
+ fetchStrategies();
96
+ }, [fetchStrategies]);
97
+
98
+ useEffect(() => {
99
+ if (autoRefresh && refreshInterval > 0) {
100
+ const interval = setInterval(fetchStrategies, refreshInterval);
101
+ return () => clearInterval(interval);
102
+ }
103
+ }, [autoRefresh, refreshInterval, fetchStrategies]);
104
+
105
+ return { strategies, isLoading, error, refresh: fetchStrategies };
106
+ }
107
+
108
+ /**
109
+ * Hook to fetch a single AI strategy with performance data
110
+ */
111
+ export interface UseAIStrategyResult {
112
+ strategy: AIStrategy | null;
113
+ performance: AINavSnapshot[];
114
+ marketData: AIMarketData[];
115
+ isLoading: boolean;
116
+ error: string | null;
117
+ refresh: () => Promise<void>;
118
+ }
119
+
120
+ export function useAIStrategy(
121
+ strategyId: string | undefined,
122
+ include: ('performance' | 'market' | 'trades')[] = ['performance', 'market']
123
+ ): UseAIStrategyResult {
124
+ const [strategy, setStrategy] = useState<AIStrategy | null>(null);
125
+ const [performance, setPerformance] = useState<AINavSnapshot[]>([]);
126
+ const [marketData, setMarketData] = useState<AIMarketData[]>([]);
127
+ const [isLoading, setIsLoading] = useState(true);
128
+ const [error, setError] = useState<string | null>(null);
129
+
130
+ const fetchStrategy = useCallback(async () => {
131
+ if (!strategyId) {
132
+ setIsLoading(false);
133
+ return;
134
+ }
135
+
136
+ setIsLoading(true);
137
+ setError(null);
138
+ try {
139
+ const result = await getClient().getAIStrategy(strategyId, include);
140
+ if (result.success && result.data) {
141
+ setStrategy(result.data.strategy);
142
+ setPerformance(result.data.performance || []);
143
+ setMarketData(result.data.marketData || []);
144
+ } else {
145
+ setError(result.error?.message || 'Failed to fetch strategy');
146
+ }
147
+ } catch (err) {
148
+ setError(err instanceof Error ? err.message : 'Unknown error');
149
+ } finally {
150
+ setIsLoading(false);
151
+ }
152
+ }, [strategyId, include.join(',')]);
153
+
154
+ useEffect(() => {
155
+ fetchStrategy();
156
+ }, [fetchStrategy]);
157
+
158
+ return { strategy, performance, marketData, isLoading, error, refresh: fetchStrategy };
159
+ }
160
+
161
+ // ============================================
162
+ // AI Orders Hooks
163
+ // ============================================
164
+
165
+ export interface UseAIOrdersOptions {
166
+ strategyId?: string;
167
+ status?: AIOrderStatus;
168
+ autoRefresh?: boolean;
169
+ refreshInterval?: number;
170
+ }
171
+
172
+ export interface UseAIOrdersResult {
173
+ orders: AIOrder[];
174
+ isLoading: boolean;
175
+ error: string | null;
176
+ refresh: () => Promise<void>;
177
+ createOrder: (request: CreateAIOrderRequest) => Promise<ApiResponse<{ order: AIOrder }>>;
178
+ pauseOrder: (orderId: string) => Promise<ApiResponse<{ order: AIOrder; message: string }>>;
179
+ resumeOrder: (orderId: string) => Promise<ApiResponse<{ order: AIOrder; message: string }>>;
180
+ redeemOrder: (orderId: string) => Promise<ApiResponse<any>>;
181
+ }
182
+
183
+ /**
184
+ * Hook to manage AI trading orders
185
+ */
186
+ export function useAIOrders(options: UseAIOrdersOptions = {}): UseAIOrdersResult {
187
+ const [orders, setOrders] = useState<AIOrder[]>([]);
188
+ const [isLoading, setIsLoading] = useState(true);
189
+ const [error, setError] = useState<string | null>(null);
190
+
191
+ const { strategyId, status, autoRefresh = true, refreshInterval = 30000 } = options;
192
+
193
+ const fetchOrders = useCallback(async () => {
194
+ setIsLoading(true);
195
+ setError(null);
196
+ try {
197
+ const result = await getClient().getAIOrders({ strategyId, status });
198
+ if (result.success && result.data?.orders) {
199
+ setOrders(result.data.orders);
200
+ } else {
201
+ setError(result.error?.message || 'Failed to fetch orders');
202
+ }
203
+ } catch (err) {
204
+ setError(err instanceof Error ? err.message : 'Unknown error');
205
+ } finally {
206
+ setIsLoading(false);
207
+ }
208
+ }, [strategyId, status]);
209
+
210
+ useEffect(() => {
211
+ fetchOrders();
212
+ }, [fetchOrders]);
213
+
214
+ useEffect(() => {
215
+ if (autoRefresh && refreshInterval > 0) {
216
+ const interval = setInterval(fetchOrders, refreshInterval);
217
+ return () => clearInterval(interval);
218
+ }
219
+ }, [autoRefresh, refreshInterval, fetchOrders]);
220
+
221
+ const createOrder = useCallback(async (request: CreateAIOrderRequest) => {
222
+ const result = await getClient().createAIOrder(request);
223
+ if (result.success) {
224
+ await fetchOrders(); // Refresh orders list
225
+ }
226
+ return result;
227
+ }, [fetchOrders]);
228
+
229
+ const pauseOrder = useCallback(async (orderId: string) => {
230
+ const result = await getClient().pauseAIOrder(orderId);
231
+ if (result.success) {
232
+ await fetchOrders();
233
+ }
234
+ return result;
235
+ }, [fetchOrders]);
236
+
237
+ const resumeOrder = useCallback(async (orderId: string) => {
238
+ const result = await getClient().resumeAIOrder(orderId);
239
+ if (result.success) {
240
+ await fetchOrders();
241
+ }
242
+ return result;
243
+ }, [fetchOrders]);
244
+
245
+ const redeemOrder = useCallback(async (orderId: string) => {
246
+ const result = await getClient().redeemAIOrder(orderId);
247
+ if (result.success) {
248
+ await fetchOrders();
249
+ }
250
+ return result;
251
+ }, [fetchOrders]);
252
+
253
+ return {
254
+ orders,
255
+ isLoading,
256
+ error,
257
+ refresh: fetchOrders,
258
+ createOrder,
259
+ pauseOrder,
260
+ resumeOrder,
261
+ redeemOrder,
262
+ };
263
+ }
264
+
265
+ // ============================================
266
+ // AI Portfolio Hooks
267
+ // ============================================
268
+
269
+ export interface UseAIPortfolioResult {
270
+ portfolio: AIPortfolioSummary | null;
271
+ allocations: AITradeAllocation[];
272
+ activeOrders: AIOrder[];
273
+ isLoading: boolean;
274
+ error: string | null;
275
+ refresh: () => Promise<void>;
276
+ }
277
+
278
+ /**
279
+ * Hook to fetch AI trading portfolio summary
280
+ */
281
+ export function useAIPortfolio(autoRefresh = true): UseAIPortfolioResult {
282
+ const [portfolio, setPortfolio] = useState<AIPortfolioSummary | null>(null);
283
+ const [allocations, setAllocations] = useState<AITradeAllocation[]>([]);
284
+ const [activeOrders, setActiveOrders] = useState<AIOrder[]>([]);
285
+ const [isLoading, setIsLoading] = useState(true);
286
+ const [error, setError] = useState<string | null>(null);
287
+
288
+ const fetchPortfolio = useCallback(async () => {
289
+ setIsLoading(true);
290
+ setError(null);
291
+ try {
292
+ const result = await getClient().getAIPortfolio(['allocations', 'orders']);
293
+ if (result.success && result.data) {
294
+ setPortfolio(result.data.portfolio);
295
+ setAllocations(result.data.allocations || []);
296
+ setActiveOrders(result.data.orders || []);
297
+ } else {
298
+ setError(result.error?.message || 'Failed to fetch portfolio');
299
+ }
300
+ } catch (err) {
301
+ setError(err instanceof Error ? err.message : 'Unknown error');
302
+ } finally {
303
+ setIsLoading(false);
304
+ }
305
+ }, []);
306
+
307
+ useEffect(() => {
308
+ fetchPortfolio();
309
+ }, [fetchPortfolio]);
310
+
311
+ useEffect(() => {
312
+ if (autoRefresh) {
313
+ const interval = setInterval(fetchPortfolio, 30000);
314
+ return () => clearInterval(interval);
315
+ }
316
+ }, [autoRefresh, fetchPortfolio]);
317
+
318
+ return { portfolio, allocations, activeOrders, isLoading, error, refresh: fetchPortfolio };
319
+ }
320
+
321
+ // ============================================
322
+ // AI Market Data Hook
323
+ // ============================================
324
+
325
+ export interface UseAIMarketDataResult {
326
+ prices: Record<string, { price: number; change24h: number }>;
327
+ isLoading: boolean;
328
+ error: string | null;
329
+ refresh: () => Promise<void>;
330
+ }
331
+
332
+ /**
333
+ * Hook to fetch real-time market data for AI trading pairs
334
+ */
335
+ export function useAIMarketData(
336
+ symbols: string[] = ['BTC', 'ETH', 'BNB', 'SOL', 'XRP', 'DOGE', 'ADA', 'AVAX'],
337
+ autoRefresh = true
338
+ ): UseAIMarketDataResult {
339
+ const [prices, setPrices] = useState<Record<string, { price: number; change24h: number }>>({});
340
+ const [isLoading, setIsLoading] = useState(true);
341
+ const [error, setError] = useState<string | null>(null);
342
+
343
+ const fetchPrices = useCallback(async () => {
344
+ setIsLoading(true);
345
+ setError(null);
346
+ try {
347
+ const result = await getClient().getTokenPrices(symbols);
348
+ if (result.success && result.data) {
349
+ setPrices(result.data);
350
+ } else {
351
+ setError(result.error?.message || 'Failed to fetch prices');
352
+ }
353
+ } catch (err) {
354
+ setError(err instanceof Error ? err.message : 'Unknown error');
355
+ } finally {
356
+ setIsLoading(false);
357
+ }
358
+ }, [symbols.join(',')]);
359
+
360
+ useEffect(() => {
361
+ fetchPrices();
362
+ }, [fetchPrices]);
363
+
364
+ useEffect(() => {
365
+ if (autoRefresh) {
366
+ const interval = setInterval(fetchPrices, 15000); // Update every 15 seconds
367
+ return () => clearInterval(interval);
368
+ }
369
+ }, [autoRefresh, fetchPrices]);
370
+
371
+ return { prices, isLoading, error, refresh: fetchPrices };
372
+ }
373
+
374
+ // ============================================
375
+ // Combined AI Trading Hook
376
+ // ============================================
377
+
378
+ export interface UseAITradingResult {
379
+ // Strategies
380
+ strategies: AIStrategy[];
381
+ strategiesLoading: boolean;
382
+
383
+ // Orders
384
+ orders: AIOrder[];
385
+ ordersLoading: boolean;
386
+
387
+ // Portfolio
388
+ portfolio: AIPortfolioSummary | null;
389
+ portfolioLoading: boolean;
390
+
391
+ // Market Data
392
+ prices: Record<string, { price: number; change24h: number }>;
393
+
394
+ // Actions
395
+ createOrder: (request: CreateAIOrderRequest) => Promise<ApiResponse<{ order: AIOrder }>>;
396
+ pauseOrder: (orderId: string) => Promise<ApiResponse<{ order: AIOrder; message: string }>>;
397
+ resumeOrder: (orderId: string) => Promise<ApiResponse<{ order: AIOrder; message: string }>>;
398
+ redeemOrder: (orderId: string) => Promise<ApiResponse<any>>;
399
+
400
+ // Refresh
401
+ refreshAll: () => Promise<void>;
402
+
403
+ // Error
404
+ error: string | null;
405
+ }
406
+
407
+ /**
408
+ * Combined hook for all AI trading functionality
409
+ */
410
+ export function useAITrading(): UseAITradingResult {
411
+ const strategiesResult = useAIStrategies({ autoRefresh: true });
412
+ const ordersResult = useAIOrders({ autoRefresh: true });
413
+ const portfolioResult = useAIPortfolio(true);
414
+ const marketResult = useAIMarketData();
415
+
416
+ const refreshAll = useCallback(async () => {
417
+ await Promise.all([
418
+ strategiesResult.refresh(),
419
+ ordersResult.refresh(),
420
+ portfolioResult.refresh(),
421
+ marketResult.refresh(),
422
+ ]);
423
+ }, [strategiesResult.refresh, ordersResult.refresh, portfolioResult.refresh, marketResult.refresh]);
424
+
425
+ const error = useMemo(() => {
426
+ return strategiesResult.error || ordersResult.error || portfolioResult.error || marketResult.error;
427
+ }, [strategiesResult.error, ordersResult.error, portfolioResult.error, marketResult.error]);
428
+
429
+ return {
430
+ strategies: strategiesResult.strategies,
431
+ strategiesLoading: strategiesResult.isLoading,
432
+ orders: ordersResult.orders,
433
+ ordersLoading: ordersResult.isLoading,
434
+ portfolio: portfolioResult.portfolio,
435
+ portfolioLoading: portfolioResult.isLoading,
436
+ prices: marketResult.prices,
437
+ createOrder: ordersResult.createOrder,
438
+ pauseOrder: ordersResult.pauseOrder,
439
+ resumeOrder: ordersResult.resumeOrder,
440
+ redeemOrder: ordersResult.redeemOrder,
441
+ refreshAll,
442
+ error,
443
+ };
444
+ }
package/src/index.ts CHANGED
@@ -157,6 +157,26 @@ export {
157
157
  useWalletBalance,
158
158
  useTokenPrice,
159
159
  useTokenPrices,
160
+ // AI Trading Hooks
161
+ useAIStrategies,
162
+ useAIStrategy,
163
+ useAIOrders,
164
+ useAIPortfolio,
165
+ useAIMarketData,
166
+ useAITrading,
167
+ setAITradingAccessToken,
168
+ clearAITradingAccessToken,
169
+ } from './hooks';
170
+
171
+ export type {
172
+ UseAIStrategiesOptions,
173
+ UseAIStrategiesResult,
174
+ UseAIStrategyResult,
175
+ UseAIOrdersOptions,
176
+ UseAIOrdersResult,
177
+ UseAIPortfolioResult,
178
+ UseAIMarketDataResult,
179
+ UseAITradingResult,
160
180
  } from './hooks';
161
181
 
162
182
  // ===== Utilities =====
@@ -67,6 +67,29 @@ export {
67
67
  isOneSDKError,
68
68
  } from './utils';
69
69
 
70
+ // ===== AI Trading Components =====
71
+ // React Native components for AI trading integration
72
+ export {
73
+ OneChainSelector,
74
+ CHAIN_CONFIG,
75
+ } from './components/ai/OneChainSelector';
76
+ export type { OneChainSelectorProps } from './components/ai/OneChainSelector';
77
+
78
+ export { OneTierSelector } from './components/ai/OneTierSelector';
79
+ export type { OneTierSelectorProps, Tier } from './components/ai/OneTierSelector';
80
+
81
+ export {
82
+ OneCycleSelector,
83
+ DEFAULT_SHARE_RATES,
84
+ } from './components/ai/OneCycleSelector';
85
+ export type { OneCycleSelectorProps } from './components/ai/OneCycleSelector';
86
+
87
+ export {
88
+ OnePairSelector,
89
+ PAIR_ICONS,
90
+ } from './components/ai/OnePairSelector';
91
+ export type { OnePairSelectorProps } from './components/ai/OnePairSelector';
92
+
70
93
  // ===== React Native Specific Utilities =====
71
94
 
72
95
  /**
@@ -1597,6 +1597,93 @@ export class OneEngineClient {
1597
1597
  return this.request(`/api/v1/admin/rate-limits/${identifier}`, { method: 'DELETE' });
1598
1598
  }
1599
1599
 
1600
+ // ========== AI Agent Configuration ==========
1601
+
1602
+ /**
1603
+ * Get all AI agent configurations
1604
+ * This returns the full agent setup including tiers, cycles, and trading parameters
1605
+ */
1606
+ async getAgentConfigs(options?: {
1607
+ includeInactive?: boolean;
1608
+ agentId?: string;
1609
+ }): Promise<ApiResponse<{
1610
+ agents?: Array<{
1611
+ id: string;
1612
+ name: string;
1613
+ name_zh: string;
1614
+ description: string;
1615
+ description_zh: string;
1616
+ category: string;
1617
+ risk_level: number;
1618
+ icon: string;
1619
+ color: string;
1620
+ tiers: Array<{ tier: number; amount: number; label: string; label_zh: string }>;
1621
+ supported_cycles: number[];
1622
+ default_cycle: number;
1623
+ supported_pairs: string[];
1624
+ supported_chains: string[];
1625
+ is_active: boolean;
1626
+ preview: {
1627
+ tier: { tier: number; amount: number; label: string };
1628
+ cycle: number;
1629
+ dailyLots: number;
1630
+ stabilityScore: number;
1631
+ roiRange: { min: number; max: number; userMin: number; userMax: number };
1632
+ shareRate: number;
1633
+ profitEstimate: { monthlyMin: number; monthlyMax: number; cycleMin: number; cycleMax: number };
1634
+ };
1635
+ }>;
1636
+ agent?: any;
1637
+ shareRates?: Record<number, number>;
1638
+ }>> {
1639
+ const params = new URLSearchParams();
1640
+ if (options?.includeInactive) params.set('includeInactive', 'true');
1641
+ if (options?.agentId) params.set('agentId', options.agentId);
1642
+ const query = params.toString();
1643
+ return this.request(`/api/v1/agents${query ? `?${query}` : ''}`, { method: 'GET' });
1644
+ }
1645
+
1646
+ /**
1647
+ * Calculate subscription parameters for an agent
1648
+ */
1649
+ async calculateAgentParams(params: {
1650
+ agentId: string;
1651
+ amount: number;
1652
+ cycleDays: number;
1653
+ }): Promise<ApiResponse<{
1654
+ dailyLots: number;
1655
+ effectiveCapital: number;
1656
+ stabilityScore: number;
1657
+ roiRange: { min: number; max: number; userMin: number; userMax: number };
1658
+ shareRate: number;
1659
+ profitEstimate: { monthlyMin: number; monthlyMax: number; cycleMin: number; cycleMax: number };
1660
+ }>> {
1661
+ return this.request('/api/v1/agents/calculate', {
1662
+ method: 'POST',
1663
+ body: JSON.stringify(params),
1664
+ });
1665
+ }
1666
+
1667
+ /**
1668
+ * Get supported trading pairs from agents
1669
+ */
1670
+ async getTradingPairs(): Promise<ApiResponse<{
1671
+ pairs: string[];
1672
+ byAgent: Record<string, string[]>;
1673
+ }>> {
1674
+ const result = await this.getAgentConfigs();
1675
+ if (result.success && result.data?.agents) {
1676
+ const allPairs = new Set<string>();
1677
+ const byAgent: Record<string, string[]> = {};
1678
+ for (const agent of result.data.agents) {
1679
+ byAgent[agent.id] = agent.supported_pairs;
1680
+ agent.supported_pairs.forEach(p => allPairs.add(p));
1681
+ }
1682
+ return { success: true, data: { pairs: Array.from(allPairs), byAgent } };
1683
+ }
1684
+ return { success: false, error: result.error };
1685
+ }
1686
+
1600
1687
  // ========== AI Quant Trading ==========
1601
1688
 
1602
1689
  /**
@@ -1842,6 +1929,103 @@ export class OneEngineClient {
1842
1929
  }>> {
1843
1930
  return this.request('/api/v1/prices?type=overview', { method: 'GET' });
1844
1931
  }
1932
+
1933
+ // ========== Project Management ==========
1934
+
1935
+ /**
1936
+ * Get user's projects
1937
+ */
1938
+ async getProjects(options?: {
1939
+ isActive?: boolean;
1940
+ }): Promise<ApiResponse<{ projects: AdminProject[]; total: number }>> {
1941
+ const params = new URLSearchParams();
1942
+ if (options?.isActive !== undefined) params.set('isActive', String(options.isActive));
1943
+ const query = params.toString();
1944
+ return this.request(`/api/v1/projects${query ? `?${query}` : ''}`, { method: 'GET' });
1945
+ }
1946
+
1947
+ /**
1948
+ * Create a new project for ecosystem partners
1949
+ */
1950
+ async createProject(params: {
1951
+ name: string;
1952
+ slug: string;
1953
+ settings?: Record<string, unknown>;
1954
+ }): Promise<ApiResponse<{ project: AdminProject }>> {
1955
+ return this.request('/api/v1/projects', {
1956
+ method: 'POST',
1957
+ body: JSON.stringify(params),
1958
+ });
1959
+ }
1960
+
1961
+ /**
1962
+ * Get project details
1963
+ */
1964
+ async getProject(projectId: string): Promise<ApiResponse<{ project: AdminProject }>> {
1965
+ return this.request(`/api/v1/projects/${projectId}`, { method: 'GET' });
1966
+ }
1967
+
1968
+ /**
1969
+ * Update project settings
1970
+ */
1971
+ async updateProject(projectId: string, updates: {
1972
+ name?: string;
1973
+ isActive?: boolean;
1974
+ settings?: Record<string, unknown>;
1975
+ }): Promise<ApiResponse<{ project: AdminProject }>> {
1976
+ return this.request(`/api/v1/projects/${projectId}`, {
1977
+ method: 'PATCH',
1978
+ body: JSON.stringify(updates),
1979
+ });
1980
+ }
1981
+
1982
+ /**
1983
+ * Get project features status
1984
+ */
1985
+ async getProjectFeatures(projectId: string): Promise<ApiResponse<{
1986
+ features: Record<string, {
1987
+ enabled: boolean;
1988
+ name: string;
1989
+ description: string;
1990
+ description_zh: string;
1991
+ }>;
1992
+ availableFeatures: string[];
1993
+ }>> {
1994
+ return this.request(`/api/v1/projects/${projectId}/features`, { method: 'GET' });
1995
+ }
1996
+
1997
+ /**
1998
+ * Enable/disable features for a project
1999
+ */
2000
+ async updateProjectFeatures(projectId: string, features: {
2001
+ wallet?: boolean;
2002
+ swap?: boolean;
2003
+ contracts?: boolean;
2004
+ fiat?: boolean;
2005
+ payments?: boolean;
2006
+ quant?: boolean;
2007
+ ai?: boolean;
2008
+ x402?: boolean;
2009
+ }): Promise<ApiResponse<{ project: AdminProject; message: string }>> {
2010
+ return this.request(`/api/v1/projects/${projectId}/features`, {
2011
+ method: 'PATCH',
2012
+ body: JSON.stringify(features),
2013
+ });
2014
+ }
2015
+
2016
+ /**
2017
+ * Regenerate project API key
2018
+ */
2019
+ async regenerateProjectApiKey(projectId: string): Promise<ApiResponse<{ apiKey: string }>> {
2020
+ return this.request(`/api/v1/projects/${projectId}/api-key`, { method: 'POST' });
2021
+ }
2022
+
2023
+ /**
2024
+ * Delete project
2025
+ */
2026
+ async deleteProject(projectId: string): Promise<ApiResponse<{ deleted: boolean }>> {
2027
+ return this.request(`/api/v1/projects/${projectId}`, { method: 'DELETE' });
2028
+ }
1845
2029
  }
1846
2030
 
1847
2031
  // Factory function