From 55ef7cb56bde744a96274809ca2aaf1f6eadbe4c Mon Sep 17 00:00:00 2001 From: "V. K." Date: Tue, 9 Dec 2025 17:07:47 +0400 Subject: [PATCH 1/6] test: add maestro test - import wallet --- .../.maestro/import-wallet.yaml | 53 +++++++++++++++++++ apps/demo-wallet-native/app.json | 4 +- .../src/app/(auth)/(tabs)/wallet.tsx | 4 +- .../src/app/(auth)/connect-dapp.tsx | 1 + .../src/app/(non-auth)/add-new-wallet.tsx | 4 +- .../src/app/(non-auth)/import-mnemonic.tsx | 2 + .../src/app/(non-auth)/new-password.tsx | 9 +++- .../active-touch-action.tsx | 3 ++ .../core/components/app-button/container.tsx | 3 ++ .../components/tab-control/tab-control.tsx | 1 + .../action-buttons/action-buttons.tsx | 6 +++ .../connect-request-modal.tsx | 2 + .../sign-data-request-modal.tsx | 2 + .../ton-connect-link-input.tsx | 3 +- .../transaction-request-modal.tsx | 2 + 15 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 apps/demo-wallet-native/.maestro/import-wallet.yaml diff --git a/apps/demo-wallet-native/.maestro/import-wallet.yaml b/apps/demo-wallet-native/.maestro/import-wallet.yaml new file mode 100644 index 000000000..c857d1d82 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/import-wallet.yaml @@ -0,0 +1,53 @@ +appId: org.ton.wallet +env: + MNEMONIC: ${MNEMONIC || "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"} + PASSWORD: 1111 + DAPP_URL: https://allure-test-runner.vercel.app/e2e +--- +- launchApp: + clearState: true + +# Start screen +- assertVisible: + id: start-import-button +- assertVisible: + id: start-create-button + +# Tap Import Wallet +- tapOn: + id: start-import-button + +# Password screen +- assertVisible: + id: password-input +- tapOn: + id: password-input +- inputText: ${PASSWORD} +- tapOn: + id: confirm-password-input +- inputText: ${PASSWORD} +- hideKeyboard +- tapOn: + id: submit-new-password + +# Import Mnemonic screen +- assertVisible: Import Wallet +- assertVisible: Enter Recovery Phrase + +# Enter mnemonic +- tapOn: + id: mnemonic-input +- inputText: ${MNEMONIC} +- hideKeyboard + +# Select network +- tapOn: + id: tab-control-mainnet + +# Import +- tapOn: + id: import-wallet-button + +# Should navigate to wallet screen +- assertVisible: + id: ton-balance-card diff --git a/apps/demo-wallet-native/app.json b/apps/demo-wallet-native/app.json index e3d83133a..976d538e5 100644 --- a/apps/demo-wallet-native/app.json +++ b/apps/demo-wallet-native/app.json @@ -15,7 +15,7 @@ }, "ios": { "supportsTablet": true, - "bundleIdentifier": "com.heyllog.tonwallet" + "bundleIdentifier": "org.ton.wallet" }, "android": { "adaptiveIcon": { @@ -24,7 +24,7 @@ }, "edgeToEdgeEnabled": true, "predictiveBackGestureEnabled": false, - "package": "com.heyllog.tonwallet" + "package": "org.ton.wallet" }, "web": { "favicon": "./assets/favicon.png" diff --git a/apps/demo-wallet-native/src/app/(auth)/(tabs)/wallet.tsx b/apps/demo-wallet-native/src/app/(auth)/(tabs)/wallet.tsx index 0b2e1a8e2..4c9f80ddd 100644 --- a/apps/demo-wallet-native/src/app/(auth)/(tabs)/wallet.tsx +++ b/apps/demo-wallet-native/src/app/(auth)/(tabs)/wallet.tsx @@ -97,7 +97,7 @@ const WalletHomeScreen: FC = () => { - router.push('/connect-dapp')}> + router.push('/connect-dapp')} testID="scan-button"> @@ -121,7 +121,7 @@ const WalletHomeScreen: FC = () => { savedWallets={savedWallets} /> - + diff --git a/apps/demo-wallet-native/src/app/(auth)/connect-dapp.tsx b/apps/demo-wallet-native/src/app/(auth)/connect-dapp.tsx index 1ab96da24..930f7472d 100644 --- a/apps/demo-wallet-native/src/app/(auth)/connect-dapp.tsx +++ b/apps/demo-wallet-native/src/app/(auth)/connect-dapp.tsx @@ -74,6 +74,7 @@ const ConnectDAppScreen: FC = () => { handleConnect(tonConnectUrl)} disabled={!tonConnectUrl.trim() || isConnecting} style={styles.connectButton} diff --git a/apps/demo-wallet-native/src/app/(non-auth)/add-new-wallet.tsx b/apps/demo-wallet-native/src/app/(non-auth)/add-new-wallet.tsx index d92f13a2a..a1de59e0c 100644 --- a/apps/demo-wallet-native/src/app/(non-auth)/add-new-wallet.tsx +++ b/apps/demo-wallet-native/src/app/(non-auth)/add-new-wallet.tsx @@ -58,11 +58,11 @@ const StartScreen: FC = () => { - + Create New Wallet - + Import Wallet diff --git a/apps/demo-wallet-native/src/app/(non-auth)/import-mnemonic.tsx b/apps/demo-wallet-native/src/app/(non-auth)/import-mnemonic.tsx index 614fcebf7..1c295ffe0 100644 --- a/apps/demo-wallet-native/src/app/(non-auth)/import-mnemonic.tsx +++ b/apps/demo-wallet-native/src/app/(non-auth)/import-mnemonic.tsx @@ -78,6 +78,7 @@ const ImportMnemonicScreen: FC = () => { { { { /> { - + Continue diff --git a/apps/demo-wallet-native/src/core/components/active-touch-action/active-touch-action.tsx b/apps/demo-wallet-native/src/core/components/active-touch-action/active-touch-action.tsx index b0e3d645f..c53258c64 100644 --- a/apps/demo-wallet-native/src/core/components/active-touch-action/active-touch-action.tsx +++ b/apps/demo-wallet-native/src/core/components/active-touch-action/active-touch-action.tsx @@ -17,6 +17,7 @@ export interface ActiveTouchActionProps extends PropsWithChildren { disabled?: boolean; scaling?: number; hitSlop?: number; + testID?: string; } export const ActiveTouchAction: FC = ({ @@ -27,6 +28,7 @@ export const ActiveTouchAction: FC = ({ scaling = 0.96, children, hitSlop, + testID, }) => { const pressed = useSharedValue(false); @@ -48,6 +50,7 @@ export const ActiveTouchAction: FC = ({ return ( Promise | void; disabled?: boolean; + testID?: string; } export const ButtonContainer: FC = ({ @@ -30,6 +31,7 @@ export const ButtonContainer: FC = colorScheme = 'primary', variant = 'standard', disabled = false, + testID, }) => { styles.useVariants({ variant, colorScheme }); @@ -49,6 +51,7 @@ export const ButtonContainer: FC = return ( ({ {options.map((option) => ( onOptionPress?.(option.value)} diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/action-buttons/action-buttons.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/action-buttons/action-buttons.tsx index f200d8dc8..ae6481d63 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/action-buttons/action-buttons.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/action-buttons/action-buttons.tsx @@ -19,6 +19,8 @@ interface ActionButtonsProps { onSecondaryPress: () => void; isLoading?: boolean; isPrimaryDisabled?: boolean; + primaryTestID?: string; + secondaryTestID?: string; } export const ActionButtons: FC = ({ @@ -28,10 +30,13 @@ export const ActionButtons: FC = ({ onSecondaryPress, isLoading = false, isPrimaryDisabled = false, + primaryTestID, + secondaryTestID, }) => { return ( = ({ = ({ request, isO onSecondaryPress={handleReject} isLoading={isLoading} isPrimaryDisabled={!selectedWallet} + primaryTestID="connect-approve" + secondaryTestID="connect-reject" /> diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx index 4fd4710a7..264363c0d 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx @@ -182,6 +182,8 @@ export const SignDataRequestModal: FC = ({ request, i onPrimaryPress={handleApprove} onSecondaryPress={handleReject} isLoading={isLoading} + primaryTestID="sign-data-approve" + secondaryTestID="sign-data-reject" /> diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-link-input/ton-connect-link-input.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-link-input/ton-connect-link-input.tsx index b1759ecd2..273949fc6 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-link-input/ton-connect-link-input.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-link-input/ton-connect-link-input.tsx @@ -52,6 +52,7 @@ export const TonConnectLinkInput: FC = ({ = ({ autoCorrect={false} /> - + diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx index c33752e04..9f7f2461f 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx @@ -137,6 +137,8 @@ export const TransactionRequestModal: FC = ({ requ onPrimaryPress={handleApprove} onSecondaryPress={handleReject} isLoading={isLoading} + primaryTestID="send-transaction-approve" + secondaryTestID="send-transaction-reject" /> From aaa7a869db33aaa2e282c28a040a5b584e0cae39 Mon Sep 17 00:00:00 2001 From: "V. K." Date: Tue, 9 Dec 2025 18:26:21 +0400 Subject: [PATCH 2/6] test: start maestro connect flow --- .../.maestro/connect-test.yaml | 62 +++++++++++++++++++ .../.maestro/flows/unlock-wallet.yaml | 24 +++++++ .../src/app/(non-auth)/unlock-wallet.tsx | 5 +- 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 apps/demo-wallet-native/.maestro/connect-test.yaml create mode 100644 apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml diff --git a/apps/demo-wallet-native/.maestro/connect-test.yaml b/apps/demo-wallet-native/.maestro/connect-test.yaml new file mode 100644 index 000000000..1bc6e6119 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/connect-test.yaml @@ -0,0 +1,62 @@ +appId: org.ton.wallet +env: + PASSWORD: 1111 + DAPP_URL: https://allure-test-runner.vercel.app/e2e +--- +- launchApp + +- runFlow: + file: flows/unlock-wallet.yaml + env: + PASSWORD: ${PASSWORD} + +- openLink: + link: ${DAPP_URL} + browser: true + +- assertVisible: + text: "Connect Wallet" + enabled: true + +- tapOn: "Connect Wallet" + +# Подождать появления модального окна с QR/URL +- assertVisible: + text: "Copy Link" + +# === ШАГ 3: Скопировать tonconnect URL === +- tapOn: "Copy Link" + +# === ШАГ 4: Вернуться в кошелёк === +- launchApp: + appId: org.ton.wallet + stopApp: false + +# === ШАГ 5: Открыть экран Connect dApp === +- tapOn: + id: scan-button + +# Подождать экран Connect to dApp +- assertVisible: + id: tonconnect-url + +# === ШАГ 6: Вставить URL из буфера обмена === +- tapOn: + id: paste-button + +# === ШАГ 7: Нажать Connect === +- tapOn: + id: tonconnect-process + +# === ШАГ 8: Подтвердить подключение === +- assertVisible: + id: connect-approve +- tapOn: + id: connect-approve + +# === ШАГ 9: Проверить успешное подключение === +# Вернуться в браузер и проверить что кнопка изменилась +- openLink: + link: ${DAPP_URL} + browser: true +- assertNotVisible: "Connect Wallet" diff --git a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml new file mode 100644 index 000000000..fc42b61f1 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml @@ -0,0 +1,24 @@ +# Unlock Wallet Flow +# Переиспользуемый flow для разблокировки кошелька +# +# Использование в других тестах: +# - runFlow: +# file: flows/unlock-wallet.yaml +# env: +# PASSWORD: ${PASSWORD} + +appId: org.ton.wallet +--- +# Ввести пароль +- tapOn: + id: unlock-password-input +- inputText: ${PASSWORD} +- hideKeyboard + +# Нажать Continue +- tapOn: + id: unlock-submit-button + +# Дождаться главного экрана +- assertVisible: + id: ton-balance-card diff --git a/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx b/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx index dc806181e..697e5b6b6 100644 --- a/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx +++ b/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx @@ -92,6 +92,7 @@ const UnlockWalletScreen: FC = () => { Enter your password to unlock your wallet. { - + Continue - + Reset Wallet From 56f829d68b3f031114ae68351a94256b22fdafcf Mon Sep 17 00:00:00 2001 From: "V. K." Date: Wed, 10 Dec 2025 10:24:15 +0400 Subject: [PATCH 3/6] test: delete comments on russian --- apps/demo-wallet-native/.maestro/connect-test.yaml | 10 ---------- .../.maestro/flows/unlock-wallet.yaml | 12 ------------ 2 files changed, 22 deletions(-) diff --git a/apps/demo-wallet-native/.maestro/connect-test.yaml b/apps/demo-wallet-native/.maestro/connect-test.yaml index 1bc6e6119..184153417 100644 --- a/apps/demo-wallet-native/.maestro/connect-test.yaml +++ b/apps/demo-wallet-native/.maestro/connect-test.yaml @@ -20,42 +20,32 @@ env: - tapOn: "Connect Wallet" -# Подождать появления модального окна с QR/URL - assertVisible: text: "Copy Link" -# === ШАГ 3: Скопировать tonconnect URL === - tapOn: "Copy Link" -# === ШАГ 4: Вернуться в кошелёк === - launchApp: appId: org.ton.wallet stopApp: false -# === ШАГ 5: Открыть экран Connect dApp === - tapOn: id: scan-button -# Подождать экран Connect to dApp - assertVisible: id: tonconnect-url -# === ШАГ 6: Вставить URL из буфера обмена === - tapOn: id: paste-button -# === ШАГ 7: Нажать Connect === - tapOn: id: tonconnect-process -# === ШАГ 8: Подтвердить подключение === - assertVisible: id: connect-approve - tapOn: id: connect-approve -# === ШАГ 9: Проверить успешное подключение === -# Вернуться в браузер и проверить что кнопка изменилась - openLink: link: ${DAPP_URL} browser: true diff --git a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml index fc42b61f1..ce18773ba 100644 --- a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml +++ b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml @@ -1,24 +1,12 @@ -# Unlock Wallet Flow -# Переиспользуемый flow для разблокировки кошелька -# -# Использование в других тестах: -# - runFlow: -# file: flows/unlock-wallet.yaml -# env: -# PASSWORD: ${PASSWORD} - appId: org.ton.wallet --- -# Ввести пароль - tapOn: id: unlock-password-input - inputText: ${PASSWORD} - hideKeyboard -# Нажать Continue - tapOn: id: unlock-submit-button -# Дождаться главного экрана - assertVisible: id: ton-balance-card From 0d4d9d9e5c1ddf4f41236ba793a537672d0bf333 Mon Sep 17 00:00:00 2001 From: "V. K." Date: Wed, 10 Dec 2025 17:07:30 +0400 Subject: [PATCH 4/6] test: complete connect-test --- .../.maestro/connect-test.yaml | 27 ++--- .../.maestro/flows/unlock-wallet.yaml | 2 +- .../.maestro/import-wallet.yaml | 2 +- apps/demo-wallet-native/app.json | 6 +- .../src/app/(auth)/(tabs)/history.tsx | 14 +-- .../src/app/+native-intent.tsx | 17 +++ apps/demo-wallet-native/src/app/_layout.tsx | 3 +- .../components/screen-header/close-button.tsx | 31 +----- .../components/screen-header/container.tsx | 21 +++- .../components/screen-header/left-side.tsx | 2 +- .../components/screen-header/right-side.tsx | 2 +- .../screen-header/screen-header.tsx | 2 +- .../nft-details-modal/nft-details-modal.tsx | 15 ++- .../token-list-sheet/token-list-sheet.tsx | 36 ++---- .../components/app-wrapper/app-wrapper.tsx | 2 + .../development-tools-section.tsx | 10 ++ .../settings/hooks/use-deep-link-handler.ts | 105 ++++++++++++++++++ .../connect-request-modal.tsx | 61 +++++----- .../sign-data-request-modal.tsx | 26 +++-- .../ton-connect-handler.tsx | 8 +- .../transaction-request-modal.tsx | 26 +++-- .../transaction-details-modal.tsx | 15 ++- .../wallet-selector-modal.tsx | 27 +++-- 23 files changed, 298 insertions(+), 162 deletions(-) create mode 100644 apps/demo-wallet-native/src/app/+native-intent.tsx create mode 100644 apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts diff --git a/apps/demo-wallet-native/.maestro/connect-test.yaml b/apps/demo-wallet-native/.maestro/connect-test.yaml index 184153417..fffbc8668 100644 --- a/apps/demo-wallet-native/.maestro/connect-test.yaml +++ b/apps/demo-wallet-native/.maestro/connect-test.yaml @@ -1,4 +1,4 @@ -appId: org.ton.wallet +appId: org.ton.demowallet env: PASSWORD: 1111 DAPP_URL: https://allure-test-runner.vercel.app/e2e @@ -21,25 +21,14 @@ env: - tapOn: "Connect Wallet" - assertVisible: - text: "Copy Link" + text: "Tonkeeper" -- tapOn: "Copy Link" - -- launchApp: - appId: org.ton.wallet - stopApp: false - -- tapOn: - id: scan-button +- tapOn: "Tonkeeper" - assertVisible: - id: tonconnect-url - -- tapOn: - id: paste-button + text: "Open" -- tapOn: - id: tonconnect-process +- tapOn: "Open" - assertVisible: id: connect-approve @@ -49,4 +38,8 @@ env: - openLink: link: ${DAPP_URL} browser: true -- assertNotVisible: "Connect Wallet" + +- scrollUntilVisible: + element: "Disconnect Wallet" + +- tapOn: "Disconnect Wallet" diff --git a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml index ce18773ba..5c18b6f2c 100644 --- a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml +++ b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml @@ -1,4 +1,4 @@ -appId: org.ton.wallet +appId: org.ton.demowallet --- - tapOn: id: unlock-password-input diff --git a/apps/demo-wallet-native/.maestro/import-wallet.yaml b/apps/demo-wallet-native/.maestro/import-wallet.yaml index c857d1d82..0fcdddd4c 100644 --- a/apps/demo-wallet-native/.maestro/import-wallet.yaml +++ b/apps/demo-wallet-native/.maestro/import-wallet.yaml @@ -1,4 +1,4 @@ -appId: org.ton.wallet +appId: org.ton.demowallet env: MNEMONIC: ${MNEMONIC || "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"} PASSWORD: 1111 diff --git a/apps/demo-wallet-native/app.json b/apps/demo-wallet-native/app.json index 976d538e5..b5bc309b7 100644 --- a/apps/demo-wallet-native/app.json +++ b/apps/demo-wallet-native/app.json @@ -2,7 +2,7 @@ "expo": { "name": "Ton Wallet", "slug": "ton-wallet", - "scheme": "ton-wallet", + "scheme": "tonkeeper", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/icon.png", @@ -15,7 +15,7 @@ }, "ios": { "supportsTablet": true, - "bundleIdentifier": "org.ton.wallet" + "bundleIdentifier": "org.ton.demowallet" }, "android": { "adaptiveIcon": { @@ -24,7 +24,7 @@ }, "edgeToEdgeEnabled": true, "predictiveBackGestureEnabled": false, - "package": "org.ton.wallet" + "package": "org.ton.demowallet" }, "web": { "favicon": "./assets/favicon.png" diff --git a/apps/demo-wallet-native/src/app/(auth)/(tabs)/history.tsx b/apps/demo-wallet-native/src/app/(auth)/(tabs)/history.tsx index 4a5b3760d..de47ef2a7 100644 --- a/apps/demo-wallet-native/src/app/(auth)/(tabs)/history.tsx +++ b/apps/demo-wallet-native/src/app/(auth)/(tabs)/history.tsx @@ -34,12 +34,6 @@ const HistoryScreen: FC = () => { setSelectedEvent(null); }, []); - const renderHeader = () => ( - - Transactions - - ); - const renderContent = () => { if (error) { return ; @@ -59,12 +53,14 @@ const HistoryScreen: FC = () => { return ( - contentContainerStyle={styles.list} data={events as Event[]} keyExtractor={(item) => item.eventId} ListHeaderComponent={ <> - {renderHeader()} + + Transactions + + {renderContent()} } @@ -96,8 +92,6 @@ const styles = StyleSheet.create(({ sizes }, runtime) => ({ marginTop: runtime.insets.top, marginLeft: runtime.insets.left, marginRight: runtime.insets.right, - }, - list: { paddingTop: sizes.page.paddingTop, paddingBottom: sizes.page.paddingBottom, paddingHorizontal: sizes.page.paddingHorizontal, diff --git a/apps/demo-wallet-native/src/app/+native-intent.tsx b/apps/demo-wallet-native/src/app/+native-intent.tsx new file mode 100644 index 000000000..dd81ac991 --- /dev/null +++ b/apps/demo-wallet-native/src/app/+native-intent.tsx @@ -0,0 +1,17 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export function redirectSystemPath({ path }: { path: string; initial: boolean }): string | null { + // Handle TON Connect deeplinks - prevent Expo Router from treating them as routes + if (path.startsWith('tonkeeper://ton-connect') || path.includes('tc://') || path.includes('ton://')) { + // Return null to cancel navigation - useDeepLinkHandler will handle the URL + return null; + } + + return path; +} diff --git a/apps/demo-wallet-native/src/app/_layout.tsx b/apps/demo-wallet-native/src/app/_layout.tsx index 68d7fff8f..60682f0b9 100644 --- a/apps/demo-wallet-native/src/app/_layout.tsx +++ b/apps/demo-wallet-native/src/app/_layout.tsx @@ -46,7 +46,8 @@ const RootLayout: FC = () => { storage={walletProviderStorage} walletKitConfig={{ storage: walletKitStorage, - bridgeUrl: 'https://walletbot.me/tonconnect-bridge/bridge', + bridgeUrl: 'https://bridge.tonapi.io/bridge', + // bridgeUrl: 'https://walletbot.me/tonconnect-bridge/bridge', tonApiKeyMainnet: ENV_TON_API_KEY_MAINNET, tonApiKeyTestnet: ENV_TON_API_KEY_TESTNET, }} diff --git a/apps/demo-wallet-native/src/core/components/screen-header/close-button.tsx b/apps/demo-wallet-native/src/core/components/screen-header/close-button.tsx index 0b537d47b..834b9077d 100644 --- a/apps/demo-wallet-native/src/core/components/screen-header/close-button.tsx +++ b/apps/demo-wallet-native/src/core/components/screen-header/close-button.tsx @@ -26,37 +26,10 @@ export const ScreenHeaderCloseButton: FC = ({ style, onClose, ...props }) ); }; -const styles = StyleSheet.create(({ colors, sizes }) => ({ - container: { - width: '100%', - position: 'relative', - height: 40, - alignItems: 'center', - justifyContent: 'center', - marginBottom: sizes.space.vertical, - }, - backButton: { - position: 'absolute', - left: 1, - top: 8, - }, - title: { - color: colors.text.highlight, - textAlign: 'center', - }, +const styles = StyleSheet.create(() => ({ closeButton: { position: 'absolute', top: 6, - right: 12, - }, - cancelButton: { - position: 'absolute', - top: 3, - right: 0, - paddingHorizontal: 14, - paddingVertical: 8, - }, - cancelButtonText: { - color: colors.text.highlight, + right: 6, }, })); diff --git a/apps/demo-wallet-native/src/core/components/screen-header/container.tsx b/apps/demo-wallet-native/src/core/components/screen-header/container.tsx index c9804d2db..5aaa6ce87 100644 --- a/apps/demo-wallet-native/src/core/components/screen-header/container.tsx +++ b/apps/demo-wallet-native/src/core/components/screen-header/container.tsx @@ -12,17 +12,30 @@ import { StyleSheet } from 'react-native-unistyles'; import { Row } from '../grid'; -export const ScreenHeaderContainer: FC = ({ style, ...props }) => { - return ; +interface Props extends ViewProps { + type?: 'screen' | 'modal'; +} + +export const ScreenHeaderContainer: FC = ({ style, type = 'screen', ...props }) => { + return ( + + ); }; const styles = StyleSheet.create(({ sizes }) => ({ container: { - width: '100%', position: 'relative', - height: 40, + height: 45, alignItems: 'center', justifyContent: 'center', marginBottom: sizes.space.vertical, }, + screen: {}, + modal: { + marginTop: sizes.page.paddingTop * 2, + marginHorizontal: sizes.page.paddingHorizontal, + }, })); diff --git a/apps/demo-wallet-native/src/core/components/screen-header/left-side.tsx b/apps/demo-wallet-native/src/core/components/screen-header/left-side.tsx index 797737fe9..da9173e70 100644 --- a/apps/demo-wallet-native/src/core/components/screen-header/left-side.tsx +++ b/apps/demo-wallet-native/src/core/components/screen-header/left-side.tsx @@ -21,6 +21,6 @@ const styles = StyleSheet.create(() => ({ justifyContent: 'center', position: 'absolute', left: 0, - height: 40, + height: 45, }, })); diff --git a/apps/demo-wallet-native/src/core/components/screen-header/right-side.tsx b/apps/demo-wallet-native/src/core/components/screen-header/right-side.tsx index 5fee213f9..345cdaf5a 100644 --- a/apps/demo-wallet-native/src/core/components/screen-header/right-side.tsx +++ b/apps/demo-wallet-native/src/core/components/screen-header/right-side.tsx @@ -22,7 +22,7 @@ const styles = StyleSheet.create(({ sizes }) => ({ alignItems: 'center', position: 'absolute', right: 0, - height: 40, + height: 45, gap: sizes.space.horizontal / 2, }, })); diff --git a/apps/demo-wallet-native/src/core/components/screen-header/screen-header.tsx b/apps/demo-wallet-native/src/core/components/screen-header/screen-header.tsx index 81ec296ee..20e731b46 100644 --- a/apps/demo-wallet-native/src/core/components/screen-header/screen-header.tsx +++ b/apps/demo-wallet-native/src/core/components/screen-header/screen-header.tsx @@ -86,7 +86,7 @@ const styles = StyleSheet.create(({ colors, sizes }) => ({ container: { width: '100%', position: 'relative', - height: 40, + height: 45, alignItems: 'center', justifyContent: 'center', marginBottom: sizes.space.vertical, diff --git a/apps/demo-wallet-native/src/features/nft/components/nft-details-modal/nft-details-modal.tsx b/apps/demo-wallet-native/src/features/nft/components/nft-details-modal/nft-details-modal.tsx index 40e61bca2..ac2f05269 100644 --- a/apps/demo-wallet-native/src/features/nft/components/nft-details-modal/nft-details-modal.tsx +++ b/apps/demo-wallet-native/src/features/nft/components/nft-details-modal/nft-details-modal.tsx @@ -63,15 +63,15 @@ export const NftDetailsModal: FC = ({ nft, visible, onClos return ( - - - {nftName} + + {nftName} - - - - + + + + + {nftImage ? ( @@ -136,7 +136,6 @@ export const NftDetailsModal: FC = ({ nft, visible, onClos const styles = StyleSheet.create(({ sizes, colors }, runtime) => ({ contentContainer: { paddingBottom: runtime.insets.bottom + sizes.page.paddingBottom, - paddingVertical: sizes.block.paddingVertical, paddingHorizontal: sizes.page.paddingHorizontal, marginLeft: runtime.insets.left, marginRight: runtime.insets.right, diff --git a/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx b/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx index 528d3bf7b..8283c63f1 100644 --- a/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx +++ b/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx @@ -19,6 +19,7 @@ import { AppModal } from '@/core/components/app-modal'; import { AppText } from '@/core/components/app-text'; import { CircleLogo } from '@/core/components/circle-logo'; import { TextAmount } from '@/core/components/text-amount'; +import { ScreenHeader } from '@/core/components/screen-header'; interface SelectedToken { type: 'TON' | 'JETTON'; @@ -37,8 +38,6 @@ export const TokenListSheet: FC = ({ isOpen, onClose, onSel const { userJettons, formatJettonAmount } = useJettons(); const tonBalance = useFormattedTonBalance(); - const { theme } = useUnistyles(); - const handleSelectTon = () => { onSelectTon(); onClose(); @@ -51,17 +50,15 @@ export const TokenListSheet: FC = ({ isOpen, onClose, onSel return ( - - - - Select - + + Select - - - - + + + + + @@ -124,22 +121,7 @@ export const TokenListSheet: FC = ({ isOpen, onClose, onSel const styles = StyleSheet.create(({ sizes, colors }, runtime) => ({ container: { paddingHorizontal: sizes.page.paddingHorizontal, - paddingVertical: sizes.block.paddingVertical, - marginBottom: runtime.insets.bottom * 2, - }, - header: { - position: 'relative', - marginTop: 10, - marginBottom: 20, - }, - title: { - color: colors.text.highlight, - textAlign: 'center', - }, - closeButton: { - position: 'absolute', - top: 0, - right: 12, + paddingBottom: runtime.insets.bottom + sizes.block.paddingVertical, }, tokenItem: { flexDirection: 'row', diff --git a/apps/demo-wallet-native/src/features/settings/components/app-wrapper/app-wrapper.tsx b/apps/demo-wallet-native/src/features/settings/components/app-wrapper/app-wrapper.tsx index a26d350f0..68a53432f 100644 --- a/apps/demo-wallet-native/src/features/settings/components/app-wrapper/app-wrapper.tsx +++ b/apps/demo-wallet-native/src/features/settings/components/app-wrapper/app-wrapper.tsx @@ -14,6 +14,7 @@ import { useWalletStore } from '@ton/demo-core'; import { useInitialRedirect } from 'src/features/settings/hooks/use-initial-redirect'; import { useAppFonts } from '../../hooks/use-app-fonts'; +import { useDeepLinkHandler } from '../../hooks/use-deep-link-handler'; import { useTheme } from '../../hooks/use-theme'; import { useWalletDataUpdater } from '../../hooks/use-wallet-data-updater'; import { setIsAppReady } from '../../store/actions/is-app-ready'; @@ -34,6 +35,7 @@ export const AppWrapper: FC = ({ children }) => { useInitialRedirect(isLoaderShown); useWalletDataUpdater(); + useDeepLinkHandler(); useEffect(() => { // eslint-disable-next-line no-undef diff --git a/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx b/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx index a6ea1faf7..579a9500d 100644 --- a/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx +++ b/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx @@ -33,6 +33,12 @@ export const DevelopmentToolsSection: FC = () => { } }, [walletKit]); + const handleLogAllSessions = useCallback(async () => { + if (!walletKit) return; + + console.log('sessions', await walletKit.listSessions()); + }, [walletKit]); + return ( @@ -50,6 +56,10 @@ export const DevelopmentToolsSection: FC = () => { Disconnect All + + + Log Sessions + ); diff --git a/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts b/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts new file mode 100644 index 000000000..01f2619c8 --- /dev/null +++ b/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts @@ -0,0 +1,105 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +import * as Linking from 'expo-linking'; +import { useEffect, useCallback, useRef } from 'react'; +import { Alert } from 'react-native'; +import { useTonConnect, useWalletStore } from '@ton/demo-core'; + +const extractTonConnectUrl = (deepLinkUrl: string): string | null => { + if (deepLinkUrl.startsWith('tc://') || deepLinkUrl.startsWith('ton://')) { + return deepLinkUrl; + } + + const tkMatch = deepLinkUrl.match(/^tonkeeper:\/\/ton-connect\?(.+)$/); + + if (tkMatch) { + return `tc://?${tkMatch[1]}`; + } + + return null; +}; + +export const useDeepLinkHandler = (): void => { + const { handleTonConnectUrl } = useTonConnect(); + + const isUnlocked = useWalletStore((state) => state.auth.isUnlocked); + const isProcessingRef = useRef(false); + const pendingUrlRef = useRef(null); + + const processDeepLink = useCallback( + async (url: string | null) => { + if (!url || isProcessingRef.current) return; + + const tonConnectUrl = extractTonConnectUrl(url); + console.log('tonConnectUrl', tonConnectUrl); + + if (!tonConnectUrl) { + return; + } + + if (!isUnlocked) { + pendingUrlRef.current = tonConnectUrl; + return; + } + + isProcessingRef.current = true; + + try { + await handleTonConnectUrl(tonConnectUrl); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Failed to handle deep link:', error); + Alert.alert('Connection Failed', 'Failed to connect to the dApp. Please try again.'); + } finally { + isProcessingRef.current = false; + } + }, + [handleTonConnectUrl, isUnlocked], + ); + + useEffect(() => { + if (isUnlocked && pendingUrlRef.current) { + const url = pendingUrlRef.current; + pendingUrlRef.current = null; + void (async () => { + isProcessingRef.current = true; + try { + await handleTonConnectUrl(url); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Failed to handle pending deep link:', error); + Alert.alert('Connection Failed', 'Failed to connect to the dApp. Please try again.'); + } finally { + isProcessingRef.current = false; + } + })(); + } + }, [isUnlocked, handleTonConnectUrl]); + + useEffect(() => { + const handleInitialUrl = async (): Promise => { + const initialUrl = await Linking.getInitialURL(); + if (initialUrl) { + await processDeepLink(initialUrl); + } + }; + + void handleInitialUrl(); + }, [processDeepLink]); + + useEffect(() => { + const subscription = Linking.addEventListener('url', (event) => { + void processDeepLink(event.url); + }); + + return () => { + subscription.remove(); + }; + }, [processDeepLink]); +}; diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/connect-request-modal/connect-request-modal.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/connect-request-modal/connect-request-modal.tsx index 0338c7d0e..31582b900 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/connect-request-modal/connect-request-modal.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/connect-request-modal/connect-request-modal.tsx @@ -9,7 +9,7 @@ import type { EventConnectRequest, IWallet } from '@ton/walletkit'; import { type SavedWallet, useWallet } from '@ton/demo-core'; import { type FC, useState, useMemo, useEffect } from 'react'; -import { View } from 'react-native'; +import { View, ScrollView } from 'react-native'; import { StyleSheet } from 'react-native-unistyles'; import { DAppInfo } from '../dapp-info'; @@ -18,8 +18,9 @@ import { SectionTitle } from '../section-title'; import { ActionButtons } from '../action-buttons'; import { ActiveTouchAction } from '@/core/components/active-touch-action'; -import { AppBottomSheet } from '@/core/components/app-bottom-sheet'; +import { AppModal } from '@/core/components/app-modal'; import { AppText } from '@/core/components/app-text'; +import { ScreenHeader } from '@/core/components/screen-header'; import { WarningBox } from '@/core/components/warning-box'; import { WalletInfoBlock, WalletSelectorModal } from '@/features/wallets'; @@ -83,8 +84,13 @@ export const ConnectRequestModal: FC = ({ request, isO return ( <> - - + + + Connect Request + + + + = ({ request, isO {selectedWallet && ( - Wallet: - - setShowWalletSelector(true)}> - - Change wallet - - + Wallet + + {availableWallets.length > 1 && ( + setShowWalletSelector(true)}> + + Change wallet + + + )} {selectedWallet && ( @@ -141,25 +149,28 @@ export const ConnectRequestModal: FC = ({ request, isO primaryTestID="connect-approve" secondaryTestID="connect-reject" /> - - - - setShowWalletSelector(false)} - wallets={availableWallets} - selectedWallet={selectedWallet} - onSelectWallet={setSelectedWallet} - title="Select Wallet" - /> + + + setShowWalletSelector(false)} + wallets={availableWallets} + selectedWallet={selectedWallet} + onSelectWallet={setSelectedWallet} + title="Select Wallet" + /> + ); }; -const styles = StyleSheet.create(({ colors, sizes }) => ({ - container: { +const styles = StyleSheet.create(({ colors, sizes }, runtime) => ({ + contentContainer: { + paddingBottom: runtime.insets.bottom + sizes.page.paddingBottom, + paddingHorizontal: sizes.page.paddingHorizontal, + marginLeft: runtime.insets.left, + marginRight: runtime.insets.right, gap: sizes.space.vertical, - paddingBottom: sizes.space.vertical, }, permissionsSection: { gap: sizes.space.vertical / 2, diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx index 264363c0d..b24cfc454 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/sign-data-request-modal/sign-data-request-modal.tsx @@ -17,11 +17,12 @@ import { SectionTitle } from '../section-title'; import { ActionButtons } from '../action-buttons'; import { SuccessView } from '../success-view'; -import { AppBottomSheet } from '@/core/components/app-bottom-sheet'; +import { AppModal } from '@/core/components/app-modal'; import { AppText } from '@/core/components/app-text'; +import { Block } from '@/core/components/block'; +import { ScreenHeader } from '@/core/components/screen-header'; import { WarningBox } from '@/core/components/warning-box'; import { WalletInfoBlock } from '@/features/wallets'; -import { Block } from '@/core/components/block'; interface SignDataRequestModalProps { request: EventSignDataRequest; @@ -144,15 +145,20 @@ export const SignDataRequestModal: FC = ({ request, i if (showSuccess) { return ( - {}} isDisabledClose isScrollable={false}> + {}}> - + ); } return ( - - + + + Sign Data Request + + + + = ({ request, i primaryTestID="sign-data-approve" secondaryTestID="sign-data-reject" /> - - + + ); }; const styles = StyleSheet.create(({ colors, sizes }) => ({ + scrollView: { + flex: 1, + }, container: { gap: sizes.space.vertical, + paddingHorizontal: sizes.page.paddingHorizontal, paddingBottom: sizes.space.vertical, }, walletSection: { diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-handler/ton-connect-handler.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-handler/ton-connect-handler.tsx index 88533c999..6fa166023 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-handler/ton-connect-handler.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/ton-connect-handler/ton-connect-handler.tsx @@ -7,19 +7,25 @@ */ import type { FC } from 'react'; -import { useTonConnect, useTransactionRequests, useSignDataRequests } from '@ton/demo-core'; +import { useTonConnect, useTransactionRequests, useSignDataRequests, useWalletStore } from '@ton/demo-core'; import { ConnectRequestModal } from '../connect-request-modal'; import { TransactionRequestModal } from '../transaction-request-modal'; import { SignDataRequestModal } from '../sign-data-request-modal'; export const TonConnectHandler: FC = () => { + const isUnlocked = useWalletStore((state) => state.auth.isUnlocked); + const { pendingConnectRequest, isConnectModalOpen, approveConnectRequest, rejectConnectRequest } = useTonConnect(); const { pendingTransactionRequest, isTransactionModalOpen, approveTransactionRequest, rejectTransactionRequest } = useTransactionRequests(); const { pendingSignDataRequest, isSignDataModalOpen, approveSignDataRequest, rejectSignDataRequest } = useSignDataRequests(); + if (!isUnlocked) { + return null; + } + return ( <> {pendingConnectRequest && ( diff --git a/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx b/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx index 9f7f2461f..c27566b30 100644 --- a/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx +++ b/apps/demo-wallet-native/src/features/ton-connect/components/transaction-request-modal/transaction-request-modal.tsx @@ -8,7 +8,7 @@ import type { EventTransactionRequest } from '@ton/walletkit'; import { type FC, useState, useMemo, useEffect } from 'react'; -import { View } from 'react-native'; +import { View, ScrollView } from 'react-native'; import { StyleSheet } from 'react-native-unistyles'; import { useWallet } from '@ton/demo-core'; import { useWalletKit } from '@ton/demo-core'; @@ -19,8 +19,9 @@ import { SectionTitle } from '../section-title'; import { ActionButtons } from '../action-buttons'; import { SuccessView } from '../success-view'; -import { AppBottomSheet } from '@/core/components/app-bottom-sheet'; +import { AppModal } from '@/core/components/app-modal'; import { AppText } from '@/core/components/app-text'; +import { ScreenHeader } from '@/core/components/screen-header'; import { WarningBox } from '@/core/components/warning-box'; import { WalletInfoBlock } from '@/features/wallets'; @@ -70,15 +71,20 @@ export const TransactionRequestModal: FC = ({ requ if (showSuccess) { return ( - {}} isDisabledClose isScrollable={false}> + {}}> - + ); } return ( - - + + + Transaction Request + + + + = ({ requ primaryTestID="send-transaction-approve" secondaryTestID="send-transaction-reject" /> - - + + ); }; const styles = StyleSheet.create(({ colors, sizes }) => ({ + scrollView: { + flex: 1, + }, container: { gap: sizes.space.vertical, + paddingHorizontal: sizes.page.paddingHorizontal, paddingBottom: sizes.space.vertical, }, walletSection: { diff --git a/apps/demo-wallet-native/src/features/transactions/components/transaction-details-modal/transaction-details-modal.tsx b/apps/demo-wallet-native/src/features/transactions/components/transaction-details-modal/transaction-details-modal.tsx index 05c7e9d9f..21bc2e428 100644 --- a/apps/demo-wallet-native/src/features/transactions/components/transaction-details-modal/transaction-details-modal.tsx +++ b/apps/demo-wallet-native/src/features/transactions/components/transaction-details-modal/transaction-details-modal.tsx @@ -99,15 +99,15 @@ export const TransactionDetailsModal: FC = ({ even return ( - - - Transaction Details + + Transaction Details - - - - + + + + + {valueImage ? ( @@ -246,7 +246,6 @@ export const TransactionDetailsModal: FC = ({ even const styles = StyleSheet.create(({ sizes, colors }, runtime) => ({ contentContainer: { paddingBottom: runtime.insets.bottom + sizes.page.paddingBottom, - paddingVertical: sizes.block.paddingVertical, paddingHorizontal: sizes.page.paddingHorizontal, marginLeft: runtime.insets.left, marginRight: runtime.insets.right, diff --git a/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx b/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx index 72d737853..9acecf830 100644 --- a/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx +++ b/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx @@ -9,13 +9,15 @@ import type { IWallet } from '@ton/walletkit'; import { useWallet } from '@ton/demo-core'; import type { FC } from 'react'; -import { View } from 'react-native'; +import { ScrollView, View } from 'react-native'; import { StyleSheet } from 'react-native-unistyles'; import { WalletInfoBlock } from '../wallet-info-block'; import { AppBottomSheet } from '@/core/components/app-bottom-sheet'; import { ActiveTouchAction } from '@/core/components/active-touch-action'; +import { AppModal } from '@/core/components/app-modal'; +import { ScreenHeader } from '@/core/components/screen-header'; interface WalletSelectorModalProps { isOpen: boolean; @@ -43,15 +45,20 @@ export const WalletSelectorModal: FC = ({ }; return ( - - + + + {title} + + + + {wallets.map((wallet, index) => { const address = wallet.getAddress(); const savedWallet = savedWallets.find((w) => w.address === address); const isSelected = selectedWallet === wallet; return ( - handleSelect(wallet)}> + handleSelect(wallet)}> = ({ ); })} - - + + ); }; -const styles = StyleSheet.create(({ sizes, colors }) => ({ - list: { +const styles = StyleSheet.create(({ sizes, colors }, runtime) => ({ + contentContainer: { + paddingBottom: runtime.insets.bottom + sizes.page.paddingBottom, + paddingHorizontal: sizes.page.paddingHorizontal, + marginLeft: runtime.insets.left, + marginRight: runtime.insets.right, gap: sizes.space.vertical / 2, }, selected: { From 30ae943adccafc20f87e0b1bebb0af1d9408277d Mon Sep 17 00:00:00 2001 From: "V. K." Date: Thu, 11 Dec 2025 10:36:21 +0400 Subject: [PATCH 5/6] test: add allure requests --- apps/demo-wallet-native/.maestro/.env.example | 11 ++ apps/demo-wallet-native/.maestro/allure.ts | 164 ++++++++++++++++++ apps/demo-wallet-native/.maestro/config.ts | 45 +++++ .../connect-wallet.yaml} | 20 +-- .../.maestro/flows/unlock-wallet.yaml | 4 + apps/demo-wallet-native/.maestro/run-tests.ts | 133 ++++++++++++++ .../.maestro/tests/connect-disconnect.yaml | 25 +++ .../.maestro/{ => tests}/import-wallet.yaml | 0 .../.maestro/tests/sign-data-test.yaml | 79 +++++++++ apps/demo-wallet-native/.maestro/utils.ts | 12 ++ apps/demo-wallet-native/docs/e2e-testing.md | 90 ++++++++++ apps/demo-wallet-native/package.json | 4 +- pnpm-lock.yaml | 3 + 13 files changed, 572 insertions(+), 18 deletions(-) create mode 100644 apps/demo-wallet-native/.maestro/.env.example create mode 100644 apps/demo-wallet-native/.maestro/allure.ts create mode 100644 apps/demo-wallet-native/.maestro/config.ts rename apps/demo-wallet-native/.maestro/{connect-test.yaml => flows/connect-wallet.yaml} (62%) create mode 100644 apps/demo-wallet-native/.maestro/run-tests.ts create mode 100644 apps/demo-wallet-native/.maestro/tests/connect-disconnect.yaml rename apps/demo-wallet-native/.maestro/{ => tests}/import-wallet.yaml (100%) create mode 100644 apps/demo-wallet-native/.maestro/tests/sign-data-test.yaml create mode 100644 apps/demo-wallet-native/.maestro/utils.ts create mode 100644 apps/demo-wallet-native/docs/e2e-testing.md diff --git a/apps/demo-wallet-native/.maestro/.env.example b/apps/demo-wallet-native/.maestro/.env.example new file mode 100644 index 000000000..88ad98ea4 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/.env.example @@ -0,0 +1,11 @@ +# Wallet credentials +MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon" +PASSWORD=1111 + +# dApp URL for e2e tests +DAPP_URL=https://allure-test-runner.vercel.app/e2e + +# Allure TestOps integration +ALLURE_API_TOKEN=your-allure-api-token +ALLURE_BASE_URL=https://tontech.testops.cloud +ALLURE_PROJECT_ID=100 diff --git a/apps/demo-wallet-native/.maestro/allure.ts b/apps/demo-wallet-native/.maestro/allure.ts new file mode 100644 index 000000000..fbaf9a7a7 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/allure.ts @@ -0,0 +1,164 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +interface TokenResponse { + access_token: string; + token_type: string; + expires_in: number; + scope: string; +} + +export interface AllureConfig { + baseUrl: string; + apiToken: string; + projectId: number; +} + +export type TestCaseData = { + precondition: string; + expectedResult: string; + isPositiveCase: boolean; +}; + +/** + * Получает JWT токен для Allure TestOps API + */ +async function getAllureToken(config: AllureConfig): Promise { + const { baseUrl, apiToken } = config; + + const formData = new FormData(); + formData.append('grant_type', 'apitoken'); + formData.append('scope', 'openid'); + formData.append('token', apiToken); + + const response = await fetch(`${baseUrl}/api/uaa/oauth/token`, { + method: 'POST', + headers: { Accept: 'application/json' }, + body: formData, + }); + + if (!response.ok) { + throw new Error(`Failed to get token: ${response.status} ${response.statusText}`); + } + + const tokenData: TokenResponse = await response.json(); + return tokenData.access_token; +} + +/** + * Создает конфигурацию Allure TestOps из переменных окружения + */ +export function createAllureConfig(): AllureConfig { + const baseUrl = process.env.ALLURE_BASE_URL || 'https://tontech.testops.cloud'; + const apiToken = process.env.ALLURE_API_TOKEN; + const projectId = parseInt(process.env.ALLURE_PROJECT_ID || '100'); + + if (!apiToken) { + throw new Error('ALLURE_API_TOKEN environment variable is required'); + } + + return { baseUrl, apiToken, projectId }; +} + +/** + * Утилита для работы с Allure TestOps API + */ +export class AllureApiClient { + private config: AllureConfig; + private token?: string; + private tokenExpiry?: number; + + constructor(config: AllureConfig) { + this.config = config; + } + + /** + * Получает актуальный токен (с кэшированием) + */ + private async getValidToken(): Promise { + const now = Date.now(); + + if (!this.token || !this.tokenExpiry || now >= this.tokenExpiry) { + this.token = await getAllureToken(this.config); + // Токен действует 1 час, обновляем за 5 минут до истечения + this.tokenExpiry = now + 55 * 60 * 1000; + } + + return this.token; + } + + /** + * Выполняет авторизованный запрос к Allure API + */ + private async makeRequest(endpoint: string, options: { headers?: Record } = {}): Promise { + const token = await this.getValidToken(); + + const response = await fetch(`${this.config.baseUrl}${endpoint}`, { + ...options, + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + Accept: 'application/json', + ...options.headers, + }, + }); + + if (!response.ok) { + throw new Error(`API request failed: ${response.status} ${response.statusText}`); + } + + return response; + } + + /** + * Получает информацию о тест-кейсе по allureId + */ + async getTestCase(allureId: string): Promise { + const response = await this.makeRequest(`/api/rs/testcase/allureId/${allureId}`); + return await response.json(); + } + + /** + * Получает информацию о тест-кейсе по ID + */ + async getTestCaseById(id: string): Promise { + const response = await this.makeRequest(`/api/testcase/${id}`); + return await response.json(); + } +} + +/** + * Получает данные тест-кейса и извлекает precondition и expectedResult + */ +export async function getTestCaseData(allureClient: AllureApiClient, allureId: string): Promise { + const testCaseData = await allureClient.getTestCaseById(allureId); + + if (typeof testCaseData !== 'object' || testCaseData === null || !('name' in testCaseData)) { + throw new Error('Test case data is not an object'); + } + + const data = testCaseData as { name: string; precondition?: string; expectedResult?: string }; + const isPositiveCase = !String(data.name).toLowerCase().includes('error'); + + return { + precondition: parseAllureField(data.precondition || ''), + expectedResult: parseAllureField(data.expectedResult || ''), + isPositiveCase, + }; +} + +function parseAllureField(value: string): string { + // Extract JSON from Markdown code block if present + const jsonMatch = value.match(/```(?:json)?\s*([\s\S]*?)```/); + + if (jsonMatch) { + return jsonMatch[1].trim(); + } + + return value.trim(); +} diff --git a/apps/demo-wallet-native/.maestro/config.ts b/apps/demo-wallet-native/.maestro/config.ts new file mode 100644 index 000000000..86fdf0fd9 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/config.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export interface TestConfig { + name: string; + file: string; + allureId?: string; +} + +export interface TestsConfig { + tests: TestConfig[]; +} + +export const config: TestsConfig = { + tests: [ + { + name: 'Import wallet', + file: 'tests/import-wallet.yaml', + }, + { + name: 'Connect/Disconnect', + file: 'tests/connect-disconnect.yaml', + }, + // { + // name: 'Sign text', + // file: 'tests/sign-data-test.yaml', + // allureId: '2258', + // }, + // { + // name: 'Sign cell', + // file: 'tests/sign-data-test.yaml', + // allureId: '2260', + // }, + // { + // name: 'Sign binary', + // file: 'tests/sign-data-test.yaml', + // allureId: '2259', + // }, + ], +}; diff --git a/apps/demo-wallet-native/.maestro/connect-test.yaml b/apps/demo-wallet-native/.maestro/flows/connect-wallet.yaml similarity index 62% rename from apps/demo-wallet-native/.maestro/connect-test.yaml rename to apps/demo-wallet-native/.maestro/flows/connect-wallet.yaml index fffbc8668..83599ed84 100644 --- a/apps/demo-wallet-native/.maestro/connect-test.yaml +++ b/apps/demo-wallet-native/.maestro/flows/connect-wallet.yaml @@ -1,15 +1,8 @@ appId: org.ton.demowallet env: - PASSWORD: 1111 DAPP_URL: https://allure-test-runner.vercel.app/e2e --- -- launchApp - -- runFlow: - file: flows/unlock-wallet.yaml - env: - PASSWORD: ${PASSWORD} - +# Open dApp and connect - openLink: link: ${DAPP_URL} browser: true @@ -30,16 +23,9 @@ env: - tapOn: "Open" +# Approve connection in wallet - assertVisible: id: connect-approve + - tapOn: id: connect-approve - -- openLink: - link: ${DAPP_URL} - browser: true - -- scrollUntilVisible: - element: "Disconnect Wallet" - -- tapOn: "Disconnect Wallet" diff --git a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml index 5c18b6f2c..6b9f93838 100644 --- a/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml +++ b/apps/demo-wallet-native/.maestro/flows/unlock-wallet.yaml @@ -1,7 +1,11 @@ appId: org.ton.demowallet --- +- assertVisible: + id: unlock-password-input + - tapOn: id: unlock-password-input + - inputText: ${PASSWORD} - hideKeyboard diff --git a/apps/demo-wallet-native/.maestro/run-tests.ts b/apps/demo-wallet-native/.maestro/run-tests.ts new file mode 100644 index 000000000..ed2c9c979 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/run-tests.ts @@ -0,0 +1,133 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +/* eslint-disable no-console */ + +import { execSync } from 'child_process'; +import { resolve } from 'path'; + +import { config } from 'dotenv'; + +import { config as testsConfig, type TestConfig } from './config'; +import { AllureApiClient, createAllureConfig, getTestCaseData } from './allure'; +import { escapeShellArg } from './utils'; + +// Load .env from .maestro folder +config({ path: resolve(__dirname, '.env') }); + +async function runTest( + testConfig: TestConfig, + allureClient: AllureApiClient | null, + baseEnvVars: string, +): Promise { + console.log(`\n${'='.repeat(60)}`); + console.log(`Running: ${testConfig.name}${testConfig.allureId ? ` (allureId: ${testConfig.allureId})` : ''}`); + console.log('='.repeat(60)); + + let envVars = baseEnvVars; + + // Only fetch Allure data if allureId is provided + if (testConfig.allureId && allureClient) { + try { + const testData = await getTestCaseData(allureClient, testConfig.allureId); + + const precondition = escapeShellArg(testData.precondition); + const expectedResult = escapeShellArg(testData.expectedResult); + + envVars += ` -e ALLURE_ID=${testConfig.allureId} -e PRECONDITION=${precondition} -e EXPECTED_RESULT=${expectedResult}`; + } catch (error) { + console.error(`Failed to fetch Allure data for ${testConfig.name}:`, error); + return false; + } + } + + const command = `maestro test ${envVars} ${testConfig.file}`; + + try { + execSync(command, { stdio: 'inherit', cwd: __dirname }); + console.log(`✅ ${testConfig.name} - PASSED`); + return true; + } catch { + console.error(`❌ ${testConfig.name} - FAILED`); + return false; + } +} + +async function main() { + const filterName = process.argv[2]; + + // Environment variables from .env + const password = process.env.PASSWORD || '1111'; + const mnemonic = process.env.MNEMONIC || ''; + const dappUrl = process.env.DAPP_URL || 'https://allure-test-runner.vercel.app/e2e'; + + let baseEnvVars = `-e PASSWORD=${escapeShellArg(password)} -e DAPP_URL=${escapeShellArg(dappUrl)}`; + + if (mnemonic) { + baseEnvVars += ` -e MNEMONIC=${escapeShellArg(mnemonic)}`; + } + + // Load tests config first to check if we need Allure + let testsToRun = testsConfig.tests; + + // Filter tests if name provided + if (filterName) { + testsToRun = testsToRun.filter( + (t) => t.name.toLowerCase().includes(filterName.toLowerCase()) || t.allureId === filterName, + ); + + if (testsToRun.length === 0) { + console.error(`No tests found matching: ${filterName}`); + process.exit(1); + } + } + + // Check if any test requires Allure + const needsAllure = testsToRun.some((t) => t.allureId); + + // Create Allure client only if needed + let allureClient: AllureApiClient | null = null; + if (needsAllure) { + try { + const allureConfig = createAllureConfig(); + allureClient = new AllureApiClient(allureConfig); + } catch (error) { + console.error('Failed to create Allure client:', error); + process.exit(1); + } + } + + console.log(`Running ${testsToRun.length} test(s)...`); + + const results: { name: string; passed: boolean }[] = []; + + for (const testConfig of testsToRun) { + const passed = await runTest(testConfig, allureClient, baseEnvVars); + results.push({ name: testConfig.name, passed }); + } + + // Summary + console.log(`\n${'='.repeat(60)}`); + console.log('SUMMARY'); + console.log('='.repeat(60)); + + const passed = results.filter((r) => r.passed).length; + const failed = results.filter((r) => !r.passed).length; + + for (const result of results) { + console.log(`${result.passed ? '✅' : '❌'} ${result.name}`); + } + + console.log(`\nTotal: ${results.length} | Passed: ${passed} | Failed: ${failed}`); + + if (failed > 0) { + process.exit(1); + } +} + +void main(); diff --git a/apps/demo-wallet-native/.maestro/tests/connect-disconnect.yaml b/apps/demo-wallet-native/.maestro/tests/connect-disconnect.yaml new file mode 100644 index 000000000..4c0bfd58b --- /dev/null +++ b/apps/demo-wallet-native/.maestro/tests/connect-disconnect.yaml @@ -0,0 +1,25 @@ +appId: org.ton.demowallet +env: + PASSWORD: 1111 + DAPP_URL: https://allure-test-runner.vercel.app/e2e +--- +- launchApp + +- runFlow: + file: ../flows/unlock-wallet.yaml + env: + PASSWORD: ${PASSWORD} + +- runFlow: + file: ../flows/connect-wallet.yaml + env: + DAPP_URL: ${DAPP_URL} + +- openLink: + link: ${DAPP_URL} + browser: true + +- scrollUntilVisible: + element: "Disconnect Wallet" + +- tapOn: "Disconnect Wallet" diff --git a/apps/demo-wallet-native/.maestro/import-wallet.yaml b/apps/demo-wallet-native/.maestro/tests/import-wallet.yaml similarity index 100% rename from apps/demo-wallet-native/.maestro/import-wallet.yaml rename to apps/demo-wallet-native/.maestro/tests/import-wallet.yaml diff --git a/apps/demo-wallet-native/.maestro/tests/sign-data-test.yaml b/apps/demo-wallet-native/.maestro/tests/sign-data-test.yaml new file mode 100644 index 000000000..f278f400b --- /dev/null +++ b/apps/demo-wallet-native/.maestro/tests/sign-data-test.yaml @@ -0,0 +1,79 @@ +appId: org.ton.demowallet +env: + PASSWORD: 1111 + DAPP_URL: https://allure-test-runner.vercel.app/e2e + PRECONDITION: ${PRECONDITION} + EXPECTED_RESULT: ${EXPECTED_RESULT} +--- +# Launch app and unlock wallet +- launchApp + +- runFlow: + file: ../flows/unlock-wallet.yaml + env: + PASSWORD: ${PASSWORD} + +- runFlow: + file: ../flows/connect-wallet.yaml + env: + DAPP_URL: ${DAPP_URL} + +# Go back to dApp, fill precondition/expectedResult, and trigger Sign Data +- openLink: + link: ${DAPP_URL} + browser: true + +# Fill precondition field if provided +- scrollUntilVisible: + element: "Sign Data" +- tapOn: + text: "Precondition (JSON)" + below: "Sign Data Test" +- waitForAnimationToEnd: + timeout: 1000 +- longPressOn: + text: "Precondition (JSON)" + below: "Sign Data Test" +- tapOn: 'Select All' +- eraseText +- inputText: ${PRECONDITION} +- hideKeyboard + +# Fill expected result field (the one after Sign Data Test) +- scrollUntilVisible: + element: "Sign Data" +- tapOn: + text: "Expected Result (JSON)" + below: "Sign Data Test" +- longPressOn: + text: "Expected Result (JSON)" + below: "Sign Data Test" +- tapOn: 'Select All' +- eraseText +- inputText: ${EXPECTED_RESULT} +- hideKeyboard + +- scrollUntilVisible: + element: "Sign Data" + +- tapOn: "Sign Data" + +- launchApp: + stopApp: false + +# Approve sign data in wallet +- assertVisible: + id: sign-data-approve + +- tapOn: + id: sign-data-approve + +- launchApp: + appId: com.apple.mobilesafari + stopApp: false + +- scrollUntilVisible: + element: "Validation Passed" + +- assertVisible: + text: "Validation Passed" diff --git a/apps/demo-wallet-native/.maestro/utils.ts b/apps/demo-wallet-native/.maestro/utils.ts new file mode 100644 index 000000000..d704fd8c4 --- /dev/null +++ b/apps/demo-wallet-native/.maestro/utils.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) TonTech. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +export const escapeShellArg = (arg: string): string => { + // Replace single quotes with escaped version and wrap in single quotes + return `'${arg.replace(/'/g, "'\\''")}'`; +}; diff --git a/apps/demo-wallet-native/docs/e2e-testing.md b/apps/demo-wallet-native/docs/e2e-testing.md new file mode 100644 index 000000000..ab93c3ab4 --- /dev/null +++ b/apps/demo-wallet-native/docs/e2e-testing.md @@ -0,0 +1,90 @@ +# E2E Testing Guide + +This guide explains how to run end-to-end tests for the demo-wallet-native app using [Maestro](https://maestro.mobile.dev/). + +## Prerequisites + +1. **Install Maestro** + + Follow the installation guide: https://docs.maestro.dev/getting-started/installing-maestro + +2. **Build the app** + ```bash + pnpm ios + # or + pnpm android + ``` + +3. **Configure environment** + ```bash + cp .maestro/.env.example .maestro/.env + ``` + + Edit `.maestro/.env` and set your values: + - `MNEMONIC` - wallet seed phrase for import tests + - `PASSWORD` - wallet password (default: 1111) + - `DAPP_URL` - dApp URL for connect tests + - `ALLURE_API_TOKEN` - Allure TestOps API token (for Allure integration) + - `ALLURE_BASE_URL` - Allure TestOps URL (default: https://tontech.testops.cloud) + - `ALLURE_PROJECT_ID` - Allure project ID (default: 100) + +## Running Tests + +### Run all tests +```bash +pnpm e2e +``` + +### Run specific test by name +```bash +pnpm e2e "Sign text" +``` + +### Run test by Allure ID +```bash +pnpm e2e 2258 +``` + +### Run any Maestro test directly +```bash +maestro test .maestro/tests/.yaml +``` + +## Test Configuration + +Tests are configured in `.maestro/config.ts`. Each test has: +- `name` - test display name +- `file` - path to Maestro YAML file +- `allureId` - (optional) Allure TestOps test case ID for fetching precondition/expectedResult + +## Test Files + +| File | Description | +|------|-------------| +| `tests/import-wallet.yaml` | Import wallet with mnemonic | +| `tests/connect-disconnect.yaml` | Connect to dApp and disconnect | +| `tests/sign-data-test.yaml` | Sign data request (requires Allure) | + +## Flows (Reusable) + +| Flow | Description | +|------|-------------| +| `flows/unlock-wallet.yaml` | Unlock wallet with password | +| `flows/connect-wallet.yaml` | Connect to dApp via Tonkeeper | + +## Architecture + +``` +.maestro/ +├── config.ts # Test configuration +├── run-tests.ts # Test runner script +├── allure.ts # Allure TestOps API client +├── utils.ts # Utility functions +├── flows/ # Reusable Maestro flows +│ ├── unlock-wallet.yaml +│ └── connect-wallet.yaml +└── tests/ # Test files + ├── import-wallet.yaml + ├── connect-disconnect.yaml + └── sign-data-test.yaml +``` diff --git a/apps/demo-wallet-native/package.json b/apps/demo-wallet-native/package.json index dce86f15e..7cb1c19d3 100644 --- a/apps/demo-wallet-native/package.json +++ b/apps/demo-wallet-native/package.json @@ -7,7 +7,8 @@ "android": "expo run:android", "ios": "expo run:ios", "typecheck": "tsc --noEmit --emitDeclarationOnly false", - "clean": "git clean -xdf .cache .expo .turbo android ios node_modules" + "clean": "git clean -xdf .cache .expo .turbo android ios node_modules", + "e2e": "npx tsx .maestro/run-tests.ts" }, "dependencies": { "@craftzdog/react-native-buffer": "6.1.1", @@ -72,6 +73,7 @@ "devDependencies": { "@biomejs/biome": "2.3.2", "@types/react": "catalog:", + "dotenv": "^17.2.3", "typescript": "5.9.3", "ultracite": "6.1.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e738899c4..7cb475387 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -373,6 +373,9 @@ importers: '@types/react': specifier: 'catalog:' version: 19.1.17 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 typescript: specifier: 5.9.3 version: 5.9.3 From 72875d7558d8c94c9a9cd427bf4055aafce7d96a Mon Sep 17 00:00:00 2001 From: "V. K." Date: Thu, 11 Dec 2025 10:46:52 +0400 Subject: [PATCH 6/6] lint: fix lint errors --- .../src/app/(non-auth)/unlock-wallet.tsx | 14 ++++++++++++-- .../token-list-sheet/token-list-sheet.tsx | 3 +-- .../development-tools-section.tsx | 10 ---------- .../settings/hooks/use-deep-link-handler.ts | 1 - .../wallet-selector-modal.tsx | 3 +-- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx b/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx index 697e5b6b6..64a59c7c0 100644 --- a/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx +++ b/apps/demo-wallet-native/src/app/(non-auth)/unlock-wallet.tsx @@ -108,11 +108,21 @@ const UnlockWalletScreen: FC = () => { - + Continue - + Reset Wallet diff --git a/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx b/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx index 8283c63f1..f99407dc4 100644 --- a/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx +++ b/apps/demo-wallet-native/src/features/send/components/token-list-sheet/token-list-sheet.tsx @@ -6,10 +6,9 @@ * */ -import { Ionicons } from '@expo/vector-icons'; import type { FC } from 'react'; import { ScrollView, View } from 'react-native'; -import { StyleSheet, useUnistyles } from 'react-native-unistyles'; +import { StyleSheet } from 'react-native-unistyles'; import { useFormattedTonBalance, useJettons } from '@ton/demo-core'; import type { AddressJetton } from '@ton/walletkit'; diff --git a/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx b/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx index 579a9500d..a6ea1faf7 100644 --- a/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx +++ b/apps/demo-wallet-native/src/features/settings/components/development-tools-section/development-tools-section.tsx @@ -33,12 +33,6 @@ export const DevelopmentToolsSection: FC = () => { } }, [walletKit]); - const handleLogAllSessions = useCallback(async () => { - if (!walletKit) return; - - console.log('sessions', await walletKit.listSessions()); - }, [walletKit]); - return ( @@ -56,10 +50,6 @@ export const DevelopmentToolsSection: FC = () => { Disconnect All - - - Log Sessions - ); diff --git a/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts b/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts index 01f2619c8..b3c3059ab 100644 --- a/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts +++ b/apps/demo-wallet-native/src/features/settings/hooks/use-deep-link-handler.ts @@ -37,7 +37,6 @@ export const useDeepLinkHandler = (): void => { if (!url || isProcessingRef.current) return; const tonConnectUrl = extractTonConnectUrl(url); - console.log('tonConnectUrl', tonConnectUrl); if (!tonConnectUrl) { return; diff --git a/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx b/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx index 9acecf830..fc1958ec8 100644 --- a/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx +++ b/apps/demo-wallet-native/src/features/wallets/components/wallet-selector-modal/wallet-selector-modal.tsx @@ -9,12 +9,11 @@ import type { IWallet } from '@ton/walletkit'; import { useWallet } from '@ton/demo-core'; import type { FC } from 'react'; -import { ScrollView, View } from 'react-native'; +import { ScrollView } from 'react-native'; import { StyleSheet } from 'react-native-unistyles'; import { WalletInfoBlock } from '../wallet-info-block'; -import { AppBottomSheet } from '@/core/components/app-bottom-sheet'; import { ActiveTouchAction } from '@/core/components/active-touch-action'; import { AppModal } from '@/core/components/app-modal'; import { ScreenHeader } from '@/core/components/screen-header';