diff --git a/docs/tutorials/marketpulse/backend.md b/docs/tutorials/marketpulse/backend.md index 6f10007d..fbc44bfe 100644 --- a/docs/tutorials/marketpulse/backend.md +++ b/docs/tutorials/marketpulse/backend.md @@ -5,15 +5,9 @@ For more information about Solidity, see https://docs.soliditylang.org. Follow these steps to set up a Solidity smart contract: -1. Remove the default Solidity smart contract `Lock.sol` in the `./contracts` folder. +1. Remove the default Solidity smart contract files `Counter.sol` and `Counter.t.sol` in the `./contracts` folder. -1. Create a new file named `Marketpulse.sol` in the `./contracts` folder. - - ```bash - touch ./contracts/Marketpulse.sol - ``` - -1. Put this code in the file: +1. Create a new file named `./contracts/Marketpulse.sol` with the following content: ```Solidity // SPDX-License-Identifier: MIT diff --git a/docs/tutorials/marketpulse/cicd.md b/docs/tutorials/marketpulse/cicd.md index 4860e53d..7873ed75 100644 --- a/docs/tutorials/marketpulse/cicd.md +++ b/docs/tutorials/marketpulse/cicd.md @@ -30,15 +30,13 @@ Here is an example of one using the Github configuration files and [Vercel](http - name: Check out repository code uses: actions/checkout@v3 - name: Use node - env: - DEPLOYER_PRIVATE_KEY: uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: 'npm' - run: npm ci - - run: HARDHAT_VAR_DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat compile - - run: HARDHAT_VAR_DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat test + - run: DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat compile + - run: DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat test - name: Cache build-hardhat-artifacts uses: actions/upload-artifact@v4 with: @@ -59,10 +57,10 @@ Here is an example of one using the Github configuration files and [Vercel](http - name: Use node uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: 'npm' - run: npm ci - - run: yes | HARDHAT_VAR_DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat ignition deploy ignition/modules/Marketpulse.ts --verify --reset --network etherlinkTestnet + - run: yes | DEPLOYER_PRIVATE_KEY=${{ secrets.DEPLOYER_PRIVATE_KEY }} npx hardhat ignition deploy ignition/modules/Marketpulse.ts --verify --reset --network etherlinkShadownet - name: Cache hardhat-ignition uses: actions/upload-artifact@v4 with: @@ -88,11 +86,11 @@ Here is an example of one using the Github configuration files and [Vercel](http - name: Use node uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: 'npm' - run: npm ci working-directory: ./app - - run: more ./ignition/deployments/chain-128123/deployed_addresses.json + - run: more ./ignition/deployments/chain-127823/deployed_addresses.json - run: npm run build working-directory: ./app - name: Cache app build @@ -110,7 +108,7 @@ Here is an example of one using the Github configuration files and [Vercel](http - name: Use node uses: actions/setup-node@v4 with: - node-version: 18 + node-version: 22 cache: 'npm' - name: Install Vercel CLI run: npm install -g vercel @@ -150,7 +148,7 @@ Here is an example of one using the Github configuration files and [Vercel](http 1. Set these variables in the GitHub pipeline configuration: - `DEPLOYER_PRIVATE_KEY`: The Etherlink account secret `private key` you need to use to deploy with Hardhat. This variable overrides the default environment variable mechanism of HardHat. - - `VERCEL_TOKEN`: Your personal Vercel token that you need to create on your Vercel account. For more information about configuring Vercel, see https://vercel.com/guides/how-can-i-use-github-actions-with-vercel. + - `VERCEL_TOKEN`: Your personal Vercel token that you need to create on your Vercel account. For more information about configuring Vercel, see https://vercel.com/kb/guide/how-do-i-use-a-vercel-api-access-token. You can set these variables in two ways: diff --git a/docs/tutorials/marketpulse/deploy.md b/docs/tutorials/marketpulse/deploy.md index 0694459a..b5e2a77d 100644 --- a/docs/tutorials/marketpulse/deploy.md +++ b/docs/tutorials/marketpulse/deploy.md @@ -1,20 +1,22 @@ --- title: Deploy the contract dependencies: - viem: 0 + viem: 2.41.2 + hardhat: 3.0.17 --- Deploy the contract locally is fine for doing simple tests, but we recommend to target the Etherlink Testnet to run complete scenarios as you may depend on other services like block explorers, oracles, etc. 1. Deploy the contract locally with Hardhat: - 1. Prepare a module for the ignition plugin of Hardhat. The module is used as the default script for deployment. Rename the default file first: + 1. Remove the default module for the ignition plugin of Hardhat. + This module is used as the default script for deployment: ```bash - mv ./ignition/modules/Lock.ts ./ignition/modules/Marketpulse.ts + rm ./ignition/modules/Counter.ts ``` - 1. Replace the contents of the file with this code: + 1. Create a module to deploy your contract named `./ignition/modules/Marketpulse.ts` with the following content: ```TypeScript // This setup uses Hardhat Ignition to manage smart contract deployments. @@ -41,7 +43,7 @@ Deploy the contract locally is fine for doing simple tests, but we recommend to npx hardhat node ``` - 1. In a different terminal window, deploy the contract using Hardhat ignition: + 1. In a different terminal window, within the same directory, deploy the contract using Hardhat ignition: ```bash npx hardhat ignition deploy ignition/modules/Marketpulse.ts --reset --network localhost @@ -49,88 +51,130 @@ Deploy the contract locally is fine for doing simple tests, but we recommend to You can deploy the contract to any local Ethereum node but Etherlink is a good choice because it is persistent and free and most tools and indexers are already deployed on it. + The response looks like this: + + ``` + Hardhat Ignition 🚀 + + Deploying [ MarketpulseModule ] + + Batch #1 + Executed MarketpulseModule#Marketpulse + + Batch #2 + Executed MarketpulseModule#Marketpulse.ping + + [ MarketpulseModule ] successfully deployed 🚀 + + Deployed Addresses + + MarketpulseModule#Marketpulse - 0x5FbDB2315678afecb367f032d93F642f64180aa3 + ``` + 1. Check that your deployment logs do not contain any error and stop the Hardhat node. -1. Deploy the contract on Etherlink Ghostnet Testnet: +1. Deploy the contract on Etherlink Shadownet Testnet: - 1. In the Hardhat configuration file `hardhat.config.ts`, add Etherlink Mainnet and Ghostnet Testnet as custom networks: + 1. In the Hardhat configuration file `hardhat.config.ts`, add Etherlink Mainnet and Shadownet Testnet as custom networks by replacing the default file with this code: ```TypeScript - import "@nomicfoundation/hardhat-toolbox-viem"; - import "@nomicfoundation/hardhat-verify"; - import type { HardhatUserConfig } from "hardhat/config"; - import { vars } from "hardhat/config"; + import hardhatToolboxViemPlugin from "@nomicfoundation/hardhat-toolbox-viem"; + import { configVariable, defineConfig } from "hardhat/config"; - if (!vars.has("DEPLOYER_PRIVATE_KEY")) { + if (!configVariable("DEPLOYER_PRIVATE_KEY")) { console.error("Missing env var DEPLOYER_PRIVATE_KEY"); } - const deployerPrivateKey = vars.get("DEPLOYER_PRIVATE_KEY"); - - const config: HardhatUserConfig = { - solidity: "0.8.24", + const deployerPrivateKey = configVariable("DEPLOYER_PRIVATE_KEY"); + export default defineConfig({ + plugins: [hardhatToolboxViemPlugin], + solidity: { + profiles: { + default: { + version: "0.8.28", + }, + production: { + version: "0.8.28", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + }, + }, networks: { + hardhatMainnet: { + type: "edr-simulated", + chainType: "l1", + }, + hardhatOp: { + type: "edr-simulated", + chainType: "op", + }, etherlinkMainnet: { + type: "http", url: "https://node.mainnet.etherlink.com", accounts: [deployerPrivateKey], }, - etherlinkTestnet: { - url: "https://node.ghostnet.etherlink.com", + etherlinkShadownet: { + type: "http", + url: "https://node.shadownet.etherlink.com", accounts: [deployerPrivateKey], }, }, - etherscan: { - apiKey: { - etherlinkMainnet: "DUMMY", - etherlinkTestnet: "DUMMY", - }, - customChains: [ - { - network: "etherlinkMainnet", - chainId: 42793, - urls: { - apiURL: "https://explorer.etherlink.com/api", - browserURL: "https://explorer.etherlink.com", + chainDescriptors: { + 127823: { + chainType: "generic", + name: "etherlinkShadownet", + blockExplorers: { + etherscan: { + name: "EtherlinkExplorer", + apiUrl: "https://shadownet.explorer.etherlink.com/api", + url: "https://shadownet.explorer.etherlink.com", }, }, - { - network: "etherlinkTestnet", - chainId: 128123, - urls: { - apiURL: "https://testnet.explorer.etherlink.com/api", - browserURL: "https://testnet.explorer.etherlink.com", - }, - }, - ], + }, + 42793: { + name: "EtherlinkMainnet", + } + }, + verify: { + blockscout: { + enabled: false, + }, + etherscan: { + apiKey: "DUMMY", + enabled: true, + }, + sourcify: { + enabled: false, + } } - }; - - export default config; + }); ``` - 1. Set up an Etherlink Ghostnet Testnet account with some native tokens to deploy the contract. See [Using your wallet](/get-started/using-your-wallet) connect your wallet to Etherlink. Then use the faucet to get XTZ tokens on Etherlink Ghostnet Testnet, as described in [Getting testnet tokens](/get-started/getting-testnet-tokens). + 1. Set up an Etherlink Shadownet Testnet account with some native tokens to deploy the contract. See [Using your wallet](/get-started/using-your-wallet) connect your wallet to Etherlink. Then use the faucet to get XTZ tokens on Etherlink Shadownet Testnet, as described in [Getting testnet tokens](/get-started/getting-testnet-tokens). - 1. Export your account private key from your wallet application. + 1. Retrieve your account private key, e.g. using your wallet. - 1. Set the private key as the value of the `DEPLOYER_PRIVATE_KEY` environment variable by running this command: + 1. Set the private key (represented in this example as ``) as the value of the `DEPLOYER_PRIVATE_KEY` environment variable by running this command: ```bash - npx hardhat vars set DEPLOYER_PRIVATE_KEY + export DEPLOYER_PRIVATE_KEY= ``` - On the prompt, enter or paste the value of your exported private key. Hardhat use its custom env var system for storing keys, we will see later how to override this on a CICD pipeline - - 1. Deploy the contract to Etherlink Ghostnet Testnet network specifying the `--network` option: + 1. Deploy the contract to Etherlink Shadownet Testnet network specifying the `--network` option: ```bash - npx hardhat ignition deploy ignition/modules/Marketpulse.ts --network etherlinkTestnet + npx hardhat ignition deploy ignition/modules/Marketpulse.ts --network etherlinkShadownet ``` A successful output should look like this: ```logs - Compiled 5 Solidity files successfully (evm target: paris). Hardhat Ignition 🚀 Deploying [ MarketpulseModule ] @@ -151,7 +195,7 @@ Deploy the contract locally is fine for doing simple tests, but we recommend to 1. Run this command to verify your deployed contract, using the contract address as the value of ``: ```bash - npx hardhat verify --network etherlinkTestnet + npx hardhat verify --network etherlinkShadownet ``` The response should include the message "Successfully verified contract Marketpulse on the block explorer" and a link to the block explorer. diff --git a/docs/tutorials/marketpulse/frontend.md b/docs/tutorials/marketpulse/frontend.md index aecc6fa7..bed1e6fd 100644 --- a/docs/tutorials/marketpulse/frontend.md +++ b/docs/tutorials/marketpulse/frontend.md @@ -1,35 +1,33 @@ --- title: Create the frontend application dependencies: - vite: 0 - viem: 0 + vite: 6.0.1 + viem: 2.41.2 --- -`Deno` is not mandatory as you can still use `npm`, but we use it on this tutorial. You can install it with [this link](https://docs.deno.com/runtime/getting_started/installation/) - 1. Create a frontend app on the same project root directory. Here we use `Vite` and `React` to start a default project; ```bash - deno run -A npm:create-vite@latest + npm create vite@latest ``` - If you have trouble with Deno, as on some Mac computers, you can create a non-deno project that works in a similar way by running this command: `npm create vite@latest`. - 1. Choose a name for the frontend project (such as `app`, which is what the examples later use), select the `React` framework, and select the `Typescript` language. +If prompted, don't use the experimental version of Vite, and choose to not install and run immediately, because we have a few more settings to do below. -1. Copy the images from the folder https://github.com/trilitech/tutorial-applications/tree/main/etherlink-marketpulse/app/public/ to the `app/public` folder of your application. - -1. Run the commands as in this example to install the dependencies and start the server: +1. Run these commands to install the dependencies: ```bash cd app npm install - npm run dev ``` - Now the Deno or Vite server is running a starter frontend application. +1. From the `./app` folder, download some sample images for the frontend application: -1. Stop the application. + ```bash + wget -O public/chiefs.png https://github.com/trilitech/tutorial-applications/raw/main/etherlink-marketpulse/app/public/chiefs.png + wget -O public/lions.png https://github.com/trilitech/tutorial-applications/raw/main/etherlink-marketpulse/app/public/lions.png + wget -O public/graph.png https://github.com/trilitech/tutorial-applications/raw/main/etherlink-marketpulse/app/public/graph.png + ``` 1. Within your frontend `./app` project, import the `Viem` library for blockchain interactions, `thirdweb` for the wallet connection and `bignumber` for calculations on large numbers: @@ -46,20 +44,14 @@ dependencies: 1. Add this line to the `scripts` section of the `./app/package.json` file in the frontend application: ```json - "postinstall": "cp ../ignition/deployments/chain-128123/deployed_addresses.json ./src && typechain --target=ethers-v6 --out-dir=./src/typechain-types --show-stack-traces ../artifacts/contracts/Marketpulse.sol/Marketpulse.json", + "postinstall": "cp ../ignition/deployments/chain-127823/deployed_addresses.json ./src && typechain --target=ethers-v6 --out-dir=./src/typechain-types --show-stack-traces ../artifacts/contracts/Marketpulse.sol/Marketpulse.json", ``` This script copies the output address of the last deployed contract into your source files and calls `typechain` to generate types from the ABI file from the Hardhat folders. 1. Run `npm i` to call the postinstall script automatically. You should see new files and folders in the `./src` folder of the frontend application. -1. Create an utility file to manage Viem errors. Better than the technical defaults and not helpful ones - - ```bash - touch src/DecodeEvmTransactionLogsArgs.ts - ``` - -1. Put this code in the `./app/src/DecodeEvmTransactionLogsArgs.ts` file: +1. Create a utility file called `app/src/DecodeEvmTransactionLogsArgs.ts` to manage Viem errors (better than the technical defaults and not helpful ones), with this content: ```Typescript import { @@ -144,7 +136,7 @@ dependencies: ``` -1. Edit `./app/src/main.tsx` to add a `Thirdweb` provider around your application. In the following example, replace **line 7** `` with your own `clientId` configured on the [Thirdweb dashboard here](https://portal.thirdweb.com/typescript/v4/getting-started#initialize-the-sdk): +1. Edit `./app/src/main.tsx` to add a `Thirdweb` provider around your application, by replacing its content with the one below. Then, replace on **line 8** the placeholder `` (including the delimiters `<` and `>`!) with your own `clientId` configured on the [Thirdweb dashboard here](https://portal.thirdweb.com/typescript/v4/getting-started#initialize-the-sdk): ```Typescript import { createRoot } from "react-dom/client"; @@ -187,7 +179,7 @@ dependencies: import { ConnectButton, useActiveAccount } from "thirdweb/react"; import { createWallet, inAppWallet } from "thirdweb/wallets"; import { parseEther } from "viem"; - import { etherlinkTestnet } from "viem/chains"; + import { etherlinkShadownetTestnet } from "viem/chains"; import { extractErrorDetails } from "./DecodeEvmTransactionLogsArgs"; import CONTRACT_ADDRESS_JSON from "./deployed_addresses.json"; @@ -218,6 +210,13 @@ dependencies: export default function App({ thirdwebClient }: AppProps) { console.log("*************App"); + const marketPulseContract = { + abi: Marketpulse__factory.abi, + client: thirdwebClient, + chain: defineChain(etherlinkShadownetTestnet.id), + address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], + } + const account = useActiveAccount(); const [options, setOptions] = useState>(new Map()); @@ -235,45 +234,25 @@ dependencies: console.log("No address..."); } else { const dataStatus = await readContract({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "status", params: [], }); const dataWinner = await readContract({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "winner", params: [], }); const dataFEES = await readContract({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "FEES", params: [], }); const dataBetKeys = await readContract({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "getBetKeys", params: [], }); @@ -310,13 +289,7 @@ dependencies: betKeys.map( async (betKey) => (await readContract({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: - CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "getBets", params: [betKey], })) as unknown as Marketpulse.BetStruct @@ -348,12 +321,7 @@ dependencies: const handlePing = async () => { try { const preparedContractCall = await prepareContractCall({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "ping", params: [], }); @@ -368,7 +336,7 @@ dependencies: //wait for tx to be included on a block const receipt = await waitForReceipt({ client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), + chain: defineChain(etherlinkShadownetTestnet.id), transactionHash: transaction.transactionHash, }); @@ -398,12 +366,7 @@ dependencies: const runFunction = async () => { try { - const contract = getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }); + const contract = getContract(marketPulseContract); const preparedContractCall = await prepareContractCall({ contract, @@ -420,7 +383,7 @@ dependencies: //wait for tx to be included on a block const receipt = await waitForReceipt({ client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), + chain: defineChain(etherlinkShadownetTestnet.id), transactionHash: transaction.transactionHash, }); @@ -559,12 +522,7 @@ dependencies: const resolve = async (option: string) => { try { const preparedContractCall = await prepareContractCall({ - contract: getContract({ - abi: Marketpulse__factory.abi, - client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), - address: CONTRACT_ADDRESS_JSON["MarketpulseModule#Marketpulse"], - }), + contract: getContract(marketPulseContract), method: "resolveResult", params: [option, BET_RESULT.WIN], }); @@ -579,7 +537,7 @@ dependencies: //wait for tx to be included on a block const receipt = await waitForReceipt({ client: thirdwebClient, - chain: defineChain(etherlinkTestnet.id), + chain: defineChain(etherlinkShadownetTestnet.id), transactionHash: transaction.transactionHash, }); @@ -605,7 +563,7 @@ dependencies: client={thirdwebClient} wallets={wallets} connectModal={{ size: "compact" }} - chain={defineChain(etherlinkTestnet.id)} + chain={defineChain(etherlinkShadownetTestnet.id)} /> @@ -615,7 +573,7 @@ dependencies:

@@ -636,7 +594,6 @@ dependencies: Internal txns tab**, you should see, if you won something, the expected amount transferred to you from the smart contract address. + 1. Find your transaction `resolveResult` on the Etherlink Shadownet Testnet explorer at `https://shadownet.explorer.etherlink.com`. In the **Transaction details>Internal txns tab**, you should see, if you won something, the expected amount transferred to you from the smart contract address. diff --git a/docs/tutorials/marketpulse/setup.md b/docs/tutorials/marketpulse/setup.md index 9d6a1fba..ad8d5167 100644 --- a/docs/tutorials/marketpulse/setup.md +++ b/docs/tutorials/marketpulse/setup.md @@ -1,4 +1,8 @@ -# Set up a development environment for Etherlink +--- +title: Set up a development environment for Etherlink +dependencies: + hardhat: 3.0.17 +--- > Etherlink is 100% compatible with Ethereum technology, which means that you can use any Ethereum-compatible tool for development, including Hardhat, Foundry, Truffle Suite, and Remix IDE. > For more information on tools that work with Etherlink, see [Developer toolkits](https://docs.etherlink.com/building-on-etherlink/development-toolkits) in the Etherlink documentation. @@ -7,25 +11,35 @@ In this tutorial, you use [Hardhat](https://hardhat.org/tutorial/creating-a-new- You also use Viem, which is a lightweight, type-safe Ethereum library for JavaScript/TypeScript. It provides low-level, efficient blockchain interactions with minimal abstraction. +1. Install Node.JS version 22 or later, which is required for Hardhat. + 1. [Install npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). -1. Initialize an Node project with NPM: +1. Initialize an Node project with NPM in a fresh directory: ```bash npm init -y - npm install -D typescript @types/node ts-node + npm install -D typescript @types/node ts-node chai @types/chai ``` 1. Install Hardhat and initialize it: ```bash npm install -D hardhat - npx hardhat init + npx hardhat --init ``` -1. In the Hardhat prompts, select `Create a TypeScript project (with Viem)`. +1. Follow these steps in the Hardhat prompts: + + 1. In the Hardhat prompts, select version 3 of Hardhat and `.` as the relative path to the project. + + 1. In the prompt for the type of project to create, select `A TypeScript Hardhat project using Node Test Runner and Viem`. + + 1. Select `true` or `Y` to convert the project's `package.json` file to ESM. + + 1. At the prompt to install dependencies, select `true` or `Y`. -1. At the prompt `Do you want to install this sample project's dependencies with npm (@nomicfoundation/hardhat-toolbox-viem)? (Y/n)` select `Y`. + 1. If Hardhat prompts you to update TypeScript dependencies, select `true` or `Y`. 1. Install `@openzeppelin/contracts` to use the Math library for safe calculations: diff --git a/docs/tutorials/marketpulse/test.md b/docs/tutorials/marketpulse/test.md index d0528448..1be5402d 100644 --- a/docs/tutorials/marketpulse/test.md +++ b/docs/tutorials/marketpulse/test.md @@ -1,24 +1,26 @@ --- title: Test the contract dependencies: - viem: 0 + viem: 2.41.2 + hardhat: 3.0.17 --- With blockchain development, testing is very important because you don't have the luxury to redeploy application updates as it. Hardhat provides you smart contract helpers on `chai` Testing framework to do so. -1. Rename the default `./test/Lock.ts` test file to `./test/Marketpulse.ts`: +1. Remove the default `./test/Counter.ts` test file: ```bash - mv ./test/Lock.ts ./test/Marketpulse.ts + rm ./test/Counter.ts ``` -1. Replace the default file with this code: +1. Create a test file named `./test/Marketpulse.ts` with the following content: ```TypeScript - import { loadFixture } from "@nomicfoundation/hardhat-toolbox-viem/network-helpers"; import { expect } from "chai"; import hre from "hardhat"; import { ContractFunctionExecutionError, parseEther } from "viem"; + import { describe, it } from "node:test"; + const { viem, networkHelpers } = await hre.network.connect(); //constants and local variables const ODD_DECIMALS = 10; @@ -38,19 +40,17 @@ With blockchain development, testing is very important because you don't have th // and reset Hardhat Network to that snapshot in every test. async function deployContractFixture() { // Contracts are deployed using the first signer/account by default - const [owner, bob] = await hre.viem.getWalletClients(); + const [owner, bob] = await viem.getWalletClients(); // Set block base fee to zero because we want exact calculation checks without network fees - await hre.network.provider.send("hardhat_setNextBlockBaseFeePerGas", [ - "0x0", - ]); + await networkHelpers.setNextBlockBaseFeePerGas("0x0"); - const marketpulseContract = await hre.viem.deployContract( + const marketpulseContract = await viem.deployContract( "Marketpulse", [] ); - const publicClient = await hre.viem.getPublicClient(); + const publicClient = await viem.getPublicClient(); initAliceAmount = await publicClient.getBalance({ address: owner.account.address, @@ -70,7 +70,7 @@ With blockchain development, testing is very important because you don't have th describe("init function", function () { it("should be initialized", async function () { - const { marketpulseContract, owner } = await loadFixture( + const { marketpulseContract, owner } = await networkHelpers.loadFixture( deployContractFixture ); @@ -82,7 +82,7 @@ With blockchain development, testing is very important because you don't have th }); it("should return Pong", async function () { - const { marketpulseContract, publicClient } = await loadFixture( + const { marketpulseContract, publicClient } = await networkHelpers.loadFixture( deployContractFixture ); @@ -112,7 +112,7 @@ With blockchain development, testing is very important because you don't have th owner: alice, publicClient, bob, - } = await loadFixture(deployContractFixture); + } = await networkHelpers.loadFixture(deployContractFixture); expect(await marketpulseContract.read.betKeys.length).to.equal(0); @@ -160,9 +160,7 @@ With blockchain development, testing is very important because you don't have th console.log("Lions bet for 2 ethers should return a hash"); // Set block base fee to zero - await hre.network.provider.send("hardhat_setNextBlockBaseFeePerGas", [ - "0x0", - ]); + await networkHelpers.setNextBlockBaseFeePerGas("0x0"); const betLions2IdHash = await marketpulseContract.write.bet( ["lions", parseEther("2")],