diff --git a/docs/develop/dapps/ton-connect/protocol/README.md b/docs/develop/dapps/ton-connect/protocol/README.md new file mode 100644 index 0000000000..c090111326 --- /dev/null +++ b/docs/develop/dapps/ton-connect/protocol/README.md @@ -0,0 +1,55 @@ +# Protocol specifications + +Understand how TON Connect works under the hood. + +## Who is this section for? + +- If you implement a wallet +- If you develop an SDK +- If you want to learn how TON Connect works + +## Sections overview + +* [Protocol workflows](/develop/dapps/ton-connect/protocol/workflow) is an overview of all the protocols involved in TON Connect. +* [Bridge API](/develop/dapps/ton-connect/protocol/bridge) specifies how the data is transmitted between the app and the wallet. +* [Session protocol](/develop/dapps/ton-connect/protocol/session) ensures end-to-end encrypted communication over the bridge. +* [Requests protocol](/develop/dapps/ton-connect/protocol/requests-responses) defines requests and responses for the app and the wallet. +* [Wallet guidelines](/develop/dapps/ton-connect/protocol/wallet-guidelines) defines guidelines for wallet developers. + +## FAQ + +#### I am building an HTML/JS app, what should I read? + +Simply use the [Supported SDKs](/develop/dapps/ton-connect/developers) and do not worry about the underlying protocols. + +#### I need an SDK in my favorite language + +Please take the [JS SDK](/develop/dapps/ton-connect/developers) as a reference and check out the protocol docs above. + +#### How do you detect whether the app is embedded in the wallet? + +JS SDK does that for you; just get wallets list `connector.getWallets()` and check `embedded` property of the corresponding list item. If you build your own SDK you should check `window.[targetWalletJsBridgeKey].tonconnect.isWalletBrowser`. + +#### How do you detect if the wallet is a browser extension? + +Like with embedded apps (see above), JS SDK detects it for you via `injected` property of the corresponding `connector.getWallets()` list item. If you build your own SDK you should check that `window.[targetWalletJsBridgeKey].tonconnect` exists. + +#### How to implement backend authorization with tonconnect? + +[See an example of dapp-backend](https://github.com/ton-connect/demo-dapp-backend) + +#### How do I make my own bridge? + +You don’t need to, unless you are building a wallet. + +If you build a wallet, you will need to provide a bridge. See our [reference implementation in Go](https://github.com/ton-connect/bridge). + +Keep in mind that the wallet’s side of the bridge API is not mandated. + +For a quick start you can use the common TON Connect bridge [github.com/ton-connect/bridge2](https://github.com/ton-connect/bridge2). + +#### I make a wallet, how do I add it to the list of wallets? + +Submit a pull request for the [wallets-list](https://github.com/ton-blockchain/wallets-list) repository and fill our all the necessary metadata. + +Apps may also add wallets directly through the SDK. diff --git a/docs/develop/dapps/ton-connect/protocol/bridge.md b/docs/develop/dapps/ton-connect/protocol/bridge.md new file mode 100644 index 0000000000..44caf7e115 --- /dev/null +++ b/docs/develop/dapps/ton-connect/protocol/bridge.md @@ -0,0 +1,202 @@ +# Bridge API + +Bridge is a transport mechanism to deliver messages from the app to the wallet and vice versa. + +* **Bridge is maintained by the wallet provider**. App developers do not have to choose or build a bridge. Each wallet’s bridge is listed in the [wallets-list](https://github.com/ton-blockchain/wallets-list) config. +* **Messages are end-to-end encrypted.** Bridge does not see the contents or long-term identifiers of the app or wallet. +* **Communication is symmetrical.** Bridge does not distinguish between apps and wallets: both are simply clients. +* Bridge keeps separate queues of messages for each recipient’s **Client ID**. + +Bridge comes in two flavors: + +- [HTTP Bridge](#http-bridge): for the external apps and services. +- [JS Bridge](#js-bridge): for apps opened within the wallet; or when the wallet is a browser extension. + +## HTTP Bridge + +Client with ID **A** connects to the bridge to listen to incoming requests. + +**Client ID is semi-private:** apps and wallets are not supposed to share their IDs with other entities to avoid having their messages removed unexpectedly. + +**Client can subscribe on few Client IDs** - in this case it should enumerate IDs separated with commas. For example: `?client_id=,,` + +```tsx +request + GET /events?client_id= + + Accept: text/event-stream +``` + +**Subscribing to the bridge second (any other) time** + +```tsx +request + GET /events?client_id=&last_event_id= + + Accept: text/event-stream +``` + +**lastEventId** – the eventId of the last SSE event wallet got over the bridge. In this case wallet will fetch all the events which happened after the last connection. + +Sending message from client A to client B. Bridge returns error if ttl is too high. + +```tsx +request + POST /message?client_id=?to=&ttl=300&topic= + + body: +``` + + +The `topic` [optional] query parameter can be used by the bridge to deliver the push notification to the wallet. If the parameter is given, it must correspond to the RPC method called inside the encrypted `message`. + +Bridge buffers messages up to TTL (in secs), but removes them as soon as the recipient receives the message. + +If the TTL exceeds the hard limit of the bridge server, it should respond with HTTP 400. Bridges should support at least 300 seconds TTL. + +When the bridge receives a message `base64_encoded_message` from client `A` addressed to client `B`, it generates a message `BridgeMessage`: + +```js +{ + "from": , + "message": +} +``` + +and sends it to the client B via SSE connection +```js +resB.write(BridgeMessage) +``` + +### Heartbeat + +To keep the connection, bridge server should periodically send a "heartbeat" message to the SSE channel. Client should ignore such messages. +So, the bridge heartbeat message is a string with word `heartbeat`. + + +## Universal link + +When the app initiates the connection it sends it directly to the wallet via the QR code or a universal link. + +```bash +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](/develop/dapps/ton-connect/protocol/requests-responses#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. + +`ret` parameter should be supported for empty deeplinks -- it might be used to specify the wallet behavior after other actions confirmation (send transaction, sign raw, ...). +```bash +https://?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. + +### Unified deeplink `tc` +In addition to its own universal link, the wallet must support the unified deeplink. + +This allows applications to create a single qr code, which can be used to connect to any wallet. + +More specifically, the wallet must support `tc://` deeplink as well as its own ``. + +Therefore, the following `connect request` must be processed by the wallet: + +```bash +tc://? + v=2& + id=& + r=& + ret=back +``` + + +## JS bridge + +Used by the embedded apps via the injected binding `window..tonconnect`. + +`wallet-js-bridge-key` can be specified in the [wallets list](https://github.com/ton-blockchain/wallets-list) + +JS bridge runs on the same device as the wallet and the app, so communication is not encrypted. + +The app works directly with plaintext requests and responses, without session keys and encryption. + +```tsx +interface TonConnectBridge { + deviceInfo: DeviceInfo; // see Requests/Responses spec + walletInfo?: WalletInfo; + protocolVersion: number; // max supported Ton Connect version (e.g. 2) + isWalletBrowser: boolean; // if the page is opened into wallet's browser + connect(protocolVersion: number, message: ConnectRequest): Promise; + restoreConnection(): Promise; + send(message: AppRequest): Promise; + listen(callback: (event: WalletEvent) => void): () => void; +} +``` + +Just like with the HTTP bridge, wallet side of the bridge does not receive the app requests except for [ConnectRequest](/develop/dapps/ton-connect/protocol/requests-responses#initiating-connection) until the session is confirmed by the user. Technically, the messages arrive from the webview into the bridge controller, but they are silently ignored. + +SDK around the implements **autoconnect()** and **connect()** as silent and non-silent attempts at establishing the connection. + +### 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. + + +### 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. + +### restoreConnection() + +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). + + +### send() + +Sends a [message](/develop/dapps/ton-connect/protocol/requests-responses#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, so you don't need to wait for responses with `listen`; + +### listen() + +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. diff --git a/docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md b/docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md new file mode 100644 index 0000000000..38b20ae6bb --- /dev/null +++ b/docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md @@ -0,0 +1,62 @@ +# Wallet Guidelines + +## Networks + +### There aren't many networks. + + At the moment, there are only two networks - Mainnet and Testnet. + In the foreseeable future, the emergence of new Mainnet TON-like networks is not expected. Note that the current Mainnet has a built-in mechanism for alternative networks - workchains. + + +### Hide the Testnet from ordinary users. + +Testnet is used exclusively by developers. Ordinary users should not see the Testnet. +This means that switching to Testnet should not be readily available and users SHOULD NOT be prompted to switch wallet to Testnet even if DAppis in Testnet. +Users switch to Testnet, don't understand this action, can't switch back to Mainnet. + +For these reasons, dapps do not need to switch networks in runtime, on the contrary, it is more preferable to have different instances of DAppon different domains dapp.com, Testnet.dapp.com. +For the same reason there is no `NetworkChanged` or `ChainChanged` event in the Ton Connect protocol. + + +### Do not send anything if the DAppis in Testnet and the wallet is in Mainnet. + + It is necessary to prevent loss of funds when DApptries to send a transaction in Testnet, and the wallet sends it in Mainnet. + + Dapps should explicitly indicate `network` field in `SendTransaction` request. + + If the `network` parameter is set, but the wallet has a different network set, the wallet should show an alert and DO NOT ALLOW TO SEND this transaction. + + The wallet SHOULD NOT offer to switch to another network in this case. + +## Multi accounts + +Multiple network accounts can be created for one key pair. Implement this functionality in your wallet - users will find it useful. + +### In general, there is no current "active" account + +At the moment, the TON Connect is not built on the paradigm that there is one selected account in the wallet, and when the user switches to another account, the `AccountChanged` event is sent to dapp. + +We think of a wallet as a physical wallet that can contain many "bank cards" (accounts). + +In most cases the sender address is not important to dapp, in these cases the user can select the appropriate account at the time of approving the transaction and the transaction will be sent from selected account. + +In some cases, it is important for DAppto send the transaction from a specific address, in which case it explicitly specifies the `from` field in `SendTransaction` request. If `from` parameter is set, the wallet should DO NOT ALLOW user to select the sender's address; If sending from the specified address is impossible, the wallet should show an alert and DO NOT ALLOW TO SEND this transaction. + +### Login flow + +When DAppconnects the wallet, the user selects in the wallet one of their accounts that they want to log into dapp. + +Regardless of what accounts the user uses next in the wallet, DAppworks with the account he received on the connection. + +Just like if you logged into a web service with one of your email accounts - if you then change the email account in the email service, the web service continues to use the one he got when you logged in. + +For this reason, the protocol does not provide the `AccountChanged` event. + +To switch account user need to disconnect (Log out) and connect (Login) again in DAppUI. + +We recommend wallets provide the ability to disconnect session with a specified DAppbecause the DAppmay have an incomplete UI. + +## See Also + +* [TON Connect Overview](/dapps/ton-connect/overview) +* [Connect a Wallet](/dapps/ton-connect/wallet) diff --git a/docs/participate/network-maintenance/custom-overlays.md b/docs/participate/network-maintenance/custom-overlays.md index 0c62729ec7..518974d1b7 100644 --- a/docs/participate/network-maintenance/custom-overlays.md +++ b/docs/participate/network-maintenance/custom-overlays.md @@ -17,7 +17,7 @@ If you have multiple node under your control it is expedient to unite them into Mytonctrl uses default custom overlays available at https://ton-blockchain.github.io/fallback_custom_overlays.json. This overlay is not used most of the time and intended for emergency use in case of problems with public overlay connectivity. To stop participation in default custom overlays run commands -```bash + MyTonCtrl> set useDefaultCustomOverlays false MyTonCtrl> delete_custom_overlay default ``` @@ -43,7 +43,6 @@ Create a config file in format: "adnl_address_hex_2": { "msg_sender": false }, - "adnl_address_hex_2": { "block_sender": true }, diff --git a/docs/participate/nodes/node-types.md b/docs/participate/nodes/node-types.md index bf47574345..a20d0a856a 100644 --- a/docs/participate/nodes/node-types.md +++ b/docs/participate/nodes/node-types.md @@ -80,18 +80,13 @@ Because of a permanent high load on public Liteservers, the majority of them is This may drive to instability of your your lite client application. ::: - - To interact with Liteservers, you can use following tools: - TON [ADNL API](/develop/dapps/apis/adnl) as the most low-level way to communicate with the blockchain; - TON [SDKs](/develop/dapps/apis/sdk) provided for various programming languages; -- TON [HTTP-based APIs](/develop/dapps/toncenter) providing the REST API middleware between your application and a Liteserver. +- TON [HTTP-based APIs](/develop/dapps/apis/toncenter) providing the REST API middleware between your application and a Liteserver. - +Enable Liteserver in your Node + \ No newline at end of file