@blazium/ton-connect-mobile 1.2.4 → 1.2.6

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.
@@ -1,441 +1,272 @@
1
- /**
2
- * React integration layer for @tonconnect/ui-react compatibility
3
- * Provides TonConnectUIProvider, hooks, and components compatible with @tonconnect/ui-react API
4
- */
5
-
6
- import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
7
- import { TonConnectMobile, ConnectionStatus, WalletInfo, SendTransactionRequest, WalletDefinition, Network, BalanceResponse, TransactionStatusResponse } from '../index';
8
- import type { TonConnectMobileConfig, TonConnectEventType, TonConnectEventListener } from '../types';
9
- import { WalletSelectionModal } from './WalletSelectionModal';
10
-
11
- /**
12
- * Account information (compatible with @tonconnect/ui-react)
13
- */
14
- export interface Account {
15
- address: string;
16
- chain: number;
17
- publicKey?: string;
18
- }
19
-
20
- /**
21
- * Wallet state (compatible with @tonconnect/ui-react)
22
- */
23
- export interface WalletState {
24
- account: Account | null;
25
- wallet: WalletInfo | null;
26
- connected: boolean;
27
- }
28
-
29
- /**
30
- * Transaction response (compatible with @tonconnect/ui-react)
31
- */
32
- export interface TransactionResponse {
33
- boc: string;
34
- signature: string;
35
- }
36
-
37
- /**
38
- * Sign data request
39
- */
40
- export interface SignDataRequest {
41
- /** Data to sign (will be base64 encoded) */
42
- data: string | Uint8Array;
43
- /** Optional version */
44
- version?: string;
45
- }
46
-
47
- /**
48
- * Sign data response
49
- */
50
- export interface SignDataResponse {
51
- signature: string;
52
- timestamp: number;
53
- }
54
-
55
- /**
56
- * TonConnect UI instance interface (compatible with @tonconnect/ui-react)
57
- * Includes all features from @tonconnect/ui-react for full compatibility
58
- */
59
- export interface TonConnectUI {
60
- /** Open connection modal */
61
- openModal: () => Promise<void>;
62
- /** Close connection modal */
63
- closeModal: () => void;
64
- /** Connect to wallet */
65
- connectWallet: () => Promise<void>;
66
- /** Disconnect from wallet */
67
- disconnect: () => Promise<void>;
68
- /** Send transaction */
69
- sendTransaction: (transaction: SendTransactionRequest) => Promise<TransactionResponse>;
70
- /** Sign data */
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;
90
- /** Current wallet state */
91
- wallet: WalletState | null;
92
- /** Modal open state */
93
- modalState: {
94
- open: boolean;
95
- };
96
- /** UI kit version */
97
- uiVersion: string;
98
- }
99
-
100
- /**
101
- * Context value
102
- */
103
- interface TonConnectUIContextValue {
104
- tonConnectUI: TonConnectUI;
105
- sdk: TonConnectMobile;
106
- }
107
-
108
- const TonConnectUIContext = createContext<TonConnectUIContextValue | null>(null);
109
-
110
- /**
111
- * TonConnectUIProvider props
112
- */
113
- export interface TonConnectUIProviderProps {
114
- /** SDK configuration */
115
- config: TonConnectMobileConfig;
116
- /** Children */
117
- children: ReactNode;
118
- /** Optional SDK instance (for testing or custom instances) */
119
- sdkInstance?: TonConnectMobile;
120
- }
121
-
122
- /**
123
- * TonConnectUIProvider - React context provider for TON Connect
124
- * Compatible with @tonconnect/ui-react API
125
- */
126
- export function TonConnectUIProvider({
127
- config,
128
- children,
129
- sdkInstance,
130
- }: TonConnectUIProviderProps): JSX.Element {
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
- });
143
- const [walletState, setWalletState] = useState<WalletState | null>(null);
144
- const [modalOpen, setModalOpen] = useState(false);
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
- }, []);
154
-
155
- // Update wallet state from SDK status
156
- const updateWalletState = useCallback((status: ConnectionStatus) => {
157
- if (status.connected && status.wallet) {
158
- const network = sdk.getNetwork();
159
- setWalletState({
160
- account: {
161
- address: status.wallet.address,
162
- chain: getChainId(network),
163
- publicKey: status.wallet.publicKey,
164
- },
165
- wallet: status.wallet,
166
- connected: true,
167
- });
168
- } else {
169
- setWalletState({
170
- account: null,
171
- wallet: null,
172
- connected: false,
173
- });
174
- }
175
- }, [sdk, getChainId]);
176
-
177
- // Subscribe to SDK status changes
178
- useEffect(() => {
179
- // Set initial state
180
- const initialStatus = sdk.getStatus();
181
- updateWalletState(initialStatus);
182
-
183
- // Subscribe to changes
184
- const unsubscribe = sdk.onStatusChange((status) => {
185
- updateWalletState(status);
186
- // Close modal when connected
187
- if (status.connected) {
188
- setModalOpen(false);
189
- setIsConnecting(false);
190
- }
191
- });
192
-
193
- return () => {
194
- unsubscribe();
195
- // CRITICAL FIX: Cleanup SDK on unmount to prevent memory leaks
196
- // Note: SDK has its own cleanup via destroy(), but we don't call it here
197
- // to allow SDK to persist across component remounts (e.g., navigation)
198
- };
199
- }, [sdk, updateWalletState]);
200
-
201
- // Open modal
202
- const openModal = useCallback(async () => {
203
- if (!walletState?.connected) {
204
- setModalOpen(true);
205
- }
206
- }, [walletState?.connected]);
207
-
208
- // Close modal
209
- const closeModal = useCallback(() => {
210
- setModalOpen(false);
211
- setIsConnecting(false);
212
- }, []);
213
-
214
- // Connect wallet
215
- const connectWallet = useCallback(async () => {
216
- // CRITICAL FIX: Use functional update to avoid race condition
217
- setIsConnecting((prev) => {
218
- if (prev) {
219
- // Already connecting, return early
220
- return prev;
221
- }
222
- return true;
223
- });
224
-
225
- // Wait for connection
226
- try {
227
- await sdk.connect();
228
- // Status update will be handled by the subscription
229
- } catch (error) {
230
- setIsConnecting(false);
231
- throw error;
232
- }
233
- }, [sdk]);
234
-
235
- // Disconnect
236
- const disconnect = useCallback(async () => {
237
- await sdk.disconnect();
238
- setModalOpen(false);
239
- }, [sdk]);
240
-
241
- // Send transaction
242
- const sendTransaction = useCallback(
243
- async (transaction: SendTransactionRequest): Promise<TransactionResponse> => {
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
- }
262
- },
263
- [sdk]
264
- );
265
-
266
- // Sign data
267
- const signData = useCallback(
268
- async (request: SignDataRequest): Promise<SignDataResponse> => {
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
- }
284
- },
285
- [sdk]
286
- );
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
-
355
- // Create TonConnectUI instance
356
- const tonConnectUI: TonConnectUI = {
357
- openModal,
358
- closeModal,
359
- connectWallet,
360
- disconnect,
361
- sendTransaction,
362
- signData,
363
- restoreConnection,
364
- setWalletList,
365
- getNetwork,
366
- setNetwork,
367
- getBalance,
368
- getTransactionStatus,
369
- getTransactionStatusByHash,
370
- on,
371
- off,
372
- wallet: walletState,
373
- modalState: {
374
- open: modalOpen,
375
- },
376
- uiVersion: '1.0.0',
377
- };
378
-
379
- const contextValue: TonConnectUIContextValue = {
380
- tonConnectUI,
381
- sdk,
382
- };
383
-
384
- return (
385
- <TonConnectUIContext.Provider value={contextValue}>
386
- {children}
387
- {/* Auto-show wallet selection modal when modalOpen is true */}
388
- <WalletSelectionModal
389
- visible={modalOpen && !walletState?.connected}
390
- onClose={closeModal}
391
- wallets={customWalletList || undefined}
392
- />
393
- </TonConnectUIContext.Provider>
394
- );
395
- }
396
-
397
- /**
398
- * Hook to access TonConnectUI instance
399
- * Compatible with @tonconnect/ui-react useTonConnectUI hook
400
- */
401
- export function useTonConnectUI(): TonConnectUI {
402
- const context = useContext(TonConnectUIContext);
403
- if (!context) {
404
- throw new Error('useTonConnectUI must be used within TonConnectUIProvider');
405
- }
406
- return context.tonConnectUI;
407
- }
408
-
409
- /**
410
- * Hook to access wallet state
411
- * Compatible with @tonconnect/ui-react useTonWallet hook
412
- */
413
- export function useTonWallet(): WalletState | null {
414
- const tonConnectUI = useTonConnectUI();
415
- return tonConnectUI.wallet;
416
- }
417
-
418
- /**
419
- * Hook to access modal state
420
- * Compatible with @tonconnect/ui-react useTonConnectModal hook
421
- */
422
- export function useTonConnectModal(): { open: boolean; close: () => void; openModal: () => Promise<void> } {
423
- const tonConnectUI = useTonConnectUI();
424
- return {
425
- open: tonConnectUI.modalState.open,
426
- close: tonConnectUI.closeModal,
427
- openModal: tonConnectUI.openModal,
428
- };
429
- }
430
-
431
- /**
432
- * Hook to access SDK instance (for advanced usage)
433
- */
434
- export function useTonConnectSDK(): TonConnectMobile {
435
- const context = useContext(TonConnectUIContext);
436
- if (!context) {
437
- throw new Error('useTonConnectSDK must be used within TonConnectUIProvider');
438
- }
439
- return context.sdk;
440
- }
441
-
1
+ /**
2
+ * React integration layer for TON Connect Mobile SDK
3
+ * Provides TonConnectUIProvider, hooks, and components compatible with @tonconnect/ui-react API
4
+ */
5
+
6
+ import React, { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
7
+ import { TonConnectMobile, ConnectionStatus, WalletInfo, SendTransactionRequest, WalletDefinition, Network, BalanceResponse, TransactionStatusResponse } from '../index';
8
+ import type { TonConnectMobileConfig, TonConnectEventType, TonConnectEventListener } from '../types';
9
+ import { WalletSelectionModal } from './WalletSelectionModal';
10
+
11
+ /**
12
+ * Account information (compatible with @tonconnect/ui-react)
13
+ */
14
+ export interface Account {
15
+ address: string;
16
+ chain: number;
17
+ publicKey?: string;
18
+ }
19
+
20
+ /**
21
+ * Wallet state (compatible with @tonconnect/ui-react)
22
+ */
23
+ export interface WalletState {
24
+ account: Account | null;
25
+ wallet: WalletInfo | null;
26
+ connected: boolean;
27
+ }
28
+
29
+ /**
30
+ * Transaction response
31
+ */
32
+ export interface TransactionResponse {
33
+ boc: string;
34
+ }
35
+
36
+ /**
37
+ * TonConnect UI instance interface
38
+ */
39
+ export interface TonConnectUI {
40
+ openModal: () => Promise<void>;
41
+ closeModal: () => void;
42
+ connectWallet: () => Promise<void>;
43
+ disconnect: () => Promise<void>;
44
+ sendTransaction: (transaction: SendTransactionRequest) => Promise<TransactionResponse>;
45
+ restoreConnection: () => Promise<void>;
46
+ setWalletList: (wallets: WalletDefinition[]) => void;
47
+ getNetwork: () => Network;
48
+ setNetwork: (network: Network) => void;
49
+ getBalance: (address?: string) => Promise<BalanceResponse>;
50
+ getTransactionStatusByHash: (txHash: string, address: string) => Promise<TransactionStatusResponse>;
51
+ on: <T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>) => () => void;
52
+ off: <T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>) => void;
53
+ wallet: WalletState | null;
54
+ modalState: { open: boolean };
55
+ uiVersion: string;
56
+ }
57
+
58
+ interface TonConnectUIContextValue {
59
+ tonConnectUI: TonConnectUI;
60
+ sdk: TonConnectMobile;
61
+ }
62
+
63
+ const TonConnectUIContext = createContext<TonConnectUIContextValue | null>(null);
64
+
65
+ export interface TonConnectUIProviderProps {
66
+ config: TonConnectMobileConfig;
67
+ children: ReactNode;
68
+ sdkInstance?: TonConnectMobile;
69
+ }
70
+
71
+ /**
72
+ * TonConnectUIProvider - React context provider for TON Connect
73
+ */
74
+ export function TonConnectUIProvider({
75
+ config,
76
+ children,
77
+ sdkInstance,
78
+ }: TonConnectUIProviderProps): JSX.Element {
79
+ const [sdk] = useState<TonConnectMobile>(() => {
80
+ if (sdkInstance) return sdkInstance;
81
+ return new TonConnectMobile(config);
82
+ });
83
+ const [walletState, setWalletState] = useState<WalletState | null>(null);
84
+ const [modalOpen, setModalOpen] = useState(false);
85
+ const [isConnecting, setIsConnecting] = useState(false);
86
+ const [customWalletList, setCustomWalletList] = useState<WalletDefinition[] | null>(null);
87
+
88
+ const getChainId = useCallback((network: Network): number => {
89
+ return network === 'testnet' ? -3 : -239;
90
+ }, []);
91
+
92
+ const updateWalletState = useCallback((status: ConnectionStatus) => {
93
+ if (status.connected && status.wallet) {
94
+ const network = sdk.getNetwork();
95
+ setWalletState({
96
+ account: {
97
+ address: status.wallet.address,
98
+ chain: getChainId(network),
99
+ publicKey: status.wallet.publicKey,
100
+ },
101
+ wallet: status.wallet,
102
+ connected: true,
103
+ });
104
+ } else {
105
+ setWalletState({
106
+ account: null,
107
+ wallet: null,
108
+ connected: false,
109
+ });
110
+ }
111
+ }, [sdk, getChainId]);
112
+
113
+ useEffect(() => {
114
+ const initialStatus = sdk.getStatus();
115
+ updateWalletState(initialStatus);
116
+
117
+ const unsubscribe = sdk.onStatusChange((status) => {
118
+ updateWalletState(status);
119
+ if (status.connected) {
120
+ setModalOpen(false);
121
+ setIsConnecting(false);
122
+ }
123
+ });
124
+
125
+ return () => { unsubscribe(); };
126
+ }, [sdk, updateWalletState]);
127
+
128
+ const openModal = useCallback(async () => {
129
+ if (!walletState?.connected) {
130
+ setModalOpen(true);
131
+ }
132
+ }, [walletState?.connected]);
133
+
134
+ const closeModal = useCallback(() => {
135
+ setModalOpen(false);
136
+ setIsConnecting(false);
137
+ }, []);
138
+
139
+ const connectWallet = useCallback(async () => {
140
+ if (isConnecting) return;
141
+ setIsConnecting(true);
142
+ try {
143
+ await sdk.connect();
144
+ } catch (error) {
145
+ setIsConnecting(false);
146
+ throw error;
147
+ }
148
+ }, [sdk, isConnecting]);
149
+
150
+ const disconnect = useCallback(async () => {
151
+ await sdk.disconnect();
152
+ setModalOpen(false);
153
+ }, [sdk]);
154
+
155
+ const sendTransaction = useCallback(
156
+ async (transaction: SendTransactionRequest): Promise<TransactionResponse> => {
157
+ const response = await sdk.sendTransaction(transaction);
158
+ return { boc: response.boc };
159
+ },
160
+ [sdk]
161
+ );
162
+
163
+ const restoreConnection = useCallback(async (): Promise<void> => {
164
+ const status = sdk.getStatus();
165
+ if (status.connected && status.wallet) {
166
+ updateWalletState(status);
167
+ }
168
+ }, [sdk, updateWalletState]);
169
+
170
+ const setWalletList = useCallback((wallets: WalletDefinition[]): void => {
171
+ setCustomWalletList(wallets);
172
+ }, []);
173
+
174
+ const getNetwork = useCallback((): Network => sdk.getNetwork(), [sdk]);
175
+ const setNetwork = useCallback((network: Network): void => {
176
+ sdk.setNetwork(network);
177
+ const status = sdk.getStatus();
178
+ updateWalletState(status);
179
+ }, [sdk, updateWalletState]);
180
+
181
+ const getBalance = useCallback(async (address?: string): Promise<BalanceResponse> => {
182
+ return await sdk.getBalance(address);
183
+ }, [sdk]);
184
+
185
+ const getTransactionStatusByHash = useCallback(async (
186
+ txHash: string, address: string
187
+ ): Promise<TransactionStatusResponse> => {
188
+ return await sdk.getTransactionStatusByHash(txHash, address);
189
+ }, [sdk]);
190
+
191
+ const on = useCallback(<T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>): (() => void) => {
192
+ return sdk.on(event, listener);
193
+ }, [sdk]);
194
+
195
+ const off = useCallback(<T = any>(event: TonConnectEventType, listener: TonConnectEventListener<T>): void => {
196
+ sdk.off(event, listener);
197
+ }, [sdk]);
198
+
199
+ const tonConnectUI: TonConnectUI = {
200
+ openModal,
201
+ closeModal,
202
+ connectWallet,
203
+ disconnect,
204
+ sendTransaction,
205
+ restoreConnection,
206
+ setWalletList,
207
+ getNetwork,
208
+ setNetwork,
209
+ getBalance,
210
+ getTransactionStatusByHash,
211
+ on,
212
+ off,
213
+ wallet: walletState,
214
+ modalState: { open: modalOpen },
215
+ uiVersion: '2.0.0',
216
+ };
217
+
218
+ const contextValue: TonConnectUIContextValue = { tonConnectUI, sdk };
219
+
220
+ return (
221
+ <TonConnectUIContext.Provider value={contextValue}>
222
+ {children}
223
+ <WalletSelectionModal
224
+ visible={modalOpen && !walletState?.connected}
225
+ onClose={closeModal}
226
+ wallets={customWalletList || undefined}
227
+ />
228
+ </TonConnectUIContext.Provider>
229
+ );
230
+ }
231
+
232
+ /**
233
+ * Hook to access TonConnectUI instance
234
+ */
235
+ export function useTonConnectUI(): TonConnectUI {
236
+ const context = useContext(TonConnectUIContext);
237
+ if (!context) {
238
+ throw new Error('useTonConnectUI must be used within TonConnectUIProvider');
239
+ }
240
+ return context.tonConnectUI;
241
+ }
242
+
243
+ /**
244
+ * Hook to access wallet state
245
+ */
246
+ export function useTonWallet(): WalletState | null {
247
+ const tonConnectUI = useTonConnectUI();
248
+ return tonConnectUI.wallet;
249
+ }
250
+
251
+ /**
252
+ * Hook to access modal state
253
+ */
254
+ export function useTonConnectModal(): { open: boolean; close: () => void; openModal: () => Promise<void> } {
255
+ const tonConnectUI = useTonConnectUI();
256
+ return {
257
+ open: tonConnectUI.modalState.open,
258
+ close: tonConnectUI.closeModal,
259
+ openModal: tonConnectUI.openModal,
260
+ };
261
+ }
262
+
263
+ /**
264
+ * Hook to access SDK instance
265
+ */
266
+ export function useTonConnectSDK(): TonConnectMobile {
267
+ const context = useContext(TonConnectUIContext);
268
+ if (!context) {
269
+ throw new Error('useTonConnectSDK must be used within TonConnectUIProvider');
270
+ }
271
+ return context.sdk;
272
+ }