{"id":19107395,"url":"https://github.com/smartcontractkit/ccip-tic-tac-toe","last_synced_at":"2025-04-30T18:46:17.181Z","repository":{"id":182281904,"uuid":"660496983","full_name":"smartcontractkit/ccip-tic-tac-toe","owner":"smartcontractkit","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-05T14:52:36.000Z","size":757,"stargazers_count":10,"open_issues_count":0,"forks_count":11,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-06-05T17:03:05.539Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smartcontractkit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-30T06:27:25.000Z","updated_at":"2024-06-05T14:52:41.000Z","dependencies_parsed_at":"2024-06-05T17:05:28.337Z","dependency_job_id":null,"html_url":"https://github.com/smartcontractkit/ccip-tic-tac-toe","commit_stats":null,"previous_names":["smartcontractkit/ccip-tic-tac-toe"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-tic-tac-toe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-tic-tac-toe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-tic-tac-toe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smartcontractkit%2Fccip-tic-tac-toe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smartcontractkit","download_url":"https://codeload.github.com/smartcontractkit/ccip-tic-tac-toe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223783167,"owners_count":17201915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T04:12:29.651Z","updated_at":"2024-11-09T04:12:30.187Z","avatar_url":"https://github.com/smartcontractkit.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## CCIP Tic-Tac-Toe \n\n\u003e **Note**\n\u003e\n\u003e _This repository represents an example of using a Chainlink product or service. It is provided to help you understand how to interact with Chainlink’s systems so that you can integrate them into your own. This template is provided \"AS IS\" without warranties of any kind, has not been audited, and may be missing key checks or error handling to make the usage of the product more clear. Take everything in this repository as an example and not something to be copy pasted into a production ready service._\n\nThis project demonstrates how Chainlink CCIP can be used to create a cross-chain Tic-Tac-Toe game\n\n\n## Prerequisites\n\n- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)\n- [Current LTS Node.js version](https://nodejs.org/en/about/releases/)\n\nVerify installation by typing:\n\n```shell\nnode -v\n```\n\nand\n\n```shell\nnpm -v\n```\n\n## Getting Started\n\n1. Install packages\n\n```\nnpm install\n```\n\n2. Compile contracts\n\n```\nnpx hardhat compile\n```\nComment out `import './tasks'` line in the file `hardhat.config` if you have issue of it. Please don't forget uncomment the line after compiling.\n\n3. Run tests\n\n```\nTS_TRANSPILE_NODE=1 npx hardhat test\n```\n\n## What is Chainlink CCIP?\n\n**Chainlink Cross-Chain Interoperability Protocol (CCIP)** provides a single, simple, and elegant interface through which dApps and web3 entrepreneurs can securely meet all their cross-chain needs, including token transfers and arbitrary messaging.\n\n![basic-architecture](./img/basic-architecture.png)\n\nWith Chainlink CCIP, one can:\n\n- Transfer supported tokens\n- Send messages (any data)\n- Send messages and tokens\n\nCCIP receiver can be:\n\n- Smart contract that implements `CCIPReceiver.sol`\n- EOA\n\n**Note**: If you send a message and token(s) to EOA, only tokens will arrive\n\nTo use this project, you can consider CCIP as a \"black-box\" component and be aware of the Router contract only. If you want to dive deep into it, check the [Official Chainlink Documentation](docs.chain.link).\n\n## Usage\n\nIn the next section you can see a couple of basic Chainlink CCIP use case examples. But before that, you need to set up some environment variables.\n\nWe are going to use the [`@chainlink/env-enc`](https://www.npmjs.com/package/@chainlink/env-enc) package for extra security. It encrypts sensitive data instead of storing them as plain text in the `.env` file, by creating a new, `.env.enc` file. Although it's not recommended to push this file online, if that accidentally happens your secrets will still be encrypted.\n\n1. Set a password for encrypting and decrypting the environment variable file. You can change it later by typing the same command.\n\n```shell\nnpx env-enc set-pw\n```\n\n2. Now set the following environment variables: `PRIVATE_KEY`, Source Blockchain RPC URL, Destination Blockchain RPC URL. You can see available options in the `.env.example` file:\n\n```shell\nETHEREUM_SEPOLIA_RPC_URL=\"\"\nOPTIMISM_SEPOLIA_RPC_URL=\"\"\nARBITRUM_SEPOLIA_RPC_URL=\"\"\nAVALANCHE_FUJI_RPC_URL=\"\"\nPOLYGON_AMOY_RPC_URL=\"\"\n```\n\nTo set these variables, type the following command and follow the instructions in the terminal:\n\n```shell\nnpx env-enc set\n```\n\nAfter you are done, the `.env.enc` file will be automatically generated.\n\nIf you want to validate your inputs you can always run the next command:\n\n```shell\nnpx env-enc view\n```\n\n## Example: Cross-chain Tic Tac Toe Game\nIn this example, we will use a simple game called TicTacToe to demonstrate how to transmit messages from one chain to another using CCIP. \n\nIn the game, we will deploy the TicTacToe smart contract on two different blockchains. By sending a transaction on the source chain, which can be either \"start\" or \"move,\" the state of the game board will be modified, and these states will be \"synchronized\" by Chainlink CCIP on the other chain.\n\nBefore starting the game, the contract needs to be deployed on two different blockchains using the following commands:\n\n### 1. Deploy TicTacToe smart contract\n```shell\nnpx hardhat run ./scripts/deployTicTacToe.ts --network \u003cblockchain\u003e\nnpx hardhat run ./scripts/deployTicTacToe.ts --network \u003cblockchain\u003e\n```\n\nWhere the list of supported chains consists of (case sensitive):\n\n- ethereumSepolia\n- optimismSepolia\n- arbitrumSepolia\n- avalancheFuji\n- polygonAmoy\n\nAlthough you can choose any two chains from the list, I highly recommend using Sepolia and Fuji because time consumed by CCIP to relay messages between these 2 chains are relatively shorter. If you want to deploy the contract at Sepolia and Fuji, the commands:\n\n```shell\nnpx hardhat run ./scripts/deployTicTacToe.ts --network ethereumSepolia\nnpx hardhat run ./scripts/deployTicTacToe.ts --network avalancheFuji\n```\n\n### 2. Transfer native tokens to TicTacToe smart contract\nAfter the deployment of the contract, you must transfer native tokens to these 2 contracts respectively. If you deployed contracts on Fuji and Sepolia, please transfer 2 AVAX and 0.01 ETH to contracts on Fuji and Sepolia respectively. If you are trying with polygon amoy, please transfer 2 MATIC to contract. \n\n### 3. Update router\nPlease use commands below to update router address for `ccipSend`. For most of cases, the router addresses input here are same as router addresses of CCIP. \n```shell\nnpx hardhat ttt-update-router --blockchain ethereumSepolia --contract \u003caddress of TicTacToe on Ethereum Sepolia\u003e --router 0xd0daae2231e9cb96b94c8512223533293c3693bf\nnpx hardhat ttt-update-router --blockchain avalancheFuji --contract \u003caddress of TicTacToe on Avalanche Fuji\u003e --router 0x554472a2720e5e7d5d3c817529aba05eed5f82d8\n```\nSince you can have your own proxy to forward request to CCIP, update the addresses above with your own proxy addresses if you want to use proxies. If you don't want to use proxies, keep the router addresses the same as CCIP. \n\nRouter addresses are listed below:\n- Ethereum Sepolia: 0xd0daae2231e9cb96b94c8512223533293c3693bf\n- Polygon Amoy: 0x9C32fCB86BF0f4a1A8921a9Fe46de3198bb884B2\n- Optimism Sepolia: 0x114A20A10b43D4115e5aeef7345a1A71d2a60C57\n- Avalanche Fuji: 0x554472a2720e5e7d5d3c817529aba05eed5f82d8\n- Arbitrum Sepolia: 0x2a9C5afB0d0e4BAb2BCdaE109EC4b0c4Be15a165\n\n\n### 4. Player 1 starts a game\nYou can start a new game through a TicTacToe contract on any chain. The player who starts a game is player 1. Player 1 needs to send a transaction to create a session, allowing the other player on the other chain to join that session and make a move.\n\nStart a game with the command blow:\n```shell\nnpx hardhat ttt-start --source-blockchain ethereumSepolia --sender \u003caddress of TicTacToe on Ethereum Sepolia\u003e --destination-blockchain avalancheFuji --receiver \u003caddress of TicTacToe on Avalanche Fuji\u003e\n```\nYou will see the message below in the terminal and that means the message is sent by CCIP.\n```\n✅ Message sent, game session created! transaction hash: 0x1f65e17eef0fd9664c389d825db317ec385fe5b1f79baa62aded05583f980e1a\n```\nWhile the message sent to CCIP, the status would not be synced until the the message is finalized on source chain and written into the contract on the other chain. Check the information in CCIP explorer and find message below to make sure the message sent to the dest chain. \n\n![alt text](./img/messageInCCIP.png \"Coordinates\")\n\nUsually it takes about 20mins to complete the cross-chain transaction.\n\n\n### 5. Get session ID by index\nIn order to join a game, a player needs to know the session ID of the game.\n\nGet the session ID of the game by index with the command below: \n```shell\nnpx hardhat ttt-get-sessionId --blockchain ethereumSepolia --contract \u003caddress of TicTacToe on Ethereum Sepolia\u003e --index 0\n```\n\n### 6. Player 2 makes a move in blockchain 2\nPlayer 2 on the other chain can make a move within the game session. The player needs to select a position with x and y coordinates(the range of x and y are from 0 to 2) with the command below:\n```shell\nnpx hardhat ttt-move --x \u003cx coordinate\u003e --y \u003cy coordinate\u003e --player 2 --session-id \u003csessionId\u003e --source-blockchain avalancheFuji --sender \u003caddress of TicTacToe on Avalanche Fuji\u003e --destination-blockchain ethereumSepolia --receiver \u003caddress of TicTacToe on Ethereum Sepolia\u003e\n```\nthe x and y are coordinates in the board. eg:\n\n![alt text](./img/xyCoordinates.png \"Coordinates\")\n\n### 7. Player 1 makes a move in blockchain 1\nAfter player 2 made the move, player 1 can make the move with x and y coordinates. Please noted that transaction will fail if the position of represented by x and y coordinates is occupied.\n\nPlayer 1 makes a move with command below:\n```shell\nnpx hardhat ttt-move --x \u003cx coordinate\u003e --y \u003cy coordinate\u003e --player 1 --session-id \u003csessionId\u003e --source-blockchain ethereumSepolia --sender \u003caddress of TicTacToe on Ethereum Sepolia\u003e --destination-blockchain avalancheFuji --receiver \u003caddress of TicTacToe on Avalanche Fuji\u003e\n```\n\n### 8. Repeat 6 and 7\nRepeat steps 6 and 7 until either combination of player 1 or player 2 matches a winning combination.\n### 9. Check the winner\nCheck the winner by command:\n```shell\nnpx hardhat ttt-check-winner --blockchain ethereumSepolia --contract \u003caddress of TicTacToe on Ethereum Sepolia\u003e --session-id \u003csessionId\u003e\n```\nyou can also check the winner from the contract on the other blockChain with command:\n```shell\nnpx hardhat ttt-check-winner --blockchain avalancheFuji --contract \u003caddress of TicTacToe on Avalanche Fuji\u003e --session-id \u003csessionId\u003e\n```\n\n### Front-end of Tic-Tac-Toe\nIf you're interested in trying to interact with CCIP Tic-Tac-Toe using the frontend, please refer to the frontend [README.md](./frontend/README.md) here to learn how to use it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fccip-tic-tac-toe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmartcontractkit%2Fccip-tic-tac-toe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmartcontractkit%2Fccip-tic-tac-toe/lists"}