{"id":113,"date":"2024-10-06T13:56:13","date_gmt":"2024-10-06T13:56:13","guid":{"rendered":"https:\/\/mytonswap.com\/blog\/?p=113"},"modified":"2024-10-06T13:58:39","modified_gmt":"2024-10-06T13:58:39","slug":"how-to-interact-with-func-contracts-using-ton-connect-ui-react","status":"publish","type":"post","link":"https:\/\/mytonswap.com\/blog\/2024\/10\/06\/how-to-interact-with-func-contracts-using-ton-connect-ui-react\/","title":{"rendered":"How to Interact with FunC Contracts Using @ton-connect\/ui-react"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"574\" src=\"https:\/\/mytonswap.com\/blog\/wp-content\/uploads\/2024\/10\/MTS-Blog--1024x574.png\" alt=\"How To Interact With Your FunC Contract Using @ton-connect\/ui-react\" class=\"wp-image-122\" srcset=\"https:\/\/mytonswap.com\/blog\/wp-content\/uploads\/2024\/10\/MTS-Blog--1024x574.png 1024w, https:\/\/mytonswap.com\/blog\/wp-content\/uploads\/2024\/10\/MTS-Blog--300x168.png 300w, https:\/\/mytonswap.com\/blog\/wp-content\/uploads\/2024\/10\/MTS-Blog--768x430.png 768w, https:\/\/mytonswap.com\/blog\/wp-content\/uploads\/2024\/10\/MTS-Blog-.png 1456w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>The <strong>TON (The Open Network)<\/strong> blockchain is one of the most innovative blockchain projects, offering high speed and extensive scalability, making it an ideal platform for developing decentralized applications (dApps). In this network, smart contracts play a crucial role in automating transactions and creating complex services.<\/p>\n\n\n\n<p>As dApps continue to grow, developers require tools that make it easy to link digital wallets to their applications. TonConnect offers a robust and secure solution, enabling developers to integrate multiple wallets with their dApps and streamline interactions with smart contracts.<\/p>\n\n\n\n<p>In this tutorial, we will use <strong>TonConnect<\/strong> and the React library to explore step-by-step how to interact with smart contracts on the TON blockchain. From setting up a project with React to connecting a digital wallet and sending transactions to the smart contract, we will cover all the steps in detail.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p><em>Foundational knowledge of React and TypeScript will help you with this tutorial more easily.<\/em><\/p>\n\n\n\n<p>Given that the TON blockchain is fundamentally based on smart contracts, it\u2019s evident that we require a method to interact with these contracts in order to create decentralized applications (dApps).<\/p>\n\n\n\n<p>For example, let\u2019s say you plan to create a <strong>ticketing system<\/strong> and provide it to users as a website. To accomplish this, you&#8217;ll need to interact with the smart contract related to the ticketing system. This involves sending transactions to the smart contract and receiving responses from it.<\/p>\n\n\n\n<p>In this tutorial, we\u2019ll assume you have already created your smart contract and are ready to deploy it. For demonstration purposes, we will use a smart contract for a ticketing system. If you haven&#8217;t yet prepared your smart contract, you can refer to this sample ticketing system smart contract on <a href=\"https:\/\/github.com\/MyTonSwap\/tutorials\/tree\/main\/01-ton-ticket-system-main\" data-type=\"link\" data-id=\"https:\/\/github.com\/Ho3einWave\/ton-ticket-system\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Required Tools and Development Environment:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Node.js<\/strong> and <strong>NPM<\/strong>: For managing packages and running the project.<\/li>\n\n\n\n<li><strong>React<\/strong>: To build the application&#8217;s user interface.<\/li>\n\n\n\n<li><strong>TypeScript<\/strong>: For safer coding practices and improved type management.<\/li>\n\n\n\n<li><strong>TonConnect SDK<\/strong>: To enable communication between the wallet and the smart contract.<\/li>\n\n\n\n<li><strong>TON Wallet<\/strong> (like Tonkeeper): For interacting with the TON network and carrying out transactions.<\/li>\n\n\n\n<li><strong>A TON blockchain environment<\/strong>: For developing and testing smart contracts (the TON testnet can be used).<\/li>\n<\/ul>\n\n\n\n<p>To begin, you&#8217;ll need to set up a <strong>React<\/strong> project. You can use any bundler you choose. In this tutorial, we will use <strong>Vite<\/strong> as our bundler due to its fast performance and efficiency in developing React projects.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>;; creates the project with react-ts template\nnpm create vite@latest my-react-app -- --template react-ts\n;; change directory to project folder\ncd my-react-app\n;; install dependecies\nnpm i<\/code><\/pre>\n\n\n\n<p>Once the project is set up, we will need to install a few libraries to facilitate interaction with smart contracts in <strong>React<\/strong>. You can do this by executing the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm i @ton\/ton @tonconnect\/ui-react @orbs-network\/ton-access zustand\n<\/code><\/pre>\n\n\n\n<p>Once you have installed the necessary libraries, the next step is to add the <strong>wrapper<\/strong> file for your smart contract. This wrapper file enables you to interact seamlessly with the methods and attributes of the smart contract.<\/p>\n\n\n\n<p>To accomplish this, create a new folder called contract in your project directory and save the smart contract wrapper file in that folder. This file will include all the essential functions and methods needed to interact with your smart contract.<\/p>\n\n\n\n<p>The layout of your project folder after adding this file will look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>src\/\n\tcontract\/\n\t\tTicketSystem.ts\n\t\tJettonWallet.ts\n\t\tJettonWallet.ts<\/code><\/pre>\n\n\n\n<p>This wrapper file will act as a bridge between your React user interface and your smart contract.<\/p>\n\n\n\n<p>Once you have added the smart contract <strong>wrapper<\/strong> file to your React project, the next step is to open it with a client to enable direct interaction with the smart contract. However, before we do that, we need to set up a <strong>store<\/strong> to manage and store contract information at the application level. For this, we will utilize the <strong>zustand<\/strong> library.<\/p>\n\n\n\n<p>In the next step, we will create a new file to manage the state of the smart contract using Zustand. This store will enable us to share the contract&#8217;s status and associated information across the application.<\/p>\n\n\n\n<p>Create a new file named <strong>contractStore.js<\/strong> (or .ts if you&#8217;re using TypeScript) in the <strong>src\/store<\/strong> directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { address, OpenedContract } from '@ton\/core';\nimport { create } from 'zustand';\nimport { TicketSystem } from '..\/contracts\/TicketSystem';\nimport { TonClient } from '@ton\/ton';\nimport { getHttpEndpoint } from '@orbs-network\/ton-access';\nimport { contractAddress } from '..\/constants';\n\ntype State = {\n\tticketSystem: OpenedContract&lt;TicketSystem&gt; | null;\n\tclient: TonClient | null;\n};\n\ntype Action = {\n\tsetupTicketSystem: () =&gt; void;\n};\n\nexport const useTicketSystem = create&lt;State &amp; Action&gt;((set, get) =&gt; ({\n\tticketSystem: null,\n\tclient: null,\n\tsetupTicketSystem: async () =&gt; {\n\t\tconst currTicketSystem = get().ticketSystem;\n\t\tif (currTicketSystem) return;\n\t\tconst client = new TonClient({\n\t\t\tendpoint: await getHttpEndpoint({ network: 'testnet' }),\n\t\t});\n\t\tconst ticketSystem = client.open(TicketSystem.createFromAddress(address(contractAddress)));\n\t\tset(() =&gt; ({ ticketSystem, client }));\n\t},\n}));<\/code><\/pre>\n\n\n\n<p>In this section, we need to store both the contract opened by the client and the client itself. Since some functions are <strong>async<\/strong>, we will need a function to initialize the client.<\/p>\n\n\n\n<p>In the <strong>App.tsx<\/strong> file, we will import the <strong>useTicketSystem<\/strong> hook and the necessary items for TonConnect as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useTicketSystem } from '..\/hooks\/useTicket';\nimport { CHAIN, TonConnectButton, useTonConnectModal, useTonConnectUI } from '@tonconnect\/ui-react';<\/code><\/pre>\n\n\n\n<p>After importing the hooks, we need to (initialize) the following hooks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const { setupTicketSystem } = useTicketSystem();\nconst &#91;tonConnectUI, setOptions] = useTonConnectUI();\nconst { open } = useTonConnectModal();\nuseEffect(() =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; setupTicketSystem();\n&nbsp; &nbsp; &nbsp; &nbsp; setOptions({ actionsConfiguration: { modals: &#91;'before', 'error', 'success'] } });\n&nbsp; &nbsp; }, &#91;]);<\/code><\/pre>\n\n\n\n<p>we can check the wallet connection status using the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const &#91;walletConnected, setWalletConnected] = useState(false);\nconst walletTonConnect = useTonWallet();\nuseEffect(() =&gt; {\n\tif (walletTonConnect) {\n\t\tsetWalletConnected(true);\n\t} else {\n\t\tsetWalletConnected(false);\n\t}\n}, &#91;walletTonConnect]);<\/code><\/pre>\n\n\n\n<p>To send a message from the user&#8217;s wallet to the smart contract, we need a <strong>state<\/strong> and a <strong>function<\/strong>, which are defined in the code below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\tconst &#91;buyCount, setBuyCount] = useState(1);\n&nbsp; &nbsp; const handlePay = async (pay_with: 'o1' | 'o-mini') =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; const message = await getTransaction(address(tonConnectUI.account!.address), pay_with, buyCount);\n&nbsp; &nbsp; &nbsp; &nbsp; tonConnectUI\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .sendTransaction({ messages: &#91;message], validUntil: Date.now() + 500 * 60 * 1000, network: CHAIN.TESTNET })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((res) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const boc = Cell.fromBase64(res.boc);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(boc.hash().toString('hex'));\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch((e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(e);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; &nbsp; onOpenChange();\n&nbsp; &nbsp; };<\/code><\/pre>\n\n\n\n<p>In the code above, there is a function named <strong>getTransaction<\/strong> that prepares our message for sending to the network. This function can look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Address, address, toNano, } from \"@ton\/ton\"\nimport { useTicketSystem } from \"..\/hooks\/useTicket\"\nimport { JettonMinter } from \"..\/contracts\/JettonMaster\"\nimport { JettonWallet } from \"..\/contracts\/JettonWallet\"\nimport { contractAddress } from \"..\/constants\"\n\nexport default async (owner: Address, paywith: \"o1\" | \"o-mini\", how_many: number) =&gt; {\n&nbsp; &nbsp; const contractAddr = address(contractAddress)\n&nbsp; &nbsp; const client = useTicketSystem.getState().client!\n&nbsp; &nbsp; if (paywith === \"o1\") {\n&nbsp; &nbsp; &nbsp; &nbsp; const O1master = client.open(JettonMinter.createFromAddress(address(\"kQDAiO286SYcHCnj6-U_bWIBbURv14yqptYPvMWzVfC7WI-J\")))\n&nbsp; &nbsp; &nbsp; &nbsp; const o1WalletAddr = await O1master.getWalletAddress(owner)\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ @ts-expect-error\n&nbsp; &nbsp; &nbsp; &nbsp; const cell = JettonWallet.transferMessage(toNano(`${how_many}`), contractAddr, owner, null, toNano(\"0.01\"), null)\n&nbsp; &nbsp; &nbsp; &nbsp; const message = {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; address: o1WalletAddr.toString(),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amount: toNano(\"0.05\").toString(),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; payload: cell.toBoc().toString(\"base64\")\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; return message\n&nbsp; &nbsp; } else {\n&nbsp; &nbsp; &nbsp; &nbsp; const Ominimaster = client.open(JettonMinter.createFromAddress(address(\"kQAuG2F399vT2Bsf_lYAXzZKpSjVP7Y7No9d--6BiX_Dq7kv\")))\n&nbsp; &nbsp; &nbsp; &nbsp; const ominiWallet = await Ominimaster.getWalletAddress(owner)\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ @ts-expect-error\n&nbsp; &nbsp; &nbsp; &nbsp; const cell = JettonWallet.transferMessage(toNano(`${how_many * 2}`), contractAddr, owner, null, toNano(\"0.01\"), null)\n&nbsp; &nbsp; &nbsp; &nbsp; const message = {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; address: ominiWallet.toString(),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; amount: toNano(\"0.05\").toString(),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; payload: cell.toBoc().toString(\"base64\")\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; return message\n&nbsp; &nbsp; }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>In this tutorial, we explored the steps for interacting with smart contracts on the <strong>TON<\/strong> blockchain network. By using <strong>TonConnect<\/strong> and the <strong>React<\/strong> library, we were able to design a simple decentralized application (dApp) for sending messages to a smart contract.<\/p>\n\n\n\n<p>The key steps in this tutorial were as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Setting Up the <strong>React<\/strong> Project: We created a new React project using <strong>Vite<\/strong> and installed the necessary libraries.<\/li>\n\n\n\n<li><strong>Creating the Contract Wrapper<\/strong>: We added the smart contract wrapper file to the project, allowing us to easily interact with the contract&#8217;s methods.<\/li>\n\n\n\n<li><strong>Managing State with Zustand<\/strong>: We created a store to store the smart contract information, enabling us to share the contract&#8217;s status throughout the application.<\/li>\n\n\n\n<li><strong>Configuring the TonConnect Client<\/strong>: We initialized the client and checked the wallet connection status for users.<\/li>\n\n\n\n<li><strong>Sending Messages to the Contract<\/strong>: We sent messages to the smart contract using a function to prepare the transaction and manage user input.<\/li>\n<\/ol>\n\n\n\n<p>This process enables developers to easily and efficiently create their decentralized applications using TonConnect, taking advantage of the smart contract capabilities on the TON blockchain network.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The TON (The Open Network) blockchain is one of the most innovative blockchain projects, offering high speed and extensive scalability, making it an ideal platform for developing decentralized applications (dApps). In this network, smart contracts play a crucial role in automating transactions and creating complex services. As dApps continue to grow, developers require tools that make it easy to link digital wallets to their applications. TonConnect offers a robust and secure solution, enabling developers to integrate multiple wallets with their dApps and streamline interactions with smart contracts. In this tutorial, we will use TonConnect and the React library to explore step-by-step how to interact with smart contracts on the TON blockchain. From setting up a project with React to connecting a digital wallet and sending transactions to the smart contract, we will cover all the steps in detail. Prerequisites Foundational knowledge of React and TypeScript will help you with this tutorial more easily. Given that the TON blockchain is fundamentally based on smart contracts, it\u2019s evident that we require a method to interact with these contracts in order to create decentralized applications (dApps). For example, let\u2019s say you plan to create a ticketing system and provide it to users as [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":122,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rank_math_lock_modified_date":false,"footnotes":""},"categories":[15],"tags":[17,16],"class_list":["post-113","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","tag-dev","tag-tutorials"],"_links":{"self":[{"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/posts\/113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/comments?post=113"}],"version-history":[{"count":6,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/posts\/113\/revisions"}],"predecessor-version":[{"id":125,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/posts\/113\/revisions\/125"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/media\/122"}],"wp:attachment":[{"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/media?parent=113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/categories?post=113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mytonswap.com\/blog\/wp-json\/wp\/v2\/tags?post=113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}