diff --git a/docs/develop/dapps/README.md b/docs/develop/dapps/README.md deleted file mode 100644 index b94edc033f..0000000000 --- a/docs/develop/dapps/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# Overview - -The best place to start is a TON Hello World guide of how to create your first Web App: - -- [TON Hello World: Step by step guide for building your first web client](https://ton-community.github.io/tutorials/03-client/) - - -## Tools - -Here you can see links to the most important resources for you to get started with TON: - -- [Wallets](/participate/wallets/apps) — a list of popular wallets for TON. -- [Explorers](/participate/explorers) — to track transactions in the blockchain. -- [Testnet](/develop/smart-contracts/environment/testnet.md) — info about the testnet and how to use it. -- [Unfreezer](https://unfreezer.ton.org/) - Unfreeze a TON contract that ran out of gas for rent. - -## Examples - -If you are a web or bot developer, you may find the following repositories useful: - -### JavaScript - -* Payment processing using JavaScript: - * [Create a key pair and a wallet](https://github.com/toncenter/examples/blob/main/common.js) (tonweb) - * [Accepting deposits to a single wallet](https://github.com/toncenter/examples/blob/main/deposits-single-wallet.js) (tonweb) - * [Accepting deposits to multiple wallets](https://github.com/toncenter/examples/blob/main/deposits.js) (tonweb) - * [Withdrawal process](https://github.com/toncenter/examples/blob/main/withdrawals.js) (tonweb) - * [Payment channel example](https://github.com/toncenter/payment-channels-example/blob/main/index.js) (tonweb) -* [TON Bridge front-end](https://github.com/ton-blockchain/bridge) (Vue.js, no comments) -* [Web Wallet source code](https://github.com/toncenter/ton-wallet) (tonweb, no comments) -* [Bot for sales of dumplings](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-js) - - -### Python - -- [psylopank/pytonlib examples](https://github.com/psylopunk/pytonlib/tree/main/examples) -- [Transfer NFT & Jettons by creating a transfer message from the owner wallet](https://github.com/tonfactory/tonsdk#transfer-nft--jettons-by-creating-a-transfer-message-from-an-owner-wallet) -- [Create mnemonic, init wallet class, create an external message to deploy the wallet](https://github.com/tonfactory/tonsdk#create-mnemonic-init-wallet-class-create-external-message-to-deploy-the-wallet) -- [Storefront bot with payments in TON](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot) -- [Bot with own balance](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-2) - -### Go - -- [10+ examples from xssnick/tonutils-go](https://github.com/xssnick/tonutils-go/tree/master/example) -- [7+ examples from tonkeeper/tongo](https://github.com/tonkeeper/tongo/tree/master/example) - -## TON SDKs - -Learn the complete list of The Open Network SDKs from the SDKs page: -* [SDK](/develop/dapps/apis/sdk) - - -## Telegram WebApps (TWA) - -- [Telegram WebApps Documentation](https://core.telegram.org/bots/webapps) — full description on Telegram website. - -### TWA SDKs - -- [ton-defi-org/tonstarter-twa](https://github.com/ton-defi-org/tonstarter-twa) — template for new TWA interaction with TON -- [twa-dev/boilerplate](https://github.com/twa-dev/Boilerplate) — another boilerplate for a new TWA. -- [twa-dev/sdk](https://github.com/twa-dev/sdk) — NPM package for TWA SDK -- [twa-dev/Mark42](https://github.com/twa-dev/Mark42) — Mark42 is a simple lightweight tree-shakable UI library for TWA - -:::info Community -Join a special Telegram [Community Chat](https://t.me/+1mQMqTopB1FkNjIy) for TWA developers if you're interested. -::: - -## Authorization SDK - -To add login button to your website or web app use the following: - -### TON Connect - -[ton-connect]( -/develop/dapps/ton-connect) is a unified authorization standard for every wallet in the TON ecosystem. It's supported and developed by Tonkeeper team with tech advisors from TON Community. - -#### Documentation - -* [Introducing TON Connect](/develop/dapps/ton-connect) -* [TON Connect for Developers](/develop/dapps/ton-connect/developers) -* [TON Connect 2.0 vs 1.0](/develop/dapps/ton-connect/comparison) -* [ton-connect/wallets-list](https://github.com/ton-connect/wallets-list) — list of supported wallets (add yours!) - - -### Usage examples - -- [Desktop standard wallet (C++ and Qt)](https://github.com/ton-blockchain/wallet-desktop) -- [Android standard wallet (Java)](https://github.com/ton-blockchain/wallet-android) -- [iOS standard wallet (Swift)](https://github.com/ton-blockchain/wallet-ios) -- [TonLib CLI (C++)](https://github.com/ton-blockchain/ton/blob/master/tonlib/tonlib/tonlib-cli.cpp) - -## APIs - -- Go to [API](/develop/dapps/apis) section to read more about APIs in TON diff --git a/docs/develop/dapps/README.mdx b/docs/develop/dapps/README.mdx new file mode 100644 index 0000000000..fd4d962251 --- /dev/null +++ b/docs/develop/dapps/README.mdx @@ -0,0 +1,92 @@ +import Button from '@site/src/components/button' + +# Overview + +To start with DApps on TON, you need to understand the basics of the blockchain and the TON architecture. You can find this information in the [Concepts](/learn/introduction) section. + +Comparing to the pure [Smart Contracts](/develop/smart-contracts/) development, DApps development is more complex. You need to understand [how to work with APIs](/develop/dapps/apis/), how to use authenticate user using [TON Connect](/develop/dapps/ton-connect/overview) and how to use [SDKs](/develop/dapps/apis/sdk) to work with the blockchain. + + + + +## Basic tools + +Here you can see links to the most important resources for you to get started with TON: + +- [Wallet Apps for Developers](/participate/wallets/apps) — to create and manage wallets. +- [List of Explorers](/participate/explorers) — to view the state of the blockchain. +- [API Types](/develop/dapps/apis/) — different ways to interact with the blockchain. +- [List of SDKs](/develop/dapps/apis/sdk) — list of SDKs for different languages and APIs. +- [Testnet and how to use it](/develop/smart-contracts/environment/testnet) — to test your contracts. +- [TON Unfreezer](https://unfreezer.ton.org/) - to unfreeze contracts that ran out of gas for rent. + +## Introduction to DeFi + +* [Toncoin processing](/develop/dapps/defi/coins) +* [Tokens on TON (Jettons & NFTs)](/develop/dapps/defi/tokens) +* [TON Payments](/develop/dapps/defi/ton-payments) +* [Subscriptions on TON](/develop/dapps/defi/subscriptions) + +### Payments processing + +* [Payment processing](/develop/dapps/asset-processing/) +* [NFT processing](/develop/dapps/asset-processing/nft) +* [Metadata parsing](/develop/dapps/asset-processing/metadata) + +## Tutorials and examples + +### Basics + +* Jettons (Tokens): [Mint your first Jetton](/develop/dapps/tutorials/jetton-minter) +* NFTs: [Step by step NFT collection minting](/develop/dapps/tutorials/collection-minting) + + +### JavaScript + +* Payment processing using JavaScript: + * [Create a key pair and a wallet](https://github.com/toncenter/examples/blob/main/common.js) (tonweb) + * [Accepting deposits to a single wallet](https://github.com/toncenter/examples/blob/main/deposits-single-wallet.js) (tonweb) + * [Accepting deposits to multiple wallets](https://github.com/toncenter/examples/blob/main/deposits.js) (tonweb) + * [Withdrawal process](https://github.com/toncenter/examples/blob/main/withdrawals.js) (tonweb) + * [Payment channel example](https://github.com/toncenter/payment-channels-example/blob/main/index.js) (tonweb) +* [TON Bridge front-end](https://github.com/ton-blockchain/bridge) (Vue.js, no comments) +* [Web Wallet source code](https://github.com/toncenter/ton-wallet) (tonweb, no comments) +* [Bot for sales of dumplings](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-js) + + +### Python + +- [psylopank/pytonlib examples](https://github.com/psylopunk/pytonlib/tree/main/examples) +- [Transfer NFT & Jettons by creating a transfer message from the owner wallet](https://github.com/tonfactory/tonsdk#transfer-nft--jettons-by-creating-a-transfer-message-from-an-owner-wallet) +- [Create mnemonic, init wallet class, create an external message to deploy the wallet](https://github.com/tonfactory/tonsdk#create-mnemonic-init-wallet-class-create-external-message-to-deploy-the-wallet) +- [Storefront bot with payments in TON](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot) +- [Bot with own balance](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-2) + +### Go + +- [10+ examples from xssnick/tonutils-go](https://github.com/xssnick/tonutils-go/tree/master/example) +- [7+ examples from tonkeeper/tongo](https://github.com/tonkeeper/tongo/tree/master/example) + +### ZK + +* [Simple ZK on TON](/develop/dapps/tutorials/simple-zk-on-ton) + +### Wallets examples + +- [Desktop standard wallet (C++ and Qt)](https://github.com/ton-blockchain/wallet-desktop) +- [Android standard wallet (Java)](https://github.com/ton-blockchain/wallet-android) +- [iOS standard wallet (Swift)](https://github.com/ton-blockchain/wallet-ios) +- [TonLib CLI (C++)](https://github.com/ton-blockchain/ton/blob/master/tonlib/tonlib/tonlib-cli.cpp) + +### No necessary material? + +You have 2 ways here: write tutorial by you own or describe the problem for the community. + + + diff --git a/docs/develop/dapps/apis/README.md b/docs/develop/dapps/apis/README.md index 79fb649a5f..0c99044c34 100644 --- a/docs/develop/dapps/apis/README.md +++ b/docs/develop/dapps/apis/README.md @@ -1,9 +1,7 @@ -# Overview +# API Types **High availability blockchain APIs is the core element of secure, convenient and fast development of useful applications in TON.** -## API Types - - [TON Center API](/develop/dapps/apis/toncenter) — fast and reliable HTTP API for The Open Network. Based on tonlib allows to get all information about accounts, transactions and blocks. - [TON HTTP API](https://tonapi.io/) — API that allows to work with the _indexed blockchain information_. - [TON ADNL API](/develop/dapps/apis/adnl) — secure API to communicate TON, based on ADNL protocol. @@ -250,7 +248,5 @@ curl -X 'GET' \ ## See Also * [TON Center API](/develop/dapps/apis/toncenter) -* [SDKs](/develop/dapps/apis/sdk) -* [SDKs](/develop/dapps/apis/sdk) -* [Apps Examples](/develop/dapps/examples) +* [List of SDKs](/develop/dapps/apis/sdk) * [Smart Contract Examples](/develop/smart-contracts/examples) \ No newline at end of file diff --git a/docs/develop/dapps/examples.md b/docs/develop/dapps/examples.md deleted file mode 100644 index eb5f7de448..0000000000 --- a/docs/develop/dapps/examples.md +++ /dev/null @@ -1,22 +0,0 @@ -# Examples - -### JavaScript - -- [A standard web wallet](https://github.com/toncenter/ton-wallet) (Plain JS) -- [Bridge frontend](https://github.com/ton-blockchain/bridge) (Vue.js) -- [Bot for sales of dumplings](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-js) - -### TypeScript -- [nns2009/ton-payment-tracker](https://github.com/nns2009/ton-payment-tracker) - -### Python - -- [Transfer NFT & Jettons by creating a transfer message from the owner wallet](https://github.com/tonfactory/tonsdk#transfer-nft--jettons-by-creating-a-transfer-message-from-an-owner-wallet) -- [Create mnemonic, init wallet class, create an external message to deploy the wallet](https://github.com/tonfactory/tonsdk#create-mnemonic-init-wallet-class-create-external-message-to-deploy-the-wallet) -- [Storefront bot with payments in TON](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot) -- [Bot with own balance](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-2) - -### Go - -- [10+ examples from xssnick/tonutils-go](https://github.com/xssnick/tonutils-go/tree/master/example) -- [nns2009/ton-payment-tracker](https://github.com/nns2009/ton-payment-tracker) diff --git a/docs/develop/dapps/ton-connect/README.mdx b/docs/develop/dapps/ton-connect/README.mdx index e7356d8799..6053f4437d 100644 --- a/docs/develop/dapps/ton-connect/README.mdx +++ b/docs/develop/dapps/ton-connect/README.mdx @@ -1,7 +1,7 @@ import Button from '@site/src/components/button' import ThemedImage from '@theme/ThemedImage'; -# Overview +# How TON Connect works TON Connect is a communication protocol between **wallets** and **apps** in TON. @@ -16,6 +16,8 @@ TON Connect is a communication protocol between **wallets** and **apps** in TON. />

+## Bird's eye view + **Apps** built on TON provide rich functionality and high performance and are designed to protect user funds via smart contracts. Because apps are built using decentralized technologies such as Blockchain, they are typically called decentralized applications (dApps). **Wallets** provide the UI to approving transactions and hold users’ cryptographic keys securely on their personal devices. @@ -23,70 +25,10 @@ This separation of concerns enables rapid innovation and high level of security TON Connect aims to offer a seamless user experience between wallets and apps. - - - -## Third-Party TON Services Compatible with TON Connect 2.0 - -- [Getgems — The Open Network Marketplace](https://getgems.io/) -- [STON.fi — AMM DEX for TON blockchain](https://ston.fi/) -- [Tonstarter](http://tonstarter.com/) - -
- Show the entire list - -* [getgems.io](https://getgems.io/) -* [fragment.com](https://fragment.com/) (Ton Connect v.1) -* [ston.fi](https://ston.fi/) -* [ton.diamonds](https://ton.diamonds/) -* [beta.disintar.io](https://beta.disintar.io/) -* [tegro.finance](https://tegro.finance/liquidity) -* [minter.ton.org](https://minter.ton.org/) -* [libermall.com](https://libermall.com/) -* [dedust.io](https://dedust.io/swap) -* [toncap.net](https://toncap.net/) -* [cryptomus.com](https://cryptomus.com/) -* [avanchange.com](https://avanchange.com/) -* [wton.dev](https://wton.dev/) -* [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) -* [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) -* [tonverifier.live](https://verifier.ton.org/) -* [stickerface.io/member](https://stickerface.io/member) -* [tonstarter.com](https://tonstarter.com/) -* [cryptogas.shop/ton](https://cryptogas.shop/ton) -* [megaton.fi](https://megaton.fi/) -* [dns.ton.org](https://dns.ton.org/) -* [coinpaymaster.com](https://coinpaymaster.com/) -* [ton.gagarin.world/app/](https://ton.gagarin.world/app) -* [daolama.co](https://daolama.co/) -* [marketplace.playmuse.org](http://marketplace.playmuse.org/) -* [ton.vote](https://ton.vote/) -* [plane.tonfancy.io](https://plane.tonfancy.io/) -* [pi.oberton.io](https://pi.oberton.io/) -* [business.thetonpay.app](https://business.thetonpay.app/) -* [bridge.orbitchain.io](https://bridge.orbitchain.io/) -* [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) -* [app.fanz.ee/staking](https://app.fanz.ee/staking) -* [testnet.pton.fi](https://testnet.pton.fi/) -* [tonft.app](https://tonft.app/) -* [cardify.casino](https://cardify.casino/) -* [4riends.org](https://4riends.org/#/) -* [tonflex.fi](https://tonflex.fi/swap) -* [soquest.xyz](https://soquest.xyz/) -* [app.evaa.finance](https://app.evaa.finance/) - -
- -## Why TON Connect? +## See also - [TON Connect for Business](/develop/dapps/ton-connect/business) -- [TON Connect for Developers](/develop/dapps/ton-connect/developers) -- [TON Connect for Security](/develop/dapps/ton-connect/security) +- [TON Connect Security](/develop/dapps/ton-connect/security) - [TON Connect 2.0 vs 1.0](/develop/dapps/ton-connect/comparison) -## TON Connect Integration Manual -In order to integrate TON Connect with your application, please see our [integration manual](/develop/dapps/ton-connect/integration) detailing the main steps to carry out this process. diff --git a/docs/develop/dapps/ton-connect/best-practices.md b/docs/develop/dapps/ton-connect/best-practices.md new file mode 100644 index 0000000000..00ef5ae83c --- /dev/null +++ b/docs/develop/dapps/ton-connect/best-practices.md @@ -0,0 +1,3 @@ +# Best Practices + +TODO \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/developers.md b/docs/develop/dapps/ton-connect/developers.md index 78f7981143..d8d23f7d63 100644 --- a/docs/develop/dapps/ton-connect/developers.md +++ b/docs/develop/dapps/ton-connect/developers.md @@ -1,60 +1,72 @@ -# TON Connect for Developers +# TON Connect SDKs + +## SDK List + +:::info +If possible, it is recommended to use the [@tonconnect/ui-react](/develop/dapps/ton-connect/developers#ton-connect-ui-react) kit for your dApps. Only switch to lower levels of the SDK or reimplement your version of the protocol if it is really necessary for your product. +::: -## SDK LIst This page contents the list of useful libraries for TON Connect. +* [TON Connect React](/develop/dapps/ton-connect/developers#ton-connect-react) * [TON Connect JS SDK](/develop/dapps/ton-connect/developers#ton-connect-js-sdk) * [TON Connect Python SDK](/develop/dapps/ton-connect/developers#ton-connect-python) * [TON Connect Dart](/develop/dapps/ton-connect/developers#ton-connect-dart) -## TON Connect JS SDK -:::info -If possible, it is recommended to use the [@tonconnect/ui-react](/develop/dapps/ton-connect/developers#ton-connect-ui-react) kit for your dApps. Only switch to lower levels of the SDK or reimplement your version of the protocol if it is really necessary for your product. -::: - -The TON Connect repository contains following main packages: +## TON Connect React - [@tonconnect/ui-react](/develop/dapps/ton-connect/developers#ton-connect-ui-react) - TON Connect User Interface (UI) for React applications -- [@tonconnect/ui](/develop/dapps/ton-connect/developers#ton-connect-ui) - TON Connect User Interface (UI) -- [@tonconnect/sdk](/develop/dapps/ton-connect/developers#ton-connect-sdk) - TON Connect SDK -- [@tonconnect/protocol](/develop/dapps/ton-connect/developers#ton-connect-protocol-models) - TON Connect protocol specifications +TonConnect UI React is a React UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol in React apps. -### TON Connect UI React +* Example of a DApp with `@tonconnect/ui-react`: [GitHub](https://github.com/ton-connect/demo-dapp-with-react-ui) +* Example of deployed `demo-dapp-with-react-ui`: [GitHub](https://ton-connect.github.io/demo-dapp-with-react-ui/) -TonConnect UI React is a React UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol in React apps. +```bash +npm i @tonconnect/ui-react +``` - [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/ui-react) - [NPM](https://www.npmjs.com/package/@tonconnect/ui-react) -- [TON Connect UI React API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui_react.html) +- [API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui_react.html) + + +## TON Connect JS SDK + +The TON Connect repository contains following main packages: + +- [@tonconnect/ui](/develop/dapps/ton-connect/developers#ton-connect-ui) - TON Connect User Interface (UI) +- [@tonconnect/sdk](/develop/dapps/ton-connect/developers#ton-connect-sdk) - TON Connect SDK +- [@tonconnect/protocol](/develop/dapps/ton-connect/developers#ton-connect-protocol-models) - TON Connect protocol specifications -* Example of a dApp with @tonconnect/ui-react: [GitHub](https://github.com/ton-connect/demo-dapp-with-react-ui) -* Example of deployed demo-dapp-with-react-ui: [GitHub](https://ton-connect.github.io/demo-dapp-with-react-ui/) ### TON Connect UI TonConnect UI is a UI kit for TonConnect SDK. Use it to connect your app to TON wallets via TonConnect protocol. It allows you to integrate TonConnect to your app easier using our UI elements such as "connect wallet button", "select wallet dialog" and confirmation modals. +```bash +npm i @tonconnect/ui +``` + - [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/ui) - [NPM](https://www.npmjs.com/package/@tonconnect/ui) -- [TON Connect UI API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui.html) +- [API Documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui.html) +The TON Connect User Interface (UI) is a framework that allows developers to improve the user experience (UX) for application users. -The TON Connect User Interface (UI) is a framework that allows developers to improve the user experience (UX) for application users. TON Connect can easily be integrated with apps using simple UI elements such as the "connect wallet button", "select wallet dialog" and confirmation modals. Here are three main examples of how TON Connect improves UX in apps: +TON Connect can easily be integrated with apps using simple UI elements such as the "connect wallet button", "select wallet dialog" and confirmation modals. Here are three main examples of how TON Connect improves UX in apps: * Example of app functionality in the dApp browser: [GitHub](https://ton-connect.github.io/demo-dapp/) - * Example of a backend partition of the dApp above: [GitHub](https://github.com/ton-connect/demo-dapp-backend) - * Bridge server using Go: [GitHub](https://github.com/ton-connect/bridge) -This kit will simplify the implementation of TON Connect in apps built for TON Blockchain. Standard frontend frameworks are supported, as well as applications that don’t use predetermined frameworks +This kit will simplify the implementation of TON Connect in apps built for TON Blockchain. Standard frontend frameworks are supported, as well as applications that don’t use predetermined frameworks. ### TON Connect SDK -The first of the three frameworks that helps developers integrate TON Connect into their applications is the TON Connect SDK. It is primarily used to connect apps to TON Wallets via the TON Connect protocol. +The most low-level of the three frameworks that helps developers integrate TON Connect into their applications is the TON Connect SDK. It is primarily used to connect apps to TON Wallets via the TON Connect protocol. - [GitHub](https://github.com/ton-connect/sdk/tree/main/packages/sdk) - [NPM](https://www.npmjs.com/package/@tonconnect/sdk) @@ -70,13 +82,11 @@ This package contains protocol requests, protocol responses, event models and en ## TON Connect Python -Python SDK for TON Connect 2.0 - -Analogue of the @tonconnect/sdk library. +Python SDK for TON Connect 2.0. Analogue of the `@tonconnect/sdk` library. Use it to connect your app to TON wallets via TonConnect protocol. -```python +```bash pip3 install pytonconnect ``` @@ -87,13 +97,11 @@ pip3 install pytonconnect ## TON Connect Dart -Dart SDK for TON Connect 2.0 - -Analogue of the @tonconnect/sdk library. +Dart SDK for TON Connect 2.0. Analogue of the `@tonconnect/sdk` library. Use it to connect your app to TON wallets via TonConnect protocol. -```dart +```bash $ dart pub add darttonconnect ``` @@ -107,6 +115,8 @@ If you experience any additional issues, or would like to present a proposal on ## See Also +* [Step by step guide for building your first web client](https://ton-community.github.io/tutorials/03-client/) +* [[YouTube] TON Smart Contracts | 10 | Telegram dapp [EN]](https://www.youtube.com/watch?v=D6t3eZPdgAU&t=254s&ab_channel=AlefmanVladimir%5BEN%5D) * [Ton Connect Getting started](https://github.com/ton-connect/sdk/tree/main/packages/sdk) * [Integration Manual](/develop/dapps/ton-connect/integration) -* [[YouTube] TON Dev Study TON Connect Protocol [RU]](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCJ226xS5_dKmXXxWx1CKz_) \ No newline at end of file +* [[YouTube] TON Dev Study TON Connect Protocol [RU]](https://www.youtube.com/playlist?list=PLyDBPwv9EPsCJ226xS5_dKmXXxWx1CKz_) diff --git a/docs/develop/dapps/ton-connect/integration.md b/docs/develop/dapps/ton-connect/integration.md index 6c91380ec7..c1309a8182 100644 --- a/docs/develop/dapps/ton-connect/integration.md +++ b/docs/develop/dapps/ton-connect/integration.md @@ -1,11 +1,11 @@ -# Integration manual +# Integration manual with the JavaScript SDK In this tutorial, we’ll create a sample web app that supports TON Connect 2.0 authentication. It will allow for signature verification to eliminate the possibility of fraudulent identity impersonation without agreement establishment between parties. ## Documentation links -1. [TON Connect SDK documentation](https://www.npmjs.com/package/@tonconnect/sdk) -2. [Wallet-application message exchange protocol](https://github.com/ton-connect/docs/blob/main/requests-responses.md), includes manifest format. +1. [@tonconnect/sdk documentation](https://www.npmjs.com/package/@tonconnect/sdk) +2. [Wallet-application message exchange protocol](https://github.com/ton-connect/docs/blob/main/requests-responses.md) 3. [Tonkeeper implementation of wallet side](https://github.com/tonkeeper/wallet/tree/main/src/tonconnect) ## Prerequisites @@ -14,7 +14,7 @@ In order for connectivity to be fluent between apps and wallets, the web app mus ## Getting wallets support list -To increase the overall adoption of TON Blockchain, it is necessary that TON Connect 2.0 is able to facilitate a vast number of application and wallet connectivity integrations. Of late and of significant importance, the ongoing development of TON Connect 2.0 has allowed for the connection of the Tonkeeper and OpenMask wallets with various TON Ecosystem Apps. It is our mission to eventually allow for the exchange of data between applications and all wallet types built on TON via the TON Connect protocol. For now, this is realized by providing the ability for TON Connect to load an extensive list of available wallets currently operating within the TON Ecosystem. +To increase the overall adoption of TON Blockchain, it is necessary that TON Connect 2.0 is able to facilitate a vast number of application and wallet connectivity integrations. Of late and of significant importance, the ongoing development of TON Connect 2.0 has allowed for the connection of the Tonkeeper, TonHub, MyTonWallet and other wallets with various TON Ecosystem Apps. It is our mission to eventually allow for the exchange of data between applications and all wallet types built on TON via the TON Connect protocol. For now, this is realized by providing the ability for TON Connect to load an extensive list of available wallets currently operating within the TON Ecosystem. At the moment our sample web app enables the following: @@ -46,7 +46,7 @@ For learning purposes, let's take a looks at the HTML page described by the foll If you load this page in browser and look into console, you may get something like that: -```js +```bash > Array [ {…}, {…} ] 0: Object { name: "Tonkeeper", imageUrl: "https://tonkeeper.com/assets/tonconnect-icon.png", aboutUrl: "https://tonkeeper.com", … } @@ -60,15 +60,6 @@ If you load this page in browser and look into console, you may get something li name: "Tonkeeper" tondns: "tonkeeper.ton" universalLink: "https://app.tonkeeper.com/ton-connect" - -1: Object { name: "OpenMask", imageUrl: "https://raw.githubusercontent.com/OpenProduct/openmask-extension/main/public/openmask-logo-288.png", aboutUrl: "https://www.openmask.app/", … } - aboutUrl: "https://www.openmask.app/" - embedded: false - imageUrl: "https://raw.githubusercontent.com/OpenProduct/openmask-extension/main/public/openmask-logo-288.png" - injected: false - jsBridgeKey: "openmask" - name: "OpenMask" - tondns: undefined ``` According to TON Connect 2.0 specifications, wallet app information always makes use of the following format: @@ -240,11 +231,7 @@ Upon clicking the mobile phone link, Tonkeeper automatically opens and then clos `Error: [TON_CONNECT_SDK_ERROR] Can't get null/tonconnect-manifest.json`. This means the application manifest must be available for download. - -### Logging in with OpenMask - -OpenMask didn't inject its information in the window, so connecting with it failed. The most probable reason is because a local page for the web app was used. - + ## Connection with using app manifest Starting from this point forward, it is necessary to host user files (mostly tonconnect-manifest.json) somewhere. In this instance we’ll use the manifest from another web application. This however is not recommended for production environments, but allowed for testing purposes. @@ -292,7 +279,7 @@ Therefore, the user is able to accept the same login request if the link is save Afterwards, the login request is accepted and is immediately reflected in the browser console as follows: -```js +```bash 22:40:13.887 Connection status: Object { device: {…}, provider: "http", account: {…} } account: Object { address: "0:b2a1ec...", chain: "-239", walletStateInit: "te6cckECFgEAAwQAAgE0ARUBFP8A9..." } @@ -307,7 +294,7 @@ The results above take the following into consideration: ## Logging out and requesting TonProof -Now we have logged into our webapp, but... how does the backend know that it is the correct party? To verify this we must request the wallet ownership proof. +Now we have logged into our Web App, but... how does the backend know that it is the correct party? To verify this we must request the wallet ownership proof. This can be completed only using authentication, so we must log out. Therefore, we run the following code in the console: diff --git a/docs/develop/dapps/ton-connect/manifest.md b/docs/develop/dapps/ton-connect/manifest.md new file mode 100644 index 0000000000..68c1bcb749 --- /dev/null +++ b/docs/develop/dapps/ton-connect/manifest.md @@ -0,0 +1,39 @@ + +# Creating manifest.json + +Every app needs to have its manifest to pass meta information to the wallet. Manifest is a JSON file named as `tonconnect-manifest.json` following format: + +```json +{ + "url": "", // required + "name": "", // required + "iconUrl": "", // required + "termsOfUseUrl": "", // optional + "privacyPolicyUrl": "" // optional +} +``` + +## Example + +You can find an example of the manifest below: + +```json +{ + "url": "https://ton.vote", + "name": "TON Vote", + "iconUrl": "https://ton.vote/logo.png" +} +``` +## Best practices + +- Best practice is to place the manifest in the root of your app and repository, e.g. `https://myapp.com/tonconnect-manifest.json`. It allows the wallet to handle your app better and improve the UX connected to your app. +- Make sure that `manifest.json` file is available to GET by its URL. + +## Fields description +|Field|Requirement|Description| +|---|---|---| +|`url` |required| app URL. Will be used as the dapp identifier. Will be used to open the dapp after click to its icon in the wallet. It is recommended to pass url without closing slash, e.g. 'https://mydapp.com' instead of 'https://mydapp.com/'.| +| `name`|required| app name. Might be simple, will not be used as identifier.| +| `iconUrl`| required | Url to the app icon. Must be PNG, ICO, ... format. SVG icons are not supported. Perfectly pass url to a 180x180px PNG icon.| +| `termsOfUseUrl` |optional| url to the Terms Of Use document. Optional for usual apps, but required for the apps which is placed in the Tonkeeper recommended apps list.| +| `privacyPolicyUrl` | optional | url to the Privacy Policy document. Optional for usual apps, but required for the apps which is placed in the Tonkeeper recommended apps list.| diff --git a/docs/develop/dapps/ton-connect/message-builders.mdx b/docs/develop/dapps/ton-connect/message-builders.mdx new file mode 100644 index 0000000000..2308ead615 --- /dev/null +++ b/docs/develop/dapps/ton-connect/message-builders.mdx @@ -0,0 +1,1072 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Preparing Messages + +While using TON Connect, you should construct the Message Body for the Payload used in various transactions. On this page you can find the most relevant examples of payload for use with the TON Connect SDKs. + +:::info +It is expected, that you learn basics on the creating TON Connect connection. Learn more with the [integration manual](/develop/dapps/ton-connect/integration). +::: + + +## TON Connect JS SDK Examples + +### Transaction Template + +No matter what level of the task developer are solving, typically it is necessary to use connector entity from @tonconnect/sdk or @tonconnect/ui. +Examples created based on @tonconnect/sdk and @tonconnect/ui: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +const [tonConnectUI] = useTonConnectUI(); + +const transaction = { + //transaction body +}) + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + +```js +import TonConnectUI from '@tonconnect/ui'; + +const tonConnectUI = new TonConnectUI({ //connect application + manifestUrl: 'https:///tonconnect-manifest.json', + buttonRootId: '' +}); + +const transaction = { + //transaction body +} + +const result = await tonConnectUI.sendTransaction(transaction) + +``` + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); + +await connector.sendTransaction({ + //transaction body +}) + +``` + + + +
+ +### Regular TON Transfer + +TON Connect SDKs include wrappers for sending messages, making it easy to prepare regular transfers of Toncoins between two wallets as default transaction without payload. + +A regular TON transfer using the TON Connect JS SDKs can be executed as follows: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; +const [tonConnectUI] = useTonConnectUI(); + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] + +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui'; + +const tonConnectUI = new TonConnectUI({ //connect application + manifestUrl: 'https:///tonconnect-manifest.json', + buttonRootId: '' +}); + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); + +await connector.sendTransaction({ + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] +}) + +``` + +
+ +:::tip +Learn more about [TON Smart Contract Addresses](/learn/overviews/addresses). +::: + +For specific custom transaction, a certain payload must be defined. + + + + +### Transfer With a Comment + +The simplest example is adding a payload with a comment. See more details on [this page](/develop/smart-contracts/guidelines/internal-messages#simple-message-with-comment). +Before transaction, it is necessary prepare a `body` [cell](/develop/data-formats/cell-boc) via the [@ton/ton](https://github.com/ton-org/ton) JavaScript library. + +```js +import { beginCell } from '@ton/ton' + +const body = beginCell() + .storeUint(0, 32) // write 32 zero bits to indicate that a text comment will follow + .storeStringTail("Hello, TON!") // write our text comment + .endCell(); +``` + +The transaction body is created by the following: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano("0.05"), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano("0.05"), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); + +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: destination, + amount: toNano("0.05"), + payload: body.toBoc().toString("base64") // payload with comment in body + } + ] +}) +``` + +
+ + +### Jetton Transfer + +The `body` for Jetton Transfer([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#1-transfer)) typically should be done according the following way: + +```js + import {beginCell, toNano} from '@ton/ton' + // 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; + + const body = beginCell() + .storeUint(0xf8a7ea5, 32) // jetton transfer op code + .storeUint(0, 64) // query_id:uint64 + .storeCoins(1000000) // amount:(VarUInteger 16) - Jetton amount for transfer (decimals = 6 - jUSDT, 9 - default) + .storeAddress(Wallet_DST) // destination:MsgAddress + .storeAddress(Wallet_SRC) // response_destination:MsgAddress + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) + .storeCoins(toNano(0.05)) // forward_ton_amount:(VarUInteger 16) + .storeUInt(0,1) // forward_payload:(Either Cell ^Cell) + .endCell(); +``` + +Next, sending the transaction with this body to sender's jettonWalletContract executed: + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +import TonConnect from '@tonconnect/sdk'; +const connector = new TonConnect(); +//... +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // sender jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with jetton transfer body + } + ] +}) +``` + + +
+ + +- `validUntil` - UNIX-time until message valid +- `jettonWalletAddress` - Address, JettonWallet address, that defined based on JettonMaser and Wallet contracts +- `balance` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the jettonContract + + +
+ Jetton Wallet State Init and Address preparation example + + +```js +import { Address, TonClient, beginCell, StateInit, storeStateInit } from '@ton/ton' + +async function main() { + const client = new TonClient({ + endpoint: 'https://toncenter.com/api/v2/jsonRPC', + apiKey: 'put your api key' + }) + + const jettonWalletAddress = Address.parse('Sender_Jetton_Wallet'); + let jettonWalletDataResult = await client.runMethod(jettonWalletAddress, 'get_wallet_data'); + jettonWalletDataResult.stack.readNumber(); + const ownerAddress = jettonWalletDataResult.stack.readAddress(); + const jettonMasterAddress = jettonWalletDataResult.stack.readAddress(); + const jettonCode = jettonWalletDataResult.stack.readCell(); + const jettonData = beginCell() + .storeCoins(0) + .storeAddress(ownerAddress) + .storeAddress(jettonMasterAddress) + .storeRef(jettonCode) + .endCell(); + + const stateInit: StateInit = { + code: jettonCode, + data: jettonData + } + + const stateInitCell = beginCell() + .store(storeStateInit(stateInit)) + .endCell(); + + console.log(new Address(0, stateInitCell.hash())); +} +``` + +
+ +### Jetton Burn + +The `body` for Jetton Burn([TEP-74](https://github.com/ton-blockchain/TEPs/blob/master/text/0074-jettons-standard.md#2-burn)) typically should be done according the following way: + + +```js + import {beginCell} from '@ton/ton' +// burn#595f07bc query_id:uint64 amount:(VarUInteger 16) +// response_destination:MsgAddress custom_payload:(Maybe ^Cell) +// = InternalMsgBody; + + const body = beginCell() + .storeUint(0x595f07bc, 32) // jetton burn op code + .storeUint(0, 64) // query_id:uint64 + .storeCoins(1000000) // amount:(VarUInteger 16) - Jetton amount in decimal + .storeAddress(Wallet_SRC) // response_destination:MsgAddress - owner's wallet + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) - w/o payload typically + .endCell(); +``` + +Message places into the following request: + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // owner's jetton wallet + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a jetton burn body + } + ] +}) +``` + + +
+ +- `jettonWalletAddress` - Jetton Wallet contract address, that defined based on JettonMaser and Wallet contracts +- `amount` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the jetton wallet with the `burn#595f07bc` op code + +### NFT Transfer + +The `body` message typically should be done according the following way: + +```js +import { beginCell, toNano} from '@ton/ton' + +// transfer#5fcc3d14 query_id:uint64 new_owner:MsgAddress response_destination:MsgAddress custom_payload:(Maybe ^Cell) +// forward_amount:(VarUInteger 16) forward_payload:(Either Cell ^Cell) = InternalMsgBody; + + const body = beginCell() + .storeUint(0x5fcc3d14, 32) // NFT transfer op code 0x5fcc3d14 + .storeUint(0, 64) // query_id:uint64 + .storeAddress(NEW_OWNER_WALLET) // new_owner:MsgAddress + .storeAddress(Wallet_DST) // response_destination:MsgAddress + .storeUint(0, 1) // custom_payload:(Maybe ^Cell) + .storeCoins(toNano('0.000000001')) // forward_amount:(VarUInteger 16) + .storeUint(0,1) // forward_payload:(Either Cell ^Cell) + .endCell(); +``` + +`WALLET_DST` - Address - The address of the initial NFT owner for the receiving excess +Transfer the `NFTitem` to a new owner `NEW_OWNER_WALLET`. + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: jettonWalletContract, // NFT Item address, which will be transferred + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, // NFT Item address, which will be transferred + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, // NFT Item address, which will be transferred + amount: toNano("0.05"), // for commission fees, excess will be returned + payload: body.toBoc().toString("base64") // payload with a NFT transfer body + } + ] +}) +``` + +
+ +- `NFTitem` - Address - The address of NFT item smart contract which we want transfer to a new owner `NEW_OWNER_WALLET`. +- `balance` - Integer, amount of Toncoin for gas payments in nanotons. +- `body` - payload for the NFT contract + +### NFT Sale (GetGems) + +Here is an example of preparing message and transaction for sale on GetGems marketplace, according to contract [nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc). + +To place NFT on GetGems Sale Contract, we should prepare special message body `transferNftBody` that will be transfer NFT to special NFT Sale Contract. +```js + const transferNftBody = beginCell() + .storeUint(0x5fcc3d14, 32) // Opcode for NFT transfer + .storeUint(0, 64) // query_id + .storeAddress(destinationAddress) // new_owner + .storeAddress(walletAddress) // response_destination for excesses + .storeBit(0) // we do not have custom_payload + .storeCoins(toNano("1")) // forward_amount + .storeBit(0) // we store forward_payload is this cell + .storeUint(0x0fe0ede, 31) // not 32, because previous 0 will be read as do_sale opcode in deployer + .storeRef(stateInitCell) + .storeRef(saleBody) + .endCell(); +``` + +Because message requires a lot of steps, the entire algorithm huge and could be found here: +
+ Show entire algorithm for the creating NFT Sale message body + + +```js +import { Address, beginCell, StateInit, storeStateInit, toNano, Cell } from '@ton/ton' + +async function main() { + const fixPriceV3R2Code = Cell.fromBase64('te6cckECCwEAArkAART/APSkE/S88sgLAQIBIAIDAgFIBAUAfvIw7UTQ0wDTH/pA+kD6QPoA1NMAMMABjh34AHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVOBfB4IA//7y8AICzQYHAFegOFnaiaGmAaY/9IH0gfSB9AGppgBgYaH0gfQB9IH0AGEEIIySsKAVgAKrAQH30A6GmBgLjYSS+CcH0gGHaiaGmAaY/9IH0gfSB9AGppgBgYOCmE44BgAEqYhOmPhW8Q4YBKGATpn8cIxbMbC3MbK2QV44LJOZlvKAVxFWAAyS+G8BJrpOEBFcCBFd0VYACRWdjYKdxjgthOjq+G6hhoaYPqGAD9gHAU4ADAgB92YIQO5rKAFJgoFIwvvLhwiTQ+kD6APpA+gAwU5KhIaFQh6EWoFKQcIAQyMsFUAPPFgH6AstqyXH7ACXCACXXScICsI4XUEVwgBDIywVQA88WAfoCy2rJcfsAECOSNDTiWnCAEMjLBVADzxYB+gLLaslx+wBwIIIQX8w9FIKAejy0ZSzjkIxMzk5U1LHBZJfCeBRUccF8uH0ghAFE42RFrry4fUD+kAwRlAQNFlwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VTgMDcowAPjAijAAJw2NxA4R2UUQzBw8AXgCMACmFVEECQQI/AF4F8KhA/y8AkA1Dg5ghA7msoAGL7y4clTRscFUVLHBRWx8uHKcCCCEF/MPRQhgBDIywUozxYh+gLLassfFcs/J88WJ88WFMoAI/oCE8oAyYMG+wBxUGZFFQRwB8jLABbLH1AEzxZYzxYBzxYB+gLMywDJ7VQAlsjLHxPLPyPPFlADzxbKAIIJycOA+gLKAMlxgBjIywUmzxZw+gLLaszJgwb7AHFVUHAHyMsAFssfUATPFljPFgHPFgH6AszLAMntVNZeZYk='); + + const marketplaceAddress = Address.parse('EQBYTuYbLf8INxFtD8tQeNk5ZLy-nAX9ahQbG_yl1qQ-GEMS'); // GetGems Address + const marketplaceFeeAddress = Address.parse('EQCjk1hh952vWaE9bRguFkAhDAL5jj3xj9p0uPWrFBq_GEMS'); // GetGems Address for Fees + const destinationAddress = Address.parse("EQAIFunALREOeQ99syMbO6sSzM_Fa1RsPD5TBoS0qVeKQ-AR"); // GetGems sale contracts deployer + + const walletAddress = Address.parse('EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162'); + const royaltyAddress = Address.parse('EQArLGBnGPvkxaJE57Y6oS4rwzDWuOE8l8_sghntXLkIt162'); + const nftAddress = Address.parse('EQCUWoe7hLlklVxH8gduCf45vPNocsjRP4wbX42UJ0Ja0S2f'); + const price = toNano('5'); // 5 TON + + const feesData = beginCell() + .storeAddress(marketplaceFeeAddress) + // 5% - GetGems fee + .storeCoins(price / BigInt(100) * BigInt(5)) + .storeAddress(royaltyAddress) + // 5% - Royalty, can be changed + .storeCoins(price / BigInt(100) * BigInt(5)) + .endCell(); + + const saleData = beginCell() + .storeBit(0) // is_complete + .storeUint(Math.round(Date.now() / 1000), 32) // created_at + .storeAddress(marketplaceAddress) // marketplace_address + .storeAddress(nftAddress) // nft_address + .storeAddress(walletAddress) // previous_owner_address + .storeCoins(price) // full price in nanotons + .storeRef(feesData) // fees_cell + .storeBit(0) // can_be_deployed_externally + .endCell(); + + const stateInit: StateInit = { + code: fixPriceV3R2Code, + data: saleData + }; + const stateInitCell = beginCell() + .store(storeStateInit(stateInit)) + .endCell(); + + // not needed, just for example + const saleContractAddress = new Address(0, stateInitCell.hash()); + + const saleBody = beginCell() + .storeUint(1, 32) // just accept coins on deploy + .storeUint(0, 64) + .endCell(); + + const transferNftBody = beginCell() + .storeUint(0x5fcc3d14, 32) // Opcode for NFT transfer + .storeUint(0, 64) // query_id + .storeAddress(destinationAddress) // new_owner + .storeAddress(walletAddress) // response_destination for excesses + .storeBit(0) // we do not have custom_payload + .storeCoins(toNano("1")) // forward_amount + .storeBit(0) // we store forward_payload is this cell + // not 32, because we stored 0 bit before | do_sale opcode for deployer + .storeUint(0x0fe0ede, 31) + .storeRef(stateInitCell) + .storeRef(saleBody) + .endCell(); +``` + +
+ +Prepared `transferNftBody` should be sent to the NFT Item Contract with at least `1.08` TON, that expected for success processing. Excess will be returned to a sender's wallet. + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of the NFT Item contract, that should be placed on market + amount: toNano("1.08"), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of NFT Item contract, that should be placed on market + amount: toNano("1.08"), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + + +```js +await connector.sendTransaction({ + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: NFTitem, //address of NFT Item contract, that should be placed on market + amount: toNano("1.08"), // amount that will require on gas fees, excess will be return + payload: transferNftBody.toBoc().toString("base64") // payload with the transferNftBody message + } + ] +}) +``` + +
+ +### NFT Buy (GetGems) + +The process of buy NFT for [nft-fixprice-sale-v3r2](https://github.com/getgems-io/nft-contracts/blob/main/packages/contracts/sources/nft-fixprice-sale-v3r2.fc) sale contract could be carry out with regular transfer without payload, the only important thing is accurate TON amount, that calculates as follows: +`buyAmount = Nftprice TON + 1.0 TON`. + + + + + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const myTransaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } + ] +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + + +
+ + + +```js +import TonConnectUI from '@tonconnect/ui' + +const transaction = { + validUntil: Math.floor(Date.now() / 1000) + 360, + messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + + + + +```js +await connector.sendTransaction({ +validUntil: Math.floor(Date.now() / 1000) + 360, +messages: [ + { + address: nftSaleContract, // NFT Sale contract, that is current desired NFT Item + amount: toNano(buyAmount), // NFT Price + exactly 1 TON, excess will be returned + } +] +}) +``` + + +
+ +## TON Connect Python SDK + +Python examples are using [PyTonConnect](https://github.com/XaBbl4/pytonconnect) and [pytoniq](https://github.com/yungwine/pytoniq). + +```python + from pytoniq_core import Address + from pytonconnect import TonConnect +``` + +:::tip +Read examples [source](https://github.com/yungwine/ton-connect-examples/blob/master/main.py). +::: + +### Regular TON Transfer + + +```python +connector = TonConnect( + manifest_url='https://raw.githubusercontent.com/XaBbl4/pytonconnect/main/pytonconnect-manifest.json') +is_connected = await connector.restore_connection() + +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + 'address' :'0:0000000000000000000000000000000000000000000000000000000000000000', # destination address + 'amount' : 1000000000, # amount should be specified in nanocoins, 1 TON + ) + ] +} +``` + + +### Transfer With Comment + +At first order, implement a message with comment via the following function: + +```python + def get_comment_message(destination_address: str, amount: int, comment: str) -> dict: + + data = { + 'address': destination_address, + 'amount': str(amount), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0, 32) # op code for comment message + .store_string(comment) # store comment + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + + return data +``` + +Final transaction body for transfer with comment: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_comment_message( + destination_address='0:0000000000000000000000000000000000000000000000000000000000000000', + amount=int(0.01 * 10**9), # amount should be specified in nanocoins + comment='hello world!' + ) + ] +} +``` +:::tip +Learn more about [TON Smart Contract Addresses](/learn/overviews/addresses). +::: + +### Jetton Transfer + +Example of function for building jetton transfer transaction: + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + +def get_jetton_transfer_message(jetton_wallet_address: str, recipient_address: str, transfer_fee: int, jettons_amount: int, response_address: str = None) -> dict: + data = { + 'address': jetton_wallet_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0xf8a7ea5, 32) # op code for jetton transfer message + .store_uint(0, 64) # query_id + .store_coins(jettons_amount) + .store_address(recipient_address) # destination address + .store_address(response_address or recipient_address) # address send excess to + .store_uint(0, 1) # custom payload + .store_coins(1) # forward amount + .store_uint(0, 1) # forward payload + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + + return data +``` + +Final transaction body: + + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_jetton_transfer_message( + jetton_wallet_address='EQCXsVvdxTVmSIvYv4tTQoQ-0Yq9mERGTKfbsIhedbN5vTVV', + recipient_address='0:0000000000000000000000000000000000000000000000000000000000000000', + transfer_fee=int(0.07 * 10**9), + jettons_amount=int(0.01 * 10**9), # replace 9 for jetton decimal. For example for jUSDT it should be (amount * 10**6) + response_address=wallet_address + ), + ] +} + +``` + + +### Jetton Burn + +Example of function for building jetton burn transaction: + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + +def get_jetton_burn_message(jetton_wallet_address: str, transfer_fee: int, jettons_amount: int, response_address: str = None) -> dict: + data = { + 'address': jetton_wallet_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0x595f07bc, 32) # op code for jetton transfer message + .store_uint(0, 64) # query_id + .store_coins(jettons_amount) + .store_address(response_address) # address send excess to + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + return data +``` + +The final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_jetton_burn_message( + jetton_wallet_address='EQCXsVvdxTVmSIvYv4tTQoQ-0Yq9mERGTKfbsIhedbN5vTVV', + transfer_fee=int(0.07 * 10 ** 9), + jettons_amount=int(0.01 * 10 ** 9), # replace 9 for jetton decimal. For example for jUSDT it should be (amount * 10**6) + response_address=wallet_address + ), + ] +} +``` + + +### NFT Transfer + +Example of function for a NFT transfer transaction: + + +```python +from pytoniq_core import begin_cell +from base64 import urlsafe_b64encode + + +def get_nft_transfer_message(nft_address: str, recipient_address: str, transfer_fee: int, response_address: str = None) -> dict: + data = { + 'address': nft_address, + 'amount': str(transfer_fee), + 'payload': urlsafe_b64encode( + begin_cell() + .store_uint(0x5fcc3d14, 32) # op code for nft transfer message + .store_uint(0, 64) # query_id + .store_address(recipient_address) # new owner + .store_address(response_address or recipient_address) # address send excess to + .store_uint(0, 1) # custom payload + .store_coins(1) # forward amount + .store_uint(0, 1) # forward payload + .end_cell() # end cell + .to_boc() # convert it to boc + ) + .decode() # encode it to urlsafe base64 + } + return data + +``` + +The final transaction body: + +```python +transaction = { + 'valid_until': int(time.time() + 3600), + 'messages': [ + get_nft_transfer_message( + nft_address='EQDrA-3zsJXTfGo_Vdzg8d07Da4vSdHZllc6W9qvoNoMstF-', + recipient_address='0:0000000000000000000000000000000000000000000000000000000000000000', + transfer_fee=int(0.07 * 10**9), + response_address=wallet_address + ), + ] +} +``` + + +## Authors +- JavaScript examples provided by [@aSpite](https://t.me/aspite) +- Python examples provided by [@yunwine](https://t.me/yungwine) + +## See Also + +* [TON Connect SDKs](/develop/dapps/ton-connect/developers) +* [TON Connect - Sending Messages](/develop/dapps/ton-connect/transactions) +* [Smart Contract Developmet - Sending Messages (Low Level)](/develop/smart-contracts/messages) diff --git a/docs/develop/dapps/ton-connect/mobile.mdx b/docs/develop/dapps/ton-connect/mobile.mdx new file mode 100644 index 0000000000..53079f2372 --- /dev/null +++ b/docs/develop/dapps/ton-connect/mobile.mdx @@ -0,0 +1 @@ +# TON Connect for Mobiles with the React Native diff --git a/docs/develop/dapps/ton-connect/overview.md b/docs/develop/dapps/ton-connect/overview.md deleted file mode 100644 index 1d2035a47f..0000000000 --- a/docs/develop/dapps/ton-connect/overview.md +++ /dev/null @@ -1,27 +0,0 @@ -# Connect with TON Ecosystem - -TON Ecosystem is a Web 3.0 space of applications that are develop and live in [The Open Network](/learn/introduction). - -## TON Ecosystem Deliverables -Discover deliverables for integrating with the TON Ecosystem. - -![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) - -- TON user's wallet as a ready-made account for your userbase exclude authenticate step for better UX -- process payments through fast and secure TON Blockchain(with Toncoin or wrapped stable coins jUSDC/jUSDT) -- attract additional traffic through crypto wallets supporting TON Connect -- increased user retention with in-app list saving feature (e.g., recently opened and favorites app lists) -- increased user engagement through multi application interaction - - -## Connect with TON Ecosystem -For connecting your service with TON Ecosystem you need to support following: - -- Create specified transaction message with TON libraries. Read about sending messages [here](/develop/smart-contracts/messages). -- Support TON Connect protocol in the application. Learn how to support TON Connect in [this](/develop/dapps/ton-connect) section of our documentation. -- Process payments through public API([tonapi](https://tonapi.io/)) or own indexer(for e.g. [gobycicle](http://github.com/gobicycle/bicycle)). Learn more in [this](/develop/dapps/asset-processing) section of our documentation. - -:::info -Note, that not all Apps require payment processing. This means, if the business logic of your service will not require it, you will not have to support this. -::: - diff --git a/docs/develop/dapps/ton-connect/overview.mdx b/docs/develop/dapps/ton-connect/overview.mdx new file mode 100644 index 0000000000..14b4f76e8d --- /dev/null +++ b/docs/develop/dapps/ton-connect/overview.mdx @@ -0,0 +1,91 @@ +import Button from '@site/src/components/button' + +# About TON Connect + +Experience seamless connectivity with wallets within [TON](/learn/introduction) using TON Connect. + +![](/img/docs/ton-connect/ton-connect-overview.png?raw=true) + +Feel free to use one of the following flows for integration of your application: + + + + + +## For Wallet Developers + +If you are a wallet developer, please read how to [integrate TON Connect into your wallet](/develop/dapps/ton-connect/wallet/). + +## Use Cases For Your DApp + +Explore these deliverables that the TON Ecosystem provides for superior DApp integration. + +- **Traffic**. Drive additional user visits via crypto wallets that support TON Connect. +- **Authenticity**. Leverage TON user's wallets as ready-made accounts, removing the need for additional authentication steps and thus, boosting user experience. +- **Payments**. Process transactions swiftly and securely through TON Blockchain using Toncoin or wrapped stable coins (jUSDC/jUSDT). +- **Retention**. Enhance user retention through the in-app list-saving feature which allows users to keep track of recently opened and favorite apps. + +## Success Stories + +- [GetGems — The Open Network Marketplace](https://getgems.io/) +- [STON.fi — AMM DEX for TON blockchain](https://ston.fi/) +- [Tonstarter](http://tonstarter.com/) + +
+ Show the entire list + + * [getgems.io](https://getgems.io/) + * [fragment.com](https://fragment.com/) (Ton Connect v.1) + * [ston.fi](https://ston.fi/) + * [ton.diamonds](https://ton.diamonds/) + * [beta.disintar.io](https://beta.disintar.io/) + * [tegro.finance](https://tegro.finance/liquidity) + * [minter.ton.org](https://minter.ton.org/) + * [libermall.com](https://libermall.com/) + * [dedust.io](https://dedust.io/swap) + * [toncap.net](https://toncap.net/) + * [cryptomus.com](https://cryptomus.com/) + * [avanchange.com](https://avanchange.com/) + * [wton.dev](https://wton.dev/) + * [mint.spiroverse.io/shop](https://mint.spiroverse.io/shop) + * [vk.com/vk_nft_hub](https://vk.com/vk_nft_hub) + * [tonverifier.live](https://verifier.ton.org/) + * [stickerface.io/member](https://stickerface.io/member) + * [tonstarter.com](https://tonstarter.com/) + * [cryptogas.shop/ton](https://cryptogas.shop/ton) + * [megaton.fi](https://megaton.fi/) + * [dns.ton.org](https://dns.ton.org/) + * [coinpaymaster.com](https://coinpaymaster.com/) + * [ton.gagarin.world/app/](https://ton.gagarin.world/app) + * [daolama.co](https://daolama.co/) + * [marketplace.playmuse.org](http://marketplace.playmuse.org/) + * [ton.vote](https://ton.vote/) + * [plane.tonfancy.io](https://plane.tonfancy.io/) + * [pi.oberton.io](https://pi.oberton.io/) + * [business.thetonpay.app](https://business.thetonpay.app/) + * [bridge.orbitchain.io](https://bridge.orbitchain.io/) + * [connecton-web-new.vercel.app](https://connecton-web-new.vercel.app/) + * [app.fanz.ee/staking](https://app.fanz.ee/staking) + * [testnet.pton.fi](https://testnet.pton.fi/) + * [tonft.app](https://tonft.app/) + * [cardify.casino](https://cardify.casino/) + * [4riends.org](https://4riends.org/#/) + * [tonflex.fi](https://tonflex.fi/swap) + * [soquest.xyz](https://soquest.xyz/) + * [app.evaa.finance](https://app.evaa.finance/) + +
+ + +## Join the TON Ecosystem +To connect your service with the TON Ecosystem, you need to implement the following: + +- **TON Connect**. Incorporate the TON Connect protocol within your application. +- **Transactions**. Create specified transaction messages using TON libraries. Dive into the process of [sending messages](/develop/dapps/ton-connect/message-builders) with our comprehensive guide. +- **Payments**. Process payments via the public API ([tonapi](https://tonapi.io/)) or your own indexer, for instance, [gobycicle](http://github.com/gobicycle/bicycle). Learn more from our extensive guide on [asset processing](/develop/dapps/asset-processing). 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..1a9015212c --- /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 https://bridge.tonapi.io/bridge. + +#### 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. \ No newline at end of file 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..8478e9a37e --- /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, do 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. \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/protocol/requests-responses.md b/docs/develop/dapps/ton-connect/protocol/requests-responses.md new file mode 100644 index 0000000000..a10a891518 --- /dev/null +++ b/docs/develop/dapps/ton-connect/protocol/requests-responses.md @@ -0,0 +1,493 @@ +# Requests and Responses + +App sends requests to the wallet. Wallet sends responses and events to the app. + +```tsx +type AppMessage = ConnectRequest | AppRequest; + +type WalletMessage = WalletResponse | WalletEvent; +``` + +### App manifest +App needs to have its manifest to pass meta information to the wallet. Manifest is a JSON file named as `tonconnect-manifest.json` following format: + +```json +{ + "url": "", // required + "name": "", // required + "iconUrl": "", // required + "termsOfUseUrl": "", // optional + "privacyPolicyUrl": "" // optional +} +``` + +Best practice is to place the manifest in the root of your app, e.g. `https://myapp.com/tonconnect-manifest.json`. It allows the wallet to handle your app better and improve the UX connected to your app. +Make sure that manifest is available to GET by its URL. + +#### Fields description +- `url` -- app URL. Will be used as the dapp identifier. Will be used to open the dapp after click to its icon in the wallet. It is recommended to pass url without closing slash, e.g. 'https://mydapp.com' instead of 'https://mydapp.com/'. +- `name` -- app name. Might be simple, will not be used as identifier. +- `iconUrl` -- Url to the app icon. Must be PNG, ICO, ... format. SVG icons are not supported. Perfectly pass url to a 180x180px PNG icon. +- `termsOfUseUrl` -- (optional) url to the Terms Of Use document. Optional for usual apps, but required for the apps which is placed in the Tonkeeper recommended apps list. +- `privacyPolicyUrl` -- (optional) url to the Privacy Policy document. Optional for usual apps, but required for the apps which is placed in the Tonkeeper recommended apps list. + +### Initiating connection + +App’s request message is **InitialRequest**. + +```tsx +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. +} +``` + +ConnectRequest description: +- `manifestUrl`: link to the app's tonconnect-manifest.json +- `items`: data items to share with the app. + +Wallet responds with **ConnectEvent** message if the user approves the request. + +```tsx +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"; + appName: string; // e.g. "Tonkeeper" + appVersion: string; // e.g. "2.3.367" + maxProtocolVersion: number; + features: Feature[]; // list of supported features and methods in RPC + // Currently there is only one feature -- 'SendTransaction'; +} + +type Feature = { name: 'SendTransaction', maxMessages: number } | // `maxMessages` is maximum number of messages in one `SendTransaction` that the wallet supports + { name: 'SignData' }; + +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' +} +``` + +**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 the requested `ConnectItem` (e.g. "ton_proof"), it must send reply with the following ConnectItemReply corresponding to the requested item. +with following structure: +```ts +type ConnectItemReplyError = { + name: ""; + error: { + code: 400; + message?: string; + } +} +``` + +### Address proof signature (`ton_proof`) + +If `TonProofItem` is requested, wallet proves ownership of the selected account’s key. The signed message is bound to: + +- Unique prefix to separate messages from on-chain messages. (`ton-connect`) +- Wallet address. +- App domain +- Signing timestamp +- App’s custom payload (where server may put its nonce, cookie id, expiration time). + +``` +message = utf8_encode("ton-proof-item-v2/") ++ + Address ++ + AppDomain ++ + Timestamp ++ + Payload +signature = Ed25519Sign(privkey, sha256(0xffff ++ utf8_encode("ton-connect") ++ sha256(message))) +``` + +where: + +* `Address` is the wallet address encoded as a sequence: + * `workchain`: 32-bit signed integer big endian; + * `hash`: 256-bit unsigned integer big endian; +* `AppDomain` is Length ++ EncodedDomainName + - `Length` is 32-bit value of utf-8 encoded app domain name length in bytes + - `EncodedDomainName` id `Length`-byte utf-8 encoded app domain name +* `Timestamp` 64-bit unix epoch time of the signing operation +* `Payload` is a variable-length binary string. + +Note: payload is variable-length untrusted data. To avoid using unnecessary length prefixes we simply put it last in the message. + +The signature must be verified by public key: + +1. First, try to obtain public key via `get_public_key` get-method on smart contract deployed at `Address`. + +2. If the smart contract is not deployed yet, or the get-method is missing, you need: + + 1. Parse `TonAddressItemReply.walletStateInit` and get public key from stateInit. You can compare the `walletStateInit.code` with the code of standard wallets contracts and parse the data according to the found wallet version. + + 2. Check that `TonAddressItemReply.publicKey` equals to obtained public key + + 3. Check that `TonAddressItemReply.walletStateInit.hash()` equals to `TonAddressItemReply.address`. `.hash()` means BoC hash. + +## Messages + +- All messages from the app to the wallet are requests for an operation. +- Messages from the wallet to the application can be either responses to app requests or events triggered by user actions on the side of the wallet. + +**Available operations:** + +- sendTransaction +- signData +- disconnect + +**Available events:** + +- connect +- connect_error +- disconnect + +### Structure + +**All app requests have the following structure (like json-rpc 2.0)** +```tsx +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 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. + +```tsx +type WalletResponse = WalletResponseSuccess | WalletResponseError; + +interface WalletResponseSuccess { + result: string; + id: string; +} + +interface WalletResponseError { + error: { code: number; message: string; data?: unknown }; + id: string; +} +``` + +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. +```tsx +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. + +### Methods + +#### Sign and send transaction + +App sends **SendTransactionRequest**: + +```tsx +interface SendTransactionRequest { + method: 'sendTransaction'; + params: []; + id: string; +} +``` + +Where `` is JSON with following properties: + +* `valid_until` (integer, optional): unix timestamp. after th moment transaction will be invalid. +* `network` (NETWORK, optional): The network (mainnet or testnet) where DApp intends to send the transaction. If not set, the transaction is sent to the network currently set in the wallet, but this is not safe and DApp should always strive to set the network. 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. +* `from` (string in `:` format, optional) - The sender address from which DApp intends to send the transaction. If not set, wallet allows user to select the sender's address at the moment of transaction approval. 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. +* `messages` (array of messages): 1-4 outgoing messages from the wallet contract to other accounts. All messages are sent out in order, however **the wallet cannot guarantee that messages will be delivered and executed in same order**. + +Message structure: +* `address` (string): message destination +* `amount` (decimal string): number of nanocoins to send. +* `payload` (string base64, optional): raw one-cell BoC encoded in Base64. +* `stateInit` (string base64, optional): raw once-cell BoC encoded in Base64. + +#### Common cases +1. No payload, no stateInit: simple transfer without a message. +2. payload is prefixed with 32 zero bits, no stateInit: simple transfer with a text message. +3. No payload or prefixed with 32 zero bits; stateInit is present: deployment of the contract. + +
+Example + +```json5 +{ + "valid_until": 1658253458, + "network": "-239", // enum NETWORK { MAINNET = '-239', TESTNET = '-3'} + "from": "0:348bcf827469c5fc38541c77fdd91d4e347eac200f6f2d9fd62dc08885f0415f", + "messages": [ + { + "address": "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", + "amount": "20000000", + "stateInit": "base64bocblahblahblah==" //deploy contract + },{ + "address": "0:E69F10CC84877ABF539F83F879291E5CA169451BA7BCE91A37A5CED3AB8080D3", + "amount": "60000000", + "payload": "base64bocblahblahblah==" //transfer nft to new deployed account 0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F + } + ] +} +``` +
+ + +Wallet replies with **SendTransactionResponse**: + +```tsx +type SendTransactionResponse = SendTransactionResponseSuccess | SendTransactionResponseError; + +interface SendTransactionResponseSuccess { + result: ; + id: string; + +} + +interface SendTransactionResponseError { + error: { code: number; message: string }; + id: string; +} +``` + +**Error codes:** + +| code | description | +|------|-------------------------------| +| 0 | Unknown error | +| 1 | Bad request | +| 100 | Unknown app | +| 300 | User declined the transaction | +| 400 | Method not supported | + + +#### Sign Data (Experimental) + +> WARNING: this is currently an experimental method and its signature may change in the future + +App sends **SignDataRequest**: + +```tsx +interface SignDataRequest { + method: 'signData'; + params: []; + id: string; +} +``` + +Where `` is JSON with following properties: + +* `schema_crc` (integer): indicates the layout of payload cell that in turn defines domain separation. +* `cell` (string, base64 encoded Cell): contains arbitrary data per its TL-B definition. +* `publicKey` (HEX string without 0x, optional): The public key of key pair from which DApp intends to sign the data. If not set, the wallet is not limited in what keypair to sign. If `publicKey` parameter is set, the wallet SHOULD to sign by keypair corresponding this public key; If sign by this specified keypair is impossible, the wallet should show an alert and DO NOT ALLOW TO SIGN this data. + +The signature will be computed in the following way: +`ed25519(uint32be(schema_crc) ++ uint64be(timestamp) ++ cell_hash(X), privkey)` + +[See details](https://github.com/oleganza/TEPs/blob/datasig/text/0000-data-signatures.md) + +Wallet should decode the cell in accordance with the schema_crc and show corresponding data to the user. +If the schema_crc is unknown to the wallet, the wallet should show danger notification/UI to the user. + +Wallet replies with **SignDataResponse**: + +```tsx +type SignDataResponse = SignDataResponseSuccess | SignDataResponseError; + +interface SignDataResponseSuccess { + result: { + signature: string; // base64 encoded signature + timestamp: string; // UNIX timestamp in seconds (UTC) at the moment on creating the signature. + }; + id: string; +} + +interface SignDataResponseError { + error: { code: number; message: string }; + id: string; +} +``` + +**Error codes:** + +| code | description | +|------|---------------------------| +| 0 | Unknown error | +| 1 | Bad request | +| 100 | Unknown app | +| 300 | User declined the request | +| 400 | Method not supported | + + +#### Disconnect operation +When user disconnects the wallet in the dApp, dApp should inform the wallet to help the wallet save resources and delete unnecessary session. +Allows the wallet to update its interface to the disconnected state. + +```tsx +interface DisconnectRequest { + method: 'disconnect'; + params: []; + id: string; +} +``` + +Wallet replies with **DisconnectResponse**: + +```ts +type DisconnectResponse = DisconnectResponseSuccess | DisconnectResponseError; + +interface DisconnectResponseSuccess { + id: string; + result: { }; +} + +interface DisconnectResponseError { + error: { code: number; message: string }; + id: string; +} +``` + +Wallet **shouldn't** emit a 'Disconnect' event if disconnect was initialized by the dApp. + +**Error codes:** + +| code | description | +|------|---------------------------| +| 0 | Unknown error | +| 1 | Bad request | +| 100 | Unknown app | +| 400 | Method not supported | + + +### Wallet events + +Disconnect + +The event fires when the user deletes the app in the wallet. The app must react to the event and delete the saved session. If the user disconnects the wallet on the app side, then the event does not fire, and the session information remains in the localstorage + +```tsx +interface DisconnectEvent { + type: "disconnect", + id: number; // increasing event counter + payload: { } +} +``` + +Connect + +```tsx +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; + } +} +``` \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/protocol/session.md b/docs/develop/dapps/ton-connect/protocol/session.md new file mode 100644 index 0000000000..a85fb87d6b --- /dev/null +++ b/docs/develop/dapps/ton-connect/protocol/session.md @@ -0,0 +1,62 @@ +# Session protocol + +Session protocol defines client identifiers and offers end-to-end encryption for the app and the wallet. This means the HTTP bridge is fully untrusted and cannot read the user’s data transmitted between the app and the wallet. JS bridge does not use this protocol since both the wallet and the app run on the same device. + +## Definitions + +### Client Keypair + +X25519 keypair for the use with NaCl “crypto_box” protocol. + +``` +a <- random 23 bytes +A <- X25519Pubkey(s) +``` + +or + +``` +(a,A) <- nacl.box.keyPair() +``` + + +### Client ID + +The public key part of the [Client Keypair](#client-keypair) (32 bytes). + +### Session + +A session is defined by a pair of two client IDs. Both the app and the wallet create their own [Client IDs](#client-id). + + +### Creating client Keypair + +``` +(a,A) <- nacl.box.keyPair() +``` + +### Encryption + +All requests from the app (except the initial request) and all responses from the wallet are encrypted. + +Given a binary encoding of message **m**, recipient’s [Client ID](#client-id) **X** and sender’s private key **y** the message is encrypted as follows: + +``` +nonce <- random(24 bytes) +ct <- nacl.box(m, nonce, X, y) +M <- nonce ++ ct +``` + +That is, the final message **M** has the first 24 bytes set to the random nonce. + +### Decryption + +To decrypt the message **M**, the recipient uses its private key **x** and sender’s public key **Y** (aka [Client ID](#client-id)): + +``` +nonce <- M[0..24] +ct <- M[24..] +m <- nacl.box.open(ct, nonce, Y, x) +``` + +Plaintext **m** is recovered and parsed per [Requests/Responses](/develop/dapps/ton-connect/protocol/requests-responses#requests-and-responses). \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/wallet-guidelines.md b/docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md similarity index 91% rename from docs/develop/dapps/ton-connect/wallet-guidelines.md rename to docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md index a3643efd6f..02b5bf7847 100644 --- a/docs/develop/dapps/ton-connect/wallet-guidelines.md +++ b/docs/develop/dapps/ton-connect/protocol/wallet-guidelines.md @@ -1,4 +1,4 @@ -# TON Wallet Guidelines +# Wallet Guidelines ## Networks @@ -56,13 +56,8 @@ To switch account user need to disconnect (Log out) and connect (Login) again i We recommend wallets provide the ability to disconnect session with a specified dapp because the dapp may have an incomplete UI. - -## References - -* https://github.com/ton-blockchain/ton-connect/blob/main/wallet-guidelines.md - ## See Also -* [Ton Connect Overview](/dapps/ton-connect/) -* [Integration manual](/develop/dapps/ton-connect/integration) -* [Telegram bot integration manual](/develop/dapps/ton-connect/tg-bot-integration) \ No newline at end of file +* [TON Connect Overview](/dapps/ton-connect/overview) +* [Protocol specifications](/dapps/ton-connect/protocol/) +* [Connect a Wallet](/dapps/ton-connect/wallet) \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/workflow.md b/docs/develop/dapps/ton-connect/protocol/workflow.md similarity index 66% rename from docs/develop/dapps/ton-connect/workflow.md rename to docs/develop/dapps/ton-connect/protocol/workflow.md index 778d371584..08ac003d6b 100644 --- a/docs/develop/dapps/ton-connect/workflow.md +++ b/docs/develop/dapps/ton-connect/protocol/workflow.md @@ -39,15 +39,15 @@ App creates app’s Client Keypair (a, A): (a,A) <- nacl.box.keyPair() ``` -App generates the **InitialRequest**. See [requests spec](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md). +App generates the **InitialRequest**. See [requests spec](/develop/dapps/ton-connect/protocol/requests-responses). -App creates a [universal link](https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md#universal-link) to a target wallet: +App creates a [universal link](/develop/dapps/ton-connect/protocol/bridge#universal-link) to a target wallet: ``` https://?v=2&id=&r= ``` -When using the [JS bridge](https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md#js-bridge), the same request is sent via the `connect()` call: +When using the [JS bridge](/develop/dapps/ton-connect/protocol/bridge#js-bridge), the same request is sent via the `connect()` call: ``` window.[walletJsBridgeKey].tonconnect.connect(2, ) @@ -57,7 +57,7 @@ Parameter **v** specifies the protocol version. Unsupported versions are not acc Parameter **id** specifies app’s Client ID encoded as hex (without '0x' prefix). -Parameter **r** specifies URL-safe json [ConnectRequest](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#initiating-connection). +Parameter **r** specifies URL-safe json [ConnectRequest](/develop/dapps/ton-connect/protocol/requests-responses#initiating-connection). The link may be embedded in a QR code or clicked directly. @@ -67,11 +67,11 @@ App is not yet in the connected state, and may restart the whole process at any ### Wallet establishes connection -Wallet opens up a link or QR code, reads plaintext app’s **Client ID** (A from parameter “**id”**) and [InitialRequest](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#initiating-connection) (from parameter **“r”**). +Wallet opens up a link or QR code, reads plaintext app’s **Client ID** (A from parameter “**id”**) and [InitialRequest](/develop/dapps/ton-connect/protocol/requests-responses#initiating-connection) (from parameter **“r”**). -Wallet computes the [InitialResponse](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#initiating-connection). +Wallet computes the [InitialResponse](/develop/dapps/ton-connect/protocol/requests-responses#initiating-connection). -Wallet generates its own [Client Keypair](https://github.com/ton-blockchain/ton-connect/blob/main/session.md#client-keypair) (b,B) and stores alongside app’s info and ID. +Wallet generates its own [Client Keypair](/develop/dapps/ton-connect/protocol/session#client-keypair) (b,B) and stores alongside app’s info and ID. Wallet encrypts the response and sends it to the **Bridge** using app’s Client ID A. @@ -81,7 +81,7 @@ Wallet connects to the bridge (link to bridge api) and listens for events using App receives the event from the bridge that contains the encrypted message from the Client ID **B.** -App decrypts the message and parses it as [InitialResponse](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#initiating-connection). +App decrypts the message and parses it as [InitialResponse](/develop/dapps/ton-connect/protocol/requests-responses#initiating-connection). If the reply is valid, App reads wallet info (address, public key, proof of ownership etc.) and remembers the wallet’s ID **B**. @@ -91,11 +91,11 @@ The session is considered established in the app when it has the wallet’s ID a When the user performs an action in the app, it may request confirmation from the wallet. -App generates a [request](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#messages). +App generates a [request](/develop/dapps/ton-connect/protocol/requests-responses#messages). App encrypts it to the wallet’s key B (see below). -App sends the encrypted message to B over the [Bridge](https://github.com/ton-blockchain/ton-connect/blob/main/bridge.md). +App sends the encrypted message to B over the [Bridge](/develop/dapps/ton-connect/protocol/bridge). App shows “pending confirmation” UI to let user know to open the wallet. @@ -103,13 +103,13 @@ Wallet receives the encrypted message through the Bridge. Wallet decrypts the message and is now assured that it came from the app with ID **A.** -Wallet shows the confirmation dialog to the user, signs transaction and [replies](https://github.com/ton-blockchain/ton-connect/blob/main/requests-responses.md#messages) over the bridge with user’s decision: “Ok, sent” or “User cancelled”. +Wallet shows the confirmation dialog to the user, signs transaction and [replies](/develop/dapps/ton-connect/protocol/requests-responses#messages) over the bridge with user’s decision: “Ok, sent” or “User cancelled”. App receives the encrypted message, decrypts it and closes the “pending confirmation” UI. ## References -* https://github.com/ton-blockchain/ton-connect/blob/main/workflows.md +* /develop/dapps/ton-connect/protocol/workflows ## See Also diff --git a/docs/develop/dapps/ton-connect/sign.mdx b/docs/develop/dapps/ton-connect/sign.mdx new file mode 100644 index 0000000000..8cb59d23cb --- /dev/null +++ b/docs/develop/dapps/ton-connect/sign.mdx @@ -0,0 +1,204 @@ +import ThemedImage from '@theme/ThemedImage'; + +# Signing and Verification + + +:::warning +The page is under development. +::: + + +Signature in works in TON Connect with a special `TonProof` entity, which implemented inside connector. + +```js +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 + } +} + +``` + +## How to use TON Proof (High-Level) + +- Send dApp id to client. Typically, dApp id nested in the QR code. +- Retrieve signed transaction with ton_proof entity +- Verify ton_proof on the backend side + +

+ +

+ +## How to Check TON Proof on Server Side + +Obtain from the frontend the following data: wallet address, domain, timestamp, walletStateInit, signature + +* Verify that the domain corresponds to the domain of your application +* Check that this payload was issued recently (you can issue cookies with the payload before authorization, and when checking ton_proof, verify the presence of a cookie for this client) +* Assemble a message according to the scheme from the previous slide +* Obtain the wallet's pubkey via the wallet contract's get method +* If the contract is not active, then obtaining the key in this manner will be impossible; you will need to parse the walletStateInit, which is provided by the frontend +* Verify that the signature from the frontend actually signs the assembled message and corresponds to the public key of the address + +## React Example + +1. Add token provider to the root of your app: + +```tsx +function App() { + const [token, setToken] = useState(null); + + return ( + + { /* Your app */ } + + ) +} +``` + +2. Describe authentication for backend: + +
+Example + +```tsx +import {useContext, useEffect, useRef} from "react"; +import {BackendTokenContext} from "./BackendTokenContext"; +import {useIsConnectionRestored, useTonConnectUI, useTonWallet} from "@tonconnect/ui-react"; +import {backendAuth} from "./backend-auth"; + +const localStorageKey = 'my-dapp-auth-token'; +const payloadTTLMS = 1000 * 60 * 20; + +export function useBackendAuth() { + const { setToken } = useContext(BackendTokenContext); + const isConnectionRestored = useIsConnectionRestored(); + const wallet = useTonWallet(); + const [tonConnectUI] = useTonConnectUI(); + const interval = useRef | undefined>(); + + useEffect(() => { + if (!isConnectionRestored || !setToken) { + return; + } + + clearInterval(interval.current); + + if (!wallet) { + localStorage.removeItem(localStorageKey); + setToken(null); + + const refreshPayload = async () => { + tonConnectUI.setConnectRequestParameters({ state: 'loading' }); + + const value = await backendAuth.generatePayload(); + if (!value) { + tonConnectUI.setConnectRequestParameters(null); + } else { + tonConnectUI.setConnectRequestParameters({state: 'ready', value}); + } + } + + refreshPayload(); + setInterval(refreshPayload, payloadTTLMS); + return; + } + + const token = localStorage.getItem(localStorageKey); + if (token) { + setToken(token); + return; + } + + if (wallet.connectItems?.tonProof && !('error' in wallet.connectItems.tonProof)) { + backendAuth.checkProof(wallet.connectItems.tonProof.proof, wallet.account).then(result => { + if (result) { + setToken(result); + localStorage.setItem(localStorageKey, result); + } else { + alert('Please try another wallet'); + tonConnectUI.disconnect(); + } + }) + } else { + alert('Please try another wallet'); + tonConnectUI.disconnect(); + } + + }, [wallet, isConnectionRestored, setToken]) +} +``` +
+ +## Concept Explanation + +If `TonProofItem` is requested, wallet proves ownership of the selected account’s key. The signed message is bound to: + +- Unique prefix to separate messages from on-chain messages. (`ton-connect`) +- Wallet address +- App domain +- Signing timestamp +- App’s custom payload (where server may put its nonce, cookie id, expiration time) + +``` +message = utf8_encode("ton-proof-item-v2/") ++ + Address ++ + AppDomain ++ + Timestamp ++ + Payload + +signature = Ed25519Sign(privkey, sha256(0xffff ++ utf8_encode("ton-connect") ++ sha256(message))) +``` + +where: + +* `Address` is the wallet address encoded as a sequence: + * `workchain`: 32-bit signed integer big endian; + * `hash`: 256-bit unsigned integer big endian; +* `AppDomain` is Length ++ EncodedDomainName +- `Length` is 32-bit value of utf-8 encoded app domain name length in bytes +- `EncodedDomainName` id `Length`-byte utf-8 encoded app domain name +* `Timestamp` 64-bit unix epoch time of the signing operation +* `Payload` is a variable-length binary string. + +Note: payload is variable-length untrusted data. To avoid using unnecessary length prefixes we put it last in the message. + +The signature must be verified by public key: + +1. First, try to obtain public key via `get_public_key` get-method on smart contract deployed at `Address`. + +2. If the smart contract is not deployed yet, or the get-method is missing, you need: + + 1. Parse `TonAddressItemReply.walletStateInit` and get public key from stateInit. You can compare the `walletStateInit.code` with the code of standard wallets contracts and parse the data according to the found wallet version. + + 2. Check that `TonAddressItemReply.publicKey` equals to obtained public key + + 3. Check that `TonAddressItemReply.walletStateInit.hash()` equals to `TonAddressItemReply.address`. `.hash()` means BoC hash. + + +### Examples of TON Proof Verification + +* [GO demo app](https://github.com/ton-connect/demo-dapp-backend/blob/master/proof.go) +* [TS example](https://gist.github.com/TrueCarry/cac00bfae051f7028085aa018c2a05c6) +* [Python example](https://github.com/disintar/ton-connect-python-proof/blob/master/check_proof.ipynb?short_path=8776c84) + +## See Also + +* [[YouTube] Check ton_proof for @tonconnect/react-ui [RU]](https://youtu.be/wIMbkJHv0Fs?list=PLyDBPwv9EPsCJ226xS5_dKmXXxWx1CKz_&t=2971) +* [Preparing Messages](/develop/dapps/ton-connect/message-builders) +* [Sending Messages](/develop/dapps/ton-connect/transactions) \ No newline at end of file diff --git a/docs/develop/dapps/ton-connect/tg-bot-integration.md b/docs/develop/dapps/ton-connect/tg-bot-integration.md index c3bb585183..bf4642c7f9 100644 --- a/docs/develop/dapps/ton-connect/tg-bot-integration.md +++ b/docs/develop/dapps/ton-connect/tg-bot-integration.md @@ -1,6 +1,6 @@ -# Telegram bot integration +# TON Connect for Telegram Bots -In this tutorial, we’ll create a sample telegram bot that supports TON Connect 2.0 authentication. +In this tutorial, we’ll create a sample telegram bot that supports TON Connect 2.0 authentication using Javascript TON Connect SDK. We will analyze connecting a wallet, sending a transaction, getting data about the connected wallet, and disconnecting a wallet. ## Documentation links diff --git a/docs/develop/dapps/ton-connect/transactions.md b/docs/develop/dapps/ton-connect/transactions.md index 6552609ec7..c2d9f2e703 100644 --- a/docs/develop/dapps/ton-connect/transactions.md +++ b/docs/develop/dapps/ton-connect/transactions.md @@ -1,10 +1,10 @@ -# Sending messages +# Sending Messages :::info There is no description of connecting a wallet on this page. We suppose you have already connected the wallet to your dApp. If not, you can refer to [integration manual](/develop/dapps/ton-connect/integration). ::: -TON Connect 2 has more powerful options than just authenticating users in the dApp: it's possible to send outgoing messages via connected wallets! +TON Connect 2.0 has more powerful options than just authenticating users in the dApp: it's possible to send outgoing messages via connected wallets! ## Playground page @@ -31,6 +31,7 @@ We'll experiment in the browser console on a page where the wallet is already co ``` + ## Sending multiple messages Let's start with something interesting! We will send two separate messages in one transaction: one to your own address, carrying 0.2 TON, and one to the other wallet address carrying 0.1 TON. @@ -148,6 +149,10 @@ console.log(await connector.sendTransaction({ })); ``` +:::info +Learn more about payload from [Preparing Messages](/develop/dapps/ton-connect/message-builders) page for Transfer NFT and Jettons. +::: + After confirmation, we may see our transaction complete at [tonscan.org](https://tonscan.org/tx/pCA8LzWlCRTBc33E2y-MYC7rhUiXkhODIobrZVVGORg=). ## What happens if the user rejects a transaction request? @@ -155,3 +160,7 @@ After confirmation, we may see our transaction complete at [tonscan.org](https:/ It's pretty easy to handle request rejection, but when you're developing some project it's better to know what would happen in advance. When a user clicks "Cancel" in the popup in the wallet application, an exception is thrown: `Error: [TON_CONNECT_SDK_ERROR] Wallet declined the request`. This error can be considered final (unlike connection cancellation) - if it has been raised, then the requested transaction will definitely not happen until the next request is sent. + +## See Also + +* [Preparing Messages](/develop/dapps/ton-connect/message-builders) diff --git a/docs/develop/dapps/ton-connect/twa.mdx b/docs/develop/dapps/ton-connect/twa.mdx new file mode 100644 index 0000000000..100609b510 --- /dev/null +++ b/docs/develop/dapps/ton-connect/twa.mdx @@ -0,0 +1,318 @@ +import Button from '@site/src/components/button' +import ThemedImage from '@theme/ThemedImage'; + +# TON Connect for TWA using React UI + +Telegram Web Apps (TWA) are web applications that run inside the Telegram messenger. They are built using web technologies — HTML, CSS, and JavaScript. TWA can be used to create bots, games, and other types of apps that can be run inside Telegram. + +Recommended TON Connect SDK for Telegram Web Apps is a [UI React SDK](/develop/dapps/ton-connect/developers#ton-connect-react). It is a React component that provides a high-level way to interact with TON Connect. + +## React UI Implementation + +1. Install `@tonconnect/ui-react` in the project of your website: + +```bash +npm i @tonconnect/ui-react +``` + +2. [Create a manifest.json](/develop/dapps/ton-connect/manifest) for you application. + +3. Add `TonConnectUIProvider` to the root of your Web App and pass the manifest URL: + +```tsx +import { TonConnectUIProvider } from '@tonconnect/ui-react'; + +export function App() { + return ( + + { /* Your app */ } + + ); +} +``` + +4. Add `TonConnectButton`. TonConnect Button is universal UI component for initializing connection. After wallet is connected it transforms to a wallet menu. It is recommended to place it in the top right corner of your app. + +```tsx +export const Header = () => { + return ( +
+ My App with React UI + +
+ ); +}; +``` + +You can add className and style props to the button as well. Note that you cannot pass child to the TonConnectButton. + +### API Documentation + +[Latest API documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui_react.html) + +### Examples + +* Step-by-step [TON Hello World guide](https://ton-community.github.io/tutorials/03-client/) to create a simple DApp with React UI. +* [Demo dApp](https://github.com/ton-connect/demo-dapp-with-react-ui) - Example of a DApp with `@tonconnect/ui-react`. +* [ton.vote](https://github.com/orbs-network/ton-vote) - Example of React website with TON Connect implementation. + +### SDKs for other frameworks + +- Don't use React for your app? Take a look at [TonConnect UI](/develop/dapps/ton-connect/developers#ton-connect-ui). +- If you want to use TonConnect on the server side, you should use the TonConnect SDK. +- Check the [supported SDKs](/develop/dapps/ton-connect/developers) list and choose the one that suits you best. + +## Use TonConnect UI hooks + +If you want to use some low-level TON Connect UI SDK features in your React app, you can use hooks from `@tonconnect/ui-react` package. + +### useTonAddress + +Use it to get user's current ton wallet address. Pass boolean parameter isUserFriendly to choose format of the address. If wallet is not connected hook will return empty string. + +```tsx +import { useTonAddress } from '@tonconnect/ui-react'; + +export const Address = () => { + const userFriendlyAddress = useTonAddress(); + const rawAddress = useTonAddress(false); + + return ( + address && ( +
+ User-friendly address: {userFriendlyAddress} + Raw address: {rawAddress} +
+ ) + ); +}; +``` + +### useTonWallet +Use it to get user's current ton wallet. If wallet is not connected hook will return null. + +See all wallet's properties + +[Wallet interface](https://ton-connect.github.io/sdk/interfaces/_tonconnect_sdk.Wallet.html) +[WalletInfo interface](https://ton-connect.github.io/sdk/types/_tonconnect_sdk.WalletInfo.html) + +```tsx +import { useTonWallet } from '@tonconnect/ui-react'; + +export const Wallet = () => { + const wallet = useTonWallet(); + + return ( + wallet && ( +
+ Connected wallet: {wallet.name} + Device: {wallet.device.appName} +
+ ) + ); +}; +``` + +### useTonConnectUI + +Use it to get access to the `TonConnectUI` instance and UI options updating function. + +[See more about TonConnectUI instance methods](https://github.com/ton-connect/sdk/tree/main/packages/ui#send-transaction) + +[See more about setOptions function](https://github.com/ton-connect/sdk/tree/main/packages/ui#change-options-if-needed) + + +```tsx +import { Locales, useTonConnectUI } from '@tonconnect/ui-react'; + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + const onLanguageChange = (lang: string) => { + setOptions({ language: lang as Locales }); + }; + + return ( +
+ + +
+ + +
+
+ ); +}; +``` + +### useIsConnectionRestored +Indicates current status of the connection restoring process. +You can use it to detect when connection restoring process if finished. + +```tsx +import { useIsConnectionRestored } from '@tonconnect/ui-react'; + +export const EntrypointPage = () => { + const connectionRestored = useIsConnectionRestored(); + + if (!connectionRestored) { + return Please wait...; + } + + return ; +}; +``` + +## Usage examples + +Let's take a look at how to use the React UI SDK on practice. + +### Sending transactions + +Here is an example of sending a transaction using the React UI SDK: + +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] + +} + +export const Settings = () => { + const [tonConnectUI, setOptions] = useTonConnectUI(); + + return ( +
+ +
+ ); +}; +``` + +- Get more examples here: [Preparing Messages](/develop/dapps/ton-connect/message-builders) + +### Add connect request parameters (ton_proof) + +:::tip +Understand how to sign and verify messages: [Signing and Verification](/develop/dapps/ton-connect/sign) +::: + +Use `tonConnectUI.setConnectRequestParameters` function to pass your connect request parameters. + +This function takes one parameter: + +Set 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. +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters({ + state: 'loading' +}); +``` + +or + +Set state to 'ready' and define `tonProof` value. Passed parameter will be applied to the connect request (QR and universal link). +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters({ + state: 'ready', + value: { + tonProof: '' + } +}); +``` + +or + +Remove 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. +```ts +const [tonConnectUI] = useTonConnectUI(); + +tonConnectUI.setConnectRequestParameters(null); +``` + + +You can call `tonConnectUI.setConnectRequestParameters` multiple times if your tonProof payload has bounded lifetime (e.g. you can refresh connect request parameters every 10 minutes). + + +```ts +const [tonConnectUI] = useTonConnectUI(); + +// enable ui loader +tonConnectUI.setConnectRequestParameters({ state: 'loading' }); + +// fetch you tonProofPayload from the backend +const tonProofPayload: string | null = await fetchTonProofPayloadFromBackend(); + +if (!tonProofPayload) { + // remove loader, connect request will be without any additional parameters + tonConnectUI.setConnectRequestParameters(null); +} else { + // add tonProof to the connect request + tonConnectUI.setConnectRequestParameters({ + state: "ready", + value: { tonProof: tonProofPayload } + }); +} + +``` + + +You can find `ton_proof` result in the `wallet` object when wallet will be connected: + +```ts +import {useTonConnectUI} from "@tonconnect/ui-react"; + +const [tonConnectUI] = useTonConnectUI(); + +useEffect(() => + tonConnectUI.onStatusChange(wallet => { + if (wallet.connectItems?.tonProof && 'proof' in wallet.connectItems.tonProof) { + checkProofInYourBackend(wallet.connectItems.tonProof.proof, wallet.account); + } + }), []); +``` + + +### Wallet Disconnection + +Call to disconnect the wallet: +```js +import { useTonConnectUI } from '@tonconnect/ui-react'; + +const [tonConnectUI] = useTonConnectUI(); + +await tonConnectUI.disconnect(); +``` + +## Telegram Web Apps + +- [Telegram Web Apps documentation](https://docs.twa.dev/docs/introduction/about-platform) — a community-driven documentation for TWA. +- [TWA Documentation by Telegram](https://core.telegram.org/bots/webapps) — full description on Telegram website. + +### Web Apps SDK list + +- [twa-dev/sdk](https://github.com/twa-dev/sdk) — NPM package for TWA SDK +- [twa-dev/boilerplate](https://github.com/twa-dev/Boilerplate) — another boilerplate for a new TWA. +- [twa-dev/Mark42](https://github.com/twa-dev/Mark42) — Mark42 is a simple lightweight tree-shakable UI library for TWA. +- [ton-defi-org/tonstarter-twa](https://github.com/ton-defi-org/tonstarter-twa) — template for new TWA interaction with TON. + +### Community + +Join a special Telegram [Community Chat](https://t.me/+1mQMqTopB1FkNjIy) for TWA developers if you're interested. + diff --git a/docs/develop/dapps/ton-connect/wallet.mdx b/docs/develop/dapps/ton-connect/wallet.mdx new file mode 100644 index 0000000000..a81bd46920 --- /dev/null +++ b/docs/develop/dapps/ton-connect/wallet.mdx @@ -0,0 +1,15 @@ +import Button from '@site/src/components/button' + +# Connect a Wallet + +If you are a wallet developer, you can connect your wallet to TON Connect and enable your users to interact with TON apps in a secure and convenient way. + +## Integration + +Use the following steps to connect your wallet to TON Connect: + +1. Read carefully [Protocol specifications](/develop/dapps/ton-connect/protocol/). +2. Implement the protocol using one of the [SDKs](/develop/dapps/ton-connect/developers). +3. Add your wallet to the [wallets-list](https://github.com/ton-blockchain/wallets-list) with a pull request. + + diff --git a/docs/develop/dapps/ton-connect/web.mdx b/docs/develop/dapps/ton-connect/web.mdx new file mode 100644 index 0000000000..2c0b4b640c --- /dev/null +++ b/docs/develop/dapps/ton-connect/web.mdx @@ -0,0 +1,86 @@ +# TON Connect for HTML/JS Web Apps + +TonConnect UI is a UI kit for TonConnect SDK. Use it to connect your HTML/JS app to TON wallets via TonConnect protocol. + +If you use React for your DApp, take a look at [TON Connect UI React SDK](/develop/dapps/ton-connect/twa). + +## HTML/JS Integration + +1. Add script in the `` of your website (or [use npm instead](https://github.com/ton-connect/sdk/tree/main/packages/ui#installation-with-npm)): + +```html + +``` + +2. [Create a manifest.json](/develop/dapps/ton-connect/manifest) for you application. + +3. Add a script for a connector `tonConnectUI` in `` part of application page: + +```html + +``` + +4. Add a button with `ton-connect` id to connect to the wallet: + +```html +
+``` + +### SDK Documentation + +- [SDK documentation](https://github.com/ton-connect/sdk/blob/main/packages/ui/README.md) +- [Latest API documentation](https://ton-connect.github.io/sdk/modules/_tonconnect_ui.html) + +## Usage + +Let's take a look at the example of using the TON Connect UI in the application. + +### Sending messages + +Here is an example of sending a transaction using the TON Connect UI: + +```js +import TonConnectUI from '@tonconnect/ui'; + +const tonConnectUI = new TonConnectUI({ //connect application + manifestUrl: 'https:///tonconnect-manifest.json', + buttonRootId: '' +}); + +const transaction = { + messages: [ + { + address: "0:412410771DA82CBA306A55FA9E0D43C9D245E38133CB58F1457DFB8D5CD8892F", // destination address + amount: "20000000" //Toncoin in nanotons + } + ] +} + +const result = await tonConnectUI.sendTransaction(transaction) +``` + +- Get more examples here: [Preparing Messages](/develop/dapps/ton-connect/message-builders) + +### Signing and Verification + +Understand how to sign and verify messages using the TON Connect: +- [Signing and Verification](/develop/dapps/ton-connect/sign) +- [TON Connect UI implementation on GitHub](https://github.com/ton-connect/sdk/tree/main/packages/ui#add-connect-request-parameters-ton_proof) + +### Wallet Disconnection + +Call to disconnect the wallet: +```js +await tonConnectUI.disconnect(); +``` + +## See Also + +* [UI Customization](https://github.com/ton-connect/sdk/tree/main/packages/ui#ui-customisation) +* [[YouTube] TON Connect UI React [RU]](https://youtu.be/wIMbkJHv0Fs?list=PLyDBPwv9EPsCJ226xS5_dKmXXxWx1CKz_&t=1747) +* [[YouTube] Connect TON Connect UI to Site [RU]](https://www.youtube.com/watch?v=HUQ1DPfFxG4&list=PLyDBPwv9EPsAIWi8vgic9kiV3KF_wvIcz&index=4) diff --git a/docs/develop/dapps/tutorials/overview.mdx b/docs/develop/dapps/tutorials/overview.mdx deleted file mode 100644 index 077eaccece..0000000000 --- a/docs/develop/dapps/tutorials/overview.mdx +++ /dev/null @@ -1,34 +0,0 @@ -import Button from '@site/src/components/button' - -# Overview - -Find a tutorial well-suited for your stack across all the materials listed below. - -## Basic - -* [Step by step NFT collection minting](/develop/dapps/tutorials/collection-minting) -* [Mint your first Jetton](/develop/dapps/tutorials/jetton-minter) - -## Telegram bots - -### JavaScript - -* [Bot for sales of dumplings](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-js) - -### Python - -* [Storefront bot with payments in TON](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot) -* [Bot with own balance](/develop/dapps/tutorials/accept-payments-in-a-telegram-bot-2) - -## ZK - -* [Simple ZK on TON](/develop/dapps/tutorials/simple-zk-on-ton) -## No necessary material? - -You have 2 ways here: write tutorial by you own or describe the problem for the community. - - - diff --git a/docs/develop/func/overview.md b/docs/develop/func/overview.md index 85b7d51bcf..3be42d10b3 100644 --- a/docs/develop/func/overview.md +++ b/docs/develop/func/overview.md @@ -55,14 +55,14 @@ The best place to start to develop using FunC: [INTRODUCTION](/develop/smart-con Other materials gracefully provided by the experts from the community: -* [Func & BluePrint](https://www.youtube.com/watch?v=7omBDfSqGfA&list=PLtUBO1QNEKwtO_zSyLj-axPzc9O9rkmYa) by **@MarcoDaTr0p0je** +* [Func & Blueprint](https://www.youtube.com/watch?v=7omBDfSqGfA&list=PLtUBO1QNEKwtO_zSyLj-axPzc9O9rkmYa) by **@MarcoDaTr0p0je** * [Learn FunC in Y Minutes](https://learnxinyminutes.com/docs/func/) by **@romanovichim** * [TON Hello World: Step-by-step guide for writing your first smart contract](https://ton-community.github.io/tutorials/02-contract/) * [TON Hello World: Step by step guide for testing your first smart contract](https://ton-community.github.io/tutorials/04-testing/) -* [10 FunC Lessons](https://github.com/romanovichim/TonFunClessons_Eng) by **@romanovichim**, using **toncli** and **toncli** tests v1 -* [10 FunC lessons](https://github.com/romanovichim/TonFunClessons_ru) by **@romanovichim**, using **toncli** and **toncli** tests v1 in Russian +* [10 FunC Lessons](https://github.com/romanovichim/TonFunClessons_Eng) by **@romanovichim**, using blueprint +* [10 FunC lessons (RU)](https://github.com/romanovichim/TonFunClessons_ru) by **@romanovichim**, using blueprint * [FunC Quiz](https://t.me/toncontests/60) by **Vadim**—Good for selfcheck. It will take 10–15 minutes. The questions are mainly about FunС with a few general questions about TON -* [FunC Quiz](https://t.me/toncontests/58?comment=14888) by **Vadim**—FunC Quiz in Russian +* [FunC Quiz (RU)](https://t.me/toncontests/58?comment=14888) by **Vadim**—FunC Quiz in Russian ## Contests diff --git a/docs/develop/smart-contracts/README.mdx b/docs/develop/smart-contracts/README.mdx index a1ca4af24b..5a66f630c3 100644 --- a/docs/develop/smart-contracts/README.mdx +++ b/docs/develop/smart-contracts/README.mdx @@ -1,8 +1,7 @@ import Button from '@site/src/components/button' # Introduction -Smart contract creation, development, and deployment on TON Blockchain leverages the [FunC programming language](/develop/smart-contracts/#func-language) and [TON Virtual Machine (TVM)](/develop/smart-contracts/#ton-virtual-machine). This section will give software engineers an overview of smart contract development on TON. - +Smart contract creation, development, and deployment on TON Blockchain leverages the [FunC programming language](/develop/smart-contracts/#func-language) and [TON Virtual Machine (TVM)](/develop/smart-contracts/#ton-virtual-machine). ## Quick Start Write and deploy your first smart contract with either *Blueprint* or *toncli* frameworks. diff --git a/docs/develop/smart-contracts/examples.md b/docs/develop/smart-contracts/examples.md index 1e6ac958ae..562b24b24b 100644 --- a/docs/develop/smart-contracts/examples.md +++ b/docs/develop/smart-contracts/examples.md @@ -61,19 +61,19 @@ Make sure you have thoroughly tested contracts before using them in a production * [Blueprint jetton_minter.fc](https://github.com/liminalAngel/func-blueprint-tutorial/blob/master/6/contracts/jetton_minter.fc) * [Simple TON DNS Subdomain manager](https://github.com/Gusarich/simple-subdomain) -### Ton Smart Challenge Solutions +### TON Smart Challenge Solutions -#### Ton Smart Challenge 1 +#### TON Smart Challenge 1 * https://github.com/nns2009/TON-FunC-contest-1/tree/main * https://github.com/pyAndr3w/func-contest1-solutions * https://github.com/crazyministr/TonContest-FunC/tree/master/func-contest1 -#### Ton Smart Challenge 2 +#### TON Smart Challenge 2 * https://github.com/ton-blockchain/func-contest2-solutions * https://github.com/nns2009/TON-FunC-contest-2 * https://github.com/crazyministr/TonContest-FunC/tree/master/func-contest2 -#### Ton Smart Challenge 3 +#### TON Smart Challenge 3 * https://github.com/nns2009/TON-FunC-contest-3 * https://github.com/shuva10v/func-contest3-solutions * https://github.com/crazyministr/TonContest-FunC/tree/master/func-contest3 diff --git a/docusaurus.config.js b/docusaurus.config.js index f944cdae17..736a459b35 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -206,125 +206,117 @@ const config = { srcDark: 'img/ton_logo_dark_background.svg', }, items: [ - { - type: 'doc', - docId: 'learn/introduction', - position: 'left', - label: 'Concepts', - }, { type: 'dropdown', - to: 'develop/dapps', + to: '/learn/introduction', position: 'left', - label: 'Apps', + label: 'Concepts', items: [ { - to: 'develop/dapps/apis', - label: 'Understand APIs', + to: '/learn/introduction', + label: 'Introduction to TON', }, { - to: 'develop/dapps/asset-processing', - label: 'Payments processing', + to: '/learn/overviews/ton-blockchain', + label: 'Blockchain of Blockchains', }, { - to: 'develop/dapps/ton-connect', - label: 'Authenticate with TON', + to: '/learn/overviews/addresses', + label: 'Smart Contract Addresses', }, { - to: 'develop/dapps/defi/ton-payments', - label: 'TON Payments', + to: '/learn/overviews/cells', + label: 'Cells as a Data Structure', }, { - to: 'develop/dapps/defi/subscriptions', - label: 'Subscriptions', + to: '/learn/networking/overview', + label: 'TON Networking', }, { - to: 'https://ton-community.github.io/tutorials/03-client/', - label: 'Build your first WebApp', + to: '/learn/docs', + label: 'Whitepapers', }, ], }, { type: 'dropdown', - to: 'develop/dapps/defi/tokens', + to: '/develop/overview', position: 'left', - label: 'Tokens', + label: 'Get Started', items: [ { - to: 'develop/dapps/defi/coins', - label: 'Native token: Toncoin', + to: 'develop/overview', + label: 'Start with Onboarding Tutorials', }, { - to: 'develop/dapps/asset-processing/jettons', - label: 'TON Jetton (Tokens) processing', + to: '/develop/dapps/ton-connect/twa', + label: 'Build your first Web App', }, { - to: '/develop/dapps/asset-processing/nfts', - label: 'TON NFT processing', + to: '/develop/dapps', + label: 'Dive into DApps Development', }, { - to: '/develop/dapps/asset-processing/metadata', - label: 'TON Metadata Parsing', + to: '/develop/dapps/tutorials/jetton-minter', + label: 'Mint your first Token (Jetton)', }, ], }, { type: 'dropdown', - to: '/develop/dapps/tutorials/overview', + to: 'develop/dapps', position: 'left', - label: 'Learn', + label: 'DApps', items: [ - { - to: 'develop/get-started-with-ton', - label: 'Get Started with TON', + to: 'develop/dapps/apis', + label: 'Understand API Types', }, { - to: '/learn/overviews/addresses', - label: 'Smart Contract Addresses', + to: 'develop/dapps/apis/sdk', + label: 'Choose an SDK', }, { - to: '/develop/smart-contracts/tutorials/wallet', - label: 'How to interact with wallet', + to: 'develop/dapps/defi/coins', + label: 'Native token: Toncoin', }, { - to: 'develop/dapps/tutorials/jetton-minter', - label: 'Mint Jettons (Tokens)', + to: 'develop/dapps/asset-processing', + label: 'Payments processing', }, { - to: '/develop/dapps/tutorials/collection-minting', - label: 'Mint NFT Collection', + to: 'develop/dapps/asset-processing/jettons', + label: 'Jetton (Tokens) processing', }, { - to: '/develop/dapps/ton-connect/integration', - label: 'TON Connect Integration Manual', + to: '/develop/dapps/asset-processing/nfts', + label: 'NFT processing', }, { - to: '/develop/dapps/tutorials/accept-payments-in-a-telegram-bot', - label: 'Telegram bot with Payments', + to: '/develop/dapps/asset-processing/metadata', + label: 'TON Metadata Parsing', }, { - to: '/develop/dapps/ton-connect/tg-bot-integration ', - label: 'Telegram bot with TON Connect', + to: 'develop/dapps/defi/subscriptions', + label: 'Subscriptions', }, { - to: '/develop/dapps/tutorials/simple-zk-on-ton', - label: 'Simple Zero-Knowledge Project on TON', + to: 'develop/dapps/defi/ton-payments', + label: 'TON Payments', }, - { - to: 'https://ton-community.github.io/tutorials/01-wallet/', - label: 'TON Community Tutorials', - } - ], }, { type: 'dropdown', to: 'develop/overview', position: 'left', - label: 'Develop', + label: 'Smart Contracts', items: [ + { + to: '/develop/smart-contracts/tutorials/wallet', + label: 'Understanding Wallets', + }, { to: 'develop/smart-contracts', label: 'Write Smart Contracts' @@ -363,23 +355,47 @@ const config = { type: 'dropdown', to: 'participate', position: 'left', - label: 'Participate', + label: 'Nodes', items: [ { to: 'participate/nodes/node-types', - label: 'Run a Node', + label: 'Node Types', }, { - to: 'participate/web3/how-to-open-any-ton-site', - label: 'Connect to TON Sites', + to: 'participate/nodes/full-node', + label: 'Run a Full Node', }, { - to: 'develop/dapps/tutorials/how-to-run-ton-site', - label: 'How to run TON Sites', + to: 'participate/nodes/liteserver', + label: 'Run a Liteserver Node', + }, + { + to: 'participate/nodes/archive-node', + label: 'Run an Archieve Node', + }, + { + to: 'https://ton.org/validator', + label: 'Become a Validator', }, + ], + }, + { + type: 'dropdown', + to: 'participate', + position: 'left', + label: 'Web3', + items: [ { to: 'participate/web3/dns', - label: 'Use TON DNS & Domains', + label: 'TON DNS & Domains', + }, + { + to: 'participate/web3/how-to-open-any-ton-site', + label: 'Open TON Sites', + }, + { + to: 'develop/dapps/tutorials/how-to-run-ton-site', + label: 'Run TON Sites', }, { to: 'participate/ton-storage/storage-daemon', @@ -387,7 +403,7 @@ const config = { }, { to: 'participate/ton-storage/storage-provider', - label: 'Become a Storage Provider', + label: 'Build a Storage Provider', }, ], }, diff --git a/sidebars.js b/sidebars.js index 9f60c5c689..5c37046eee 100644 --- a/sidebars.js +++ b/sidebars.js @@ -157,7 +157,7 @@ const sidebars = { }, { type: 'category', - label: 'Develop Smart Contracts', + label: 'Smart Contracts', items: [ 'develop/smart-contracts/README', { @@ -172,14 +172,9 @@ const sidebars = { items: [ { type: 'link', - label: 'TON Hello World', + label: 'Using Blueprint', href: 'https://ton-community.github.io/tutorials/02-contract/', - }, - { - type: 'link', - label: 'TON FunC Lessons', - href: 'https://github.com/romanovichim/TonFunClessons_Eng/blob/main/1lesson/firstlesson.md', - }, + } ], }, { @@ -200,11 +195,6 @@ const sidebars = { 'develop/smart-contracts/examples' ], }, - { - type: 'link', - label: 'TON FunC Lessons', - href: 'https://github.com/romanovichim/TonFunClessons_Eng', - }, ], }, { @@ -285,21 +275,23 @@ const sidebars = { }, ], }, - ], }, { type: 'category', - label: 'Develop Apps', + label: 'DApp Development', items: [ 'develop/dapps/README', { type: 'category', label: 'Learn', items: [ - 'develop/dapps/tutorials/overview', - 'develop/dapps/tutorials/collection-minting', + { + type: 'doc', + id: 'develop/dapps/tutorials/collection-minting', + label: 'NFT collection minting', + }, 'develop/dapps/tutorials/jetton-minter', { type: 'category', @@ -334,7 +326,6 @@ const sidebars = { 'develop/dapps/defi/subscriptions', ], }, - 'develop/dapps/examples', ] }, { @@ -343,30 +334,64 @@ const sidebars = { items: [ 'develop/dapps/ton-connect/overview', { - type: 'category', - label: 'TON Connect', - items: [ - 'develop/dapps/ton-connect/README', + type: 'doc', + id: 'develop/dapps/ton-connect/wallet' + }, { type: 'category', - label: 'Learn', + label: 'Platforms', // items: [ - 'develop/dapps/ton-connect/integration', - 'develop/dapps/ton-connect/tg-bot-integration', - 'develop/dapps/ton-connect/transactions', - 'develop/dapps/ton-connect/tg-bot-tonapi-nft', + { + type: 'doc', + id: 'develop/dapps/ton-connect/twa', + label: 'Telegram Web Apps', + }, + { + type: 'doc', + id: 'develop/dapps/ton-connect/web', + label: 'HTML/JS Web Apps', + }, + { + type: 'doc', + id: 'develop/dapps/ton-connect/tg-bot-integration', + label: 'Telegram Bots', + }, ], }, { type: 'category', label: 'Guidelines', items: [ + 'develop/dapps/ton-connect/README', 'develop/dapps/ton-connect/developers', - 'develop/dapps/ton-connect/wallet-guidelines', - 'develop/dapps/ton-connect/workflow', + 'develop/dapps/ton-connect/manifest', + 'develop/dapps/ton-connect/message-builders', + 'develop/dapps/ton-connect/transactions', + 'develop/dapps/ton-connect/sign', + 'develop/dapps/ton-connect/integration', + ], + }, + { + type: 'category', + label: 'Protocol specifications', + items: [ + { + type: 'doc', + label: 'TON Connect Protocol', + id: 'develop/dapps/ton-connect/protocol/README', + }, + 'develop/dapps/ton-connect/protocol/workflow', + 'develop/dapps/ton-connect/protocol/bridge', + 'develop/dapps/ton-connect/protocol/session', + 'develop/dapps/ton-connect/protocol/requests-responses', + 'develop/dapps/ton-connect/protocol/wallet-guidelines', + { + type: 'link', + label: 'Wallets List', + href: 'https://github.com/ton-blockchain/wallets-list', + }, ], }, - { type: 'category', label: 'Business', @@ -376,9 +401,6 @@ const sidebars = { 'develop/dapps/ton-connect/comparison', ], }, - ] - }, - 'develop/howto/subresolvers', ], }, { @@ -615,6 +637,7 @@ const sidebars = { 'label': 'TON DNS', 'items': [ 'participate/web3/dns', + 'develop/howto/subresolvers', ], }, { diff --git a/static/img/docs/ton-connect/ton_proof_scheme-dark.svg b/static/img/docs/ton-connect/ton_proof_scheme-dark.svg new file mode 100644 index 0000000000..c19a6820a7 --- /dev/null +++ b/static/img/docs/ton-connect/ton_proof_scheme-dark.svg @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + + + + + + + + Actor lifeline + dApp frontend + + Sheet.39 + + + + Sheet.41 + + + Sheet.42 + + + + + + + dApp frontend + + + + + + + + + Object lifeline + dApp backend + + Sheet.44 + + + + Sheet.45 + + + + Sheet.46 + + + Sheet.47 + + + + + + + dApp backend + + + + + + + + + Object lifeline.54 + Wallet + + Sheet.55 + + + + Sheet.56 + + + + Sheet.57 + + + Sheet.58 + + + + + + + Wallet + + + Activation + + + + + + + + Activation.60 + + + + + + + + Activation.65 + + + + + + + + Message.21 + + + + + + + + + + + + Dynamic connector.161 + + + + + + + Activation.148 + + + + + + + + Dynamic connector + + + + + + + Dynamic connector.152 + + + + + + + Dynamic connector.153 + + + + + + + + + + + User + + + + + Sheet.155 + + Sheet.156 + + + + + + + Sheet.157 + + + + + + + + + Dynamic connector.160 + + + + + + + + + + + + + Object lifeline.142 + User + + Sheet.164 + + + + Sheet.165 + + + + Sheet.166 + + + Sheet.167 + + + + + + + User + + + Dynamic connector.169 + + + + + + + Sheet.175 + Connect wallet + + + + + + + Connect wallet + + Sheet.179 + generate ton_proof payload + + + + + + + generate ton_proofpayload + + Sheet.181 + Connection request with ton_proof + + + + + + + Connection request with ton_proof + + Sheet.183 + Signed ton_proof + + + + + + + Signed ton_proof + + Sheet.185 + Check ton_proof + + + + + + + Check ton_proof + + Sheet.189 + Auth token/cookie + + + + + + + Auth token/cookie + + diff --git a/static/img/docs/ton-connect/ton_proof_scheme.svg b/static/img/docs/ton-connect/ton_proof_scheme.svg new file mode 100644 index 0000000000..c1c3d33e5a --- /dev/null +++ b/static/img/docs/ton-connect/ton_proof_scheme.svg @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + + + + + + + + Actor lifeline + dApp frontend + + Sheet.39 + + + + + + + Sheet.41 + + + + Sheet.42 + + + + + + + + + + dApp frontend + + + + + + + + + Object lifeline + dApp backend + + Sheet.44 + + + + + + + Sheet.45 + + + + + + + Sheet.46 + + + + Sheet.47 + + + + + + + + + + dApp backend + + + + + + + + + Object lifeline.54 + Wallet + + Sheet.55 + + + + + + + Sheet.56 + + + + + + + Sheet.57 + + + + Sheet.58 + + + + + + + + + + Wallet + + + Activation + + + + + + + + Activation.60 + + + + + + + + Activation.65 + + + + + + + + Message.21 + generate ton_proof payload + + + + + + + + + + + + + generate ton_proofpayload + + Activation.148 + + + + + + + + Dynamic connector + + + + + + + Dynamic connector.152 + Connection request with ton_proof + + + + + + + + Connection request with ton_proof + + Dynamic connector.153 + Signed ton_proof + + + + + + + + Signed ton_proof + + + + + + User + + + + + Sheet.155 + + Sheet.156 + + + + + + + Sheet.157 + + + + + + + + + Dynamic connector.160 + Check ton_proof + + + + + + + + Check ton_proof + + Dynamic connector.161 + Auth token/cookie + + + + + + + + Auth token/cookie + + + + + + + + Object lifeline.142 + User + + Sheet.164 + + + + + + + Sheet.165 + + + + + + + Sheet.166 + + + + Sheet.167 + + + + + + + + + + User + + + Dynamic connector.169 + Connect wallet + + + + + + + + Connect wallet + + diff --git a/static/schemes-visio/readme.md b/static/schemes-visio/readme.md index 5823149e62..f154287b19 100644 --- a/static/schemes-visio/readme.md +++ b/static/schemes-visio/readme.md @@ -2,6 +2,10 @@ In this directory collected unified Visio schemes created specially for the docs.ton.org documentation. +## Font + +It is preferable to use Inter fonts family. + ## Colors ### Light Mode diff --git a/static/schemes-visio/ton_proof_scheme.vsdx b/static/schemes-visio/ton_proof_scheme.vsdx new file mode 100644 index 0000000000..a44688ac8c Binary files /dev/null and b/static/schemes-visio/ton_proof_scheme.vsdx differ diff --git a/static/schemes-visio/ton_proof_scheme_dark.vsdx b/static/schemes-visio/ton_proof_scheme_dark.vsdx new file mode 100644 index 0000000000..4fc590262f Binary files /dev/null and b/static/schemes-visio/ton_proof_scheme_dark.vsdx differ