{"_id":"@alejandbel/ton-connect-ui","name":"@alejandbel/ton-connect-ui","dist-tags":{"latest":"2.4.2"},"versions":{"2.4.2":{"name":"@alejandbel/ton-connect-ui","version":"2.4.2","repository":{"type":"git","url":"git+https://github.com/Alejandbel/ton-connect-sdk.git"},"homepage":"https://github.com/Alejandbel/ton-connect-sdk/tree/main/packages/ui","bugs":{"url":"https://github.com/Alejandbel/ton-connect-sdk/issues"},"keywords":["TON","Wallet","ton-connect","tonconnect","Connect","Tonkeeper","sdk","UI"],"author":{"name":"tonconnect"},"license":"Apache-2.0","main":"./lib/index.cjs","module":"./lib/index.mjs","types":"./lib/index.d.ts","exports":{".":{"types":"./lib/index.d.ts","require":"./lib/index.cjs","import":"./lib/index.mjs","default":"./lib/index.cjs"}},"dependencies":{"classnames":"^2.5.1","csstype":"^3.1.3","deepmerge":"^4.3.1","ua-parser-js":"^1.0.35","@tonconnect/sdk":"npm:@alejandbel/ton-connect-sdk@3.4.1"},"devDependencies":{"@floating-ui/dom":"^1.7.3","@rollup/plugin-replace":"6.0.2","@solid-primitives/i18n":"^1.1.2","@types/node":"^24.2.0","@types/ua-parser-js":"^0.7.36","is-plain-object":"^5.0.0","jsdom":"^27.0.1","qrcode-generator":"^1.4.4","rollup":"^4.46.2","rollup-plugin-dts":"^6.2.1","solid-devtools":"^0.24.7","solid-floating-ui":"^0.3.1","solid-js":"^1.9.7","solid-styled-components":"^0.28.5","solid-transition-group":"^0.3.0","typescript":"^5.9.2","vite":"^7.0.6","vite-plugin-solid":"^2.11.8","vitest":"^3.2.4"},"typedoc":{"entryPoint":"./src/library.ts"},"scripts":{"start":"vite --host","dev":"vite","test":"vitest run","build":"tsc --noEmit --emitDeclarationOnly false && vite build && rollup -c rollup.config.mjs && vite build -c vite.cdn-config.ts"},"_id":"@alejandbel/ton-connect-ui@2.4.2","description":"TonConnect UI is a UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol.","_integrity":"sha512-KpxdpRta5pRDxLHcL3yu99ZXHLySBN4Mh9Lw6+pd+TYc751sTIaBepe36NoaGSb24cOaHmaZSb/A9gjt6q7Xiw==","_resolved":"/private/var/folders/h9/wfnrk3496fx8kcbxgcpnmwsm0000gn/T/9666b4ae84f18e42926cb686906e769f/alejandbel-ton-connect-ui-2.4.2.tgz","_from":"file:alejandbel-ton-connect-ui-2.4.2.tgz","_nodeVersion":"24.11.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-KpxdpRta5pRDxLHcL3yu99ZXHLySBN4Mh9Lw6+pd+TYc751sTIaBepe36NoaGSb24cOaHmaZSb/A9gjt6q7Xiw==","shasum":"ee5b5ab898dccaa5200f36500875dd693fd9d412","tarball":"https://registry.npmjs.org/@alejandbel/ton-connect-ui/-/ton-connect-ui-2.4.2.tgz","fileCount":10,"unpackedSize":5065628,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCXYo0yxcJQtR5Rp1JB5TINCzffhhQOAZkaWjiKK7e+BQIgTKHRoYCrWU1z1CWPTfn3dSmiT7Wi+Cp7A5fsh4Zy9pk="}]},"_npmUser":{"name":"a-bahdanau","email":"bogdanov28c@gmail.com"},"directories":{},"maintainers":[{"name":"a-bahdanau","email":"bogdanov28c@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ton-connect-ui_2.4.2_1773234457029_0.2800606706698503"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T13:07:36.925Z","2.4.2":"2026-03-11T13:07:37.210Z","modified":"2026-03-11T13:07:37.374Z"},"maintainers":[{"name":"a-bahdanau","email":"bogdanov28c@gmail.com"}],"description":"TonConnect UI is a UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol.","homepage":"https://github.com/Alejandbel/ton-connect-sdk/tree/main/packages/ui","keywords":["TON","Wallet","ton-connect","tonconnect","Connect","Tonkeeper","sdk","UI"],"repository":{"type":"git","url":"git+https://github.com/Alejandbel/ton-connect-sdk.git"},"author":{"name":"tonconnect"},"bugs":{"url":"https://github.com/Alejandbel/ton-connect-sdk/issues"},"license":"Apache-2.0","readme":"# TON Connect UI\n\nTonConnect UI is a UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol.\n\nIf you use React for your dapp, take a look at [TonConnect UI React kit](https://github.com/ton-connect/sdk/tree/main/packages/ui-react).\n\nIf you want to use TonConnect on the server side, you should use the [TonConnect SDK](https://github.com/ton-connect/sdk/tree/main/packages/sdk).\n\nYou can find more details and the protocol specification in the [docs](https://docs.ton.org/develop/dapps/ton-connect/overview).\n\n---\n\n[Latest API documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui.html)\n\n# Getting started\n\n## Installation with cdn\nAdd the script to your HTML file:\n```html\n<script src=\"https://unpkg.com/@tonconnect/ui@latest/dist/tonconnect-ui.min.js\"></script>\n```\n\nℹ️ If you don't want auto-update the library, pass concrete version instead of `latest`, e.g.\n```html\n<script src=\"https://unpkg.com/@tonconnect/ui@0.0.9/dist/tonconnect-ui.min.js\"></script>\n```\n\nYou can find `TonConnectUI` in global variable `TON_CONNECT_UI`, e.g.\n```html\n<script>\n    const tonConnectUI = new TON_CONNECT_UI.TonConnectUI({\n        manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n        buttonRootId: '<YOUR_CONNECT_BUTTON_ANCHOR_ID>'\n    });\n</script>\n```\n\n\n## Installation with npm\n`npm i @tonconnect/ui`\n\n# Usage\n\n## Create TonConnectUI instance\n```ts\nimport { TonConnectUI } from '@tonconnect/ui'\n\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    buttonRootId: '<YOUR_CONNECT_BUTTON_ANCHOR_ID>'\n});\n```\n\nYou can also specify required wallet features to filter wallets that will be shown in the connect wallet modal:\n\n```ts\nimport { TonConnectUI } from '@tonconnect/ui'\n\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    buttonRootId: '<YOUR_CONNECT_BUTTON_ANCHOR_ID>',\n    walletsRequiredFeatures: {\n        sendTransaction: {\n            minMessages: 2, // Wallet must support at least 2 messages\n            extraCurrencyRequired: true // Wallet must support extra currency\n        }\n    }\n});\n```\n\nThis will filter out wallets that don't support sending multiple messages or don't support extra currencies.\n\nYou can also specify preferred wallet features to prioritize wallets that support them in the connect wallet modal. These wallets will be shown first in the list, but others will still be available:\n\n```ts\nimport { TonConnectUI } from '@tonconnect/ui'\n\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    buttonRootId: '<YOUR_CONNECT_BUTTON_ANCHOR_ID>',\n    walletsPreferredFeatures: {\n        sendTransaction: {\n            minMessages: 2,\n            extraCurrencyRequired: true\n        }\n    }\n});\n```\n\nThis will highlight wallets that support sending multiple messages and extra currencies, but won’t hide those that don’t. Use this to gently recommend more feature-rich wallets without excluding others.\n\n### Analytics\n\nYou can configure analytics collection when creating TonConnectUI:\n\n```ts\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    analytics: { mode: 'off' } // or 'telemetry' (default), 'full'\n});\n```\n\n**Analytics modes:**\n\n| Mode                    | Description                                                |\n|-------------------------|------------------------------------------------------------|\n| **off**                 | Analytics turned off. No events are collected or sent.     |\n| **telemetry** (default) | Analytics used for technical research and issue debugging. |\n| **full**                | Full analytics events.                                     |\n\nSee all available options:\n\n[TonConnectUiOptionsWithManifest](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.TonConnectUiOptionsWithManifest.html)\n\n[TonConnectUiOptionsWithConnector](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.TonConnectUiOptionsWithConnector.html)\n\n## Change options if needed \n```ts\ntonConnectUI.uiOptions = {\n    language: 'ru',\n    uiPreferences: {\n        theme: THEME.DARK\n    }\n};\n```\n\nUI element will be rerendered after assignation. You should pass only options that you want to change.\nPassed options will be merged with current UI options. Note, that you have to pass object to `tonConnectUI.uiOptions` to keep reactivity.\n\nDON'T do this:\n```ts\n/* WRONG, WILL NOT WORK */ tonConnectUI.uiOptions.language = 'ru'; \n```\n\n[See all available options](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.TonConnectUiOptions.html)\n\n## Fetch wallets list\n```ts\nconst walletsList = await tonConnectUI.getWallets();\n\n/* walletsList is \n{\n    name: string;\n    imageUrl: string;\n    tondns?: string;\n    aboutUrl: string;\n    universalLink?: string;\n    deepLink?: string;\n    bridgeUrl?: string;\n    jsBridgeKey?: string;\n    injected?: boolean; // true if this wallet is injected to the webpage\n    embedded?: boolean; // true if the dapp is opened inside this wallet's browser\n}[] \n */\n```\n\nor\n\n```ts\nconst walletsList = await TonConnectUI.getWallets();\n```\n\n## Open connect modal\n\"TonConnect UI connect button\" (which is added at `buttonRootId`) automatically handles clicks and calls connect.\nBut you are still able to open \"connect modal\" programmatically, e.g. after click on your custom connect button.\n\n```ts\nawait tonConnectUI.openModal();\n```\n\nThis method opens the modal window and returns a promise that resolves after the modal window is opened.\n\nIf there is an error while modal opening, `TonConnectUIError` or `TonConnectError` will be thrown depends on situation.\n\n## Close connect modal\n\n```ts\ntonConnectUI.closeModal();\n```\n\nThis method closes the modal window.\n\n## Get current modal state\n\nThis getter returns the current state of the modal window. The state will be an object with `status` and `closeReason` properties. The `status` can be either 'opened' or 'closed'. If the modal is closed, you can check the `closeReason` to find out the reason of closing.\n\n```ts\nconst currentModalState = tonConnectUI.modalState;\n```\n\n## Subscribe to the modal window state changes\nTo subscribe to the changes of the modal window state, you can use the `onModalStateChange` method. It returns a function which has to be called to unsubscribe.\n\n```js\nconst unsubscribeModal = tonConnectUI.onModalStateChange(\n    (state: WalletsModalState) => {\n        // update state/reactive variables to show updates in the ui\n        // state.status will be 'opened' or 'closed'\n        // if state.status is 'closed', you can check state.closeReason to find out the reason\n    }\n);\n```\n\nCall `unsubscribeModal()` later to save resources when you don't need to listen for updates anymore.\n\n## Wallets Modal Control\n\nThe `tonConnectUI` provides methods for managing the modal window, such as `openModal()`, `closeModal()` and other, which are designed for ease of use and cover most use cases.\n\n```typescript\nconst { modal } = tonConnectUI;\n\n// Open and close the modal\nawait modal.open();\nmodal.close();\n\n// Get the current modal state\nconst currentState = modal.state;\n\n// Subscribe and unsubscribe to modal state changes\nconst unsubscribe = modal.onStateChange(state => { /* ... */ });\nunsubscribe();\n```\n\nWhile `tonConnectUI` internally delegates these calls to the `modal`, it is recommended to use the `tonConnectUI` methods for a more straightforward and consistent experience. The `modal` is exposed in case you need direct access to the modal window's state and behavior, but this should generally be avoided unless necessary.\n\n## Open specific wallet\n\n> The methods described in this section are marked as experimental and are subject to change in future releases.\n\nTo open a modal window for a specific wallet, use the `openSingleWalletModal()` method. This method accepts the wallet `app_name` as a parameter (please refer to the [wallets-list.json](https://config.ton.org/wallets-v2.json)) and opens the corresponding wallet modal. It returns a promise that resolves after the modal window is successfully opened.\n\n```typescript\nawait tonConnectUI.openSingleWalletModal('wallet_identifier');\n````\n\nTo close the currently open specific wallet modal, use the `closeSingleWalletModal()` method:\n\n```typescript\ntonConnectUI.closeSingleWalletModal();\n```\n\nTo subscribe to the state changes of the specific wallet modal, use the `onSingleWalletModalStateChange((state) => {})` method. It accepts a callback function that will be called with the current modal state.\n\n```typescript\nconst unsubscribe = tonConnectUI.onSingleWalletModalStateChange((state) => {\n    console.log('Modal state changed:', state);\n});\n\n// Call `unsubscribe` when you want to stop listening to the state changes\nunsubscribe();\n````\n\nTo get the current state of the specific wallet modal window, use the `singleWalletModalState` property:\n\n```typescript\nconst currentState = tonConnectUI.singleWalletModalState;\nconsole.log('Current modal state:', currentState);\n```\n\n## Get current connected Wallet and WalletInfo\nYou can use special getters to read current connection state. Note that this getter only represents current value, so they are not reactive. \nTo react and handle wallet changes use `onStatusChange` method.\n\n```ts\nconst currentWallet = tonConnectUI.wallet;\nconst currentWalletInfo = tonConnectUI.walletInfo;\nconst currentAccount = tonConnectUI.account;\nconst currentIsConnectedStatus = tonConnectUI.connected;\n```\n\n## Subscribe to the connection status changes\n\nTo subscribe to the changes of the connection status, you can use the `onStatusChange` method. It returns a function which has to be called to unsubscribe.\n\n```ts\nconst unsubscribe = tonConnectUI.onStatusChange(\n    walletAndwalletInfo => {\n        // update state/reactive variables to show updates in the ui\n    } \n);\n```\n\nCall `unsubscribe()` later to save resources when you don't need to listen for updates anymore.\n\n## Disconnect wallet\nCall to disconnect the wallet.\n\n```ts\nawait tonConnectUI.disconnect();\n```\n\n## Send transaction\nWallet must be connected when you call `sendTransaction`. Otherwise, an error will be thrown.\n\n```ts\nconst transaction = {\n    validUntil: Math.floor(Date.now() / 1000) + 60, // 60 sec\n    messages: [\n        {\n            address: \"EQBBJBB3HagsujBqVfqeDUPJ0kXjgTPLWPFFffuNXNiJL0aA\",\n            amount: \"20000000\",\n         // stateInit: \"base64bocblahblahblah==\" // just for instance. Replace with your transaction initState or remove\n        },\n        {\n            address: \"EQDmnxDMhId6v1Ofg_h5KR5coWlFG6e86Ro3pc7Tq4CA0-Jn\",\n            amount: \"60000000\",\n         // payload: \"base64bocblahblahblah==\" // just for instance. Replace with your transaction payload or remove\n        }\n    ]\n};\n\n// you can also include extra currencies in your transaction\nconst transactionWithExtraCurrency = {\n    validUntil: Math.floor(Date.now() / 1000) + 60,\n    messages: [\n        {\n            address: \"EQBBJBB3HagsujBqVfqeDUPJ0kXjgTPLWPFFffuNXNiJL0aA\",\n            // Specify the extra currency\n            extraCurrency: {\n                100: \"10000000\"\n            }\n        }\n    ]\n};\n\ntry {\n    const result = await tonConnectUI.sendTransaction(transaction);\n\n    // you can use signed boc to find the transaction \n    const someTxData = await myAppExplorerService.getTransaction(result.boc);\n    alert('Transaction was sent successfully', someTxData);\n} catch (e) {\n    console.error(e);\n}\n```\n\n### Trace ID for analytics\n\nYou can pass a custom trace ID to track the transaction through your analytics:\n\n```ts\nconst result = await tonConnectUI.sendTransaction(transaction, {\n    traceId: '019a2a92-a884-7cfc-b1bc-caab18644b6f' // optional, UUIDv7 auto-generated if not provided\n});\n\nconsole.log(result.traceId); // use this ID to correlate with analytics events\n```\n\n`sendTransaction` will automatically render informational modals and notifications. You can change its behaviour:\n\n```ts\nconst result = await tonConnectUI.sendTransaction(defaultTx, {\n    modals: ['before', 'success', 'error'],\n    notifications: ['before', 'success', 'error']\n});\n```\n\nDefault configuration is: \n```ts\nconst defaultBehaviour = {\n    modals: ['before'],\n    notifications: ['before', 'success', 'error']\n}\n```\n\nYou can also modify this behaviour for all actions calls using `uiOptions` setter:\n```ts\ntonConnectUI.uiOptions = {\n        actionsConfiguration: {\n            modals: ['before', 'success', 'error'],\n            notifications: ['before', 'success', 'error']\n        }\n    };\n```\n\n## Sign data\n\nSign arbitrary data with the user's wallet. The wallet will display the data to the user for confirmation before signing. Wallet must be connected when you call `signData`, otherwise an error will be thrown.\n\n### Data Types\n\nYou can sign three types of data. Choose the right format based on your use case:\n\n- **Text** - Use for human-readable text that users should see and understand\n- **Cell** - Use for TON Blockchain data that should be used in smart contracts (wallet may show unknown content warning)  \n- **Binary** - For other arbitrary data (least preferred due to security warnings)\n\n#### Text Format\n\nUse when you need to sign human-readable text. The wallet displays the text to the user.\n\n**Parameters:**\n- `type` (string, required): Must be `\"text\"`\n- `text` (string, required): UTF-8 text to sign\n- `network` (string, optional): `\"-239\"` for mainnet, `\"-3\"` for testnet\n- `from` (string, optional): Signer address in raw format `\"0:<hex>\"`\n\n```ts\nconst textData = {\n    type: \"text\",\n    text: \"Confirm new 2fa number:\\n+1 234 567 8901\",\n    network: \"-239\", // MAINNET = '-239', TESTNET = '-3'\n    from: \"0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f\"\n};\n\ntry {\n    const result = await tonConnectUI.signData(textData);\n    console.log('Signed:', result);\n} catch (e) {\n    console.error('Error:', e);\n}\n```\n\nYou can also pass a trace ID to correlate with analytics:\n\n```ts\nconst result = await tonConnectUI.signData(textData, {\n    traceId: '019a2a92-a884-7cfc-b1bc-caab18644b6f' // optional, UUIDv7 auto-generated if not provided\n});\n\nconsole.log(result.traceId); // use this ID to correlate with analytics events\n```\n\n#### Binary Format\n\nUse for arbitrary binary data. The wallet shows a warning about unknown content.\n\n**Parameters:**\n- `type` (string, required): Must be `\"binary\"`\n- `bytes` (string, required): Base64 encoded binary data (not url-safe)\n- `network` (string, optional): `\"-239\"` for mainnet, `\"-3\"` for testnet\n- `from` (string, optional): Signer address in raw format `\"0:<hex>\"`\n\n```ts\nconst binaryData = {\n    type: \"binary\",\n    bytes: \"1Z/SGh+3HFMKlVHSkN91DpcCzT4C5jzHT3sA/24C5A==\",\n    network: \"-239\", // MAINNET = '-239', TESTNET = '-3'\n    from: \"0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f\"\n};\n\ntry {\n    const result = await tonConnectUI.signData(binaryData);\n    console.log('Signed:', result);\n} catch (e) {\n    console.error('Error:', e);\n}\n```\n\n#### Cell Format\n\nUse for TON Blockchain data with TL-B schema. The wallet can parse and display the content if the schema is valid.\n\n**Parameters:**\n- `type` (string, required): Must be `\"cell\"`\n- `schema` (string, required): TL-B schema of the cell payload\n- `cell` (string, required): Base64 encoded BoC (not url-safe) with single-root cell\n- `network` (string, optional): `\"-239\"` for mainnet, `\"-3\"` for testnet\n- `from` (string, optional): Signer address in raw format `\"0:<hex>\"`\n\n```ts\nconst cellData = {\n    type: \"cell\",\n    schema: \"transfer#0f8a7ea5 query_id:uint64 amount:(VarUInteger 16) destination:MsgAddress response_destination:MsgAddress custom_payload:(Maybe ^Cell) forward_ton_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) = InternalMsgBody;\",\n    cell: \"te6ccgEBAQEAVwAAqg+KfqVUbeTvKqB4h0AcnDgIAZucsOi6TLrfP6FcuPKEeTI6oB3fF/NBjyqtdov/KtutACCLqvfmyV9kH+Pyo5lcsrJzJDzjBJK6fd+ZnbFQe4+XggI=\",\n    network: \"-239\", // MAINNET = '-239', TESTNET = '-3'\n    from: \"0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f\"\n};\n\ntry {\n    const result = await tonConnectUI.signData(cellData);\n    console.log('Signed:', result);\n} catch (e) {\n    console.error('Error:', e);\n}\n```\n\n### Response\n\nAll signData calls return the same response structure:\n\n```ts\ninterface SignDataResult {\n    signature: string; // Base64 encoded signature\n    address: string;   // Wallet address in raw format\n    timestamp: number; // UNIX timestamp in seconds (UTC)\n    domain: string;    // App domain name \n    payload: object;   // Original payload from the request\n}\n```\n\n### Signature Verification\n\nAfter receiving the signed data, you need to verify the signature to ensure it's authentic and was signed by the claimed wallet address.\n\n**For backend verification:** See [TypeScript verification example](https://github.com/ton-connect/demo-dapp-with-react-ui/blob/master/src/server/services/sign-data-service.ts#L32-L109) showing how to verify signatures on your server.\n\n**For smart contract verification:** See [FunC verification example](https://github.com/p0lunin/sign-data-contract-verify-example/blob/master/contracts/sign_data_example.fc) showing how to verify signatures in TON smart contracts.\n\n**For complete technical details:** See the [Sign Data specification](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#sign-data) for full signature verification requirements.\n\n## Universal links redirecting issues (IOS)\nSome operating systems, and especially iOS, have restrictions related to universal link usage. \nFor instance, if you try to open a universal link on an iOS device via `window.open`, you can face the following problem:\nthe mobile browser won't redirect the user to the wallet app and will open the fallback tab instead. \nThat's because universal links can only be opened synchronously after a user's action in the browser (button click/...). \nThis means that you either can't perform any asynchronous requests after the user clicks an action button in your dapp, either you can't redirect the user to the connected wallet on some devices.\n\nSo, by default, if the user's operating system is iOS, they won't be automatically redirected to the wallet after the dapp calls `tonConnectUI.sendTransaction`. \nYou can change this behavior using the skipRedirectToWallet option:\n\n```ts\nconst result = await tonConnectUI.sendTransaction(defaultTx, {\n    modals: ['before', 'success', 'error'],\n    notifications: ['before', 'success', 'error'],\n    skipRedirectToWallet: 'ios' //'ios' (default), or 'never', or 'always'\n});\n```\n\n<details>\n<summary>You can set it globally with `uiOptions` setter, and it will be applied for all actions (send transaction/...).</summary>\n\n```ts\ntonConnectUI.uiOptions = {\n        actionsConfiguration: {\n            skipRedirectToWallet: 'ios'\n        }\n    };\n```\n\n</details>\n\n<details>\n<summary>You should use the option `'never'` if there are no any async calls in the action button's click handler before `tonConnectUI.sendTransaction` call</summary>\n\n```ts\n// use skipRedirectToWallet: 'never' for better UX\nconst onClick = async ()  => {\n    const txBody = packTxBodySynchrone();\n    tonConnectUI.sendTransaction(txBody, { skipRedirectToWallet: 'never' });\n\n    const myApiResponse = await notifyBackend();\n    //...\n}\n```\n\n```ts\n// DON'T use skipRedirectToWallet: 'never', you should use skipRedirectToWallet: 'ios' \nconst onClick = async ()  => {\n    const myApiResponse = await notifyBackend();\n    \n    const txBody = packTxBodySynchrone();\n    tonConnectUI.sendTransaction(txBody, { skipRedirectToWallet: 'ios' });\n    //...\n}\n```\n</details>\n\n## Add the return strategy\n\nReturn strategy (optional) specifies return strategy for the deeplink when user signs/declines the request.\n\n'back' (default) means return to the app which initialized deeplink jump (e.g. browser, native app, ...),\n'none' means no jumps after user action;\na URL: wallet will open this URL after completing the user's action. Note, that you shouldn't pass your app's URL if it is a webpage. This option should be used for native apps to work around possible OS-specific issues with 'back' option.\n\nYou can set it globally with `uiOptions` setter, and it will be applied for connect request and all subsequent actions (send transaction/...).\n\n```ts\ntonConnectUI.uiOptions = {\n        actionsConfiguration: {\n            returnStrategy: 'none'\n        }\n    };\n```\n\nOr you can set it directly when you send a transaction (will be applied only for this transaction request)\n```ts\nconst result = await tonConnectUI.sendTransaction(defaultTx, {\n    returnStrategy: '<protocol>://<your_return_url>' // Note, that you shouldn't pass your app's URL if it is a webpage.\n     // This option should be used for native apps to work around possible OS-specific issues with 'back' option.\n});\n```\n\n## Use inside TMA (Telegram Mini Apps)\nTonConnect UI will work in TMA in the same way as in a regular website!\nBasically, no changes are required from the dApp's developers. The only thing you have to set is a dynamic return strategy.\n\nCurrently, it is impossible for TMA-wallets to redirect back to previous opened TMA-dApp like native wallet-apps do.\nIt means, that you need to specify the return strategy as a link to your TMA that will be only applied if the dApp is opened in TMA mode.\n\n```ts\ntonConnectUI.uiOptions = {\n    twaReturnUrl: 'https://t.me/durov'\n};\n```\n\nIn other words, TonConnect UI will automatically handle the return strategy based on the environment. **The following pseudo-code demonstrates the internal logic of TonConnect UI**:\n\n> Please note that you **don't need to add this code to your dApp**. It's just an example of how TonConnect UI processes the return strategy internally.\n\n```ts\nlet finalReturnStrategy;\n\n// Determine if the provided link opens Telegram (using protocols tg:// or domain t.me).\nif (isLinkToTelegram('https://example.com')) {\n    // In the Telegram Mini Apps environment,\n    if (isInTWA()) {\n        // preference is given to 'twaReturnUrl',\n        finalReturnStrategy = actionsConfiguration.twaReturnUrl;\n\n        // but if it's not set, fallback to 'returnStrategy'.\n        if (!finalReturnStrategy) {\n            finalReturnStrategy = actionsConfiguration.returnStrategy;\n        }\n    }\n    // If not in a TMA environment,\n    else {\n        // the return strategy is set to 'none'.\n        finalReturnStrategy = 'none';\n    }\n}\n// When the link does not open Telegram,\nelse {\n    // use the predefined 'returnStrategy'.\n    finalReturnStrategy = actionsConfiguration.returnStrategy;\n}\n\n// Now, 'finalReturnStrategy' contains the correct strategy based on the link's destination and the dApp's environment.\n```\n\n## Detect end of the connection restoring process\nBefore restoring previous connected wallet TonConnect has to set up SSE connection with bridge, so you have to wait a little while connection restoring.\nIf you need to update your UI depending on if connection is restoring, you can use `tonConnectUI.connectionRestored` promise.\n\nPromise that resolves after end of th connection restoring process (promise will fire after `onStatusChange`, so you can get actual information about wallet and session after when promise resolved).\nResolved value `true`/`false` indicates if the session was restored successfully.\n\n\n```ts\ntonConnectUI.connectionRestored.then(restored => {\n    if (restored) {\n        console.log(\n            'Connection restored. Wallet:',\n            JSON.stringify({\n                ...tonConnectUI.wallet,\n                ...tonConnectUI.walletInfo\n            })\n        );\n    } else {\n        console.log('Connection was not restored.');\n    }\n});\n```\n\n## UI customisation\nTonConnect UI provides an interface that should be familiar and recognizable to the user when using various apps. \nHowever, the app developer can make changes to this interface to keep it consistent with the app interface.\n\n### Customise UI using tonconnectUI.uiOptions\nAll such updates are reactive -- change `tonconnectUI.uiOptions` and changes will be applied immediately.  \n\n[See all available options](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.UIPreferences.html)\n\n#### Change border radius\nThere are three border-radius modes: `'m'`, `'s'` and `'none'`. Default is `'m'`. You can change it via tonconnectUI.uiOptions, or set on tonConnectUI creating:\n\n```ts\n/* Pass to the constructor */\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    uiPreferences: {\n        borderRadius: 's'\n    }\n});\n\n\n/* Or update dynamically */\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            borderRadius: 's'\n        }\n    };\n```\n\nNote, that `uiOptions` is a setter which will merge new options with previous ones. So you doesn't need to merge it explicitly. Just pass changed options.\n```ts\n/* DON'T DO THIS. SEE DESCRIPTION ABOVE */\ntonConnectUI.uiOptions = {\n        ...previousUIOptions,\n        uiPreferences: {\n            borderRadius: 's'\n        }\n    };\n\n/* Just pass changed property */\ntonConnectUI.uiOptions = {\n    uiPreferences: {\n        borderRadius: 's'\n    }\n};\n```\n\n#### Change theme\nYou can set fixed theme: `'THEME.LIGHT'` or `'THEME.DARK'`, or use system theme. Default theme is system.\n\n```ts\nimport { THEME } from '@tonconnect/ui';\n\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            theme: THEME.DARK\n        }\n    };\n```\n\nYou also can set `'SYSTEM'` theme:\n```ts\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            theme: 'SYSTEM'\n        }\n    };\n```\n\nYou can set theme in the constructor if needed:\n```ts\nimport { THEME } from '@tonconnect/ui';\n\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    uiPreferences: {\n        theme: THEME.DARK\n    }\n});\n```\n\n#### Change colors scheme\nYou can redefine all colors scheme for each theme or change some colors. Just pass colors that you want to change.\n\n```ts\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            colorsSet: {\n                [THEME.DARK]: {\n                    connectButton: {\n                        background: '#29CC6A'\n                    }\n                }\n            }\n        }\n    };\n```\n\nYou can change colors for both themes at the same time:\n\n```ts\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            colorsSet: {\n                [THEME.DARK]: {\n                    connectButton: {\n                        background: '#29CC6A'\n                    }\n                },\n                [THEME.LIGHT]: {\n                    text: {\n                        primary: '#FF0000'\n                    }\n                }\n            }\n        }\n    };\n\n```\n\nYou can set colors scheme in the constructor if needed:\n```ts\nimport { THEME } from '@tonconnect/ui';\n\nconst tonConnectUI = new TonConnectUI({\n    manifestUrl: 'https://<YOUR_APP_URL>/tonconnect-manifest.json',\n    uiPreferences: {\n        colorsSet: {\n            [THEME.DARK]: {\n                connectButton: {\n                    background: '#29CC6A'\n                }\n            }\n        }\n    }\n});\n```\n\n[See all available options](https://ton-connect.github.io/sdk/interfaces/_tonconnect_ui.PartialColorsSet.html)\n\n#### Combine options\nIt is possible to change all required options at the same time:\n\n```ts\ntonConnectUI.uiOptions = {\n        uiPreferences: {\n            theme: THEME.DARK,\n            borderRadius: 's',\n            colorsSet: {\n                [THEME.DARK]: {\n                    connectButton: {\n                        background: '#29CC6A'\n                    }\n                },\n                [THEME.LIGHT]: {\n                    text: {\n                        primary: '#FF0000'\n                    }\n                }\n            }\n        }\n    };\n```\n\n\n### Direct css customisation\nIt is not recommended to customise TonConnect UI elements via css as it may confuse the user when looking for known and familiar UI elements such as connect button/modals.\nHowever, it is possible if needed. You can add css styles to the specified selectors of the UI element. See list of selectors in the table below:\n\nUI components:\n\n| Element                              | Selector                                            | Element description                                                                                                   |\n|--------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|\n| Connect wallet modal container       | `[data-tc-wallets-modal-container=\"true\"]`          | Container of the modal window that opens when you click on the \"connect wallet\" button.                               |\n| Mobile universal modal page content  | `[data-tc-wallets-modal-universal-mobile=\"true\"]`   | Content of the general mobile modal page with horizontal list.                                                        |\n| Desktop universal modal page content | `[data-tc-wallets-modal-universal-desktop=\"true\"]`  | Content of the universal desktop modal page with QR.                                                                  |\n| Mobile selected wallet's modal page  | `[data-tc-wallets-modal-connection-mobile=\"true\"]`  | Content of the selected wallet's modal page on mobile.                                                                |\n| Desktop selected wallet's modal page | `[data-tc-wallets-modal-connection-desktop=\"true\"]` | Content of the selected wallet's modal page on desktop.                                                               |\n| Wallets list modal page              | `[data-tc-wallets-modal-list=\"true\"]`               | Content of the modal page with all available wallets list (desktop and mobile).                                       |\n| Info modal page                      | `[data-tc-wallets-modal-info=\"true\"]`               | Content of the modal page with \"What is a wallet information\".                                                        |\n| Action modal container               | `[data-tc-actions-modal-container=\"true\"]`          | Container of the modal window that opens when you call `sendTransaction` or other action.                             |\n| Confirm transaction modal content    | `[data-tc-confirm-modal=\"true\"]`                    | Content of the modal window asking for confirmation of the action in the wallet.                                      |\n| \"Transaction sent\" modal content     | `[data-tc-transaction-sent-modal=\"true\"]`           | Content of the modal window informing that the transaction was successfully sent.                                     |\n| \"Transaction canceled\" modal content | `[data-tc-transaction-canceled-modal=\"true\"]`       | Content of the modal window informing that the transaction was not sent.                                              |\n| Confirm sign data modal              | `[data-tc-sign-data-confirm-modal=\"true\"]`          | Content of the modal window asking for confirmation of the signing data in the wallet.                                |\n| \"Sign data canceled\" moda l          | `[data-tc-notification-sign-data-cancelled=\"true\"]` | Content of the modal window informing that the signing data was not confirmed.                                        |\n| \"Sign data error\" modal              | `[data-tc-notification-sign-data-error=\"true\"]`     | Content of the modal window informing that the signing data was not confirmed due to an error.                        |\n| \"Connect Wallet\" button              | `[data-tc-connect-button=\"true\"]`                   | \"Connect Wallet\" button element.                                                                                      |\n| Wallet menu loading button           | `[data-tc-connect-button-loading=\"true\"]`           | Button element which appears instead of \"Connect Wallet\" and dropdown menu buttons while restoring connection process |\n| Wallet menu dropdown button          | `[data-tc-dropdown-button=\"true\"]`                  | Wallet menu button -- host of the dropdown wallet menu (copy address/disconnect).                                     |\n| Wallet menu dropdown container       | `[data-tc-dropdown-container=\"true\"]`               | Container of the dropdown that opens when you click on the \"wallet menu\" button with ton address.                     |\n| Wallet menu dropdown content         | `[data-tc-dropdown=\"true\"]`                         | Content of the dropdown that opens when you click on the \"wallet menu\" button with ton address.                       |\n| Notifications container              | `[data-tc-list-notifications=\"true\"]`               | Container of the actions notifications.                                                                               |\n| Notification confirm                 | `[data-tc-notification-confirm=\"true\"]`             | Confirmation notification element.                                                                                    |\n| Notification tx sent                 | `[data-tc-notification-tx-sent=\"true\"]`             | Transaction sent notification element.                                                                                |\n| Notification cancelled tx            | `[data-tc-notification-tx-cancelled=\"true\"]`        | Cancelled transaction notification element.                                                                           |\n\n---\n\nBasic UI elements:\n\n| Element                        | Selector                        |\n|--------------------------------|---------------------------------|\n| Button                         | `[data-tc-button=\"true\"]`       |\n| Icon-button                    | `[data-tc-icon-button=\"true\"]`  |\n| Modal window                   | `[data-tc-modal=\"true\"]`        |\n| Notification                   | `[data-tc-notification=\"true\"]` |\n| Tab bar                        | `[data-tc-tab-bar=\"true\"]`      |\n| H1                             | `[data-tc-h1=\"true\"]`           |\n| H2                             | `[data-tc-h2=\"true\"]`           |\n| H3                             | `[data-tc-h3=\"true\"]`           |\n| Text                           | `[data-tc-text=\"true\"]`         |\n| Wallet-item                    | `[data-tc-wallet-item=\"true\"]`  |\n\n\n## Customize the list of displayed wallets\nYou can customize the list of displayed wallets: change order, exclude wallets or add custom wallets.\n\n\n### Extend wallets list\nPass custom wallets array to extend the wallets list. Passed wallets will be added to the end of the original wallets list.  \n\nYou can define custom wallet with `jsBridgeKey` (wallet = browser extension or there is a wallet dapp browser) or with `bridgeUrl` and `universalLink` pair (for http-connection compatible wallets), or pass all of these properties. \n```ts\nimport { UIWallet } from '@tonconnect/ui';\n\nconst customWallet: UIWallet = {\n    name: '<CUSTOM_WALLET_NAME>',\n    imageUrl: '<CUSTOM_WALLET_IMAGE_URL>',\n    aboutUrl: '<CUSTOM_WALLET_ABOUT_URL>',\n    jsBridgeKey: '<CUSTOM_WALLET_JS_BRIDGE_KEY>',\n    bridgeUrl: '<CUSTOM_WALLET_HTTP_BRIDGE_URL>',\n    universalLink: '<CUSTOM_WALLET_UNIVERSAL_LINK>'\n};\n\ntonConnectUI.uiOptions = {\n    walletsListConfiguration: {\n        includeWallets: [customWallet]\n    }\n}\n```\n\n## Add connect request parameters (ton_proof)\nUse `tonConnectUI.setConnectRequestParameters` function to pass your connect request parameters.\n\nThis function takes one parameter:\n\nSet state to 'loading' while you are waiting for the response from your backend. If user opens connect wallet modal at this moment, he will see a loader.\n```ts\ntonConnectUI.setConnectRequestParameters({\n    state: 'loading'\n});\n```\n\nor\n\nSet state to 'ready' and define `tonProof` value. Passed parameter will be applied to the connect request (QR and universal link).\n```ts\ntonConnectUI.setConnectRequestParameters({\n    state: 'ready',\n    value: {\n        tonProof: '<your-proof-payload>'\n    }\n});\n```\n\nor \n\nRemove loader if it was enabled via `state: 'loading'` (e.g. you received an error instead of a response from your backend). Connect request will be created without any additional parameters.\n```ts\ntonConnectUI.setConnectRequestParameters(null);\n```\n\n\nYou can call `tonConnectUI.setConnectRequestParameters` multiple times if your tonProof payload has bounded lifetime (e.g. you can refresh connect request parameters every 10 minutes). \n\n\n```ts\n// enable ui loader\ntonConnectUI.setConnectRequestParameters({ state: 'loading' });\n\n// fetch you tonProofPayload from the backend\nconst tonProofPayload: string | null = await fetchTonProofPayloadFromBackend();\n\nif (!tonProofPayload) {\n    // remove loader, connect request will be without any additional parameters\n    tonConnectUI.setConnectRequestParameters(null);\n} else {\n    // add tonProof to the connect request\n    tonConnectUI.setConnectRequestParameters({\n        state: \"ready\",\n        value: { tonProof: tonProofPayload }\n    });\n}\n\n```\n\n\nYou can find `ton_proof` result in the `wallet` object when wallet will be connected:\n```ts\ntonConnectUI.onStatusChange(wallet => {\n        if (wallet && wallet.connectItems?.tonProof && 'proof' in wallet.connectItems.tonProof) {\n            checkProofInYourBackend(wallet.connectItems.tonProof.proof);\n        }\n    });\n```\n\n## Network selection\n\nYou can specify the desired network before connecting to a wallet using the `setConnectionNetwork()` method. If the wallet connects to a different network, the connection will be aborted with a `WalletWrongNetworkError`.\n\n```ts\nimport { CHAIN } from '@tonconnect/ui';\n\n// Set desired network before connecting\ntonConnectUI.setConnectionNetwork(CHAIN.MAINNET); // or CHAIN.TESTNET, or any custom chainId string\n\n// Allow any network (default behavior)\ntonConnectUI.setConnectionNetwork(undefined);\n```\n\n**Important:** \n- Network must be set before calling `connectWallet()` or opening the wallet selection modal. Attempting to change network while connected will throw an error.\n- Network validation is also performed for `sendTransaction` and `signData` operations if a network was specified.\n\n# Tracking\n\n## Track events\n\nTracker for TonConnect user actions, such as transaction signing, connection, etc.\n\nList of events:\n* `connection-started`: when a user starts connecting a wallet.\n* `connection-completed`: when a user successfully connected a wallet.\n* `connection-error`: when a user cancels a connection or there is an error during the connection process.\n* `connection-restoring-started`: when the dApp starts restoring a connection.\n* `connection-restoring-completed`: when the dApp successfully restores a connection.\n* `connection-restoring-error`: when the dApp fails to restore a connection.\n* `disconnection`: when a user starts disconnecting a wallet.\n* `transaction-sent-for-signature`: when a user sends a transaction for signature.\n* `transaction-signed`: when a user successfully signs a transaction.\n* `transaction-signing-failed`: when a user cancels transaction signing or there is an error during the signing process.\n* `sign-data-request-initiated`: when a user sends data for signing.\n* `sign-data-request-completed` when a user successfully signs data.\n* `sign-data-request-failed`: when a user cancels data signing or there is an error during the signing process.\n\nIf you want to track user actions, you can subscribe to the window events with prefix `ton-connect-ui-`:\n\n```typescript\nwindow.addEventListener('ton-connect-ui-transaction-sent-for-signature', (event) => {\n    console.log('Transaction init', event.detail);\n});\n```\n\n## Use custom event dispatcher\n\nYou can use your custom event dispatcher to track user actions. To do this, you need to pass the `eventDispatcher` to the TonConnect constructor:\n\n```typescript\nimport { TonConnectUI, EventDispatcher, SdkActionEvent, UserActionEvent } from '@tonconnect/ui';\n\nclass CustomEventDispatcher implements EventDispatcher<UserActionEvent | SdkActionEvent> {\n    public async dispatchEvent(\n      eventName: string,\n      eventDetails: UserActionEvent | SdkActionEvent\n    ): Promise<void> {\n        console.log(`Event: ${eventName}, details:`, eventDetails);\n    }\n}\n\nconst eventDispatcher = new CustomEventDispatcher();\n\nconst connector = new TonConnectUI({ eventDispatcher });\n```\n\n# Troubleshooting\n\n## Android Back Handler\n\nIf you encounter any issues with the Android back handler, such as modals not closing properly when the back button is pressed, or conflicts with `history.pushState()` if you are manually handling browser history in your application, you can disable the back handler by setting `enableAndroidBackHandler` to `false`:\n\n```ts\nconst tonConnectUI = new TonConnectUI({\n    // ...\n    enableAndroidBackHandler: false\n});\n```\n\nThis will disable the custom back button behavior on Android, and you can then handle the back button press manually in your application.\n\nWhile we do not foresee any problems arising with the Android back handler, but if you find yourself needing to disable it due to an issue, please describe the problem in on [GitHub Issues](https://github.com/ton-connect/sdk/issues), so we can assist you further.\n\n## Animations not working\n\nIf you are experiencing issues with animations not working in your environment, it might be due to a lack of support for the Web Animations API. To resolve this issue, you can use the `web-animations-js` polyfill.\n\n### Using npm\n\nTo install the polyfill, run the following command:\n\n```shell\nnpm install web-animations-js\n```\n\nThen, import the polyfill in your project:\n\n```typescript\nimport 'web-animations-js';\n```\n\n### Using CDN\n\nAlternatively, you can include the polyfill via CDN by adding the following script tag to your HTML:\n\n```html\n<script src=\"https://www.unpkg.com/web-animations-js@latest/web-animations.min.js\"></script>\n```\n\nBoth methods will provide a fallback implementation of the Web Animations API and should resolve the animation issues you are facing.\n\n## Warning about 'encoding' module in Next.js\n\nIf you are using Next.js and see a warning similar to the following:\n\n```\n ⚠ ./node_modules/node-fetch/lib/index.js\nModule not found: Can't resolve 'encoding' in '.../node_modules/node-fetch/lib'\n\nImport trace for requested module:\n./node_modules/node-fetch/lib/index.js\n./node_modules/@tonconnect/isomorphic-fetch/index.mjs\n./node_modules/@tonconnect/sdk/lib/esm/index.mjs\n./node_modules/@tonconnect/ui/lib/esm/index.mjs\n```\n\nPlease note that this is just a warning and should not affect the functionality of your application. If you wish to suppress the warning, you have two options:\n\n1. (Recommended) Wait for us to remove the dependency on `@tonconnect/isomorphic-fetch` in future releases. This dependency will be removed when we drop support for Node.js versions below 18.\n\n2. (Optional) Install the `encoding` package, to resolve the warning:\n```shell\nnpm install encoding\n```\n\n## How to find a sent transaction on the blockchain\n\nSee the detailed guide: [Transaction-by-external-message](../../guidelines/transaction-by-external-message.md)\n\nThis guide explains how to find the corresponding transaction on the TON blockchain by the BOC of an external-in message.\n","readmeFilename":"README.md","_rev":"1-2ba96a49a29be1193b285e24a4830039"}