From 7e697a5ae7f8b8a90c8f17c620df6c54b8d20a31 Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Tue, 4 Jun 2024 22:52:33 -0400 Subject: [PATCH 1/6] update code --- .../evm-token-factory/contracts/.gitignore | 14 ++++++++ .../{smart-contracts => contracts}/README.md | 0 .../foundry.toml | 1 - .../lib/forge-std | 0 .../lib/openzeppelin-contracts | 0 .../contracts/remappings.txt | 1 + .../contracts/script/Counter.s.sol | 12 +++++++ .../contracts/script/CreateToken.s.sol | 23 ++++++++++++ .../contracts/src/Counter.sol | 14 ++++++++ .../src/Factory.sol | 2 +- .../src/Token.sol | 5 +-- .../contracts/test/Counter.t.sol | 24 +++++++++++++ .../contracts/test/Factory.t.sol | 35 +++++++++++++++++++ .../contracts/test/Token.t.sol | 33 +++++++++++++++++ .../smart-contracts/abi/factory.json | 1 - .../smart-contracts/script/Factory.s.sol | 16 --------- .../smart-contracts/test/Factory.t.sol | 35 ------------------- 17 files changed, 160 insertions(+), 56 deletions(-) create mode 100644 sample-dapps/evm-token-factory/contracts/.gitignore rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/README.md (100%) rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/foundry.toml (67%) rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/lib/forge-std (100%) rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/lib/openzeppelin-contracts (100%) create mode 100644 sample-dapps/evm-token-factory/contracts/remappings.txt create mode 100644 sample-dapps/evm-token-factory/contracts/script/Counter.s.sol create mode 100644 sample-dapps/evm-token-factory/contracts/script/CreateToken.s.sol create mode 100644 sample-dapps/evm-token-factory/contracts/src/Counter.sol rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/src/Factory.sol (99%) rename sample-dapps/evm-token-factory/{smart-contracts => contracts}/src/Token.sol (91%) create mode 100644 sample-dapps/evm-token-factory/contracts/test/Counter.t.sol create mode 100644 sample-dapps/evm-token-factory/contracts/test/Factory.t.sol create mode 100644 sample-dapps/evm-token-factory/contracts/test/Token.t.sol delete mode 100644 sample-dapps/evm-token-factory/smart-contracts/abi/factory.json delete mode 100644 sample-dapps/evm-token-factory/smart-contracts/script/Factory.s.sol delete mode 100644 sample-dapps/evm-token-factory/smart-contracts/test/Factory.t.sol diff --git a/sample-dapps/evm-token-factory/contracts/.gitignore b/sample-dapps/evm-token-factory/contracts/.gitignore new file mode 100644 index 0000000..85198aa --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/.gitignore @@ -0,0 +1,14 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/sample-dapps/evm-token-factory/smart-contracts/README.md b/sample-dapps/evm-token-factory/contracts/README.md similarity index 100% rename from sample-dapps/evm-token-factory/smart-contracts/README.md rename to sample-dapps/evm-token-factory/contracts/README.md diff --git a/sample-dapps/evm-token-factory/smart-contracts/foundry.toml b/sample-dapps/evm-token-factory/contracts/foundry.toml similarity index 67% rename from sample-dapps/evm-token-factory/smart-contracts/foundry.toml rename to sample-dapps/evm-token-factory/contracts/foundry.toml index 2781e19..25b918f 100644 --- a/sample-dapps/evm-token-factory/smart-contracts/foundry.toml +++ b/sample-dapps/evm-token-factory/contracts/foundry.toml @@ -2,6 +2,5 @@ src = "src" out = "out" libs = ["lib"] -remappings = ["@openzeppelin/=node_modules/@openzeppelin/openzeppelin-contracts/"] # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/sample-dapps/evm-token-factory/smart-contracts/lib/forge-std b/sample-dapps/evm-token-factory/contracts/lib/forge-std similarity index 100% rename from sample-dapps/evm-token-factory/smart-contracts/lib/forge-std rename to sample-dapps/evm-token-factory/contracts/lib/forge-std diff --git a/sample-dapps/evm-token-factory/smart-contracts/lib/openzeppelin-contracts b/sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts similarity index 100% rename from sample-dapps/evm-token-factory/smart-contracts/lib/openzeppelin-contracts rename to sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts diff --git a/sample-dapps/evm-token-factory/contracts/remappings.txt b/sample-dapps/evm-token-factory/contracts/remappings.txt new file mode 100644 index 0000000..6fdbafd --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/remappings.txt @@ -0,0 +1 @@ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ diff --git a/sample-dapps/evm-token-factory/contracts/script/Counter.s.sol b/sample-dapps/evm-token-factory/contracts/script/Counter.s.sol new file mode 100644 index 0000000..df9ee8b --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/script/Counter.s.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script, console} from "forge-std/Script.sol"; + +contract CounterScript is Script { + function setUp() public {} + + function run() public { + vm.broadcast(); + } +} diff --git a/sample-dapps/evm-token-factory/contracts/script/CreateToken.s.sol b/sample-dapps/evm-token-factory/contracts/script/CreateToken.s.sol new file mode 100644 index 0000000..0af44ba --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/script/CreateToken.s.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "forge-std/Script.sol"; +import "../src/Factory.sol"; + +contract CreateToken is Script { + function run() public { + vm.startBroadcast(); + + address initialOwner = msg.sender; + uint256 initialSupply = 1000; + string memory name = "MyToken"; + string memory symbol = "MTK"; + + TokenFactory factory = new TokenFactory(); + + address tokenAddress = factory.createToken(initialOwner, initialSupply, name, symbol); + console.log("Token created at address:", tokenAddress); + + vm.stopBroadcast(); + } +} diff --git a/sample-dapps/evm-token-factory/contracts/src/Counter.sol b/sample-dapps/evm-token-factory/contracts/src/Counter.sol new file mode 100644 index 0000000..aded799 --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/sample-dapps/evm-token-factory/smart-contracts/src/Factory.sol b/sample-dapps/evm-token-factory/contracts/src/Factory.sol similarity index 99% rename from sample-dapps/evm-token-factory/smart-contracts/src/Factory.sol rename to sample-dapps/evm-token-factory/contracts/src/Factory.sol index 26a1c25..2116e1c 100644 --- a/sample-dapps/evm-token-factory/smart-contracts/src/Factory.sol +++ b/sample-dapps/evm-token-factory/contracts/src/Factory.sol @@ -13,4 +13,4 @@ contract TokenFactory { return address(newToken); } -} \ No newline at end of file +} diff --git a/sample-dapps/evm-token-factory/smart-contracts/src/Token.sol b/sample-dapps/evm-token-factory/contracts/src/Token.sol similarity index 91% rename from sample-dapps/evm-token-factory/smart-contracts/src/Token.sol rename to sample-dapps/evm-token-factory/contracts/src/Token.sol index a23a9f6..e6bb4a1 100644 --- a/sample-dapps/evm-token-factory/smart-contracts/src/Token.sol +++ b/sample-dapps/evm-token-factory/contracts/src/Token.sol @@ -5,7 +5,8 @@ import "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; import "openzeppelin-contracts/contracts/access/Ownable.sol"; contract Token is ERC20, Ownable { - constructor(address initialOwner, uint256 initialSupply, string memory name, string memory symbol) + constructor(address initialOwner, uint256 initialSupply, string memory +name, string memory symbol) ERC20(name, symbol) Ownable(initialOwner) { @@ -13,4 +14,4 @@ contract Token is ERC20, Ownable { _mint(initialOwner, initialSupply * 10 ** 18); } -} \ No newline at end of file +} diff --git a/sample-dapps/evm-token-factory/contracts/test/Counter.t.sol b/sample-dapps/evm-token-factory/contracts/test/Counter.t.sol new file mode 100644 index 0000000..54b724f --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/test/Counter.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test, console} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function test_Increment() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testFuzz_SetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} diff --git a/sample-dapps/evm-token-factory/contracts/test/Factory.t.sol b/sample-dapps/evm-token-factory/contracts/test/Factory.t.sol new file mode 100644 index 0000000..487ea1f --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/test/Factory.t.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +import "forge-std/Test.sol"; +import "../src/Factory.sol"; +import "../src/Token.sol"; + +contract TokenFactoryTest is Test { + TokenFactory factory; + address initialOwner; + uint256 initialSupply = 1000; + string name = "MyToken"; + string symbol = "MTK"; + + event TokenCreated(address indexed tokenAddress, address indexed owner, uint256 initialSupply); + + function setUp() public { + factory = new TokenFactory(); + initialOwner = address(this); + } + + function testCreateToken() public { + vm.expectEmit(false, false, false, false); + emit TokenCreated(address(0), initialOwner, initialSupply); + + address tokenAddr = factory.createToken(initialOwner, initialSupply, name, symbol); + assertTrue(tokenAddr != address(0), "Token creation failed"); + + Token token = Token(tokenAddr); + assertEq(token.owner(), initialOwner, "Owner is not set correctly"); + assertEq(token.totalSupply(), initialSupply * 10 ** 18, "Initial supply is incorrect"); + assertEq(token.name(), name, "Token name is incorrect"); + assertEq(token.symbol(), symbol, "Token symbol is incorrect"); + } +} diff --git a/sample-dapps/evm-token-factory/contracts/test/Token.t.sol b/sample-dapps/evm-token-factory/contracts/test/Token.t.sol new file mode 100644 index 0000000..f284ac5 --- /dev/null +++ b/sample-dapps/evm-token-factory/contracts/test/Token.t.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/Test.sol"; +import "../src/Token.sol"; + +contract TokenTest is Test { + Token token; + address initialOwner; + uint initialSupply = 1000; + string name = "TestToken"; + string symbol = "TT"; + + function setUp() public { + initialOwner = address(this); + token = new Token(initialOwner, initialSupply, name, symbol); + } + + function testInitialOwner() public view { + assertEq(token.owner(), initialOwner); + } + + function testInitialSupply() public view { + uint expectedSupply = initialSupply * 10 ** token.decimals(); + assertEq(token.totalSupply(), expectedSupply); + assertEq(token.balanceOf(initialOwner), expectedSupply); + } + + function testNameAndSymbol() public view { + assertEq(token.name(), name); + assertEq(token.symbol(), symbol); + } +} diff --git a/sample-dapps/evm-token-factory/smart-contracts/abi/factory.json b/sample-dapps/evm-token-factory/smart-contracts/abi/factory.json deleted file mode 100644 index 4aa5255..0000000 --- a/sample-dapps/evm-token-factory/smart-contracts/abi/factory.json +++ /dev/null @@ -1 +0,0 @@ -[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"initialSupply","type":"uint256"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"createToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/sample-dapps/evm-token-factory/smart-contracts/script/Factory.s.sol b/sample-dapps/evm-token-factory/smart-contracts/script/Factory.s.sol deleted file mode 100644 index bd58994..0000000 --- a/sample-dapps/evm-token-factory/smart-contracts/script/Factory.s.sol +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import "forge-std/Script.sol"; -import "../src/Factory.sol"; - -contract DeployTokenFactory is Script { - function run() external { - vm.startBroadcast(); - - TokenFactory tokenFactory = new TokenFactory(); - console.log("TokenFactory deployed at:", address(tokenFactory)); - - vm.stopBroadcast(); - } -} diff --git a/sample-dapps/evm-token-factory/smart-contracts/test/Factory.t.sol b/sample-dapps/evm-token-factory/smart-contracts/test/Factory.t.sol deleted file mode 100644 index 94e5291..0000000 --- a/sample-dapps/evm-token-factory/smart-contracts/test/Factory.t.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -import { Test } from "forge-std/Test.sol"; -import { TokenFactory } from "../src/Factory.sol"; -import { Token } from "../src/Token.sol"; - -contract TokenFactoryTest is Test { - TokenFactory public factory; - - function setUp() public { - factory = new TokenFactory(); - } - - function test_CreateToken() public { - address initialOwner = address(this); - uint256 initialSupply = 1000; - string memory name = "TestToken"; - string memory symbol = "TTK"; - - vm.startPrank(initialOwner); - address tokenAddress = factory.createToken(initialOwner, initialSupply, name, symbol); - vm.stopPrank(); - - assertTrue(tokenAddress != address(0), "Token address should not be zero"); - - Token token = Token(tokenAddress); - assertEq(token.name(), name, "Token name should match"); - assertEq(token.symbol(), symbol, "Token symbol should match"); - assertEq(token.totalSupply(), initialSupply * 10 ** 18, "Token supply should be adjusted for decimals"); - assertEq(token.balanceOf(initialOwner), initialSupply * 10 ** 18, "Initial owner should hold all tokens"); - assertEq(token.owner(), initialOwner, "Initial owner should be the owner"); - } - -} From 4828fe763e9991d95e5d601fa67d82d2408dd640 Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Thu, 6 Jun 2024 13:11:37 -0400 Subject: [PATCH 2/6] update readme and abi path --- sample-dapps/evm-token-factory/README.md | 28 +- .../app/api/evm/createToken/route.ts | 2 +- .../evm-token-factory/package-lock.json | 336 +++++++++--------- 3 files changed, 184 insertions(+), 182 deletions(-) diff --git a/sample-dapps/evm-token-factory/README.md b/sample-dapps/evm-token-factory/README.md index b70dbef..9b8aa8b 100644 --- a/sample-dapps/evm-token-factory/README.md +++ b/sample-dapps/evm-token-factory/README.md @@ -1,3 +1,4 @@ + # QuickNode EVM Token Factory Demo ## Overview @@ -12,10 +13,22 @@ The demo uses [Next.js 14](https://nextjs.org/) project bootstrapped with [`crea ## Getting Started +Open the project directory: + +```bash +cd sample-dapps/evm-token-factory +``` + ### Set Environment Variables 1. Rename `.env.example` to `.env.local `and update it with RPC URLs for each blockchain. Also, include your [WalletConnect](https://cloud.walletconnect.com/). project ID (optionally, you can leave this blank but some features will not be supported). To create RPC URLs for each chain, you can run your own node locally or use a service like [QuickNode](https://quicknode.com) to quickly spin up a node endpoint. +### Configure Smart Contract Addresses + +2. Update the `factoryAddress` value in `evm-token-factory/app/utils/ethereum.ts` with your deployed factory contract address. This is the address you received in the output during the [Deployment](https://quicknode.com/guides/ethereum-development/dapps/how-to-create-an-evm-token-factory-dapp#deployment) section. + +3. Remove any unused chains (e.g., mainnet) from the `src/context/web3modal.tsx` file. + ### RPC Configuration This app requires a valid RPC URL for each blockchain you want to support. Here are more details on how RPC is configured throughout the app. @@ -27,12 +40,6 @@ If you do not want to support a blockchain(s), you can remove references of the ### Install Dependencies -Open the project directory: - -```bash -cd sample-dapps/evm-token-factory -``` - Then, install the dependencies: ```bash @@ -45,7 +52,7 @@ pnpm install bun install ``` -First, run the development server: +After, start the development server: ```bash npm run dev @@ -109,12 +116,7 @@ The ERC-20 Token Factory is built with two smart contracts: To deploy the Factory contract on a new chain using Foundry, follow these steps: -1. Ensure [Foundry](https://book.getfoundry.sh/) is installed and navigate inside the `smart-contracts` directory. Install the required dependencies with the following commands: - -```sh -forge install OpenZeppelin/openzeppelin-contracts --no-commit -forge install foundry-rs/forge-std --no-commit -``` +1. Ensure [Foundry](https://book.getfoundry.sh/) is installed and navigate inside the `contracts` directory. Install the required dependencies with the following commands: 2. Build (compile) the smart contracts using the `forge build` command. diff --git a/sample-dapps/evm-token-factory/app/api/evm/createToken/route.ts b/sample-dapps/evm-token-factory/app/api/evm/createToken/route.ts index 2586dc3..8bf3e76 100644 --- a/sample-dapps/evm-token-factory/app/api/evm/createToken/route.ts +++ b/sample-dapps/evm-token-factory/app/api/evm/createToken/route.ts @@ -1,6 +1,6 @@ import { ethers } from 'ethers'; import { RequestBody, CHAINS } from '@/app/utils/ethereum'; -import abi from '@/smart-contracts/abi/factory.json' +import abi from '@/app/utils/abi.json'; export async function POST(request: Request) { try { diff --git a/sample-dapps/evm-token-factory/package-lock.json b/sample-dapps/evm-token-factory/package-lock.json index 8f5eee1..b5062c6 100644 --- a/sample-dapps/evm-token-factory/package-lock.json +++ b/sample-dapps/evm-token-factory/package-lock.json @@ -523,6 +523,126 @@ "node": ">= 10" } }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz", + "integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz", + "integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz", + "integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz", + "integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz", + "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", + "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", + "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", + "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@noble/curves": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", @@ -7435,126 +7555,6 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } - }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz", - "integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz", - "integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz", - "integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz", - "integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz", - "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", - "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", - "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", - "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } } }, "dependencies": { @@ -7957,6 +7957,54 @@ "integrity": "sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==", "optional": true }, + "@next/swc-darwin-x64": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz", + "integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==", + "optional": true + }, + "@next/swc-linux-arm64-gnu": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz", + "integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==", + "optional": true + }, + "@next/swc-linux-arm64-musl": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz", + "integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==", + "optional": true + }, + "@next/swc-linux-x64-gnu": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz", + "integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==", + "optional": true + }, + "@next/swc-linux-x64-musl": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz", + "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==", + "optional": true + }, + "@next/swc-win32-arm64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", + "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", + "optional": true + }, + "@next/swc-win32-ia32-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", + "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", + "optional": true + }, + "@next/swc-win32-x64-msvc": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", + "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", + "optional": true + }, "@noble/curves": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", @@ -13026,54 +13074,6 @@ "version": "3.22.4", "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==" - }, - "@next/swc-darwin-x64": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz", - "integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==", - "optional": true - }, - "@next/swc-linux-arm64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz", - "integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==", - "optional": true - }, - "@next/swc-linux-arm64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz", - "integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==", - "optional": true - }, - "@next/swc-linux-x64-gnu": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz", - "integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==", - "optional": true - }, - "@next/swc-linux-x64-musl": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz", - "integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==", - "optional": true - }, - "@next/swc-win32-arm64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz", - "integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==", - "optional": true - }, - "@next/swc-win32-ia32-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz", - "integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==", - "optional": true - }, - "@next/swc-win32-x64-msvc": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz", - "integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==", - "optional": true } } } From a9bac0213298dedb8b9fc8fa7005280f6caa5dbd Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Thu, 6 Jun 2024 14:57:16 -0400 Subject: [PATCH 3/6] remove libs --- sample-dapps/evm-token-factory/contracts/lib/forge-std | 1 - .../evm-token-factory/contracts/lib/openzeppelin-contracts | 1 - 2 files changed, 2 deletions(-) delete mode 160000 sample-dapps/evm-token-factory/contracts/lib/forge-std delete mode 160000 sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts diff --git a/sample-dapps/evm-token-factory/contracts/lib/forge-std b/sample-dapps/evm-token-factory/contracts/lib/forge-std deleted file mode 160000 index 978ac6f..0000000 --- a/sample-dapps/evm-token-factory/contracts/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 978ac6fadb62f5f0b723c996f64be52eddba6801 diff --git a/sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts b/sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts deleted file mode 160000 index dbb6104..0000000 --- a/sample-dapps/evm-token-factory/contracts/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dbb6104ce834628e473d2173bbc9d47f81a9eec3 From abfbcab3af9c0d32c0829d55ba41c18881b668ff Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Thu, 6 Jun 2024 15:18:54 -0400 Subject: [PATCH 4/6] update abi --- sample-dapps/evm-token-factory/app/utils/abi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample-dapps/evm-token-factory/app/utils/abi.json b/sample-dapps/evm-token-factory/app/utils/abi.json index 41e27d0..4aa5255 100644 --- a/sample-dapps/evm-token-factory/app/utils/abi.json +++ b/sample-dapps/evm-token-factory/app/utils/abi.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"initialSupply","type":"uint256"}],"name":"TokenCreated","type":"event"},{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"name":"createToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file From f21e185174fb2ef84edb2a993465a9fdb84a971d Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Thu, 6 Jun 2024 15:41:13 -0400 Subject: [PATCH 5/6] add await --- sample-dapps/evm-token-factory/app/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/sample-dapps/evm-token-factory/app/page.tsx b/sample-dapps/evm-token-factory/app/page.tsx index d0b88c7..3bffd27 100644 --- a/sample-dapps/evm-token-factory/app/page.tsx +++ b/sample-dapps/evm-token-factory/app/page.tsx @@ -51,6 +51,7 @@ export default function Home() { const chainConfig = CHAINS[chainId ?? 1]; const populateTxn = await signer.populateTransaction(data.apiResponse) const send = await signer.sendTransaction(populateTxn) + await send.wait() const receipt = await ethersProvider.getTransactionReceipt(send.hash) const tokenAddressLogs = receipt?.logs[3].topics[1] as string; const tokenAddress = decoder.decode(['address'], tokenAddressLogs)[0] From 54ec873a56bbaa69c3a6852774e2df4741e9e34b Mon Sep 17 00:00:00 2001 From: Ferhat K Date: Fri, 7 Jun 2024 10:35:37 -0400 Subject: [PATCH 6/6] implement feedback --- sample-dapps/evm-token-factory/README.md | 82 +++++++++++++------ .../evm-token-factory/package-lock.json | 27 ++++++ sample-dapps/evm-token-factory/package.json | 1 + 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/sample-dapps/evm-token-factory/README.md b/sample-dapps/evm-token-factory/README.md index 9b8aa8b..5163aa5 100644 --- a/sample-dapps/evm-token-factory/README.md +++ b/sample-dapps/evm-token-factory/README.md @@ -71,30 +71,59 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the 1. Connect your wallet - Make sure you have enough ETH (or other native EVM gas token) in your wallet to cover the create token transaction - If you are using Testnet, you can get free ETH from the [QuickNode Faucet](https://faucet.quicknode.com/) -2. Click "Create Token" and confirm the transaction to create the ERC-2O token! +2. Click "Create Token" and confirm the transaction to create the ERC-20 token! ### Architecture -```bash -src/ -├── app/ -│ ├── page.tsx # Main page for Token Factory -│ └── layout.tsx # Import the Web3Modal component -│ └── api/ -│ └── evm/ -│ └── createToken/route.ts # Create New ERC-20 Transaction -└── components/ -| ├── Connect.tsx # Web3Modal Component -| ├── Navbar.tsx # Navbar component - └── Footer.tsx # Footer Component -└── context/ - ├── web3modal.tsx # Wallet Adapter Context providers -└── smart_contracts/ -│ └── abi/ -│ └── factory.json # Factory ABI -│ └── Factory.sol # Token Factory -│ └── Token.sol # Token Details -├── .env.local # Configure RPCs and WalletConnect Project ID + +```sh +├── app +│   ├── api +│   │   └── evm +│   │   └── createToken +│   │   └── route.ts # API Method for calling CreateToken function +│   ├── components +│   │   ├── Connect.tsx # Web3Modal Component +│   │   ├── Footer.tsx +│   │   └── Navbar.tsx +│   ├── favicon.ico +│   ├── globals.css +│   ├── layout.tsx # The Web3Modal component +│   ├── page.tsx # Main page for Token Factory +│   └── utils +│   ├── abi.json # Factory ABI +│   └── ethereum.ts # Chain configuration and helpers +├── context +│   └── web3modal.tsx # Wallet Adapter Context providers +├── contracts +│   ├── README.md +│   ├── foundry.toml # Forge configuration +│   ├── lib # Dependencies +│   ├── remappings.txt # Library mappings +│   ├── script +│   │   ├── Counter.s.sol +│   │   └── CreateToken.s.sol +│   ├── src +│   │   ├── Counter.sol +│   │   ├── Factory.sol +│   │   └── Token.sol +│   └── test +│   ├── Counter.t.sol +│   ├── Factory.t.sol +│   └── Token.t.sol +├── next-env.d.ts +├── next.config.mjs +├── package-lock.json +├── package.json +├── postcss.config.mjs +├── public +│   ├── next.svg +│   ├── preview.png +│   ├── preview2.png +│   └── vercel.svg +├── .env.example # Configure RPCs and WalletConnect Project ID +├── tailwind.config.ts +└── tsconfig.json ``` ## Smart Contracts @@ -103,9 +132,9 @@ The ERC-20 Token Factory backend built on smart contracts with Solidity can be d The ERC-20 Token Factory is built with two smart contracts: -- **Factory**: The Factory contract (`smart-contracts/Factory.sol`) inherits the Token.sol smart contract and acts as a Factory for creating and tracking new ERC-20 tokens. +- **Factory**: The Factory contract (`contracts/Factory.sol`) inherits the Token.sol smart contract and acts as a Factory for creating and tracking new ERC-20 tokens. -- **Token**: This is an ERC-20 smart contract (`smart-contracts/Token.sol`) defined by the OpenZeppelin standard and includes a `mint` and `transferOwnership` function call in the constructor upon deployment. +- **Token**: This is an ERC-20 smart contract (`contracts/Token.sol`) defined by the OpenZeppelin standard and includes a `mint` and `transferOwnership` function call in the constructor upon deployment. ### Supported Chains & Addresses @@ -118,6 +147,11 @@ To deploy the Factory contract on a new chain using Foundry, follow these steps: 1. Ensure [Foundry](https://book.getfoundry.sh/) is installed and navigate inside the `contracts` directory. Install the required dependencies with the following commands: +```sh +forge install foundry-rs/forge-std --no-commit +forge install OpenZeppelin/openzeppelin-contracts --no-commit +``` + 2. Build (compile) the smart contracts using the `forge build` command. 3. Run tests using the `forge test` command. @@ -127,7 +161,7 @@ To deploy the Factory contract on a new chain using Foundry, follow these steps: ```sh forge create --rpc-url QUICKNODE_HTTP_URL \ --private-key YOUR_PRIVATE_KEY \ -src/Factory.sol:Factory +src/Factory.sol:TokenFactory ``` 5. Edit the `src/context/web3modal.tsx` file and add a new chain object with its chain ID (find a list [here](https://chainlist.org/)), name, native gas token currency, explorer URL, and RPC URL (e.g., QuickNode): diff --git a/sample-dapps/evm-token-factory/package-lock.json b/sample-dapps/evm-token-factory/package-lock.json index b5062c6..050d574 100644 --- a/sample-dapps/evm-token-factory/package-lock.json +++ b/sample-dapps/evm-token-factory/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "@openzeppelin/contracts": "^5.0.2", + "@types/node": "^20.14.2", "@web3modal/ethers": "^4.1.11", "ethers": "^6.12.0", "next": "14.2.3", @@ -1039,6 +1040,14 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, + "node_modules/@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -7010,6 +7019,11 @@ "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==" }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unenv": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.9.0.tgz", @@ -8332,6 +8346,14 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, + "@types/node": { + "version": "20.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", + "integrity": "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==", + "requires": { + "undici-types": "~5.26.4" + } + }, "@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -12723,6 +12745,11 @@ "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==" }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "unenv": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/unenv/-/unenv-1.9.0.tgz", diff --git a/sample-dapps/evm-token-factory/package.json b/sample-dapps/evm-token-factory/package.json index f7af22d..c4b74a6 100644 --- a/sample-dapps/evm-token-factory/package.json +++ b/sample-dapps/evm-token-factory/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@openzeppelin/contracts": "^5.0.2", + "@types/node": "^20.14.2", "@web3modal/ethers": "^4.1.11", "ethers": "^6.12.0", "next": "14.2.3",