@blazium/ton-connect-mobile 1.2.0 → 1.2.3

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.
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
7
- import { TonConnectMobile, ConnectionStatus, WalletInfo, SendTransactionRequest } from '../index';
8
- import type { TonConnectMobileConfig } from '../types';
7
+ import { TonConnectMobile, ConnectionStatus, WalletInfo, SendTransactionRequest, WalletDefinition, Network, BalanceResponse, TransactionStatusResponse } from '../index';
8
+ import type { TonConnectMobileConfig, TonConnectEventType, TonConnectEventListener } from '../types';
9
9
  import { WalletSelectionModal } from './WalletSelectionModal';
10
10
 
11
11
  /**
@@ -54,6 +54,7 @@ export interface SignDataResponse {
54
54
 
55
55
  /**
56
56
  * TonConnect UI instance interface (compatible with @tonconnect/ui-react)
57
+ * Includes all features from @tonconnect/ui-react for full compatibility
57
58
  */
58
59
  export interface TonConnectUI {
59
60
  /** Open connection modal */
@@ -68,6 +69,24 @@ export interface TonConnectUI {
68
69
  sendTransaction: (transaction: SendTransactionRequest) => Promise<TransactionResponse>;
69
70
  /** Sign data */
70
71
  signData: (request: SignDataRequest) => Promise<SignDataResponse>;
72
+ /** Restore connection from stored session */
73
+ restoreConnection: () => Promise<void>;
74
+ /** Set wallet list (customize available wallets) */
75
+ setWalletList: (wallets: WalletDefinition[]) => void;
76
+ /** Get current network */
77
+ getNetwork: () => Network;
78
+ /** Set network (mainnet/testnet) */
79
+ setNetwork: (network: Network) => void;
80
+ /** Get wallet balance */
81
+ getBalance: (address?: string) => Promise<BalanceResponse>;
82
+ /** Get transaction status */
83
+ getTransactionStatus: (boc: string, maxAttempts?: number, intervalMs?: number) => Promise<TransactionStatusResponse>;
84
+ /** Get transaction status by hash */
85
+ getTransactionStatusByHash: (txHash: string, address: string) => Promise<TransactionStatusResponse>;
86
+ /** Add event listener */
87
+ on: <T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>) => () => void;
88
+ /** Remove event listener */
89
+ off: <T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>) => void;
71
90
  /** Current wallet state */
72
91
  wallet: WalletState | null;
73
92
  /** Modal open state */
@@ -109,18 +128,38 @@ export function TonConnectUIProvider({
109
128
  children,
110
129
  sdkInstance,
111
130
  }: TonConnectUIProviderProps): JSX.Element {
112
- const [sdk] = useState<TonConnectMobile>(() => sdkInstance || new TonConnectMobile(config));
131
+ // CRITICAL: Initialize SDK only once
132
+ const [sdk] = useState<TonConnectMobile>(() => {
133
+ if (sdkInstance) {
134
+ return sdkInstance;
135
+ }
136
+ try {
137
+ return new TonConnectMobile(config);
138
+ } catch (error) {
139
+ console.error('[TonConnectUIProvider] Failed to initialize SDK:', error);
140
+ throw error;
141
+ }
142
+ });
113
143
  const [walletState, setWalletState] = useState<WalletState | null>(null);
114
144
  const [modalOpen, setModalOpen] = useState(false);
115
145
  const [isConnecting, setIsConnecting] = useState(false);
146
+ const [customWalletList, setCustomWalletList] = useState<WalletDefinition[] | null>(null);
147
+
148
+ // Get chain ID based on network
149
+ const getChainId = useCallback((network: Network): number => {
150
+ // TON mainnet chain ID: -239
151
+ // TON testnet chain ID: -3
152
+ return network === 'testnet' ? -3 : -239;
153
+ }, []);
116
154
 
117
155
  // Update wallet state from SDK status
118
156
  const updateWalletState = useCallback((status: ConnectionStatus) => {
119
157
  if (status.connected && status.wallet) {
158
+ const network = sdk.getNetwork();
120
159
  setWalletState({
121
160
  account: {
122
161
  address: status.wallet.address,
123
- chain: -239, // TON mainnet chain ID
162
+ chain: getChainId(network),
124
163
  publicKey: status.wallet.publicKey,
125
164
  },
126
165
  wallet: status.wallet,
@@ -133,7 +172,7 @@ export function TonConnectUIProvider({
133
172
  connected: false,
134
173
  });
135
174
  }
136
- }, []);
175
+ }, [sdk, getChainId]);
137
176
 
138
177
  // Subscribe to SDK status changes
139
178
  useEffect(() => {
@@ -202,11 +241,24 @@ export function TonConnectUIProvider({
202
241
  // Send transaction
203
242
  const sendTransaction = useCallback(
204
243
  async (transaction: SendTransactionRequest): Promise<TransactionResponse> => {
205
- const response = await sdk.sendTransaction(transaction);
206
- return {
207
- boc: response.boc,
208
- signature: response.signature,
209
- };
244
+ try {
245
+ // Validate transaction before sending
246
+ if (!transaction || !transaction.messages || transaction.messages.length === 0) {
247
+ throw new Error('Invalid transaction: messages array is required and cannot be empty');
248
+ }
249
+ if (!transaction.validUntil || transaction.validUntil <= Date.now()) {
250
+ throw new Error('Invalid transaction: validUntil must be in the future');
251
+ }
252
+
253
+ const response = await sdk.sendTransaction(transaction);
254
+ return {
255
+ boc: response.boc,
256
+ signature: response.signature,
257
+ };
258
+ } catch (error) {
259
+ console.error('[TonConnectUIProvider] Transaction error:', error);
260
+ throw error;
261
+ }
210
262
  },
211
263
  [sdk]
212
264
  );
@@ -214,15 +266,92 @@ export function TonConnectUIProvider({
214
266
  // Sign data
215
267
  const signData = useCallback(
216
268
  async (request: SignDataRequest): Promise<SignDataResponse> => {
217
- const response = await sdk.signData(request.data, request.version);
218
- return {
219
- signature: response.signature,
220
- timestamp: response.timestamp,
221
- };
269
+ try {
270
+ // Validate request
271
+ if (!request || (!request.data && request.data !== '')) {
272
+ throw new Error('Invalid sign data request: data is required');
273
+ }
274
+
275
+ const response = await sdk.signData(request.data, request.version);
276
+ return {
277
+ signature: response.signature,
278
+ timestamp: response.timestamp,
279
+ };
280
+ } catch (error) {
281
+ console.error('[TonConnectUIProvider] Sign data error:', error);
282
+ throw error;
283
+ }
222
284
  },
223
285
  [sdk]
224
286
  );
225
287
 
288
+ // Restore connection from stored session
289
+ const restoreConnection = useCallback(async (): Promise<void> => {
290
+ try {
291
+ // SDK automatically loads session on initialization
292
+ // This method triggers a re-check of the stored session
293
+ const status = sdk.getStatus();
294
+ if (status.connected && status.wallet) {
295
+ updateWalletState(status);
296
+ }
297
+ } catch (error) {
298
+ console.error('[TonConnectUIProvider] Restore connection error:', error);
299
+ throw error;
300
+ }
301
+ }, [sdk, updateWalletState]);
302
+
303
+ // Set wallet list (customize available wallets)
304
+ const setWalletList = useCallback((wallets: WalletDefinition[]): void => {
305
+ if (!wallets || !Array.isArray(wallets)) {
306
+ throw new Error('Wallet list must be an array');
307
+ }
308
+ setCustomWalletList(wallets);
309
+ }, []);
310
+
311
+ // Get network
312
+ const getNetwork = useCallback((): Network => {
313
+ return sdk.getNetwork();
314
+ }, [sdk]);
315
+
316
+ // Set network
317
+ const setNetwork = useCallback((network: Network): void => {
318
+ sdk.setNetwork(network);
319
+ // Update wallet state to reflect new chain ID
320
+ const status = sdk.getStatus();
321
+ updateWalletState(status);
322
+ }, [sdk, updateWalletState]);
323
+
324
+ // Get balance
325
+ const getBalance = useCallback(async (address?: string): Promise<BalanceResponse> => {
326
+ return await sdk.getBalance(address);
327
+ }, [sdk]);
328
+
329
+ // Get transaction status
330
+ const getTransactionStatus = useCallback(async (
331
+ boc: string,
332
+ maxAttempts: number = 10,
333
+ intervalMs: number = 2000
334
+ ): Promise<TransactionStatusResponse> => {
335
+ return await sdk.getTransactionStatus(boc, maxAttempts, intervalMs);
336
+ }, [sdk]);
337
+
338
+ // Get transaction status by hash
339
+ const getTransactionStatusByHash = useCallback(async (
340
+ txHash: string,
341
+ address: string
342
+ ): Promise<TransactionStatusResponse> => {
343
+ return await sdk.getTransactionStatusByHash(txHash, address);
344
+ }, [sdk]);
345
+
346
+ // Event listeners
347
+ const on = useCallback(<T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>): (() => void) => {
348
+ return sdk.on(event, listener);
349
+ }, [sdk]);
350
+
351
+ const off = useCallback(<T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>): void => {
352
+ sdk.off(event, listener);
353
+ }, [sdk]);
354
+
226
355
  // Create TonConnectUI instance
227
356
  const tonConnectUI: TonConnectUI = {
228
357
  openModal,
@@ -231,6 +360,15 @@ export function TonConnectUIProvider({
231
360
  disconnect,
232
361
  sendTransaction,
233
362
  signData,
363
+ restoreConnection,
364
+ setWalletList,
365
+ getNetwork,
366
+ setNetwork,
367
+ getBalance,
368
+ getTransactionStatus,
369
+ getTransactionStatusByHash,
370
+ on,
371
+ off,
234
372
  wallet: walletState,
235
373
  modalState: {
236
374
  open: modalOpen,
@@ -250,6 +388,7 @@ export function TonConnectUIProvider({
250
388
  <WalletSelectionModal
251
389
  visible={modalOpen && !walletState?.connected}
252
390
  onClose={closeModal}
391
+ wallets={customWalletList || undefined}
253
392
  />
254
393
  </TonConnectUIContext.Provider>
255
394
  );
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * WalletSelectionModal component
3
3
  * Provides a beautiful wallet selection UI compatible with @tonconnect/ui-react
4
+ * Matches the exact UI/UX of @tonconnect/ui-react wallet selection modal
4
5
  */
5
6
 
6
7
  import React from 'react';
@@ -11,8 +12,9 @@ import {
11
12
  TouchableOpacity,
12
13
  ScrollView,
13
14
  StyleSheet,
14
- Image,
15
15
  Platform,
16
+ Image,
17
+ ActivityIndicator,
16
18
  } from 'react-native';
17
19
  import { useTonConnectUI, useTonConnectSDK } from './index';
18
20
  import type { WalletDefinition } from '../index';
@@ -42,27 +44,56 @@ export function WalletSelectionModal({
42
44
  const sdk = useTonConnectSDK();
43
45
  const [wallets, setWallets] = React.useState<WalletDefinition[]>([]);
44
46
  const [connectingWallet, setConnectingWallet] = React.useState<string | null>(null);
47
+ const [walletAvailability, setWalletAvailability] = React.useState<Record<string, boolean>>({});
45
48
 
46
- // Load wallets
49
+ // Load wallets and check availability
47
50
  React.useEffect(() => {
48
- if (customWallets) {
49
- setWallets(customWallets);
50
- } else {
51
- const supportedWallets = sdk.getSupportedWallets();
52
- // Filter wallets for current platform
53
- const platform = Platform.OS === 'ios' ? 'ios' : Platform.OS === 'android' ? 'android' : 'web';
54
- const platformWallets = supportedWallets.filter((w) => w.platforms.includes(platform));
55
- setWallets(platformWallets);
51
+ const loadWallets = async () => {
52
+ if (customWallets) {
53
+ setWallets(customWallets);
54
+ } else {
55
+ const supportedWallets = sdk.getSupportedWallets();
56
+ // Show all wallets (like @tonconnect/ui-react does)
57
+ // Availability will be checked and displayed
58
+ setWallets(supportedWallets);
59
+ }
60
+
61
+ // Check availability for all wallets
62
+ const availability: Record<string, boolean> = {};
63
+ const walletsToCheck = customWallets || sdk.getSupportedWallets();
64
+ for (const wallet of walletsToCheck) {
65
+ try {
66
+ const isAvailable = await sdk.isWalletAvailable(wallet.name);
67
+ availability[wallet.name] = isAvailable;
68
+ } catch (error) {
69
+ availability[wallet.name] = false;
70
+ }
71
+ }
72
+ setWalletAvailability(availability);
73
+ };
74
+
75
+ if (visible) {
76
+ loadWallets();
56
77
  }
57
- }, [sdk, customWallets]);
78
+ }, [sdk, customWallets, visible]);
58
79
 
59
80
  // Handle wallet selection
60
81
  const handleSelectWallet = async (wallet: WalletDefinition) => {
82
+ // Prevent multiple simultaneous connection attempts
83
+ if (connectingWallet) {
84
+ return;
85
+ }
86
+
61
87
  try {
62
88
  setConnectingWallet(wallet.name);
63
89
 
64
90
  // Set preferred wallet
65
- sdk.setPreferredWallet(wallet.name);
91
+ try {
92
+ sdk.setPreferredWallet(wallet.name);
93
+ } catch (error) {
94
+ console.error('[WalletSelectionModal] Failed to set preferred wallet:', error);
95
+ // Continue anyway - SDK will use default wallet
96
+ }
66
97
 
67
98
  // Close modal
68
99
  onClose();
@@ -73,13 +104,9 @@ export function WalletSelectionModal({
73
104
  // Connect
74
105
  await tonConnectUI.connectWallet();
75
106
  } catch (error) {
76
- console.error('Wallet connection error:', error);
107
+ console.error('[WalletSelectionModal] Wallet connection error:', error);
77
108
  setConnectingWallet(null);
78
- // Re-open modal on error
79
- onClose();
80
- setTimeout(() => {
81
- // Modal will be re-opened by parent if needed
82
- }, 500);
109
+ // Error is handled by SDK/UI, just reset connecting state
83
110
  }
84
111
  };
85
112
 
@@ -92,17 +119,23 @@ export function WalletSelectionModal({
92
119
  >
93
120
  <View style={[styles.overlay, style]}>
94
121
  <View style={styles.modalContainer}>
95
- {/* Header */}
122
+ {/* Header - matches @tonconnect/ui-react style */}
96
123
  <View style={styles.header}>
97
- <Text style={styles.title}>Connect your TON wallet</Text>
98
- <Text style={styles.subtitle}>Choose a wallet to connect to this app</Text>
124
+ <TouchableOpacity style={styles.backButton} onPress={onClose}>
125
+ <Text style={styles.backButtonText}>←</Text>
126
+ </TouchableOpacity>
127
+ <Text style={styles.title}>Wallets</Text>
99
128
  <TouchableOpacity style={styles.closeButton} onPress={onClose}>
100
129
  <Text style={styles.closeButtonText}>✕</Text>
101
130
  </TouchableOpacity>
102
131
  </View>
103
132
 
104
- {/* Wallet List */}
105
- <ScrollView style={styles.walletList} showsVerticalScrollIndicator={false}>
133
+ {/* Wallet Grid - matches @tonconnect/ui-react grid layout */}
134
+ <ScrollView
135
+ style={styles.walletList}
136
+ showsVerticalScrollIndicator={false}
137
+ contentContainerStyle={styles.walletGrid}
138
+ >
106
139
  {wallets.length === 0 ? (
107
140
  <View style={styles.emptyState}>
108
141
  <Text style={styles.emptyStateText}>No wallets available</Text>
@@ -113,16 +146,28 @@ export function WalletSelectionModal({
113
146
  ) : (
114
147
  wallets.map((wallet) => {
115
148
  const isConnecting = connectingWallet === wallet.name;
149
+ const isAvailable = walletAvailability[wallet.name] !== false;
116
150
  return (
117
151
  <TouchableOpacity
118
152
  key={wallet.name}
119
- style={[styles.walletItem, isConnecting && styles.walletItemConnecting]}
120
- onPress={() => handleSelectWallet(wallet)}
121
- disabled={isConnecting}
153
+ style={[
154
+ styles.walletCard,
155
+ !isAvailable && styles.walletCardUnavailable,
156
+ isConnecting && styles.walletCardConnecting,
157
+ ]}
158
+ onPress={() => isAvailable && !isConnecting && handleSelectWallet(wallet)}
159
+ disabled={!isAvailable || isConnecting}
122
160
  >
123
161
  <View style={styles.walletIconContainer}>
124
- {wallet.iconUrl ? (
125
- <Image source={{ uri: wallet.iconUrl }} style={styles.walletIcon} />
162
+ {wallet.iconUrl && Platform.OS !== 'web' ? (
163
+ <Image
164
+ source={{ uri: wallet.iconUrl }}
165
+ style={styles.walletIcon}
166
+ onError={() => {
167
+ // Fallback to placeholder on error
168
+ }}
169
+ resizeMode="cover"
170
+ />
126
171
  ) : (
127
172
  <View style={styles.walletIconPlaceholder}>
128
173
  <Text style={styles.walletIconText}>
@@ -131,14 +176,15 @@ export function WalletSelectionModal({
131
176
  </View>
132
177
  )}
133
178
  </View>
134
- <View style={styles.walletInfo}>
135
- <Text style={styles.walletName}>{wallet.name}</Text>
136
- <Text style={styles.walletAppName}>{wallet.appName}</Text>
137
- </View>
179
+ <Text style={styles.walletName} numberOfLines={1}>
180
+ {wallet.name}
181
+ </Text>
138
182
  {isConnecting && (
139
- <View style={styles.connectingIndicator}>
140
- <Text style={styles.connectingText}>Connecting...</Text>
141
- </View>
183
+ <ActivityIndicator
184
+ size="small"
185
+ color="#0088cc"
186
+ style={styles.connectingSpinner}
187
+ />
142
188
  )}
143
189
  </TouchableOpacity>
144
190
  );
@@ -146,11 +192,17 @@ export function WalletSelectionModal({
146
192
  )}
147
193
  </ScrollView>
148
194
 
149
- {/* Footer */}
195
+ {/* Footer - matches @tonconnect/ui-react footer */}
150
196
  <View style={styles.footer}>
151
- <Text style={styles.footerText}>
152
- By connecting, you agree to the app's Terms of Service and Privacy Policy
153
- </Text>
197
+ <View style={styles.footerContent}>
198
+ <View style={styles.tonConnectLogo}>
199
+ <Text style={styles.tonConnectLogoText}>TON</Text>
200
+ </View>
201
+ <Text style={styles.footerText}>TON Connect</Text>
202
+ </View>
203
+ <TouchableOpacity style={styles.helpButton}>
204
+ <Text style={styles.helpButtonText}>?</Text>
205
+ </TouchableOpacity>
154
206
  </View>
155
207
  </View>
156
208
  </View>
@@ -168,30 +220,36 @@ const styles = StyleSheet.create({
168
220
  backgroundColor: '#1a1a1a',
169
221
  borderTopLeftRadius: 24,
170
222
  borderTopRightRadius: 24,
171
- maxHeight: '85%',
223
+ maxHeight: '90%',
172
224
  paddingBottom: Platform.OS === 'ios' ? 34 : 20,
173
225
  },
174
226
  header: {
175
- padding: 24,
227
+ flexDirection: 'row',
228
+ alignItems: 'center',
229
+ justifyContent: 'space-between',
230
+ padding: 16,
176
231
  borderBottomWidth: 1,
177
232
  borderBottomColor: '#2a2a2a',
178
- position: 'relative',
233
+ },
234
+ backButton: {
235
+ width: 32,
236
+ height: 32,
237
+ justifyContent: 'center',
238
+ alignItems: 'center',
239
+ },
240
+ backButtonText: {
241
+ color: '#ffffff',
242
+ fontSize: 20,
243
+ fontWeight: '600',
179
244
  },
180
245
  title: {
181
- fontSize: 28,
246
+ fontSize: 20,
182
247
  fontWeight: 'bold',
183
248
  color: '#ffffff',
184
- marginBottom: 8,
185
- },
186
- subtitle: {
187
- fontSize: 15,
188
- color: '#999999',
189
- lineHeight: 20,
249
+ flex: 1,
250
+ textAlign: 'center',
190
251
  },
191
252
  closeButton: {
192
- position: 'absolute',
193
- top: 24,
194
- right: 24,
195
253
  width: 32,
196
254
  height: 32,
197
255
  borderRadius: 16,
@@ -205,66 +263,65 @@ const styles = StyleSheet.create({
205
263
  fontWeight: '600',
206
264
  },
207
265
  walletList: {
208
- padding: 16,
209
- maxHeight: 400,
266
+ flex: 1,
210
267
  },
211
- walletItem: {
268
+ walletGrid: {
212
269
  flexDirection: 'row',
213
- alignItems: 'center',
270
+ flexWrap: 'wrap',
214
271
  padding: 16,
215
- backgroundColor: '#2a2a2a',
216
- borderRadius: 16,
217
- marginBottom: 12,
218
- minHeight: 72,
272
+ justifyContent: 'flex-start',
273
+ },
274
+ walletCard: {
275
+ width: '25%',
276
+ aspectRatio: 1,
277
+ alignItems: 'center',
278
+ justifyContent: 'center',
279
+ padding: 8,
280
+ marginBottom: 16,
281
+ },
282
+ walletCardUnavailable: {
283
+ opacity: 0.5,
219
284
  },
220
- walletItemConnecting: {
285
+ walletCardConnecting: {
221
286
  opacity: 0.7,
222
287
  },
223
288
  walletIconContainer: {
224
- marginRight: 16,
289
+ width: 64,
290
+ height: 64,
291
+ marginBottom: 8,
225
292
  },
226
293
  walletIcon: {
227
- width: 48,
228
- height: 48,
229
- borderRadius: 12,
294
+ width: 64,
295
+ height: 64,
296
+ borderRadius: 16,
230
297
  },
231
298
  walletIconPlaceholder: {
232
- width: 48,
233
- height: 48,
234
- borderRadius: 12,
235
- backgroundColor: '#3a3a3a',
299
+ width: 64,
300
+ height: 64,
301
+ borderRadius: 16,
302
+ backgroundColor: '#2a2a2a',
236
303
  justifyContent: 'center',
237
304
  alignItems: 'center',
238
305
  },
239
306
  walletIconText: {
240
307
  color: '#ffffff',
241
- fontSize: 20,
308
+ fontSize: 24,
242
309
  fontWeight: 'bold',
243
310
  },
244
- walletInfo: {
245
- flex: 1,
246
- },
247
311
  walletName: {
248
- fontSize: 17,
249
- fontWeight: '600',
312
+ fontSize: 12,
313
+ fontWeight: '500',
250
314
  color: '#ffffff',
251
- marginBottom: 4,
252
- },
253
- walletAppName: {
254
- fontSize: 14,
255
- color: '#999999',
256
- },
257
- connectingIndicator: {
258
- marginLeft: 12,
315
+ textAlign: 'center',
316
+ maxWidth: '100%',
259
317
  },
260
- connectingText: {
261
- fontSize: 14,
262
- color: '#0088cc',
263
- fontWeight: '500',
318
+ connectingSpinner: {
319
+ marginTop: 4,
264
320
  },
265
321
  emptyState: {
266
322
  padding: 40,
267
323
  alignItems: 'center',
324
+ width: '100%',
268
325
  },
269
326
  emptyStateText: {
270
327
  fontSize: 18,
@@ -278,15 +335,48 @@ const styles = StyleSheet.create({
278
335
  textAlign: 'center',
279
336
  },
280
337
  footer: {
338
+ flexDirection: 'row',
339
+ alignItems: 'center',
340
+ justifyContent: 'space-between',
281
341
  padding: 16,
282
342
  borderTopWidth: 1,
283
343
  borderTopColor: '#2a2a2a',
284
344
  },
345
+ footerContent: {
346
+ flexDirection: 'row',
347
+ alignItems: 'center',
348
+ },
349
+ tonConnectLogo: {
350
+ width: 20,
351
+ height: 20,
352
+ borderRadius: 4,
353
+ backgroundColor: '#0088cc',
354
+ justifyContent: 'center',
355
+ alignItems: 'center',
356
+ marginRight: 8,
357
+ },
358
+ tonConnectLogoText: {
359
+ color: '#ffffff',
360
+ fontSize: 10,
361
+ fontWeight: 'bold',
362
+ },
285
363
  footerText: {
286
364
  fontSize: 12,
287
- color: '#666666',
288
- textAlign: 'center',
289
- lineHeight: 16,
365
+ color: '#ffffff',
366
+ fontWeight: '500',
367
+ },
368
+ helpButton: {
369
+ width: 24,
370
+ height: 24,
371
+ borderRadius: 12,
372
+ backgroundColor: '#2a2a2a',
373
+ justifyContent: 'center',
374
+ alignItems: 'center',
375
+ },
376
+ helpButtonText: {
377
+ color: '#999999',
378
+ fontSize: 14,
379
+ fontWeight: '600',
290
380
  },
291
381
  });
292
382
 
@@ -19,6 +19,7 @@ export type {
19
19
  SignDataRequest,
20
20
  SignDataResponse,
21
21
  } from './TonConnectUIProvider';
22
+ export type { Network, BalanceResponse, TransactionStatusResponse, TransactionStatus } from '../types';
22
23
  export { TonConnectButton } from './TonConnectButton';
23
24
  export type { TonConnectButtonProps } from './TonConnectButton';
24
25
  export { WalletSelectionModal } from './WalletSelectionModal';