@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.
- package/README.md +316 -18
- package/dist/adapters/expo.js +3 -3
- package/dist/adapters/react-native.js +3 -3
- package/dist/core/protocol.d.ts +1 -0
- package/dist/core/protocol.js +69 -9
- package/dist/core/wallets.js +5 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +309 -13
- package/dist/react/TonConnectUIProvider.d.ts +21 -2
- package/dist/react/TonConnectUIProvider.js +118 -14
- package/dist/react/WalletSelectionModal.d.ts +1 -0
- package/dist/react/WalletSelectionModal.js +153 -80
- package/dist/react/index.d.ts +1 -0
- package/dist/types/index.d.ts +46 -0
- package/dist/utils/transactionBuilder.js +50 -7
- package/package.json +1 -1
- package/src/adapters/expo.ts +3 -3
- package/src/adapters/react-native.ts +3 -3
- package/src/core/protocol.ts +76 -9
- package/src/core/wallets.ts +5 -1
- package/src/index.ts +381 -15
- package/src/react/TonConnectUIProvider.tsx +154 -15
- package/src/react/WalletSelectionModal.tsx +180 -90
- package/src/react/index.ts +1 -0
- package/src/types/index.ts +52 -0
- package/src/utils/transactionBuilder.ts +56 -7
|
@@ -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
|
-
|
|
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:
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
<
|
|
98
|
-
|
|
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
|
|
105
|
-
<ScrollView
|
|
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={[
|
|
120
|
-
|
|
121
|
-
|
|
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
|
|
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
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</View>
|
|
179
|
+
<Text style={styles.walletName} numberOfLines={1}>
|
|
180
|
+
{wallet.name}
|
|
181
|
+
</Text>
|
|
138
182
|
{isConnecting && (
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
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: '
|
|
223
|
+
maxHeight: '90%',
|
|
172
224
|
paddingBottom: Platform.OS === 'ios' ? 34 : 20,
|
|
173
225
|
},
|
|
174
226
|
header: {
|
|
175
|
-
|
|
227
|
+
flexDirection: 'row',
|
|
228
|
+
alignItems: 'center',
|
|
229
|
+
justifyContent: 'space-between',
|
|
230
|
+
padding: 16,
|
|
176
231
|
borderBottomWidth: 1,
|
|
177
232
|
borderBottomColor: '#2a2a2a',
|
|
178
|
-
|
|
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:
|
|
246
|
+
fontSize: 20,
|
|
182
247
|
fontWeight: 'bold',
|
|
183
248
|
color: '#ffffff',
|
|
184
|
-
|
|
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
|
-
|
|
209
|
-
maxHeight: 400,
|
|
266
|
+
flex: 1,
|
|
210
267
|
},
|
|
211
|
-
|
|
268
|
+
walletGrid: {
|
|
212
269
|
flexDirection: 'row',
|
|
213
|
-
|
|
270
|
+
flexWrap: 'wrap',
|
|
214
271
|
padding: 16,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
285
|
+
walletCardConnecting: {
|
|
221
286
|
opacity: 0.7,
|
|
222
287
|
},
|
|
223
288
|
walletIconContainer: {
|
|
224
|
-
|
|
289
|
+
width: 64,
|
|
290
|
+
height: 64,
|
|
291
|
+
marginBottom: 8,
|
|
225
292
|
},
|
|
226
293
|
walletIcon: {
|
|
227
|
-
width:
|
|
228
|
-
height:
|
|
229
|
-
borderRadius:
|
|
294
|
+
width: 64,
|
|
295
|
+
height: 64,
|
|
296
|
+
borderRadius: 16,
|
|
230
297
|
},
|
|
231
298
|
walletIconPlaceholder: {
|
|
232
|
-
width:
|
|
233
|
-
height:
|
|
234
|
-
borderRadius:
|
|
235
|
-
backgroundColor: '#
|
|
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:
|
|
308
|
+
fontSize: 24,
|
|
242
309
|
fontWeight: 'bold',
|
|
243
310
|
},
|
|
244
|
-
walletInfo: {
|
|
245
|
-
flex: 1,
|
|
246
|
-
},
|
|
247
311
|
walletName: {
|
|
248
|
-
fontSize:
|
|
249
|
-
fontWeight: '
|
|
312
|
+
fontSize: 12,
|
|
313
|
+
fontWeight: '500',
|
|
250
314
|
color: '#ffffff',
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
walletAppName: {
|
|
254
|
-
fontSize: 14,
|
|
255
|
-
color: '#999999',
|
|
256
|
-
},
|
|
257
|
-
connectingIndicator: {
|
|
258
|
-
marginLeft: 12,
|
|
315
|
+
textAlign: 'center',
|
|
316
|
+
maxWidth: '100%',
|
|
259
317
|
},
|
|
260
|
-
|
|
261
|
-
|
|
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: '#
|
|
288
|
-
|
|
289
|
-
|
|
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
|
|
package/src/react/index.ts
CHANGED
|
@@ -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';
|