@one_deploy/sdk 1.0.7 → 1.2.0
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.
- package/README.md +339 -0
- package/dist/ForexPoolDataGenerator--__twRwl.d.mts +76 -0
- package/dist/ForexPoolDataGenerator-eUgwsU_B.d.ts +76 -0
- package/dist/OneForexTradeHistory-TlKxjbFF.d.ts +250 -0
- package/dist/OneForexTradeHistory-iDySMcw0.d.mts +250 -0
- package/dist/components/index.d.mts +539 -0
- package/dist/components/index.d.ts +539 -0
- package/dist/components/index.js +7295 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +7243 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config/index.d.mts +1 -0
- package/dist/config/index.d.ts +1 -0
- package/dist/console-BfTMA7ah.d.mts +504 -0
- package/dist/console-BfTMA7ah.d.ts +504 -0
- package/dist/hooks/index.d.mts +323 -1
- package/dist/hooks/index.d.ts +323 -1
- package/dist/hooks/index.js +3223 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +3204 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/index.d.mts +18 -352
- package/dist/index.d.ts +18 -352
- package/dist/index.js +8646 -574
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8449 -432
- package/dist/index.mjs.map +1 -1
- package/dist/providers/index.d.mts +31 -31
- package/dist/providers/index.d.ts +31 -31
- package/dist/providers/index.js +140 -153
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/index.mjs +100 -109
- package/dist/providers/index.mjs.map +1 -1
- package/dist/react-native.d.mts +8 -144
- package/dist/react-native.d.ts +8 -144
- package/dist/react-native.js +2640 -689
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +2610 -691
- package/dist/react-native.mjs.map +1 -1
- package/dist/services/index.d.mts +85 -4
- package/dist/services/index.d.ts +85 -4
- package/dist/services/index.js +1621 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +1619 -1
- package/dist/services/index.mjs.map +1 -1
- package/dist/types/index.d.mts +203 -1
- package/dist/types/index.d.ts +203 -1
- package/dist/types/index.js +275 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/index.mjs +251 -0
- package/dist/types/index.mjs.map +1 -1
- package/dist/useForexTrading-BleeSor8.d.mts +80 -0
- package/dist/useForexTrading-ZgW_G40Q.d.ts +80 -0
- package/package.json +9 -2
- package/src/components/OneConnectButton.tsx +24 -1
- package/src/components/OneNFTGallery.tsx +13 -7
- package/src/components/OneOfframpWidget.tsx +4 -3
- package/src/components/OnePayWidget.tsx +10 -1
- package/src/components/OneSendWidget.tsx +3 -3
- package/src/components/OneSwapWidget.tsx +4 -4
- package/src/components/OneTransactionButton.tsx +28 -3
- package/src/components/OneWalletBalance.tsx +1 -1
- package/src/components/ai/OneChainSelector.tsx +63 -336
- package/src/components/ai/OneForexCapitalSplit.tsx +112 -0
- package/src/components/ai/OneForexConsoleView.tsx +90 -0
- package/src/components/ai/OneForexPairSelector.tsx +101 -0
- package/src/components/ai/OneForexPoolCard.tsx +105 -0
- package/src/components/ai/OneForexTradeHistory.tsx +107 -0
- package/src/components/ai/OnePairSelector.tsx +77 -434
- package/src/components/ai/console/OneAIQuantConsole.tsx +423 -0
- package/src/components/ai/console/OneAgentCard.tsx +383 -0
- package/src/components/ai/console/OneAgentConsole.tsx +469 -0
- package/src/components/ai/console/OneDecisionTimeline.tsx +433 -0
- package/src/components/ai/console/OneMetricsDashboard.tsx +493 -0
- package/src/components/ai/console/OnePositionCard.tsx +406 -0
- package/src/components/ai/console/OnePositionDetail.tsx +600 -0
- package/src/components/ai/console/OneRiskIndicator.tsx +464 -0
- package/src/components/ai/console/OneTradingConsole.tsx +660 -0
- package/src/components/ai/console/index.ts +17 -0
- package/src/components/ai/index.ts +10 -0
- package/src/hooks/index.ts +46 -0
- package/src/hooks/useAIDecisions.ts +280 -0
- package/src/hooks/useAIPositions.ts +349 -0
- package/src/hooks/useAIQuantConsole.ts +283 -0
- package/src/hooks/useAIRiskStatus.ts +276 -0
- package/src/hooks/useAITrading.ts +190 -0
- package/src/hooks/useBotSimulation.ts +201 -0
- package/src/hooks/useForexTrading.ts +430 -0
- package/src/hooks/useTradingConsole.ts +243 -0
- package/src/index.ts +123 -5
- package/src/providers/OneProvider.tsx +181 -5
- package/src/providers/index.ts +22 -8
- package/src/react-native.ts +41 -0
- package/src/services/forex/BotSimulationEngine.ts +968 -0
- package/src/services/forex/ForexPoolDataGenerator.ts +542 -0
- package/src/services/forex/ForexSimulationEngine.ts +482 -0
- package/src/services/forex/index.ts +21 -0
- package/src/services/index.ts +16 -0
- package/src/types/aiTrading.ts +151 -0
- package/src/types/console.ts +380 -0
- package/src/types/forex.ts +282 -0
- package/src/types/index.ts +106 -0
- package/dist/price-CgqXPnT3.d.ts +0 -13
- package/dist/price-ClbLHHjv.d.mts +0 -13
- package/dist/supabase-BT0c7q9e.d.mts +0 -82
- package/dist/supabase-BT0c7q9e.d.ts +0 -82
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OneChainSelector - Multi-chain selection component
|
|
3
|
-
* Part of ONE Ecosystem SDK -
|
|
2
|
+
* OneChainSelector - Multi-chain selection component for AI trading
|
|
3
|
+
* Part of ONE Ecosystem SDK - can be used by any ecosystem partner
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React
|
|
7
|
-
import { View, Text, StyleSheet, TouchableOpacity, ViewStyle, TextStyle
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { View, Text, StyleSheet, TouchableOpacity, ViewStyle, TextStyle } from 'react-native';
|
|
8
8
|
|
|
9
9
|
// Chain configuration with branding
|
|
10
10
|
export const CHAIN_CONFIG: Record<string, { name: string; icon: string; color: string }> = {
|
|
@@ -37,19 +37,12 @@ export interface OneChainSelectorProps {
|
|
|
37
37
|
subtitle?: string;
|
|
38
38
|
/** Minimum required selections (for multi-select) */
|
|
39
39
|
minSelections?: number;
|
|
40
|
-
/** Placeholder text */
|
|
41
|
-
placeholder?: string;
|
|
42
40
|
/** Custom styles */
|
|
43
41
|
style?: ViewStyle;
|
|
44
42
|
/** Custom title style */
|
|
45
43
|
titleStyle?: TextStyle;
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
const isDesktop = () => {
|
|
49
|
-
const { width } = Dimensions.get('window');
|
|
50
|
-
return Platform.OS === 'web' && width >= 768;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
46
|
export const OneChainSelector: React.FC<OneChainSelectorProps> = ({
|
|
54
47
|
supportedChains,
|
|
55
48
|
selectedChains,
|
|
@@ -59,179 +52,69 @@ export const OneChainSelector: React.FC<OneChainSelectorProps> = ({
|
|
|
59
52
|
title,
|
|
60
53
|
subtitle,
|
|
61
54
|
minSelections = 1,
|
|
62
|
-
placeholder = 'Select chains...',
|
|
63
55
|
style,
|
|
64
56
|
titleStyle,
|
|
65
57
|
}) => {
|
|
66
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
67
|
-
const desktop = isDesktop();
|
|
68
|
-
|
|
69
58
|
const handleSelect = (chain: string) => {
|
|
70
59
|
if (multiSelect) {
|
|
60
|
+
// In multi-select, prevent deselecting if at minimum
|
|
71
61
|
if (selectedChains.includes(chain) && selectedChains.length <= minSelections) {
|
|
72
62
|
return;
|
|
73
63
|
}
|
|
74
64
|
onSelectChain(chain);
|
|
75
65
|
} else {
|
|
66
|
+
// Single select - always allow selection
|
|
76
67
|
if (!selectedChains.includes(chain)) {
|
|
77
68
|
onSelectChain(chain);
|
|
78
69
|
}
|
|
79
|
-
setIsOpen(false);
|
|
80
70
|
}
|
|
81
71
|
};
|
|
82
72
|
|
|
83
|
-
// Desktop: Inline grid display
|
|
84
|
-
if (desktop) {
|
|
85
|
-
return (
|
|
86
|
-
<View style={[styles.container, style]}>
|
|
87
|
-
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
|
|
88
|
-
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
|
|
89
|
-
|
|
90
|
-
<View style={styles.desktopGrid}>
|
|
91
|
-
{supportedChains.map((chain) => {
|
|
92
|
-
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
93
|
-
const isSelected = selectedChains.includes(chain);
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
<TouchableOpacity
|
|
97
|
-
key={chain}
|
|
98
|
-
style={[
|
|
99
|
-
styles.desktopChip,
|
|
100
|
-
isSelected && styles.desktopChipSelected,
|
|
101
|
-
isSelected && { borderColor: accentColor, backgroundColor: accentColor + '12' }
|
|
102
|
-
]}
|
|
103
|
-
onPress={() => handleSelect(chain)}
|
|
104
|
-
activeOpacity={0.7}
|
|
105
|
-
>
|
|
106
|
-
<View style={[styles.desktopIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
107
|
-
<Text style={[styles.desktopIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
108
|
-
</View>
|
|
109
|
-
<Text style={[
|
|
110
|
-
styles.desktopChipText,
|
|
111
|
-
isSelected && { color: accentColor, fontWeight: '600' }
|
|
112
|
-
]}>
|
|
113
|
-
{chainInfo.name}
|
|
114
|
-
</Text>
|
|
115
|
-
{isSelected && (
|
|
116
|
-
<View style={[styles.desktopCheckbox, { backgroundColor: accentColor }]}>
|
|
117
|
-
<Text style={styles.desktopCheckIcon}>✓</Text>
|
|
118
|
-
</View>
|
|
119
|
-
)}
|
|
120
|
-
</TouchableOpacity>
|
|
121
|
-
);
|
|
122
|
-
})}
|
|
123
|
-
</View>
|
|
124
|
-
|
|
125
|
-
{multiSelect && selectedChains.length > 0 && (
|
|
126
|
-
<Text style={[styles.selectedCount, { color: accentColor }]}>
|
|
127
|
-
{selectedChains.length} chain{selectedChains.length > 1 ? 's' : ''} selected
|
|
128
|
-
</Text>
|
|
129
|
-
)}
|
|
130
|
-
</View>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Mobile: Dropdown modal
|
|
135
73
|
return (
|
|
136
74
|
<View style={[styles.container, style]}>
|
|
137
75
|
{title && <Text style={[styles.title, titleStyle]}>{title}</Text>}
|
|
138
76
|
{subtitle && <Text style={styles.subtitle}>{subtitle}</Text>}
|
|
139
77
|
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
78
|
+
<View style={styles.chainsContainer}>
|
|
79
|
+
{supportedChains.map((chain) => {
|
|
80
|
+
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
81
|
+
const isSelected = selectedChains.includes(chain);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<TouchableOpacity
|
|
85
|
+
key={chain}
|
|
86
|
+
style={[
|
|
87
|
+
styles.chainChip,
|
|
88
|
+
isSelected && styles.chainChipSelected,
|
|
89
|
+
isSelected && { borderColor: accentColor, backgroundColor: accentColor + '15' }
|
|
90
|
+
]}
|
|
91
|
+
onPress={() => handleSelect(chain)}
|
|
92
|
+
activeOpacity={0.7}
|
|
93
|
+
>
|
|
94
|
+
<View style={[styles.chainIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
95
|
+
<Text style={[styles.chainIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
151
96
|
</View>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
</
|
|
97
|
+
<Text style={[
|
|
98
|
+
styles.chainText,
|
|
99
|
+
isSelected && { color: accentColor, fontWeight: '600' }
|
|
100
|
+
]}>
|
|
101
|
+
{chainInfo.name}
|
|
102
|
+
</Text>
|
|
103
|
+
{isSelected && (
|
|
104
|
+
<Text style={[styles.checkmark, { color: accentColor }]}>✓</Text>
|
|
105
|
+
)}
|
|
106
|
+
</TouchableOpacity>
|
|
107
|
+
);
|
|
108
|
+
})}
|
|
109
|
+
</View>
|
|
165
110
|
|
|
166
111
|
{multiSelect && selectedChains.length > 0 && (
|
|
167
|
-
<
|
|
168
|
-
{
|
|
169
|
-
|
|
112
|
+
<View style={styles.selectedInfo}>
|
|
113
|
+
<Text style={styles.selectedText}>
|
|
114
|
+
{selectedChains.length} chain{selectedChains.length > 1 ? 's' : ''} selected
|
|
115
|
+
</Text>
|
|
116
|
+
</View>
|
|
170
117
|
)}
|
|
171
|
-
|
|
172
|
-
<Modal
|
|
173
|
-
visible={isOpen}
|
|
174
|
-
transparent
|
|
175
|
-
animationType="fade"
|
|
176
|
-
onRequestClose={() => setIsOpen(false)}
|
|
177
|
-
>
|
|
178
|
-
<Pressable style={styles.modalOverlay} onPress={() => setIsOpen(false)}>
|
|
179
|
-
<View style={styles.modalContent}>
|
|
180
|
-
<View style={styles.modalHeader}>
|
|
181
|
-
<Text style={styles.modalTitle}>{title || 'Select Chains'}</Text>
|
|
182
|
-
<TouchableOpacity onPress={() => setIsOpen(false)}>
|
|
183
|
-
<Text style={styles.modalClose}>✕</Text>
|
|
184
|
-
</TouchableOpacity>
|
|
185
|
-
</View>
|
|
186
|
-
|
|
187
|
-
<ScrollView style={styles.optionsList} showsVerticalScrollIndicator={false}>
|
|
188
|
-
{supportedChains.map((chain) => {
|
|
189
|
-
const chainInfo = CHAIN_CONFIG[chain] || { name: chain, icon: '●', color: '#888' };
|
|
190
|
-
const isSelected = selectedChains.includes(chain);
|
|
191
|
-
|
|
192
|
-
return (
|
|
193
|
-
<TouchableOpacity
|
|
194
|
-
key={chain}
|
|
195
|
-
style={[
|
|
196
|
-
styles.optionItem,
|
|
197
|
-
isSelected && styles.optionItemSelected,
|
|
198
|
-
isSelected && { backgroundColor: accentColor + '10', borderColor: accentColor }
|
|
199
|
-
]}
|
|
200
|
-
onPress={() => handleSelect(chain)}
|
|
201
|
-
activeOpacity={0.7}
|
|
202
|
-
>
|
|
203
|
-
<View style={[styles.optionIconBg, { backgroundColor: chainInfo.color + '20' }]}>
|
|
204
|
-
<Text style={[styles.optionIcon, { color: chainInfo.color }]}>{chainInfo.icon}</Text>
|
|
205
|
-
</View>
|
|
206
|
-
<Text style={[
|
|
207
|
-
styles.optionText,
|
|
208
|
-
isSelected && { color: accentColor, fontWeight: '600' }
|
|
209
|
-
]}>
|
|
210
|
-
{chainInfo.name}
|
|
211
|
-
</Text>
|
|
212
|
-
{isSelected ? (
|
|
213
|
-
<View style={[styles.checkbox, { backgroundColor: accentColor }]}>
|
|
214
|
-
<Text style={styles.checkboxIcon}>✓</Text>
|
|
215
|
-
</View>
|
|
216
|
-
) : (
|
|
217
|
-
<View style={styles.checkboxEmpty} />
|
|
218
|
-
)}
|
|
219
|
-
</TouchableOpacity>
|
|
220
|
-
);
|
|
221
|
-
})}
|
|
222
|
-
</ScrollView>
|
|
223
|
-
|
|
224
|
-
{multiSelect && (
|
|
225
|
-
<TouchableOpacity
|
|
226
|
-
style={[styles.doneButton, { backgroundColor: accentColor }]}
|
|
227
|
-
onPress={() => setIsOpen(false)}
|
|
228
|
-
>
|
|
229
|
-
<Text style={styles.doneButtonText}>Done ({selectedChains.length})</Text>
|
|
230
|
-
</TouchableOpacity>
|
|
231
|
-
)}
|
|
232
|
-
</View>
|
|
233
|
-
</Pressable>
|
|
234
|
-
</Modal>
|
|
235
118
|
</View>
|
|
236
119
|
);
|
|
237
120
|
};
|
|
@@ -251,206 +134,50 @@ const styles = StyleSheet.create({
|
|
|
251
134
|
color: '#666',
|
|
252
135
|
marginBottom: 12,
|
|
253
136
|
},
|
|
254
|
-
|
|
255
|
-
desktopGrid: {
|
|
137
|
+
chainsContainer: {
|
|
256
138
|
flexDirection: 'row',
|
|
257
139
|
flexWrap: 'wrap',
|
|
258
|
-
gap:
|
|
140
|
+
gap: 8,
|
|
259
141
|
},
|
|
260
|
-
|
|
142
|
+
chainChip: {
|
|
261
143
|
flexDirection: 'row',
|
|
262
144
|
alignItems: 'center',
|
|
263
|
-
paddingHorizontal:
|
|
264
|
-
paddingVertical:
|
|
145
|
+
paddingHorizontal: 12,
|
|
146
|
+
paddingVertical: 8,
|
|
265
147
|
backgroundColor: '#fff',
|
|
266
|
-
borderRadius:
|
|
148
|
+
borderRadius: 12,
|
|
267
149
|
borderWidth: 2,
|
|
268
|
-
borderColor: '#
|
|
269
|
-
gap:
|
|
270
|
-
cursor: 'pointer' as any,
|
|
150
|
+
borderColor: '#e5e5e5',
|
|
151
|
+
gap: 8,
|
|
271
152
|
},
|
|
272
|
-
|
|
153
|
+
chainChipSelected: {
|
|
273
154
|
borderWidth: 2,
|
|
274
155
|
},
|
|
275
|
-
|
|
276
|
-
width:
|
|
277
|
-
height:
|
|
278
|
-
borderRadius:
|
|
156
|
+
chainIconBg: {
|
|
157
|
+
width: 28,
|
|
158
|
+
height: 28,
|
|
159
|
+
borderRadius: 14,
|
|
279
160
|
alignItems: 'center',
|
|
280
161
|
justifyContent: 'center',
|
|
281
162
|
},
|
|
282
|
-
|
|
163
|
+
chainIcon: {
|
|
283
164
|
fontSize: 14,
|
|
284
165
|
fontWeight: '700',
|
|
285
166
|
},
|
|
286
|
-
|
|
167
|
+
chainText: {
|
|
287
168
|
fontSize: 14,
|
|
288
|
-
color: '#
|
|
289
|
-
},
|
|
290
|
-
desktopCheckbox: {
|
|
291
|
-
width: 20,
|
|
292
|
-
height: 20,
|
|
293
|
-
borderRadius: 10,
|
|
294
|
-
alignItems: 'center',
|
|
295
|
-
justifyContent: 'center',
|
|
296
|
-
marginLeft: 4,
|
|
297
|
-
},
|
|
298
|
-
desktopCheckIcon: {
|
|
299
|
-
fontSize: 12,
|
|
300
|
-
color: '#fff',
|
|
301
|
-
fontWeight: '700',
|
|
302
|
-
},
|
|
303
|
-
// Mobile dropdown styles
|
|
304
|
-
dropdownTrigger: {
|
|
305
|
-
flexDirection: 'row',
|
|
306
|
-
alignItems: 'center',
|
|
307
|
-
justifyContent: 'space-between',
|
|
308
|
-
paddingHorizontal: 14,
|
|
309
|
-
paddingVertical: 12,
|
|
310
|
-
backgroundColor: '#fff',
|
|
311
|
-
borderRadius: 12,
|
|
312
|
-
borderWidth: 2,
|
|
313
|
-
borderColor: '#e5e5e5',
|
|
314
|
-
minHeight: 52,
|
|
315
|
-
},
|
|
316
|
-
selectedPreview: {
|
|
317
|
-
flex: 1,
|
|
318
|
-
flexDirection: 'row',
|
|
319
|
-
alignItems: 'center',
|
|
320
|
-
gap: 6,
|
|
321
|
-
},
|
|
322
|
-
previewChip: {
|
|
323
|
-
width: 32,
|
|
324
|
-
height: 32,
|
|
325
|
-
borderRadius: 16,
|
|
326
|
-
alignItems: 'center',
|
|
327
|
-
justifyContent: 'center',
|
|
169
|
+
color: '#666',
|
|
328
170
|
},
|
|
329
|
-
|
|
330
|
-
fontSize:
|
|
171
|
+
checkmark: {
|
|
172
|
+
fontSize: 16,
|
|
331
173
|
fontWeight: '700',
|
|
332
174
|
},
|
|
333
|
-
|
|
334
|
-
|
|
175
|
+
selectedInfo: {
|
|
176
|
+
marginTop: 8,
|
|
335
177
|
paddingVertical: 4,
|
|
336
|
-
backgroundColor: '#f0f0f0',
|
|
337
|
-
borderRadius: 8,
|
|
338
|
-
},
|
|
339
|
-
previewMoreText: {
|
|
340
|
-
fontSize: 12,
|
|
341
|
-
color: '#666',
|
|
342
|
-
fontWeight: '600',
|
|
343
|
-
},
|
|
344
|
-
placeholderText: {
|
|
345
|
-
fontSize: 14,
|
|
346
|
-
color: '#999',
|
|
347
|
-
},
|
|
348
|
-
dropdownArrow: {
|
|
349
|
-
fontSize: 12,
|
|
350
|
-
color: '#888',
|
|
351
|
-
marginLeft: 8,
|
|
352
178
|
},
|
|
353
|
-
|
|
179
|
+
selectedText: {
|
|
354
180
|
fontSize: 12,
|
|
355
|
-
marginTop: 6,
|
|
356
|
-
fontWeight: '500',
|
|
357
|
-
},
|
|
358
|
-
// Modal styles
|
|
359
|
-
modalOverlay: {
|
|
360
|
-
flex: 1,
|
|
361
|
-
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
362
|
-
justifyContent: 'center',
|
|
363
|
-
alignItems: 'center',
|
|
364
|
-
},
|
|
365
|
-
modalContent: {
|
|
366
|
-
width: '85%',
|
|
367
|
-
maxWidth: 340,
|
|
368
|
-
maxHeight: '70%',
|
|
369
|
-
backgroundColor: '#fff',
|
|
370
|
-
borderRadius: 16,
|
|
371
|
-
overflow: 'hidden',
|
|
372
|
-
},
|
|
373
|
-
modalHeader: {
|
|
374
|
-
flexDirection: 'row',
|
|
375
|
-
justifyContent: 'space-between',
|
|
376
|
-
alignItems: 'center',
|
|
377
|
-
paddingHorizontal: 16,
|
|
378
|
-
paddingVertical: 14,
|
|
379
|
-
borderBottomWidth: 1,
|
|
380
|
-
borderBottomColor: '#f0f0f0',
|
|
381
|
-
},
|
|
382
|
-
modalTitle: {
|
|
383
|
-
fontSize: 18,
|
|
384
|
-
fontWeight: '700',
|
|
385
|
-
color: '#1a1a1a',
|
|
386
|
-
},
|
|
387
|
-
modalClose: {
|
|
388
|
-
fontSize: 20,
|
|
389
181
|
color: '#888',
|
|
390
|
-
padding: 4,
|
|
391
|
-
},
|
|
392
|
-
optionsList: {
|
|
393
|
-
padding: 8,
|
|
394
|
-
},
|
|
395
|
-
optionItem: {
|
|
396
|
-
flexDirection: 'row',
|
|
397
|
-
alignItems: 'center',
|
|
398
|
-
paddingHorizontal: 12,
|
|
399
|
-
paddingVertical: 12,
|
|
400
|
-
borderRadius: 10,
|
|
401
|
-
borderWidth: 1,
|
|
402
|
-
borderColor: 'transparent',
|
|
403
|
-
marginBottom: 6,
|
|
404
|
-
gap: 12,
|
|
405
|
-
},
|
|
406
|
-
optionItemSelected: {
|
|
407
|
-
borderWidth: 1,
|
|
408
|
-
},
|
|
409
|
-
optionIconBg: {
|
|
410
|
-
width: 36,
|
|
411
|
-
height: 36,
|
|
412
|
-
borderRadius: 18,
|
|
413
|
-
alignItems: 'center',
|
|
414
|
-
justifyContent: 'center',
|
|
415
|
-
},
|
|
416
|
-
optionIcon: {
|
|
417
|
-
fontSize: 16,
|
|
418
|
-
fontWeight: '700',
|
|
419
|
-
},
|
|
420
|
-
optionText: {
|
|
421
|
-
flex: 1,
|
|
422
|
-
fontSize: 15,
|
|
423
|
-
color: '#333',
|
|
424
|
-
},
|
|
425
|
-
checkbox: {
|
|
426
|
-
width: 24,
|
|
427
|
-
height: 24,
|
|
428
|
-
borderRadius: 12,
|
|
429
|
-
alignItems: 'center',
|
|
430
|
-
justifyContent: 'center',
|
|
431
|
-
},
|
|
432
|
-
checkboxIcon: {
|
|
433
|
-
fontSize: 14,
|
|
434
|
-
color: '#fff',
|
|
435
|
-
fontWeight: '700',
|
|
436
|
-
},
|
|
437
|
-
checkboxEmpty: {
|
|
438
|
-
width: 24,
|
|
439
|
-
height: 24,
|
|
440
|
-
borderRadius: 12,
|
|
441
|
-
borderWidth: 2,
|
|
442
|
-
borderColor: '#ddd',
|
|
443
|
-
},
|
|
444
|
-
doneButton: {
|
|
445
|
-
marginHorizontal: 16,
|
|
446
|
-
marginVertical: 12,
|
|
447
|
-
paddingVertical: 14,
|
|
448
|
-
borderRadius: 10,
|
|
449
|
-
alignItems: 'center',
|
|
450
|
-
},
|
|
451
|
-
doneButtonText: {
|
|
452
|
-
fontSize: 16,
|
|
453
|
-
fontWeight: '600',
|
|
454
|
-
color: '#fff',
|
|
455
182
|
},
|
|
456
183
|
});
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneForexCapitalSplit - Displays 50/50 capital allocation split
|
|
3
|
+
* Part of ONE Ecosystem SDK
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { View, Text, StyleSheet, ViewStyle } from 'react-native';
|
|
8
|
+
import { FOREX_CAPITAL_SPLIT, FOREX_POOL_DEFAULTS, computePoolAllocations } from '../../types/forex';
|
|
9
|
+
|
|
10
|
+
export interface OneForexCapitalSplitProps {
|
|
11
|
+
/** Total investment amount */
|
|
12
|
+
amount: number;
|
|
13
|
+
/** Labels (provide translated strings) */
|
|
14
|
+
labels?: {
|
|
15
|
+
title?: string;
|
|
16
|
+
tradingCapital?: string;
|
|
17
|
+
poolReserves?: string;
|
|
18
|
+
clearing?: string;
|
|
19
|
+
hedging?: string;
|
|
20
|
+
insurance?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Show pool breakdown within reserves */
|
|
23
|
+
showPoolBreakdown?: boolean;
|
|
24
|
+
/** Custom container style */
|
|
25
|
+
style?: ViewStyle;
|
|
26
|
+
/** Dark mode */
|
|
27
|
+
dark?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const OneForexCapitalSplit: React.FC<OneForexCapitalSplitProps> = ({
|
|
31
|
+
amount,
|
|
32
|
+
labels = {},
|
|
33
|
+
showPoolBreakdown = true,
|
|
34
|
+
style,
|
|
35
|
+
dark = false,
|
|
36
|
+
}) => {
|
|
37
|
+
const allocs = computePoolAllocations(amount);
|
|
38
|
+
const bg = dark ? '#111111' : '#ffffff';
|
|
39
|
+
const border = dark ? '#1a1a1a' : '#e5e5e5';
|
|
40
|
+
const textPrimary = dark ? '#ffffff' : '#1a1a1a';
|
|
41
|
+
const textSecondary = dark ? '#9ca3af' : '#666666';
|
|
42
|
+
const itemBg = dark ? '#0a0a0a' : '#f5f5f5';
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<View style={[styles.container, { backgroundColor: bg, borderColor: border }, style]}>
|
|
46
|
+
{labels.title && <Text style={[styles.title, { color: textPrimary }]}>{labels.title}</Text>}
|
|
47
|
+
|
|
48
|
+
<View style={styles.splitRow}>
|
|
49
|
+
<View style={[styles.splitItem, { backgroundColor: itemBg }]}>
|
|
50
|
+
<View style={[styles.dot, { backgroundColor: '#0EA5E9' }]} />
|
|
51
|
+
<Text style={[styles.splitLabel, { color: textSecondary }]}>
|
|
52
|
+
{labels.tradingCapital || 'Active Trading (RFQ)'}
|
|
53
|
+
</Text>
|
|
54
|
+
<Text style={[styles.splitPct, { color: textSecondary }]}>50%</Text>
|
|
55
|
+
<Text style={[styles.splitAmt, { color: textPrimary }]}>
|
|
56
|
+
${allocs.tradingCapital.toLocaleString()}
|
|
57
|
+
</Text>
|
|
58
|
+
</View>
|
|
59
|
+
<View style={[styles.splitItem, { backgroundColor: itemBg }]}>
|
|
60
|
+
<View style={[styles.dot, { backgroundColor: '#8B5CF6' }]} />
|
|
61
|
+
<Text style={[styles.splitLabel, { color: textSecondary }]}>
|
|
62
|
+
{labels.poolReserves || 'Pool Reserves'}
|
|
63
|
+
</Text>
|
|
64
|
+
<Text style={[styles.splitPct, { color: textSecondary }]}>50%</Text>
|
|
65
|
+
<Text style={[styles.splitAmt, { color: textPrimary }]}>
|
|
66
|
+
${allocs.totalPoolReserves.toLocaleString()}
|
|
67
|
+
</Text>
|
|
68
|
+
</View>
|
|
69
|
+
</View>
|
|
70
|
+
|
|
71
|
+
{showPoolBreakdown && amount > 0 && (
|
|
72
|
+
<View style={[styles.breakdown, { borderTopColor: border }]}>
|
|
73
|
+
{FOREX_POOL_DEFAULTS.map(pool => {
|
|
74
|
+
const poolAmt = allocs[pool.id as keyof typeof allocs] as number;
|
|
75
|
+
return (
|
|
76
|
+
<View key={pool.id} style={styles.poolRow}>
|
|
77
|
+
<View style={[styles.poolDot, { backgroundColor: pool.color }]} />
|
|
78
|
+
<Text style={[styles.poolName, { color: textSecondary }]}>
|
|
79
|
+
{(labels as any)?.[pool.id] || pool.nameKey}
|
|
80
|
+
</Text>
|
|
81
|
+
<View style={[styles.poolBar, { backgroundColor: dark ? '#1a1a1a' : '#e5e5e5' }]}>
|
|
82
|
+
<View style={[styles.poolBarFill, { width: `${pool.allocation * 100}%`, backgroundColor: pool.color }]} />
|
|
83
|
+
</View>
|
|
84
|
+
<Text style={[styles.poolAmt, { color: textPrimary }]}>
|
|
85
|
+
${poolAmt.toLocaleString()}
|
|
86
|
+
</Text>
|
|
87
|
+
</View>
|
|
88
|
+
);
|
|
89
|
+
})}
|
|
90
|
+
</View>
|
|
91
|
+
)}
|
|
92
|
+
</View>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const styles = StyleSheet.create({
|
|
97
|
+
container: { borderRadius: 8, borderWidth: 1, padding: 14 },
|
|
98
|
+
title: { fontSize: 14, fontWeight: '600', marginBottom: 12 },
|
|
99
|
+
splitRow: { gap: 8 },
|
|
100
|
+
splitItem: { flexDirection: 'row', alignItems: 'center', paddingVertical: 10, paddingHorizontal: 12, borderRadius: 8 },
|
|
101
|
+
dot: { width: 10, height: 10, borderRadius: 5, marginRight: 8 },
|
|
102
|
+
splitLabel: { flex: 1, fontSize: 13, fontWeight: '500' },
|
|
103
|
+
splitPct: { fontSize: 12, fontWeight: '600', marginRight: 12 },
|
|
104
|
+
splitAmt: { fontSize: 14, fontWeight: '700' },
|
|
105
|
+
breakdown: { marginTop: 12, paddingTop: 12, borderTopWidth: 1 },
|
|
106
|
+
poolRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 },
|
|
107
|
+
poolDot: { width: 8, height: 8, borderRadius: 4, marginRight: 8 },
|
|
108
|
+
poolName: { width: 80, fontSize: 12 },
|
|
109
|
+
poolBar: { flex: 1, height: 6, borderRadius: 3, overflow: 'hidden', marginHorizontal: 8 },
|
|
110
|
+
poolBarFill: { height: '100%', borderRadius: 3 },
|
|
111
|
+
poolAmt: { width: 70, fontSize: 12, fontWeight: '600', textAlign: 'right' },
|
|
112
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneForexConsoleView - Displays live forex trading console log feed
|
|
3
|
+
* Part of ONE Ecosystem SDK
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React, { useRef, useEffect } from 'react';
|
|
7
|
+
import { View, Text, StyleSheet, ScrollView, ViewStyle, Platform } from 'react-native';
|
|
8
|
+
import type { ForexLogEntry } from '../../types/forex';
|
|
9
|
+
import { FOREX_LOG_COLORS } from '../../types/console';
|
|
10
|
+
|
|
11
|
+
const MONO = Platform.OS === 'ios' ? 'Courier New' : 'monospace';
|
|
12
|
+
|
|
13
|
+
export interface OneForexConsoleViewProps {
|
|
14
|
+
/** Array of log entries to display */
|
|
15
|
+
logs: ForexLogEntry[];
|
|
16
|
+
/** Maximum visible entries */
|
|
17
|
+
maxItems?: number;
|
|
18
|
+
/** Auto-scroll to bottom */
|
|
19
|
+
autoScroll?: boolean;
|
|
20
|
+
/** Custom container style */
|
|
21
|
+
style?: ViewStyle;
|
|
22
|
+
/** Console height */
|
|
23
|
+
height?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const OneForexConsoleView: React.FC<OneForexConsoleViewProps> = ({
|
|
27
|
+
logs,
|
|
28
|
+
maxItems = 100,
|
|
29
|
+
autoScroll = true,
|
|
30
|
+
style,
|
|
31
|
+
height = 400,
|
|
32
|
+
}) => {
|
|
33
|
+
const scrollRef = useRef<ScrollView>(null);
|
|
34
|
+
const visibleLogs = logs.slice(-maxItems);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (autoScroll && scrollRef.current) {
|
|
38
|
+
setTimeout(() => scrollRef.current?.scrollToEnd({ animated: true }), 50);
|
|
39
|
+
}
|
|
40
|
+
}, [logs.length, autoScroll]);
|
|
41
|
+
|
|
42
|
+
const formatTime = (ts: number) => {
|
|
43
|
+
const d = new Date(ts);
|
|
44
|
+
return `${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}:${d.getSeconds().toString().padStart(2, '0')}`;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<View style={[styles.container, { height }, style]}>
|
|
49
|
+
<ScrollView ref={scrollRef} style={styles.scroll} contentContainerStyle={styles.scrollContent}>
|
|
50
|
+
{visibleLogs.map((log) => (
|
|
51
|
+
<View key={log.id} style={styles.logRow}>
|
|
52
|
+
<Text style={styles.timestamp}>{formatTime(log.timestamp)}</Text>
|
|
53
|
+
<Text style={[styles.type, { color: FOREX_LOG_COLORS[log.type] || '#9CA3AF' }]}>
|
|
54
|
+
{log.type.padEnd(8)}
|
|
55
|
+
</Text>
|
|
56
|
+
<Text style={[
|
|
57
|
+
styles.message,
|
|
58
|
+
log.importance === 'high' && styles.messageHigh,
|
|
59
|
+
]} numberOfLines={2}>
|
|
60
|
+
{log.message}
|
|
61
|
+
</Text>
|
|
62
|
+
</View>
|
|
63
|
+
))}
|
|
64
|
+
{visibleLogs.length === 0 && (
|
|
65
|
+
<Text style={styles.emptyText}>Waiting for trading activity...</Text>
|
|
66
|
+
)}
|
|
67
|
+
</ScrollView>
|
|
68
|
+
</View>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Terminal palette – always dark regardless of app theme
|
|
73
|
+
const T = {
|
|
74
|
+
base: '#0A0A0C',
|
|
75
|
+
border: '#2A2A35',
|
|
76
|
+
muted: '#555560',
|
|
77
|
+
secondary: '#9CA3AF',
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const styles = StyleSheet.create({
|
|
81
|
+
container: { backgroundColor: T.base, borderRadius: 8, borderWidth: 1, borderColor: T.border, overflow: 'hidden' },
|
|
82
|
+
scroll: { flex: 1 },
|
|
83
|
+
scrollContent: { padding: 8 },
|
|
84
|
+
logRow: { flexDirection: 'row', paddingVertical: 3 },
|
|
85
|
+
timestamp: { fontFamily: MONO, fontSize: 10, color: T.muted, width: 60, marginRight: 6 },
|
|
86
|
+
type: { fontFamily: MONO, fontSize: 10, fontWeight: '700', width: 65, marginRight: 6 },
|
|
87
|
+
message: { fontFamily: MONO, fontSize: 10, color: T.secondary, flex: 1 },
|
|
88
|
+
messageHigh: { color: '#ffffff', fontWeight: '600' },
|
|
89
|
+
emptyText: { fontFamily: MONO, fontSize: 11, color: T.muted, textAlign: 'center', paddingVertical: 40 },
|
|
90
|
+
});
|