### Sign Data Examples Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Illustrative examples of SignDataRequest payloads for text, binary, and cell data. ```APIDOC ## Sign Data Examples ### Text Payload Example ```json { "type": "text", "text": "Confirm new 2fa number:\n+1 234 567 8901", "network": "-239", "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` ### Binary Payload Example ```json { "type": "binary", "bytes": "1Z/SGh+3HFMKlVHSkN91DpcCzT4C5jzHT3sA/24C5A==", "network": "-239", "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` ### Cell Payload Example ```json { "type": "cell", "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;", "cell": "te6ccgEBAQEAVwAAqg+KfqVUbeTvKqB4h0AcnDgIAZucsOi6TLrfP6FcuPKEeTI6oB3fF/NBjyqtdov/KtutACCLqvfmyV9kH+Pyo5lcsrJzJDzjBJK6fd+ZnbFQe4+XggI=", "network": "-239", "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` ``` -------------------------------- ### Sign Binary Payload Example Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Example of a payload for signing base64 encoded arbitrary bytes. The wallet will display a warning as the content is unknown. ```json { "type": "binary", "bytes": "1Z/SGh+3HFMKlVHSkN91DpcCzT4C5jzHT3sA/24C5A==", "network": "-239", // enum NETWORK { MAINNET = '-239', TESTNET = '-3'} "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` -------------------------------- ### Sign Text Payload Example Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Example of a payload for signing arbitrary UTF-8 text. The wallet will display this text in a monospace font with forced line breaks. ```json { "type": "text", "text": "Confirm new 2fa number:\n+1 234 567 8901", "network": "-239", // enum NETWORK { MAINNET = '-239', TESTNET = '-3'} "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` -------------------------------- ### SendTransactionRequest Payload Example Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md An example of the JSON payload for a `SendTransactionRequest`, demonstrating how to specify transaction details such as validity period, network, sender, and multiple messages with optional state initialization and extra currency. ```json5 { "valid_until": 1658253458, "network": "-239", // enum NETWORK { MAINNET = '-239', TESTNET = '-3'} "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f", "messages": [ { "address": "EQBBJBB3HagsujBqVfqeDUPJ0kXjgTPLWPFFffuNXNiJL0aA", "amount": "20000000", "stateInit": "base64bocblahblahblah==", //deploy contract "extra_currency": { "239": "1000000000" } },{ "address": "EQDmnxDMhId6v1Ofg_h5KR5coWlFG6e86Ro3pc7Tq4CA0-Jn", "amount": "60000000", "payload": "base64bocblahblahblah==" //transfer nft to new deployed account 0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F } ] } ``` -------------------------------- ### Sign Cell Payload Example Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Example of a payload for signing a cell structure defined by a TL-B schema. The 'cell' field contains the base64 encoded BoC. ```json { "type": "cell", "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;", "cell": "te6ccgEBAQEAVwAAqg+KfqVUbeTvKqB4h0AcnDgIAZucsOi6TLrfP6FcuPKEeTI6oB3fF/NBjyqtdov/KtutACCLqvfmyV9kH+Pyo5lcsrJzJDzjBJK6fd+ZnbFQe4+XggI=", "network": "-239", // enum NETWORK { MAINNET = '-239', TESTNET = '-3'} "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f" } ``` -------------------------------- ### Initiating Connection Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Applications initiate a connection by sending an `InitialRequest` containing the app's manifest URL and desired data items. The wallet responds with a `ConnectEvent` upon user approval. ```APIDOC ## Initiating Connection ### Description Applications initiate a connection by sending an `InitialRequest` containing the app's manifest URL and desired data items. The wallet responds with a `ConnectEvent` upon user approval. ### Request (App to Wallet) `InitialRequest` message: ```typescript type ConnectRequest = { manifestUrl: string; items: ConnectItem[]; // data items to share with the app } type ConnectItem = TonAddressItem | TonProofItem | ...; type TonAddressItem = { name: "ton_addr"; } type TonProofItem = { name: "ton_proof"; payload: string; // arbitrary payload, e.g. nonce + expiration timestamp. } ``` **`ConnectRequest` fields:** - `manifestUrl` (string): Link to the app's `tonconnect-manifest.json`. - `items` (ConnectItem[]): Data items to share with the app. ### Response (Wallet to App) `ConnectEvent` message (either `ConnectEventSuccess` or `ConnectEventError`): ```typescript type ConnectEvent = ConnectEventSuccess | ConnectEventError; type ConnectEventSuccess = { event: "connect"; id: number; // increasing event counter payload: { items: ConnectItemReply[]; device: DeviceInfo; } } type ConnectEventError = { event: "connect_error", id: number; // increasing event counter payload: { code: number; message: string; } } type DeviceInfo = { platform: 'iphone' | 'ipad' | 'android' | 'windows' | 'mac' | 'linux' | 'browser'; appName: string; // e.g. "Tonkeeper" appVersion: string; // e.g. "2.3.367" maxProtocolVersion: number; features: Feature[]; // list of supported features and methods in RPC } type Feature = | { name: 'SendTransaction'; maxMessages: number; // maximum number of messages in one `SendTransaction` that the wallet supports extraCurrencySupported?: boolean; // indicates if the wallet supports extra currencies } | { name: 'SignData'; types: ('text' | 'binary' | 'cell')[]; // array of supported data types for signing }; type ConnectItemReply = TonAddressItemReply | TonProofItemReply ...; // Untrusted data returned by the wallet. // If you need a guarantee that the user owns this address and public key, you need to additionally request a ton_proof. type TonAddressItemReply = { name: "ton_addr"; address: string; // TON address raw (`0:`) network: NETWORK; // network global_id publicKey: string; // HEX string without 0x walletStateInit: string; // Base64 (not url safe) encoded stateinit cell for the wallet contract } type TonProofItemReply = TonProofItemReplySuccess | TonProofItemReplyError; type TonProofItemReplySuccess = { name: "ton_proof"; proof: { timestamp: string; // 64-bit unix epoch time of the signing operation (seconds) domain: { lengthBytes: number; // AppDomain Length value: string; // app domain name (as url part, without encoding) }; signature: string; // base64-encoded signature payload: string; // payload from the request } } type TonProofItemReplyError = { name: "ton_addr"; error: { code: ConnectItemErrorCode; message?: string; } } enum NETWORK { MAINNET = '-239', TESTNET = '-3' } ``` **`ConnectEvent` fields:** - `event` (string): Type of event, either "connect" or "connect_error". - `id` (number): Increasing event counter. - `payload` (object): Contains either success data or error details. - `items` (ConnectItemReply[]): Data items returned by the wallet. - `device` (DeviceInfo): Information about the wallet device. - `code` (number): Error code if `event` is "connect_error". - `message` (string): Error message if `event` is "connect_error". ### Connect Event Error Codes: | code | description | |------|------------------------------| | 0 | Unknown error | | 1 | Bad request | | 2 | App manifest not found | | 3 | App manifest content error | | 100 | Unknown app | | 300 | User declined the connection | ### Connect Item Error Codes: | code | description | |------|------------------------------| | 0 | Unknown error | | 400 | Method is not supported | If the wallet doesn't support a requested `ConnectItem`, it must send a reply with the following structure: ```typescript type ConnectItemReplyError = { name: ""; error: { code: 400; message?: string; } } ``` ``` -------------------------------- ### listen() Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Registers a listener for events from the wallet. Currently, only the 'disconnect' event is available. ```APIDOC ## listen(callback) ### Description Registers a listener for events from the wallet. Returns unsubscribe function. Currently, only `disconnect` event is available. Later there will be a switch account event and other wallet events. ### Method (Implicitly a method call, no HTTP method specified) ### Endpoint (Not applicable for this method) ### Parameters #### Request Body - **callback** (function) - Required - The function to call when an event is received. ### Request Example (Example not provided in source) ### Response - **unsubscribe** (function) - A function to call to unregister the listener. ``` -------------------------------- ### Initiating Connection with Deep Links Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Initiates a wallet connection using universal or unified deep links. The link includes the DApp's Client ID and a URL-encoded `ConnectRequest`. ```bash # Wallet-specific universal link https://?v=2&id=&r=&ret=back ``` ```bash # Unified deep link (all wallets must support) tc://?v=2&id=&r=%7B%22manifestUrl%22%3A%22https%3A%2F%2Fmyapp.com%2Ftonconnect-manifest.json%22%2C%22items%22%3A%5B%7B%22name%22%3A%22ton_addr%22%7D%5D%7D&ret=back ``` ```text # ConnectRequest JSON (before URL-encoding): # { # "manifestUrl": "https://myapp.com/tonconnect-manifest.json", # "items": [ # { "name": "ton_addr" }, # { "name": "ton_proof", "payload": "nonce_abc123_exp_1700000000" } # ] # } ``` -------------------------------- ### Full TON Connect Workflow with HTTP Bridge Source: https://context7.com/ton-blockchain/ton-connect/llms.txt This snippet demonstrates the complete TON Connect flow using the HTTP bridge. It includes generating ephemeral keys, subscribing to bridge events via SSE, constructing a universal link for wallet connection, and sending encrypted transaction requests. Ensure nacl and Buffer are available in your environment. ```typescript import nacl from 'tweetnacl'; const BRIDGE = 'https://bridge.tonapi.io/bridge'; // 1. Generate ephemeral keypair const { publicKey: A, secretKey: a } = nacl.box.keyPair(); const clientId = Buffer.from(A).toString('hex'); // 2. Subscribe to bridge events (SSE) const evtSource = new EventSource(`${BRIDGE}/events?client_id=${clientId}&heartbeat=message`); let walletClientId: string; evtSource.onmessage = (e) => { if (e.data === 'heartbeat') return; const { from, message: encryptedB64 } = JSON.parse(e.data); walletClientId = from; const B = Buffer.from(from, 'hex'); const plaintext = nacl.box.open( Buffer.from(encryptedB64, 'base64').slice(24), Buffer.from(encryptedB64, 'base64').slice(0, 24), B, a ); const connectEvent: ConnectEvent = JSON.parse(Buffer.from(plaintext!).toString('utf8')); if (connectEvent.event === 'connect') { console.log('Connected! Address:', connectEvent.payload.items[0].address); // Persist session: { clientId, a (private), walletClientId } } }; // 3. Build and display universal link / QR code const connectRequest: ConnectRequest = { manifestUrl: 'https://myapp.com/tonconnect-manifest.json', items: [{ name: 'ton_addr' }, { name: 'ton_proof', payload: 'nonce_xyz_1700000000' }] }; const universalLink = `https://app.tonkeeper.com/ton-connect?v=2` + `&id=${clientId}` + `&r=${encodeURIComponent(JSON.stringify(connectRequest))}` + `&ret=back`; console.log('Show this as QR code:', universalLink); // 4. After session established — send an encrypted sendTransaction request async function sendEncryptedRequest(request: AppRequest) { const B = Buffer.from(walletClientId, 'hex'); const msg = Buffer.from(JSON.stringify(request), 'utf8'); const nonce = nacl.randomBytes(24); const ct = nacl.box(msg, nonce, B, a); const payload = Buffer.concat([nonce, ct]).toString('base64'); const resp = await fetch( `${BRIDGE}/message?client_id=${clientId}&to=${walletClientId}&ttl=300&topic=sendTransaction`, { method: 'POST', body: payload } ); if (!resp.ok) throw new Error(`Bridge error: ${resp.status}`); } ``` -------------------------------- ### connect() Method Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Initiates a connection request to a TON wallet. This method is analogous to using a universal link or QR code with the HTTP bridge. It attempts a silent connection if the app was previously approved for the account, otherwise, it displays a confirmation dialog. ```APIDOC #### connect() Initiates connect request, this is analogous to QR/link when using the HTTP bridge. If the app was previously approved for the current account — connects silently with ConnectEvent. Otherwise shows confirmation dialog to the user. You shouldn't use the `connect` method without explicit user action (e.g. connect button click). If you want automatically try to restore previous connection, you should use the `restoreConnection` method. ``` -------------------------------- ### Construct Universal Link for Wallet Connection Source: https://github.com/ton-blockchain/ton-connect/blob/main/workflows.md App creates a universal link to a target wallet, including protocol version, app's Client ID, and the initial connection request. ```javascript https://?v=2&id=&r= ``` -------------------------------- ### Initiate Connection via JS Bridge Source: https://github.com/ton-blockchain/ton-connect/blob/main/workflows.md When using the JS bridge, the app calls the `connect()` method with the protocol version and the initial request object. ```javascript window.[walletJsBridgeKey].tonconnect.connect(2, ) ``` -------------------------------- ### Signature Computation for Text/Binary Data Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Illustrates the message construction and signing process for text or binary payloads using Ed25519. Ensure correct encoding of address, domain, and payload. ```plaintext message = 0xffff ++\n utf8_encode("ton-connect/sign-data/") ++\n Address ++\n AppDomain ++\n Timestamp ++\n Payload signature = Ed25519Sign(privkey, sha256(message)) ``` -------------------------------- ### Define DeviceInfo structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Provides information about the wallet device and application. Includes platform, app name and version, maximum protocol version, and supported features. ```typescript type DeviceInfo = { platform: 'iphone' | 'ipad' | 'android' | 'windows' | 'mac' | 'linux' | 'browser'; appName: string; // e.g. "Tonkeeper" appVersion: string; // e.g. "2.3.367" maxProtocolVersion: number; features: Feature[]; // list of supported features and methods in RPC } ``` -------------------------------- ### restoreConnection() Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Attempts to restore the previous connection. If the app was previously approved for the current account, it connects silently. Otherwise, it returns a ConnectEventError. ```APIDOC ## restoreConnection() ### Description Attempts to restore the previous connection. If the app was previously approved for the current account — connects silently with the new `ConnectEvent` with only a `ton_addr` data item. Otherwise returns `ConnectEventError` with error code 100 (Unknown app). ### Method (Implicitly a method call, no HTTP method specified) ### Endpoint (Not applicable for this method) ### Parameters (No parameters specified) ### Request Example (Not applicable for this method) ### Response - `ConnectEvent` (on success, with `ton_addr`) - `ConnectEventError` (on failure, error code 100) ``` -------------------------------- ### Universal Link for Connection Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md This is the universal link format used by applications to initiate a connection with a TON wallet. It can be embedded in QR codes or used as a direct link. ```APIDOC ## Universal link When the app initiates the connection it sends it directly to the wallet via the QR code or a universal link. ``` https://? v=2& id=& r=& ret=back ``` Parameter **v** specifies the protocol version. Unsupported versions are not accepted by the wallets. Parameter **id** specifies app’s Client ID encoded as hex (without '0x' prefix). Parameter **r** specifies URL-safe json [ConnectRequest](requests-responses.md#initiating-connection). Parameter **ret** (optional) specifies return strategy for the deeplink when user signs/declines the request. - 'back' (default) means return to the app which initialized deeplink jump (e.g. browser, native app, ...), - 'none' means no jumps after user action; - a 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. The `id` parameter should be supported even in empty deeplinks -- it might be used by wallets to identify the application. `ret` parameter should also be supported for empty deeplinks -- it might be used to specify the wallet behavior after other actions confirmation (send transaction, sign raw, ...). ``` https://?id=&ret=back ``` The link may be embedded in a QR code or clicked directly. The initial request is unencrypted because (1) there is no personal data being communicated yet, (2) app does not even know the identity of the wallet. ``` -------------------------------- ### Define ConnectRequest structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the structure for initiating a connection request from an application to a wallet. Requires the app's manifest URL and a list of data items to share. ```typescript type ConnectRequest = { manifestUrl: string; items: ConnectItem[]; // data items to share with the app } // In the future we may add other personal items. // Or, instead of the wallet address we may ask for per-service ID. type ConnectItem = TonAddressItem | TonProofItem | ...; type TonAddressItem = { name: "ton_addr"; } type TonProofItem = { name: "ton_proof"; payload: string; // arbitrary payload, e.g. nonce + expiration timestamp. } ``` -------------------------------- ### Generate Bouncable and Non-Bouncable Addresses with @ton/core Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Use the `@ton/core` library to generate both bouncable and non-bouncable address formats from a raw or friendly address string. Bouncable addresses are recommended for smart contracts, while non-bouncable addresses are suitable for wallet contracts or when errors are expected. ```typescript import { Address } from '@ton/core'; const address = Address.parse('...'); // raw or friendly // Bouncable format, for smart contract interactions const bouncable = address.toString({ urlSafe: true, bounceable: true }); // bounce = true // No-bouncable format, for wallet contracts or expected-to-fail transactions const nonBouncable = address.toString({ urlSafe: true, bounceable: false }); // bounce = false ``` -------------------------------- ### WalletInfo Interface Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md The WalletInfo interface defines the structure for wallet metadata, which can be used to configure TON Connect even if the wallet is not listed in the official wallets list. ```APIDOC #### walletInfo (optional) Represents wallet metadata. Might be defined to make an injectable wallet works with TonConnect even if the wallet is not listed in the [wallets-list.json](https://github.com/ton-blockchain/wallets-list). Wallet metadata format: ```ts interface WalletInfo { name: string; image: ; tondns?: string; about_url: ; } ``` Detailed properties description: https://github.com/ton-blockchain/wallets-list#entry-format. If `TonConnectBridge.walletInfo` is defined and the wallet is listed in the [wallets-list.json](https://github.com/ton-blockchain/wallets-list), `TonConnectBridge.walletInfo` properties will override corresponding wallet properties from the wallets-list.json. ``` -------------------------------- ### Listen for Incoming Events Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md This endpoint allows a client to subscribe to incoming messages and events from the bridge. It supports fetching events since the last connection using `lastEventId`. ```APIDOC ## GET /events ### Description Subscribes to incoming messages and events from the bridge. Can be used to fetch events since the last connection. ### Method GET ### Endpoint /events ### Parameters #### Query Parameters - **client_id** (string) - Required - The Client ID of the recipient, expected in hex string format. Can be a comma-separated list for multiple subscriptions. - **last_event_id** (string) - Optional - The event ID of the last SSE event received. Used to fetch subsequent events. - **heartbeat** (string) - Optional - Controls the heartbeat message format. Can be `legacy` (default) or `message`. ### Request Headers - **Accept**: text/event-stream ### Response #### Success Response (200) - The response is a Server-Sent Events (SSE) stream containing messages and heartbeats. ``` -------------------------------- ### Generate Client Keypair Source: https://github.com/ton-blockchain/ton-connect/blob/main/session.md Generates an X25519 keypair for use with NaCl's crypto_box protocol. This keypair consists of a private key 'a' and its corresponding public key 'A'. ```javascript (a,A) <- nacl.box.keyPair() ``` -------------------------------- ### Address Proof Signature Generation (ton_proof) Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the message structure and signature generation for proving ownership of an account's key. The message includes a unique prefix, wallet address, app domain, timestamp, and custom payload. ```text message = utf8_encode("ton-proof-item-v2/") ++ Address ++ AppDomain ++ Timestamp ++ Payload signature = Ed25519Sign(privkey, sha256(0xffff ++ utf8_encode("ton-connect") ++ sha256(message))) ``` -------------------------------- ### Handle unsupported ConnectItem Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Specifies the structure for a `ConnectItemReplyError` when a wallet does not support a requested `ConnectItem`, such as 'ton_proof'. ```typescript type ConnectItemReplyError = { name: ""; error: { code: 400; message?: string; } } ``` -------------------------------- ### App Request Structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the structure for all requests initiated by the DApp to the TON Wallet. ```APIDOC ## App Request Structure All app requests have the following structure (like json-rpc 2.0): ```typescript interface AppRequest { method: string; params: string[]; id: string; } ``` Where - `method`: name of the operation ('sendTransaction', 'signMessage', ...) - `params`: array of the operation specific parameters - `id`: increasing identifier that allows to match requests and responses ``` -------------------------------- ### Wallet Universal Link Structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md This is the structure of a universal link used to initiate a connection with a TON wallet. It includes parameters for protocol version, app client ID, connection request, and return strategy. ```url https://? v=2& id=& r=& ret=back ``` -------------------------------- ### Resume Listening for Events (HTTP Bridge) Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md To resume listening after a disconnection, provide the `last_event_id` of the last received SSE event. This ensures no messages are missed. The `client_id` should be a hexadecimal string. ```http request GET /events?client_id=&last_event_id=[&heartbeat=] Accept: text/event-stream ``` -------------------------------- ### App Manifest Configuration Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Defines the structure of the tonconnect-manifest.json file. Wallets fetch this file to identify DApps, display their names and icons, and link to legal documents. ```json { "url": "https://myapp.com", "name": "My TON DApp", "iconUrl": "https://myapp.com/icon-180.png", "termsOfUseUrl": "https://myapp.com/terms", "privacyPolicyUrl": "https://myapp.com/privacy" } ``` -------------------------------- ### Session Protocol - Encryption Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Details on key pair generation and encryption using X25519 NaCl for secure communication between the app and the wallet after the initial connection. ```APIDOC ## Session Protocol — Key Pair Generation and Encryption Each side (app and wallet) generates an X25519 NaCl keypair. All app requests (after the initial connect) and all wallet responses are encrypted with `nacl.box`. The 24-byte random nonce is prepended to the ciphertext. ```ts import nacl from 'tweetnacl'; // Generate client keypair — do once, persist private key securely const { publicKey: A, secretKey: a } = nacl.box.keyPair(); // Encrypt a message from app (private key: a) to wallet (public key: B) function encrypt(message: Uint8Array, recipientPubKey: Uint8Array, senderSecretKey: Uint8Array): string { const nonce = nacl.randomBytes(24); const ciphertext = nacl.box(message, nonce, recipientPubKey, senderSecretKey); const fullMessage = new Uint8Array(nonce.length + ciphertext.length); fullMessage.set(nonce); fullMessage.set(ciphertext, nonce.length); return Buffer.from(fullMessage).toString('base64'); } // Decrypt a message received from wallet (public key: B) using app's private key (a) function decrypt(base64Message: string, senderPubKey: Uint8Array, recipientSecretKey: Uint8Array): Uint8Array { const fullMessage = Buffer.from(base64Message, 'base64'); const nonce = fullMessage.slice(0, 24); const ciphertext = fullMessage.slice(24); const plaintext = nacl.box.open(ciphertext, nonce, senderPubKey, recipientSecretKey); if (!plaintext) throw new Error('Decryption failed — invalid message or keys'); return plaintext; } // Client ID = hex-encoded public key const clientId = Buffer.from(A).toString('hex'); ``` ``` -------------------------------- ### App Manifest JSON Format Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Specifies the structure for the `tonconnect-manifest.json` file. This file provides essential metadata about your application to the wallet. ```json { "url": "", // required "name": "", // required "iconUrl": "", // required "termsOfUseUrl": "", // optional "privacyPolicyUrl": "" // optional } ``` -------------------------------- ### send() Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Sends a message to the bridge. This method directly returns a promise with WalletResponse. ```APIDOC ## send(message) ### Description Sends a [message](requests-responses.md#messages) to the bridge, excluding the ConnectRequest (that goes into QR code when using HTTP bridge and into connect when using JS Bridge). Directly returns promise with WalletResponse, do you don't need to wait for responses with `listen`. ### Method (Implicitly a method call, no HTTP method specified) ### Endpoint (Not applicable for this method) ### Parameters #### Request Body - **message** (object) - Required - The message to send to the bridge. See [messages](requests-responses.md#messages) for format. ### Request Example (Example not provided in source) ### Response #### Success Response - **WalletResponse** (object) - The response from the wallet. ``` -------------------------------- ### signData Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Asks the wallet to sign arbitrary data in text, binary, or cell format. The signature can be verified on-chain. ```APIDOC ## signData ### Description The app asks the wallet to sign arbitrary data in one of three formats: human-readable `text`, raw `binary` bytes, or a structured TL-B `cell`. The resulting Ed25519 signature can be verified on-chain by a smart contract. ### Method `signData` ### Parameters This method accepts a single parameter, which is a JSON string representing the data signing request. #### Request Body (JSON String) - **type** (string) - Required - The format of the data to sign (`text`, `binary`, or `cell`). - **text** (string) - Required if type is `text` - The human-readable text to sign. - **bytes** (string) - Required if type is `binary` - Base64 encoded raw bytes to sign. - **schema** (string) - Required if type is `cell` - The TL-B schema for the cell. - **cell** (string) - Required if type is `cell` - Base64 encoded BoC of the cell to sign. - **network** (string) - Required - The network ID (e.g., '-239' for MAINNET). - **from** (string) - Required - The address initiating the signing request. ### Request Example ```javascript // Text payload const textRequest = { method: 'signData', params: [JSON.stringify({ type: 'text', text: 'Confirm new 2FA number:\n+1 234 567 8901', network: '-239', from: '0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f' })], id: '2' }; // Binary payload const binaryRequest = { method: 'signData', params: [JSON.stringify({ type: 'binary', bytes: '1Z/SGh+3HFMKlVHSkN91DpcCzT4C5jzHT3sA/24C5A==', network: '-239', from: '0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f' })], id: '3' }; // Cell payload const cellRequest = { method: 'signData', params: [JSON.stringify({ type: 'cell', 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;', cell: 'te6ccgEBAQEAVwAAqg+KfqVU...', network: '-239', from: '0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f' })], id: '4' }; ``` ### Response #### Success Response - **result** (object) - **signature** (string) - Base64-encoded Ed25519 signature. - **address** (string) - The address that signed the data. - **timestamp** (integer) - The timestamp of the signing operation. - **domain** (object) - Information about the domain that requested the signature. - **payload** (string) - The original payload that was signed. #### Error Response - **error** (object) - **code** (integer) - Error code (e.g., 0=Unknown, 1=BadRequest, 300=UserDeclined, 400=MethodNotSupported). - **message** (string) - Error message. ``` -------------------------------- ### Listen for Incoming Events (HTTP Bridge) Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Use this endpoint to subscribe to incoming messages from other clients. The `client_id` should be a hexadecimal string. The `heartbeat` parameter controls the format of keep-alive messages. ```http request GET /events?client_id=[&heartbeat=] Accept: text/event-stream ``` -------------------------------- ### TON Connect Session Protocol: Key Pair Generation Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Each side generates an X25519 NaCl keypair for encrypting requests and responses. Generate the client keypair once and persist the private key securely. The client ID is the hex-encoded public key. ```typescript import nacl from 'tweetnacl'; // Generate client keypair — do once, persist private key securely const { publicKey: A, secretKey: a } = nacl.box.keyPair(); ``` ```typescript // Client ID = hex-encoded public key const clientId = Buffer.from(A).toString('hex'); ``` -------------------------------- ### Define ConnectEvent structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the structure for wallet responses to a connection request. It can be a success event with connection details or an error event. ```typescript type ConnectEvent = ConnectEventSuccess | ConnectEventError; type ConnectEventSuccess = { event: "connect"; id: number; // increasing event counter payload: { items: ConnectItemReply[]; device: DeviceInfo; } } type ConnectEventError = { event: "connect_error", id: number; // increasing event counter payload: { code: number; message: string; } } ``` -------------------------------- ### App Request Structure in TON Connect Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the standard structure for requests sent from a DApp to a TON wallet. Includes method name, operation-specific parameters, and a unique identifier for matching with responses. ```typescript interface AppRequest { method: string; params: string[]; id: string; } ``` -------------------------------- ### TON Connect JS Bridge Interface Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Use this interface for apps running inside a wallet's browser or alongside a wallet browser extension. Communication is local and unencrypted. Ensure the bridge is available before calling its methods. ```typescript interface TonConnectBridge { deviceInfo: DeviceInfo; walletInfo?: WalletInfo; // optional: override wallet metadata protocolVersion: number; // max supported TON Connect version (e.g. 2) isWalletBrowser: boolean; connect(protocolVersion: number, message: ConnectRequest): Promise; restoreConnection(): Promise; send(message: AppRequest): Promise; listen(callback: (event: WalletEvent) => void): () => void; } ``` ```typescript // --- Detect injection --- const bridge = window['tonkeeper']?.tonconnect; if (!bridge) throw new Error('Wallet not available'); ``` ```typescript // --- First-time connect (triggered by user action) --- const connectEvent = await bridge.connect(2, { manifestUrl: 'https://myapp.com/tonconnect-manifest.json', items: [{ name: 'ton_addr' }, { name: 'ton_proof', payload: 'my-nonce-12345' }] }); // connectEvent.event === 'connect' on success ``` ```typescript // --- Silent reconnect on page load --- const restored = await bridge.restoreConnection(); if (restored.event === 'connect_error' && restored.payload.code === 100) { console.log('No prior session — prompt user to connect'); } ``` ```typescript // --- Listen for wallet-initiated disconnect --- const unsubscribe = bridge.listen((event) => { if (event.event === 'disconnect') { localStorage.removeItem('ton-connect-session'); } }); // Call unsubscribe() when component unmounts ``` -------------------------------- ### Wallet Response Structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Details the structure of responses from the TON Wallet to DApp requests, including success and error formats. ```APIDOC ## Wallet Response Structure Wallet messages are responses or events. Response is an object formatted as a json-rpc 2.0 response. Response `id` must match request's id. Wallet doesn't accept any request with an id that does not greater the last processed request id of that session. ```typescript type WalletResponse = WalletResponseSuccess | WalletResponseError; interface WalletResponseSuccess { result: string; id: string; } interface WalletResponseError { error: { code: number; message: string; data?: unknown }; id: string; } ``` ``` -------------------------------- ### Wallet Event Structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Describes the structure for events emitted by the TON Wallet, such as connection status changes. ```APIDOC ## Wallet Event Structure Event is an object with property `event` that is equal to event's name, `id` that is increasing event counter (**not** related to `request.id` because there is no request for an event), and `payload` that contains event additional data. ```typescript interface WalletEvent { event: WalletEventName; id: number; // increasing event counter payload: ; // specific payload for each event } type WalletEventName = 'connect' | 'connect_error' | 'disconnect'; ``` Wallet must increase `id` while generating a new event. (Every next event must have `id` > previous event `id`) DApp doesn't accept any event with an id that does not greater the last processed event id of that session. ``` -------------------------------- ### Simplified Wallet Universal Link Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md A simplified version of the wallet universal link, often used when only the client ID and return strategy are needed. ```url https://?id=&ret=back ``` -------------------------------- ### HTTP Bridge - Subscribe to Events Source: https://context7.com/ton-blockchain/ton-connect/llms.txt Clients subscribe to their message queue on the bridge using Server-Sent Events (SSE). Use `client_id` for subscription and `last_event_id` for replaying missed messages upon reconnection. ```bash # First-time connection curl -N -H "Accept: text/event-stream" \ "https://bridge.tonapi.io/bridge/events?client_id=" ``` ```bash # Reconnection — replay events after last known event curl -N -H "Accept: text/event-stream" \ "https://bridge.tonapi.io/bridge/events?client_id=&last_event_id=42&heartbeat=message" ``` ```text # Expected SSE stream: # event: message # data: heartbeat # # event: message # data: {"from":"","message":""} ``` -------------------------------- ### Define ConnectItemReply structure Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the structure for replies to requested data items. Includes success replies for addresses and proofs, and error replies if an item is not supported. ```typescript type ConnectItemReply = TonAddressItemReply | TonProofItemReply ...; // Untrusted data returned by the wallet. // If you need a guarantee that the user owns this address and public key, you need to additionally request a ton_proof. type TonAddressItemReply = { name: "ton_addr"; address: string; // TON address raw (`0:`) network: NETWORK; // network global_id publicKey: string; // HEX string without 0x walletStateInit: string; // Base64 (not url safe) encoded stateinit cell for the wallet contract } type TonProofItemReply = TonProofItemReplySuccess | TonProofItemReplyError; type TonProofItemReplySuccess = { name: "ton_proof"; proof: { timestamp: string; // 64-bit unix epoch time of the signing operation (seconds) domain: { lengthBytes: number; // AppDomain Length value: string; // app domain name (as url part, without encoding) }; signature: string; // base64-encoded signature payload: string; // payload from the request } } type TonProofItemReplyError = { name: "ton_addr"; error: { code: ConnectItemErrorCode; message?: string; } } ``` -------------------------------- ### TonConnectBridge Interface Source: https://context7.com/ton-blockchain/ton-connect/llms.txt The `TonConnectBridge` interface provides methods for interacting with a TON wallet's bridge. This includes connecting, restoring connections, sending requests, and listening for events. ```APIDOC ## JS Bridge Interface (`window..tonconnect`) For apps running inside a wallet's browser or alongside a wallet browser extension, the wallet injects a `TonConnectBridge` object. Communication is local and unencrypted. The app calls `connect()` or `restoreConnection()` directly, and uses `send()` for subsequent operations. ```ts interface TonConnectBridge { deviceInfo: DeviceInfo; walletInfo?: WalletInfo; // optional: override wallet metadata protocolVersion: number; // max supported TON Connect version (e.g. 2) isWalletBrowser: boolean; connect(protocolVersion: number, message: ConnectRequest): Promise; restoreConnection(): Promise; send(message: AppRequest): Promise; listen(callback: (event: WalletEvent) => void): () => void; } // --- Detect injection --- const bridge = window['tonkeeper']?.tonconnect; if (!bridge) throw new Error('Wallet not available'); // --- First-time connect (triggered by user action) --- const connectEvent = await bridge.connect(2, { manifestUrl: 'https://myapp.com/tonconnect-manifest.json', items: [{ name: 'ton_addr' }, { name: 'ton_proof', payload: 'my-nonce-12345' }] }); // connectEvent.event === 'connect' on success // --- Silent reconnect on page load --- const restored = await bridge.restoreConnection(); if (restored.event === 'connect_error' && restored.payload.code === 100) { console.log('No prior session — prompt user to connect'); } // --- Listen for wallet-initiated disconnect --- const unsubscribe = bridge.listen((event) => { if (event.event === 'disconnect') { localStorage.removeItem('ton-connect-session'); } }); // Call unsubscribe() when component unmounts ``` ``` -------------------------------- ### Connect Event Success Type Source: https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md Defines the structure for a successful connect event from the wallet. It includes connection items and device information. ```typescript type ConnectEventSuccess = { event: "connect"; id: number; // increasing event counter payload: { items: ConnectItemReply[]; device: DeviceInfo; } } ``` -------------------------------- ### WalletInfo Interface Definition Source: https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md Defines the TypeScript interface for WalletInfo, used to provide metadata for an injectable wallet. ```typescript interface WalletInfo { name: string; image: ; tondns?: string; about_url: ; } ```